Support 4096-bit keys in FIPS mode.

Change-Id: I9aa66109bd0f6acc0c30a505eef6d85b6972132d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43624
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c
index 86ff2f3..7343b75 100644
--- a/crypto/fipsmodule/rsa/rsa_impl.c
+++ b/crypto/fipsmodule/rsa/rsa_impl.c
@@ -933,20 +933,57 @@
   return *out != NULL;
 }
 
-// kBoringSSLRSASqrtTwo is the BIGNUM representation of ⌊2¹⁵³⁵×√2⌋. This is
-// chosen to give enough precision for 3072-bit RSA, the largest key size FIPS
+// kBoringSSLRSASqrtTwo is the BIGNUM representation of ⌊2²⁰⁴⁷×√2⌋. This is
+// chosen to give enough precision for 4096-bit RSA, the largest key size FIPS
 // specifies. Key sizes beyond this will round up.
 //
-// To verify this number, check that n² < 2³⁰⁷¹ < (n+1)², where n is value
+// To calculate, use the following Haskell code:
+//
+// import Text.Printf (printf)
+// import Data.List (intercalate)
+//
+// pow2 = 4095
+// target = 2^pow2
+//
+// f x = x*x - (toRational target)
+//
+// fprime x = 2*x
+//
+// newtonIteration x = x - (f x) / (fprime x)
+//
+// converge x =
+//   let n = floor x in
+//   if n*n - target < 0 && (n+1)*(n+1) - target > 0
+//     then n
+//     else converge (newtonIteration x)
+//
+// divrem bits x = (x `div` (2^bits), x `rem` (2^bits))
+//
+// bnWords :: Integer -> [Integer]
+// bnWords x =
+//   if x == 0
+//     then []
+//     else let (high, low) = divrem 64 x in low : bnWords high
+//
+// showWord x = let (high, low) = divrem 32 x in printf "TOBN(0x%08x, 0x%08x)" high low
+//
+// output :: String
+// output = intercalate ", " $ map showWord $ bnWords $ converge (2 ^ (pow2 `div` 2))
+//
+// To verify this number, check that n² < 2⁴⁰⁹⁵ < (n+1)², where n is value
 // represented here. Note the components are listed in little-endian order. Here
 // is some sample Python code to check:
 //
 //   >>> TOBN = lambda a, b: a << 32 | b
 //   >>> l = [ <paste the contents of kSqrtTwo> ]
 //   >>> n = sum(a * 2**(64*i) for i, a in enumerate(l))
-//   >>> n**2 < 2**3071 < (n+1)**2
+//   >>> n**2 < 2**4095 < (n+1)**2
 //   True
 const BN_ULONG kBoringSSLRSASqrtTwo[] = {
+    TOBN(0x4d7c60a5, 0xe633e3e1), TOBN(0x5fcf8f7b, 0xca3ea33b),
+    TOBN(0xc246785e, 0x92957023), TOBN(0xf9acce41, 0x797f2805),
+    TOBN(0xfdfe170f, 0xd3b1f780), TOBN(0xd24f4a76, 0x3facb882),
+    TOBN(0x18838a2e, 0xaff5f3b2), TOBN(0xc1fcbdde, 0xa2f7dc33),
     TOBN(0xdea06241, 0xf7aa81c2), TOBN(0xf6a1be3f, 0xca221307),
     TOBN(0x332a5e9f, 0x7bda1ebf), TOBN(0x0104dc01, 0xfe32352f),
     TOBN(0xb8cf341b, 0x6f8236c7), TOBN(0x4264dabc, 0xd528b651),
@@ -1167,13 +1204,13 @@
   int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2;
   assert(sqrt2_bits == (int)BN_num_bits(sqrt2));
   if (sqrt2_bits > prime_bits) {
-    // For key sizes up to 3072 (prime_bits = 1536), this is exactly
+    // For key sizes up to 4096 (prime_bits = 2048), this is exactly
     // ⌊2^(prime_bits-1)×√2⌋.
     if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) {
       goto bn_err;
     }
   } else if (prime_bits > sqrt2_bits) {
-    // For key sizes beyond 3072, this is approximate. We err towards retrying
+    // For key sizes beyond 4096, this is approximate. We err towards retrying
     // to ensure our key is the right size and round up.
     if (!BN_add_word(sqrt2, 1) ||
         !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) {
@@ -1330,7 +1367,9 @@
 int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb) {
   // FIPS 186-4 allows 2048-bit and 3072-bit RSA keys (1024-bit and 1536-bit
   // primes, respectively) with the prime generation method we use.
-  if (bits != 2048 && bits != 3072) {
+  // Subsequently, IG A.14 stated that larger modulus sizes can be used and ACVP
+  // testing supports 4096 bits.
+  if (bits != 2048 && bits != 3072 && bits != 4096) {
     OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
     return 0;
   }
diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc
index e9b68c9..883eb97 100644
--- a/crypto/rsa_extra/rsa_test.cc
+++ b/crypto/rsa_extra/rsa_test.cc
@@ -496,24 +496,26 @@
   bssl::UniquePtr<RSA> rsa(RSA_new());
   ASSERT_TRUE(rsa);
 
-  // RSA_generate_key_fips may only be used for 2048-bit and 3072-bit keys.
+  // RSA_generate_key_fips may only be used for 2048-, 3072-, and 4096-bit
+  // keys.
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 512, nullptr));
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 1024, nullptr));
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 2047, nullptr));
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 2049, nullptr));
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 3071, nullptr));
   EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 3073, nullptr));
-  EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 4096, nullptr));
+  EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 4095, nullptr));
+  EXPECT_FALSE(RSA_generate_key_fips(rsa.get(), 4097, nullptr));
   ERR_clear_error();
 
-  // Test that we can generate 2048-bit and 3072-bit RSA keys.
-  ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), 2048, nullptr));
-  EXPECT_EQ(2048u, BN_num_bits(rsa->n));
+  // Test that we can generate keys of the supported lengths:
+  for (const size_t bits : {2048, 3072, 4096}) {
+    SCOPED_TRACE(bits);
 
-  rsa.reset(RSA_new());
-  ASSERT_TRUE(rsa);
-  ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), 3072, nullptr));
-  EXPECT_EQ(3072u, BN_num_bits(rsa->n));
+    rsa.reset(RSA_new());
+    ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), bits, nullptr));
+    EXPECT_EQ(bits, BN_num_bits(rsa->n));
+  }
 }
 
 TEST(RSATest, BadKey) {
@@ -1044,8 +1046,8 @@
   ASSERT_TRUE(BN_sqr(sqrt.get(), sqrt.get(), ctx.get()));
   EXPECT_LT(BN_cmp(pow2.get(), sqrt.get()), 0);
 
-  // Check the kBoringSSLRSASqrtTwo is sized for a 3072-bit RSA key.
-  EXPECT_EQ(3072u / 2u, bits);
+  // Check the kBoringSSLRSASqrtTwo is sized for a 4096-bit RSA key.
+  EXPECT_EQ(4096u / 2u, bits);
 }
 #endif  // !BORINGSSL_SHARED_LIBRARY