Blob Blame History Raw
diff -up ./nss/lib/freebl/mpi/mpprime.c.fips-186-4 ./nss/lib/freebl/mpi/mpprime.c
--- ./nss/lib/freebl/mpi/mpprime.c.fips-186-4	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/lib/freebl/mpi/mpprime.c	2014-10-16 09:54:02.787374811 -0700
@@ -410,31 +410,32 @@ mp_err mpp_make_prime(mp_int *start, mp_
   MP_DIGITS(&q) = 0;
   MP_CHECKOK( mp_init(&trial) );
   MP_CHECKOK( mp_init(&q)     );
-  /* values taken from table 4.4, HandBook of Applied Cryptography */
-  if (nBits >= 1300) {
-    num_tests = 2;
-  } else if (nBits >= 850) {
+  /* values originally taken from table 4.4, 
+   * HandBook of Applied Cryptography, augmented by FIPS-186
+   * requirements, Table C.2 and C.3 */
+  if (nBits >= 2000) {
     num_tests = 3;
-  } else if (nBits >= 650) {
+  } else if (nBits >= 1536) {
     num_tests = 4;
-  } else if (nBits >= 550) {
+  } else if (nBits >= 1024) {
     num_tests = 5;
-  } else if (nBits >= 450) {
+  } else if (nBits >= 550) {
     num_tests = 6;
-  } else if (nBits >= 400) {
+  } else if (nBits >= 450) {
     num_tests = 7;
-  } else if (nBits >= 350) {
+  } else if (nBits >= 400) {
     num_tests = 8;
-  } else if (nBits >= 300) {
+  } else if (nBits >= 350) {
     num_tests = 9;
+  } else if (nBits >= 300) {
+    num_tests = 10;
   } else if (nBits >= 250) {
-    num_tests = 12;
+    num_tests = 20;
   } else if (nBits >= 200) {
-    num_tests = 15;
-  } else if (nBits >= 150) {
-    num_tests = 18;
+    num_tests = 41;
   } else if (nBits >= 100) {
-    num_tests = 27;
+    num_tests = 38;  /* funny anomaly in the FIPS tables, for aux primes, the
+	              * required more iterations for larger aux primes */
   } else
     num_tests = 50;
 
diff -up ./nss/lib/freebl/rsa.c.fips-186-4 ./nss/lib/freebl/rsa.c
--- ./nss/lib/freebl/rsa.c.fips-186-4	2014-10-16 09:54:02.784374761 -0700
+++ ./nss/lib/freebl/rsa.c	2014-10-16 15:08:33.946099491 -0700
@@ -138,7 +138,7 @@ rsa_build_from_primes(const mp_int *p, c
     CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) );
     CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) );
     if (needPublicExponent || needPrivateExponent) {
-	CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) );
+	CHECK_MPI_OK( mp_lcm(&psub1, &qsub1, &phi) );
 	/* 3.  Compute d = e**-1 mod(phi) */
 	/*     or      e = d**-1 mod(phi) as necessary */
 	if (needPublicExponent) {
@@ -226,6 +226,45 @@ cleanup:
 }
 
 /*
+ *  make sure the key components meet fips186 requirements.
+ */
+static PRBool
+rsa_fips186_verify(mp_int *p, mp_int *q, mp_int *d, int keySizeInBits)
+{
+    mp_int pq_diff;
+    mp_err   err = MP_OKAY;
+    PRBool ret=PR_FALSE;
+
+    if (keySizeInBits < 250) {
+ 	/* not a valid FIPS length, no point in our other tests */
+	/* if you are here, and in FIPS mode, you are outside the security 
+  	 * policy */
+	return PR_TRUE;
+    }
+
+    /* p & q are already known to be greater then sqrt(2)*2^(keySize/2-1) */
+    /* we also know that gcd(p-1,e) = 1 and gcd(q-1,e) = 1 because the 
+     * mp_invmod() function will fail. */
+    /* now check p-q > 2^(keysize/2-100) */
+    MP_DIGITS(&pq_diff) = 0;
+    CHECK_MPI_OK( mp_init(&pq_diff) );
+    /* NSS always has p > q, so we know pq_diff is positive */
+    CHECK_MPI_OK( mp_sub(p,q,&pq_diff) );
+    if ((unsigned)mpl_significant_bits(&pq_diff) < (keySizeInBits/2 - 100)) {
+	goto cleanup;
+    }
+    /* now verify d is large enough*/
+    if ((unsigned)mpl_significant_bits(d) < (keySizeInBits/2)) {
+	goto cleanup;
+    }
+    ret = PR_TRUE;
+
+cleanup:
+    mp_clear(&pq_diff);
+    return ret;
+}
+
+/*
 ** Generate and return a new RSA public and private key.
 **	Both keys are encoded in a single RSAPrivateKey structure.
 **	"cx" is the random number generator context
@@ -241,6 +280,7 @@ RSA_NewKey(int keySizeInBits, SECItem *p
     unsigned int primeLen;
     mp_int p, q, e, d;
     int kiter;
+    int max_attempts;
     mp_err   err = MP_OKAY;
     SECStatus rv = SECSuccess;
     int prerr = 0;
@@ -281,6 +321,7 @@ RSA_NewKey(int keySizeInBits, SECItem *p
     /* 3.  Set the public exponent */
     SECITEM_TO_MPINT(*publicExponent, &e);
     kiter = 0;
+    max_attempts = 5*(keySizeInBits/2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */
     do {
 	prerr = 0;
 	PORT_SetError(0);
@@ -298,12 +339,18 @@ RSA_NewKey(int keySizeInBits, SECItem *p
 			&e, PR_FALSE,  /* needPublicExponent=false */
 			&d, PR_TRUE,   /* needPrivateExponent=true */
 			key, keySizeInBits);
-	if (rv == SECSuccess)
-	    break; /* generated two good primes */
+	if (rv == SECSuccess) {
+	    if (rsa_fips186_verify(&p, &q, &d, keySizeInBits) ){
+		break;
+	    }
+	    prerr = PORT_GetError();
+	} else {
+	    prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
+	}
 	prerr = PORT_GetError();
 	kiter++;
 	/* loop until have primes */
-    } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
+    } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts);
     if (prerr)
 	goto cleanup;
 cleanup: