| 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
|
|
|