From 5833dd807e3deab0d3ba110f8692e16aa4d78ed5 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 3 Mar 2018 22:07:49 -0500 Subject: [PATCH] Limit the public exponent in RSA_generate_key_ex. Windows CryptoAPI and Go bound public exponents at 2^32-1, so don't generate keys which would violate that. https://github.com/golang/go/issues/3161 https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx BoringSSL itself also enforces a 33-bit limit. I don't currently have plans to take much advantage of it, but the modular inverse step and one of the GCDs in RSA key generation are helped by small public exponents[0]. In case someone feels inspired later, get this limit enforced now. Use 32-bits as that's a more convenient limit, and there's no requirement to produce e=2^32+1 keys. (Is there still a requirement to accept them?) [0] This isn't too bad, but it's only worth it if it produces simpler or smaller code. RSA keygen is not performance-critical. 1. Make bn_mod_u16_consttime work for uint32_t. It only barely doesn't work. Maybe only accept 3 and 65537 and pre-compute, maybe call into bn_div_rem_words and friends, maybe just tighten the bound a hair longer. 2. Implement bn_div_u32_consttime by incorporating 32-bit chunks much like bn_mod_u32_consttime. 3. Perform one normal Euclidean algorithm iteration rather than using the binary version. u, v, B, and D are now single words, while A and C are full-width. 4. Continue with binary Euclidean algorithm (u and v are still secret), taking advantage of most values being small. Update-Note: RSA_generate_key_ex will no longer generate keys with public exponents larger than 2^32-1. Everyone uses 65537, save some folks who use 3, so this shouldn't matter. Change-Id: I0d28a29a30d9ff73bff282e34dd98e2b64c35c79 Reviewed-on: https://boringssl-review.googlesource.com/26365 Reviewed-by: Adam Langley --- crypto/fipsmodule/rsa/rsa_impl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index 90d2e9a0..49cbc15a 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -1042,6 +1042,17 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { return 0; } + // Reject excessively large public exponents. Windows CryptoAPI and Go don't + // support values larger than 32 bits, so match their limits for generating + // keys. (|check_modulus_and_exponent_sizes| uses a slightly more conservative + // value, but we don't need to support generating such keys.) + // https://github.com/golang/go/issues/3161 + // https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + if (BN_num_bits(e_value) > 32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + int ret = 0; int prime_bits = bits / 2; BN_CTX *ctx = BN_CTX_new();