Bug 596692 and bug 636802: Increase max RSA and DH key sizes to 16K bits.
authorwtc%google.com
Thu, 14 Jun 2012 18:55:10 +0000
changeset 10377 f43add98969cb71594c6ab41de424acfd3983455
parent 10376 ace6564665deadc79d08f5865321260ca5630b91
child 10378 a28f7deaed332c2e8d663ac62dc397448ac12133
push idunknown
push userunknown
push dateunknown
bugs596692, 636802
Bug 596692 and bug 636802: Increase max RSA and DH key sizes to 16K bits. Adjust DH secret key size to group size. r=rrelyea. Modified Files: blapit.h dh.c
security/nss/lib/freebl/blapit.h
security/nss/lib/freebl/dh.c
--- a/security/nss/lib/freebl/blapit.h
+++ b/security/nss/lib/freebl/blapit.h
@@ -124,20 +124,20 @@ typedef int __BLAPI_DEPRECATED __attribu
 
 #define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048
 
 /*
  * These values come from the initial key size limits from the PKCS #11
  * module. They may be arbitrarily adjusted to any value freebl supports.
  */
 #define RSA_MIN_MODULUS_BITS   128
-#define RSA_MAX_MODULUS_BITS  8192
+#define RSA_MAX_MODULUS_BITS 16384
 #define RSA_MAX_EXPONENT_BITS   64
 #define DH_MIN_P_BITS	       128
-#define DH_MAX_P_BITS         3072
+#define DH_MAX_P_BITS        16384
 
 /*
  * The FIPS 186-1 algorithm for generating primes P and Q allows only 9
  * distinct values for the length of P, and only one value for the
  * length of Q.
  * The algorithm uses a variable j to indicate which of the 9 lengths
  * of P is to be used.
  * The following table relates j to the lengths of P and Q in bits.
--- a/security/nss/lib/freebl/dh.c
+++ b/security/nss/lib/freebl/dh.c
@@ -16,19 +16,38 @@
 #include "secerr.h"
 
 #include "blapi.h"
 #include "secitem.h"
 #include "mpi.h"
 #include "mpprime.h"
 #include "secmpi.h"
 
-#define DH_SECRET_KEY_LEN      20
 #define KEA_DERIVED_SECRET_LEN 128
 
+/* Lengths are in bytes. */
+static unsigned int
+dh_GetSecretKeyLen(unsigned int primeLen)
+{
+    /* Based on Table 2 in NIST SP 800-57. */
+    if (primeLen >= 1920) { /* 15360 bits */
+        return 64;  /* 512 bits */
+    }
+    if (primeLen >= 960) { /* 7680 bits */
+        return 48;  /* 384 bits */
+    }
+    if (primeLen >= 384) { /* 3072 bits */
+        return 32;  /* 256 bits */
+    }
+    if (primeLen >= 256) { /* 2048 bits */
+        return 28;  /* 224 bits */
+    }
+    return 20;  /* 160 bits */
+}
+
 SECStatus 
 DH_GenParam(int primeLen, DHParams **params)
 {
     PRArenaPool *arena;
     DHParams *dhparams;
     unsigned char *pb = NULL;
     unsigned char *ab = NULL;
     unsigned long counter = 0;
@@ -149,17 +168,18 @@ DH_NewKey(DHParams *params, DHPrivateKey
     CHECK_MPI_OK( mp_init(&Ya) );
     /* Set private key's p */
     CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->prime, &params->prime) );
     SECITEM_TO_MPINT(key->prime, &p);
     /* Set private key's g */
     CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->base, &params->base) );
     SECITEM_TO_MPINT(key->base, &g);
     /* Generate private key xa */
-    SECITEM_AllocItem(arena, &key->privateValue, DH_SECRET_KEY_LEN);
+    SECITEM_AllocItem(arena, &key->privateValue,
+                      dh_GetSecretKeyLen(params->prime.len));
     RNG_GenerateGlobalRandomBytes(key->privateValue.data, 
                                   key->privateValue.len);
     SECITEM_TO_MPINT( key->privateValue, &xa );
     /* xa < p */
     CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
     /* Compute public key Ya = g ** xa mod p */
     CHECK_MPI_OK( mp_exptmod(&g, &xa, &p, &Ya) );
     MPINT_TO_SECITEM(&Ya, &key->publicValue, key->arena);