I'd like to thank several people for looking into my assertion that it
is possible for common factors in p-1 and q-1 to leak from the
factorisation of n-1.
Particularly, Viktor Dukhovni, for trying tens of thousands of key
generation iterations to see if common factors are possible. From
Viktor's work and other people's comments I drew the following
conclusions:
Viktor Dukhovni reports, after looking at the rsa key generation code
of openssl, that p-1 and q-1 are both checked for the first 2048
factors (up to 17863). As such such low primes are not possible as
factors of either p-1 or q-1. However, common factors higher than
17863 are possible as factors of both p-1 and q-1. But it takes
20,000 key generations (not in safe mode) before such an event
happens. He managed to get a common factor of gcd(p-1,q-1) = 2 * 28559
from the following 1024 bit rsa generated key (factorisation of p*q-1
is shown):
n-1 = 2 * 3^3 * 7 * 13 * 67 * 2399 * 28559 *
5485062554686449262177590194597345407327047899375366044215091312099734701911004226037445837630559113651708968440813791318544450398897628 67234233761906471233193768567784328338581360170038166729050302672416075037390699071355182394190448204086007354388034161296410061846686501
4941425056336718955019
Any rsa key generation in SAFE mode will always have a gcd(p-1,q-1)=2,
so SAFE mode always avoids common factors.
My conclusion is that openssl code can have common factors (must be
above 17863) in its rsa keys every 20,000 key generations or so when
not generated in SAFE mode, and that at this time approximately 30
bits of the totient will be revealed out of the 1024 bits of the full
totient. There is, of course, no way of knowing which of the 20,000
key generations will have the common factors.
Most people felt that the check (for gcd(p-1,q-1)> 16) was possible
but they were not sure it was worth doing.
I'd like to point out from a cyber-attack possibility the check is
worth doing. In RSA_generate_key_ex() in rsa_gen.c the following code
is seen:
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
{
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD);
return 0;
}
#endif
if (rsa->meth->rsa_keygen)
return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
#ifdef OPENSSL_FIPS
if (FIPS_mode())
return FIPS_rsa_generate_key_ex(rsa, bits, e_value, cb);
#endif
return rsa_builtin_keygen(rsa, bits, e_value, cb);
}
Third party modules, or methods, can be added to openssl code and
these can do the rsa key generation as in:
if (rsa->meth->rsa_keygen)
return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
As such it is appropriate that some checks be made at
RSA_generate_key_ex() to make sure that the other software hasn't
returned a bad key. Openssl software is a significant part of the
Internet security infastructure and so it would obviously be the
target of hacking and cyber infiltration. Some redundant checks are
appropriate because of this.
A gcd(p-1,q-1)>16 check will disallow less than 1 percent of the
currently acceptable keys, won't take much time to run, and would
defeat cyber attempts to create a key with a significant common factor
within it.
Thanks
Paul Cheffers
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev