Blob Blame History Raw
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;