/* * Verify that the public data in an RSA key matches the private * data. We also check the private data itself: we ensure that p > * q and that iqmp really is the inverse of q mod p. */ int rsa_verify(struct RSAKey *key) { Bignum n, ed, pm1, qm1; int cmp; /* n must equal pq. */ n = bigmul(key->p, key->q); cmp = bignum_cmp(n, key->modulus); freebn(n); if (cmp != 0) return 0; /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */ pm1 = copybn(key->p); decbn(pm1); ed = modmul(key->exponent, key->private_exponent, pm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) return 0; qm1 = copybn(key->q); decbn(qm1); ed = modmul(key->exponent, key->private_exponent, qm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) return 0; /* * Ensure p > q. */ if (bignum_cmp(key->p, key->q) <= 0) return 0; /* * Ensure iqmp * q is congruent to 1, modulo p. */ n = modmul(key->iqmp, key->q, key->p); cmp = bignum_cmp(n, One); sfree(n); if (cmp != 0) return 0; return 1; }
/* * Verify that the public data in an RSA key matches the private * data. We also check the private data itself: we ensure that p > * q and that iqmp really is the inverse of q mod p. */ bool RSAKey::Check() const { Bignum n, ed, pm1, qm1; int cmp; /* n must equal pq. */ n = bigmul(this->p, this->q); cmp = bignum_cmp(n, this->modulus); freebn(n); if (cmp != 0) return 0; /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */ pm1 = copybn(this->p); decbn(pm1); ed = modmul(this->exponent, this->private_exponent, pm1); cmp = bignum_cmp(ed, One); delete [] ed; if (cmp != 0) return 0; qm1 = copybn(this->q); decbn(qm1); ed = modmul(this->exponent, this->private_exponent, qm1); cmp = bignum_cmp(ed, One); delete [] ed; if (cmp != 0) return 0; /* * Ensure p > q. */ if (bignum_cmp(this->p, this->q) <= 0) return 0; /* * Ensure iqmp * q is congruent to 1, modulo p. */ n = modmul(this->iqmp, this->q, this->p); cmp = bignum_cmp(n, One); delete [] n; if (cmp != 0) return 0; return 1; }
/* * This function is a wrapper on modpow(). It has the same effect * as modpow(), but employs RSA blinding to protect against timing * attacks. */ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key) { Bignum random, random_encrypted, random_inverse; Bignum input_blinded, ret_blinded; Bignum ret; SHA512_State ss; unsigned char digest512[64]; int digestused = lenof(digest512); int hashseq = 0; /* * Start by inventing a random number chosen uniformly from the * range 2..modulus-1. (We do this by preparing a random number * of the right length and retrying if it's greater than the * modulus, to prevent any potential Bleichenbacher-like * attacks making use of the uneven distribution within the * range that would arise from just reducing our number mod n. * There are timing implications to the potential retries, of * course, but all they tell you is the modulus, which you * already knew.) * * To preserve determinism and avoid Pageant needing to share * the random number pool, we actually generate this `random' * number by hashing stuff with the private key. */ while (1) { int bits, byte, bitsleft, v; random = copybn(key->modulus); /* * Find the topmost set bit. (This function will return its * index plus one.) Then we'll set all bits from that one * downwards randomly. */ bits = bignum_bitcount(random); byte = 0; bitsleft = 0; while (bits--) { if (bitsleft <= 0) { bitsleft = 8; /* * Conceptually the following few lines are equivalent to * byte = random_byte(); */ if (digestused >= lenof(digest512)) { unsigned char seqbuf[4]; PUT_32BIT(seqbuf, hashseq); pSHA512_Init(&ss); SHA512_Bytes(&ss, "RSA deterministic blinding", 26); SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf)); sha512_mpint(&ss, key->private_exponent); pSHA512_Final(&ss, digest512); hashseq++; /* * Now hash that digest plus the signature * input. */ pSHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); sha512_mpint(&ss, input); pSHA512_Final(&ss, digest512); digestused = 0; } byte = digest512[digestused++]; } v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(random, bits, v); } /* * Now check that this number is strictly greater than * zero, and strictly less than modulus. */ if (bignum_cmp(random, Zero) <= 0 || bignum_cmp(random, key->modulus) >= 0) { freebn(random); continue; } else { break; } } /* * RSA blinding relies on the fact that (xy)^d mod n is equal * to (x^d mod n) * (y^d mod n) mod n. We invent a random pair * y and y^d; then we multiply x by y, raise to the power d mod * n as usual, and divide by y^d to recover x^d. Thus an * attacker can't correlate the timing of the modpow with the * input, because they don't know anything about the number * that was input to the actual modpow. * * The clever bit is that we don't have to do a huge modpow to * get y and y^d; we will use the number we just invented as * _y^d_, and use the _public_ exponent to compute (y^d)^e = y * from it, which is much faster to do. */ random_encrypted = modpow(random, key->exponent, key->modulus); random_inverse = modinv(random, key->modulus); input_blinded = modmul(input, random_encrypted, key->modulus); ret_blinded = modpow(input_blinded, key->private_exponent, key->modulus); ret = modmul(ret_blinded, random_inverse, key->modulus); freebn(ret_blinded); freebn(input_blinded); freebn(random_inverse); freebn(random_encrypted); freebn(random); return ret; }
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn, void *pfnparam) { Bignum qm1, power, g, h, tmp; unsigned pfirst, qfirst; int progress; /* * Set up the phase limits for the progress report. We do this * by passing minus the phase number. * * For prime generation: our initial filter finds things * coprime to everything below 2^16. Computing the product of * (p-1)/p for all prime p below 2^16 gives about 20.33; so * among B-bit integers, one in every 20.33 will get through * the initial filter to be a candidate prime. * * Meanwhile, we are searching for primes in the region of 2^B; * since pi(x) ~ x/log(x), when x is in the region of 2^B, the * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about * 1/0.6931B. So the chance of any given candidate being prime * is 20.33/0.6931B, which is roughly 29.34 divided by B. * * So now we have this probability P, we're looking at an * exponential distribution with parameter P: we will manage in * one attempt with probability P, in two with probability * P(1-P), in three with probability P(1-P)^2, etc. The * probability that we have still not managed to find a prime * after N attempts is (1-P)^N. * * We therefore inform the progress indicator of the number B * (29.34/B), so that it knows how much to increment by each * time. We do this in 16-bit fixed point, so 29.34 becomes * 0x1D.57C4. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 1, 0x2800); pfn(pfnparam, PROGFN_EXP_PHASE, 1, -0x1D57C4 / 160); pfn(pfnparam, PROGFN_PHASE_EXTENT, 2, 0x40 * bits); pfn(pfnparam, PROGFN_EXP_PHASE, 2, -0x1D57C4 / bits); /* * In phase three we are finding an order-q element of the * multiplicative group of p, by finding an element whose order * is _divisible_ by q and raising it to the power of (p-1)/q. * _Most_ elements will have order divisible by q, since for a * start phi(p) of them will be primitive roots. So * realistically we don't need to set this much below 1 (64K). * Still, we'll set it to 1/2 (32K) to be on the safe side. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 3, 0x2000); pfn(pfnparam, PROGFN_EXP_PHASE, 3, -32768); /* * In phase four we are finding an element x between 1 and q-1 * (exclusive), by inventing 160 random bits and hoping they * come out to a plausible number; so assuming q is uniformly * distributed between 2^159 and 2^160, the chance of any given * attempt succeeding is somewhere between 0.5 and 1. Lacking * the energy to arrange to be able to specify this probability * _after_ generating q, we'll just set it to 0.75. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 4, 0x2000); pfn(pfnparam, PROGFN_EXP_PHASE, 4, -49152); pfn(pfnparam, PROGFN_READY, 0, 0); invent_firstbits(&pfirst, &qfirst); /* * Generate q: a prime of length 160. */ key->q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst); /* * Now generate p: a prime of length `bits', such that p-1 is * divisible by q. */ key->p = primegen(bits-160, 2, 2, key->q, 2, pfn, pfnparam, pfirst); /* * Next we need g. Raise 2 to the power (p-1)/q modulo p, and * if that comes out to one then try 3, then 4 and so on. As * soon as we hit a non-unit (and non-zero!) one, that'll do * for g. */ power = bigdiv(key->p, key->q); /* this is floor(p/q) == (p-1)/q */ h = bignum_from_long(1); progress = 0; while (1) { pfn(pfnparam, PROGFN_PROGRESS, 3, ++progress); g = modpow(h, power, key->p); if (bignum_cmp(g, One) > 0) break; /* got one */ tmp = h; h = bignum_add_long(h, 1); freebn(tmp); } key->g = g; freebn(h); /* * Now we're nearly done. All we need now is our private key x, * which should be a number between 1 and q-1 exclusive, and * our public key y = g^x mod p. */ qm1 = copybn(key->q); decbn(qm1); progress = 0; while (1) { int i, v, byte, bitsleft; Bignum x; pfn(pfnparam, PROGFN_PROGRESS, 4, ++progress); x = bn_power_2(159); byte = 0; bitsleft = 0; for (i = 0; i < 160; i++) { if (bitsleft <= 0) bitsleft = 8, byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(x, i, v); } if (bignum_cmp(x, One) <= 0 || bignum_cmp(x, qm1) >= 0) { freebn(x); continue; } else { key->x = x; break; } } freebn(qm1); key->y = modpow(key->g, key->x, key->p); return 1; }
/* * Generate a prime. We arrange to select a prime with the property * (prime % modulus) != residue (to speed up use in RSA). */ Bignum primegen(int bits, int modulus, int residue, int phase, progfn_t pfn, void *pfnparam) { int i, k, v, byte, bitsleft, check, checks; unsigned long delta, moduli[NPRIMES+1], residues[NPRIMES+1]; Bignum p, pm1, q, wqp, wqp2; int progress = 0; byte = 0; bitsleft = 0; STARTOVER: pfn(pfnparam, phase, ++progress); /* * Generate a k-bit random number with top and bottom bits set. */ p = newbn((bits+15)/16); for (i = 0; i < bits; i++) { if (i == 0 || i == bits-1) v = 1; else { if (bitsleft <= 0) bitsleft = 8; byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; } bignum_set_bit(p, i, v); } /* * Ensure this random number is coprime to the first few * primes, by repeatedly adding 2 to it until it is. */ for (i = 0; i < NPRIMES; i++) { moduli[i] = primes[i]; residues[i] = bignum_mod_short(p, primes[i]); } moduli[NPRIMES] = modulus; residues[NPRIMES] = (bignum_mod_short(p, (unsigned short)modulus) + modulus - residue); delta = 0; while (1) { for (i = 0; i < (sizeof(moduli) / sizeof(*moduli)); i++) if (!((residues[i] + delta) % moduli[i])) break; if (i < (sizeof(moduli) / sizeof(*moduli))) {/* we broke */ delta += 2; if (delta < 2) { freebn(p); goto STARTOVER; } continue; } break; } q = p; p = bignum_add_long(q, delta); freebn(q); /* * Now apply the Miller-Rabin primality test a few times. First * work out how many checks are needed. */ checks = 27; if (bits >= 150) checks = 18; if (bits >= 200) checks = 15; if (bits >= 250) checks = 12; if (bits >= 300) checks = 9; if (bits >= 350) checks = 8; if (bits >= 400) checks = 7; if (bits >= 450) checks = 6; if (bits >= 550) checks = 5; if (bits >= 650) checks = 4; if (bits >= 850) checks = 3; if (bits >= 1300) checks = 2; /* * Next, write p-1 as q*2^k. */ for (k = 0; bignum_bit(p, k) == !k; k++); /* find first 1 bit in p-1 */ q = bignum_rshift(p, k); /* And store p-1 itself, which we'll need. */ pm1 = copybn(p); decbn(pm1); /* * Now, for each check ... */ for (check = 0; check < checks; check++) { Bignum w; /* * Invent a random number between 1 and p-1 inclusive. */ while (1) { w = newbn((bits+15)/16); for (i = 0; i < bits; i++) { if (bitsleft <= 0) bitsleft = 8; byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(w, i, v); } if (bignum_cmp(w, p) >= 0 || bignum_cmp(w, Zero) == 0) { freebn(w); continue; } break; } pfn(pfnparam, phase, ++progress); /* * Compute w^q mod p. */ wqp = modpow(w, q, p); freebn(w); /* * See if this is 1, or if it is -1, or if it becomes -1 * when squared at most k-1 times. */ if (bignum_cmp(wqp, One) == 0 || bignum_cmp(wqp, pm1) == 0) { freebn(wqp); continue; } for (i = 0; i < k-1; i++) { wqp2 = modmul(wqp, wqp, p); freebn(wqp); wqp = wqp2; if (bignum_cmp(wqp, pm1) == 0) break; } if (i < k-1) { freebn(wqp); continue; } /* * It didn't. Therefore, w is a witness for the * compositeness of p. */ freebn(p); freebn(pm1); freebn(q); goto STARTOVER; } /* * We have a prime! */ freebn(q); freebn(pm1); return p; }
int rsa_generate(struct RSAKey *key, struct RSAAux *aux, int bits, progfn_t pfn, void *pfnparam) { Bignum pm1, qm1, phi_n; /* * Set up the phase limits for the progress report. We do this * by passing minus the phase number. * * For prime generation: our initial filter finds things * coprime to everything below 2^16. Computing the product of * (p-1)/p for all prime p below 2^16 gives about 20.33; so * among B-bit integers, one in every 20.33 will get through * the initial filter to be a candidate prime. * * Meanwhile, we are searching for primes in the region of 2^B; * since pi(x) ~ x/log(x), when x is in the region of 2^B, the * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about * 1/0.6931B. So the chance of any given candidate being prime * is 20.33/0.6931B, which is roughly 29.34 divided by B. * * So now we have this probability P, we're looking at an * exponential distribution with parameter P: we will manage in * one attempt with probability P, in two with probability * P(1-P), in three with probability P(1-P)^2, etc. The * probability that we have still not managed to find a prime * after N attempts is (1-P)^N. * * We therefore inform the progress indicator of the number B * (29.34/B), so that it knows how much to increment by each * time. We do this in 16-bit fixed point, so 29.34 becomes * 0x1D.57C4. */ pfn(pfnparam, -1, -0x1D57C4/(bits/2)); pfn(pfnparam, -2, -0x1D57C4/(bits-bits/2)); pfn(pfnparam, -3, 5); /* * We don't generate e; we just use a standard one always. */ key->exponent = bignum_from_short(RSA_EXPONENT); /* * Generate p and q: primes with combined length `bits', not * congruent to 1 modulo e. (Strictly speaking, we wanted (p-1) * and e to be coprime, and (q-1) and e to be coprime, but in * general that's slightly more fiddly to arrange. By choosing * a prime e, we can simplify the criterion.) */ aux->p = primegen(bits/2, RSA_EXPONENT, 1, 1, pfn, pfnparam); aux->q = primegen(bits - bits/2, RSA_EXPONENT, 1, 2, pfn, pfnparam); /* * Ensure p > q, by swapping them if not. */ if (bignum_cmp(aux->p, aux->q) < 0) { Bignum t = aux->p; aux->p = aux->q; aux->q = t; } /* * Now we have p, q and e. All we need to do now is work out * the other helpful quantities: n=pq, d=e^-1 mod (p-1)(q-1), * and (q^-1 mod p). */ pfn(pfnparam, 3, 1); key->modulus = bigmul(aux->p, aux->q); pfn(pfnparam, 3, 2); pm1 = copybn(aux->p); decbn(pm1); qm1 = copybn(aux->q); decbn(qm1); phi_n = bigmul(pm1, qm1); pfn(pfnparam, 3, 3); freebn(pm1); freebn(qm1); key->private_exponent = modinv(key->exponent, phi_n); pfn(pfnparam, 3, 4); aux->iqmp = modinv(aux->q, aux->p); pfn(pfnparam, 3, 5); /* * Clean up temporary numbers. */ freebn(phi_n); return 1; }