Use a higher iteration limit for RSA key generation at e = 3.
Generating a 2048-bit RSA key with e = 3 (don't do this), the failure
rate at 5*bits iterations appears to be around 7 failures in 1000 tries.
Bump the limit up to 32*bits. This should give a failure rate of around
2 failures in 10^14 tries.
(The FIPS 186-4 algorithm is meant for saner values of e, like 65537. e
= 3 implies a restrictive GCD requirement: the primes must both be 2 mod
3.)
Change-Id: Icd373f61e2eb90df5afaff9a0fc2b2fbb6ec3f0a
Reviewed-on: https://boringssl-review.googlesource.com/22584
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c
index b89eccb..adbb69f 100644
--- a/crypto/fipsmodule/rsa/rsa_impl.c
+++ b/crypto/fipsmodule/rsa/rsa_impl.c
@@ -807,11 +807,16 @@
return 0;
}
- // Ensure the bound on |tries| does not overflow.
- if (bits >= INT_MAX/5) {
+ // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is nlen/2.
+
+ // Use the limit from steps 4.7 and 5.8 for most values of |e|. When |e| is 3,
+ // the 186-4 limit is too low, so we use a higher one. Note this case is not
+ // reachable from |RSA_generate_key_fips|.
+ if (bits >= INT_MAX/32) {
OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
return 0;
}
+ int limit = BN_is_word(e, 3) ? bits * 32 : bits * 5;
int ret = 0, tries = 0, rand_tries = 0;
BN_CTX_start(ctx);
@@ -820,8 +825,6 @@
goto err;
}
- // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is
- // nlen/2.
for (;;) {
// Generate a random number of length |bits| where the bottom bit is set
// (steps 4.2, 4.3, 5.2 and 5.3) and the top bit is set (implied by the
@@ -890,7 +893,7 @@
// If we've tried too many times to find a prime, abort (steps 4.7 and
// 5.8).
tries++;
- if (tries >= bits * 5) {
+ if (tries >= limit) {
OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
goto err;
}