| Index: nss/mozilla/security/nss/lib/freebl/pqg.c
|
| ===================================================================
|
| --- nss/mozilla/security/nss/lib/freebl/pqg.c (revision 162724)
|
| +++ nss/mozilla/security/nss/lib/freebl/pqg.c (working copy)
|
| @@ -5,7 +5,7 @@
|
| /*
|
| * PQG parameter generation/verification. Based on FIPS 186-3.
|
| *
|
| - * $Id: pqg.c,v 1.23 2012/09/25 23:38:38 wtc%google.com Exp $
|
| + * $Id: pqg.c,v 1.25 2012/10/11 00:18:23 rrelyea%redhat.com Exp $
|
| */
|
| #ifdef FREEBL_NO_DEPEND
|
| #include "stubs.h"
|
| @@ -73,7 +73,7 @@
|
| * this gives us one place to go if we need to bump the requirements in the
|
| * future.
|
| */
|
| -SECStatus static
|
| +static SECStatus
|
| pqg_validate_dsa2(unsigned int L, unsigned int N)
|
| {
|
|
|
| @@ -103,6 +103,27 @@
|
| return SECSuccess;
|
| }
|
|
|
| +static unsigned int
|
| +pqg_get_default_N(unsigned int L)
|
| +{
|
| + unsigned int N = 0;
|
| + switch (L) {
|
| + case 1024:
|
| + N = DSA1_Q_BITS;
|
| + break;
|
| + case 2048:
|
| + N = 224;
|
| + break;
|
| + case 3072:
|
| + N = 256;
|
| + break;
|
| + default:
|
| + PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| + break; /* N already set to zero */
|
| + }
|
| + return N;
|
| +}
|
| +
|
| /*
|
| * Select the lowest hash algorithm usable
|
| */
|
| @@ -221,7 +242,7 @@
|
| return SECFailure;
|
| }
|
| j = PQG_PBITS_TO_INDEX(L);
|
| - if ( j >= 0 && j <= 8 ) {
|
| + if ( j < 0 ) {
|
| PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| rv = SECFailure;
|
| }
|
| @@ -1223,7 +1244,10 @@
|
| PQGVerify *verify = NULL;
|
| PRBool passed;
|
| SECItem hit = { 0, 0, 0 };
|
| - mp_int P, Q, G, H, l;
|
| + SECItem firstseed = { 0, 0, 0 };
|
| + SECItem qseed = { 0, 0, 0 };
|
| + SECItem pseed = { 0, 0, 0 };
|
| + mp_int P, Q, G, H, l, p0;
|
| mp_err err = MP_OKAY;
|
| SECStatus rv = SECFailure;
|
| int iterations = 0;
|
| @@ -1271,11 +1295,13 @@
|
| MP_DIGITS(&G) = 0;
|
| MP_DIGITS(&H) = 0;
|
| MP_DIGITS(&l) = 0;
|
| + MP_DIGITS(&p0) = 0;
|
| CHECK_MPI_OK( mp_init(&P) );
|
| CHECK_MPI_OK( mp_init(&Q) );
|
| CHECK_MPI_OK( mp_init(&G) );
|
| CHECK_MPI_OK( mp_init(&H) );
|
| CHECK_MPI_OK( mp_init(&l) );
|
| + CHECK_MPI_OK( mp_init(&p0) );
|
|
|
| /* Select Hash and Compute lengths. */
|
| /* getFirstHash gives us the smallest acceptable hash for this key
|
| @@ -1314,11 +1340,48 @@
|
| ** "q = 2**(N-1) + U + 1 - (U mod 2) (186-3)
|
| **
|
| ** Note: Both formulations are the same for U < 2**(N-1) and N=160
|
| + **
|
| + ** If using Shawe-Taylor, We do the entire A.1.2.1.2 setps in the block
|
| + ** FIPS186_3_ST_TYPE.
|
| */
|
| if (type == FIPS186_1_TYPE) {
|
| CHECK_SEC_OK( makeQfromSeed(seedlen, seed, &Q) );
|
| + } else if (type == FIPS186_3_TYPE) {
|
| + CHECK_SEC_OK( makeQ2fromSeed(hashtype, N, seed, &Q) );
|
| } else {
|
| - CHECK_SEC_OK( makeQ2fromSeed(hashtype, N, seed, &Q) );
|
| + /* FIPS186_3_ST_TYPE */
|
| + int qgen_counter, pgen_counter;
|
| +
|
| + /* Step 1 (L,N) already checked for acceptability */
|
| +
|
| + firstseed = *seed;
|
| + qgen_counter = 0;
|
| + /* Step 2. Use N and firstseed to generate random prime q
|
| + * using Apendix C.6 */
|
| + CHECK_SEC_OK( makePrimefromSeedShaweTaylor(hashtype, N, &firstseed, &Q,
|
| + &qseed, &qgen_counter) );
|
| + /* Step 3. Use floor(L/2+1) and qseed to generate random prime p0
|
| + * using Appendix C.6 */
|
| + pgen_counter = 0;
|
| + CHECK_SEC_OK( makePrimefromSeedShaweTaylor(hashtype, (L+1)/2+1,
|
| + &qseed, &p0, &pseed, &pgen_counter) );
|
| + /* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
|
| + CHECK_SEC_OK( makePrimefromPrimesShaweTaylor(hashtype, L,
|
| + &p0, &Q, &P, &pseed, &pgen_counter) );
|
| +
|
| + /* combine all the seeds */
|
| + seed->len = firstseed.len +qseed.len + pseed.len;
|
| + seed->data = PORT_ArenaZAlloc(verify->arena, seed->len);
|
| + if (seed->data == NULL) {
|
| + goto cleanup;
|
| + }
|
| + PORT_Memcpy(seed->data, firstseed.data, firstseed.len);
|
| + PORT_Memcpy(seed->data+firstseed.len, pseed.data, pseed.len);
|
| + PORT_Memcpy(seed->data+firstseed.len+pseed.len, qseed.data, qseed.len);
|
| + counter = 0 ; /* (qgen_counter << 16) | pgen_counter; */
|
| +
|
| + /* we've generated both P and Q now, skip to generating G */
|
| + goto generate_G;
|
| }
|
| /* ******************************************************************
|
| ** Step 8. (Step 4 in 186-1)
|
| @@ -1403,6 +1466,8 @@
|
| */
|
| if (counter > maxCount)
|
| goto step_5;
|
| +
|
| +generate_G:
|
| /* ******************************************************************
|
| ** returning p, q, seed and counter
|
| */
|
| @@ -1435,11 +1500,18 @@
|
| *pParams = params;
|
| *pVfy = verify;
|
| cleanup:
|
| + if (pseed.data) {
|
| + PORT_Free(pseed.data);
|
| + }
|
| + if (qseed.data) {
|
| + PORT_Free(qseed.data);
|
| + }
|
| mp_clear(&P);
|
| mp_clear(&Q);
|
| mp_clear(&G);
|
| mp_clear(&H);
|
| mp_clear(&l);
|
| + mp_clear(&p0);
|
| if (err) {
|
| MP_TO_SEC_ERROR(err);
|
| rv = SECFailure;
|
| @@ -1489,11 +1561,18 @@
|
| PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
|
| PQGParams **pParams, PQGVerify **pVfy)
|
| {
|
| + if (N == 0) {
|
| + N = pqg_get_default_N(L);
|
| + }
|
| + if (seedBytes == 0) {
|
| + /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
|
| + seedBytes = N/8;
|
| + }
|
| if (pqg_validate_dsa2(L,N) != SECSuccess) {
|
| /* error code already set */
|
| return SECFailure;
|
| }
|
| - return pqg_ParamGen(L, N, FIPS186_3_TYPE, seedBytes, pParams, pVfy);
|
| + return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy);
|
| }
|
|
|
|
|
|
|