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