| 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 | } |