xref: /aosp_15_r20/external/boringssl/src/crypto/fipsmodule/rsa/padding.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
2  * project 2005.
3  */
4 /* ====================================================================
5  * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    [email protected].
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * ([email protected]).  This product includes software written by Tim
54  * Hudson ([email protected]). */
55 
56 #include <openssl/rsa.h>
57 
58 #include <assert.h>
59 #include <limits.h>
60 #include <string.h>
61 
62 #include <openssl/bn.h>
63 #include <openssl/digest.h>
64 #include <openssl/err.h>
65 #include <openssl/mem.h>
66 #include <openssl/rand.h>
67 #include <openssl/sha.h>
68 
69 #include "internal.h"
70 #include "../service_indicator/internal.h"
71 #include "../../internal.h"
72 
73 
RSA_padding_add_PKCS1_type_1(uint8_t * to,size_t to_len,const uint8_t * from,size_t from_len)74 int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len,
75                                  const uint8_t *from, size_t from_len) {
76   // See RFC 8017, section 9.2.
77   if (to_len < RSA_PKCS1_PADDING_SIZE) {
78     OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
79     return 0;
80   }
81 
82   if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
83     OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
84     return 0;
85   }
86 
87   to[0] = 0;
88   to[1] = 1;
89   OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len);
90   to[to_len - from_len - 1] = 0;
91   OPENSSL_memcpy(to + to_len - from_len, from, from_len);
92   return 1;
93 }
94 
RSA_padding_check_PKCS1_type_1(uint8_t * out,size_t * out_len,size_t max_out,const uint8_t * from,size_t from_len)95 int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len,
96                                    size_t max_out, const uint8_t *from,
97                                    size_t from_len) {
98   // See RFC 8017, section 9.2. This is part of signature verification and thus
99   // does not need to run in constant-time.
100   if (from_len < 2) {
101     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
102     return 0;
103   }
104 
105   // Check the header.
106   if (from[0] != 0 || from[1] != 1) {
107     OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
108     return 0;
109   }
110 
111   // Scan over padded data, looking for the 00.
112   size_t pad;
113   for (pad = 2 /* header */; pad < from_len; pad++) {
114     if (from[pad] == 0x00) {
115       break;
116     }
117 
118     if (from[pad] != 0xff) {
119       OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
120       return 0;
121     }
122   }
123 
124   if (pad == from_len) {
125     OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
126     return 0;
127   }
128 
129   if (pad < 2 /* header */ + 8) {
130     OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT);
131     return 0;
132   }
133 
134   // Skip over the 00.
135   pad++;
136 
137   if (from_len - pad > max_out) {
138     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
139     return 0;
140   }
141 
142   OPENSSL_memcpy(out, from + pad, from_len - pad);
143   *out_len = from_len - pad;
144   return 1;
145 }
146 
RSA_padding_add_none(uint8_t * to,size_t to_len,const uint8_t * from,size_t from_len)147 int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from,
148                          size_t from_len) {
149   if (from_len > to_len) {
150     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
151     return 0;
152   }
153 
154   if (from_len < to_len) {
155     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
156     return 0;
157   }
158 
159   OPENSSL_memcpy(to, from, from_len);
160   return 1;
161 }
162 
PKCS1_MGF1(uint8_t * out,size_t len,const uint8_t * seed,size_t seed_len,const EVP_MD * md)163 int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len,
164                const EVP_MD *md) {
165   int ret = 0;
166   EVP_MD_CTX ctx;
167   EVP_MD_CTX_init(&ctx);
168   FIPS_service_indicator_lock_state();
169 
170   size_t md_len = EVP_MD_size(md);
171 
172   for (uint32_t i = 0; len > 0; i++) {
173     uint8_t counter[4];
174     counter[0] = (uint8_t)(i >> 24);
175     counter[1] = (uint8_t)(i >> 16);
176     counter[2] = (uint8_t)(i >> 8);
177     counter[3] = (uint8_t)i;
178     if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
179         !EVP_DigestUpdate(&ctx, seed, seed_len) ||
180         !EVP_DigestUpdate(&ctx, counter, sizeof(counter))) {
181       goto err;
182     }
183 
184     if (md_len <= len) {
185       if (!EVP_DigestFinal_ex(&ctx, out, NULL)) {
186         goto err;
187       }
188       out += md_len;
189       len -= md_len;
190     } else {
191       uint8_t digest[EVP_MAX_MD_SIZE];
192       if (!EVP_DigestFinal_ex(&ctx, digest, NULL)) {
193         goto err;
194       }
195       OPENSSL_memcpy(out, digest, len);
196       len = 0;
197     }
198   }
199 
200   ret = 1;
201 
202 err:
203   EVP_MD_CTX_cleanup(&ctx);
204   FIPS_service_indicator_unlock_state();
205   return ret;
206 }
207 
208 static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0};
209 
RSA_verify_PKCS1_PSS_mgf1(const RSA * rsa,const uint8_t * mHash,const EVP_MD * Hash,const EVP_MD * mgf1Hash,const uint8_t * EM,int sLen)210 int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
211                               const EVP_MD *Hash, const EVP_MD *mgf1Hash,
212                               const uint8_t *EM, int sLen) {
213   if (mgf1Hash == NULL) {
214     mgf1Hash = Hash;
215   }
216 
217   int ret = 0;
218   uint8_t *DB = NULL;
219   EVP_MD_CTX ctx;
220   EVP_MD_CTX_init(&ctx);
221   FIPS_service_indicator_lock_state();
222 
223   // Negative sLen has special meanings:
224   //   -1      sLen == hLen
225   //   -2      salt length is autorecovered from signature
226   //   -N      reserved
227   size_t hLen = EVP_MD_size(Hash);
228   if (sLen == -1) {
229     sLen = (int)hLen;
230   } else if (sLen == -2) {
231     sLen = -2;
232   } else if (sLen < -2) {
233     OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
234     goto err;
235   }
236 
237   unsigned MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
238   size_t emLen = RSA_size(rsa);
239   if (EM[0] & (0xFF << MSBits)) {
240     OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
241     goto err;
242   }
243   if (MSBits == 0) {
244     EM++;
245     emLen--;
246   }
247   // |sLen| may be -2 for the non-standard salt length recovery mode.
248   if (emLen < hLen + 2 ||
249       (sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) {
250     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
251     goto err;
252   }
253   if (EM[emLen - 1] != 0xbc) {
254     OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
255     goto err;
256   }
257   size_t maskedDBLen = emLen - hLen - 1;
258   const uint8_t *H = EM + maskedDBLen;
259   DB = OPENSSL_malloc(maskedDBLen);
260   if (!DB) {
261     goto err;
262   }
263   if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) {
264     goto err;
265   }
266   for (size_t i = 0; i < maskedDBLen; i++) {
267     DB[i] ^= EM[i];
268   }
269   if (MSBits) {
270     DB[0] &= 0xFF >> (8 - MSBits);
271   }
272   // This step differs slightly from EMSA-PSS-VERIFY (RFC 8017) step 10 because
273   // it accepts a non-standard salt recovery flow. DB should be some number of
274   // zeros, a one, then the salt.
275   size_t salt_start;
276   for (salt_start = 0; DB[salt_start] == 0 && salt_start < maskedDBLen - 1;
277        salt_start++) {
278     ;
279   }
280   if (DB[salt_start] != 0x1) {
281     OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
282     goto err;
283   }
284   salt_start++;
285   // If a salt length was specified, check it matches.
286   if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) {
287     OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
288     goto err;
289   }
290   uint8_t H_[EVP_MAX_MD_SIZE];
291   if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
292       !EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) ||
293       !EVP_DigestUpdate(&ctx, mHash, hLen) ||
294       !EVP_DigestUpdate(&ctx, DB + salt_start, maskedDBLen - salt_start) ||
295       !EVP_DigestFinal_ex(&ctx, H_, NULL)) {
296     goto err;
297   }
298   if (OPENSSL_memcmp(H_, H, hLen) != 0) {
299     OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
300     goto err;
301   }
302 
303   ret = 1;
304 
305 err:
306   OPENSSL_free(DB);
307   EVP_MD_CTX_cleanup(&ctx);
308   FIPS_service_indicator_unlock_state();
309   return ret;
310 }
311 
RSA_padding_add_PKCS1_PSS_mgf1(const RSA * rsa,unsigned char * EM,const unsigned char * mHash,const EVP_MD * Hash,const EVP_MD * mgf1Hash,int sLenRequested)312 int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM,
313                                    const unsigned char *mHash,
314                                    const EVP_MD *Hash, const EVP_MD *mgf1Hash,
315                                    int sLenRequested) {
316   int ret = 0;
317   size_t maskedDBLen, MSBits, emLen;
318   size_t hLen;
319   unsigned char *H, *salt = NULL, *p;
320 
321   if (mgf1Hash == NULL) {
322     mgf1Hash = Hash;
323   }
324 
325   FIPS_service_indicator_lock_state();
326   hLen = EVP_MD_size(Hash);
327 
328   if (BN_is_zero(rsa->n)) {
329     OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
330     goto err;
331   }
332 
333   MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
334   emLen = RSA_size(rsa);
335   if (MSBits == 0) {
336     assert(emLen >= 1);
337     *EM++ = 0;
338     emLen--;
339   }
340 
341   if (emLen < hLen + 2) {
342     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
343     goto err;
344   }
345 
346   // Negative sLenRequested has special meanings:
347   //   -1  sLen == hLen
348   //   -2  salt length is maximized
349   //   -N  reserved
350   size_t sLen;
351   if (sLenRequested == -1) {
352     sLen = hLen;
353   } else if (sLenRequested == -2) {
354     sLen = emLen - hLen - 2;
355   } else if (sLenRequested < 0) {
356     OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
357     goto err;
358   } else {
359     sLen = (size_t)sLenRequested;
360   }
361 
362   if (emLen - hLen - 2 < sLen) {
363     OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
364     goto err;
365   }
366 
367   if (sLen > 0) {
368     salt = OPENSSL_malloc(sLen);
369     if (!salt) {
370       goto err;
371     }
372     if (!RAND_bytes(salt, sLen)) {
373       goto err;
374     }
375   }
376   maskedDBLen = emLen - hLen - 1;
377   H = EM + maskedDBLen;
378 
379   EVP_MD_CTX ctx;
380   EVP_MD_CTX_init(&ctx);
381   int digest_ok = EVP_DigestInit_ex(&ctx, Hash, NULL) &&
382                   EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) &&
383                   EVP_DigestUpdate(&ctx, mHash, hLen) &&
384                   EVP_DigestUpdate(&ctx, salt, sLen) &&
385                   EVP_DigestFinal_ex(&ctx, H, NULL);
386   EVP_MD_CTX_cleanup(&ctx);
387   if (!digest_ok) {
388     goto err;
389   }
390 
391   // Generate dbMask in place then perform XOR on it
392   if (!PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
393     goto err;
394   }
395 
396   p = EM;
397 
398   // Initial PS XORs with all zeroes which is a NOP so just update
399   // pointer. Note from a test above this value is guaranteed to
400   // be non-negative.
401   p += emLen - sLen - hLen - 2;
402   *p++ ^= 0x1;
403   if (sLen > 0) {
404     for (size_t i = 0; i < sLen; i++) {
405       *p++ ^= salt[i];
406     }
407   }
408   if (MSBits) {
409     EM[0] &= 0xFF >> (8 - MSBits);
410   }
411 
412   // H is already in place so just set final 0xbc
413 
414   EM[emLen - 1] = 0xbc;
415 
416   ret = 1;
417 
418 err:
419   OPENSSL_free(salt);
420   FIPS_service_indicator_unlock_state();
421 
422   return ret;
423 }
424