Index: nss/lib/softoken/pkcs11c.c |
diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c |
index 955d4c95554b186a30809f9ee1a267e253618df2..992fba41c6129e771d582c61362b7e7aa9999d3e 100644 |
--- a/nss/lib/softoken/pkcs11c.c |
+++ b/nss/lib/softoken/pkcs11c.c |
@@ -73,6 +73,7 @@ static void sftk_Null(void *data, PRBool freeit) |
} \ |
printf("\n") |
#else |
+#undef EC_DEBUG |
#define SEC_PRINT(a, b, c, d) |
#endif |
#endif /* NSS_DISABLE_ECC */ |
@@ -2637,10 +2638,52 @@ finish_rsa: |
*(CK_ULONG *)pMechanism->pParameter); |
break; |
case CKM_TLS_PRF_GENERAL: |
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL); |
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); |
break; |
+ case CKM_TLS_MAC: { |
+ CK_TLS_MAC_PARAMS *tls12_mac_params; |
+ HASH_HashType tlsPrfHash; |
+ const char *label; |
+ |
+ if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter; |
+ if (tls12_mac_params->prfMechanism == CKM_TLS_PRF) { |
+ /* The TLS 1.0 and 1.1 PRF */ |
+ tlsPrfHash = HASH_AlgNULL; |
+ if (tls12_mac_params->ulMacLength != 12) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ } else { |
+ /* The hash function for the TLS 1.2 PRF */ |
+ tlsPrfHash = |
+ GetHashTypeFromMechanism(tls12_mac_params->prfMechanism); |
+ if (tlsPrfHash == HASH_AlgNULL || |
+ tls12_mac_params->ulMacLength < 12) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ } |
+ if (tls12_mac_params->ulServerOrClient == 1) { |
+ label = "server finished"; |
+ } else if (tls12_mac_params->ulServerOrClient == 2) { |
+ label = "client finished"; |
+ } else { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash, |
+ tls12_mac_params->ulMacLength); |
+ if (crv == CKR_OK) { |
+ context->hashUpdate(context->hashInfo, label, 15); |
+ } |
+ break; |
+ } |
case CKM_NSS_TLS_PRF_GENERAL_SHA256: |
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256); |
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); |
break; |
case CKM_NSS_HMAC_CONSTANT_TIME: { |
@@ -2654,6 +2697,7 @@ finish_rsa: |
} |
intpointer = PORT_New(CK_ULONG); |
if (intpointer == NULL) { |
+ PORT_Free(ctx); |
crv = CKR_HOST_MEMORY; |
break; |
} |
@@ -2683,6 +2727,7 @@ finish_rsa: |
} |
intpointer = PORT_New(CK_ULONG); |
if (intpointer == NULL) { |
+ PORT_Free(ctx); |
crv = CKR_HOST_MEMORY; |
break; |
} |
@@ -3234,10 +3279,10 @@ finish_rsa: |
*(CK_ULONG *)pMechanism->pParameter); |
break; |
case CKM_TLS_PRF_GENERAL: |
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL); |
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); |
break; |
case CKM_NSS_TLS_PRF_GENERAL_SHA256: |
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256); |
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); |
break; |
default: |
@@ -3777,6 +3822,7 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe) |
salt.data = (unsigned char *)pbe_params->pSalt; |
salt.len = (unsigned int)pbe_params->ulSaltLen; |
+ salt.type = siBuffer; |
rv = SECITEM_CopyItem(arena,¶ms->salt,&salt); |
if (rv != SECSuccess) { |
PORT_FreeArena(arena,PR_TRUE); |
@@ -3921,7 +3967,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, |
* produce them any more. The affected algorithm was 3DES. |
*/ |
PRBool faultyPBE3DES = PR_FALSE; |
- HASH_HashType hashType; |
+ HASH_HashType hashType = HASH_AlgNULL; |
CHECK_FORK(); |
@@ -4163,8 +4209,8 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, |
*/ |
CK_MECHANISM mech = {0, NULL, 0}; |
- CK_ULONG modulusLen; |
- CK_ULONG subPrimeLen; |
+ CK_ULONG modulusLen = 0; |
+ CK_ULONG subPrimeLen = 0; |
PRBool isEncryptable = PR_FALSE; |
PRBool canSignVerify = PR_FALSE; |
PRBool isDerivable = PR_FALSE; |
@@ -4462,7 +4508,6 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, |
DSAPrivateKey * dsaPriv; |
/* Diffie Hellman */ |
- int private_value_bits = 0; |
DHPrivateKey * dhPriv; |
#ifndef NSS_DISABLE_ECC |
@@ -4514,7 +4559,6 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, |
*/ |
for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) { |
if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) { |
- private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue; |
continue; |
} |
@@ -4984,7 +5028,9 @@ static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) |
SECStatus rv = SECSuccess; |
SECItem *encodedKey = NULL; |
#ifndef NSS_DISABLE_ECC |
+#ifdef EC_DEBUG |
SECItem *fordebug; |
+#endif |
int savelen; |
#endif |
@@ -5057,9 +5103,11 @@ static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) |
lk->u.ec.ecParams.curveOID.len = savelen; |
lk->u.ec.publicValue.len >>= 3; |
+#ifdef EC_DEBUG |
fordebug = &pki->privateKey; |
SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType, |
fordebug); |
+#endif |
param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding); |
@@ -5098,7 +5146,7 @@ static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) |
nsslowkey_PrivateKeyInfoTemplate); |
*crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR; |
-#ifndef NSS_DISABLE_ECC |
+#ifdef EC_DEBUG |
fordebug = encodedKey; |
SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType, |
fordebug); |
@@ -5947,9 +5995,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
CK_OBJECT_CLASS classType = CKO_SECRET_KEY; |
CK_KEY_DERIVATION_STRING_DATA *stringPtr; |
+ CK_MECHANISM_TYPE mechanism = pMechanism->mechanism; |
PRBool isTLS = PR_FALSE; |
- PRBool isSHA256 = PR_FALSE; |
PRBool isDH = PR_FALSE; |
+ HASH_HashType tlsPrfHash = HASH_AlgNULL; |
SECStatus rv; |
int i; |
unsigned int outLen; |
@@ -5996,7 +6045,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
keySize = sftk_MapKeySize(keyType); |
} |
- switch (pMechanism->mechanism) { |
+ switch (mechanism) { |
case CKM_NSS_JPAKE_ROUND2_SHA1: /* fall through */ |
case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */ |
case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */ |
@@ -6044,18 +6093,16 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
} |
} |
- switch (pMechanism->mechanism) { |
+ switch (mechanism) { |
/* |
* generate the master secret |
*/ |
+ case CKM_TLS12_MASTER_KEY_DERIVE: |
+ case CKM_TLS12_MASTER_KEY_DERIVE_DH: |
case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256: |
case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256: |
- isSHA256 = PR_TRUE; |
- /* fall thru */ |
case CKM_TLS_MASTER_KEY_DERIVE: |
case CKM_TLS_MASTER_KEY_DERIVE_DH: |
- isTLS = PR_TRUE; |
- /* fall thru */ |
case CKM_SSL3_MASTER_KEY_DERIVE: |
case CKM_SSL3_MASTER_KEY_DERIVE_DH: |
{ |
@@ -6063,12 +6110,32 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
SSL3RSAPreMasterSecret * rsa_pms; |
unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
- if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || |
- (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) || |
- (pMechanism->mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) |
- isDH = PR_TRUE; |
+ if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) || |
+ (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) { |
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master = |
+ (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter; |
+ tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism); |
+ if (tlsPrfHash == HASH_AlgNULL) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) || |
+ (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) { |
+ tlsPrfHash = HASH_AlgSHA256; |
+ } |
- /* first do the consistancy checks */ |
+ if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE) && |
+ (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH)) { |
+ isTLS = PR_TRUE; |
+ } |
+ if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || |
+ (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) || |
+ (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256) || |
+ (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) { |
+ isDH = PR_TRUE; |
+ } |
+ |
+ /* first do the consistency checks */ |
if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) { |
crv = CKR_KEY_TYPE_INCONSISTENT; |
break; |
@@ -6133,8 +6200,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
pms.data = (unsigned char*)att->attrib.pValue; |
pms.len = att->attrib.ulValueLen; |
- if (isSHA256) { |
- status = TLS_P_hash(HASH_AlgSHA256, &pms, "master secret", |
+ if (tlsPrfHash != HASH_AlgNULL) { |
+ status = TLS_P_hash(tlsPrfHash, &pms, "master secret", |
&crsr, &master, isFIPS); |
} else { |
status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); |
@@ -6197,12 +6264,108 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
break; |
} |
+ /* Extended master key derivation [draft-ietf-tls-session-hash] */ |
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE: |
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: |
+ { |
+ CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params; |
+ SSL3RSAPreMasterSecret *rsa_pms; |
+ SECStatus status; |
+ SECItem pms = { siBuffer, NULL, 0 }; |
+ SECItem seed = { siBuffer, NULL, 0 }; |
+ SECItem master = { siBuffer, NULL, 0 }; |
+ |
+ ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS*) |
+ pMechanism->pParameter; |
+ |
+ /* First do the consistency checks */ |
+ if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) && |
+ (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) { |
+ crv = CKR_KEY_TYPE_INCONSISTENT; |
+ break; |
+ } |
+ att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE); |
+ if ((att2 == NULL) || |
+ (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET)) { |
+ if (att2) sftk_FreeAttribute(att2); |
+ crv = CKR_KEY_FUNCTION_NOT_PERMITTED; |
+ break; |
+ } |
+ sftk_FreeAttribute(att2); |
+ if (keyType != CKK_GENERIC_SECRET) { |
+ crv = CKR_KEY_FUNCTION_NOT_PERMITTED; |
+ break; |
+ } |
+ if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) { |
+ crv = CKR_KEY_FUNCTION_NOT_PERMITTED; |
+ break; |
+ } |
+ |
+ /* Do the key derivation */ |
+ pms.data = (unsigned char*) att->attrib.pValue; |
+ pms.len = att->attrib.ulValueLen; |
+ seed.data = ems_params->pSessionHash; |
+ seed.len = ems_params->ulSessionHashLen; |
+ master.data = key_block; |
+ master.len = SSL3_MASTER_SECRET_LENGTH; |
+ if (ems_params-> prfHashMechanism == CKM_TLS_PRF) { |
+ /* |
+ * In this case, the session hash is the concatenation of SHA-1 |
+ * and MD5, so it should be 36 bytes long. |
+ */ |
+ if (seed.len != MD5_LENGTH + SHA1_LENGTH) { |
+ crv = CKR_TEMPLATE_INCONSISTENT; |
+ break; |
+ } |
+ |
+ status = TLS_PRF(&pms, "extended master secret", |
+ &seed, &master, isFIPS); |
+ } else { |
+ const SECHashObject *hashObj; |
+ |
+ tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism); |
+ if (tlsPrfHash == HASH_AlgNULL) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ |
+ hashObj = HASH_GetRawHashObject(tlsPrfHash); |
+ if (seed.len != hashObj->length) { |
+ crv = CKR_TEMPLATE_INCONSISTENT; |
+ break; |
+ } |
+ |
+ status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret", |
+ &seed, &master, isFIPS); |
+ } |
+ if (status != SECSuccess) { |
+ crv = CKR_FUNCTION_FAILED; |
+ break; |
+ } |
+ |
+ /* Reflect the version if required */ |
+ if (ems_params->pVersion) { |
+ SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); |
+ rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue; |
+ /* don't leak more key material than necessary for SSL to work */ |
+ if ((sessKey == NULL) || sessKey->wasDerived) { |
+ ems_params->pVersion->major = 0xff; |
+ ems_params->pVersion->minor = 0xff; |
+ } else { |
+ ems_params->pVersion->major = rsa_pms->client_version[0]; |
+ ems_params->pVersion->minor = rsa_pms->client_version[1]; |
+ } |
+ } |
+ |
+ /* Store the results */ |
+ crv = sftk_forceAttribute(key, CKA_VALUE, key_block, |
+ SSL3_MASTER_SECRET_LENGTH); |
+ break; |
+ } |
+ |
+ case CKM_TLS12_KEY_AND_MAC_DERIVE: |
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: |
- isSHA256 = PR_TRUE; |
- /* fall thru */ |
case CKM_TLS_KEY_AND_MAC_DERIVE: |
- isTLS = PR_TRUE; |
- /* fall thru */ |
case CKM_SSL3_KEY_AND_MAC_DERIVE: |
{ |
CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; |
@@ -6212,6 +6375,22 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; |
unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
+ if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) { |
+ CK_TLS12_KEY_MAT_PARAMS *tls12_keys = |
+ (CK_TLS12_KEY_MAT_PARAMS *) pMechanism->pParameter; |
+ tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism); |
+ if (tlsPrfHash == HASH_AlgNULL) { |
+ crv = CKR_MECHANISM_PARAM_INVALID; |
+ break; |
+ } |
+ } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) { |
+ tlsPrfHash = HASH_AlgSHA256; |
+ } |
+ |
+ if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE) { |
+ isTLS = PR_TRUE; |
+ } |
+ |
crv = sftk_DeriveSensitiveCheck(sourceKey,key); |
if (crv != CKR_OK) break; |
@@ -6291,8 +6470,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, |
master.data = (unsigned char*)att->attrib.pValue; |
master.len = att->attrib.ulValueLen; |
- if (isSHA256) { |
- status = TLS_P_hash(HASH_AlgSHA256, &master, "key expansion", |
+ if (tlsPrfHash != HASH_AlgNULL) { |
+ status = TLS_P_hash(tlsPrfHash, &master, "key expansion", |
&srcr, &keyblk, isFIPS); |
} else { |
status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, |
@@ -6856,7 +7035,7 @@ key_and_mac_derive_fail: |
PRBool withCofactor = PR_FALSE; |
unsigned char *secret; |
unsigned char *keyData = NULL; |
- int secretlen, curveLen, pubKeyLen; |
+ unsigned int secretlen, curveLen, pubKeyLen; |
CK_ECDH1_DERIVE_PARAMS *mechParams; |
NSSLOWKEYPrivateKey *privKey; |
PLArenaPool *arena = NULL; |
@@ -6908,7 +7087,7 @@ key_and_mac_derive_fail: |
ecPoint = newPoint; |
} |
- if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) { |
+ if (mechanism == CKM_ECDH1_COFACTOR_DERIVE) { |
withCofactor = PR_TRUE; |
} else { |
/* When not using cofactor derivation, one should |