diff -up ./nss/lib/softoken/pkcs11.c.add_encrypt_derive ./nss/lib/softoken/pkcs11.c --- ./nss/lib/softoken/pkcs11.c.add_encrypt_derive 2014-06-24 13:45:27.000000000 -0700 +++ ./nss/lib/softoken/pkcs11.c 2014-10-31 17:24:58.021526521 -0700 @@ -442,11 +442,22 @@ static const struct mechanismList mechan #endif /* --------------------- Secret Key Operations ------------------------ */ {CKM_GENERIC_SECRET_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_CONCATENATE_BASE_AND_KEY, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_CONCATENATE_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_CONCATENATE_DATA_AND_BASE, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_XOR_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE}, + {CKM_CONCATENATE_BASE_AND_KEY, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_CONCATENATE_BASE_AND_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_CONCATENATE_DATA_AND_BASE, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_XOR_BASE_AND_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, {CKM_EXTRACT_KEY_FROM_KEY, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_EXTRACT_KEY_FROM_KEY, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_DES_ECB_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_DES_CBC_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_DES3_ECB_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_DES3_CBC_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_AES_ECB_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_AES_CBC_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_CAMELLIA_ECB_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_CAMELLIA_CBC_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_SEED_ECB_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, + {CKM_SEED_CBC_ENCRYPT_DATA, {1, 32, CKF_DERIVE}, PR_FALSE}, /* ---------------------- SSL Key Derivations ------------------------- */ {CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}, PR_FALSE}, {CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE}, diff -up ./nss/lib/softoken/pkcs11c.c.add_encrypt_derive ./nss/lib/softoken/pkcs11c.c --- ./nss/lib/softoken/pkcs11c.c.add_encrypt_derive 2014-10-31 17:24:58.007526287 -0700 +++ ./nss/lib/softoken/pkcs11c.c 2014-10-31 17:33:59.457507480 -0700 @@ -5840,6 +5840,44 @@ static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE #endif /* NSS_DISABLE_ECC */ /* + * Handle The derive from a block encryption cipher + */ +CK_RV +sftk_DeriveEncrypt(SFTKObject *key, CK_ULONG keySize, void *cipherInfo, + int blockSize, unsigned char *data, CK_ULONG len, SFTKCipher encrypt) +{ + unsigned char *tmpdata = NULL; + SECStatus rv; + unsigned int outLen; + CK_RV crv; + + if ((len % blockSize) != 0) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize && (len < keySize)) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize == 0) { + keySize = len; + } + + tmpdata = PORT_Alloc(len); + if (tmpdata == NULL) { + return CKR_HOST_MEMORY; + } + rv = (*encrypt)(cipherInfo, tmpdata, &outLen, len, data, len); + if (rv != SECSuccess) { + crv = sftk_MapCryptError(PORT_GetError()); + PORT_ZFree(tmpdata, len); + return crv; + } + + crv = sftk_forceAttribute (key,CKA_VALUE,tmpdata,keySize); + PORT_ZFree(tmpdata,len); + return crv; +} + +/* * SSL Key generation given pre master secret */ #define NUM_MIXERS 9 @@ -5883,6 +5921,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE h CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; CK_OBJECT_CLASS classType = CKO_SECRET_KEY; CK_KEY_DERIVATION_STRING_DATA *stringPtr; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr; + void *cipherInfo; PRBool isTLS = PR_FALSE; PRBool isSHA256 = PR_FALSE; PRBool isDH = PR_FALSE; @@ -5892,6 +5933,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE h unsigned char sha_out[SHA1_LENGTH]; unsigned char key_block[NUM_MIXERS * MD5_LENGTH]; unsigned char key_block2[MD5_LENGTH]; + unsigned char des3key[24]; PRBool isFIPS; HASH_HashType hashType; PRBool extractValue = PR_TRUE; @@ -6544,6 +6586,136 @@ key_and_mac_derive_fail: break; } + case CKM_DES_ECB_ENCRYPT_DATA: + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; + cipherInfo = DES_CreateContext( (unsigned char*)att->attrib.pValue, + NULL, NSS_DES, PR_TRUE); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 8, + stringPtr->pData, stringPtr->ulLen, (SFTKCipher) DES_Encrypt); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_DES_CBC_ENCRYPT_DATA: + desEncryptPtr = (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + cipherInfo = DES_CreateContext( (unsigned char*)att->attrib.pValue, + desEncryptPtr->iv, NSS_DES_CBC, PR_TRUE); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 8, + desEncryptPtr->pData, desEncryptPtr->length, + (SFTKCipher) DES_Encrypt); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_DES3_ECB_ENCRYPT_DATA: + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; + if (att->attrib.ulValueLen == 16) { + PORT_Memcpy(des3key, att->attrib.pValue, 16); + PORT_Memcpy(des3key + 16, des3key, 8); + } else if (att->attrib.ulValueLen == 24) { + PORT_Memcpy(des3key, att->attrib.pValue, 24); + } else { + crv = CKR_KEY_SIZE_RANGE; break; + } + cipherInfo = DES_CreateContext( des3key, NULL, NSS_DES_EDE3, PR_TRUE); + PORT_Memset(des3key, 0, 24); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 8, + stringPtr->pData, stringPtr->ulLen, (SFTKCipher) DES_Encrypt); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_DES3_CBC_ENCRYPT_DATA: + desEncryptPtr = (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + if (att->attrib.ulValueLen == 16) { + PORT_Memcpy(des3key, att->attrib.pValue, 16); + PORT_Memcpy(des3key + 16, des3key, 8); + } else if (att->attrib.ulValueLen == 24) { + PORT_Memcpy(des3key, att->attrib.pValue, 24); + } else { + crv = CKR_KEY_SIZE_RANGE; break; + } + cipherInfo = DES_CreateContext( des3key, desEncryptPtr->iv, + NSS_DES_EDE3_CBC, PR_TRUE); + PORT_Memset(des3key, 0, 24); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 8, + desEncryptPtr->pData, desEncryptPtr->length, + (SFTKCipher) DES_Encrypt); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_AES_ECB_ENCRYPT_DATA: + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; + cipherInfo = AES_CreateContext( (unsigned char*)att->attrib.pValue, + NULL, NSS_AES, PR_TRUE, att->attrib.ulValueLen, 16); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + stringPtr->pData, stringPtr->ulLen, (SFTKCipher) AES_Encrypt); + AES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_AES_CBC_ENCRYPT_DATA: + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + cipherInfo = AES_CreateContext( (unsigned char*)att->attrib.pValue, + aesEncryptPtr->iv, NSS_AES_CBC, + PR_TRUE, att->attrib.ulValueLen, 16); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + aesEncryptPtr->pData, aesEncryptPtr->length, + (SFTKCipher) AES_Encrypt); + AES_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_CAMELLIA_ECB_ENCRYPT_DATA: + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; + cipherInfo = Camellia_CreateContext( (unsigned char*)att->attrib.pValue, + NULL, NSS_CAMELLIA, PR_TRUE,att->attrib.ulValueLen); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + stringPtr->pData, stringPtr->ulLen, + (SFTKCipher) Camellia_Encrypt); + Camellia_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_CAMELLIA_CBC_ENCRYPT_DATA: + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + cipherInfo = Camellia_CreateContext((unsigned char*)att->attrib.pValue, + aesEncryptPtr->iv,NSS_CAMELLIA_CBC, + PR_TRUE, att->attrib.ulValueLen); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + aesEncryptPtr->pData, aesEncryptPtr->length, + (SFTKCipher) Camellia_Encrypt); + Camellia_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_SEED_ECB_ENCRYPT_DATA: + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; + cipherInfo = SEED_CreateContext( (unsigned char*)att->attrib.pValue, + NULL, NSS_SEED, PR_TRUE); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + stringPtr->pData, stringPtr->ulLen, (SFTKCipher) SEED_Encrypt); + SEED_DestroyContext(cipherInfo, PR_TRUE); + break; + + case CKM_SEED_CBC_ENCRYPT_DATA: + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + cipherInfo = SEED_CreateContext( (unsigned char*)att->attrib.pValue, + aesEncryptPtr->iv, NSS_SEED_CBC, PR_TRUE); + if (cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } + crv = sftk_DeriveEncrypt(key, keySize, cipherInfo, 16, + aesEncryptPtr->pData, aesEncryptPtr->length, + (SFTKCipher) SEED_Encrypt); + SEED_DestroyContext(cipherInfo, PR_TRUE); + break; + case CKM_CONCATENATE_BASE_AND_DATA: crv = sftk_DeriveSensitiveCheck(sourceKey,key); if (crv != CKR_OK) break;