286 lines
8.7 KiB
Diff
286 lines
8.7 KiB
Diff
|
# HG changeset patch
|
||
|
# User Hans Petter Jansson <hpj@cl.no>
|
||
|
# Date 1574234297 -3600
|
||
|
# Wed Nov 20 08:18:17 2019 +0100
|
||
|
# Node ID af7d3ee4e96cf685be0b95dff7aa5a1d3ab64a89
|
||
|
# Parent 5d6e015d1af40b5f5b990d0cf4d97932774c2a61
|
||
|
[PATCH] 20
|
||
|
From ac98082c3bc0c9f85213078b730980483062f25c Mon Sep 17 00:00:00 2001
|
||
|
---
|
||
|
nss/cmd/fipstest/fipstest.c | 194 ++++++++++++++++++++++++++++++++++++
|
||
|
nss/cmd/fipstest/kas.sh | 47 +++++++++
|
||
|
2 files changed, 241 insertions(+)
|
||
|
create mode 100644 nss/cmd/fipstest/kas.sh
|
||
|
|
||
|
Index: nss/cmd/fipstest/fipstest.c
|
||
|
===================================================================
|
||
|
--- nss.orig/cmd/fipstest/fipstest.c
|
||
|
+++ nss/cmd/fipstest/fipstest.c
|
||
|
@@ -2257,6 +2257,29 @@ fips_hashBuf(HASH_HashType type, unsigne
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
+SECStatus
|
||
|
+fips_hashBuf_zeropad(HASH_HashType type, unsigned char *hashBuf,
|
||
|
+ unsigned char *msg, int len, int pad_to_len)
|
||
|
+{
|
||
|
+ unsigned char buf [8192];
|
||
|
+
|
||
|
+ if (pad_to_len > 8192)
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Internal buffer too small.\n");
|
||
|
+ exit (1);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (len > pad_to_len)
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Value to hash exceeds maximum length.\n");
|
||
|
+ exit (1);
|
||
|
+ }
|
||
|
+
|
||
|
+ memset (buf, 0, pad_to_len - len);
|
||
|
+ memcpy (buf + (pad_to_len - len), msg, len);
|
||
|
+ return fips_hashBuf (type, hashBuf, buf, pad_to_len);
|
||
|
+}
|
||
|
+
|
||
|
int
|
||
|
fips_hashLen(HASH_HashType type)
|
||
|
{
|
||
|
@@ -8892,6 +8915,168 @@ out:
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+parse_secitem (const char *name, const char *buf, SECItem *secitem)
|
||
|
+{
|
||
|
+ if (!strncmp (buf, name, strlen (name))) {
|
||
|
+ int i, j, len;
|
||
|
+
|
||
|
+ i = strlen (name);
|
||
|
+ while (isspace(buf[i]) || buf[i] == '=') {
|
||
|
+ i++;
|
||
|
+ }
|
||
|
+
|
||
|
+ len = strspn (&buf[i], "0123456789abcdefABCDEF");
|
||
|
+ if (!len)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ if (secitem->data) {
|
||
|
+ SECITEM_ZfreeItem(secitem, PR_FALSE);
|
||
|
+ secitem->data = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ len = (len + 1) / 2;
|
||
|
+ SECITEM_AllocItem(NULL, secitem, len);
|
||
|
+ secitem->len = len;
|
||
|
+
|
||
|
+ memset(secitem->data, 0, secitem->len);
|
||
|
+ for (j = 0; j < secitem->len; i += 2, j++) {
|
||
|
+ hex_to_byteval(&buf[i], &secitem->data[j]);
|
||
|
+ }
|
||
|
+
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+void
|
||
|
+kas_ffc_test(char *reqfn, int do_validity)
|
||
|
+{
|
||
|
+ char buf[1024];
|
||
|
+ FILE *req; /* input stream from the REQUEST file */
|
||
|
+ FILE *resp; /* output stream to the RESPONSE file */
|
||
|
+ PQGParams keyParams;
|
||
|
+ HASH_HashType hashType = HASH_AlgNULL;
|
||
|
+ int hashNum = 0;
|
||
|
+ SECItem y_ephem_cavs;
|
||
|
+ SECItem x_ephem_iut;
|
||
|
+ SECItem y_ephem_iut;
|
||
|
+ SECItem cavs_hash_zz;
|
||
|
+
|
||
|
+ req = fopen(reqfn, "r");
|
||
|
+ resp = stdout;
|
||
|
+ memset(&keyParams, 0, sizeof(keyParams));
|
||
|
+ memset(&y_ephem_cavs, 0, sizeof(y_ephem_cavs));
|
||
|
+ memset(&x_ephem_iut, 0, sizeof(x_ephem_iut));
|
||
|
+ memset(&y_ephem_iut, 0, sizeof(y_ephem_iut));
|
||
|
+ memset(&cavs_hash_zz, 0, sizeof(cavs_hash_zz));
|
||
|
+
|
||
|
+ while (fgets(buf, sizeof buf, req) != NULL) {
|
||
|
+ /* [xx] or
|
||
|
+ * [xx - SHAxxx] or
|
||
|
+ * [SHA(s) supported (Used for hashing Z): SHAxxx] */
|
||
|
+ if (buf[0] == '[') {
|
||
|
+ unsigned char tbuf [2];
|
||
|
+
|
||
|
+ if (sscanf(buf, "[%c%c - SHA%d]", &tbuf [0], &tbuf [1],
|
||
|
+ &hashNum) != 3) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ fputs(buf, resp);
|
||
|
+
|
||
|
+ hashType = sha_get_hashType(hashNum);
|
||
|
+ if (hashType == HASH_AlgNULL) {
|
||
|
+ fprintf(resp, "ERROR: invalid hash (SHA-%d)", hashNum);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("YephemCAVS", buf, &y_ephem_cavs)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+
|
||
|
+ if (!do_validity) {
|
||
|
+ SECItem ZZ;
|
||
|
+ unsigned char ZZ_hash_buf [1024];
|
||
|
+ DHParams dh_params;
|
||
|
+ DHPrivateKey *dh_privKey;
|
||
|
+
|
||
|
+ dh_params.prime = keyParams.prime;
|
||
|
+ dh_params.base = keyParams.base;
|
||
|
+
|
||
|
+ DH_NewKey (&dh_params, &dh_privKey);
|
||
|
+ DH_Derive(&y_ephem_cavs, &keyParams.prime, &dh_privKey->privateValue, &ZZ, 0);
|
||
|
+
|
||
|
+ fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, keyParams.prime.len);
|
||
|
+
|
||
|
+ to_hex_str(buf, dh_privKey->publicValue.data, dh_privKey->publicValue.len);
|
||
|
+ fprintf(resp, "YephemIUT = %s\n", buf);
|
||
|
+
|
||
|
+ to_hex_str(buf, ZZ_hash_buf, hashNum / 8);
|
||
|
+ fprintf(resp, "HashZZ = %s\n", buf);
|
||
|
+
|
||
|
+ PORT_FreeArena(dh_privKey->arena, PR_TRUE);
|
||
|
+ }
|
||
|
+
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("XephemIUT", buf, &x_ephem_iut)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("YephemIUT", buf, &y_ephem_iut)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("CAVSHashZZ", buf, &cavs_hash_zz)) {
|
||
|
+ if (do_validity) {
|
||
|
+ SECItem ZZ;
|
||
|
+ unsigned char ZZ_hash_buf [1024];
|
||
|
+ char Z_buf [1024];
|
||
|
+
|
||
|
+ DH_Derive(&y_ephem_cavs, &keyParams.prime, &x_ephem_iut, &ZZ, 0);
|
||
|
+
|
||
|
+ fputs(buf, resp);
|
||
|
+
|
||
|
+ to_hex_str(Z_buf, ZZ.data, ZZ.len);
|
||
|
+
|
||
|
+ fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, keyParams.prime.len);
|
||
|
+ to_hex_str(Z_buf, ZZ_hash_buf, hashNum / 8);
|
||
|
+ fprintf(resp, "IUTHashZZ = %s\n", Z_buf);
|
||
|
+
|
||
|
+ fprintf(resp, "Result = %s\n",
|
||
|
+ (cavs_hash_zz.len == hashNum / 8 && memcmp (cavs_hash_zz.data, ZZ_hash_buf, hashNum / 8) == 0) ? "P" : "F");
|
||
|
+ } else {
|
||
|
+ fputs(buf, resp);
|
||
|
+ }
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("P", buf, &keyParams.prime)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("Q", buf, &keyParams.subPrime)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ } else if (parse_secitem ("G", buf, &keyParams.base)) {
|
||
|
+ fputs(buf, resp);
|
||
|
+ continue;
|
||
|
+ } else {
|
||
|
+ /* Comments, blank lines, ... */
|
||
|
+ fputs(buf, resp);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+out:
|
||
|
+ fclose(req);
|
||
|
+ if (keyParams.prime.data) { /* P */
|
||
|
+ SECITEM_ZfreeItem(&keyParams.prime, PR_FALSE);
|
||
|
+ }
|
||
|
+ if (keyParams.subPrime.data) { /* Q */
|
||
|
+ SECITEM_ZfreeItem(&keyParams.subPrime, PR_FALSE);
|
||
|
+ }
|
||
|
+ if (keyParams.base.data) { /* G */
|
||
|
+ SECITEM_ZfreeItem(&keyParams.base, PR_FALSE);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
int
|
||
|
main(int argc, char **argv)
|
||
|
{
|
||
|
@@ -9078,6 +9263,15 @@ main(int argc, char **argv)
|
||
|
/* AES Keywrap */
|
||
|
/***************/
|
||
|
keywrap(argv[2]);
|
||
|
+ } else if (strcmp(argv[1], "kasffc") == 0) {
|
||
|
+ /***************/
|
||
|
+ /* KAS FFC */
|
||
|
+ /***************/
|
||
|
+ if (strcmp(argv[2], "validity") == 0) {
|
||
|
+ kas_ffc_test(argv[3], PR_TRUE);
|
||
|
+ } else {
|
||
|
+ kas_ffc_test(argv[3], PR_FALSE);
|
||
|
+ }
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
Index: nss/cmd/fipstest/kas.sh
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ nss/cmd/fipstest/kas.sh
|
||
|
@@ -0,0 +1,47 @@
|
||
|
+#!/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 RNG Validation Suite
|
||
|
+#
|
||
|
+# 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
|
||
|
+
|
||
|
+kas_requests_ffc_function="
|
||
|
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req
|
||
|
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req
|
||
|
+"
|
||
|
+
|
||
|
+kas_requests_ffc_validity="
|
||
|
+KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req
|
||
|
+KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
|
||
|
+"
|
||
|
+
|
||
|
+if [ ${COMMAND} = "verify" ]; then
|
||
|
+ for request in $kas_requests; do
|
||
|
+ sh ./validate1.sh ${TESTDIR} $request
|
||
|
+ done
|
||
|
+ exit 0
|
||
|
+fi
|
||
|
+
|
||
|
+for request in $kas_requests_ffc_function; do
|
||
|
+ response=`echo $request | sed -e "s/req/rsp/"`
|
||
|
+ echo $request $response
|
||
|
+ fipstest kasffc function ${REQDIR}/$request > ${RSPDIR}/$response
|
||
|
+done
|
||
|
+
|
||
|
+for request in $kas_requests_ffc_validity; do
|
||
|
+ response=`echo $request | sed -e "s/req/rsp/"`
|
||
|
+ echo $request $response
|
||
|
+ fipstest kasffc validity ${REQDIR}/$request > ${RSPDIR}/$response
|
||
|
+done
|