|
|
70d46f |
diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
|
|
|
70d46f |
--- a/cmd/fipstest/fipstest.c
|
|
|
70d46f |
+++ b/cmd/fipstest/fipstest.c
|
|
|
70d46f |
@@ -2330,16 +2330,44 @@ sha_get_hashType(int hashbits)
|
|
|
70d46f |
hashType = HASH_AlgSHA512;
|
|
|
70d46f |
break;
|
|
|
70d46f |
default:
|
|
|
70d46f |
break;
|
|
|
70d46f |
}
|
|
|
70d46f |
return hashType;
|
|
|
70d46f |
}
|
|
|
70d46f |
|
|
|
70d46f |
+HASH_HashType
|
|
|
70d46f |
+hash_string_to_hashType(const char * src)
|
|
|
70d46f |
+{
|
|
|
70d46f |
+ HASH_HashType shaAlg = HASH_AlgNULL;
|
|
|
70d46f |
+ if (strncmp(src, "SHA-1", 5) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA-224", 7) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA-256", 7) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA-384", 7) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA-512", 7) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA1", 4) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA224", 6) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA256", 6) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA384", 6) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
+ } else if (strncmp(src, "SHA512", 6) == 0) {
|
|
|
70d46f |
+ shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ return shaAlg;
|
|
|
70d46f |
+}
|
|
|
70d46f |
+
|
|
|
70d46f |
/*
|
|
|
70d46f |
* Perform the ECDSA Key Pair Generation Test.
|
|
|
70d46f |
*
|
|
|
70d46f |
* reqfn is the pathname of the REQUEST file.
|
|
|
70d46f |
*
|
|
|
70d46f |
* The output RESPONSE file is written to stdout.
|
|
|
70d46f |
*/
|
|
|
70d46f |
void
|
|
|
70d46f |
@@ -2623,27 +2651,18 @@ ecdsa_siggen_test(char *reqfn)
|
|
|
70d46f |
*dst++ = tolower(*src);
|
|
|
70d46f |
src += 2; /* skip the hyphen */
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst = '\0';
|
|
|
70d46f |
src++; /* skip the comma */
|
|
|
70d46f |
/* set the SHA Algorithm */
|
|
|
70d46f |
- if (strncmp(src, "SHA-1", 5) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-224", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-256", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-384", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-512", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
- } else {
|
|
|
70d46f |
+ shaAlg = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (shaAlg == HASH_AlgNULL){
|
|
|
70d46f |
fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
goto loser;
|
|
|
70d46f |
}
|
|
|
70d46f |
if (ecparams != NULL) {
|
|
|
70d46f |
PORT_FreeArena(ecparams->arena, PR_FALSE);
|
|
|
70d46f |
ecparams = NULL;
|
|
|
70d46f |
}
|
|
|
70d46f |
encodedparams = getECParams(curve);
|
|
|
70d46f |
@@ -2793,27 +2812,18 @@ ecdsa_sigver_test(char *reqfn)
|
|
|
70d46f |
*dst++ = tolower(*src);
|
|
|
70d46f |
src += 2; /* skip the hyphen */
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst++ = *src++;
|
|
|
70d46f |
*dst = '\0';
|
|
|
70d46f |
src++; /* skip the comma */
|
|
|
70d46f |
/* set the SHA Algorithm */
|
|
|
70d46f |
- if (strncmp(src, "SHA-1", 5) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-224", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-256", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-384", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
- } else if (strncmp(src, "SHA-512", 7) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
- } else {
|
|
|
70d46f |
+ shaAlg = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (shaAlg == HASH_AlgNULL) {
|
|
|
70d46f |
fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
goto loser;
|
|
|
70d46f |
}
|
|
|
70d46f |
encodedparams = getECParams(curve);
|
|
|
70d46f |
if (encodedparams == NULL) {
|
|
|
70d46f |
fprintf(stderr, "Unknown curve %s.", curve);
|
|
|
70d46f |
goto loser;
|
|
|
70d46f |
}
|
|
|
70d46f |
@@ -2951,16 +2961,932 @@ ecdsa_sigver_test(char *reqfn)
|
|
|
70d46f |
}
|
|
|
70d46f |
loser:
|
|
|
70d46f |
if (ecpub.ecParams.arena != NULL) {
|
|
|
70d46f |
PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
|
|
|
70d46f |
}
|
|
|
70d46f |
fclose(ecdsareq);
|
|
|
70d46f |
}
|
|
|
70d46f |
|
|
|
70d46f |
+/*
|
|
|
70d46f |
+ * Perform the ECDH Functional Test.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * reqfn is the pathname of the REQUEST file.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * The output RESPONSE file is written to stdout.
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+#define MAX_ECC_PARAMS 256
|
|
|
70d46f |
+void
|
|
|
70d46f |
+ecdh_functional(char *reqfn, PRBool response)
|
|
|
70d46f |
+{
|
|
|
70d46f |
+ char buf[256]; /* holds one line from the input REQUEST file.
|
|
|
70d46f |
+ * needs to be large enough to hold the longest
|
|
|
70d46f |
+ * line "Qx = <144 hex digits>\n".
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+ FILE *ecdhreq; /* input stream from the REQUEST file */
|
|
|
70d46f |
+ FILE *ecdhresp; /* output stream to the RESPONSE file */
|
|
|
70d46f |
+ char curve[16]; /* "nistxddd" */
|
|
|
70d46f |
+ unsigned char hashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ ECParams *ecparams[MAX_ECC_PARAMS] = {NULL};
|
|
|
70d46f |
+ ECPrivateKey *ecpriv = NULL;
|
|
|
70d46f |
+ ECParams *current_ecparams = NULL;
|
|
|
70d46f |
+ SECItem pubkey;
|
|
|
70d46f |
+ SECItem ZZ;
|
|
|
70d46f |
+ unsigned int i;
|
|
|
70d46f |
+ unsigned int len = 0;
|
|
|
70d46f |
+ unsigned int uit_len = 0;
|
|
|
70d46f |
+ int current_curve = -1;
|
|
|
70d46f |
+ HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
|
|
|
70d46f |
+
|
|
|
70d46f |
+ ecdhreq = fopen(reqfn, "r");
|
|
|
70d46f |
+ ecdhresp = stdout;
|
|
|
70d46f |
+ strcpy(curve, "nist");
|
|
|
70d46f |
+ pubkey.data = NULL;
|
|
|
70d46f |
+ while (fgets(buf, sizeof buf, ecdhreq) != NULL) {
|
|
|
70d46f |
+ /* a comment or blank line */
|
|
|
70d46f |
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == '[') {
|
|
|
70d46f |
+ /* [Ex] */
|
|
|
70d46f |
+ if (buf[1] == 'E' && buf[3] == ']') {
|
|
|
70d46f |
+ current_curve = buf[2] - 'A';
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* [Curve selected: x-nnn */
|
|
|
70d46f |
+ if (strncmp(buf, "[Curve ", 7) == 0) {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ char *dst;
|
|
|
70d46f |
+ SECItem *encodedparams;
|
|
|
70d46f |
+
|
|
|
70d46f |
+ if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS)) {
|
|
|
70d46f |
+ fprintf(stderr, "No curve type defined\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ while (*src && *src != ':') src++;
|
|
|
70d46f |
+ if (*src != ':') {
|
|
|
70d46f |
+ fprintf(stderr,
|
|
|
70d46f |
+ "No colon in curve selected statement\n%s", buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ dst = &curve[4];
|
|
|
70d46f |
+ *dst++ = tolower(*src);
|
|
|
70d46f |
+ src += 2; /* skip the hyphen */
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst = '\0';
|
|
|
70d46f |
+ if (ecparams[current_curve] != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(ecparams[current_curve]->arena, PR_FALSE);
|
|
|
70d46f |
+ ecparams[current_curve] = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ encodedparams = getECParams(curve);
|
|
|
70d46f |
+ if (encodedparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "Unknown curve %s.", curve);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (EC_DecodeParams(encodedparams, &ecparams[current_curve])
|
|
|
70d46f |
+ != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr, "Curve %s not supported.\n", curve);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* [Ex - SHAxxx] */
|
|
|
70d46f |
+ if (buf[1] == 'E' && buf[3] == ' ') {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ current_curve = buf[2] - 'A';
|
|
|
70d46f |
+ if ((current_curve < 0) || (current_curve > 256)) {
|
|
|
70d46f |
+ fprintf(stderr, "bad curve type defined (%c)\n", buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ current_ecparams = ecparams[current_curve];
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined for type %c defined\n",
|
|
|
70d46f |
+ buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ while (*src && *src != '-') src++;
|
|
|
70d46f |
+ if (*src != '-') {
|
|
|
70d46f |
+ fprintf(stderr,
|
|
|
70d46f |
+ "No data in curve selected statement\n%s",buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ hash = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (hash == HASH_AlgNULL){
|
|
|
70d46f |
+ fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* COUNT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "COUNT", 5) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined for type %c defined\n",
|
|
|
70d46f |
+ buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ len = (current_ecparams->fieldID.size + 7) >> 3;
|
|
|
70d46f |
+ if (pubkey.data != NULL) {
|
|
|
70d46f |
+ PORT_Free(pubkey.data);
|
|
|
70d46f |
+ pubkey.data = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(current_ecparams));
|
|
|
70d46f |
+ if (pubkey.data == NULL) {
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* QeCAVSx = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "QeCAVSx", 7) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 7;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(&pubkey.data[1], len, &buf[i]);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* QeCAVSy = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "QeCAVSy", 7) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 7;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* validate CAVS public key */
|
|
|
70d46f |
+ if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"BAD key detected\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* generate ECC key pair */
|
|
|
70d46f |
+ if (EC_NewKey(current_ecparams, &ecpriv) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Failed to generate new key\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* validate UIT generated public key */
|
|
|
70d46f |
+ if (EC_ValidatePublicKey(current_ecparams, &ecpriv->publicValue) !=
|
|
|
70d46f |
+ SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"generate key did not validate\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* output UIT public key */
|
|
|
70d46f |
+ uit_len = ecpriv->publicValue.len;
|
|
|
70d46f |
+ if (uit_len % 2 == 0) {
|
|
|
70d46f |
+ fprintf(stderr,"generate key had invalid public value len\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ uit_len = (uit_len - 1) / 2;
|
|
|
70d46f |
+ if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
|
|
|
70d46f |
+ fprintf(stderr,"generate key was compressed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs("QeIUTx = ", ecdhresp);
|
|
|
70d46f |
+ to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len);
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+ fputs("QeIUTy = ", ecdhresp);
|
|
|
70d46f |
+ to_hex_str(buf, &ecpriv->publicValue.data[1 + uit_len], uit_len);
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+ /* ECDH */
|
|
|
70d46f |
+ if (ECDH_Derive(&pubkey,current_ecparams, &ecpriv->privateValue,
|
|
|
70d46f |
+ PR_FALSE, &ZZ) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Derive failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* output hash of ZZ */
|
|
|
70d46f |
+ if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess ) {
|
|
|
70d46f |
+ fprintf(stderr,"hash of derived key failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(&ZZ, PR_FALSE);
|
|
|
70d46f |
+ fputs("HashZZ = ", ecdhresp);
|
|
|
70d46f |
+ to_hex_str(buf, hashBuf, fips_hashLen(hash));
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
|
|
|
70d46f |
+ ecpriv = NULL;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+loser:
|
|
|
70d46f |
+ if (ecpriv != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (i=0; i < MAX_ECC_PARAMS; i++) {
|
|
|
70d46f |
+ if (ecparams[i] != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(ecparams[i]->arena, PR_FALSE);
|
|
|
70d46f |
+ ecparams[i] = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pubkey.data != NULL) {
|
|
|
70d46f |
+ PORT_Free(pubkey.data);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fclose(ecdhreq);
|
|
|
70d46f |
+}
|
|
|
70d46f |
+
|
|
|
70d46f |
+#define MATCH_OPENSSL 1
|
|
|
70d46f |
+/*
|
|
|
70d46f |
+ * Perform the ECDH Validity Test.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * reqfn is the pathname of the REQUEST file.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * The output RESPONSE file is written to stdout.
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+void
|
|
|
70d46f |
+ecdh_verify(char *reqfn, PRBool response)
|
|
|
70d46f |
+{
|
|
|
70d46f |
+ char buf[256]; /* holds one line from the input REQUEST file.
|
|
|
70d46f |
+ * needs to be large enough to hold the longest
|
|
|
70d46f |
+ * line "Qx = <144 hex digits>\n".
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+ FILE *ecdhreq; /* input stream from the REQUEST file */
|
|
|
70d46f |
+ FILE *ecdhresp; /* output stream to the RESPONSE file */
|
|
|
70d46f |
+ char curve[16]; /* "nistxddd" */
|
|
|
70d46f |
+ unsigned char hashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ unsigned char cavsHashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ unsigned char private_data[MAX_ECKEY_LEN];
|
|
|
70d46f |
+ ECParams *ecparams[MAX_ECC_PARAMS] = {NULL};
|
|
|
70d46f |
+ ECParams *current_ecparams = NULL;
|
|
|
70d46f |
+ SECItem pubkey;
|
|
|
70d46f |
+ SECItem ZZ;
|
|
|
70d46f |
+ SECItem private_value;
|
|
|
70d46f |
+ unsigned int i;
|
|
|
70d46f |
+ unsigned int len = 0;
|
|
|
70d46f |
+ int current_curve = -1;
|
|
|
70d46f |
+ HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
|
|
|
70d46f |
+
|
|
|
70d46f |
+ ecdhreq = fopen(reqfn, "r");
|
|
|
70d46f |
+ ecdhresp = stdout;
|
|
|
70d46f |
+ strcpy(curve, "nist");
|
|
|
70d46f |
+ pubkey.data = NULL;
|
|
|
70d46f |
+ while (fgets(buf, sizeof buf, ecdhreq) != NULL) {
|
|
|
70d46f |
+ /* a comment or blank line */
|
|
|
70d46f |
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == '[') {
|
|
|
70d46f |
+ /* [Ex] */
|
|
|
70d46f |
+ if (buf[1] == 'E' && buf[3] == ']') {
|
|
|
70d46f |
+ current_curve = buf[2] - 'A';
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* [Curve selected: x-nnn */
|
|
|
70d46f |
+ if (strncmp(buf, "[Curve ", 7) == 0) {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ char *dst;
|
|
|
70d46f |
+ SECItem *encodedparams;
|
|
|
70d46f |
+
|
|
|
70d46f |
+ if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS)) {
|
|
|
70d46f |
+ fprintf(stderr, "No curve type defined\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ while (*src && *src != ':') src++;
|
|
|
70d46f |
+ if (*src != ':') {
|
|
|
70d46f |
+ fprintf(stderr,
|
|
|
70d46f |
+ "No colon in curve selected statement\n%s", buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ dst = &curve[4];
|
|
|
70d46f |
+ *dst++ = tolower(*src);
|
|
|
70d46f |
+ src += 2; /* skip the hyphen */
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst++ = *src++;
|
|
|
70d46f |
+ *dst = '\0';
|
|
|
70d46f |
+ if (ecparams[current_curve] != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(ecparams[current_curve]->arena, PR_FALSE);
|
|
|
70d46f |
+ ecparams[current_curve] = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ encodedparams = getECParams(curve);
|
|
|
70d46f |
+ if (encodedparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "Unknown curve %s.\n", curve);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (EC_DecodeParams(encodedparams, &ecparams[current_curve])
|
|
|
70d46f |
+ != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr, "Curve %s not supported.\n", curve);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* [Ex - SHAxxx] */
|
|
|
70d46f |
+ if (buf[1] == 'E' && buf[3] == ' ') {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ current_curve = buf[2] - 'A';
|
|
|
70d46f |
+ if ((current_curve < 0) || (current_curve > 256)) {
|
|
|
70d46f |
+ fprintf(stderr, "bad curve type defined (%c)\n", buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ current_ecparams = ecparams[current_curve];
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined for type %c defined\n",
|
|
|
70d46f |
+ buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ while (*src && *src != '-') src++;
|
|
|
70d46f |
+ if (*src != '-') {
|
|
|
70d46f |
+ fprintf(stderr,
|
|
|
70d46f |
+ "No data in curve selected statement\n%s",buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ hash = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (hash == HASH_AlgNULL){
|
|
|
70d46f |
+ fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* COUNT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "COUNT", 5) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined for type %c defined\n",
|
|
|
70d46f |
+ buf[2]);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ len = (current_ecparams->fieldID.size + 7) >> 3;
|
|
|
70d46f |
+ if (pubkey.data != NULL) {
|
|
|
70d46f |
+ PORT_Free(pubkey.data);
|
|
|
70d46f |
+ pubkey.data = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(current_ecparams));
|
|
|
70d46f |
+ if (pubkey.data == NULL) {
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* QeCAVSx = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "QeCAVSx", 7) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 7;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(&pubkey.data[1], len, &buf[i]);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* QeCAVSy = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "QeCAVSy", 7) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 7;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (strncmp(buf, "deIUT", 5) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 5;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(private_data, len, &buf[i]);
|
|
|
70d46f |
+ private_value.data = private_data;
|
|
|
70d46f |
+ private_value.len = len;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (strncmp(buf, "QeIUTx", 6) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (strncmp(buf, "QeIUTy", 6) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (strncmp(buf, "CAVSHashZZ", 10) == 0) {
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ i = 10;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]);
|
|
|
70d46f |
+ if (current_ecparams == NULL) {
|
|
|
70d46f |
+ fprintf(stderr, "no curve defined for type defined\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* validate CAVS public key */
|
|
|
70d46f |
+ if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) {
|
|
|
70d46f |
+#ifdef MATCH_OPENSSL
|
|
|
70d46f |
+ fprintf(ecdhresp, "Result = F\n");
|
|
|
70d46f |
+#else
|
|
|
70d46f |
+ fprintf(ecdhresp, "Result = F # key didn't validate\n");
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* ECDH */
|
|
|
70d46f |
+ if (ECDH_Derive(&pubkey, current_ecparams, &private_value,
|
|
|
70d46f |
+ PR_FALSE, &ZZ) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Derive failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* output ZZ */
|
|
|
70d46f |
+#ifndef MATCH_OPENSSL
|
|
|
70d46f |
+ fputs("Z = ", ecdhresp);
|
|
|
70d46f |
+ to_hex_str(buf, ZZ.data, ZZ.len);
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+
|
|
|
70d46f |
+ if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess ) {
|
|
|
70d46f |
+ fprintf(stderr,"hash of derived key failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(&ZZ, PR_FALSE);
|
|
|
70d46f |
+#ifndef MATCH_NIST
|
|
|
70d46f |
+ fputs("IUTHashZZ = ", ecdhresp);
|
|
|
70d46f |
+ to_hex_str(buf, hashBuf, fips_hashLen(hash));
|
|
|
70d46f |
+ fputs(buf, ecdhresp);
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) {
|
|
|
70d46f |
+#ifdef MATCH_OPENSSL
|
|
|
70d46f |
+ fprintf(ecdhresp, "Result = F\n");
|
|
|
70d46f |
+#else
|
|
|
70d46f |
+ fprintf(ecdhresp, "Result = F # hash doesn't match\n");
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ } else {
|
|
|
70d46f |
+ fprintf(ecdhresp, "Result = P\n");
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+#ifndef MATCH_OPENSSL
|
|
|
70d46f |
+ fputc('\n', ecdhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+loser:
|
|
|
70d46f |
+ for (i=0; i < MAX_ECC_PARAMS; i++) {
|
|
|
70d46f |
+ if (ecparams[i] != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(ecparams[i]->arena, PR_FALSE);
|
|
|
70d46f |
+ ecparams[i] = NULL;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pubkey.data != NULL) {
|
|
|
70d46f |
+ PORT_Free(pubkey.data);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fclose(ecdhreq);
|
|
|
70d46f |
+}
|
|
|
70d46f |
+
|
|
|
70d46f |
+/*
|
|
|
70d46f |
+ * Perform the DH Functional Test.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * reqfn is the pathname of the REQUEST file.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * The output RESPONSE file is written to stdout.
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+#define MAX_ECC_PARAMS 256
|
|
|
70d46f |
+void
|
|
|
70d46f |
+dh_functional(char *reqfn, PRBool response)
|
|
|
70d46f |
+{
|
|
|
70d46f |
+ char buf[1024]; /* holds one line from the input REQUEST file.
|
|
|
70d46f |
+ * needs to be large enough to hold the longest
|
|
|
70d46f |
+ * line "YephCAVS = <512 hex digits>\n".
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+ FILE *dhreq; /* input stream from the REQUEST file */
|
|
|
70d46f |
+ FILE *dhresp; /* output stream to the RESPONSE file */
|
|
|
70d46f |
+ unsigned char hashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ DSAPrivateKey *dsapriv = NULL;
|
|
|
70d46f |
+ PQGParams pqg = { 0 };
|
|
|
70d46f |
+ unsigned char pubkeydata[DSA_MAX_P_BITS/8];
|
|
|
70d46f |
+ SECItem pubkey;
|
|
|
70d46f |
+ SECItem ZZ;
|
|
|
70d46f |
+ unsigned int i,j;
|
|
|
70d46f |
+ unsigned int pgySize;
|
|
|
70d46f |
+ HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
|
|
|
70d46f |
+
|
|
|
70d46f |
+ dhreq = fopen(reqfn, "r");
|
|
|
70d46f |
+ dhresp = stdout;
|
|
|
70d46f |
+ while (fgets(buf, sizeof buf, dhreq) != NULL) {
|
|
|
70d46f |
+ /* a comment or blank line */
|
|
|
70d46f |
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == '[') {
|
|
|
70d46f |
+ /* [Fx - SHAxxx] */
|
|
|
70d46f |
+ if (buf[1] == 'F' && buf[3] == ' ') {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ while (*src && *src != '-') src++;
|
|
|
70d46f |
+ if (*src != '-') {
|
|
|
70d46f |
+ fprintf(stderr, "No hash specified\n%s",buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ hash = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (hash == HASH_AlgNULL){
|
|
|
70d46f |
+ fprintf(dhresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* clear the PQG parameters */
|
|
|
70d46f |
+ if (pqg.prime.data) { /* P */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pqg.subPrime.data) { /* Q */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pqg.base.data) { /* G */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ pgySize = DSA_MAX_P_BITS / 8; /* change if more key sizes are supported in CAVS */
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.prime, pgySize);
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.base, pgySize);
|
|
|
70d46f |
+ pqg.prime.len = pqg.base.len = pgySize;
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* set q to the max allows */
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.subPrime, DSA_MAX_Q_BITS/ 8);
|
|
|
70d46f |
+ pqg.subPrime.len = DSA_MAX_Q_BITS / 8;
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == 'P') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.prime.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.prime.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.prime.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* Q = ... */
|
|
|
70d46f |
+ if (buf[0] == 'Q') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.subPrime.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* G = ... */
|
|
|
70d46f |
+ if (buf[0] == 'G') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.base.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.base.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.base.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* COUNT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "COUNT", 5) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* YephemCAVS = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "YephemCAVS", 10) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ i = 10;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(pubkeydata, pqg.prime.len, &buf[i]);
|
|
|
70d46f |
+ pubkey.data = pubkeydata;
|
|
|
70d46f |
+ pubkey.len = pqg.prime.len;
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* generate FCC key pair, nist uses pqg rather then pg,
|
|
|
70d46f |
+ * so use DSA to generate the key */
|
|
|
70d46f |
+ if (DSA_NewKey(&pqg, &dsapriv) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Failed to generate new key\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs("XephemIUT = ", dhresp);
|
|
|
70d46f |
+ to_hex_str(buf, dsapriv->privateValue.data, dsapriv->privateValue.len);
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+ fputs("YephemIUT = ", dhresp);
|
|
|
70d46f |
+ to_hex_str(buf, dsapriv->publicValue.data, dsapriv->publicValue.len);
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+ /* DH */
|
|
|
70d46f |
+ if (DH_Derive(&pubkey,&pqg.prime, &dsapriv->privateValue,
|
|
|
70d46f |
+ &ZZ, pqg.prime.len) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Derive failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* output hash of ZZ */
|
|
|
70d46f |
+ if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess ) {
|
|
|
70d46f |
+ fprintf(stderr,"hash of derived key failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(&ZZ, PR_FALSE);
|
|
|
70d46f |
+ fputs("HashZZ = ", dhresp);
|
|
|
70d46f |
+ to_hex_str(buf, hashBuf, fips_hashLen(hash));
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+ PORT_FreeArena(dsapriv->params.arena, PR_TRUE);
|
|
|
70d46f |
+ dsapriv = NULL;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+loser:
|
|
|
70d46f |
+ if (dsapriv != NULL) {
|
|
|
70d46f |
+ PORT_FreeArena(dsapriv->params.arena, PR_TRUE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fclose(dhreq);
|
|
|
70d46f |
+}
|
|
|
70d46f |
+
|
|
|
70d46f |
+#define MATCH_OPENSSL 1
|
|
|
70d46f |
+/*
|
|
|
70d46f |
+ * Perform the DH Validity Test.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * reqfn is the pathname of the REQUEST file.
|
|
|
70d46f |
+ *
|
|
|
70d46f |
+ * The output RESPONSE file is written to stdout.
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+void
|
|
|
70d46f |
+dh_verify(char *reqfn, PRBool response)
|
|
|
70d46f |
+{
|
|
|
70d46f |
+ char buf[1024]; /* holds one line from the input REQUEST file.
|
|
|
70d46f |
+ * needs to be large enough to hold the longest
|
|
|
70d46f |
+ * line "YephCAVS = <512 hex digits>\n".
|
|
|
70d46f |
+ */
|
|
|
70d46f |
+ FILE *dhreq; /* input stream from the REQUEST file */
|
|
|
70d46f |
+ FILE *dhresp; /* output stream to the RESPONSE file */
|
|
|
70d46f |
+ unsigned char hashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ unsigned char cavsHashBuf[HASH_LENGTH_MAX];
|
|
|
70d46f |
+ PQGParams pqg = { 0 };
|
|
|
70d46f |
+ unsigned char pubkeydata[DSA_MAX_P_BITS/8];
|
|
|
70d46f |
+ unsigned char privkeydata[DSA_MAX_P_BITS/8];
|
|
|
70d46f |
+ SECItem pubkey;
|
|
|
70d46f |
+ SECItem privkey;
|
|
|
70d46f |
+ SECItem ZZ;
|
|
|
70d46f |
+ unsigned int i,j;
|
|
|
70d46f |
+ unsigned int pgySize;
|
|
|
70d46f |
+ HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
|
|
|
70d46f |
+
|
|
|
70d46f |
+ dhreq = fopen(reqfn, "r");
|
|
|
70d46f |
+ dhresp = stdout;
|
|
|
70d46f |
+ while (fgets(buf, sizeof buf, dhreq) != NULL) {
|
|
|
70d46f |
+ /* a comment or blank line */
|
|
|
70d46f |
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == '[') {
|
|
|
70d46f |
+ /* [Fx - SHAxxx] */
|
|
|
70d46f |
+ if (buf[1] == 'F' && buf[3] == ' ') {
|
|
|
70d46f |
+ const char *src;
|
|
|
70d46f |
+ /* skip passed the colon */
|
|
|
70d46f |
+ src = &buf[1];
|
|
|
70d46f |
+ while (*src && *src != '-') src++;
|
|
|
70d46f |
+ if (*src != '-') {
|
|
|
70d46f |
+ fprintf(stderr, "No hash specified\n%s",buf);
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ src++;
|
|
|
70d46f |
+ /* skip to the first non-space */
|
|
|
70d46f |
+ while (*src && *src == ' ') src++;
|
|
|
70d46f |
+ hash = hash_string_to_hashType(src);
|
|
|
70d46f |
+ if (hash == HASH_AlgNULL){
|
|
|
70d46f |
+ fprintf(dhresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* clear the PQG parameters */
|
|
|
70d46f |
+ if (pqg.prime.data) { /* P */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pqg.subPrime.data) { /* Q */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (pqg.base.data) { /* G */
|
|
|
70d46f |
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ pgySize = DSA_MAX_P_BITS / 8; /* change if more key sizes are supported in CAVS */
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.prime, pgySize);
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.base, pgySize);
|
|
|
70d46f |
+ pqg.prime.len = pqg.base.len = pgySize;
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* set q to the max allows */
|
|
|
70d46f |
+ SECITEM_AllocItem(NULL, &pqg.subPrime, DSA_MAX_Q_BITS/ 8);
|
|
|
70d46f |
+ pqg.subPrime.len = DSA_MAX_Q_BITS / 8;
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ if (buf[0] == 'P') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.prime.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.prime.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.prime.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* Q = ... */
|
|
|
70d46f |
+ if (buf[0] == 'Q') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.subPrime.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* G = ... */
|
|
|
70d46f |
+ if (buf[0] == 'G') {
|
|
|
70d46f |
+ i = 1;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ for (j = 0; j < pqg.base.len; i += 2, j++) {
|
|
|
70d46f |
+ if (!isxdigit(buf[i])) {
|
|
|
70d46f |
+ pqg.base.len = j;
|
|
|
70d46f |
+ break;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ hex_to_byteval(&buf[i], &pqg.base.data[j]);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* COUNT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "COUNT", 5) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+
|
|
|
70d46f |
+ /* YephemCAVS = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "YephemCAVS", 10) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ i = 10;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(pubkeydata, pqg.prime.len, &buf[i]);
|
|
|
70d46f |
+ pubkey.data = pubkeydata;
|
|
|
70d46f |
+ pubkey.len = pqg.prime.len;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* XephemUIT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "XephemIUT", 9) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ i = 9;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(privkeydata, pqg.subPrime.len, &buf[i]);
|
|
|
70d46f |
+ privkey.data = privkeydata;
|
|
|
70d46f |
+ privkey.len = pqg.subPrime.len;
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* YephemUIT = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "YephemIUT", 9) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* CAVSHashZZ = ... */
|
|
|
70d46f |
+ if (strncmp(buf, "CAVSHashZZ", 10) == 0) {
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ i = 10;
|
|
|
70d46f |
+ while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
+ i++;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]);
|
|
|
70d46f |
+ /* do the DH operation*/
|
|
|
70d46f |
+ if (DH_Derive(&pubkey,&pqg.prime, &privkey,
|
|
|
70d46f |
+ &ZZ, pqg.prime.len) != SECSuccess) {
|
|
|
70d46f |
+ fprintf(stderr,"Derive failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /* output ZZ */
|
|
|
70d46f |
+#ifndef MATCH_OPENSSL
|
|
|
70d46f |
+ fputs("Z = ", dhresp);
|
|
|
70d46f |
+ to_hex_str(buf, ZZ.data, ZZ.len);
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess ) {
|
|
|
70d46f |
+ fprintf(stderr,"hash of derived key failed\n");
|
|
|
70d46f |
+ goto loser;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ SECITEM_FreeItem(&ZZ, PR_FALSE);
|
|
|
70d46f |
+#ifndef MATCH_NIST_
|
|
|
70d46f |
+ fputs("IUTHashZZ = ", dhresp);
|
|
|
70d46f |
+ to_hex_str(buf, hashBuf, fips_hashLen(hash));
|
|
|
70d46f |
+ fputs(buf, dhresp);
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) {
|
|
|
70d46f |
+ fprintf(dhresp, "Result = F\n");
|
|
|
70d46f |
+ } else {
|
|
|
70d46f |
+ fprintf(dhresp, "Result = P\n");
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+#ifndef MATCH_OPENSSL
|
|
|
70d46f |
+ fputc('\n', dhresp);
|
|
|
70d46f |
+#endif
|
|
|
70d46f |
+ continue;
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+loser:
|
|
|
70d46f |
+ fclose(dhreq);
|
|
|
70d46f |
+}
|
|
|
70d46f |
+
|
|
|
70d46f |
PRBool
|
|
|
70d46f |
isblankline(char *b)
|
|
|
70d46f |
{
|
|
|
70d46f |
while (isspace(*b))
|
|
|
70d46f |
b++;
|
|
|
70d46f |
if ((*b == '\n') || (*b == 0)) {
|
|
|
70d46f |
return PR_TRUE;
|
|
|
70d46f |
}
|
|
|
70d46f |
@@ -5337,27 +6263,18 @@ rsa_siggen_test(char *reqfn)
|
|
|
70d46f |
|
|
|
70d46f |
/* SHAAlg = ... */
|
|
|
70d46f |
if (strncmp(buf, "SHAAlg", 6) == 0) {
|
|
|
70d46f |
i = 6;
|
|
|
70d46f |
while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
i++;
|
|
|
70d46f |
}
|
|
|
70d46f |
/* set the SHA Algorithm */
|
|
|
70d46f |
- if (strncmp(&buf[i], "SHA1", 4) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA224", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
- } else {
|
|
|
70d46f |
+ shaAlg = hash_string_to_hashType(&buf[i]);
|
|
|
70d46f |
+ if (shaAlg == HASH_AlgNULL) {
|
|
|
70d46f |
fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
goto loser;
|
|
|
70d46f |
}
|
|
|
70d46f |
fputs(buf, rsaresp);
|
|
|
70d46f |
continue;
|
|
|
70d46f |
}
|
|
|
70d46f |
/* Msg = ... */
|
|
|
70d46f |
if (strncmp(buf, "Msg", 3) == 0) {
|
|
|
70d46f |
@@ -5532,27 +6449,18 @@ rsa_sigver_test(char *reqfn)
|
|
|
70d46f |
|
|
|
70d46f |
/* SHAAlg = ... */
|
|
|
70d46f |
if (strncmp(buf, "SHAAlg", 6) == 0) {
|
|
|
70d46f |
i = 6;
|
|
|
70d46f |
while (isspace(buf[i]) || buf[i] == '=') {
|
|
|
70d46f |
i++;
|
|
|
70d46f |
}
|
|
|
70d46f |
/* set the SHA Algorithm */
|
|
|
70d46f |
- if (strncmp(&buf[i], "SHA1", 4) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA1;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA224", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA224;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA256;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA384;
|
|
|
70d46f |
- } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
|
|
|
70d46f |
- shaAlg = HASH_AlgSHA512;
|
|
|
70d46f |
- } else {
|
|
|
70d46f |
+ shaAlg = hash_string_to_hashType(&buf[i]);
|
|
|
70d46f |
+ if (shaAlg == HASH_AlgNULL) {
|
|
|
70d46f |
fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
|
|
|
70d46f |
goto loser;
|
|
|
70d46f |
}
|
|
|
70d46f |
fputs(buf, rsaresp);
|
|
|
70d46f |
continue;
|
|
|
70d46f |
}
|
|
|
70d46f |
|
|
|
70d46f |
/* e = ... public Key */
|
|
|
70d46f |
@@ -6103,16 +7011,44 @@ main(int argc, char **argv)
|
|
|
70d46f |
} else if (strcmp(argv[2], "siggen") == 0) {
|
|
|
70d46f |
/* Signature Generation Test */
|
|
|
70d46f |
ecdsa_siggen_test(argv[3]);
|
|
|
70d46f |
} else if (strcmp(argv[2], "sigver") == 0) {
|
|
|
70d46f |
/* Signature Verification Test */
|
|
|
70d46f |
ecdsa_sigver_test(argv[3]);
|
|
|
70d46f |
}
|
|
|
70d46f |
/*************/
|
|
|
70d46f |
+ /* ECDH */
|
|
|
70d46f |
+ /*************/
|
|
|
70d46f |
+ } else if (strcmp(argv[1], "ecdh") == 0) {
|
|
|
70d46f |
+ /* argv[2]={init|resp}-{func|verify} argv[3]=<test name>.req */
|
|
|
70d46f |
+ if (strcmp(argv[2], "init-func") == 0) {
|
|
|
70d46f |
+ ecdh_functional(argv[3], 0);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "resp-func") == 0) {
|
|
|
70d46f |
+ ecdh_functional(argv[3], 1);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "init-verify") == 0) {
|
|
|
70d46f |
+ ecdh_verify(argv[3], 0);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "resp-verify") == 0) {
|
|
|
70d46f |
+ ecdh_verify(argv[3], 1);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /*************/
|
|
|
70d46f |
+ /* DH */
|
|
|
70d46f |
+ /*************/
|
|
|
70d46f |
+ } else if (strcmp(argv[1], "dh") == 0) {
|
|
|
70d46f |
+ /* argv[2]={init|resp}-{func|verify} argv[3]=<test name>.req */
|
|
|
70d46f |
+ if (strcmp(argv[2], "init-func") == 0) {
|
|
|
70d46f |
+ dh_functional(argv[3], 0);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "resp-func") == 0) {
|
|
|
70d46f |
+ dh_functional(argv[3], 1);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "init-verify") == 0) {
|
|
|
70d46f |
+ dh_verify(argv[3], 0);
|
|
|
70d46f |
+ } else if (strcmp(argv[2], "resp-verify") == 0) {
|
|
|
70d46f |
+ dh_verify(argv[3], 1);
|
|
|
70d46f |
+ }
|
|
|
70d46f |
+ /*************/
|
|
|
70d46f |
/* RNG */
|
|
|
70d46f |
/*************/
|
|
|
70d46f |
} else if (strcmp(argv[1], "rng") == 0) {
|
|
|
70d46f |
/* argv[2]=vst|mct argv[3]=<test name>.req */
|
|
|
70d46f |
if (strcmp(argv[2], "vst") == 0) {
|
|
|
70d46f |
/* Variable Seed Test */
|
|
|
70d46f |
rng_vst(argv[3]);
|
|
|
70d46f |
} else if (strcmp(argv[2], "mct") == 0) {
|
|
|
70d46f |
diff --git a/cmd/fipstest/kas.sh b/cmd/fipstest/kas.sh
|
|
|
70d46f |
new file mode 100755
|
|
|
70d46f |
--- /dev/null
|
|
|
70d46f |
+++ b/cmd/fipstest/kas.sh
|
|
|
70d46f |
@@ -0,0 +1,84 @@
|
|
|
70d46f |
+#!/bin/sh
|
|
|
70d46f |
+#
|
|
|
70d46f |
+# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
70d46f |
+# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
70d46f |
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
70d46f |
+#
|
|
|
70d46f |
+# A Bourne shell script for running the NIST DSA Validation System
|
|
|
70d46f |
+#
|
|
|
70d46f |
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
|
|
|
70d46f |
+# variables appropriately so that the fipstest command and the NSPR and NSS
|
|
|
70d46f |
+# shared libraries/DLLs are on the search path. Then run this script in the
|
|
|
70d46f |
+# directory where the REQUEST (.req) files reside. The script generates the
|
|
|
70d46f |
+# RESPONSE (.rsp) files in the same directory.
|
|
|
70d46f |
+BASEDIR=${1-.}
|
|
|
70d46f |
+TESTDIR=${BASEDIR}/KAS
|
|
|
70d46f |
+COMMAND=${2-run}
|
|
|
70d46f |
+REQDIR=${TESTDIR}/req
|
|
|
70d46f |
+RSPDIR=${TESTDIR}/resp
|
|
|
70d46f |
+
|
|
|
70d46f |
+
|
|
|
70d46f |
+#
|
|
|
70d46f |
+if [ ${COMMAND} = "verify" ]; then
|
|
|
70d46f |
+#
|
|
|
70d46f |
+# need verify for KAS tests
|
|
|
70d46f |
+
|
|
|
70d46f |
+# verify generated keys
|
|
|
70d46f |
+# name=KeyPair
|
|
|
70d46f |
+# echo ">>>>> $name"
|
|
|
70d46f |
+# fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
|
|
70d46f |
+# verify generated pqg values
|
|
|
70d46f |
+# name=PQGGen
|
|
|
70d46f |
+# echo ">>>>> $name"
|
|
|
70d46f |
+# fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
|
|
70d46f |
+# verify PQGVer with known answer
|
|
|
70d46f |
+# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
|
|
|
70d46f |
+# verify signatures
|
|
|
70d46f |
+# name=SigGen
|
|
|
70d46f |
+# echo ">>>>> $name"
|
|
|
70d46f |
+# fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
|
|
70d46f |
+# verify SigVer with known answer
|
|
|
70d46f |
+# sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
|
|
|
70d46f |
+ exit 0
|
|
|
70d46f |
+fi
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest ecdh init-func ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest ecdh resp-func ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest ecdh init-verify ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest ecdh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest dh init-func ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest dh resp-func ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest dh init-verify ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
+request=KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
|
|
|
70d46f |
+response=`echo $request | sed -e "s/req/rsp/"`
|
|
|
70d46f |
+echo $request $response
|
|
|
70d46f |
+fipstest dh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response
|
|
|
70d46f |
+
|
|
|
70d46f |
diff --git a/cmd/fipstest/runtest.sh b/cmd/fipstest/runtest.sh
|
|
|
70d46f |
--- a/cmd/fipstest/runtest.sh
|
|
|
70d46f |
+++ b/cmd/fipstest/runtest.sh
|
|
|
70d46f |
@@ -1,14 +1,14 @@
|
|
|
70d46f |
#!/bin/sh
|
|
|
70d46f |
#
|
|
|
70d46f |
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
70d46f |
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
70d46f |
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
70d46f |
#
|
|
|
70d46f |
TESTDIR=${1-.}
|
|
|
70d46f |
COMMAND=${2-run}
|
|
|
70d46f |
-TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea"
|
|
|
70d46f |
+TESTS="aes aesgcm dsa ecdsa hmac kas tls rng rsa sha tdea"
|
|
|
70d46f |
for i in $TESTS
|
|
|
70d46f |
do
|
|
|
70d46f |
echo "********************Running $i tests"
|
|
|
70d46f |
sh ./${i}.sh ${TESTDIR} ${COMMAND}
|
|
|
70d46f |
done
|