Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
mozilla-nss.2166
nss-CAVS-fixes.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nss-CAVS-fixes.patch of Package mozilla-nss.2166
# HG changeset patch # Parent 2706b90296a4137a738f19ea81f378fc2dcce465 extend CAVS test to provide what it takes for certification diff --git a/cmd/fipstest/dsa.sh b/cmd/fipstest/dsa.sh --- a/cmd/fipstest/dsa.sh +++ b/cmd/fipstest/dsa.sh @@ -17,17 +17,17 @@ response=`echo $request | sed -e "s/req/ echo $request $response fipstest dsa keypair $request > $response request=PQGGen.req response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest dsa pqggen $request > $response -request=PQGVer.req +request=PQGVer1863.req response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest dsa pqgver $request > $response request=SigGen.req response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest dsa siggen $request > $response diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c --- a/cmd/fipstest/fipstest.c +++ b/cmd/fipstest/fipstest.c @@ -1,28 +1,31 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> +#include <dlfcn.h> #include "secitem.h" #include "blapi.h" #include "nssutil.h" #include "secerr.h" #include "secder.h" #include "secdig.h" #include "secoid.h" #include "ec.h" #include "hasht.h" #include "lowkeyi.h" #include "softoken.h" +#include "../../lib/freebl/fips.h" + #if 0 #include "../../lib/freebl/mpi/mpi.h" #endif #ifndef NSS_DISABLE_ECC extern SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); extern SECStatus @@ -34,16 +37,26 @@ EC_CopyParams(PLArenaPool *arena, ECPara #define DECRYPT 0 #define BYTE unsigned char #define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001 #define RSA_MAX_TEST_MODULUS_BITS 4096 #define RSA_MAX_TEST_MODULUS_BYTES RSA_MAX_TEST_MODULUS_BITS/8 #define RSA_MAX_TEST_EXPONENT_BYTES 8 #define PQG_TEST_SEED_BYTES 20 +/* Function pointers for dynamically loaded functions */ +void *(*FREEBL_GetGlobalVar_p) (int which, void *data); +SECStatus (*FREEBL_Test_PQG_ParamGenV3_p) (unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, int *pgen_counter, int *qgen_counter, + SECItem *firstseed, SECItem *pseed, SECItem *qseed); +SECStatus (*FREEBL_Test_PQG_GenerateG_p) (unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, const SECItem *P, const SECItem *Q); + SECStatus hex_to_byteval(const char *c2, unsigned char *byteval) { int i; unsigned char offset; *byteval = 0; for (i=0; i<2; i++) { if (c2[i] >= '0' && c2[i] <= '9') { @@ -93,16 +106,34 @@ to_hex_str_cap(char *str, const unsigned { unsigned int i; for (i=0; i<len; i++) { byteval_to_hex(buf[i], &str[2*i], 'A'); } str[2*len] = '\0'; } +void +to_hex_str_pad (char *str, const unsigned char *buf, unsigned int len, unsigned int padlen) +{ + unsigned int i, j; + + for (j = 0; len < padlen; padlen--) + { + str [j++] = '0'; + str [j++] = '0'; + } + + for (i=0; i<len; i++, j += 2) { + byteval_to_hex(buf[i], &str[j], 'a'); + } + + str[j] = '\0'; +} + /* * Convert a string of hex digits (str) to an array (buf) of len bytes. * Return PR_TRUE if the hex string can fit in the byte array. Return * PR_FALSE if the hex string is empty or is too long. */ PRBool from_hex_str(unsigned char *buf, unsigned int len, const char *str) { @@ -147,16 +178,181 @@ from_hex_str(unsigned char *buf, unsigne } else { hex_to_byteval(&str[j], &buf[i]); j += 2; } } return PR_TRUE; } +/* + * Convert a string of hex digits (str) to an array (buf) of maxlen bytes. + * Return length of resulting output in buf, or 0 on error. + */ +int +from_hex_str_varlen (unsigned char *buf, unsigned int maxlen, const char *str) +{ + unsigned int nxdigit; /* number of hex digits in str */ + unsigned int i; /* index into buf */ + unsigned int j; /* index into str */ + + /* count the hex digits */ + nxdigit = 0; + for (nxdigit = 0; isxdigit (str [nxdigit]); nxdigit++) { + /* empty body */ + } + if (nxdigit == 0) { + return 0; + } + + for (i = 0, j = 0; j < nxdigit; i++) { + if ((nxdigit - j) % 2 == 1) { + char tmp [2]; + tmp [0] = '0'; + tmp [1] = str [j]; + hex_to_byteval (tmp, &buf [i]); + j++; + } else { + hex_to_byteval (&str [j], &buf [i]); + j += 2; + } + } + return i; +} + +/* + * HASH_ functions are available to full NSS apps and internally inside + * freebl, but not exported to users of freebl. Create short stubs to + * replace the functionality for fipstest. + */ +SECStatus +fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, + unsigned char *msg, int len) +{ + SECStatus rv = SECFailure; + + switch (type) { + case HASH_AlgSHA1: + rv = SHA1_HashBuf(hashBuf, msg, len); + break; + case HASH_AlgSHA224: + rv = SHA224_HashBuf(hashBuf, msg, len); + break; + case HASH_AlgSHA256: + rv = SHA256_HashBuf(hashBuf, msg, len); + break; + case HASH_AlgSHA384: + rv = SHA384_HashBuf(hashBuf, msg, len); + break; + case HASH_AlgSHA512: + rv = SHA512_HashBuf(hashBuf, msg, len); + break; + default: + break; + } + return rv; +} + +int +fips_hashLen(HASH_HashType type) +{ + int len = 0; + + switch (type) { + case HASH_AlgSHA1: + len = SHA1_LENGTH; + break; + case HASH_AlgSHA224: + len = SHA224_LENGTH; + break; + case HASH_AlgSHA256: + len = SHA256_LENGTH; + break; + case HASH_AlgSHA384: + len = SHA384_LENGTH; + break; + case HASH_AlgSHA512: + len = SHA512_LENGTH; + break; + default: + break; + } + return len; +} + +SECOidTag +fips_hashOid(HASH_HashType type) +{ + SECOidTag oid = SEC_OID_UNKNOWN; + + switch (type) { + case HASH_AlgSHA1: + oid = SEC_OID_SHA1; + break; + case HASH_AlgSHA224: + oid = SEC_OID_SHA224; + break; + case HASH_AlgSHA256: + oid = SEC_OID_SHA256; + break; + case HASH_AlgSHA384: + oid = SEC_OID_SHA384; + break; + case HASH_AlgSHA512: + oid = SEC_OID_SHA512; + break; + default: + break; + } + return oid; +} + +HASH_HashType +sha_get_hashType(int hashbits) +{ + HASH_HashType hashType = HASH_AlgNULL; + + switch (hashbits) { + case 1: + case (SHA1_LENGTH*PR_BITS_PER_BYTE): + hashType = HASH_AlgSHA1; + break; + case (SHA224_LENGTH*PR_BITS_PER_BYTE): + hashType = HASH_AlgSHA224; + break; + case (SHA256_LENGTH*PR_BITS_PER_BYTE): + hashType = HASH_AlgSHA256; + break; + case (SHA384_LENGTH*PR_BITS_PER_BYTE): + hashType = HASH_AlgSHA384; + break; + case (SHA512_LENGTH*PR_BITS_PER_BYTE): + hashType = HASH_AlgSHA512; + break; + default: + break; + } + return hashType; +} + +/* + * Calculate the SHA Message Digest + * + * MD = Message digest + * MDLen = length of Message Digest and SHA_Type + * msg = message to digest + * msgLen = length of message to digest + */ +SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen) +{ + HASH_HashType hashType = sha_get_hashType(MDLen*PR_BITS_PER_BYTE); + + return fips_hashBuf(hashType, MD, msg, msgLen); +} + SECStatus tdea_encrypt_buf( int mode, const unsigned char *key, const unsigned char *iv, unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen, const unsigned char *input, unsigned int inputlen) { @@ -2001,22 +2197,22 @@ ecdsa_keypair_test(char *reqfn) int i; unsigned int len; ecdsareq = fopen(reqfn, "r"); ecdsaresp = stdout; strcpy(curve, "nist"); while (fgets(buf, sizeof buf, ecdsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { fputs(buf, ecdsaresp); continue; } /* [X-ddd] */ - if (buf[0] == '[') { + if (buf[0] == '[' && buf [1] != '\0' && buf [2] == '-') { const char *src; char *dst; SECItem *encodedparams; src = &buf[1]; dst = &curve[4]; *dst++ = tolower(*src); src += 2; /* skip the hyphen */ @@ -2030,16 +2226,21 @@ ecdsa_keypair_test(char *reqfn) } if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) { goto loser; } SECITEM_FreeItem(encodedparams, PR_TRUE); fputs(buf, ecdsaresp); continue; } + /* [...] */ + if (buf [0] == '[') { + fputs(buf, ecdsaresp); + continue; + } /* N = x */ if (buf[0] == 'N') { if (sscanf(buf, "N = %d", &N) != 1) { goto loser; } for (i = 0; i < N; i++) { ECPrivateKey *ecpriv; @@ -2216,20 +2417,23 @@ ecdsa_siggen_test(char *reqfn) * needs to be large enough to hold the longest * line "Msg = <256 hex digits>\n". */ FILE *ecdsareq; /* input stream from the REQUEST file */ FILE *ecdsaresp; /* output stream to the RESPONSE file */ char curve[16]; /* "nistxddd" */ ECParams *ecparams = NULL; int i, j; + char c; + int curvenum; + int shanum; unsigned int len; unsigned char msg[512]; /* message to be signed (<= 128 bytes) */ unsigned int msglen; - unsigned char sha1[20]; /* SHA-1 hash (160 bits) */ + unsigned char md[SHA512_LENGTH]; unsigned char sig[2*MAX_ECKEY_LEN]; SECItem signature, digest; ecdsareq = fopen(reqfn, "r"); ecdsaresp = stdout; strcpy(curve, "nist"); while (fgets(buf, sizeof buf, ecdsareq) != NULL) { /* a comment or blank line */ @@ -2238,16 +2442,19 @@ ecdsa_siggen_test(char *reqfn) continue; } /* [X-ddd] */ if (buf[0] == '[') { const char *src; char *dst; SECItem *encodedparams; + if (sscanf (buf, "[%c-%d,SHA-%d]", &c, &curvenum, &shanum) != 3) + goto loser; + src = &buf[1]; dst = &curve[4]; *dst++ = tolower(*src); src += 2; /* skip the hyphen */ *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst = '\0'; @@ -2273,17 +2480,17 @@ ecdsa_siggen_test(char *reqfn) i = 3; while (isspace(buf[i]) || buf[i] == '=') { i++; } for (j=0; isxdigit(buf[i]); i+=2,j++) { hex_to_byteval(&buf[i], &msg[j]); } msglen = j; - if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) { + if (fips_hashBuf(sha_get_hashType(shanum), md, msg, msglen) != SECSuccess) { goto loser; } fputs(buf, ecdsaresp); if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) { goto loser; } if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) @@ -2303,18 +2510,18 @@ ecdsa_siggen_test(char *reqfn) fputs(buf, ecdsaresp); fputc('\n', ecdsaresp); fputs("Qy = ", ecdsaresp); to_hex_str(buf, &ecpriv->publicValue.data[1+len], len); fputs(buf, ecdsaresp); fputc('\n', ecdsaresp); digest.type = siBuffer; - digest.data = sha1; - digest.len = sizeof sha1; + digest.data = md; + digest.len = fips_hashLen (sha_get_hashType (shanum)); signature.type = siBuffer; signature.data = sig; signature.len = sizeof sig; if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) { goto loser; } len = signature.len; if (len%2 != 0) { @@ -2355,21 +2562,24 @@ ecdsa_sigver_test(char *reqfn) * needs to be large enough to hold the longest * line "Msg = <256 hex digits>\n". */ FILE *ecdsareq; /* input stream from the REQUEST file */ FILE *ecdsaresp; /* output stream to the RESPONSE file */ char curve[16]; /* "nistxddd" */ ECPublicKey ecpub; unsigned int i, j; + char c; + int curvenum; + int shanum; unsigned int flen; /* length in bytes of the field size */ unsigned int olen; /* length in bytes of the base point order */ unsigned char msg[512]; /* message that was signed (<= 128 bytes) */ unsigned int msglen; - unsigned char sha1[20]; /* SHA-1 hash (160 bits) */ + unsigned char md[SHA512_LENGTH]; unsigned char sig[2*MAX_ECKEY_LEN]; SECItem signature, digest; PRBool keyvalid = PR_TRUE; PRBool sigvalid = PR_TRUE; ecdsareq = fopen(reqfn, "r"); ecdsaresp = stdout; ecpub.ecParams.arena = NULL; @@ -2382,16 +2592,19 @@ ecdsa_sigver_test(char *reqfn) } /* [X-ddd] */ if (buf[0] == '[') { const char *src; char *dst; SECItem *encodedparams; ECParams *ecparams; + if (sscanf (buf, "[%c-%d,SHA-%d]", &c, &curvenum, &shanum) != 3) + goto loser; + src = &buf[1]; dst = &curve[4]; *dst++ = tolower(*src); src += 2; /* skip the hyphen */ *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst = '\0'; @@ -2437,24 +2650,24 @@ ecdsa_sigver_test(char *reqfn) i = 3; while (isspace(buf[i]) || buf[i] == '=') { i++; } for (j=0; isxdigit(buf[i]); i+=2,j++) { hex_to_byteval(&buf[i], &msg[j]); } msglen = j; - if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) { + if (fips_hashBuf(sha_get_hashType(shanum), md, msg, msglen) != SECSuccess) { goto loser; } fputs(buf, ecdsaresp); digest.type = siBuffer; - digest.data = sha1; - digest.len = sizeof sha1; + digest.data = md; + digest.len = fips_hashLen (sha_get_hashType (shanum)); continue; } /* Qx = ... */ if (strncmp(buf, "Qx", 2) == 0) { fputs(buf, ecdsaresp); i = 2; while (isspace(buf[i]) || buf[i] == '=') { @@ -2603,19 +2816,19 @@ drbg(char *reqfn) unsigned char *nonce = NULL; int nonceLen = 0; unsigned char *personalizationString = NULL; int personalizationStringLen = 0; unsigned char *additionalInput = NULL; int additionalInputLen = 0; unsigned char *entropyInput = NULL; int entropyInputLen = 0; - unsigned char predictedreturn_bytes[SHA256_LENGTH]; - unsigned char return_bytes[SHA256_LENGTH]; - int return_bytes_len = SHA256_LENGTH; + unsigned char *predictedreturn_bytes = NULL; + unsigned char *return_bytes = NULL; + int return_bytes_len = 0; enum { NONE, INSTANTIATE, GENERATE, RESEED, RESULT } command = NONE; PRBool genResult = PR_FALSE; SECStatus rv; rngreq = fopen(reqfn, "r"); rngresp = stdout; while (fgets(buf, sizeof buf, rngreq) != NULL) { @@ -2804,16 +3017,41 @@ drbg(char *reqfn) additionalInputLen = additionalInputLen/8; if (additionalInputLen > 0) { additionalInput = PORT_Alloc(additionalInputLen); } fputs(buf, rngresp); continue; } + if (strncmp(buf, "[ReturnedBitsLen", 16) == 0) { + if (return_bytes) { + PORT_ZFree(return_bytes, return_bytes_len); + return_bytes = NULL; + } + + if (predictedreturn_bytes) { + PORT_ZFree(predictedreturn_bytes, return_bytes_len); + predictedreturn_bytes = NULL; + } + + return_bytes_len = 0; + + if (sscanf(buf, "[ReturnedBitsLen = %d]", &return_bytes_len) != 1) { + goto loser; + } + return_bytes_len = return_bytes_len/8; + if (return_bytes_len > 0) { + return_bytes = PORT_Alloc(return_bytes_len); + predictedreturn_bytes = PORT_Alloc(return_bytes_len); + } + fputs(buf, rngresp); + continue; + } + if (strncmp(buf, "COUNT", 5) == 0) { /* zeroize the variables for the test with this data set */ if (entropyInput) { memset(entropyInput, 0, entropyInputLen); } if (nonce) { memset(nonce, 0, nonceLen); } @@ -2954,17 +3192,17 @@ drbg(char *reqfn) to_hex_str(buf, predictedreturn_bytes, return_bytes_len); fputs(buf, stderr); fputs("\n actual = ", stderr); fputs(buf2, stderr); fputc('\n', stderr); } } - memset(predictedreturn_bytes, 0 , sizeof predictedreturn_bytes); + memset(predictedreturn_bytes, 0, return_bytes_len); continue; } } loser: fclose(rngreq); } @@ -3213,146 +3451,16 @@ rng_mct(char *reqfn) continue; } } loser: fclose(rngreq); } /* - * HASH_ functions are available to full NSS apps and internally inside - * freebl, but not exported to users of freebl. Create short stubs to - * replace the functionality for fipstest. - */ -SECStatus -fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, - unsigned char *msg, int len) -{ - SECStatus rv = SECFailure; - - switch (type) { - case HASH_AlgSHA1: - rv = SHA1_HashBuf(hashBuf, msg, len); - break; - case HASH_AlgSHA224: - rv = SHA224_HashBuf(hashBuf, msg, len); - break; - case HASH_AlgSHA256: - rv = SHA256_HashBuf(hashBuf, msg, len); - break; - case HASH_AlgSHA384: - rv = SHA384_HashBuf(hashBuf, msg, len); - break; - case HASH_AlgSHA512: - rv = SHA512_HashBuf(hashBuf, msg, len); - break; - default: - break; - } - return rv; -} - -int -fips_hashLen(HASH_HashType type) -{ - int len = 0; - - switch (type) { - case HASH_AlgSHA1: - len = SHA1_LENGTH; - break; - case HASH_AlgSHA224: - len = SHA224_LENGTH; - break; - case HASH_AlgSHA256: - len = SHA256_LENGTH; - break; - case HASH_AlgSHA384: - len = SHA384_LENGTH; - break; - case HASH_AlgSHA512: - len = SHA512_LENGTH; - break; - default: - break; - } - return len; -} - -SECOidTag -fips_hashOid(HASH_HashType type) -{ - SECOidTag oid = SEC_OID_UNKNOWN; - - switch (type) { - case HASH_AlgSHA1: - oid = SEC_OID_SHA1; - break; - case HASH_AlgSHA224: - oid = SEC_OID_SHA224; - break; - case HASH_AlgSHA256: - oid = SEC_OID_SHA256; - break; - case HASH_AlgSHA384: - oid = SEC_OID_SHA384; - break; - case HASH_AlgSHA512: - oid = SEC_OID_SHA512; - break; - default: - break; - } - return oid; -} - -HASH_HashType -sha_get_hashType(int hashbits) -{ - HASH_HashType hashType = HASH_AlgNULL; - - switch (hashbits) { - case 1: - case (SHA1_LENGTH*PR_BITS_PER_BYTE): - hashType = HASH_AlgSHA1; - break; - case (SHA224_LENGTH*PR_BITS_PER_BYTE): - hashType = HASH_AlgSHA224; - break; - case (SHA256_LENGTH*PR_BITS_PER_BYTE): - hashType = HASH_AlgSHA256; - break; - case (SHA384_LENGTH*PR_BITS_PER_BYTE): - hashType = HASH_AlgSHA384; - break; - case (SHA512_LENGTH*PR_BITS_PER_BYTE): - hashType = HASH_AlgSHA512; - break; - default: - break; - } - return hashType; -} - -/* - * Calculate the SHA Message Digest - * - * MD = Message digest - * MDLen = length of Message Digest and SHA_Type - * msg = message to digest - * msgLen = length of message to digest - */ -SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen) -{ - HASH_HashType hashType = sha_get_hashType(MDLen*PR_BITS_PER_BYTE); - - return fips_hashBuf(hashType, MD, msg, msgLen); -} - -/* * Perform the SHA Monte Carlo Test * * MDLen = length of Message Digest and SHA_Type * seed = input seed value * resp = is the output response file. */ SECStatus sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp) { @@ -3414,17 +3522,17 @@ SECStatus sha_mct_test(unsigned int MDLe * The output RESPONSE file is written to stdout. */ void sha_test(char *reqfn) { unsigned int i, j; unsigned int MDlen; /* the length of the Message Digest in Bytes */ unsigned int msgLen; /* the length of the input Message in Bytes */ unsigned char *msg = NULL; /* holds the message to digest.*/ - size_t bufSize = 25608; /*MAX buffer size */ + size_t bufSize = 102400; /*MAX buffer size */ char *buf = NULL; /* holds one line from the input REQUEST file.*/ unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */ unsigned char MD[HASH_LENGTH_MAX]; /* message digest */ FILE *req = NULL; /* input stream from the REQUEST file */ FILE *resp; /* output stream to the RESPONSE file */ buf = PORT_ZAlloc(bufSize); @@ -3721,17 +3829,17 @@ void hmac_test(char *reqfn) hex_to_byteval(&buf[i], &msg[j]); } fputs(buf, resp); /* calculate the HMAC and output */ if (hmac_calc(HMAC, HMACLen, key, keyLen, msg, msgLen, hash_alg) != SECSuccess) { goto loser; } - fputs("MAC = ", resp); + fputs("Mac = ", resp); to_hex_str(buf, HMAC, TLen); fputs(buf, resp); fputc('\n', resp); continue; } } loser: if (req) { @@ -3868,16 +3976,17 @@ loser: /* * pqg generation type */ typedef enum { FIPS186_1,/* Generate/Verify P,Q & G according to FIPS 186-1 */ A_1_1_2, /* Generate Probable P & Q */ A_1_1_3, /* Verify Probable P & Q */ + A_1_2_1, /* Generate Provable P & Q */ A_1_2_2, /* Verify Provable P & Q */ A_2_1, /* Generate Unverifiable G */ A_2_2, /* Assure Unverifiable G */ A_2_3, /* Generate Verifiable G */ A_2_4 /* Verify Verifiable G */ } dsa_pqg_type; /* @@ -3906,17 +4015,17 @@ dsa_pqgver_test(char *reqfn) dsareq = fopen(reqfn, "r"); dsaresp = stdout; memset(&pqg, 0, sizeof(pqg)); memset(&vfy, 0, sizeof(vfy)); while (fgets(buf, sizeof buf, dsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { fputs(buf, dsaresp); continue; } /* [A.xxxxx ] */ if (buf[0] == '[' && buf[1] == 'A') { if (strncmp(&buf[1],"A.1.1.3",7) == 0) { @@ -4119,17 +4228,16 @@ dsa_pqgver_test(char *reqfn) if (rv != SECSuccess) { goto loser; } if (result == SECSuccess) { fprintf(dsaresp, "Result = P\n"); } else { fprintf(dsaresp, "Result = F\n"); } - fprintf(dsaresp, "\n"); } continue; } if (strncmp(buf,"pgen_counter", 12) == 0) { if (sscanf(buf, "pgen_counter = %u", &vfy.counter) != 1) { goto loser; } fputs(buf, dsaresp); @@ -4144,17 +4252,16 @@ dsa_pqgver_test(char *reqfn) if (rv != SECSuccess) { goto loser; } if (result == SECSuccess) { fprintf(dsaresp, "Result = P\n"); } else { fprintf(dsaresp, "Result = F\n"); } - fprintf(dsaresp, "\n"); } continue; } /* H = ... */ if (buf[0] == 'H') { SECStatus rv, result = SECFailure; i = 1; @@ -4182,17 +4289,16 @@ dsa_pqgver_test(char *reqfn) if (rv != SECSuccess) { goto loser; } if (result == SECSuccess) { fprintf(dsaresp, "Result = P\n"); } else { fprintf(dsaresp, "Result = F\n"); } - fprintf(dsaresp, "\n"); continue; } } loser: fclose(dsareq); if (pqg.prime.data) { /* P */ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE); } @@ -4226,61 +4332,63 @@ dsa_pqggen_test(char *reqfn) * 800 to hold seed = (384 public key (x2 for HEX) */ FILE *dsareq; /* input stream from the REQUEST file */ FILE *dsaresp; /* output stream to the RESPONSE file */ int count; /* number of times to generate parameters */ int N; int L; int i; + int shanum = 0; unsigned int j; PQGParams *pqg = NULL; PQGVerify *vfy = NULL; + SECItem P, Q; unsigned int keySizeIndex; dsa_pqg_type type = FIPS186_1; dsareq = fopen(reqfn, "r"); dsaresp = stdout; while (fgets(buf, sizeof buf, dsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { fputs(buf, dsaresp); continue; } /* [A.xxxxx ] */ if (buf[0] == '[' && buf[1] == 'A') { if (strncmp(&buf[1],"A.1.1.2",7) == 0) { type = A_1_1_2; } else if (strncmp(&buf[1],"A.2.1",5) == 0) { - fprintf(stderr, "NSS only Generates G with P&Q\n"); - exit(1); + type = A_2_1; } else if (strncmp(&buf[1],"A.2.3",5) == 0) { fprintf(stderr, "NSS only Generates G with P&Q\n"); exit(1); } else if (strncmp(&buf[1],"A.1.2.1",7) == 0) { - fprintf(stderr, "NSS does not support Shawe-Taylor Primes\n"); - exit(1); + type = A_1_2_1; } else { fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]); exit(1); } fputs(buf, dsaresp); continue; } /* [Mod = ... ] */ if (buf[0] == '[') { + shanum = 0; if (type == FIPS186_1) { N=160; if (sscanf(buf, "[mod = %d]", &L) != 1) { goto loser; } - } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) { + } else if (sscanf (buf, "[mod = L=%d, N=%d, SHA-%d", &L, &N, &shanum) != 3 && + sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) { goto loser; } fputs(buf, dsaresp); fputc('\n', dsaresp); if (type == FIPS186_1) { /************************************************************ @@ -4292,71 +4400,151 @@ dsa_pqggen_test(char *reqfn) fprintf(dsaresp, "DSA key size must be a multiple of 64 between 512 " "and 1024, inclusive"); goto loser; } } continue; } - /* N = ... */ - if (buf[0] == 'N') { - if (sscanf(buf, "N = %d", &count) != 1) { + /* Num = ... */ + if (strncmp(buf, "Num", 3) == 0) { + if (sscanf(buf, "Num = %d", &count) != 1) { goto loser; } for (i = 0; i < count; i++) { + int pgen_counter, qgen_counter; + SECItem firstseed = { 0 }, qseed = { 0 }, pseed = { 0 }; SECStatus rv; if (type == FIPS186_1) { rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES, &pqg, &vfy); + } else if (type == A_1_2_1) { + rv = FREEBL_Test_PQG_ParamGenV3_p(L, N, 0, &pqg, &vfy, + shanum, &pgen_counter, &qgen_counter, + &firstseed, &pseed, &qseed); + } else if (type == A_1_1_2) { + rv = PQG_ParamGenV2(L, N, 0, &pqg, &vfy); } else { - rv = PQG_ParamGenV2(L, N, N, &pqg, &vfy); + /* A_2_1 -- Generate G when P and Q have been read */ + continue; } + if (rv != SECSuccess) { fprintf(dsaresp, "ERROR: Unable to generate PQG parameters"); goto loser; } to_hex_str(buf, pqg->prime.data, pqg->prime.len); fprintf(dsaresp, "P = %s\n", buf); to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len); fprintf(dsaresp, "Q = %s\n", buf); - to_hex_str(buf, pqg->base.data, pqg->base.len); - fprintf(dsaresp, "G = %s\n", buf); if (type == FIPS186_1) { + to_hex_str(buf, pqg->base.data, pqg->base.len); + fprintf(dsaresp, "G = %s\n", buf); to_hex_str(buf, vfy->seed.data, vfy->seed.len); fprintf(dsaresp, "Seed = %s\n", buf); fprintf(dsaresp, "c = %d\n", vfy->counter); to_hex_str(buf, vfy->h.data, vfy->h.len); fputs("H = ", dsaresp); for (j=vfy->h.len; j< pqg->prime.len; j++) { fprintf(dsaresp, "00"); } fprintf(dsaresp, "%s\n", buf); + } else if (type == A_1_2_1) { + to_hex_str(buf, firstseed.data, firstseed.len); + fprintf(dsaresp, "firstseed = %s\n", buf); + to_hex_str(buf, pseed.data, pseed.len); + fprintf(dsaresp, "pseed = %s\n", buf); + to_hex_str(buf, qseed.data, qseed.len); + fprintf(dsaresp, "qseed = %s\n", buf); + fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter); + fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter); } else { + to_hex_str(buf, pqg->base.data, pqg->base.len); + fprintf(dsaresp, "G = %s\n", buf); fprintf(dsaresp, "counter = %d\n", vfy->counter); fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); to_hex_str(buf, vfy->seed.data, vfy->seed.len); fprintf(dsaresp, "domain_parameter_seed = %s\n", buf); } + fputc('\n', dsaresp); + if(pqg!=NULL) { PQG_DestroyParams(pqg); pqg = NULL; } if(vfy!=NULL) { PQG_DestroyVerify(vfy); vfy = NULL; } + + if (firstseed.data) { + SECITEM_FreeItem(&firstseed, PR_FALSE); + firstseed.data = NULL; + } + if (pseed.data) { + SECITEM_FreeItem(&pseed, PR_FALSE); + pseed.data = NULL; + } + if (qseed.data) { + SECITEM_FreeItem(&qseed, PR_FALSE); + qseed.data = NULL; + } } continue; } + /* P = ... */ + if (buf[0] == 'P') { + unsigned char databuf [1024]; + int len; + + fputs(buf, dsaresp); + + for (i = 1; isspace (buf [i]) || buf [i] == '='; i++) + ; + + len = from_hex_str_varlen (databuf, 1024, &buf [i]); + + P.type = siBuffer; + P.data = NULL; + P.len = 0; + SECITEM_AllocItem (NULL, &P, len); + memcpy (P.data, databuf, len); + } + + /* Q = ... */ + if (buf[0] == 'Q') { + unsigned char databuf [1024]; + char hexbuf [1024]; + int len; + + fputs(buf, dsaresp); + + for (i = 1; isspace (buf [i]) || buf [i] == '='; i++) + ; + + len = from_hex_str_varlen (databuf, 1024, &buf [i]); + + Q.type = siBuffer; + Q.data = NULL; + Q.len = 0; + SECITEM_AllocItem (NULL, &Q, len); + memcpy (Q.data, databuf, len); + + /* Generate G from P and Q according to FIPS 186-3 A2.1 */ + FREEBL_Test_PQG_GenerateG_p (L, N, 0, &pqg, &vfy, shanum, &P, &Q); + + to_hex_str((char *) hexbuf, pqg->base.data, pqg->base.len); + fprintf(dsaresp, "G = %s\n", hexbuf); + } } loser: fclose(dsareq); if(pqg!=NULL) { PQG_DestroyParams(pqg); } if(vfy!=NULL) { PQG_DestroyVerify(vfy); @@ -4395,17 +4583,17 @@ dsa_siggen_test(char *reqfn) HASH_HashType hashType = HASH_AlgNULL; int hashNum = 0; dsareq = fopen(reqfn, "r"); dsaresp = stdout; while (fgets(buf, sizeof buf, dsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { fputs(buf, dsaresp); continue; } /* [Mod = x] */ if (buf[0] == '[') { if(pqg!=NULL) { PQG_DestroyParams(pqg); @@ -4424,17 +4612,16 @@ dsa_siggen_test(char *reqfn) &hashNum) != 3) { use_dsa1 = PR_TRUE; hashNum = 1; if (sscanf(buf, "[mod = %d]", &modulus) != 1) { goto loser; } } fputs(buf, dsaresp); - fputc('\n', dsaresp); /**************************************************************** * PQG_ParamGenSeedLen doesn't take a key size, it takes an index * that points to a valid key size. */ if (use_dsa1) { keySizeIndex = PQG_PBITS_TO_INDEX(modulus); if(keySizeIndex == -1 || modulus<512 || modulus>1024) { @@ -4452,16 +4639,17 @@ dsa_siggen_test(char *reqfn) } } else { if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) { fprintf(dsaresp, "ERROR: Unable to generate PQG parameters"); goto loser; } } + to_hex_str(buf, pqg->prime.data, pqg->prime.len); fprintf(dsaresp, "P = %s\n", buf); to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len); fprintf(dsaresp, "Q = %s\n", buf); to_hex_str(buf, pqg->base.data, pqg->base.len); fprintf(dsaresp, "G = %s\n", buf); /* create DSA Key */ @@ -4526,17 +4714,16 @@ dsa_siggen_test(char *reqfn) fputs(buf, dsaresp); to_hex_str(buf, dsakey->publicValue.data, dsakey->publicValue.len); fprintf(dsaresp, "Y = %s\n", buf); to_hex_str(buf, &signature.data[0], len); fprintf(dsaresp, "R = %s\n", buf); to_hex_str(buf, &signature.data[len], len); fprintf(dsaresp, "S = %s\n", buf); - fputc('\n', dsaresp); continue; } } loser: fclose(dsareq); if(pqg != NULL) { PQG_DestroyParams(pqg); @@ -4580,17 +4767,17 @@ dsa_sigver_test(char *reqfn) int hashNum = 0; dsareq = fopen(reqfn, "r"); dsaresp = stdout; memset(&pubkey, 0, sizeof(pubkey)); while (fgets(buf, sizeof buf, dsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { fputs(buf, dsaresp); continue; } /* [Mod = x] */ if (buf[0] == '[') { if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d]", &L, & N, @@ -4762,17 +4949,16 @@ dsa_sigver_test(char *reqfn) signature.data = sig; signature.len = pubkey.params.subPrime.len*2; if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) { fprintf(dsaresp, "Result = P\n"); } else { fprintf(dsaresp, "Result = F\n"); } - fprintf(dsaresp, "\n"); continue; } } loser: fclose(dsareq); if (pubkey.params.prime.data) { /* P */ SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE); } @@ -4783,16 +4969,140 @@ loser: SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE); } if (pubkey.publicValue.data) { /* Y */ SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE); } } /* + * Perform the RSA Provable-prime key generation test + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +rsa_keygen_probable_test(char *reqfn) +{ + char buf[2*RSA_MAX_TEST_MODULUS_BYTES+1]; + /* buf holds one line from the input REQUEST file + * or to the output RESPONSE file. + * 2x for HEX output + 1 for \n + */ + FILE *rsareq; /* input stream from the REQUEST file */ + FILE *rsaresp; /* output stream to the RESPONSE file */ + int i; + int modulus; /* the Modulus size */ + int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT; + SECItem pe = {0, 0, 0 }; + unsigned char pubEx[4]; + int peCount = 0; + RSAPrivateKey *rsaBlapiPrivKey = NULL; /* holds RSA private and + * public keys */ + + rsareq = fopen(reqfn, "r"); + rsaresp = stdout; + + /* calculate the exponent */ + for (i=0; i < 4; i++) { + if (peCount || (publicExponent & + ((unsigned long)0xff000000L >> (i*8)))) { + pubEx[peCount] = + (unsigned char)((publicExponent >> (3-i)*8) & 0xff); + peCount++; + } + } + pe.len = peCount; + pe.data = &pubEx[0]; + pe.type = siBuffer; + + while (fgets(buf, sizeof buf, rsareq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { + fputs(buf, rsaresp); + continue; + } + + /* [PrimeMethod = ...] */ + if (strncmp (buf, "[PrimeMethod", 4) == 0) { + /* PrimeMethod is always ProvRP */ + fputs(buf, rsaresp); + } + + /* [Table = ...] */ + if (strncmp (buf, "[Table", 4) == 0) { + /* M-R Test table */ + fputs(buf, rsaresp); + } + + /* [mod = ...] */ + if (strncmp (buf, "[mod", 4) == 0) { + if (sscanf(buf, "[mod = %d]", &modulus) != 1) { + goto loser; + } + if (modulus > RSA_MAX_TEST_MODULUS_BITS) { + fprintf(rsaresp,"ERROR: modulus greater than test maximum\n"); + goto loser; + } + + fputs(buf, rsaresp); + } + + if (strncmp (buf, "N", 1) == 0) { + int count; + int i; + + if (sscanf(buf, "N = %d", &count) != 1) { + goto loser; + } + + for (i = 0; i < count; i++) { + if (rsaBlapiPrivKey != NULL) { + PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE); + rsaBlapiPrivKey = NULL; + } + + rsaBlapiPrivKey = RSA_NewKey(modulus, &pe); + if (rsaBlapiPrivKey == NULL) { + fprintf(rsaresp, "Error unable to create RSA key\n"); + goto loser; + } + + to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data, + rsaBlapiPrivKey->publicExponent.len); + fprintf(rsaresp, "e = %s\n", buf); + to_hex_str(buf, rsaBlapiPrivKey->prime1.data, + rsaBlapiPrivKey->prime1.len); + fprintf(rsaresp, "p = %s\n", buf); + to_hex_str(buf, rsaBlapiPrivKey->prime2.data, + rsaBlapiPrivKey->prime2.len); + fprintf(rsaresp, "q = %s\n", buf); + + to_hex_str(buf, rsaBlapiPrivKey->modulus.data, + rsaBlapiPrivKey->modulus.len); + fprintf(rsaresp, "n = %s\n", buf); + to_hex_str_pad(buf, rsaBlapiPrivKey->privateExponent.data, + rsaBlapiPrivKey->privateExponent.len, + modulus / 8); + fprintf(rsaresp, "d = %s\n\n", buf); + } + } + } +loser: + fclose(rsareq); + + if (rsaBlapiPrivKey != NULL) { + /* frees private and public key */ + PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE); + rsaBlapiPrivKey = NULL; + } +} + +/* * Perform the RSA Signature Generation Test. * * reqfn is the pathname of the REQUEST file. * * The output RESPONSE file is written to stdout. */ void rsa_siggen_test(char *reqfn) @@ -4832,17 +5142,17 @@ rsa_siggen_test(char *reqfn) } } pe.len = peCount; pe.data = &pubEx[0]; pe.type = siBuffer; while (fgets(buf, sizeof buf, rsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { fputs(buf, rsaresp); continue; } /* [mod = ...] */ if (buf[0] == '[') { if (sscanf(buf, "[mod = %d]", &modulus) != 1) { @@ -5030,17 +5340,17 @@ rsa_sigver_test(char *reqfn) RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */ rsareq = fopen(reqfn, "r"); rsaresp = stdout; memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey)); while (fgets(buf, sizeof buf, rsareq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { fputs(buf, rsaresp); continue; } /* [Mod = ...] */ if (buf[0] == '[') { unsigned int flen; /* length in bytes of the field size */ @@ -5101,16 +5411,17 @@ rsa_sigver_test(char *reqfn) } else if (strncmp(&buf[i], "SHA384", 6) == 0) { shaAlg = HASH_AlgSHA384; } else if (strncmp(&buf[i], "SHA512", 6) == 0) { shaAlg = HASH_AlgSHA512; } else { fprintf(rsaresp, "ERROR: Unable to find SHAAlg type"); goto loser; } + shaOid = fips_hashOid(shaAlg); fputs(buf, rsaresp); continue; } /* e = ... public Key */ if (buf[0] == 'e') { unsigned char data[RSA_MAX_TEST_EXPONENT_BYTES]; unsigned char t; @@ -5228,22 +5539,57 @@ loser: if (rsaBlapiPublicKey.modulus.data) { /* n */ SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE); } if (rsaBlapiPublicKey.publicExponent.data) { /* e */ SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE); } } +static void +init_functions (void) +{ + void *freebl_so; + + freebl_so = dlopen ("libfreebl3.so", RTLD_LAZY); + if (freebl_so == NULL) + { + fprintf (stderr, "Failed to load libfreebl3.so."); + exit (1); + } + + FREEBL_GetGlobalVar_p = dlsym (freebl_so, "FREEBL_GetGlobalVar"); + FREEBL_Test_PQG_ParamGenV3_p = dlsym (freebl_so, "FREEBL_Test_PQG_ParamGenV3"); + FREEBL_Test_PQG_GenerateG_p = dlsym (freebl_so, "FREEBL_Test_PQG_GenerateG"); + + if (FREEBL_GetGlobalVar_p == NULL) + { + fprintf (stderr, "Failed to bind FREEBL_GetGlobalVar."); + exit (1); + } + if (FREEBL_Test_PQG_ParamGenV3_p == NULL) + { + fprintf (stderr, "Failed to bind FREEBL_TEST_PQG_ParamGenV3."); + exit (1); + } + if (FREEBL_Test_PQG_GenerateG_p == NULL) + { + fprintf (stderr, "Failed to bind FREEBL_TEST_PQG_GenerateG."); + exit (1); + } +} + int main(int argc, char **argv) { if (argc < 2) exit (-1); + init_functions (); RNG_RNGInit(); SECOID_Init(); + BL_Init(); /*************/ /* TDEA */ /*************/ if (strcmp(argv[1], "tdea") == 0) { /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */ if (strcmp(argv[2], "kat") == 0) { /* Known Answer Test (KAT) */ @@ -5294,16 +5640,19 @@ int main(int argc, char **argv) /* argv[2]=siggen|sigver */ /* argv[3]=<test name>.req */ if (strcmp(argv[2], "siggen") == 0) { /* Signature Generation Test */ rsa_siggen_test(argv[3]); } else if (strcmp(argv[2], "sigver") == 0) { /* Signature Verification Test */ rsa_sigver_test(argv[3]); + } else if (strcmp(argv[2], "keygen") == 0) { + /* Key Generation Test with probable primes */ + rsa_keygen_probable_test(argv[3]); } /*************/ /* HMAC */ /*************/ } else if (strcmp(argv[1], "hmac") == 0) { hmac_test(argv[2]); /*************/ /* DSA */ diff --git a/cmd/fipstest/rng.sh b/cmd/fipstest/rng.sh old mode 100644 new mode 100755 --- a/cmd/fipstest/rng.sh +++ b/cmd/fipstest/rng.sh @@ -8,16 +8,16 @@ # # Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment # variables appropriately so that the fipstest command and the NSPR and NSS # shared libraries/DLLs are on the search path. Then run this script in the # directory where the REQUEST (.req) files reside. The script generates the # RESPONSE (.rsp) files in the same directory. drbg_requests=" -SHA256_DRBG.req +Hash_DRBG.req " for request in $drbg_requests; do response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest drbg $request > $response done diff --git a/cmd/fipstest/rsa.sh b/cmd/fipstest/rsa.sh old mode 100644 new mode 100755 --- a/cmd/fipstest/rsa.sh +++ b/cmd/fipstest/rsa.sh @@ -8,17 +8,22 @@ # # Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment # variables appropriately so that the fipstest command and the NSPR and NSS # shared libraries/DLLs are on the search path. Then run this script in the # directory where the REQUEST (.req) files reside. The script generates the # RESPONSE (.rsp) files in the same directory. -request=SigGen15.req +request=SigGen15_186-3.req response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest rsa siggen $request > $response -request=SigVer15.req +request=SigVer15_186-3.req response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest rsa sigver $request > $response + +request=KeyGen_RandomProbablyPrime3_3.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest rsa keygen $request > $response diff --git a/cmd/fipstest/sha.sh b/cmd/fipstest/sha.sh old mode 100644 new mode 100755 --- a/cmd/fipstest/sha.sh +++ b/cmd/fipstest/sha.sh @@ -9,30 +9,33 @@ # Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment # variables appropriately so that the fipstest command and the NSPR and NSS # shared libraries/DLLs are on the search path. Then run this script in the # directory where the REQUEST (.req) files reside. The script generates the # RESPONSE (.rsp) files in the same directory. sha_ShortMsg_requests=" SHA1ShortMsg.req +SHA224ShortMsg.req SHA256ShortMsg.req SHA384ShortMsg.req SHA512ShortMsg.req " sha_LongMsg_requests=" SHA1LongMsg.req +SHA224LongMsg.req SHA256LongMsg.req SHA384LongMsg.req SHA512LongMsg.req " sha_Monte_requests=" SHA1Monte.req +SHA224Monte.req SHA256Monte.req SHA384Monte.req SHA512Monte.req " for request in $sha_ShortMsg_requests; do response=`echo $request | sed -e "s/req/rsp/"` echo $request $response fipstest sha $request > $response diff --git a/cmd/pk11gcmtest/pk11gcmtest.c b/cmd/pk11gcmtest/pk11gcmtest.c --- a/cmd/pk11gcmtest/pk11gcmtest.c +++ b/cmd/pk11gcmtest/pk11gcmtest.c @@ -28,16 +28,42 @@ hex_to_byteval(const char *c2, unsigned *byteval |= (offset + 10) << 4*(1-i); } else { return SECFailure; } } return SECSuccess; } +SECStatus +byteval_to_hex(unsigned char byteval, char *c2, char a) +{ + int i; + unsigned char offset; + for (i=0; i<2; i++) { + offset = (byteval >> 4*(1-i)) & 0x0f; + if (offset < 10) { + c2[i] = '0' + offset; + } else { + c2[i] = a + offset - 10; + } + } + return SECSuccess; +} + +void +to_hex_str(char *str, const unsigned char *buf, unsigned int len) +{ + unsigned int i; + for (i=0; i<len; i++) { + byteval_to_hex(buf[i], &str[2*i], 'a'); + } + str[2*len] = '\0'; +} + static SECStatus aes_encrypt_buf( const unsigned char *key, unsigned int keysize, const unsigned char *iv, unsigned int ivsize, unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen, const unsigned char *input, unsigned int inputlen, const unsigned char *aad, unsigned int aadlen, unsigned int tagsize) { @@ -117,17 +143,19 @@ aes_decrypt_buf( key_item.data = (unsigned char *) key; /* const cast */ key_item.len = keysize; slot = PK11_GetInternalSlot(); symKey = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL); PK11_FreeSlot(slot); slot = NULL; if (!symKey) { +#if 0 fprintf(stderr, "PK11_ImportSymKey failed\n"); +#endif goto loser; } gcm_params.pIv = (unsigned char *) iv; gcm_params.ulIvLen = ivsize; gcm_params.pAAD = (unsigned char *) aad; gcm_params.ulAADLen = aadlen; gcm_params.ulTagBits = tagsize * 8; @@ -149,26 +177,27 @@ loser: PK11_FreeSymKey(symKey); } return rv; } /* * Perform the AES Known Answer Test (KAT) in Galois Counter Mode (GCM). * - * respfn is the pathname of the RESPONSE file. + * reqfn is the pathname of the RESPONSE file. */ static void -aes_gcm_kat(const char *respfn) +aes_gcm_kat(const char *reqfn) { char buf[512]; /* holds one line from the input REQUEST file. * needs to be large enough to hold the longest * line "CIPHERTEXT = <320 hex digits>\n". */ - FILE *aesresp; /* input stream from the RESPONSE file */ + FILE *aesreq; /* input stream from the REQUEST file */ + FILE *aesresp; /* output stream to the RESPONSE file */ int i, j; unsigned int test_group = 0; unsigned int num_tests; PRBool is_encrypt; unsigned char key[32]; /* 128, 192, or 256 bits */ unsigned int keysize; unsigned char iv[10*16]; /* 1 to 10 blocks */ unsigned int ivsize; @@ -185,32 +214,34 @@ aes_gcm_kat(const char *respfn) unsigned int expected_keylen = 0; unsigned int expected_ivlen = 0; unsigned int expected_ptlen = 0; unsigned int expected_aadlen = 0; unsigned int expected_taglen = 0; SECStatus rv; - if (strstr(respfn, "Encrypt") != NULL) { + if (strstr(reqfn, "Encrypt") != NULL) { is_encrypt = PR_TRUE; - } else if (strstr(respfn, "Decrypt") != NULL) { + } else if (strstr(reqfn, "Decrypt") != NULL) { is_encrypt = PR_FALSE; } else { fprintf(stderr, "Input file name must contain Encrypt or Decrypt\n"); exit(1); } - aesresp = fopen(respfn, "r"); - if (aesresp == NULL) { - fprintf(stderr, "Cannot open input file %s\n", respfn); + aesreq = fopen(reqfn, "r"); + if (aesreq == NULL) { + fprintf(stderr, "Cannot open input file %s\n", reqfn); exit(1); } - while (fgets(buf, sizeof buf, aesresp) != NULL) { + aesresp = stdout; + while (fgets(buf, sizeof buf, aesreq) != NULL) { /* a comment or blank line */ - if (buf[0] == '#' || buf[0] == '\n') { + if (buf[0] == '#' || buf[0] == '\n' || buf [0] == '\r') { + fputs(buf, aesresp); continue; } /* [Keylen = ...], [IVlen = ...], etc. */ if (buf[0] == '[') { if (strncmp(&buf[1], "Keylen = ", 9) == 0) { expected_keylen = atoi(&buf[10]); } else if (strncmp(&buf[1], "IVlen = ", 8) == 0) { expected_ivlen = atoi(&buf[9]); @@ -218,38 +249,43 @@ aes_gcm_kat(const char *respfn) expected_ptlen = atoi(&buf[9]); } else if (strncmp(&buf[1], "AADlen = ", 9) == 0) { expected_aadlen = atoi(&buf[10]); } else if (strncmp(&buf[1], "Taglen = ", 9) == 0) { expected_taglen = atoi(&buf[10]); test_group++; if (test_group > 1) { +#if 0 /* Report num_tests for the previous test group. */ printf("%u tests\n", num_tests); +#endif } num_tests = 0; +#if 0 printf("Keylen = %u, IVlen = %u, PTlen = %u, AADlen = %u, " "Taglen = %u: ", expected_keylen, expected_ivlen, expected_ptlen, expected_aadlen, expected_taglen); +#endif /* Convert lengths in bits to lengths in bytes. */ PORT_Assert(expected_keylen % 8 == 0); expected_keylen /= 8; PORT_Assert(expected_ivlen % 8 == 0); expected_ivlen /= 8; PORT_Assert(expected_ptlen % 8 == 0); expected_ptlen /= 8; PORT_Assert(expected_aadlen % 8 == 0); expected_aadlen /= 8; PORT_Assert(expected_taglen % 8 == 0); expected_taglen /= 8; } else { fprintf(stderr, "Unexpected input line: %s\n", buf); exit(1); } + fputs(buf, aesresp); continue; } /* "Count = x" begins a new data set */ if (strncmp(buf, "Count", 5) == 0) { /* zeroize the variables for the test with this data set */ memset(key, 0, sizeof key); keysize = 0; memset(iv, 0, sizeof iv); @@ -258,16 +294,17 @@ aes_gcm_kat(const char *respfn) plaintextlen = 0; memset(aad, 0, sizeof aad); aadlen = 0; memset(ciphertext, 0, sizeof ciphertext); ciphertextlen = 0; memset(output, 0, sizeof output); outputlen = 0; num_tests++; + fputs(buf, aesresp); continue; } /* Key = ... */ if (strncmp(buf, "Key", 3) == 0) { i = 3; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -275,16 +312,17 @@ aes_gcm_kat(const char *respfn) hex_to_byteval(&buf[i], &key[j]); } keysize = j; if (keysize != expected_keylen) { fprintf(stderr, "Unexpected key length: %u vs. %u\n", keysize, expected_keylen); exit(1); } + fputs(buf, aesresp); continue; } /* IV = ... */ if (strncmp(buf, "IV", 2) == 0) { i = 2; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -292,16 +330,17 @@ aes_gcm_kat(const char *respfn) hex_to_byteval(&buf[i], &iv[j]); } ivsize = j; if (ivsize != expected_ivlen) { fprintf(stderr, "Unexpected IV length: %u vs. %u\n", ivsize, expected_ivlen); exit(1); } + fputs(buf, aesresp); continue; } /* PT = ... */ if (strncmp(buf, "PT", 2) == 0) { i = 2; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -310,33 +349,17 @@ aes_gcm_kat(const char *respfn) } plaintextlen = j; if (plaintextlen != expected_ptlen) { fprintf(stderr, "Unexpected PT length: %u vs. %u\n", plaintextlen, expected_ptlen); exit(1); } - if (!is_encrypt) { - rv = aes_decrypt_buf(key, keysize, iv, ivsize, - output, &outputlen, sizeof output, - ciphertext, ciphertextlen, aad, aadlen, tag, tagsize); - if (rv != SECSuccess) { - fprintf(stderr, "aes_decrypt_buf failed\n"); - goto loser; - } - if (outputlen != plaintextlen) { - fprintf(stderr, "aes_decrypt_buf: wrong output size\n"); - goto loser; - } - if (memcmp(output, plaintext, plaintextlen) != 0) { - fprintf(stderr, "aes_decrypt_buf: wrong plaintext\n"); - goto loser; - } - } + fputs(buf, aesresp); continue; } /* FAIL */ if (strncmp(buf, "FAIL", 4) == 0) { plaintextlen = 0; PORT_Assert(!is_encrypt); rv = aes_decrypt_buf(key, keysize, iv, ivsize, @@ -363,16 +386,56 @@ aes_gcm_kat(const char *respfn) hex_to_byteval(&buf[i], &aad[j]); } aadlen = j; if (aadlen != expected_aadlen) { fprintf(stderr, "Unexpected AAD length: %u vs. %u\n", aadlen, expected_aadlen); exit(1); } + + fputs(buf, aesresp); + + if (is_encrypt) { + rv = aes_encrypt_buf(key, keysize, iv, ivsize, + output, &outputlen, sizeof output, + plaintext, plaintextlen, aad, aadlen, expected_taglen); + if (rv != SECSuccess) { + fprintf(stderr, "aes_encrypt_buf failed\n"); + goto loser; + } + if (outputlen != plaintextlen + expected_taglen) { + fprintf(stderr, "aes_encrypt_buf: wrong output size\n"); + goto loser; + } +#if 0 + /* XXX Don't try to compare the ciphertext, as there is none + * to compare with. Just output the resulting CT. */ + if (memcmp(output, ciphertext, plaintextlen) != 0) { + fprintf(stderr, "aes_encrypt_buf: wrong ciphertext\n"); + goto loser; + } + + if (memcmp(output + plaintextlen, tag, tagsize) != 0) { + fprintf(stderr, "aes_encrypt_buf: wrong tag\n"); + goto loser; + } +#endif + + fputs ("CT = ", aesresp); + to_hex_str (buf, output, plaintextlen); + fputs (buf, aesresp); + fputc ('\n', aesresp); + + fputs ("Tag = ", aesresp); + to_hex_str (buf, output + plaintextlen, expected_taglen); + fputs (buf, aesresp); + fputc ('\n', aesresp); + } + continue; } /* CT = ... */ if (strncmp(buf, "CT", 2) == 0) { i = 2; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -380,16 +443,18 @@ aes_gcm_kat(const char *respfn) hex_to_byteval(&buf[i], &ciphertext[j]); } ciphertextlen = j; if (ciphertextlen != expected_ptlen) { fprintf(stderr, "Unexpected CT length: %u vs. %u\n", ciphertextlen, expected_ptlen); exit(1); } + + fputs(buf, aesresp); continue; } /* Tag = ... */ if (strncmp(buf, "Tag", 3) == 0) { i = 3; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -398,46 +463,54 @@ aes_gcm_kat(const char *respfn) } tagsize = j; if (tagsize != expected_taglen) { fprintf(stderr, "Unexpected tag length: %u vs. %u\n", tagsize, expected_taglen); exit(1); } - if (is_encrypt) { - rv = aes_encrypt_buf(key, keysize, iv, ivsize, + fputs(buf, aesresp); + + if (!is_encrypt) { + rv = aes_decrypt_buf(key, keysize, iv, ivsize, output, &outputlen, sizeof output, - plaintext, plaintextlen, aad, aadlen, tagsize); - if (rv != SECSuccess) { - fprintf(stderr, "aes_encrypt_buf failed\n"); + ciphertext, ciphertextlen, aad, aadlen, tag, tagsize); + if (rv != SECSuccess || outputlen < expected_ptlen) { + fputs ("FAIL\n", aesresp); + } else { + fputs ("PT = ", aesresp); + to_hex_str (buf, output, expected_ptlen); + fputs (buf, aesresp); + fputc ('\n', aesresp); + } + +#if 0 + /* XXX Nothing to compare against */ + + if (memcmp(output, plaintext, plaintextlen) != 0) { + fprintf(stderr, "aes_decrypt_buf: wrong plaintext\n"); goto loser; } - if (outputlen != plaintextlen + tagsize) { - fprintf(stderr, "aes_encrypt_buf: wrong output size\n"); - goto loser; - } - if (memcmp(output, ciphertext, plaintextlen) != 0) { - fprintf(stderr, "aes_encrypt_buf: wrong ciphertext\n"); - goto loser; - } - if (memcmp(output + plaintextlen, tag, tagsize) != 0) { - fprintf(stderr, "aes_encrypt_buf: wrong tag\n"); - goto loser; - } +#endif } + continue; } } + +#if 0 /* Report num_tests for the last test group. */ printf("%u tests\n", num_tests); printf("%u test groups\n", test_group); printf("PASS\n"); +#endif + loser: - fclose(aesresp); + fclose(aesreq); } int main(int argc, char **argv) { if (argc < 2) exit(1); NSS_NoDB_Init(NULL); diff --git a/lib/freebl/fips.h b/lib/freebl/fips.h --- a/lib/freebl/fips.h +++ b/lib/freebl/fips.h @@ -3,27 +3,35 @@ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef FIPS_H #define FIPS_H +#include "blapit.h" #include "hasht.h" -#include "secerr.h" #define IN_FIPS_RETURN(rv) \ do { \ if (FIPS_mode()) { \ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); \ return rv; \ } \ } while (0) int FIPS_mode(void); char* FIPS_rngDev(void); PRBool FIPS_hashAlgApproved(HASH_HashType hashAlg); void* FREEBL_GetGlobalVar(int which, void *data); +SECStatus FREEBL_Test_PQG_ParamGenV3 (unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, int *pgen_counter, int *qgen_counter, + SECItem *firstseed, SECItem *pseed, SECItem *qseed); +SECStatus FREEBL_Test_PQG_GenerateG (unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, const SECItem *P, const SECItem *Q); + #endif diff --git a/lib/freebl/freebl.def b/lib/freebl/freebl.def --- a/lib/freebl/freebl.def +++ b/lib/freebl/freebl.def @@ -17,11 +17,13 @@ ;+# directives are hidden behind ";", ";+", and ";-" ;+ ;+NSSprivate_3.11 { # NSS 3.11 release ;+ global: LIBRARY freebl3 ;- EXPORTS ;- FREEBL_GetVector; FREEBL_GetGlobalVar; +FREEBL_Test_PQG_GenerateG; +FREEBL_Test_PQG_ParamGenV3; ;+ local: ;+ *; ;+}; diff --git a/lib/freebl/freebl_hash.def b/lib/freebl/freebl_hash.def --- a/lib/freebl/freebl_hash.def +++ b/lib/freebl/freebl_hash.def @@ -17,16 +17,18 @@ ;+# directives are hidden behind ";", ";+", and ";-" ;+ ;+NSSprivate_3.11 { # NSS 3.11 release ;+ global: LIBRARY freebl3 ;- EXPORTS ;- FREEBL_GetVector; FREEBL_GetGlobalVar; +FREEBL_Test_PQG_GenerateG; +FREEBL_Test_PQG_ParamGenV3; ;+ local: ;+ *; ;+}; ;+NSSRAWHASH_3.12.3 { # NSS 3.12.3 release ;+ global: NSSLOW_Init; NSSLOW_Shutdown; NSSLOWHASH_Length; diff --git a/lib/freebl/pqg.c b/lib/freebl/pqg.c --- a/lib/freebl/pqg.c +++ b/lib/freebl/pqg.c @@ -1223,17 +1223,21 @@ cleanup: /* This code uses labels and gotos, so that it can follow the numbered ** steps in the algorithms from FIPS 186-3 appendix A.1.1.2 very closely, ** and so that the correctness of this code can be easily verified. ** So, please forgive the ugly c code. **/ static SECStatus pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type, - unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy) + unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy, + const SECItem *P_in, const SECItem *Q_in, + int minHashLen, int *pgen_counter_out, + int *qgen_counter_out, SECItem *firstseed_out, + SECItem *pseed_out, SECItem *qseed_out) { unsigned int n; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */ unsigned int b; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */ unsigned int seedlen; /* Per FIPS 186-3 app A.1.1.2 (was 'g' 186-1)*/ unsigned int counter; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */ unsigned int offset; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */ unsigned int outlen; /* Per FIPS 186-3, appendix A.1.1.2. */ unsigned int maxCount; @@ -1247,17 +1251,16 @@ pqg_ParamGen(unsigned int L, unsigned in 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; - /* Step 1. L and N already checked by caller*/ /* Step 2. if (seedlen < N) return INVALID; */ if (seedBytes < N/PR_BITS_PER_BYTE || !pParams || !pVfy) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* Initialize an arena for the params. */ arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE); @@ -1298,20 +1301,27 @@ pqg_ParamGen(unsigned int L, unsigned in 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) ); + if (P_in && Q_in && P_in->data && Q_in->data && + P_in->len > 0 && Q_in->len > 0) { + SECITEM_TO_MPINT(*P_in, &P); + SECITEM_TO_MPINT(*Q_in, &Q); + goto generate_G; + } + /* Select Hash and Compute lengths. */ /* getFirstHash gives us the smallest acceptable hash for this key * strength */ - hashtype = getFirstHash(L,N); + hashtype = getFirstHash(L, minHashLen > N ? minHashLen : N); outlen = HASH_ResultLen(hashtype)*PR_BITS_PER_BYTE; /* Step 3: n = Ceil(L/outlen)-1; (same as n = Floor((L-1)/outlen)) */ n = (L - 1) / outlen; /* Step 4: b = L -1 - (n*outlen); (same as n = (L-1) mod outlen) */ b = (L - 1) % outlen; seedlen = seedBytes * PR_BITS_PER_BYTE; /* bits in seed */ step_5: @@ -1375,16 +1385,21 @@ step_5: 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; */ + if (pgen_counter_out) + *pgen_counter_out = pgen_counter; + if (qgen_counter_out) + *qgen_counter_out = qgen_counter; + /* we've generated both P and Q now, skip to generating G */ goto generate_G; } /* ****************************************************************** ** Step 8. (Step 4 in 186-1) ** "Use a robust primality testing algorithm to test whether q is prime." ** ** Appendix 2.1 states that a Rabin test with at least 50 iterations @@ -1494,16 +1509,24 @@ generate_G: } /* All generation is done. Now, save the PQG params. */ MPINT_TO_SECITEM(&P, ¶ms->prime, params->arena); MPINT_TO_SECITEM(&Q, ¶ms->subPrime, params->arena); MPINT_TO_SECITEM(&G, ¶ms->base, params->arena); verify->counter = counter; *pParams = params; *pVfy = verify; + + if (firstseed_out) + SECITEM_CopyItem (NULL, firstseed_out, &firstseed); + if (qseed_out) + SECITEM_CopyItem (NULL, qseed_out, &qseed); + if (pseed_out) + SECITEM_CopyItem (NULL, pseed_out, &pseed); + cleanup: if (pseed.data) { PORT_Free(pseed.data); } if (qseed.data) { PORT_Free(qseed.data); } mp_clear(&P); @@ -1533,53 +1556,102 @@ PQG_ParamGen(unsigned int j, PQGParams * unsigned int seedBytes; if (j > 8 || !pParams || !pVfy) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } L = 512 + (j * 64); /* bits in P */ seedBytes = L/8; - return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes, - pParams, pVfy); + return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes, pParams, pVfy, + NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL); } SECStatus PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy) { unsigned int L; /* Length of P in bits. Per FIPS 186. */ if (j > 8 || !pParams || !pVfy) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } L = 512 + (j * 64); /* bits in P */ - return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes, - pParams, pVfy); + return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes, pParams, pVfy, + NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL); } SECStatus PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes, - PQGParams **pParams, PQGVerify **pVfy) + 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_ST_TYPE, seedBytes, pParams, pVfy); + return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy, + NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL); } +SECStatus +FREEBL_Test_PQG_ParamGenV3(unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, int *pgen_counter, int *qgen_counter, + SECItem *firstseed, SECItem *pseed, SECItem *qseed) +{ + 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_ST_TYPE, seedBytes, pParams, pVfy, + NULL, NULL, shanum, pgen_counter, qgen_counter, firstseed, pseed, qseed); +} + +/* Only to be used by FIPS tests */ +SECStatus +FREEBL_Test_PQG_GenerateG (unsigned int L, unsigned int N, unsigned int seedBytes, + PQGParams **pParams, PQGVerify **pVfy, + int shanum, const SECItem *P, const SECItem *Q) +{ + int rv; + + /* Generate G from P and Q according to FIPS 186-3 A2.1 */ + + 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_1_TYPE, seedBytes, pParams, pVfy, + P, Q, shanum, NULL, NULL, NULL, NULL, NULL); +} /* * verify can use vfy structures returned from either FIPS186-1 or * FIPS186-2, and can handle differences in selected Hash functions to * generate the parameters. */ SECStatus PQG_VerifyParams(const PQGParams *params,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor