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