From f4a12fc67689a830e9da1c87fd11afe5bc09deb3 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 2 Jan 2020 21:06:40 +0100 Subject: Issue #1338 - Part 2: Update NSS to 3.48-RTM --- security/nss/cmd/fipstest/README | 1 + security/nss/cmd/fipstest/aes.sh | 112 --- security/nss/cmd/fipstest/aesgcm.sh | 67 -- security/nss/cmd/fipstest/dsa.sh | 71 -- security/nss/cmd/fipstest/ecdsa.sh | 60 -- security/nss/cmd/fipstest/fipstest.c | 1381 +++++++++++++++++++++++++++++++- security/nss/cmd/fipstest/hmac.sh | 36 - security/nss/cmd/fipstest/kas.sh | 84 -- security/nss/cmd/fipstest/rng.sh | 34 - security/nss/cmd/fipstest/rsa.sh | 50 -- security/nss/cmd/fipstest/runtest.sh | 14 - security/nss/cmd/fipstest/sha.sh | 66 -- security/nss/cmd/fipstest/tdea.sh | 106 --- security/nss/cmd/fipstest/tls.sh | 34 - security/nss/cmd/fipstest/validate.sh | 7 - security/nss/cmd/fipstest/validate1.sh | 30 - 16 files changed, 1361 insertions(+), 792 deletions(-) create mode 100644 security/nss/cmd/fipstest/README delete mode 100644 security/nss/cmd/fipstest/aes.sh delete mode 100644 security/nss/cmd/fipstest/aesgcm.sh delete mode 100755 security/nss/cmd/fipstest/dsa.sh delete mode 100644 security/nss/cmd/fipstest/ecdsa.sh delete mode 100755 security/nss/cmd/fipstest/hmac.sh delete mode 100644 security/nss/cmd/fipstest/kas.sh delete mode 100644 security/nss/cmd/fipstest/rng.sh delete mode 100644 security/nss/cmd/fipstest/rsa.sh delete mode 100644 security/nss/cmd/fipstest/runtest.sh delete mode 100644 security/nss/cmd/fipstest/sha.sh delete mode 100644 security/nss/cmd/fipstest/tdea.sh delete mode 100644 security/nss/cmd/fipstest/tls.sh delete mode 100644 security/nss/cmd/fipstest/validate.sh delete mode 100644 security/nss/cmd/fipstest/validate1.sh (limited to 'security/nss/cmd/fipstest') diff --git a/security/nss/cmd/fipstest/README b/security/nss/cmd/fipstest/README new file mode 100644 index 000000000..8f076587d --- /dev/null +++ b/security/nss/cmd/fipstest/README @@ -0,0 +1 @@ +The scripts have been moved to tests/fips/cavs_scripts diff --git a/security/nss/cmd/fipstest/aes.sh b/security/nss/cmd/fipstest/aes.sh deleted file mode 100644 index 7e25e60d2..000000000 --- a/security/nss/cmd/fipstest/aes.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/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 AES Algorithm 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}/AES -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -cbc_kat_requests=" -CBCGFSbox128.req -CBCGFSbox192.req -CBCGFSbox256.req -CBCKeySbox128.req -CBCKeySbox192.req -CBCKeySbox256.req -CBCVarKey128.req -CBCVarKey192.req -CBCVarKey256.req -CBCVarTxt128.req -CBCVarTxt192.req -CBCVarTxt256.req -" - -cbc_mct_requests=" -CBCMCT128.req -CBCMCT192.req -CBCMCT256.req -" - -cbc_mmt_requests=" -CBCMMT128.req -CBCMMT192.req -CBCMMT256.req -" - -ecb_kat_requests=" -ECBGFSbox128.req -ECBGFSbox192.req -ECBGFSbox256.req -ECBKeySbox128.req -ECBKeySbox192.req -ECBKeySbox256.req -ECBVarKey128.req -ECBVarKey192.req -ECBVarKey256.req -ECBVarTxt128.req -ECBVarTxt192.req -ECBVarTxt256.req -" - -ecb_mct_requests=" -ECBMCT128.req -ECBMCT192.req -ECBMCT256.req -" - -ecb_mmt_requests=" -ECBMMT128.req -ECBMMT192.req -ECBMMT256.req -" - -if [ ${COMMAND} = "verify" ]; then - for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do - sh ./validate1.sh ${TESTDIR} $request - done - exit 0 -fi - -for request in $cbc_kat_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $cbc_mct_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $cbc_mmt_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_kat_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_mct_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_mmt_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response -done diff --git a/security/nss/cmd/fipstest/aesgcm.sh b/security/nss/cmd/fipstest/aesgcm.sh deleted file mode 100644 index 3b4dcf5e4..000000000 --- a/security/nss/cmd/fipstest/aesgcm.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/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 AES Algorithm 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}/AES_GCM -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -gcm_decrypt_requests=" -gcmDecrypt128.req -gcmDecrypt192.req -gcmDecrypt256.req -" - -gcm_encrypt_extiv_requests=" -gcmEncryptExtIV128.req -gcmEncryptExtIV192.req -gcmEncryptExtIV256.req -" -gcm_encrypt_intiv_requests=" -" - -#gcm_encrypt_intiv_requests=" -#gcmEncryptIntIV128.req -#gcmEncryptIntIV192.req -#gcmEncryptIntIV256.req -#" - -if [ ${COMMAND} = "verify" ]; then - for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do - sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d' - done - for request in $gcm_encrypt_intiv_requests; do - name=`basename $request .req` - echo ">>>>> $name" - fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL - done - exit 0 -fi - -for request in $gcm_decrypt_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $gcm_encrypt_intiv_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $gcm_encrypt_extiv_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response -done diff --git a/security/nss/cmd/fipstest/dsa.sh b/security/nss/cmd/fipstest/dsa.sh deleted file mode 100755 index da18e1fa3..000000000 --- a/security/nss/cmd/fipstest/dsa.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/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}/DSA2 -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - - -# -# several of the DSA tests do use known answer tests to verify the result. -# in those cases, feed generated tests back into the fipstest tool and -# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify -# the dsa pqgver and dsa sigver functions, so we know they can detect errors -# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular. -# -if [ ${COMMAND} = "verify" ]; then -# 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=KeyPair.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response - -request=PQGGen.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response - -request=PQGVer1863.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response - -request=SigGen.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response - -request=SigVer.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response diff --git a/security/nss/cmd/fipstest/ecdsa.sh b/security/nss/cmd/fipstest/ecdsa.sh deleted file mode 100644 index 9482160cc..000000000 --- a/security/nss/cmd/fipstest/ecdsa.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/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 ECDSA 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}/ECDSA2 -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -# -# several of the ECDSA tests do not use known answer tests to verify the result. -# In those cases, feed generated tests back into the fipstest tool and -# see if we can verify those value. NOTE: PQGVer and SigVer tests verify -# the dsa pqgver and dsa sigver functions, so we know they can detect errors -# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular. -# -if [ ${COMMAND} = "verify" ]; then -# verify generated keys - name=KeyPair - echo ">>>>> $name" - fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F - sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' -# verify signatures - name=SigGen - echo ">>>>> $name" - fipstest ecdsa 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;.(.*);; -e /^Result.=.P/s;.(.*);;' - exit 0 -fi - -request=KeyPair.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response - -request=PKV.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response - -request=SigGen.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response - -request=SigVer.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index 5d00b3070..1a8008d59 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -34,6 +34,11 @@ #if 0 #include "../../lib/freebl/mpi/mpi.h" #endif +#define MATCH_OPENSSL 1 +/*#define MATCH_NIST 1 */ +#ifdef MATCH_NIST +#define VERBOSE_REASON 1 +#endif extern SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); @@ -3169,6 +3174,10 @@ ecdh_functional(char *reqfn, PRBool response) fprintf(stderr, "generate key was compressed\n"); goto loser; } + fputs("deIUT = ", ecdhresp); + to_hex_str(buf, ecpriv->privateValue.data, ecpriv->privateValue.len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); fputs("QeIUTx = ", ecdhresp); to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len); fputs(buf, ecdhresp); @@ -3215,7 +3224,6 @@ loser: fclose(ecdhreq); } -#define MATCH_OPENSSL 1 /* * Perform the ECDH Validity Test. * @@ -3408,9 +3416,10 @@ ecdh_verify(char *reqfn, PRBool response) fputs(buf, ecdhresp); continue; } - if (strncmp(buf, "CAVSHashZZ", 10) == 0) { + if ((strncmp(buf, "CAVSHashZZ", 10) == 0) || + (strncmp(buf, "HashZZ", 6) == 0)) { fputs(buf, ecdhresp); - i = 10; + i = (buf[0] == 'C') ? 10 : 6; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -3421,10 +3430,10 @@ ecdh_verify(char *reqfn, PRBool response) } /* validate CAVS public key */ if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) { -#ifdef MATCH_OPENSSL - fprintf(ecdhresp, "Result = F\n"); -#else +#ifdef VERBOSE_REASON fprintf(ecdhresp, "Result = F # key didn't validate\n"); +#else + fprintf(ecdhresp, "Result = F\n"); #endif continue; } @@ -3432,8 +3441,12 @@ ecdh_verify(char *reqfn, PRBool response) /* ECDH */ if (ECDH_Derive(&pubkey, current_ecparams, &private_value, PR_FALSE, &ZZ) != SECSuccess) { - fprintf(stderr, "Derive failed\n"); - goto loser; +#ifdef VERBOSE_REASON + fprintf(ecdhresp, "Result = F # derive failure\n"); +#else + fprintf(ecdhresp, "Result = F\n"); +#endif + continue; } /* output ZZ */ #ifndef MATCH_OPENSSL @@ -3455,10 +3468,10 @@ ecdh_verify(char *reqfn, PRBool response) fputc('\n', ecdhresp); #endif if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) { -#ifdef MATCH_OPENSSL - fprintf(ecdhresp, "Result = F\n"); -#else +#ifdef VERBOSE_REASON fprintf(ecdhresp, "Result = F # hash doesn't match\n"); +#else + fprintf(ecdhresp, "Result = F\n"); #endif } else { fprintf(ecdhresp, "Result = P\n"); @@ -3675,7 +3688,6 @@ loser: fclose(dhreq); } -#define MATCH_OPENSSL 1 /* * Perform the DH Validity Test. * @@ -3846,9 +3858,10 @@ dh_verify(char *reqfn, PRBool response) continue; } /* CAVSHashZZ = ... */ - if (strncmp(buf, "CAVSHashZZ", 10) == 0) { + if ((strncmp(buf, "CAVSHashZZ", 10) == 0) || + (strncmp(buf, "HashZZ", 6) == 0)) { fputs(buf, dhresp); - i = 10; + i = buf[0] == 'C' ? 10 : 6; while (isspace(buf[i]) || buf[i] == '=') { i++; } @@ -3871,7 +3884,7 @@ dh_verify(char *reqfn, PRBool response) goto loser; } SECITEM_FreeItem(&ZZ, PR_FALSE); -#ifndef MATCH_NIST_ +#ifndef MATCH_NIST fputs("IUTHashZZ = ", dhresp); to_hex_str(buf, hashBuf, fips_hashLen(hash)); fputs(buf, dhresp); @@ -6656,12 +6669,13 @@ tls(char *reqfn) CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE, NULL, 0 }; CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE, NULL, 0 }; - CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; - CK_SSL3_KEY_MAT_PARAMS key_block_params; + CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params; + CK_TLS12_KEY_MAT_PARAMS key_block_params; CK_SSL3_KEY_MAT_OUT key_material; CK_RV crv; /* set up PKCS #11 parameters */ + master_params.prfHashMechanism = CKM_SHA256; master_params.pVersion = NULL; master_params.RandomInfo.pClientRandom = clientHello_random; master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random); @@ -6669,6 +6683,7 @@ tls(char *reqfn) master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random); master_mech.pParameter = (void *)&master_params; master_mech.ulParameterLen = sizeof(master_params); + key_block_params.prfHashMechanism = CKM_SHA256; key_block_params.ulMacSizeInBits = 0; key_block_params.ulKeySizeInBits = 0; key_block_params.ulIVSizeInBits = 0; @@ -6711,13 +6726,39 @@ tls(char *reqfn) if (buf[0] == '[') { if (strncmp(buf, "[TLS", 4) == 0) { if (buf[7] == '0') { + /* CK_SSL3_MASTER_KEY_DERIVE_PARAMS is a subset of + * CK_TLS12_MASTER_KEY_DERIVE_PARAMS and + * CK_SSL3_KEY_MAT_PARAMS is a subset of + * CK_TLS12_KEY_MAT_PARAMS. The latter params have + * an extra prfHashMechanism field at the end. */ master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE; key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE; + master_mech.ulParameterLen = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); + key_block_mech.ulParameterLen = sizeof(CK_SSL3_KEY_MAT_PARAMS); } else if (buf[7] == '2') { - master_mech.mechanism = - CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256; - key_block_mech.mechanism = - CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; + if (strncmp(&buf[10], "SHA-1", 5) == 0) { + master_params.prfHashMechanism = CKM_SHA_1; + key_block_params.prfHashMechanism = CKM_SHA_1; + } else if (strncmp(&buf[10], "SHA-224", 7) == 0) { + master_params.prfHashMechanism = CKM_SHA224; + key_block_params.prfHashMechanism = CKM_SHA224; + } else if (strncmp(&buf[10], "SHA-256", 7) == 0) { + master_params.prfHashMechanism = CKM_SHA256; + key_block_params.prfHashMechanism = CKM_SHA256; + } else if (strncmp(&buf[10], "SHA-384", 7) == 0) { + master_params.prfHashMechanism = CKM_SHA384; + key_block_params.prfHashMechanism = CKM_SHA384; + } else if (strncmp(&buf[10], "SHA-512", 7) == 0) { + master_params.prfHashMechanism = CKM_SHA512; + key_block_params.prfHashMechanism = CKM_SHA512; + } else { + fprintf(tlsresp, "ERROR: Unable to find prf Hash type"); + goto loser; + } + master_mech.mechanism = CKM_TLS12_MASTER_KEY_DERIVE; + key_block_mech.mechanism = CKM_TLS12_KEY_AND_MAC_DERIVE; + master_mech.ulParameterLen = sizeof(master_params); + key_block_mech.ulParameterLen = sizeof(key_block_params); } else { fprintf(stderr, "Unknown TLS type %x\n", (unsigned int)buf[0]); @@ -6900,6 +6941,1296 @@ loser: fclose(tlsreq); } +void +ikev1(char *reqfn) +{ + char buf[4096]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "g^xy = <2048 hex digits>\n". + */ + unsigned char *gxy = NULL; + int gxy_len; + unsigned char *Ni = NULL; + int Ni_len; + unsigned char *Nr = NULL; + int Nr_len; + unsigned char CKYi[8]; + int CKYi_len; + unsigned char CKYr[8]; + int CKYr_len; + unsigned int i, j; + FILE *ikereq = NULL; /* input stream from the REQUEST file */ + FILE *ikeresp; /* output stream to the RESPONSE file */ + + CK_SLOT_ID slotList[10]; + CK_SLOT_ID slotID; + CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); + CK_ULONG count; + static const CK_C_INITIALIZE_ARGS pk11args = { + NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, + (void *)"flags=readOnly,noCertDB,noModDB", NULL + }; + static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; + static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; + static CK_BBOOL ck_true = CK_TRUE; + static CK_ULONG keyLen = 1; + CK_ATTRIBUTE gxy_template[] = { + { CKA_VALUE, NULL, 0 }, /* must be first */ + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + CK_ULONG gxy_template_count = + sizeof(gxy_template) / sizeof(gxy_template[0]); + CK_ATTRIBUTE derive_template[] = { + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */ + }; + CK_ULONG derive_template_count = + sizeof(derive_template) / sizeof(derive_template[0]); + CK_ATTRIBUTE skeyid_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_d_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_a_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_e_template = + { CKA_VALUE, NULL, 0 }; + unsigned char skeyid_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_d_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_a_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_e_secret[HASH_LENGTH_MAX]; + + CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; + CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 }; + CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; + CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf; + CK_RV crv; + + /* set up PKCS #11 parameters */ + ike_prf.bDataAsKey = PR_TRUE; + ike_prf.bRekey = PR_FALSE; + ike_prf.hNewKey = CK_INVALID_HANDLE; + CKYi_len = sizeof(CKYi); + CKYr_len = sizeof(CKYr); + ike1_prf.pCKYi = CKYi; + ike1_prf.ulCKYiLen = CKYi_len; + ike1_prf.pCKYr = CKYr; + ike1_prf.ulCKYrLen = CKYr_len; + ike_mech.pParameter = &ike_prf; + ike_mech.ulParameterLen = sizeof(ike_prf); + ike1_mech.pParameter = &ike1_prf; + ike1_mech.ulParameterLen = sizeof(ike1_prf); + skeyid_template.pValue = skeyid_secret; + skeyid_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_d_template.pValue = skeyid_d_secret; + skeyid_d_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_a_template.pValue = skeyid_a_secret; + skeyid_a_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_e_template.pValue = skeyid_e_secret; + skeyid_e_template.ulValueLen = HASH_LENGTH_MAX; + + crv = NSC_Initialize((CK_VOID_PTR)&pk11args); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + count = slotListCount; + crv = NSC_GetSlotList(PR_TRUE, slotList, &count); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + if ((count > slotListCount) || count < 1) { + fprintf(stderr, + "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", + (int)count, (int)slotListCount); + goto loser; + } + slotID = slotList[0]; + ikereq = fopen(reqfn, "r"); + ikeresp = stdout; + while (fgets(buf, sizeof buf, ikereq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ikeresp); + continue; + } + /* [.....] */ + if (buf[0] == '[') { + if (strncmp(buf, "[SHA-1]", 7) == 0) { + ike_prf.prfMechanism = CKM_SHA_1_HMAC; + ike1_prf.prfMechanism = CKM_SHA_1_HMAC; + } + if (strncmp(buf, "[SHA-224]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA224_HMAC; + ike1_prf.prfMechanism = CKM_SHA224_HMAC; + } + if (strncmp(buf, "[SHA-256]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA256_HMAC; + ike1_prf.prfMechanism = CKM_SHA256_HMAC; + } + if (strncmp(buf, "[SHA-384]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA384_HMAC; + ike1_prf.prfMechanism = CKM_SHA384_HMAC; + } + if (strncmp(buf, "[SHA-512]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA512_HMAC; + ike1_prf.prfMechanism = CKM_SHA512_HMAC; + } + if (strncmp(buf, "[AES-XCBC", 9) == 0) { + ike_prf.prfMechanism = CKM_AES_XCBC_MAC; + ike1_prf.prfMechanism = CKM_AES_XCBC_MAC; + } + if (strncmp(buf, "[g^xy", 5) == 0) { + if (sscanf(buf, "[g^xy length = %d]", + &gxy_len) != 1) { + goto loser; + } + gxy_len = gxy_len / 8; + if (gxy) + free(gxy); + gxy = malloc(gxy_len); + gxy_template[0].pValue = gxy; + gxy_template[0].ulValueLen = gxy_len; + } + if (strncmp(buf, "[Ni", 3) == 0) { + if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { + goto loser; + } + Ni_len = Ni_len / 8; + if (Ni) + free(Ni); + Ni = malloc(Ni_len); + ike_prf.pNi = Ni; + ike_prf.ulNiLen = Ni_len; + } + if (strncmp(buf, "[Nr", 3) == 0) { + if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { + goto loser; + } + Nr_len = Nr_len / 8; + if (Nr) + free(Nr); + Nr = malloc(Nr_len); + ike_prf.pNr = Nr; + ike_prf.ulNrLen = Nr_len; + } + fputs(buf, ikeresp); + continue; + } + /* "COUNT = x" begins a new data set */ + if (strncmp(buf, "COUNT", 5) == 0) { + /* zeroize the variables for the test with this data set */ + memset(gxy, 0, gxy_len); + memset(Ni, 0, Ni_len); + memset(Nr, 0, Nr_len); + memset(CKYi, 0, CKYi_len); + memset(CKYr, 0, CKYr_len); + fputs(buf, ikeresp); + continue; + } + /* Ni = ... */ + if (strncmp(buf, "Ni", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Ni_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Ni[j]); + } + fputs(buf, ikeresp); + continue; + } + /* Nr = ... */ + if (strncmp(buf, "Nr", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Nr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Nr[j]); + } + fputs(buf, ikeresp); + continue; + } + /* CKYi = ... */ + if (strncmp(buf, "CKY_I", 5) == 0) { + i = 5; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < CKYi_len; i += 2, j++) { + hex_to_byteval(&buf[i], &CKYi[j]); + } + fputs(buf, ikeresp); + continue; + } + /* CKYr = ... */ + if (strncmp(buf, "CKY_R", 5) == 0) { + i = 5; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < CKYr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &CKYr[j]); + } + fputs(buf, ikeresp); + continue; + } + /* g^xy = ... */ + if (strncmp(buf, "g^xy", 4) == 0) { + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE gxy_handle; + CK_OBJECT_HANDLE skeyid_handle; + CK_OBJECT_HANDLE skeyid_d_handle; + CK_OBJECT_HANDLE skeyid_a_handle; + CK_OBJECT_HANDLE skeyid_e_handle; + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < gxy_len; i += 2, j++) { + hex_to_byteval(&buf[i], &gxy[j]); + } + fputs(buf, ikeresp); + crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_CreateObject(session, gxy_template, + gxy_template_count, &gxy_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + /* get the skeyid key */ + crv = NSC_DeriveKey(session, &ike_mech, gxy_handle, + derive_template, derive_template_count - 1, + &skeyid_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + skeyid_template.ulValueLen = HASH_LENGTH_MAX; + crv = NSC_GetAttributeValue(session, skeyid_handle, + &skeyid_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + /* use the length of the skeyid to set the target length of all the + * other keys */ + keyLen = skeyid_template.ulValueLen; + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = PR_FALSE; + ike1_prf.keyNumber = 0; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_d_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = CK_TRUE; + ike1_prf.hPrevKey = skeyid_d_handle; + ike1_prf.keyNumber = 1; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_a_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = CK_TRUE; + ike1_prf.hPrevKey = skeyid_a_handle; + ike1_prf.keyNumber = 2; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_e_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID = ", ikeresp); + to_hex_str(buf, skeyid_secret, keyLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_d_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_d_handle, + &skeyid_d_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_d = ", ikeresp); + to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_a_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_a_handle, + &skeyid_a_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_a = ", ikeresp); + to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_e_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_e_handle, + &skeyid_e_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_e = ", ikeresp); + to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + crv = NSC_CloseSession(session); + continue; + } + } +loser: + NSC_Finalize(NULL); + if (gxy) + free(gxy); + if (Ni) + free(Ni); + if (Nr) + free(Nr); + if (ikereq) + fclose(ikereq); +} + +void +ikev1_psk(char *reqfn) +{ + char buf[4096]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "g^xy = <2048 hex digits>\n". + */ + unsigned char *gxy = NULL; + int gxy_len; + unsigned char *Ni = NULL; + int Ni_len; + unsigned char *Nr = NULL; + int Nr_len; + unsigned char CKYi[8]; + int CKYi_len; + unsigned char CKYr[8]; + int CKYr_len; + unsigned char *psk = NULL; + int psk_len; + unsigned int i, j; + FILE *ikereq = NULL; /* input stream from the REQUEST file */ + FILE *ikeresp; /* output stream to the RESPONSE file */ + + CK_SLOT_ID slotList[10]; + CK_SLOT_ID slotID; + CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); + CK_ULONG count; + static const CK_C_INITIALIZE_ARGS pk11args = { + NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, + (void *)"flags=readOnly,noCertDB,noModDB", NULL + }; + static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; + static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; + static CK_BBOOL ck_true = CK_TRUE; + static CK_ULONG keyLen = 1; + CK_ATTRIBUTE gxy_template[] = { + { CKA_VALUE, NULL, 0 }, /* must be first */ + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + CK_ULONG gxy_template_count = + sizeof(gxy_template) / sizeof(gxy_template[0]); + CK_ATTRIBUTE psk_template[] = { + { CKA_VALUE, NULL, 0 }, /* must be first */ + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + CK_ULONG psk_template_count = + sizeof(psk_template) / sizeof(psk_template[0]); + CK_ATTRIBUTE derive_template[] = { + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */ + }; + CK_ULONG derive_template_count = + sizeof(derive_template) / sizeof(derive_template[0]); + CK_ATTRIBUTE skeyid_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_d_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_a_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE skeyid_e_template = + { CKA_VALUE, NULL, 0 }; + unsigned char skeyid_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_d_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_a_secret[HASH_LENGTH_MAX]; + unsigned char skeyid_e_secret[HASH_LENGTH_MAX]; + + CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; + CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 }; + CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; + CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf; + CK_RV crv; + + /* set up PKCS #11 parameters */ + ike_prf.bDataAsKey = PR_FALSE; + ike_prf.bRekey = PR_FALSE; + ike_prf.hNewKey = CK_INVALID_HANDLE; + CKYi_len = 8; + CKYr_len = 8; + ike1_prf.pCKYi = CKYi; + ike1_prf.ulCKYiLen = CKYi_len; + ike1_prf.pCKYr = CKYr; + ike1_prf.ulCKYrLen = CKYr_len; + ike_mech.pParameter = &ike_prf; + ike_mech.ulParameterLen = sizeof(ike_prf); + ike1_mech.pParameter = &ike1_prf; + ike1_mech.ulParameterLen = sizeof(ike1_prf); + skeyid_template.pValue = skeyid_secret; + skeyid_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_d_template.pValue = skeyid_d_secret; + skeyid_d_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_a_template.pValue = skeyid_a_secret; + skeyid_a_template.ulValueLen = HASH_LENGTH_MAX; + skeyid_e_template.pValue = skeyid_e_secret; + skeyid_e_template.ulValueLen = HASH_LENGTH_MAX; + + crv = NSC_Initialize((CK_VOID_PTR)&pk11args); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + count = slotListCount; + crv = NSC_GetSlotList(PR_TRUE, slotList, &count); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + if ((count > slotListCount) || count < 1) { + fprintf(stderr, + "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", + (int)count, (int)slotListCount); + goto loser; + } + slotID = slotList[0]; + ikereq = fopen(reqfn, "r"); + ikeresp = stdout; + while (fgets(buf, sizeof buf, ikereq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ikeresp); + continue; + } + /* [.....] */ + if (buf[0] == '[') { + if (strncmp(buf, "[SHA-1]", 7) == 0) { + ike_prf.prfMechanism = CKM_SHA_1_HMAC; + ike1_prf.prfMechanism = CKM_SHA_1_HMAC; + } + if (strncmp(buf, "[SHA-224]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA224_HMAC; + ike1_prf.prfMechanism = CKM_SHA224_HMAC; + } + if (strncmp(buf, "[SHA-256]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA256_HMAC; + ike1_prf.prfMechanism = CKM_SHA256_HMAC; + } + if (strncmp(buf, "[SHA-384]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA384_HMAC; + ike1_prf.prfMechanism = CKM_SHA384_HMAC; + } + if (strncmp(buf, "[SHA-512]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA512_HMAC; + ike1_prf.prfMechanism = CKM_SHA512_HMAC; + } + if (strncmp(buf, "[AES-XCBC", 9) == 0) { + ike_prf.prfMechanism = CKM_AES_XCBC_MAC; + ike1_prf.prfMechanism = CKM_AES_XCBC_MAC; + } + if (strncmp(buf, "[g^xy", 5) == 0) { + if (sscanf(buf, "[g^xy length = %d]", + &gxy_len) != 1) { + goto loser; + } + gxy_len = gxy_len / 8; + if (gxy) + free(gxy); + gxy = malloc(gxy_len); + gxy_template[0].pValue = gxy; + gxy_template[0].ulValueLen = gxy_len; + } + if (strncmp(buf, "[pre-shared-key", 15) == 0) { + if (sscanf(buf, "[pre-shared-key length = %d]", + &psk_len) != 1) { + goto loser; + } + psk_len = psk_len / 8; + if (psk) + free(psk); + psk = malloc(psk_len); + psk_template[0].pValue = psk; + psk_template[0].ulValueLen = psk_len; + } + if (strncmp(buf, "[Ni", 3) == 0) { + if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { + goto loser; + } + Ni_len = Ni_len / 8; + if (Ni) + free(Ni); + Ni = malloc(Ni_len); + ike_prf.pNi = Ni; + ike_prf.ulNiLen = Ni_len; + } + if (strncmp(buf, "[Nr", 3) == 0) { + if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { + goto loser; + } + Nr_len = Nr_len / 8; + if (Nr) + free(Nr); + Nr = malloc(Nr_len); + ike_prf.pNr = Nr; + ike_prf.ulNrLen = Nr_len; + } + fputs(buf, ikeresp); + continue; + } + /* "COUNT = x" begins a new data set */ + if (strncmp(buf, "COUNT", 5) == 0) { + /* zeroize the variables for the test with this data set */ + memset(gxy, 0, gxy_len); + memset(Ni, 0, Ni_len); + memset(Nr, 0, Nr_len); + memset(CKYi, 0, CKYi_len); + memset(CKYr, 0, CKYr_len); + fputs(buf, ikeresp); + continue; + } + /* Ni = ... */ + if (strncmp(buf, "Ni", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Ni_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Ni[j]); + } + fputs(buf, ikeresp); + continue; + } + /* Nr = ... */ + if (strncmp(buf, "Nr", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Nr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Nr[j]); + } + fputs(buf, ikeresp); + continue; + } + /* CKYi = ... */ + if (strncmp(buf, "CKY_I", 5) == 0) { + i = 5; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < CKYi_len; i += 2, j++) { + hex_to_byteval(&buf[i], &CKYi[j]); + } + fputs(buf, ikeresp); + continue; + } + /* CKYr = ... */ + if (strncmp(buf, "CKY_R", 5) == 0) { + i = 5; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < CKYr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &CKYr[j]); + } + fputs(buf, ikeresp); + continue; + } + /* g^xy = ... */ + if (strncmp(buf, "g^xy", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < gxy_len; i += 2, j++) { + hex_to_byteval(&buf[i], &gxy[j]); + } + fputs(buf, ikeresp); + continue; + } + /* pre-shared-key = ... */ + if (strncmp(buf, "pre-shared-key", 14) == 0) { + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE gxy_handle; + CK_OBJECT_HANDLE psk_handle; + CK_OBJECT_HANDLE skeyid_handle; + CK_OBJECT_HANDLE skeyid_d_handle; + CK_OBJECT_HANDLE skeyid_a_handle; + CK_OBJECT_HANDLE skeyid_e_handle; + i = 14; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < psk_len; i += 2, j++) { + hex_to_byteval(&buf[i], &psk[j]); + } + fputs(buf, ikeresp); + crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_CreateObject(session, psk_template, + psk_template_count, &psk_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject(psk) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_CreateObject(session, gxy_template, + gxy_template_count, &gxy_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject(gxy) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + /* get the skeyid key */ + crv = NSC_DeriveKey(session, &ike_mech, psk_handle, + derive_template, derive_template_count - 1, + &skeyid_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + skeyid_template.ulValueLen = HASH_LENGTH_MAX; + crv = NSC_GetAttributeValue(session, skeyid_handle, + &skeyid_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + /* use the length of the skeyid to set the target length of all the + * other keys */ + keyLen = skeyid_template.ulValueLen; + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = PR_FALSE; + ike1_prf.keyNumber = 0; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_d_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = CK_TRUE; + ike1_prf.hPrevKey = skeyid_d_handle; + ike1_prf.keyNumber = 1; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_a_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + ike1_prf.hKeygxy = gxy_handle; + ike1_prf.bHasPrevKey = CK_TRUE; + ike1_prf.hPrevKey = skeyid_a_handle; + ike1_prf.keyNumber = 2; + crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, + derive_template, derive_template_count, + &skeyid_e_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID = ", ikeresp); + to_hex_str(buf, skeyid_secret, keyLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_d_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_d_handle, + &skeyid_d_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_d = ", ikeresp); + to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_a_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_a_handle, + &skeyid_a_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_a = ", ikeresp); + to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + skeyid_e_template.ulValueLen = keyLen; + crv = NSC_GetAttributeValue(session, skeyid_e_handle, + &skeyid_e_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYID_e = ", ikeresp); + to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + crv = NSC_CloseSession(session); + continue; + } + } +loser: + NSC_Finalize(NULL); + if (psk) + free(psk); + if (gxy) + free(gxy); + if (Ni) + free(Ni); + if (Nr) + free(Nr); + if (ikereq) + fclose(ikereq); +} + +void +ikev2(char *reqfn) +{ + char buf[4096]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "g^xy = <2048 hex digits>\n". + */ + unsigned char *gir = NULL; + unsigned char *gir_new = NULL; + int gir_len; + unsigned char *Ni = NULL; + int Ni_len; + unsigned char *Nr = NULL; + int Nr_len; + unsigned char *SPIi = NULL; + int SPIi_len = 8; + unsigned char *SPIr = NULL; + int SPIr_len = 8; + unsigned char *DKM = NULL; + int DKM_len; + unsigned char *DKM_child = NULL; + int DKM_child_len; + unsigned char *seed_data = NULL; + int seed_data_len = 0; + unsigned int i, j; + FILE *ikereq = NULL; /* input stream from the REQUEST file */ + FILE *ikeresp; /* output stream to the RESPONSE file */ + + CK_SLOT_ID slotList[10]; + CK_SLOT_ID slotID; + CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); + CK_ULONG count; + static const CK_C_INITIALIZE_ARGS pk11args = { + NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, + (void *)"flags=readOnly,noCertDB,noModDB", NULL + }; + static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; + static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; + static CK_BBOOL ck_true = CK_TRUE; + static CK_ULONG keyLen = 1; + CK_ATTRIBUTE gir_template[] = { + { CKA_VALUE, NULL, 0 }, + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + CK_ULONG gir_template_count = + sizeof(gir_template) / sizeof(gir_template[0]); + CK_ATTRIBUTE gir_new_template[] = { + { CKA_VALUE, NULL, 0 }, + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + CK_ULONG gir_new_template_count = + sizeof(gir_new_template) / sizeof(gir_new_template[0]); + CK_ATTRIBUTE derive_template[] = { + { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, + }; + CK_ULONG derive_template_count = + sizeof(derive_template) / sizeof(derive_template[0]); + CK_ATTRIBUTE skeyseed_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE dkm_template = + { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE dkm_child_template = + { CKA_VALUE, NULL, 0 }; + unsigned char skeyseed_secret[HASH_LENGTH_MAX]; + + CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; + CK_MECHANISM ike2_mech = { CKM_NSS_IKE_PRF_PLUS_DERIVE, NULL, 0 }; + CK_MECHANISM subset_mech = { CKM_EXTRACT_KEY_FROM_KEY, NULL, 0 }; + CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; + CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ike2_prf; + CK_EXTRACT_PARAMS subset_params; + CK_RV crv; + + /* set up PKCS #11 parameters */ + ike_mech.pParameter = &ike_prf; + ike_mech.ulParameterLen = sizeof(ike_prf); + ike2_mech.pParameter = &ike2_prf; + ike2_mech.ulParameterLen = sizeof(ike2_prf); + subset_mech.pParameter = &subset_params; + subset_mech.ulParameterLen = sizeof(subset_params); + subset_params = 0; + skeyseed_template.pValue = skeyseed_secret; + skeyseed_template.ulValueLen = HASH_LENGTH_MAX; + + crv = NSC_Initialize((CK_VOID_PTR)&pk11args); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + count = slotListCount; + crv = NSC_GetSlotList(PR_TRUE, slotList, &count); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); + goto loser; + } + if ((count > slotListCount) || count < 1) { + fprintf(stderr, + "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", + (int)count, (int)slotListCount); + goto loser; + } + slotID = slotList[0]; + ikereq = fopen(reqfn, "r"); + ikeresp = stdout; + while (fgets(buf, sizeof buf, ikereq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ikeresp); + continue; + } + /* [.....] */ + if (buf[0] == '[') { + if (strncmp(buf, "[SHA-1]", 7) == 0) { + ike_prf.prfMechanism = CKM_SHA_1_HMAC; + ike2_prf.prfMechanism = CKM_SHA_1_HMAC; + } + if (strncmp(buf, "[SHA-224]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA224_HMAC; + ike2_prf.prfMechanism = CKM_SHA224_HMAC; + } + if (strncmp(buf, "[SHA-256]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA256_HMAC; + ike2_prf.prfMechanism = CKM_SHA256_HMAC; + } + if (strncmp(buf, "[SHA-384]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA384_HMAC; + ike2_prf.prfMechanism = CKM_SHA384_HMAC; + } + if (strncmp(buf, "[SHA-512]", 9) == 0) { + ike_prf.prfMechanism = CKM_SHA512_HMAC; + ike2_prf.prfMechanism = CKM_SHA512_HMAC; + } + if (strncmp(buf, "[AES-XCBC", 9) == 0) { + ike_prf.prfMechanism = CKM_AES_XCBC_MAC; + ike2_prf.prfMechanism = CKM_AES_XCBC_MAC; + } + if (strncmp(buf, "[g^ir", 5) == 0) { + if (sscanf(buf, "[g^ir length = %d]", + &gir_len) != 1) { + goto loser; + } + gir_len = gir_len / 8; + if (gir) + free(gir); + if (gir_new) + free(gir_new); + gir = malloc(gir_len); + gir_new = malloc(gir_len); + gir_template[0].pValue = gir; + gir_template[0].ulValueLen = gir_len; + gir_new_template[0].pValue = gir_new; + gir_new_template[0].ulValueLen = gir_len; + } + if (strncmp(buf, "[Ni", 3) == 0) { + if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { + goto loser; + } + Ni_len = Ni_len / 8; + } + if (strncmp(buf, "[Nr", 3) == 0) { + if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { + goto loser; + } + Nr_len = Nr_len / 8; + } + if (strncmp(buf, "[DKM", 4) == 0) { + if (sscanf(buf, "[DKM length = %d]", + &DKM_len) != 1) { + goto loser; + } + DKM_len = DKM_len / 8; + if (DKM) + free(DKM); + DKM = malloc(DKM_len); + dkm_template.pValue = DKM; + dkm_template.ulValueLen = DKM_len; + } + if (strncmp(buf, "[Child SA DKM", 13) == 0) { + if (sscanf(buf, "[Child SA DKM length = %d]", + &DKM_child_len) != 1) { + goto loser; + } + DKM_child_len = DKM_child_len / 8; + if (DKM_child) + free(DKM_child); + DKM_child = malloc(DKM_child_len); + dkm_child_template.pValue = DKM_child; + dkm_child_template.ulValueLen = DKM_child_len; + } + fputs(buf, ikeresp); + continue; + } + /* "COUNT = x" begins a new data set */ + if (strncmp(buf, "COUNT", 5) == 0) { + /* zeroize the variables for the test with this data set */ + int new_seed_len = Ni_len + Nr_len + SPIi_len + SPIr_len; + if (seed_data_len != new_seed_len) { + if (seed_data) + free(seed_data); + seed_data_len = new_seed_len; + seed_data = malloc(seed_data_len); + Ni = seed_data; + Nr = &seed_data[Ni_len]; + SPIi = &seed_data[Ni_len + Nr_len]; + SPIr = &seed_data[new_seed_len - SPIr_len]; + ike_prf.pNi = Ni; + ike_prf.ulNiLen = Ni_len; + ike_prf.pNr = Nr; + ike_prf.ulNrLen = Nr_len; + ike2_prf.pSeedData = seed_data; + } + memset(gir, 0, gir_len); + memset(gir_new, 0, gir_len); + memset(seed_data, 0, seed_data_len); + fputs(buf, ikeresp); + continue; + } + /* Ni = ... */ + if (strncmp(buf, "Ni", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Ni_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Ni[j]); + } + fputs(buf, ikeresp); + continue; + } + /* Nr = ... */ + if (strncmp(buf, "Nr", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < Nr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &Nr[j]); + } + fputs(buf, ikeresp); + continue; + } + /* g^ir (new) = ... */ + if (strncmp(buf, "g^ir (new)", 10) == 0) { + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < gir_len; i += 2, j++) { + hex_to_byteval(&buf[i], &gir_new[j]); + } + fputs(buf, ikeresp); + continue; + } + /* g^ir = ... */ + if (strncmp(buf, "g^ir", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < gir_len; i += 2, j++) { + hex_to_byteval(&buf[i], &gir[j]); + } + fputs(buf, ikeresp); + continue; + } + /* SPIi = ... */ + if (strncmp(buf, "SPIi", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < SPIi_len; i += 2, j++) { + hex_to_byteval(&buf[i], &SPIi[j]); + } + fputs(buf, ikeresp); + continue; + } + /* SPIr = ... */ + if (strncmp(buf, "SPIr", 4) == 0) { + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE gir_handle; + CK_OBJECT_HANDLE gir_new_handle; + CK_OBJECT_HANDLE skeyseed_handle; + CK_OBJECT_HANDLE sk_d_handle; + CK_OBJECT_HANDLE skeyseed_new_handle; + CK_OBJECT_HANDLE dkm_handle; + CK_OBJECT_HANDLE dkm_child_handle; + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j = 0; j < SPIr_len; i += 2, j++) { + hex_to_byteval(&buf[i], &SPIr[j]); + } + fputs(buf, ikeresp); + crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_CreateObject(session, gir_template, + gir_template_count, &gir_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject (g^ir) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_CreateObject(session, gir_new_template, + gir_new_template_count, &gir_new_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject (g^ir new) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + /* get the SKEYSEED key */ + ike_prf.bDataAsKey = CK_TRUE; + ike_prf.bRekey = CK_FALSE; + ike_prf.hNewKey = CK_INVALID_HANDLE; + crv = NSC_DeriveKey(session, &ike_mech, gir_handle, + derive_template, derive_template_count - 1, + &skeyseed_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + skeyseed_template.ulValueLen = HASH_LENGTH_MAX; + crv = NSC_GetAttributeValue(session, skeyseed_handle, + &skeyseed_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYSEED = ", ikeresp); + to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + /* get DKM */ + keyLen = DKM_len; + ike2_prf.bHasSeedKey = CK_FALSE; + ike2_prf.hSeedKey = CK_INVALID_HANDLE; + ike2_prf.ulSeedDataLen = seed_data_len; + crv = NSC_DeriveKey(session, &ike2_mech, skeyseed_handle, + derive_template, derive_template_count, + &dkm_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(DKM) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_GetAttributeValue(session, dkm_handle, + &dkm_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(DKM) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("DKM = ", ikeresp); + to_hex_str(buf, DKM, DKM_len); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + /* get the sk_d from the DKM */ + keyLen = skeyseed_template.ulValueLen; + crv = NSC_DeriveKey(session, &subset_mech, dkm_handle, + derive_template, derive_template_count, + &sk_d_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(sk_d) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + + /* get DKM child */ + keyLen = DKM_child_len; + ike2_prf.bHasSeedKey = CK_FALSE; + ike2_prf.hSeedKey = CK_INVALID_HANDLE; + ike2_prf.ulSeedDataLen = Ni_len + Nr_len; + crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle, + derive_template, derive_template_count, + &dkm_child_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(DKM Child SA) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_GetAttributeValue(session, dkm_child_handle, + &dkm_child_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(DKM Child SA) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("DKM(Child SA) = ", ikeresp); + to_hex_str(buf, DKM_child, DKM_child_len); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + /* get DKM child D-H*/ + keyLen = DKM_child_len; + ike2_prf.bHasSeedKey = CK_TRUE; + ike2_prf.hSeedKey = gir_new_handle; + ike2_prf.ulSeedDataLen = Ni_len + Nr_len; + crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle, + derive_template, derive_template_count, + &dkm_child_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(DKM Child SA D-H) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + crv = NSC_GetAttributeValue(session, dkm_child_handle, + &dkm_child_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(DKM Child SA D-H) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("DKM(Child SA D-H) = ", ikeresp); + to_hex_str(buf, DKM_child, DKM_child_len); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + /* get SKEYSEED(rekey) */ + ike_prf.bDataAsKey = CK_FALSE; + ike_prf.bRekey = CK_TRUE; + ike_prf.hNewKey = gir_new_handle; + crv = NSC_DeriveKey(session, &ike_mech, sk_d_handle, + derive_template, derive_template_count - 1, + &skeyseed_new_handle); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(skeyid rekey) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + skeyseed_template.ulValueLen = HASH_LENGTH_MAX; + crv = NSC_GetAttributeValue(session, skeyseed_new_handle, + &skeyseed_template, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", + (unsigned int)crv); + goto loser; + } + fputs("SKEYSEED(rekey) = ", ikeresp); + to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen); + fputs(buf, ikeresp); + fputc('\n', ikeresp); + + crv = NSC_CloseSession(session); + continue; + } + } +loser: + NSC_Finalize(NULL); + if (gir) + free(gir); + if (gir_new) + free(gir_new); + if (seed_data) + free(seed_data); + if (DKM) + free(DKM); + if (DKM_child) + free(DKM_child); + if (ikereq) + fclose(ikereq); +} + int main(int argc, char **argv) { @@ -7071,6 +8402,14 @@ main(int argc, char **argv) } else if (strcmp(argv[1], "ddrbg") == 0) { debug = 1; drbg(argv[2]); + } else if (strcmp(argv[1], "tls") == 0) { + tls(argv[2]); + } else if (strcmp(argv[1], "ikev1") == 0) { + ikev1(argv[2]); + } else if (strcmp(argv[1], "ikev1-psk") == 0) { + ikev1_psk(argv[2]); + } else if (strcmp(argv[1], "ikev2") == 0) { + ikev2(argv[2]); } return 0; } diff --git a/security/nss/cmd/fipstest/hmac.sh b/security/nss/cmd/fipstest/hmac.sh deleted file mode 100755 index d29dbc27f..000000000 --- a/security/nss/cmd/fipstest/hmac.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/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 HMAC Algorithm 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}/HMAC -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -hmac_requests=" -HMAC.req -" - -if [ ${COMMAND} = "verify" ]; then - for request in $hmac_requests; do - sh ./validate1.sh ${TESTDIR} $request - done - exit 0 -fi -for request in $hmac_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response -done - diff --git a/security/nss/cmd/fipstest/kas.sh b/security/nss/cmd/fipstest/kas.sh deleted file mode 100644 index 9aa5387a8..000000000 --- a/security/nss/cmd/fipstest/kas.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/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/security/nss/cmd/fipstest/rng.sh b/security/nss/cmd/fipstest/rng.sh deleted file mode 100644 index 1a313b422..000000000 --- a/security/nss/cmd/fipstest/rng.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/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}/DRBG800-90A -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -drbg_requests=" -Hash_DRBG.req -" - -if [ ${COMMAND} = "verify" ]; then - for request in $drbg_requests; do - sh ./validate1.sh ${TESTDIR} $request - done - exit 0 -fi -for request in $drbg_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response -done diff --git a/security/nss/cmd/fipstest/rsa.sh b/security/nss/cmd/fipstest/rsa.sh deleted file mode 100644 index b86a73969..000000000 --- a/security/nss/cmd/fipstest/rsa.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/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 RSA 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}/RSA2 -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -if [ ${COMMAND} = "verify" ]; then -#verify the signatures. The fax file does not have any known answers, so -#use our own verify function. - name=SigGen15_186-3 - echo ">>>>> $name" - fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F -# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F -#The Fax file has the private exponent and the salt value, remove it -#also remove the false reason - sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;' -# -# currently don't have a way to verify the RSA keygen -# - exit 0 -fi - -request=SigGen15_186-3.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response - -request=SigVer15_186-3.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response - -#request=KeyGen_186-3.req -request=KeyGen_RandomProbablyPrime3_3.req -response=`echo $request | sed -e "s/req/rsp/"` -echo $request $response -fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response diff --git a/security/nss/cmd/fipstest/runtest.sh b/security/nss/cmd/fipstest/runtest.sh deleted file mode 100644 index fcb16348b..000000000 --- a/security/nss/cmd/fipstest/runtest.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/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 kas tls rng rsa sha tdea" -for i in $TESTS -do - echo "********************Running $i tests" - sh ./${i}.sh ${TESTDIR} ${COMMAND} -done diff --git a/security/nss/cmd/fipstest/sha.sh b/security/nss/cmd/fipstest/sha.sh deleted file mode 100644 index ccc52d297..000000000 --- a/security/nss/cmd/fipstest/sha.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/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 SHA Algorithm 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}/SHA -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -sha_ShortMsg_requests=" -SHA1ShortMsg.req -SHA224ShortMsg.req -SHA256ShortMsg.req -SHA384ShortMsg.req -SHA512ShortMsg.req -" - -sha_LongMsg_requests=" -SHA1LongMsg.req -SHA224LongMsg.req -SHA256LongMsg.req -SHA384LongMsg.req -SHA512LongMsg.req -" - -sha_Monte_requests=" -SHA1Monte.req -SHA224Monte.req -SHA256Monte.req -SHA384Monte.req -SHA512Monte.req -" - -if [ ${COMMAND} = "verify" ]; then - for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do - sh ./validate1.sh ${TESTDIR} $request - done - exit 0 -fi - -for request in $sha_ShortMsg_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $sha_LongMsg_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $sha_Monte_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response -done - diff --git a/security/nss/cmd/fipstest/tdea.sh b/security/nss/cmd/fipstest/tdea.sh deleted file mode 100644 index cbddad7d7..000000000 --- a/security/nss/cmd/fipstest/tdea.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/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 tdea Algorithm 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}/TDES -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -#CBC_Known_Answer_tests -#Initial Permutation KAT -#Permutation Operation KAT -#Subsitution Table KAT -#Variable Key KAT -#Variable PlainText KAT -cbc_kat_requests=" -TCBCinvperm.req -TCBCpermop.req -TCBCsubtab.req -TCBCvarkey.req -TCBCvartext.req -" - -#CBC Monte Carlo KATs -cbc_monte_requests=" -TCBCMonte1.req -TCBCMonte2.req -TCBCMonte3.req -" -#Multi-block Message KATs -cbc_mmt_requests=" -TCBCMMT1.req -TCBCMMT2.req -TCBCMMT3.req -" - -ecb_kat_requests=" -TECBinvperm.req -TECBpermop.req -TECBsubtab.req -TECBvarkey.req -TECBvartext.req -" - -ecb_monte_requests=" -TECBMonte1.req -TECBMonte2.req -TECBMonte3.req -" - -ecb_mmt_requests=" -TECBMMT1.req -TECBMMT2.req -TECBMMT3.req -" - - -if [ ${COMMAND} = "verify" ]; then - for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests - do - sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d" - done - exit 0 -fi - -for request in $cbc_kat_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $cbc_mmt_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $cbc_monte_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_kat_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_mmt_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response -done -for request in $ecb_monte_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response -done diff --git a/security/nss/cmd/fipstest/tls.sh b/security/nss/cmd/fipstest/tls.sh deleted file mode 100644 index 1c2824539..000000000 --- a/security/nss/cmd/fipstest/tls.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/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}/KDF135 -COMMAND=${2-run} -REQDIR=${TESTDIR}/req -RSPDIR=${TESTDIR}/resp - -drbg_requests=" -tls.req -" - -if [ ${COMMAND} = "verify" ]; then - for request in $drbg_requests; do - sh ./validate1.sh ${TESTDIR} $request - done - exit 0 -fi -for request in $drbg_requests; do - response=`echo $request | sed -e "s/req/rsp/"` - echo $request $response - fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response -done diff --git a/security/nss/cmd/fipstest/validate.sh b/security/nss/cmd/fipstest/validate.sh deleted file mode 100644 index d446dd587..000000000 --- a/security/nss/cmd/fipstest/validate.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/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/. -# -sh ./runtest.sh ${1-.} verify diff --git a/security/nss/cmd/fipstest/validate1.sh b/security/nss/cmd/fipstest/validate1.sh deleted file mode 100644 index 1440af8fc..000000000 --- a/security/nss/cmd/fipstest/validate1.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/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/. -# -# Validate1.sh is a helper shell script that each of the base test shell -# scripts call to help validate that the generated response (response) -# matches the known answer response (fax). Sometimes (depending on the -# individual tests) there are extraneous output in either or both response -# and fax files. These allow the caller to pass in additional sed commands -# to clear out those extraneous outputs before we compare the two files. -# The sed line always clears out Windows line endings, replaces tabs with -# spaces, and removed comments. -# -TESTDIR=${1-.} -request=${2} -extraneous_response=${3} -extraneous_fax=${4} -name=`basename $request .req` -echo ">>>>> $name" -sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1 -# if we didn't generate any output, flag that as an error -size=`sum /tmp/y1 | awk '{ print $NF }'` -if [ $size -eq 0 ]; then - echo "${TESTDIR}/resp/${name}.rsp: empty" - exit 1; -fi -sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2 -diff -i -w -B /tmp/y1 /tmp/y2 -- cgit v1.2.3