summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd/fipstest/fipstest.c
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
commitf4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch)
tree211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/cmd/fipstest/fipstest.c
parentf7d30133221896638f7bf4f66c504255c4b14f48 (diff)
downloadUXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.gz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.lz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.xz
UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.zip
Issue #1338 - Part 2: Update NSS to 3.48-RTM
Diffstat (limited to 'security/nss/cmd/fipstest/fipstest.c')
-rw-r--r--security/nss/cmd/fipstest/fipstest.c1381
1 files changed, 1360 insertions, 21 deletions
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;
}