diff -up ./nss/lib/softoken/pkcs11.c.add_encrypt_derive ./nss/lib/softoken/pkcs11.c
--- ./nss/lib/softoken/pkcs11.c.add_encrypt_derive 2017-02-17 14:20:06.000000000 +0100
+++ ./nss/lib/softoken/pkcs11.c 2017-05-26 14:10:26.633700334 +0200
@@ -423,11 +423,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 2017-02-17 14:20:06.000000000 +0100
+++ ./nss/lib/softoken/pkcs11c.c 2017-05-26 14:09:34.990901108 +0200
@@ -6213,6 +6213,44 @@ sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_UL
#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
@@ -6257,6 +6295,9 @@ 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_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
+ CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
+ void *cipherInfo;
CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
PRBool isTLS = PR_FALSE;
PRBool isDH = PR_FALSE;
@@ -6266,6 +6307,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
unsigned int outLen;
unsigned char sha_out[SHA1_LENGTH];
unsigned char key_block[NUM_MIXERS * SFTK_MAX_MAC_LENGTH];
+ unsigned char des3key[24];
PRBool isFIPS;
HASH_HashType hashType;
PRBool extractValue = PR_TRUE;
@@ -6935,6 +6977,168 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
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)