mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-18 11:31:00 -05:00
Fix RSA key gen at awkward sizes mod BIGNUM_INT_BITS.
If you try to generate (say) a 2049-bit RSA key, then primegen will try to generate a 1025-bit prime. It will do it by making a random 1024-bit mp_int (that is, one strictly _less_ than 2^1024), and then trying to set bit 1024. But that will fail an assertion in mp_set_bit, because the number of random bits is a multiple of BIGNUM_INT_BITS, so an mp_int of the minimum size that can hold the random bits is not quite big enough to hold the extra bit at the top. Fix: change the strategy in primegen so that we allocate the mp_int large enough to hold even the top bit, and copy in the random numbers via mp_or_into. There's a second bug hiding behind that one. If the key has odd size, then the two primes are generated with different bit lengths. If the overall key size is congruent to 1 mod (2*BIGNUM_INT_BITS), then the two primes will be allocated as mp_ints with different numbers of words, leading to another assertion failure in the mp_cond_swap that sorts the primes into a consistent order. Fix for that one: if the primes are being generated different bit lengths, then we arrange those lengths to be already in the right order, and replace the mp_cond_swap with an assert() that checks the ordering is already correct. Combined effect: now you should be able to successfully generate a 2049-bit key without assertion failures.
This commit is contained in:
21
sshrsag.c
21
sshrsag.c
@ -71,15 +71,26 @@ int rsa_generate(RSAKey *key, int bits, progfn_t pfn,
|
||||
* but it doesn't cost much to make sure.)
|
||||
*/
|
||||
invent_firstbits(&pfirst, &qfirst, 2);
|
||||
mp_int *p = primegen(bits / 2, RSA_EXPONENT, 1, NULL,
|
||||
1, pfn, pfnparam, pfirst);
|
||||
mp_int *q = primegen(bits - bits / 2, RSA_EXPONENT, 1, NULL,
|
||||
2, pfn, pfnparam, qfirst);
|
||||
int qbits = bits / 2;
|
||||
int pbits = bits - qbits;
|
||||
assert(pbits >= qbits);
|
||||
mp_int *p = primegen(pbits, RSA_EXPONENT, 1, NULL,
|
||||
1, pfn, pfnparam, pfirst);
|
||||
mp_int *q = primegen(qbits, RSA_EXPONENT, 1, NULL,
|
||||
2, pfn, pfnparam, qfirst);
|
||||
|
||||
/*
|
||||
* Ensure p > q, by swapping them if not.
|
||||
*
|
||||
* We only need to do this if the two primes were generated with
|
||||
* the same number of bits (i.e. if the requested key size is
|
||||
* even) - otherwise it's already guaranteed!
|
||||
*/
|
||||
mp_cond_swap(p, q, mp_cmp_hs(q, p));
|
||||
if (pbits == qbits) {
|
||||
mp_cond_swap(p, q, mp_cmp_hs(q, p));
|
||||
} else {
|
||||
assert(mp_cmp_hs(p, q));
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have p, q and e. All we need to do now is work out
|
||||
|
Reference in New Issue
Block a user