openssl: RSA key generation on arm processor with default parameters hangs
I have tried this on openssl 3.1.2 and 3.1.3 and gotten same results. When attempting to generate rsa keys using default parameters on our arm based processor, it hangs and never finishes (at least not in the 1.5 hours I let it run for). The same code on an x86_64 processor runs fine. Below is some info about our CPU. After tweaking number of bits and number of exponents and finding less recommended values worked and fiddling with gdb, I found that when the ossl_rsa_sp800_56b_generate_key routine is used, it never returns - seems like it always choses a “d” that is 1 bit too small and keeps trying forever. In rsa_sp800_56b_gen.c, routine ossl_rsa_sp800_56b_derive_params_from_pq, line 273 - step 3, it returns the same number of bits as nbits divided by 2 every time and just repeats:
/* (Step 3) return an error if d is too small */
if (BN_num_bits(rsa->d) <= (nbits >> 1)) {
ret = 0;
goto err;
}
However, if I force it to call the rsa_multiprime_keygen routine, it works as expected. For now, I am applying the following patch on our ARM processor:
--- openssl-3.1.2/crypto/rsa/rsa_gen.c.orig 2023-08-01 08:36:55.000000000 -0500
+++ openssl-3.1.2/crypto/rsa/rsa_gen.c 2023-09-28 10:30:59.731975152 -0500
@@ -434,11 +434,13 @@ static int rsa_keygen(OSSL_LIB_CTX *libc
* Only multi-prime keys or insecure keys with a small key length or a
* public exponent <= 2^16 will use the older rsa_multiprime_keygen().
*/
+/*APCON - ossl_rsa_sp800_56b_generate_key seems to hang indefinitely. Go back to the "old" way!
if (primes == 2
&& bits >= 2048
&& (e_value == NULL || BN_num_bits(e_value) > 16))
ok = ossl_rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
else
+*/
ok = rsa_multiprime_keygen(rsa, bits, primes, e_value, cb);
#endif /* FIPS_MODULE */
Any advice on this course of action or a fix would be greatly appreciated.
Testing on ARM target with original code just results in apparent hung-for-ever comand:
root@Plano-Dev:/tmp# openssl genrsa -out t.key
^C
root@Plano-Dev:/tmp# cat /proc/cpuinfo
processor : 0
model name : ARMv7 Processor rev 2 (v7l)
BogoMIPS : 1332.01
Features : half thumb fastmult vfp edsp thumbee vfpv3 tls idiva idivt vfpd32 lpae
CPU implementer : 0x56
CPU architecture: 7
CPU variant : 0x2
CPU part : 0x584
CPU revision : 2
processor : 1
model name : ARMv7 Processor rev 2 (v7l)
BogoMIPS : 1332.01
Features : half thumb fastmult vfp edsp thumbee vfpv3 tls idiva idivt vfpd32 lpae
CPU implementer : 0x56
CPU architecture: 7
CPU variant : 0x2
CPU part : 0x584
CPU revision : 2
processor : 2
model name : ARMv7 Processor rev 2 (v7l)
BogoMIPS : 1332.01
Features : half thumb fastmult vfp edsp thumbee vfpv3 tls idiva idivt vfpd32 lpae
CPU implementer : 0x56
CPU architecture: 7
CPU variant : 0x2
CPU part : 0x584
CPU revision : 2
processor : 3
model name : ARMv7 Processor rev 2 (v7l)
BogoMIPS : 1332.01
Features : half thumb fastmult vfp edsp thumbee vfpv3 tls idiva idivt vfpd32 lpae
CPU implementer : 0x56
CPU architecture: 7
CPU variant : 0x2
CPU part : 0x584
CPU revision : 2
Hardware : Marvell Armada 370/XP (Device Tree)
Revision : 0000
Serial : 0000000000000000
root@Plano-Dev:/tmp# openssl version
OpenSSL 3.1.2 1 Aug 2023 (Library: OpenSSL 3.1.2 1 Aug 2023)
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Comments: 40 (21 by maintainers)
Commits related to this issue
- BN_gcd(): Avoid shifts of negative values Fixes #22216 — committed to t8m/openssl by t8m 9 months ago
- BN_gcd(): Avoid shifts of negative values Fixes #22216 Thanks to Leland Mills for investigation and testing. — committed to t8m/openssl by t8m 9 months ago
- BN_gcd(): Avoid shifts of negative values Fixes #22216 Thanks to Leland Mills for investigation and testing. Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com> Reviewed-by: Matt Caswell <matt@openssl... — committed to openssl/openssl by t8m 9 months ago
- BN_gcd(): Avoid shifts of negative values Fixes #22216 Thanks to Leland Mills for investigation and testing. Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com> Reviewed-by: Matt Caswell <matt@openssl... — committed to openssl/openssl by t8m 9 months ago
- BN_gcd(): Avoid shifts of negative values Fixes #22216 Thanks to Leland Mills for investigation and testing. Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com> Reviewed-by: Matt Caswell <matt@openssl... — committed to absole/openssl by t8m 9 months ago
Actually, thank you for working through and helping us get to the root of the problem - much appreciated
Yes, any shift right of a signed value is a (potential) problem (technically, a right shift of a negative signed value might not give the same result on different implementations, where “implementation” can include “same compiler and target, but different optimisation level”).
The code is written the way it is so that it is constant time - i.e. it doesn’t branch based on the value of sensitive data (since this can lead to timing attacks).
Everything works at -O2 unless I compile the BN_gcd function within bn_gcd.c - that one, for me needs to be compiled with -O1 to work. I’ll try hacking it up and getting it narrowed down even further.