File: | s/lib/freebl/rsa.c |
Warning: | line 1515, column 9 4th function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* This Source Code Form is subject to the terms of the Mozilla Public | |||
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
4 | ||||
5 | /* | |||
6 | * RSA key generation, public key op, private key op. | |||
7 | */ | |||
8 | #ifdef FREEBL_NO_DEPEND1 | |||
9 | #include "stubs.h" | |||
10 | #endif | |||
11 | ||||
12 | #include "secerr.h" | |||
13 | ||||
14 | #include "prclist.h" | |||
15 | #include "nssilock.h" | |||
16 | #include "prinit.h" | |||
17 | #include "blapi.h" | |||
18 | #include "mpi.h" | |||
19 | #include "mpprime.h" | |||
20 | #include "mplogic.h" | |||
21 | #include "secmpi.h" | |||
22 | #include "secitem.h" | |||
23 | #include "blapii.h" | |||
24 | ||||
25 | /* The minimal required randomness is 64 bits */ | |||
26 | /* EXP_BLINDING_RANDOMNESS_LEN is the length of the randomness in mp_digits */ | |||
27 | /* for 32 bits platforts it is 2 mp_digits (= 2 * 32 bits), for 64 bits it is equal to 128 bits */ | |||
28 | #define EXP_BLINDING_RANDOMNESS_LEN((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit))) ((128 + MP_DIGIT_BIT(8 * sizeof(mp_digit)) - 1) / MP_DIGIT_BIT(8 * sizeof(mp_digit))) | |||
29 | #define EXP_BLINDING_RANDOMNESS_LEN_BYTES(((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit)) ) * sizeof(mp_digit)) (EXP_BLINDING_RANDOMNESS_LEN((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit))) * sizeof(mp_digit)) | |||
30 | ||||
31 | /* | |||
32 | ** Number of times to attempt to generate a prime (p or q) from a random | |||
33 | ** seed (the seed changes for each iteration). | |||
34 | */ | |||
35 | #define MAX_PRIME_GEN_ATTEMPTS10 10 | |||
36 | /* | |||
37 | ** Number of times to attempt to generate a key. The primes p and q change | |||
38 | ** for each attempt. | |||
39 | */ | |||
40 | #define MAX_KEY_GEN_ATTEMPTS10 10 | |||
41 | ||||
42 | /* Blinding Parameters max cache size */ | |||
43 | #define RSA_BLINDING_PARAMS_MAX_CACHE_SIZE20 20 | |||
44 | ||||
45 | /* exponent should not be greater than modulus */ | |||
46 | #define BAD_RSA_KEY_SIZE(modLen, expLen)((expLen) > (modLen) || (modLen) > 16384 / 8 || (expLen ) > 64 / 8) \ | |||
47 | ((expLen) > (modLen) || (modLen) > RSA_MAX_MODULUS_BITS16384 / 8 || \ | |||
48 | (expLen) > RSA_MAX_EXPONENT_BITS64 / 8) | |||
49 | ||||
50 | struct blindingParamsStr; | |||
51 | typedef struct blindingParamsStr blindingParams; | |||
52 | ||||
53 | struct blindingParamsStr { | |||
54 | blindingParams *next; | |||
55 | mp_int f, g; /* blinding parameter */ | |||
56 | int counter; /* number of remaining uses of (f, g) */ | |||
57 | }; | |||
58 | ||||
59 | /* | |||
60 | ** RSABlindingParamsStr | |||
61 | ** | |||
62 | ** For discussion of Paul Kocher's timing attack against an RSA private key | |||
63 | ** operation, see http://www.cryptography.com/timingattack/paper.html. The | |||
64 | ** countermeasure to this attack, known as blinding, is also discussed in | |||
65 | ** the Handbook of Applied Cryptography, 11.118-11.119. | |||
66 | */ | |||
67 | struct RSABlindingParamsStr { | |||
68 | /* Blinding-specific parameters */ | |||
69 | PRCList link; /* link to list of structs */ | |||
70 | SECItem modulus; /* list element "key" */ | |||
71 | blindingParams *free, *bp; /* Blinding parameters queue */ | |||
72 | blindingParams array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE20]; | |||
73 | /* precalculate montegomery reduction value */ | |||
74 | mp_digit n0i; /* n0i = -( n & MP_DIGIT) ** -1 mod mp_RADIX */ | |||
75 | }; | |||
76 | typedef struct RSABlindingParamsStr RSABlindingParams; | |||
77 | ||||
78 | /* | |||
79 | ** RSABlindingParamsListStr | |||
80 | ** | |||
81 | ** List of key-specific blinding params. The arena holds the volatile pool | |||
82 | ** of memory for each entry and the list itself. The lock is for list | |||
83 | ** operations, in this case insertions and iterations, as well as control | |||
84 | ** of the counter for each set of blinding parameters. | |||
85 | */ | |||
86 | struct RSABlindingParamsListStr { | |||
87 | PZLockPRLock *lock; /* Lock for the list */ | |||
88 | PRCondVar *cVar; /* Condidtion Variable */ | |||
89 | int waitCount; /* Number of threads waiting on cVar */ | |||
90 | PRCList head; /* Pointer to the list */ | |||
91 | }; | |||
92 | ||||
93 | /* | |||
94 | ** The master blinding params list. | |||
95 | */ | |||
96 | static struct RSABlindingParamsListStr blindingParamsList = { 0 }; | |||
97 | ||||
98 | /* Number of times to reuse (f, g). Suggested by Paul Kocher */ | |||
99 | #define RSA_BLINDING_PARAMS_MAX_REUSE50 50 | |||
100 | ||||
101 | /* Global, allows optional use of blinding. On by default. */ | |||
102 | /* Cannot be changed at the moment, due to thread-safety issues. */ | |||
103 | static PRBool nssRSAUseBlinding = PR_TRUE1; | |||
104 | ||||
105 | static SECStatus | |||
106 | rsa_build_from_primes(const mp_int *p, const mp_int *q, | |||
107 | mp_int *e, PRBool needPublicExponent, | |||
108 | mp_int *d, PRBool needPrivateExponent, | |||
109 | RSAPrivateKey *key, unsigned int keySizeInBits) | |||
110 | { | |||
111 | mp_int n, phi; | |||
112 | mp_int psub1, qsub1, tmp; | |||
113 | mp_err err = MP_OKAY0; | |||
114 | SECStatus rv = SECSuccess; | |||
115 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
116 | MP_DIGITS(&phi)((&phi)->dp) = 0; | |||
117 | MP_DIGITS(&psub1)((&psub1)->dp) = 0; | |||
118 | MP_DIGITS(&qsub1)((&qsub1)->dp) = 0; | |||
119 | MP_DIGITS(&tmp)((&tmp)->dp) = 0; | |||
120 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
121 | CHECK_MPI_OK(mp_init(&phi))if (0 > (err = mp_init(&phi))) goto cleanup; | |||
122 | CHECK_MPI_OK(mp_init(&psub1))if (0 > (err = mp_init(&psub1))) goto cleanup; | |||
123 | CHECK_MPI_OK(mp_init(&qsub1))if (0 > (err = mp_init(&qsub1))) goto cleanup; | |||
124 | CHECK_MPI_OK(mp_init(&tmp))if (0 > (err = mp_init(&tmp))) goto cleanup; | |||
125 | /* p and q must be distinct. */ | |||
126 | if (mp_cmp(p, q) == 0) { | |||
127 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NEED_RANDOM); | |||
128 | rv = SECFailure; | |||
129 | goto cleanup; | |||
130 | } | |||
131 | /* 1. Compute n = p*q */ | |||
132 | CHECK_MPI_OK(mp_mul(p, q, &n))if (0 > (err = mp_mul(p, q, &n))) goto cleanup; | |||
133 | /* verify that the modulus has the desired number of bits */ | |||
134 | if ((unsigned)mpl_significant_bits(&n) != keySizeInBits) { | |||
135 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NEED_RANDOM); | |||
136 | rv = SECFailure; | |||
137 | goto cleanup; | |||
138 | } | |||
139 | ||||
140 | /* at least one exponent must be given */ | |||
141 | PORT_Assert(!(needPublicExponent && needPrivateExponent))((!(needPublicExponent && needPrivateExponent))?((void )0):PR_Assert_stub("!(needPublicExponent && needPrivateExponent)" ,"rsa.c",141)); | |||
142 | ||||
143 | /* 2. Compute phi = (p-1)*(q-1) */ | |||
144 | CHECK_MPI_OK(mp_sub_d(p, 1, &psub1))if (0 > (err = mp_sub_d(p, 1, &psub1))) goto cleanup; | |||
145 | CHECK_MPI_OK(mp_sub_d(q, 1, &qsub1))if (0 > (err = mp_sub_d(q, 1, &qsub1))) goto cleanup; | |||
146 | if (needPublicExponent || needPrivateExponent) { | |||
147 | CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi))if (0 > (err = mp_lcm(&psub1, &qsub1, &phi))) goto cleanup; | |||
148 | /* 3. Compute d = e**-1 mod(phi) */ | |||
149 | /* or e = d**-1 mod(phi) as necessary */ | |||
150 | if (needPublicExponent) { | |||
151 | err = mp_invmod(d, &phi, e); | |||
152 | } else { | |||
153 | err = mp_invmod(e, &phi, d); | |||
154 | } | |||
155 | } else { | |||
156 | err = MP_OKAY0; | |||
157 | } | |||
158 | /* Verify that phi(n) and e have no common divisors */ | |||
159 | if (err != MP_OKAY0) { | |||
160 | if (err == MP_UNDEF-5) { | |||
161 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NEED_RANDOM); | |||
162 | err = MP_OKAY0; /* to keep PORT_SetError from being called again */ | |||
163 | rv = SECFailure; | |||
164 | } | |||
165 | goto cleanup; | |||
166 | } | |||
167 | ||||
168 | /* 4. Compute exponent1 = d mod (p-1) */ | |||
169 | CHECK_MPI_OK(mp_mod(d, &psub1, &tmp))if (0 > (err = mp_mod(d, &psub1, &tmp))) goto cleanup; | |||
170 | MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena)do { int mpintLen = mp_unsigned_octet_size(&tmp); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub( key->arena, (&key->exponent1), mpintLen); if ((& key->exponent1)->data == ((void*)0)) { err = -2; goto cleanup ; } err = mp_to_unsigned_octets(&tmp, (&key->exponent1 )->data, (&key->exponent1)->len); if (err < 0 ) goto cleanup; else err = 0; } while (0); | |||
171 | /* 5. Compute exponent2 = d mod (q-1) */ | |||
172 | CHECK_MPI_OK(mp_mod(d, &qsub1, &tmp))if (0 > (err = mp_mod(d, &qsub1, &tmp))) goto cleanup; | |||
173 | MPINT_TO_SECITEM(&tmp, &key->exponent2, key->arena)do { int mpintLen = mp_unsigned_octet_size(&tmp); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub( key->arena, (&key->exponent2), mpintLen); if ((& key->exponent2)->data == ((void*)0)) { err = -2; goto cleanup ; } err = mp_to_unsigned_octets(&tmp, (&key->exponent2 )->data, (&key->exponent2)->len); if (err < 0 ) goto cleanup; else err = 0; } while (0); | |||
174 | /* 6. Compute coefficient = q**-1 mod p */ | |||
175 | CHECK_MPI_OK(mp_invmod(q, p, &tmp))if (0 > (err = mp_invmod(q, p, &tmp))) goto cleanup; | |||
176 | MPINT_TO_SECITEM(&tmp, &key->coefficient, key->arena)do { int mpintLen = mp_unsigned_octet_size(&tmp); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub( key->arena, (&key->coefficient), mpintLen); if ((& key->coefficient)->data == ((void*)0)) { err = -2; goto cleanup; } err = mp_to_unsigned_octets(&tmp, (&key-> coefficient)->data, (&key->coefficient)->len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
177 | ||||
178 | /* copy our calculated results, overwrite what is there */ | |||
179 | key->modulus.data = NULL((void*)0); | |||
180 | MPINT_TO_SECITEM(&n, &key->modulus, key->arena)do { int mpintLen = mp_unsigned_octet_size(&n); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub( key->arena, (&key->modulus), mpintLen); if ((&key ->modulus)->data == ((void*)0)) { err = -2; goto cleanup ; } err = mp_to_unsigned_octets(&n, (&key->modulus )->data, (&key->modulus)->len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
181 | key->privateExponent.data = NULL((void*)0); | |||
182 | MPINT_TO_SECITEM(d, &key->privateExponent, key->arena)do { int mpintLen = mp_unsigned_octet_size(d); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub(key-> arena, (&key->privateExponent), mpintLen); if ((&key ->privateExponent)->data == ((void*)0)) { err = -2; goto cleanup; } err = mp_to_unsigned_octets(d, (&key->privateExponent )->data, (&key->privateExponent)->len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
183 | key->publicExponent.data = NULL((void*)0); | |||
184 | MPINT_TO_SECITEM(e, &key->publicExponent, key->arena)do { int mpintLen = mp_unsigned_octet_size(e); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub(key-> arena, (&key->publicExponent), mpintLen); if ((&key ->publicExponent)->data == ((void*)0)) { err = -2; goto cleanup; } err = mp_to_unsigned_octets(e, (&key->publicExponent )->data, (&key->publicExponent)->len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
185 | key->prime1.data = NULL((void*)0); | |||
186 | MPINT_TO_SECITEM(p, &key->prime1, key->arena)do { int mpintLen = mp_unsigned_octet_size(p); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub(key-> arena, (&key->prime1), mpintLen); if ((&key->prime1 )->data == ((void*)0)) { err = -2; goto cleanup; } err = mp_to_unsigned_octets (p, (&key->prime1)->data, (&key->prime1)-> len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
187 | key->prime2.data = NULL((void*)0); | |||
188 | MPINT_TO_SECITEM(q, &key->prime2, key->arena)do { int mpintLen = mp_unsigned_octet_size(q); if (mpintLen <= 0) { err = -3; goto cleanup; } SECITEM_AllocItem_stub(key-> arena, (&key->prime2), mpintLen); if ((&key->prime2 )->data == ((void*)0)) { err = -2; goto cleanup; } err = mp_to_unsigned_octets (q, (&key->prime2)->data, (&key->prime2)-> len); if (err < 0) goto cleanup; else err = 0; } while (0); | |||
189 | cleanup: | |||
190 | mp_clear(&n); | |||
191 | mp_clear(&phi); | |||
192 | mp_clear(&psub1); | |||
193 | mp_clear(&qsub1); | |||
194 | mp_clear(&tmp); | |||
195 | if (err) { | |||
196 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
197 | rv = SECFailure; | |||
198 | } | |||
199 | return rv; | |||
200 | } | |||
201 | ||||
202 | SECStatus | |||
203 | generate_prime(mp_int *prime, int primeLen) | |||
204 | { | |||
205 | mp_err err = MP_OKAY0; | |||
206 | SECStatus rv = SECSuccess; | |||
207 | int piter; | |||
208 | unsigned char *pb = NULL((void*)0); | |||
209 | pb = PORT_AllocPORT_Alloc_stub(primeLen); | |||
210 | if (!pb) { | |||
211 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
212 | goto cleanup; | |||
213 | } | |||
214 | for (piter = 0; piter < MAX_PRIME_GEN_ATTEMPTS10; piter++) { | |||
215 | CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(pb, primeLen))if (SECSuccess != (rv = RNG_GenerateGlobalRandomBytes(pb, primeLen ))) goto cleanup; | |||
216 | pb[0] |= 0xC0; /* set two high-order bits */ | |||
217 | pb[primeLen - 1] |= 0x01; /* set low-order bit */ | |||
218 | CHECK_MPI_OK(mp_read_unsigned_octets(prime, pb, primeLen))if (0 > (err = mp_read_unsigned_octets(prime, pb, primeLen ))) goto cleanup; | |||
219 | err = mpp_make_prime_secure(prime, primeLen * 8, PR_FALSE0); | |||
220 | if (err != MP_NO-1) | |||
221 | goto cleanup; | |||
222 | /* keep going while err == MP_NO */ | |||
223 | } | |||
224 | cleanup: | |||
225 | if (pb) | |||
226 | PORT_ZFreePORT_ZFree_stub(pb, primeLen); | |||
227 | if (err) { | |||
228 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
229 | rv = SECFailure; | |||
230 | } | |||
231 | return rv; | |||
232 | } | |||
233 | ||||
234 | /* | |||
235 | * make sure the key components meet fips186 requirements. | |||
236 | */ | |||
237 | static PRBool | |||
238 | rsa_fips186_verify(mp_int *p, mp_int *q, mp_int *d, int keySizeInBits) | |||
239 | { | |||
240 | mp_int pq_diff; | |||
241 | mp_err err = MP_OKAY0; | |||
242 | PRBool ret = PR_FALSE0; | |||
243 | ||||
244 | if (keySizeInBits < 250) { | |||
245 | /* not a valid FIPS length, no point in our other tests */ | |||
246 | /* if you are here, and in FIPS mode, you are outside the security | |||
247 | * policy */ | |||
248 | return PR_TRUE1; | |||
249 | } | |||
250 | ||||
251 | /* p & q are already known to be greater then sqrt(2)*2^(keySize/2-1) */ | |||
252 | /* we also know that gcd(p-1,e) = 1 and gcd(q-1,e) = 1 because the | |||
253 | * mp_invmod() function will fail. */ | |||
254 | /* now check p-q > 2^(keysize/2-100) */ | |||
255 | MP_DIGITS(&pq_diff)((&pq_diff)->dp) = 0; | |||
256 | CHECK_MPI_OK(mp_init(&pq_diff))if (0 > (err = mp_init(&pq_diff))) goto cleanup; | |||
257 | /* NSS always has p > q, so we know pq_diff is positive */ | |||
258 | CHECK_MPI_OK(mp_sub(p, q, &pq_diff))if (0 > (err = mp_sub(p, q, &pq_diff))) goto cleanup; | |||
259 | if ((unsigned)mpl_significant_bits(&pq_diff) < (keySizeInBits / 2 - 100)) { | |||
260 | goto cleanup; | |||
261 | } | |||
262 | /* now verify d is large enough*/ | |||
263 | if ((unsigned)mpl_significant_bits(d) < (keySizeInBits / 2)) { | |||
264 | goto cleanup; | |||
265 | } | |||
266 | ret = PR_TRUE1; | |||
267 | ||||
268 | cleanup: | |||
269 | mp_clear(&pq_diff); | |||
270 | return ret; | |||
271 | } | |||
272 | ||||
273 | /* | |||
274 | ** Generate and return a new RSA public and private key. | |||
275 | ** Both keys are encoded in a single RSAPrivateKey structure. | |||
276 | ** "cx" is the random number generator context | |||
277 | ** "keySizeInBits" is the size of the key to be generated, in bits. | |||
278 | ** 512, 1024, etc. | |||
279 | ** "publicExponent" when not NULL is a pointer to some data that | |||
280 | ** represents the public exponent to use. The data is a byte | |||
281 | ** encoded integer, in "big endian" order. | |||
282 | */ | |||
283 | RSAPrivateKey * | |||
284 | RSA_NewKey(int keySizeInBits, SECItem *publicExponent) | |||
285 | { | |||
286 | unsigned int primeLen; | |||
287 | mp_int p = { 0, 0, 0, NULL((void*)0) }; | |||
288 | mp_int q = { 0, 0, 0, NULL((void*)0) }; | |||
289 | mp_int e = { 0, 0, 0, NULL((void*)0) }; | |||
290 | mp_int d = { 0, 0, 0, NULL((void*)0) }; | |||
291 | int kiter; | |||
292 | int max_attempts; | |||
293 | mp_err err = MP_OKAY0; | |||
294 | SECStatus rv = SECSuccess; | |||
295 | int prerr = 0; | |||
296 | RSAPrivateKey *key = NULL((void*)0); | |||
297 | PLArenaPool *arena = NULL((void*)0); | |||
298 | /* Require key size to be a multiple of 16 bits. */ | |||
299 | if (!publicExponent || keySizeInBits % 16 != 0 || | |||
300 | BAD_RSA_KEY_SIZE((unsigned int)keySizeInBits / 8, publicExponent->len)((publicExponent->len) > ((unsigned int)keySizeInBits / 8) || ((unsigned int)keySizeInBits / 8) > 16384 / 8 || (publicExponent ->len) > 64 / 8)) { | |||
301 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
302 | return NULL((void*)0); | |||
303 | } | |||
304 | /* 1. Set the public exponent and check if it's uneven and greater than 2.*/ | |||
305 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
306 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
307 | SECITEM_TO_MPINT(*publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (*publicExponent ).data, (*publicExponent).len))) goto cleanup; | |||
308 | if (mp_iseven(&e) || !(mp_cmp_d(&e, 2) > 0)) { | |||
309 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
310 | goto cleanup; | |||
311 | } | |||
312 | #ifndef NSS_FIPS_DISABLED | |||
313 | /* Check that the exponent is not smaller than 65537 */ | |||
314 | if (mp_cmp_d(&e, 0x10001) < 0) { | |||
315 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
316 | goto cleanup; | |||
317 | } | |||
318 | #endif | |||
319 | ||||
320 | /* 2. Allocate arena & key */ | |||
321 | arena = PORT_NewArenaPORT_NewArena_stub(NSS_FREEBL_DEFAULT_CHUNKSIZE2048); | |||
322 | if (!arena) { | |||
323 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
324 | goto cleanup; | |||
325 | } | |||
326 | key = PORT_ArenaZNew(arena, RSAPrivateKey)(RSAPrivateKey *)PORT_ArenaZAlloc_stub(arena, sizeof(RSAPrivateKey )); | |||
327 | if (!key) { | |||
328 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
329 | goto cleanup; | |||
330 | } | |||
331 | key->arena = arena; | |||
332 | /* length of primes p and q (in bytes) */ | |||
333 | primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE8); | |||
334 | MP_DIGITS(&p)((&p)->dp) = 0; | |||
335 | MP_DIGITS(&q)((&q)->dp) = 0; | |||
336 | MP_DIGITS(&d)((&d)->dp) = 0; | |||
337 | CHECK_MPI_OK(mp_init(&p))if (0 > (err = mp_init(&p))) goto cleanup; | |||
338 | CHECK_MPI_OK(mp_init(&q))if (0 > (err = mp_init(&q))) goto cleanup; | |||
339 | CHECK_MPI_OK(mp_init(&d))if (0 > (err = mp_init(&d))) goto cleanup; | |||
340 | /* 3. Set the version number (PKCS1 v1.5 says it should be zero) */ | |||
341 | SECITEM_AllocItemSECITEM_AllocItem_stub(arena, &key->version, 1); | |||
342 | key->version.data[0] = 0; | |||
343 | ||||
344 | kiter = 0; | |||
345 | max_attempts = 5 * (keySizeInBits / 2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */ | |||
346 | do { | |||
347 | PORT_SetErrorPORT_SetError_stub(0); | |||
348 | CHECK_SEC_OK(generate_prime(&p, primeLen))if (SECSuccess != (rv = generate_prime(&p, primeLen))) goto cleanup; | |||
349 | CHECK_SEC_OK(generate_prime(&q, primeLen))if (SECSuccess != (rv = generate_prime(&q, primeLen))) goto cleanup; | |||
350 | /* Assure p > q */ | |||
351 | /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any | |||
352 | * implementation optimization that requires p > q. We can remove | |||
353 | * this code in the future. | |||
354 | */ | |||
355 | if (mp_cmp(&p, &q) < 0) | |||
356 | mp_exch(&p, &q); | |||
357 | /* Attempt to use these primes to generate a key */ | |||
358 | rv = rsa_build_from_primes(&p, &q, | |||
359 | &e, PR_FALSE0, /* needPublicExponent=false */ | |||
360 | &d, PR_TRUE1, /* needPrivateExponent=true */ | |||
361 | key, keySizeInBits); | |||
362 | if (rv == SECSuccess) { | |||
363 | if (rsa_fips186_verify(&p, &q, &d, keySizeInBits)) { | |||
364 | break; | |||
365 | } | |||
366 | prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */ | |||
367 | } else { | |||
368 | prerr = PORT_GetErrorPORT_GetError_stub(); | |||
369 | } | |||
370 | kiter++; | |||
371 | /* loop until have primes */ | |||
372 | } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts); | |||
373 | ||||
374 | cleanup: | |||
375 | mp_clear(&p); | |||
376 | mp_clear(&q); | |||
377 | mp_clear(&e); | |||
378 | mp_clear(&d); | |||
379 | if (err) { | |||
380 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
381 | rv = SECFailure; | |||
382 | } | |||
383 | if (rv && arena) { | |||
384 | PORT_FreeArenaPORT_FreeArena_stub(arena, PR_TRUE1); | |||
385 | key = NULL((void*)0); | |||
386 | } | |||
387 | return key; | |||
388 | } | |||
389 | ||||
390 | mp_err | |||
391 | rsa_is_prime(mp_int *p) | |||
392 | { | |||
393 | int res; | |||
394 | ||||
395 | /* run a Fermat test */ | |||
396 | res = mpp_fermat(p, 2); | |||
397 | if (res != MP_OKAY0) { | |||
398 | return res; | |||
399 | } | |||
400 | ||||
401 | /* If that passed, run some Miller-Rabin tests */ | |||
402 | res = mpp_pprime_secure(p, 2); | |||
403 | return res; | |||
404 | } | |||
405 | ||||
406 | /* | |||
407 | * Factorize a RSA modulus n into p and q by using the exponents e and d. | |||
408 | * | |||
409 | * In: e, d, n | |||
410 | * Out: p, q | |||
411 | * | |||
412 | * See Handbook of Applied Cryptography, 8.2.2(i). | |||
413 | * | |||
414 | * The algorithm is probabilistic, it is run 64 times and each run has a 50% | |||
415 | * chance of succeeding with a runtime of O(log(e*d)). | |||
416 | * | |||
417 | * The returned p might be smaller than q. | |||
418 | */ | |||
419 | static mp_err | |||
420 | rsa_factorize_n_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q, | |||
421 | mp_int *n) | |||
422 | { | |||
423 | /* lambda is the private modulus: e*d = 1 mod lambda */ | |||
424 | /* so: e*d - 1 = k*lambda = t*2^s where t is odd */ | |||
425 | mp_int klambda; | |||
426 | mp_int t, onetwentyeight; | |||
427 | unsigned long s = 0; | |||
428 | unsigned long i; | |||
429 | ||||
430 | /* cand = a^(t * 2^i) mod n, next_cand = a^(t * 2^(i+1)) mod n */ | |||
431 | mp_int a; | |||
432 | mp_int cand; | |||
433 | mp_int next_cand; | |||
434 | ||||
435 | mp_int n_minus_one; | |||
436 | mp_err err = MP_OKAY0; | |||
437 | ||||
438 | MP_DIGITS(&klambda)((&klambda)->dp) = 0; | |||
439 | MP_DIGITS(&t)((&t)->dp) = 0; | |||
440 | MP_DIGITS(&a)((&a)->dp) = 0; | |||
441 | MP_DIGITS(&cand)((&cand)->dp) = 0; | |||
442 | MP_DIGITS(&n_minus_one)((&n_minus_one)->dp) = 0; | |||
443 | MP_DIGITS(&next_cand)((&next_cand)->dp) = 0; | |||
444 | MP_DIGITS(&onetwentyeight)((&onetwentyeight)->dp) = 0; | |||
445 | CHECK_MPI_OK(mp_init(&klambda))if (0 > (err = mp_init(&klambda))) goto cleanup; | |||
446 | CHECK_MPI_OK(mp_init(&t))if (0 > (err = mp_init(&t))) goto cleanup; | |||
447 | CHECK_MPI_OK(mp_init(&a))if (0 > (err = mp_init(&a))) goto cleanup; | |||
448 | CHECK_MPI_OK(mp_init(&cand))if (0 > (err = mp_init(&cand))) goto cleanup; | |||
449 | CHECK_MPI_OK(mp_init(&n_minus_one))if (0 > (err = mp_init(&n_minus_one))) goto cleanup; | |||
450 | CHECK_MPI_OK(mp_init(&next_cand))if (0 > (err = mp_init(&next_cand))) goto cleanup; | |||
451 | CHECK_MPI_OK(mp_init(&onetwentyeight))if (0 > (err = mp_init(&onetwentyeight))) goto cleanup; | |||
452 | ||||
453 | mp_set_int(&onetwentyeight, 128); | |||
454 | ||||
455 | /* calculate k*lambda = e*d - 1 */ | |||
456 | CHECK_MPI_OK(mp_mul(e, d, &klambda))if (0 > (err = mp_mul(e, d, &klambda))) goto cleanup; | |||
457 | CHECK_MPI_OK(mp_sub_d(&klambda, 1, &klambda))if (0 > (err = mp_sub_d(&klambda, 1, &klambda))) goto cleanup; | |||
458 | ||||
459 | /* factorize klambda into t*2^s */ | |||
460 | CHECK_MPI_OK(mp_copy(&klambda, &t))if (0 > (err = mp_copy(&klambda, &t))) goto cleanup; | |||
461 | while (mpp_divis_d(&t, 2) == MP_YES0) { | |||
462 | CHECK_MPI_OK(mp_div_2(&t, &t))if (0 > (err = mp_div_2(&t, &t))) goto cleanup; | |||
463 | s += 1; | |||
464 | } | |||
465 | ||||
466 | /* precompute n_minus_one = n - 1 */ | |||
467 | CHECK_MPI_OK(mp_copy(n, &n_minus_one))if (0 > (err = mp_copy(n, &n_minus_one))) goto cleanup; | |||
468 | CHECK_MPI_OK(mp_sub_d(&n_minus_one, 1, &n_minus_one))if (0 > (err = mp_sub_d(&n_minus_one, 1, &n_minus_one ))) goto cleanup; | |||
469 | ||||
470 | /* pick random bases a, each one has a 50% leading to a factorization */ | |||
471 | CHECK_MPI_OK(mp_set_int(&a, 2))if (0 > (err = mp_set_int(&a, 2))) goto cleanup; | |||
472 | /* The following is equivalent to for (a=2, a <= 128, a+=2) */ | |||
473 | while (mp_cmp(&a, &onetwentyeight) <= 0) { | |||
474 | /* compute the base cand = a^(t * 2^0) [i = 0] */ | |||
475 | CHECK_MPI_OK(mp_exptmod(&a, &t, n, &cand))if (0 > (err = mp_exptmod(&a, &t, n, &cand))) goto cleanup; | |||
476 | ||||
477 | for (i = 0; i < s; i++) { | |||
478 | /* condition 1: skip the base if we hit a trivial factor of n */ | |||
479 | if (mp_cmp(&cand, &n_minus_one) == 0 || mp_cmp_d(&cand, 1) == 0) { | |||
480 | break; | |||
481 | } | |||
482 | ||||
483 | /* increase i in a^(t * 2^i) by squaring the number */ | |||
484 | CHECK_MPI_OK(mp_exptmod_d(&cand, 2, n, &next_cand))if (0 > (err = mp_exptmod_d(&cand, 2, n, &next_cand ))) goto cleanup; | |||
485 | ||||
486 | /* condition 2: a^(t * 2^(i+1)) = 1 mod n */ | |||
487 | if (mp_cmp_d(&next_cand, 1) == 0) { | |||
488 | /* conditions verified, gcd(a^(t * 2^i) - 1, n) is a factor */ | |||
489 | CHECK_MPI_OK(mp_sub_d(&cand, 1, &cand))if (0 > (err = mp_sub_d(&cand, 1, &cand))) goto cleanup; | |||
490 | CHECK_MPI_OK(mp_gcd(&cand, n, p))if (0 > (err = mp_gcd(&cand, n, p))) goto cleanup; | |||
491 | if (mp_cmp_d(p, 1) == 0) { | |||
492 | CHECK_MPI_OK(mp_add_d(&cand, 1, &cand))if (0 > (err = mp_add_d(&cand, 1, &cand))) goto cleanup; | |||
493 | break; | |||
494 | } | |||
495 | CHECK_MPI_OK(mp_div(n, p, q, NULL))if (0 > (err = mp_div(n, p, q, ((void*)0)))) goto cleanup; | |||
496 | goto cleanup; | |||
497 | } | |||
498 | CHECK_MPI_OK(mp_copy(&next_cand, &cand))if (0 > (err = mp_copy(&next_cand, &cand))) goto cleanup; | |||
499 | } | |||
500 | ||||
501 | CHECK_MPI_OK(mp_add_d(&a, 2, &a))if (0 > (err = mp_add_d(&a, 2, &a))) goto cleanup; | |||
502 | } | |||
503 | ||||
504 | /* if we reach here it's likely (2^64 - 1 / 2^64) that d is wrong */ | |||
505 | err = MP_RANGE-3; | |||
506 | ||||
507 | cleanup: | |||
508 | mp_clear(&klambda); | |||
509 | mp_clear(&t); | |||
510 | mp_clear(&a); | |||
511 | mp_clear(&cand); | |||
512 | mp_clear(&n_minus_one); | |||
513 | mp_clear(&next_cand); | |||
514 | mp_clear(&onetwentyeight); | |||
515 | return err; | |||
516 | } | |||
517 | ||||
518 | /* | |||
519 | * Try to find the two primes based on 2 exponents plus a prime. | |||
520 | * | |||
521 | * In: e, d and p. | |||
522 | * Out: p,q. | |||
523 | * | |||
524 | * Step 1, Since d = e**-1 mod phi, we know that d*e == 1 mod phi, or | |||
525 | * d*e = 1+k*phi, or d*e-1 = k*phi. since d is less than phi and e is | |||
526 | * usually less than d, then k must be an integer between e-1 and 1 | |||
527 | * (probably on the order of e). | |||
528 | * Step 1a, We can divide k*phi by prime-1 and get k*(q-1). This will reduce | |||
529 | * the size of our division through the rest of the loop. | |||
530 | * Step 2, Loop through the values k=e-1 to 1 looking for k. k should be on | |||
531 | * the order or e, and e is typically small. This may take a while for | |||
532 | * a large random e. We are looking for a k that divides kphi | |||
533 | * evenly. Once we find a k that divides kphi evenly, we assume it | |||
534 | * is the true k. It's possible this k is not the 'true' k but has | |||
535 | * swapped factors of p-1 and/or q-1. Because of this, we | |||
536 | * tentatively continue Steps 3-6 inside this loop, and may return looking | |||
537 | * for another k on failure. | |||
538 | * Step 3, Calculate our tentative phi=kphi/k. Note: real phi is (p-1)*(q-1). | |||
539 | * Step 4a, kphi is k*(q-1), so phi is our tenative q-1. q = phi+1. | |||
540 | * If k is correct, q should be the right length and prime. | |||
541 | * Step 4b, It's possible q-1 and k could have swapped factors. We now have a | |||
542 | * possible solution that meets our criteria. It may not be the only | |||
543 | * solution, however, so we keep looking. If we find more than one, | |||
544 | * we will fail since we cannot determine which is the correct | |||
545 | * solution, and returning the wrong modulus will compromise both | |||
546 | * moduli. If no other solution is found, we return the unique solution. | |||
547 | * | |||
548 | * This will return p & q. q may be larger than p in the case that p was given | |||
549 | * and it was the smaller prime. | |||
550 | */ | |||
551 | static mp_err | |||
552 | rsa_get_prime_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q, | |||
553 | mp_int *n, unsigned int keySizeInBits) | |||
554 | { | |||
555 | mp_int kphi; /* k*phi */ | |||
556 | mp_int k; /* current guess at 'k' */ | |||
557 | mp_int phi; /* (p-1)(q-1) */ | |||
558 | mp_int r; /* remainder */ | |||
559 | mp_int tmp; /* p-1 if p is given */ | |||
560 | mp_err err = MP_OKAY0; | |||
561 | unsigned int order_k; | |||
562 | ||||
563 | MP_DIGITS(&kphi)((&kphi)->dp) = 0; | |||
564 | MP_DIGITS(&phi)((&phi)->dp) = 0; | |||
565 | MP_DIGITS(&k)((&k)->dp) = 0; | |||
566 | MP_DIGITS(&r)((&r)->dp) = 0; | |||
567 | MP_DIGITS(&tmp)((&tmp)->dp) = 0; | |||
568 | CHECK_MPI_OK(mp_init(&kphi))if (0 > (err = mp_init(&kphi))) goto cleanup; | |||
569 | CHECK_MPI_OK(mp_init(&phi))if (0 > (err = mp_init(&phi))) goto cleanup; | |||
570 | CHECK_MPI_OK(mp_init(&k))if (0 > (err = mp_init(&k))) goto cleanup; | |||
571 | CHECK_MPI_OK(mp_init(&r))if (0 > (err = mp_init(&r))) goto cleanup; | |||
572 | CHECK_MPI_OK(mp_init(&tmp))if (0 > (err = mp_init(&tmp))) goto cleanup; | |||
573 | ||||
574 | /* our algorithm looks for a factor k whose maximum size is dependent | |||
575 | * on the size of our smallest exponent, which had better be the public | |||
576 | * exponent (if it's the private, the key is vulnerable to a brute force | |||
577 | * attack). | |||
578 | * | |||
579 | * since our factor search is linear, we need to limit the maximum | |||
580 | * size of the public key. this should not be a problem normally, since | |||
581 | * public keys are usually small. | |||
582 | * | |||
583 | * if we want to handle larger public key sizes, we should have | |||
584 | * a version which tries to 'completely' factor k*phi (where completely | |||
585 | * means 'factor into primes, or composites with which are products of | |||
586 | * large primes). Once we have all the factors, we can sort them out and | |||
587 | * try different combinations to form our phi. The risk is if (p-1)/2, | |||
588 | * (q-1)/2, and k are all large primes. In any case if the public key | |||
589 | * is small (order of 20 some bits), then a linear search for k is | |||
590 | * manageable. | |||
591 | */ | |||
592 | if (mpl_significant_bits(e) > 23) { | |||
593 | err = MP_RANGE-3; | |||
594 | goto cleanup; | |||
595 | } | |||
596 | ||||
597 | /* calculate k*phi = e*d - 1 */ | |||
598 | CHECK_MPI_OK(mp_mul(e, d, &kphi))if (0 > (err = mp_mul(e, d, &kphi))) goto cleanup; | |||
599 | CHECK_MPI_OK(mp_sub_d(&kphi, 1, &kphi))if (0 > (err = mp_sub_d(&kphi, 1, &kphi))) goto cleanup; | |||
600 | ||||
601 | /* kphi is (e*d)-1, which is the same as k*(p-1)(q-1) | |||
602 | * d < (p-1)(q-1), therefor k must be less than e-1 | |||
603 | * We can narrow down k even more, though. Since p and q are odd and both | |||
604 | * have their high bit set, then we know that phi must be on order of | |||
605 | * keySizeBits. | |||
606 | */ | |||
607 | order_k = (unsigned)mpl_significant_bits(&kphi) - keySizeInBits; | |||
608 | ||||
609 | if (order_k <= 1) { | |||
610 | err = MP_RANGE-3; | |||
611 | goto cleanup; | |||
612 | } | |||
613 | ||||
614 | /* for (k=kinit; order(k) >= order_k; k--) { */ | |||
615 | /* k=kinit: k can't be bigger than kphi/2^(keySizeInBits -1) */ | |||
616 | CHECK_MPI_OK(mp_2expt(&k, keySizeInBits - 1))if (0 > (err = mp_2expt(&k, keySizeInBits - 1))) goto cleanup; | |||
617 | CHECK_MPI_OK(mp_div(&kphi, &k, &k, NULL))if (0 > (err = mp_div(&kphi, &k, &k, ((void*)0 )))) goto cleanup; | |||
618 | if (mp_cmp(&k, e) >= 0) { | |||
619 | /* also can't be bigger then e-1 */ | |||
620 | CHECK_MPI_OK(mp_sub_d(e, 1, &k))if (0 > (err = mp_sub_d(e, 1, &k))) goto cleanup; | |||
621 | } | |||
622 | ||||
623 | /* calculate our temp value */ | |||
624 | /* This saves recalculating this value when the k guess is wrong, which | |||
625 | * is reasonably frequent. */ | |||
626 | /* tmp = p-1 (used to calculate q-1= phi/tmp) */ | |||
627 | CHECK_MPI_OK(mp_sub_d(p, 1, &tmp))if (0 > (err = mp_sub_d(p, 1, &tmp))) goto cleanup; | |||
628 | CHECK_MPI_OK(mp_div(&kphi, &tmp, &kphi, &r))if (0 > (err = mp_div(&kphi, &tmp, &kphi, & r))) goto cleanup; | |||
629 | if (mp_cmp_z(&r) != 0) { | |||
630 | /* p-1 doesn't divide kphi, some parameter wasn't correct */ | |||
631 | err = MP_RANGE-3; | |||
632 | goto cleanup; | |||
633 | } | |||
634 | mp_zero(q); | |||
635 | /* kphi is now k*(q-1) */ | |||
636 | ||||
637 | /* rest of the for loop */ | |||
638 | for (; (err == MP_OKAY0) && (mpl_significant_bits(&k) >= order_k); | |||
639 | err = mp_sub_d(&k, 1, &k)) { | |||
640 | CHECK_MPI_OK(err)if (0 > (err = err)) goto cleanup; | |||
641 | /* looking for k as a factor of kphi */ | |||
642 | CHECK_MPI_OK(mp_div(&kphi, &k, &phi, &r))if (0 > (err = mp_div(&kphi, &k, &phi, &r) )) goto cleanup; | |||
643 | if (mp_cmp_z(&r) != 0) { | |||
644 | /* not a factor, try the next one */ | |||
645 | continue; | |||
646 | } | |||
647 | /* we have a possible phi, see if it works */ | |||
648 | if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits / 2) { | |||
649 | /* phi is not the right size */ | |||
650 | continue; | |||
651 | } | |||
652 | /* phi should be divisible by 2, since | |||
653 | * q is odd and phi=(q-1). */ | |||
654 | if (mpp_divis_d(&phi, 2) == MP_NO-1) { | |||
655 | /* phi is not divisible by 4 */ | |||
656 | continue; | |||
657 | } | |||
658 | /* we now have a candidate for the second prime */ | |||
659 | CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp))if (0 > (err = mp_add_d(&phi, 1, &tmp))) goto cleanup; | |||
660 | ||||
661 | /* check to make sure it is prime */ | |||
662 | err = rsa_is_prime(&tmp); | |||
663 | if (err != MP_OKAY0) { | |||
664 | if (err == MP_NO-1) { | |||
665 | /* No, then we still have the wrong phi */ | |||
666 | continue; | |||
667 | } | |||
668 | goto cleanup; | |||
669 | } | |||
670 | /* | |||
671 | * It is possible that we have the wrong phi if | |||
672 | * k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors). | |||
673 | * since our q_quess is prime, however. We have found a valid | |||
674 | * rsa key because: | |||
675 | * q is the correct order of magnitude. | |||
676 | * phi = (p-1)(q-1) where p and q are both primes. | |||
677 | * e*d mod phi = 1. | |||
678 | * There is no way to know from the info given if this is the | |||
679 | * original key. We never want to return the wrong key because if | |||
680 | * two moduli with the same factor is known, then euclid's gcd | |||
681 | * algorithm can be used to find that factor. Even though the | |||
682 | * caller didn't pass the original modulus, it doesn't mean the | |||
683 | * modulus wasn't known or isn't available somewhere. So to be safe | |||
684 | * if we can't be sure we have the right q, we don't return any. | |||
685 | * | |||
686 | * So to make sure we continue looking for other valid q's. If none | |||
687 | * are found, then we can safely return this one, otherwise we just | |||
688 | * fail */ | |||
689 | if (mp_cmp_z(q) != 0) { | |||
690 | /* this is the second valid q, don't return either, | |||
691 | * just fail */ | |||
692 | err = MP_RANGE-3; | |||
693 | break; | |||
694 | } | |||
695 | /* we only have one q so far, save it and if no others are found, | |||
696 | * it's safe to return it */ | |||
697 | CHECK_MPI_OK(mp_copy(&tmp, q))if (0 > (err = mp_copy(&tmp, q))) goto cleanup; | |||
698 | continue; | |||
699 | } | |||
700 | if ((unsigned)mpl_significant_bits(&k) < order_k) { | |||
701 | if (mp_cmp_z(q) == 0) { | |||
702 | /* If we get here, something was wrong with the parameters we | |||
703 | * were given */ | |||
704 | err = MP_RANGE-3; | |||
705 | } | |||
706 | } | |||
707 | cleanup: | |||
708 | mp_clear(&kphi); | |||
709 | mp_clear(&phi); | |||
710 | mp_clear(&k); | |||
711 | mp_clear(&r); | |||
712 | mp_clear(&tmp); | |||
713 | return err; | |||
714 | } | |||
715 | ||||
716 | /* | |||
717 | * take a private key with only a few elements and fill out the missing pieces. | |||
718 | * | |||
719 | * All the entries will be overwritten with data allocated out of the arena | |||
720 | * If no arena is supplied, one will be created. | |||
721 | * | |||
722 | * The following fields must be supplied in order for this function | |||
723 | * to succeed: | |||
724 | * one of either publicExponent or privateExponent | |||
725 | * two more of the following 5 parameters. | |||
726 | * modulus (n) | |||
727 | * prime1 (p) | |||
728 | * prime2 (q) | |||
729 | * publicExponent (e) | |||
730 | * privateExponent (d) | |||
731 | * | |||
732 | * NOTE: if only the publicExponent, privateExponent, and one prime is given, | |||
733 | * then there may be more than one RSA key that matches that combination. | |||
734 | * | |||
735 | * All parameters will be replaced in the key structure with new parameters | |||
736 | * Allocated out of the arena. There is no attempt to free the old structures. | |||
737 | * Prime1 will always be greater than prime2 (even if the caller supplies the | |||
738 | * smaller prime as prime1 or the larger prime as prime2). The parameters are | |||
739 | * not overwritten on failure. | |||
740 | * | |||
741 | * How it works: | |||
742 | * We can generate all the parameters from one of the exponents, plus the | |||
743 | * two primes. (rsa_build_key_from_primes) | |||
744 | * If we are given one of the exponents and both primes, we are done. | |||
745 | * If we are given one of the exponents, the modulus and one prime, we | |||
746 | * caclulate the second prime by dividing the modulus by the given | |||
747 | * prime, giving us an exponent and 2 primes. | |||
748 | * If we are given 2 exponents and one of the primes we calculate | |||
749 | * k*phi = d*e-1, where k is an integer less than d which | |||
750 | * divides d*e-1. We find factor k so we can isolate phi. | |||
751 | * phi = (p-1)(q-1) | |||
752 | * We can use phi to find the other prime as follows: | |||
753 | * q = (phi/(p-1)) + 1. We now have 2 primes and an exponent. | |||
754 | * (NOTE: if more then one prime meets this condition, the operation | |||
755 | * will fail. See comments elsewhere in this file about this). | |||
756 | * (rsa_get_prime_from_exponents) | |||
757 | * If we are given 2 exponents and the modulus we factor the modulus to | |||
758 | * get the 2 missing primes (rsa_factorize_n_from_exponents) | |||
759 | * | |||
760 | */ | |||
761 | SECStatus | |||
762 | RSA_PopulatePrivateKey(RSAPrivateKey *key) | |||
763 | { | |||
764 | PLArenaPool *arena = NULL((void*)0); | |||
765 | PRBool needPublicExponent = PR_TRUE1; | |||
766 | PRBool needPrivateExponent = PR_TRUE1; | |||
767 | PRBool hasModulus = PR_FALSE0; | |||
768 | unsigned int keySizeInBits = 0; | |||
769 | int prime_count = 0; | |||
770 | /* standard RSA nominclature */ | |||
771 | mp_int p, q, e, d, n; | |||
772 | /* remainder */ | |||
773 | mp_int r; | |||
774 | mp_err err = 0; | |||
775 | SECStatus rv = SECFailure; | |||
776 | ||||
777 | MP_DIGITS(&p)((&p)->dp) = 0; | |||
778 | MP_DIGITS(&q)((&q)->dp) = 0; | |||
779 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
780 | MP_DIGITS(&d)((&d)->dp) = 0; | |||
781 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
782 | MP_DIGITS(&r)((&r)->dp) = 0; | |||
783 | CHECK_MPI_OK(mp_init(&p))if (0 > (err = mp_init(&p))) goto cleanup; | |||
784 | CHECK_MPI_OK(mp_init(&q))if (0 > (err = mp_init(&q))) goto cleanup; | |||
785 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
786 | CHECK_MPI_OK(mp_init(&d))if (0 > (err = mp_init(&d))) goto cleanup; | |||
787 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
788 | CHECK_MPI_OK(mp_init(&r))if (0 > (err = mp_init(&r))) goto cleanup; | |||
789 | ||||
790 | /* if the key didn't already have an arena, create one. */ | |||
791 | if (key->arena == NULL((void*)0)) { | |||
792 | arena = PORT_NewArenaPORT_NewArena_stub(NSS_FREEBL_DEFAULT_CHUNKSIZE2048); | |||
793 | if (!arena) { | |||
794 | goto cleanup; | |||
795 | } | |||
796 | key->arena = arena; | |||
797 | } | |||
798 | ||||
799 | /* load up the known exponents */ | |||
800 | if (key->publicExponent.data) { | |||
801 | SECITEM_TO_MPINT(key->publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (key-> publicExponent).data, (key->publicExponent).len))) goto cleanup; | |||
802 | needPublicExponent = PR_FALSE0; | |||
803 | } | |||
804 | if (key->privateExponent.data) { | |||
805 | SECITEM_TO_MPINT(key->privateExponent, &d)if (0 > (err = mp_read_unsigned_octets((&d), (key-> privateExponent).data, (key->privateExponent).len))) goto cleanup; | |||
806 | needPrivateExponent = PR_FALSE0; | |||
807 | } | |||
808 | if (needPrivateExponent && needPublicExponent) { | |||
809 | /* Not enough information, we need at least one exponent */ | |||
810 | err = MP_BADARG-4; | |||
811 | goto cleanup; | |||
812 | } | |||
813 | ||||
814 | /* load up the known primes. If only one prime is given, it will be | |||
815 | * assigned 'p'. Once we have both primes, well make sure p is the larger. | |||
816 | * The value prime_count tells us howe many we have acquired. | |||
817 | */ | |||
818 | if (key->prime1.data) { | |||
819 | int primeLen = key->prime1.len; | |||
820 | if (key->prime1.data[0] == 0) { | |||
821 | primeLen--; | |||
822 | } | |||
823 | keySizeInBits = primeLen * 2 * PR_BITS_PER_BYTE8; | |||
824 | SECITEM_TO_MPINT(key->prime1, &p)if (0 > (err = mp_read_unsigned_octets((&p), (key-> prime1).data, (key->prime1).len))) goto cleanup; | |||
825 | prime_count++; | |||
826 | } | |||
827 | if (key->prime2.data) { | |||
828 | int primeLen = key->prime2.len; | |||
829 | if (key->prime2.data[0] == 0) { | |||
830 | primeLen--; | |||
831 | } | |||
832 | keySizeInBits = primeLen * 2 * PR_BITS_PER_BYTE8; | |||
833 | SECITEM_TO_MPINT(key->prime2, prime_count ? &q : &p)if (0 > (err = mp_read_unsigned_octets((prime_count ? & q : &p), (key->prime2).data, (key->prime2).len))) goto cleanup; | |||
834 | prime_count++; | |||
835 | } | |||
836 | /* load up the modulus */ | |||
837 | if (key->modulus.data) { | |||
838 | int modLen = key->modulus.len; | |||
839 | if (key->modulus.data[0] == 0) { | |||
840 | modLen--; | |||
841 | } | |||
842 | keySizeInBits = modLen * PR_BITS_PER_BYTE8; | |||
843 | SECITEM_TO_MPINT(key->modulus, &n)if (0 > (err = mp_read_unsigned_octets((&n), (key-> modulus).data, (key->modulus).len))) goto cleanup; | |||
844 | hasModulus = PR_TRUE1; | |||
845 | } | |||
846 | /* if we have the modulus and one prime, calculate the second. */ | |||
847 | if ((prime_count == 1) && (hasModulus)) { | |||
848 | if (mp_div(&n, &p, &q, &r) != MP_OKAY0 || mp_cmp_z(&r) != 0) { | |||
849 | /* p is not a factor or n, fail */ | |||
850 | err = MP_BADARG-4; | |||
851 | goto cleanup; | |||
852 | } | |||
853 | prime_count++; | |||
854 | } | |||
855 | ||||
856 | /* If we didn't have enough primes try to calculate the primes from | |||
857 | * the exponents */ | |||
858 | if (prime_count < 2) { | |||
859 | /* if we don't have at least 2 primes at this point, then we need both | |||
860 | * exponents and one prime or a modulus*/ | |||
861 | if (!needPublicExponent && !needPrivateExponent && | |||
862 | (prime_count > 0)) { | |||
863 | CHECK_MPI_OK(rsa_get_prime_from_exponents(&e, &d, &p, &q, &n,if (0 > (err = rsa_get_prime_from_exponents(&e, &d , &p, &q, &n, keySizeInBits))) goto cleanup | |||
864 | keySizeInBits))if (0 > (err = rsa_get_prime_from_exponents(&e, &d , &p, &q, &n, keySizeInBits))) goto cleanup; | |||
865 | } else if (!needPublicExponent && !needPrivateExponent && hasModulus) { | |||
866 | CHECK_MPI_OK(rsa_factorize_n_from_exponents(&e, &d, &p, &q, &n))if (0 > (err = rsa_factorize_n_from_exponents(&e, & d, &p, &q, &n))) goto cleanup; | |||
867 | } else { | |||
868 | /* not enough given parameters to get both primes */ | |||
869 | err = MP_BADARG-4; | |||
870 | goto cleanup; | |||
871 | } | |||
872 | } | |||
873 | ||||
874 | /* Assure p > q */ | |||
875 | /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any | |||
876 | * implementation optimization that requires p > q. We can remove | |||
877 | * this code in the future. | |||
878 | */ | |||
879 | if (mp_cmp(&p, &q) < 0) | |||
880 | mp_exch(&p, &q); | |||
881 | ||||
882 | /* we now have our 2 primes and at least one exponent, we can fill | |||
883 | * in the key */ | |||
884 | rv = rsa_build_from_primes(&p, &q, | |||
885 | &e, needPublicExponent, | |||
886 | &d, needPrivateExponent, | |||
887 | key, keySizeInBits); | |||
888 | cleanup: | |||
889 | mp_clear(&p); | |||
890 | mp_clear(&q); | |||
891 | mp_clear(&e); | |||
892 | mp_clear(&d); | |||
893 | mp_clear(&n); | |||
894 | mp_clear(&r); | |||
895 | if (err) { | |||
896 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
897 | rv = SECFailure; | |||
898 | } | |||
899 | if (rv && arena) { | |||
900 | PORT_FreeArenaPORT_FreeArena_stub(arena, PR_TRUE1); | |||
901 | key->arena = NULL((void*)0); | |||
902 | } | |||
903 | return rv; | |||
904 | } | |||
905 | ||||
906 | static unsigned int | |||
907 | rsa_modulusLen(SECItem *modulus) | |||
908 | { | |||
909 | if (modulus->len == 0) { | |||
910 | return 0; | |||
911 | }; | |||
912 | unsigned char byteZero = modulus->data[0]; | |||
913 | unsigned int modLen = modulus->len - !byteZero; | |||
914 | return modLen; | |||
915 | } | |||
916 | ||||
917 | /* | |||
918 | ** Perform a raw public-key operation | |||
919 | ** Length of input and output buffers are equal to key's modulus len. | |||
920 | */ | |||
921 | SECStatus | |||
922 | RSA_PublicKeyOp(RSAPublicKey *key, | |||
923 | unsigned char *output, | |||
924 | const unsigned char *input) | |||
925 | { | |||
926 | unsigned int modLen, expLen, offset; | |||
927 | mp_int n, e, m, c; | |||
928 | mp_err err = MP_OKAY0; | |||
929 | SECStatus rv = SECSuccess; | |||
930 | if (!key || !output || !input) { | |||
931 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
932 | return SECFailure; | |||
933 | } | |||
934 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
935 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
936 | MP_DIGITS(&m)((&m)->dp) = 0; | |||
937 | MP_DIGITS(&c)((&c)->dp) = 0; | |||
938 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
939 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
940 | CHECK_MPI_OK(mp_init(&m))if (0 > (err = mp_init(&m))) goto cleanup; | |||
941 | CHECK_MPI_OK(mp_init(&c))if (0 > (err = mp_init(&c))) goto cleanup; | |||
942 | modLen = rsa_modulusLen(&key->modulus); | |||
943 | expLen = rsa_modulusLen(&key->publicExponent); | |||
944 | ||||
945 | if (modLen == 0) { | |||
946 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
947 | rv = SECFailure; | |||
948 | goto cleanup; | |||
949 | } | |||
950 | ||||
951 | /* 1. Obtain public key (n, e) */ | |||
952 | if (BAD_RSA_KEY_SIZE(modLen, expLen)((expLen) > (modLen) || (modLen) > 16384 / 8 || (expLen ) > 64 / 8)) { | |||
953 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_KEY); | |||
954 | rv = SECFailure; | |||
955 | goto cleanup; | |||
956 | } | |||
957 | SECITEM_TO_MPINT(key->modulus, &n)if (0 > (err = mp_read_unsigned_octets((&n), (key-> modulus).data, (key->modulus).len))) goto cleanup; | |||
958 | SECITEM_TO_MPINT(key->publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (key-> publicExponent).data, (key->publicExponent).len))) goto cleanup; | |||
959 | if (e.used > n.used) { | |||
960 | /* exponent should not be greater than modulus */ | |||
961 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_KEY); | |||
962 | rv = SECFailure; | |||
963 | goto cleanup; | |||
964 | } | |||
965 | /* 2. check input out of range (needs to be in range [0..n-1]) */ | |||
966 | offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */ | |||
967 | if (memcmp(input, key->modulus.data + offset, modLen) >= 0) { | |||
968 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INPUT_LEN); | |||
969 | rv = SECFailure; | |||
970 | goto cleanup; | |||
971 | } | |||
972 | /* 2 bis. Represent message as integer in range [0..n-1] */ | |||
973 | CHECK_MPI_OK(mp_read_unsigned_octets(&m, input, modLen))if (0 > (err = mp_read_unsigned_octets(&m, input, modLen ))) goto cleanup; | |||
974 | /* 3. Compute c = m**e mod n */ | |||
975 | #ifdef USE_MPI_EXPT_D | |||
976 | /* XXX see which is faster */ | |||
977 | if (MP_USED(&e)((&e)->used) == 1) { | |||
978 | CHECK_MPI_OK(mp_exptmod_d(&m, MP_DIGIT(&e, 0), &n, &c))if (0 > (err = mp_exptmod_d(&m, (&e)->dp[(0)], & n, &c))) goto cleanup; | |||
979 | } else | |||
980 | #endif | |||
981 | CHECK_MPI_OK(mp_exptmod(&m, &e, &n, &c))if (0 > (err = mp_exptmod(&m, &e, &n, &c)) ) goto cleanup; | |||
982 | /* 4. result c is ciphertext */ | |||
983 | err = mp_to_fixlen_octets(&c, output, modLen); | |||
984 | if (err >= 0) | |||
985 | err = MP_OKAY0; | |||
986 | cleanup: | |||
987 | mp_clear(&n); | |||
988 | mp_clear(&e); | |||
989 | mp_clear(&m); | |||
990 | mp_clear(&c); | |||
991 | if (err) { | |||
992 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
993 | rv = SECFailure; | |||
994 | } | |||
995 | return rv; | |||
996 | } | |||
997 | ||||
998 | /* | |||
999 | ** RSA Private key operation (no CRT). | |||
1000 | */ | |||
1001 | static SECStatus | |||
1002 | rsa_PrivateKeyOpNoCRT(RSAPrivateKey *key, mp_int *m, mp_int *c, mp_int *n, | |||
1003 | unsigned int modLen) | |||
1004 | { | |||
1005 | mp_int d; | |||
1006 | mp_err err = MP_OKAY0; | |||
1007 | SECStatus rv = SECSuccess; | |||
1008 | MP_DIGITS(&d)((&d)->dp) = 0; | |||
1009 | CHECK_MPI_OK(mp_init(&d))if (0 > (err = mp_init(&d))) goto cleanup; | |||
1010 | SECITEM_TO_MPINT(key->privateExponent, &d)if (0 > (err = mp_read_unsigned_octets((&d), (key-> privateExponent).data, (key->privateExponent).len))) goto cleanup; | |||
1011 | /* 1. m = c**d mod n */ | |||
1012 | CHECK_MPI_OK(mp_exptmod(c, &d, n, m))if (0 > (err = mp_exptmod(c, &d, n, m))) goto cleanup; | |||
1013 | cleanup: | |||
1014 | mp_clear(&d); | |||
1015 | if (err) { | |||
1016 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1017 | rv = SECFailure; | |||
1018 | } | |||
1019 | return rv; | |||
1020 | } | |||
1021 | ||||
1022 | /* | |||
1023 | ** RSA Private key operation using CRT. | |||
1024 | */ | |||
1025 | static SECStatus | |||
1026 | rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c) | |||
1027 | { | |||
1028 | mp_int p, q, d_p, d_q, qInv; | |||
1029 | /* | |||
1030 | The length of the randomness comes from the papers: | |||
1031 | https://link.springer.com/chapter/10.1007/978-3-642-29912-4_7 | |||
1032 | https://link.springer.com/chapter/10.1007/978-3-642-21554-4_5. | |||
1033 | */ | |||
1034 | mp_int blinding_dp, blinding_dq, r1, r2; | |||
1035 | unsigned char random_block[EXP_BLINDING_RANDOMNESS_LEN_BYTES(((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit)) ) * sizeof(mp_digit))]; | |||
1036 | mp_int m1, m2, h, ctmp; | |||
1037 | mp_err err = MP_OKAY0; | |||
1038 | SECStatus rv = SECSuccess; | |||
1039 | MP_DIGITS(&p)((&p)->dp) = 0; | |||
1040 | MP_DIGITS(&q)((&q)->dp) = 0; | |||
1041 | MP_DIGITS(&d_p)((&d_p)->dp) = 0; | |||
1042 | MP_DIGITS(&d_q)((&d_q)->dp) = 0; | |||
1043 | MP_DIGITS(&qInv)((&qInv)->dp) = 0; | |||
1044 | MP_DIGITS(&m1)((&m1)->dp) = 0; | |||
1045 | MP_DIGITS(&m2)((&m2)->dp) = 0; | |||
1046 | MP_DIGITS(&h)((&h)->dp) = 0; | |||
1047 | MP_DIGITS(&ctmp)((&ctmp)->dp) = 0; | |||
1048 | MP_DIGITS(&blinding_dp)((&blinding_dp)->dp) = 0; | |||
1049 | MP_DIGITS(&blinding_dq)((&blinding_dq)->dp) = 0; | |||
1050 | MP_DIGITS(&r1)((&r1)->dp) = 0; | |||
1051 | MP_DIGITS(&r2)((&r2)->dp) = 0; | |||
1052 | ||||
1053 | CHECK_MPI_OK(mp_init(&p))if (0 > (err = mp_init(&p))) goto cleanup; | |||
1054 | CHECK_MPI_OK(mp_init(&q))if (0 > (err = mp_init(&q))) goto cleanup; | |||
1055 | CHECK_MPI_OK(mp_init(&d_p))if (0 > (err = mp_init(&d_p))) goto cleanup; | |||
1056 | CHECK_MPI_OK(mp_init(&d_q))if (0 > (err = mp_init(&d_q))) goto cleanup; | |||
1057 | CHECK_MPI_OK(mp_init(&qInv))if (0 > (err = mp_init(&qInv))) goto cleanup; | |||
1058 | CHECK_MPI_OK(mp_init(&m1))if (0 > (err = mp_init(&m1))) goto cleanup; | |||
1059 | CHECK_MPI_OK(mp_init(&m2))if (0 > (err = mp_init(&m2))) goto cleanup; | |||
1060 | CHECK_MPI_OK(mp_init(&h))if (0 > (err = mp_init(&h))) goto cleanup; | |||
1061 | CHECK_MPI_OK(mp_init(&ctmp))if (0 > (err = mp_init(&ctmp))) goto cleanup; | |||
1062 | CHECK_MPI_OK(mp_init(&blinding_dp))if (0 > (err = mp_init(&blinding_dp))) goto cleanup; | |||
1063 | CHECK_MPI_OK(mp_init(&blinding_dq))if (0 > (err = mp_init(&blinding_dq))) goto cleanup; | |||
1064 | CHECK_MPI_OK(mp_init_size(&r1, EXP_BLINDING_RANDOMNESS_LEN))if (0 > (err = mp_init_size(&r1, ((128 + (8 * sizeof(mp_digit )) - 1) / (8 * sizeof(mp_digit)))))) goto cleanup; | |||
1065 | CHECK_MPI_OK(mp_init_size(&r2, EXP_BLINDING_RANDOMNESS_LEN))if (0 > (err = mp_init_size(&r2, ((128 + (8 * sizeof(mp_digit )) - 1) / (8 * sizeof(mp_digit)))))) goto cleanup; | |||
1066 | ||||
1067 | /* copy private key parameters into mp integers */ | |||
1068 | SECITEM_TO_MPINT(key->prime1, &p)if (0 > (err = mp_read_unsigned_octets((&p), (key-> prime1).data, (key->prime1).len))) goto cleanup; /* p */ | |||
1069 | SECITEM_TO_MPINT(key->prime2, &q)if (0 > (err = mp_read_unsigned_octets((&q), (key-> prime2).data, (key->prime2).len))) goto cleanup; /* q */ | |||
1070 | SECITEM_TO_MPINT(key->exponent1, &d_p)if (0 > (err = mp_read_unsigned_octets((&d_p), (key-> exponent1).data, (key->exponent1).len))) goto cleanup; /* d_p = d mod (p-1) */ | |||
1071 | SECITEM_TO_MPINT(key->exponent2, &d_q)if (0 > (err = mp_read_unsigned_octets((&d_q), (key-> exponent2).data, (key->exponent2).len))) goto cleanup; /* d_q = d mod (q-1) */ | |||
1072 | SECITEM_TO_MPINT(key->coefficient, &qInv)if (0 > (err = mp_read_unsigned_octets((&qInv), (key-> coefficient).data, (key->coefficient).len))) goto cleanup; /* qInv = q**-1 mod p */ | |||
1073 | ||||
1074 | // blinding_dp = 1 | |||
1075 | CHECK_MPI_OK(mp_set_int(&blinding_dp, 1))if (0 > (err = mp_set_int(&blinding_dp, 1))) goto cleanup; | |||
1076 | // blinding_dp = p - 1 | |||
1077 | CHECK_MPI_OK(mp_sub(&p, &blinding_dp, &blinding_dp))if (0 > (err = mp_sub(&p, &blinding_dp, &blinding_dp ))) goto cleanup; | |||
1078 | // generating a random value | |||
1079 | RNG_GenerateGlobalRandomBytes(random_block, EXP_BLINDING_RANDOMNESS_LEN_BYTES(((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit)) ) * sizeof(mp_digit))); | |||
1080 | MP_USED(&r1)((&r1)->used) = EXP_BLINDING_RANDOMNESS_LEN((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit))); | |||
1081 | memcpy(MP_DIGITS(&r1)((&r1)->dp), random_block, sizeof(random_block)); | |||
1082 | // blinding_dp = random * (p - 1) | |||
1083 | CHECK_MPI_OK(mp_mul(&blinding_dp, &r1, &blinding_dp))if (0 > (err = mp_mul(&blinding_dp, &r1, &blinding_dp ))) goto cleanup; | |||
1084 | //d_p = d_p + random * (p - 1) | |||
1085 | CHECK_MPI_OK(mp_add(&d_p, &blinding_dp, &d_p))if (0 > (err = mp_add(&d_p, &blinding_dp, &d_p ))) goto cleanup; | |||
1086 | ||||
1087 | // blinding_dq = 1 | |||
1088 | CHECK_MPI_OK(mp_set_int(&blinding_dq, 1))if (0 > (err = mp_set_int(&blinding_dq, 1))) goto cleanup; | |||
1089 | // blinding_dq = q - 1 | |||
1090 | CHECK_MPI_OK(mp_sub(&q, &blinding_dq, &blinding_dq))if (0 > (err = mp_sub(&q, &blinding_dq, &blinding_dq ))) goto cleanup; | |||
1091 | // generating a random value | |||
1092 | RNG_GenerateGlobalRandomBytes(random_block, EXP_BLINDING_RANDOMNESS_LEN_BYTES(((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit)) ) * sizeof(mp_digit))); | |||
1093 | memcpy(MP_DIGITS(&r2)((&r2)->dp), random_block, sizeof(random_block)); | |||
1094 | MP_USED(&r2)((&r2)->used) = EXP_BLINDING_RANDOMNESS_LEN((128 + (8 * sizeof(mp_digit)) - 1) / (8 * sizeof(mp_digit))); | |||
1095 | // blinding_dq = random * (q - 1) | |||
1096 | CHECK_MPI_OK(mp_mul(&blinding_dq, &r2, &blinding_dq))if (0 > (err = mp_mul(&blinding_dq, &r2, &blinding_dq ))) goto cleanup; | |||
1097 | //d_q = d_q + random * (q-1) | |||
1098 | CHECK_MPI_OK(mp_add(&d_q, &blinding_dq, &d_q))if (0 > (err = mp_add(&d_q, &blinding_dq, &d_q ))) goto cleanup; | |||
1099 | ||||
1100 | /* 1. m1 = c**d_p mod p */ | |||
1101 | CHECK_MPI_OK(mp_mod(c, &p, &ctmp))if (0 > (err = mp_mod(c, &p, &ctmp))) goto cleanup; | |||
1102 | CHECK_MPI_OK(mp_exptmod(&ctmp, &d_p, &p, &m1))if (0 > (err = mp_exptmod(&ctmp, &d_p, &p, & m1))) goto cleanup; | |||
1103 | /* 2. m2 = c**d_q mod q */ | |||
1104 | CHECK_MPI_OK(mp_mod(c, &q, &ctmp))if (0 > (err = mp_mod(c, &q, &ctmp))) goto cleanup; | |||
1105 | CHECK_MPI_OK(mp_exptmod(&ctmp, &d_q, &q, &m2))if (0 > (err = mp_exptmod(&ctmp, &d_q, &q, & m2))) goto cleanup; | |||
1106 | /* 3. h = (m1 - m2) * qInv mod p */ | |||
1107 | CHECK_MPI_OK(mp_submod(&m1, &m2, &p, &h))if (0 > (err = mp_submod(&m1, &m2, &p, &h) )) goto cleanup; | |||
1108 | CHECK_MPI_OK(mp_mulmod(&h, &qInv, &p, &h))if (0 > (err = mp_mulmod(&h, &qInv, &p, &h ))) goto cleanup; | |||
1109 | /* 4. m = m2 + h * q */ | |||
1110 | CHECK_MPI_OK(mp_mul(&h, &q, m))if (0 > (err = mp_mul(&h, &q, m))) goto cleanup; | |||
1111 | CHECK_MPI_OK(mp_add(m, &m2, m))if (0 > (err = mp_add(m, &m2, m))) goto cleanup; | |||
1112 | cleanup: | |||
1113 | mp_clear(&p); | |||
1114 | mp_clear(&q); | |||
1115 | mp_clear(&d_p); | |||
1116 | mp_clear(&d_q); | |||
1117 | mp_clear(&qInv); | |||
1118 | mp_clear(&m1); | |||
1119 | mp_clear(&m2); | |||
1120 | mp_clear(&h); | |||
1121 | mp_clear(&ctmp); | |||
1122 | mp_clear(&blinding_dp); | |||
1123 | mp_clear(&blinding_dq); | |||
1124 | mp_clear(&r1); | |||
1125 | mp_clear(&r2); | |||
1126 | if (err) { | |||
1127 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1128 | rv = SECFailure; | |||
1129 | } | |||
1130 | return rv; | |||
1131 | } | |||
1132 | ||||
1133 | /* | |||
1134 | ** An attack against RSA CRT was described by Boneh, DeMillo, and Lipton in: | |||
1135 | ** "On the Importance of Eliminating Errors in Cryptographic Computations", | |||
1136 | ** http://theory.stanford.edu/~dabo/papers/faults.ps.gz | |||
1137 | ** | |||
1138 | ** As a defense against the attack, carry out the private key operation, | |||
1139 | ** followed up with a public key operation to invert the result. | |||
1140 | ** Verify that result against the input. | |||
1141 | */ | |||
1142 | static SECStatus | |||
1143 | rsa_PrivateKeyOpCRTCheckedPubKey(RSAPrivateKey *key, mp_int *m, mp_int *c) | |||
1144 | { | |||
1145 | mp_int n, e, v; | |||
1146 | mp_err err = MP_OKAY0; | |||
1147 | SECStatus rv = SECSuccess; | |||
1148 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
1149 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
1150 | MP_DIGITS(&v)((&v)->dp) = 0; | |||
1151 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
1152 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
1153 | CHECK_MPI_OK(mp_init(&v))if (0 > (err = mp_init(&v))) goto cleanup; | |||
1154 | CHECK_SEC_OK(rsa_PrivateKeyOpCRTNoCheck(key, m, c))if (SECSuccess != (rv = rsa_PrivateKeyOpCRTNoCheck(key, m, c) )) goto cleanup; | |||
1155 | SECITEM_TO_MPINT(key->modulus, &n)if (0 > (err = mp_read_unsigned_octets((&n), (key-> modulus).data, (key->modulus).len))) goto cleanup; | |||
1156 | SECITEM_TO_MPINT(key->publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (key-> publicExponent).data, (key->publicExponent).len))) goto cleanup; | |||
1157 | /* Perform a public key operation v = m ** e mod n */ | |||
1158 | CHECK_MPI_OK(mp_exptmod(m, &e, &n, &v))if (0 > (err = mp_exptmod(m, &e, &n, &v))) goto cleanup; | |||
1159 | if (mp_cmp(&v, c) != 0) { | |||
1160 | rv = SECFailure; | |||
1161 | } | |||
1162 | cleanup: | |||
1163 | mp_clear(&n); | |||
1164 | mp_clear(&e); | |||
1165 | mp_clear(&v); | |||
1166 | if (err) { | |||
1167 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1168 | rv = SECFailure; | |||
1169 | } | |||
1170 | return rv; | |||
1171 | } | |||
1172 | ||||
1173 | static PRCallOnceType coBPInit = { 0, 0, 0 }; | |||
1174 | static PRStatus | |||
1175 | init_blinding_params_list(void) | |||
1176 | { | |||
1177 | blindingParamsList.lock = PZ_NewLock(nssILockOther)PR_NewLock_stub(); | |||
1178 | if (!blindingParamsList.lock) { | |||
1179 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
1180 | return PR_FAILURE; | |||
1181 | } | |||
1182 | blindingParamsList.cVar = PR_NewCondVarPR_NewCondVar_stub(blindingParamsList.lock); | |||
1183 | if (!blindingParamsList.cVar) { | |||
1184 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
1185 | return PR_FAILURE; | |||
1186 | } | |||
1187 | blindingParamsList.waitCount = 0; | |||
1188 | PR_INIT_CLIST(&blindingParamsList.head)do { (&blindingParamsList.head)->next = (&blindingParamsList .head); (&blindingParamsList.head)->prev = (&blindingParamsList .head); } while (0); | |||
1189 | return PR_SUCCESS; | |||
1190 | } | |||
1191 | ||||
1192 | static SECStatus | |||
1193 | generate_blinding_params(RSAPrivateKey *key, mp_int *f, mp_int *g, mp_int *n, | |||
1194 | unsigned int modLen) | |||
1195 | { | |||
1196 | SECStatus rv = SECSuccess; | |||
1197 | mp_int e, k; | |||
1198 | mp_err err = MP_OKAY0; | |||
1199 | unsigned char *kb = NULL((void*)0); | |||
1200 | ||||
1201 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
1202 | MP_DIGITS(&k)((&k)->dp) = 0; | |||
1203 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
1204 | CHECK_MPI_OK(mp_init(&k))if (0 > (err = mp_init(&k))) goto cleanup; | |||
1205 | SECITEM_TO_MPINT(key->publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (key-> publicExponent).data, (key->publicExponent).len))) goto cleanup; | |||
1206 | /* generate random k < n */ | |||
1207 | kb = PORT_AllocPORT_Alloc_stub(modLen); | |||
1208 | if (!kb) { | |||
1209 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
1210 | goto cleanup; | |||
1211 | } | |||
1212 | CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(kb, modLen))if (SECSuccess != (rv = RNG_GenerateGlobalRandomBytes(kb, modLen ))) goto cleanup; | |||
1213 | CHECK_MPI_OK(mp_read_unsigned_octets(&k, kb, modLen))if (0 > (err = mp_read_unsigned_octets(&k, kb, modLen) )) goto cleanup; | |||
1214 | /* k < n */ | |||
1215 | CHECK_MPI_OK(mp_mod(&k, n, &k))if (0 > (err = mp_mod(&k, n, &k))) goto cleanup; | |||
1216 | /* f = k**e mod n */ | |||
1217 | CHECK_MPI_OK(mp_exptmod(&k, &e, n, f))if (0 > (err = mp_exptmod(&k, &e, n, f))) goto cleanup; | |||
1218 | /* g = k**-1 mod n */ | |||
1219 | CHECK_MPI_OK(mp_invmod(&k, n, g))if (0 > (err = mp_invmod(&k, n, g))) goto cleanup; | |||
1220 | /* g in montgomery form.. */ | |||
1221 | CHECK_MPI_OK(mp_to_mont(g, n, g))if (0 > (err = mp_to_mont(g, n, g))) goto cleanup; | |||
1222 | cleanup: | |||
1223 | if (kb) | |||
1224 | PORT_ZFreePORT_ZFree_stub(kb, modLen); | |||
1225 | mp_clear(&k); | |||
1226 | mp_clear(&e); | |||
1227 | if (err) { | |||
1228 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1229 | rv = SECFailure; | |||
1230 | } | |||
1231 | return rv; | |||
1232 | } | |||
1233 | ||||
1234 | static SECStatus | |||
1235 | init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key, | |||
1236 | mp_int *n, unsigned int modLen) | |||
1237 | { | |||
1238 | blindingParams *bp = rsabp->array; | |||
1239 | int i = 0; | |||
1240 | ||||
1241 | /* Initialize the list pointer for the element */ | |||
1242 | PR_INIT_CLIST(&rsabp->link)do { (&rsabp->link)->next = (&rsabp->link); ( &rsabp->link)->prev = (&rsabp->link); } while (0); | |||
1243 | for (i = 0; i < RSA_BLINDING_PARAMS_MAX_CACHE_SIZE20; ++i, ++bp) { | |||
1244 | bp->next = bp + 1; | |||
1245 | MP_DIGITS(&bp->f)((&bp->f)->dp) = 0; | |||
1246 | MP_DIGITS(&bp->g)((&bp->g)->dp) = 0; | |||
1247 | bp->counter = 0; | |||
1248 | } | |||
1249 | /* The last bp->next value was initialized with out | |||
1250 | * of rsabp->array pointer and must be set to NULL | |||
1251 | */ | |||
1252 | rsabp->array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE20 - 1].next = NULL((void*)0); | |||
1253 | ||||
1254 | bp = rsabp->array; | |||
1255 | rsabp->bp = NULL((void*)0); | |||
1256 | rsabp->free = bp; | |||
1257 | ||||
1258 | /* precalculate montgomery reduction parameter */ | |||
1259 | rsabp->n0i = mp_calculate_mont_n0i(n); | |||
1260 | ||||
1261 | /* List elements are keyed using the modulus */ | |||
1262 | return SECITEM_CopyItemSECITEM_CopyItem_stub(NULL((void*)0), &rsabp->modulus, &key->modulus); | |||
1263 | } | |||
1264 | ||||
1265 | static SECStatus | |||
1266 | get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen, | |||
1267 | mp_int *f, mp_int *g, mp_digit *n0i) | |||
1268 | { | |||
1269 | RSABlindingParams *rsabp = NULL((void*)0); | |||
1270 | blindingParams *bpUnlinked = NULL((void*)0); | |||
1271 | blindingParams *bp; | |||
1272 | PRCList *el; | |||
1273 | SECStatus rv = SECSuccess; | |||
1274 | mp_err err = MP_OKAY0; | |||
1275 | int cmp = -1; | |||
1276 | PRBool holdingLock = PR_FALSE0; | |||
1277 | ||||
1278 | do { | |||
1279 | if (blindingParamsList.lock == NULL((void*)0)) { | |||
1280 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); | |||
1281 | return SECFailure; | |||
1282 | } | |||
1283 | /* Acquire the list lock */ | |||
1284 | PZ_Lock(blindingParamsList.lock)PR_Lock_stub((blindingParamsList.lock)); | |||
1285 | holdingLock = PR_TRUE1; | |||
1286 | ||||
1287 | /* Walk the list looking for the private key */ | |||
1288 | for (el = PR_NEXT_LINK(&blindingParamsList.head)((&blindingParamsList.head)->next); | |||
1289 | el != &blindingParamsList.head; | |||
1290 | el = PR_NEXT_LINK(el)((el)->next)) { | |||
1291 | rsabp = (RSABlindingParams *)el; | |||
1292 | cmp = SECITEM_CompareItemSECITEM_CompareItem_stub(&rsabp->modulus, &key->modulus); | |||
1293 | if (cmp >= 0) { | |||
1294 | /* The key is found or not in the list. */ | |||
1295 | break; | |||
1296 | } | |||
1297 | } | |||
1298 | ||||
1299 | if (cmp) { | |||
1300 | /* At this point, the key is not in the list. el should point to | |||
1301 | ** the list element before which this key should be inserted. | |||
1302 | */ | |||
1303 | rsabp = PORT_ZNew(RSABlindingParams)(RSABlindingParams *)PORT_ZAlloc_stub(sizeof(RSABlindingParams )); | |||
1304 | if (!rsabp) { | |||
1305 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_NO_MEMORY); | |||
1306 | goto cleanup; | |||
1307 | } | |||
1308 | ||||
1309 | rv = init_blinding_params(rsabp, key, n, modLen); | |||
1310 | if (rv != SECSuccess) { | |||
1311 | PORT_ZFreePORT_ZFree_stub(rsabp, sizeof(RSABlindingParams)); | |||
1312 | goto cleanup; | |||
1313 | } | |||
1314 | ||||
1315 | /* Insert the new element into the list | |||
1316 | ** If inserting in the middle of the list, el points to the link | |||
1317 | ** to insert before. Otherwise, the link needs to be appended to | |||
1318 | ** the end of the list, which is the same as inserting before the | |||
1319 | ** head (since el would have looped back to the head). | |||
1320 | */ | |||
1321 | PR_INSERT_BEFORE(&rsabp->link, el)do { (&rsabp->link)->next = (el); (&rsabp->link )->prev = (el)->prev; (el)->prev->next = (&rsabp ->link); (el)->prev = (&rsabp->link); } while (0 ); | |||
1322 | } | |||
1323 | ||||
1324 | /* We've found (or created) the RSAblindingParams struct for this key. | |||
1325 | * Now, search its list of ready blinding params for a usable one. | |||
1326 | */ | |||
1327 | *n0i = rsabp->n0i; | |||
1328 | while (0 != (bp = rsabp->bp)) { | |||
1329 | #ifdef UNSAFE_FUZZER_MODE | |||
1330 | /* Found a match and there are still remaining uses left */ | |||
1331 | /* Return the parameters */ | |||
1332 | CHECK_MPI_OK(mp_copy(&bp->f, f))if (0 > (err = mp_copy(&bp->f, f))) goto cleanup; | |||
1333 | CHECK_MPI_OK(mp_copy(&bp->g, g))if (0 > (err = mp_copy(&bp->g, g))) goto cleanup; | |||
1334 | ||||
1335 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1336 | return SECSuccess; | |||
1337 | #else | |||
1338 | if (--(bp->counter) > 0) { | |||
1339 | /* Found a match and there are still remaining uses left */ | |||
1340 | /* Return the parameters */ | |||
1341 | CHECK_MPI_OK(mp_copy(&bp->f, f))if (0 > (err = mp_copy(&bp->f, f))) goto cleanup; | |||
1342 | CHECK_MPI_OK(mp_copy(&bp->g, g))if (0 > (err = mp_copy(&bp->g, g))) goto cleanup; | |||
1343 | ||||
1344 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1345 | return SECSuccess; | |||
1346 | } | |||
1347 | /* exhausted this one, give its values to caller, and | |||
1348 | * then retire it. | |||
1349 | */ | |||
1350 | mp_exch(&bp->f, f); | |||
1351 | mp_exch(&bp->g, g); | |||
1352 | mp_clear(&bp->f); | |||
1353 | mp_clear(&bp->g); | |||
1354 | bp->counter = 0; | |||
1355 | /* Move to free list */ | |||
1356 | rsabp->bp = bp->next; | |||
1357 | bp->next = rsabp->free; | |||
1358 | rsabp->free = bp; | |||
1359 | /* In case there're threads waiting for new blinding | |||
1360 | * value - notify 1 thread the value is ready | |||
1361 | */ | |||
1362 | if (blindingParamsList.waitCount > 0) { | |||
1363 | PR_NotifyCondVarPR_NotifyCondVar_stub(blindingParamsList.cVar); | |||
1364 | blindingParamsList.waitCount--; | |||
1365 | } | |||
1366 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1367 | return SECSuccess; | |||
1368 | #endif | |||
1369 | } | |||
1370 | /* We did not find a usable set of blinding params. Can we make one? */ | |||
1371 | /* Find a free bp struct. */ | |||
1372 | if ((bp = rsabp->free) != NULL((void*)0)) { | |||
1373 | /* unlink this bp */ | |||
1374 | rsabp->free = bp->next; | |||
1375 | bp->next = NULL((void*)0); | |||
1376 | bpUnlinked = bp; /* In case we fail */ | |||
1377 | ||||
1378 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1379 | holdingLock = PR_FALSE0; | |||
1380 | /* generate blinding parameter values for the current thread */ | |||
1381 | CHECK_SEC_OK(generate_blinding_params(key, f, g, n, modLen))if (SECSuccess != (rv = generate_blinding_params(key, f, g, n , modLen))) goto cleanup; | |||
1382 | ||||
1383 | /* put the blinding parameter values into cache */ | |||
1384 | CHECK_MPI_OK(mp_init(&bp->f))if (0 > (err = mp_init(&bp->f))) goto cleanup; | |||
1385 | CHECK_MPI_OK(mp_init(&bp->g))if (0 > (err = mp_init(&bp->g))) goto cleanup; | |||
1386 | CHECK_MPI_OK(mp_copy(f, &bp->f))if (0 > (err = mp_copy(f, &bp->f))) goto cleanup; | |||
1387 | CHECK_MPI_OK(mp_copy(g, &bp->g))if (0 > (err = mp_copy(g, &bp->g))) goto cleanup; | |||
1388 | ||||
1389 | /* Put this at head of queue of usable params. */ | |||
1390 | PZ_Lock(blindingParamsList.lock)PR_Lock_stub((blindingParamsList.lock)); | |||
1391 | holdingLock = PR_TRUE1; | |||
1392 | (void)holdingLock; | |||
1393 | /* initialize RSABlindingParamsStr */ | |||
1394 | bp->counter = RSA_BLINDING_PARAMS_MAX_REUSE50; | |||
1395 | bp->next = rsabp->bp; | |||
1396 | rsabp->bp = bp; | |||
1397 | bpUnlinked = NULL((void*)0); | |||
1398 | /* In case there're threads waiting for new blinding value | |||
1399 | * just notify them the value is ready | |||
1400 | */ | |||
1401 | if (blindingParamsList.waitCount > 0) { | |||
1402 | PR_NotifyAllCondVarPR_NotifyAllCondVar_stub(blindingParamsList.cVar); | |||
1403 | blindingParamsList.waitCount = 0; | |||
1404 | } | |||
1405 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1406 | return SECSuccess; | |||
1407 | } | |||
1408 | /* Here, there are no usable blinding parameters available, | |||
1409 | * and no free bp blocks, presumably because they're all | |||
1410 | * actively having parameters generated for them. | |||
1411 | * So, we need to wait here and not eat up CPU until some | |||
1412 | * change happens. | |||
1413 | */ | |||
1414 | blindingParamsList.waitCount++; | |||
1415 | PR_WaitCondVarPR_WaitCondVar_stub(blindingParamsList.cVar, PR_INTERVAL_NO_TIMEOUT0xffffffffUL); | |||
1416 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1417 | holdingLock = PR_FALSE0; | |||
1418 | (void)holdingLock; | |||
1419 | } while (1); | |||
1420 | ||||
1421 | cleanup: | |||
1422 | /* It is possible to reach this after the lock is already released. */ | |||
1423 | if (bpUnlinked) { | |||
1424 | if (!holdingLock) { | |||
1425 | PZ_Lock(blindingParamsList.lock)PR_Lock_stub((blindingParamsList.lock)); | |||
1426 | holdingLock = PR_TRUE1; | |||
1427 | } | |||
1428 | bp = bpUnlinked; | |||
1429 | mp_clear(&bp->f); | |||
1430 | mp_clear(&bp->g); | |||
1431 | bp->counter = 0; | |||
1432 | /* Must put the unlinked bp back on the free list */ | |||
1433 | bp->next = rsabp->free; | |||
1434 | rsabp->free = bp; | |||
1435 | } | |||
1436 | if (holdingLock) { | |||
1437 | PZ_Unlock(blindingParamsList.lock)PR_Unlock_stub((blindingParamsList.lock)); | |||
1438 | } | |||
1439 | if (err) { | |||
1440 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1441 | } | |||
1442 | *n0i = 0; | |||
1443 | return SECFailure; | |||
1444 | } | |||
1445 | ||||
1446 | /* | |||
1447 | ** Perform a raw private-key operation | |||
1448 | ** Length of input and output buffers are equal to key's modulus len. | |||
1449 | */ | |||
1450 | static SECStatus | |||
1451 | rsa_PrivateKeyOp(RSAPrivateKey *key, | |||
1452 | unsigned char *output, | |||
1453 | const unsigned char *input, | |||
1454 | PRBool check) | |||
1455 | { | |||
1456 | unsigned int modLen; | |||
1457 | unsigned int offset; | |||
1458 | SECStatus rv = SECSuccess; | |||
1459 | mp_err err; | |||
1460 | mp_int n, c, m; | |||
1461 | mp_int f, g; | |||
1462 | mp_digit n0i; | |||
1463 | if (!key || !output || !input) { | |||
1464 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
1465 | return SECFailure; | |||
1466 | } | |||
1467 | /* check input out of range (needs to be in range [0..n-1]) */ | |||
1468 | modLen = rsa_modulusLen(&key->modulus); | |||
1469 | if (modLen
| |||
1470 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
1471 | return SECFailure; | |||
1472 | } | |||
1473 | offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */ | |||
1474 | if (memcmp(input, key->modulus.data + offset, modLen) >= 0) { | |||
1475 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_INVALID_ARGS); | |||
1476 | return SECFailure; | |||
1477 | } | |||
1478 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
1479 | MP_DIGITS(&c)((&c)->dp) = 0; | |||
1480 | MP_DIGITS(&m)((&m)->dp) = 0; | |||
1481 | MP_DIGITS(&f)((&f)->dp) = 0; | |||
1482 | MP_DIGITS(&g)((&g)->dp) = 0; | |||
1483 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
1484 | CHECK_MPI_OK(mp_init(&c))if (0 > (err = mp_init(&c))) goto cleanup; | |||
1485 | CHECK_MPI_OK(mp_init(&m))if (0 > (err = mp_init(&m))) goto cleanup; | |||
1486 | CHECK_MPI_OK(mp_init(&f))if (0 > (err = mp_init(&f))) goto cleanup; | |||
1487 | CHECK_MPI_OK(mp_init(&g))if (0 > (err = mp_init(&g))) goto cleanup; | |||
1488 | SECITEM_TO_MPINT(key->modulus, &n)if (0 > (err = mp_read_unsigned_octets((&n), (key-> modulus).data, (key->modulus).len))) goto cleanup; | |||
1489 | OCTETS_TO_MPINT(input, &c, modLen)if (0 > (err = mp_read_unsigned_octets((&c), input, modLen ))) goto cleanup; | |||
1490 | /* If blinding, compute pre-image of ciphertext by multiplying by | |||
1491 | ** blinding factor | |||
1492 | */ | |||
1493 | if (nssRSAUseBlinding) { | |||
1494 | CHECK_SEC_OK(get_blinding_params(key, &n, modLen, &f, &g, &n0i))if (SECSuccess != (rv = get_blinding_params(key, &n, modLen , &f, &g, &n0i))) goto cleanup; | |||
1495 | /* c' = c*f mod n */ | |||
1496 | CHECK_MPI_OK(mp_mulmod(&c, &f, &n, &c))if (0 > (err = mp_mulmod(&c, &f, &n, &c))) goto cleanup; | |||
1497 | } | |||
1498 | /* Do the private key operation m = c**d mod n */ | |||
1499 | if (key->prime1.len == 0 || | |||
1500 | key->prime2.len == 0 || | |||
1501 | key->exponent1.len == 0 || | |||
1502 | key->exponent2.len == 0 || | |||
1503 | key->coefficient.len == 0) { | |||
1504 | CHECK_SEC_OK(rsa_PrivateKeyOpNoCRT(key, &m, &c, &n, modLen))if (SECSuccess != (rv = rsa_PrivateKeyOpNoCRT(key, &m, & c, &n, modLen))) goto cleanup; | |||
1505 | } else if (check) { | |||
1506 | CHECK_SEC_OK(rsa_PrivateKeyOpCRTCheckedPubKey(key, &m, &c))if (SECSuccess != (rv = rsa_PrivateKeyOpCRTCheckedPubKey(key, &m, &c))) goto cleanup; | |||
1507 | } else { | |||
1508 | CHECK_SEC_OK(rsa_PrivateKeyOpCRTNoCheck(key, &m, &c))if (SECSuccess != (rv = rsa_PrivateKeyOpCRTNoCheck(key, & m, &c))) goto cleanup; | |||
1509 | } | |||
1510 | /* If blinding, compute post-image of plaintext by multiplying by | |||
1511 | ** blinding factor | |||
1512 | */ | |||
1513 | if (nssRSAUseBlinding) { | |||
1514 | /* m = m'*g mod n */ | |||
1515 | CHECK_MPI_OK(mp_mulmontmodCT(&m, &g, &n, n0i, &m))if (0 > (err = mp_mulmontmodCT(&m, &g, &n, n0i , &m))) goto cleanup; | |||
| ||||
1516 | } | |||
1517 | err = mp_to_fixlen_octets(&m, output, modLen); | |||
1518 | if (err >= 0) | |||
1519 | err = MP_OKAY0; | |||
1520 | cleanup: | |||
1521 | mp_clear(&n); | |||
1522 | mp_clear(&c); | |||
1523 | mp_clear(&m); | |||
1524 | mp_clear(&f); | |||
1525 | mp_clear(&g); | |||
1526 | if (err) { | |||
1527 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1528 | rv = SECFailure; | |||
1529 | } | |||
1530 | return rv; | |||
1531 | } | |||
1532 | ||||
1533 | SECStatus | |||
1534 | RSA_PrivateKeyOp(RSAPrivateKey *key, | |||
1535 | unsigned char *output, | |||
1536 | const unsigned char *input) | |||
1537 | { | |||
1538 | return rsa_PrivateKeyOp(key, output, input, PR_FALSE0); | |||
| ||||
1539 | } | |||
1540 | ||||
1541 | SECStatus | |||
1542 | RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey *key, | |||
1543 | unsigned char *output, | |||
1544 | const unsigned char *input) | |||
1545 | { | |||
1546 | return rsa_PrivateKeyOp(key, output, input, PR_TRUE1); | |||
1547 | } | |||
1548 | ||||
1549 | SECStatus | |||
1550 | RSA_PrivateKeyCheck(const RSAPrivateKey *key) | |||
1551 | { | |||
1552 | mp_int p, q, n, psub1, qsub1, e, d, d_p, d_q, qInv, res; | |||
1553 | mp_err err = MP_OKAY0; | |||
1554 | SECStatus rv = SECSuccess; | |||
1555 | MP_DIGITS(&p)((&p)->dp) = 0; | |||
1556 | MP_DIGITS(&q)((&q)->dp) = 0; | |||
1557 | MP_DIGITS(&n)((&n)->dp) = 0; | |||
1558 | MP_DIGITS(&psub1)((&psub1)->dp) = 0; | |||
1559 | MP_DIGITS(&qsub1)((&qsub1)->dp) = 0; | |||
1560 | MP_DIGITS(&e)((&e)->dp) = 0; | |||
1561 | MP_DIGITS(&d)((&d)->dp) = 0; | |||
1562 | MP_DIGITS(&d_p)((&d_p)->dp) = 0; | |||
1563 | MP_DIGITS(&d_q)((&d_q)->dp) = 0; | |||
1564 | MP_DIGITS(&qInv)((&qInv)->dp) = 0; | |||
1565 | MP_DIGITS(&res)((&res)->dp) = 0; | |||
1566 | CHECK_MPI_OK(mp_init(&p))if (0 > (err = mp_init(&p))) goto cleanup; | |||
1567 | CHECK_MPI_OK(mp_init(&q))if (0 > (err = mp_init(&q))) goto cleanup; | |||
1568 | CHECK_MPI_OK(mp_init(&n))if (0 > (err = mp_init(&n))) goto cleanup; | |||
1569 | CHECK_MPI_OK(mp_init(&psub1))if (0 > (err = mp_init(&psub1))) goto cleanup; | |||
1570 | CHECK_MPI_OK(mp_init(&qsub1))if (0 > (err = mp_init(&qsub1))) goto cleanup; | |||
1571 | CHECK_MPI_OK(mp_init(&e))if (0 > (err = mp_init(&e))) goto cleanup; | |||
1572 | CHECK_MPI_OK(mp_init(&d))if (0 > (err = mp_init(&d))) goto cleanup; | |||
1573 | CHECK_MPI_OK(mp_init(&d_p))if (0 > (err = mp_init(&d_p))) goto cleanup; | |||
1574 | CHECK_MPI_OK(mp_init(&d_q))if (0 > (err = mp_init(&d_q))) goto cleanup; | |||
1575 | CHECK_MPI_OK(mp_init(&qInv))if (0 > (err = mp_init(&qInv))) goto cleanup; | |||
1576 | CHECK_MPI_OK(mp_init(&res))if (0 > (err = mp_init(&res))) goto cleanup; | |||
1577 | ||||
1578 | if (!key->modulus.data || !key->prime1.data || !key->prime2.data || | |||
1579 | !key->publicExponent.data || !key->privateExponent.data || | |||
1580 | !key->exponent1.data || !key->exponent2.data || | |||
1581 | !key->coefficient.data) { | |||
1582 | /* call RSA_PopulatePrivateKey first, if the application wishes to | |||
1583 | * recover these parameters */ | |||
1584 | err = MP_BADARG-4; | |||
1585 | goto cleanup; | |||
1586 | } | |||
1587 | ||||
1588 | SECITEM_TO_MPINT(key->modulus, &n)if (0 > (err = mp_read_unsigned_octets((&n), (key-> modulus).data, (key->modulus).len))) goto cleanup; | |||
1589 | SECITEM_TO_MPINT(key->prime1, &p)if (0 > (err = mp_read_unsigned_octets((&p), (key-> prime1).data, (key->prime1).len))) goto cleanup; | |||
1590 | SECITEM_TO_MPINT(key->prime2, &q)if (0 > (err = mp_read_unsigned_octets((&q), (key-> prime2).data, (key->prime2).len))) goto cleanup; | |||
1591 | SECITEM_TO_MPINT(key->publicExponent, &e)if (0 > (err = mp_read_unsigned_octets((&e), (key-> publicExponent).data, (key->publicExponent).len))) goto cleanup; | |||
1592 | SECITEM_TO_MPINT(key->privateExponent, &d)if (0 > (err = mp_read_unsigned_octets((&d), (key-> privateExponent).data, (key->privateExponent).len))) goto cleanup; | |||
1593 | SECITEM_TO_MPINT(key->exponent1, &d_p)if (0 > (err = mp_read_unsigned_octets((&d_p), (key-> exponent1).data, (key->exponent1).len))) goto cleanup; | |||
1594 | SECITEM_TO_MPINT(key->exponent2, &d_q)if (0 > (err = mp_read_unsigned_octets((&d_q), (key-> exponent2).data, (key->exponent2).len))) goto cleanup; | |||
1595 | SECITEM_TO_MPINT(key->coefficient, &qInv)if (0 > (err = mp_read_unsigned_octets((&qInv), (key-> coefficient).data, (key->coefficient).len))) goto cleanup; | |||
1596 | /* p and q must be distinct. */ | |||
1597 | if (mp_cmp(&p, &q) == 0) { | |||
1598 | rv = SECFailure; | |||
1599 | goto cleanup; | |||
1600 | } | |||
1601 | #define VERIFY_MPI_EQUAL(m1, m2)if (mp_cmp(m1, m2) != 0) { rv = SECFailure; goto cleanup; } \ | |||
1602 | if (mp_cmp(m1, m2) != 0) { \ | |||
1603 | rv = SECFailure; \ | |||
1604 | goto cleanup; \ | |||
1605 | } | |||
1606 | #define VERIFY_MPI_EQUAL_1(m)if (mp_cmp_d(m, 1) != 0) { rv = SECFailure; goto cleanup; } \ | |||
1607 | if (mp_cmp_d(m, 1) != 0) { \ | |||
1608 | rv = SECFailure; \ | |||
1609 | goto cleanup; \ | |||
1610 | } | |||
1611 | /* n == p * q */ | |||
1612 | CHECK_MPI_OK(mp_mul(&p, &q, &res))if (0 > (err = mp_mul(&p, &q, &res))) goto cleanup; | |||
1613 | VERIFY_MPI_EQUAL(&res, &n)if (mp_cmp(&res, &n) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1614 | /* gcd(e, p-1) == 1 */ | |||
1615 | CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1))if (0 > (err = mp_sub_d(&p, 1, &psub1))) goto cleanup; | |||
1616 | CHECK_MPI_OK(mp_gcd(&e, &psub1, &res))if (0 > (err = mp_gcd(&e, &psub1, &res))) goto cleanup; | |||
1617 | VERIFY_MPI_EQUAL_1(&res)if (mp_cmp_d(&res, 1) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1618 | /* gcd(e, q-1) == 1 */ | |||
1619 | CHECK_MPI_OK(mp_sub_d(&q, 1, &qsub1))if (0 > (err = mp_sub_d(&q, 1, &qsub1))) goto cleanup; | |||
1620 | CHECK_MPI_OK(mp_gcd(&e, &qsub1, &res))if (0 > (err = mp_gcd(&e, &qsub1, &res))) goto cleanup; | |||
1621 | VERIFY_MPI_EQUAL_1(&res)if (mp_cmp_d(&res, 1) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1622 | /* d*e == 1 mod p-1 */ | |||
1623 | CHECK_MPI_OK(mp_mulmod(&d, &e, &psub1, &res))if (0 > (err = mp_mulmod(&d, &e, &psub1, & res))) goto cleanup; | |||
1624 | VERIFY_MPI_EQUAL_1(&res)if (mp_cmp_d(&res, 1) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1625 | /* d*e == 1 mod q-1 */ | |||
1626 | CHECK_MPI_OK(mp_mulmod(&d, &e, &qsub1, &res))if (0 > (err = mp_mulmod(&d, &e, &qsub1, & res))) goto cleanup; | |||
1627 | VERIFY_MPI_EQUAL_1(&res)if (mp_cmp_d(&res, 1) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1628 | /* d_p == d mod p-1 */ | |||
1629 | CHECK_MPI_OK(mp_mod(&d, &psub1, &res))if (0 > (err = mp_mod(&d, &psub1, &res))) goto cleanup; | |||
1630 | VERIFY_MPI_EQUAL(&res, &d_p)if (mp_cmp(&res, &d_p) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1631 | /* d_q == d mod q-1 */ | |||
1632 | CHECK_MPI_OK(mp_mod(&d, &qsub1, &res))if (0 > (err = mp_mod(&d, &qsub1, &res))) goto cleanup; | |||
1633 | VERIFY_MPI_EQUAL(&res, &d_q)if (mp_cmp(&res, &d_q) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1634 | /* q * q**-1 == 1 mod p */ | |||
1635 | CHECK_MPI_OK(mp_mulmod(&q, &qInv, &p, &res))if (0 > (err = mp_mulmod(&q, &qInv, &p, &res ))) goto cleanup; | |||
1636 | VERIFY_MPI_EQUAL_1(&res)if (mp_cmp_d(&res, 1) != 0) { rv = SECFailure; goto cleanup ; }; | |||
1637 | ||||
1638 | cleanup: | |||
1639 | mp_clear(&n); | |||
1640 | mp_clear(&p); | |||
1641 | mp_clear(&q); | |||
1642 | mp_clear(&psub1); | |||
1643 | mp_clear(&qsub1); | |||
1644 | mp_clear(&e); | |||
1645 | mp_clear(&d); | |||
1646 | mp_clear(&d_p); | |||
1647 | mp_clear(&d_q); | |||
1648 | mp_clear(&qInv); | |||
1649 | mp_clear(&res); | |||
1650 | if (err) { | |||
1651 | MP_TO_SEC_ERROR(err)switch (err) { case -2: PORT_SetError_stub(SEC_ERROR_NO_MEMORY ); break; case -3: PORT_SetError_stub(SEC_ERROR_BAD_DATA); break ; case -4: PORT_SetError_stub(SEC_ERROR_INVALID_ARGS); break; default: PORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); break ; }; | |||
1652 | rv = SECFailure; | |||
1653 | } | |||
1654 | return rv; | |||
1655 | } | |||
1656 | ||||
1657 | SECStatus | |||
1658 | RSA_Init(void) | |||
1659 | { | |||
1660 | if (PR_CallOncePR_CallOnce_stub(&coBPInit, init_blinding_params_list) != PR_SUCCESS) { | |||
1661 | PORT_SetErrorPORT_SetError_stub(SEC_ERROR_LIBRARY_FAILURE); | |||
1662 | return SECFailure; | |||
1663 | } | |||
1664 | return SECSuccess; | |||
1665 | } | |||
1666 | ||||
1667 | /* cleanup at shutdown */ | |||
1668 | void | |||
1669 | RSA_Cleanup(void) | |||
1670 | { | |||
1671 | blindingParams *bp = NULL((void*)0); | |||
1672 | if (!coBPInit.initialized) | |||
1673 | return; | |||
1674 | ||||
1675 | while (!PR_CLIST_IS_EMPTY(&blindingParamsList.head)((&blindingParamsList.head)->next == (&blindingParamsList .head))) { | |||
1676 | RSABlindingParams *rsabp = | |||
1677 | (RSABlindingParams *)PR_LIST_HEAD(&blindingParamsList.head)(&blindingParamsList.head)->next; | |||
1678 | PR_REMOVE_LINK(&rsabp->link)do { (&rsabp->link)->prev->next = (&rsabp-> link)->next; (&rsabp->link)->next->prev = (& rsabp->link)->prev; } while (0); | |||
1679 | /* clear parameters cache */ | |||
1680 | while (rsabp->bp != NULL((void*)0)) { | |||
1681 | bp = rsabp->bp; | |||
1682 | rsabp->bp = rsabp->bp->next; | |||
1683 | mp_clear(&bp->f); | |||
1684 | mp_clear(&bp->g); | |||
1685 | } | |||
1686 | SECITEM_ZfreeItemSECITEM_ZfreeItem_stub(&rsabp->modulus, PR_FALSE0); | |||
1687 | PORT_FreePORT_Free_stub(rsabp); | |||
1688 | } | |||
1689 | ||||
1690 | if (blindingParamsList.cVar) { | |||
1691 | PR_DestroyCondVarPR_DestroyCondVar_stub(blindingParamsList.cVar); | |||
1692 | blindingParamsList.cVar = NULL((void*)0); | |||
1693 | } | |||
1694 | ||||
1695 | if (blindingParamsList.lock) { | |||
1696 | SKIP_AFTER_FORK(PZ_DestroyLock(blindingParamsList.lock))if (!bl_parentForkedAfterC_Initialize) PR_DestroyLock_stub((blindingParamsList .lock)); | |||
1697 | blindingParamsList.lock = NULL((void*)0); | |||
1698 | } | |||
1699 | ||||
1700 | coBPInit.initialized = 0; | |||
1701 | coBPInit.inProgress = 0; | |||
1702 | coBPInit.status = 0; | |||
1703 | } | |||
1704 | ||||
1705 | /* | |||
1706 | * need a central place for this function to free up all the memory that | |||
1707 | * free_bl may have allocated along the way. Currently only RSA does this, | |||
1708 | * so I've put it here for now. | |||
1709 | */ | |||
1710 | void | |||
1711 | BL_Cleanup(void) | |||
1712 | { | |||
1713 | RSA_Cleanup(); | |||
1714 | } | |||
1715 | ||||
1716 | PRBool bl_parentForkedAfterC_Initialize; | |||
1717 | ||||
1718 | /* | |||
1719 | * Set fork flag so it can be tested in SKIP_AFTER_FORK on relevant platforms. | |||
1720 | */ | |||
1721 | void | |||
1722 | BL_SetForkState(PRBool forked) | |||
1723 | { | |||
1724 | bl_parentForkedAfterC_Initialize = forked; | |||
1725 | } |