summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Jacobs <kjacobs@mozilla.com>2019-09-30 22:16:21 +0000
committerKevin Jacobs <kjacobs@mozilla.com>2019-09-30 22:16:21 +0000
commit3246acfff91e20b7bc18184da77206812eb756c3 (patch)
treeb2c3b6b4f898c1ea42e9a7be79e0f5b2a0e361a2
parentb5eecf2f86646f45923664c494b1a430619d3742 (diff)
downloadnss-hg-3246acfff91e20b7bc18184da77206812eb756c3.tar.gz
Bug 1576307 - Check mechanism param and param length before casting to mechanism-specific structs. r=jcj
This patch adds missing PKCS11 input parameter checks, which are needed prior to casting to mechanism-specific structs. Differential Revision: https://phabricator.services.mozilla.com/D44075
-rw-r--r--gtests/pk11_gtest/pk11_cbc_unittest.cc84
-rw-r--r--lib/softoken/pkcs11c.c149
2 files changed, 214 insertions, 19 deletions
diff --git a/gtests/pk11_gtest/pk11_cbc_unittest.cc b/gtests/pk11_gtest/pk11_cbc_unittest.cc
index 5f7a8f921..7de51f828 100644
--- a/gtests/pk11_gtest/pk11_cbc_unittest.cc
+++ b/gtests/pk11_gtest/pk11_cbc_unittest.cc
@@ -233,6 +233,90 @@ TEST_P(Pkcs11CbcPadTest, FailEncryptSimple) {
EXPECT_EQ(333U, output_len);
}
+// It's a bit of a lie to put this in pk11_cbc_unittest, since we
+// also test bounds checking in other modes. There doesn't seem
+// to be an appropriately-generic place elsewhere.
+TEST_F(Pkcs11CbcPadTest, FailEncryptShortParam) {
+ SECStatus rv = SECFailure;
+ uint8_t encrypted[sizeof(kInput)];
+ unsigned int encrypted_len = 0;
+ size_t input_len = AES_BLOCK_SIZE;
+
+ // CK_GCM_PARAMS is the largest param struct used across AES modes
+ uint8_t param_buf[sizeof(CK_GCM_PARAMS)];
+ SECItem param = {siBuffer, param_buf, sizeof(param_buf)};
+ SECItem key_item = {siBuffer, const_cast<uint8_t*>(kKeyData), 16};
+
+ // Setup (we use the ECB key for other modes)
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ASSERT_NE(nullptr, slot);
+ ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), CKM_AES_ECB,
+ PK11_OriginUnwrap, CKA_ENCRYPT,
+ &key_item, nullptr));
+ ASSERT_TRUE(key.get());
+
+ // CTR should have a CK_AES_CTR_PARAMS
+ param.len = sizeof(CK_AES_CTR_PARAMS) - 1;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CTR, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECFailure, rv);
+
+ param.len++;
+ reinterpret_cast<CK_AES_CTR_PARAMS*>(param.data)->ulCounterBits = 32;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CTR, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECSuccess, rv);
+
+ // GCM should have a CK_GCM_PARAMS
+ param.len = sizeof(CK_GCM_PARAMS) - 1;
+ rv = PK11_Encrypt(key.get(), CKM_AES_GCM, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECFailure, rv);
+
+ param.len++;
+ reinterpret_cast<CK_GCM_PARAMS*>(param.data)->pIv = param_buf;
+ reinterpret_cast<CK_GCM_PARAMS*>(param.data)->ulIvLen = 12;
+ reinterpret_cast<CK_GCM_PARAMS*>(param.data)->pAAD = nullptr;
+ reinterpret_cast<CK_GCM_PARAMS*>(param.data)->ulAADLen = 0;
+ reinterpret_cast<CK_GCM_PARAMS*>(param.data)->ulTagBits = 128;
+ rv = PK11_Encrypt(key.get(), CKM_AES_GCM, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECSuccess, rv);
+
+ // CBC (and the below modes) should have a 16B IV
+ param.len = AES_BLOCK_SIZE - 1;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CBC, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECFailure, rv);
+
+ param.len++;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CBC, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECSuccess, rv);
+
+ // ECB
+ param.len = AES_BLOCK_SIZE - 1;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CBC, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECFailure, rv);
+
+ param.len++;
+ rv = PK11_Encrypt(key.get(), CKM_AES_ECB, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECSuccess, rv);
+
+ // CTS
+ param.len = AES_BLOCK_SIZE - 1;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CBC, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECFailure, rv);
+
+ param.len++;
+ rv = PK11_Encrypt(key.get(), CKM_AES_CTS, &param, encrypted, &encrypted_len,
+ sizeof(encrypted), kInput, input_len);
+ EXPECT_EQ(SECSuccess, rv);
+}
+
TEST_P(Pkcs11CbcPadTest, ContextFailDecryptSimple) {
ScopedPK11Context dctx = MakeContext(CKA_DECRYPT);
uint8_t output[sizeof(kInput) + 64];
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
index 0a1c69892..2ad7ed92f 100644
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -40,7 +40,7 @@
#include "prenv.h"
#define __PASTE(x, y) x##y
-
+#define BAD_PARAM_CAST(pMech, typeSize) (!pMech->pParameter || pMech->ulParameterLen < typeSize)
/*
* we renamed all our internal functions, get the correct
* definitions for them...
@@ -783,6 +783,10 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
PRBool useNewKey = PR_FALSE;
int t;
+ if (!pMechanism) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage);
if (crv != CKR_OK)
return crv;
@@ -896,6 +900,11 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_KEY_HANDLE_INVALID;
break;
}
+
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_CBC_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
effectiveKeyLength = (rc2_param->ulEffectiveBits + 7) / 8;
context->cipherInfo =
@@ -925,6 +934,11 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_KEY_HANDLE_INVALID;
break;
}
+
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_CBC_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
context->blockSize = rc5_param->ulWordsize * 2;
rc5Key.data = (unsigned char *)att->attrib.pValue;
@@ -1122,6 +1136,14 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
case CKM_AES_CTS:
case CKM_AES_CTR:
case CKM_AES_GCM:
+ /* Note the catch-all only applies to the above cases */
+ if ((pMechanism->mechanism == CKM_AES_GCM && BAD_PARAM_CAST(pMechanism, sizeof(CK_GCM_PARAMS))) ||
+ (pMechanism->mechanism == CKM_AES_CTR && BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CTR_PARAMS))) ||
+ BAD_PARAM_CAST(pMechanism, AES_BLOCK_SIZE) /* Cast target is an IV */) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+
if (pMechanism->mechanism == CKM_AES_GCM) {
context->multi = PR_FALSE;
}
@@ -2216,9 +2238,13 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
unsigned int blockSize;
PRBool isXCBC = PR_FALSE;
+ if (!pMechanism) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
switch (pMechanism->mechanism) {
case CKM_RC2_MAC_GENERAL:
- if (!pMechanism->pParameter) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_MAC_GENERAL_PARAMS))) {
return CKR_MECHANISM_PARAM_INVALID;
}
mac_bytes =
@@ -2238,12 +2264,18 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
break;
#if NSS_SOFTOKEN_DOES_RC5
case CKM_RC5_MAC_GENERAL:
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
mac_bytes =
((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
/* fall through */
case CKM_RC5_MAC:
/* this works because ulEffectiveBits is in the same place in both the
* CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
rc5_params.ulWordsize = rc5_mac->ulWordsize;
rc5_params.ulRounds = rc5_mac->ulRounds;
@@ -3847,11 +3879,17 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
iv.len = 0;
if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PKCS5_PBKD2_PARAMS))) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
pwitem.data = (unsigned char *)pbkd2_params->pPassword;
/* was this a typo in the PKCS #11 spec? */
pwitem.len = *pbkd2_params->ulPasswordLen;
} else {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
pwitem.data = (unsigned char *)pbe_params->pPassword;
pwitem.len = pbe_params->ulPasswordLen;
@@ -4151,6 +4189,10 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
PORT_FreeArena(arena, PR_TRUE);
return CKR_HOST_MEMORY;
}
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) {
+ PORT_FreeArena(arena, PR_TRUE);
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
params->poolp = arena;
params->ivLen = 0;
@@ -4230,10 +4272,10 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
}
if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
- pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
- if (pbkd2_params == NULL) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PKCS5_PBKD2_PARAMS))) {
return CKR_MECHANISM_PARAM_INVALID;
}
+ pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
switch (pbkd2_params->prf) {
case CKP_PKCS5_PBKD2_HMAC_SHA1:
hashType = HASH_AlgSHA1;
@@ -4260,6 +4302,9 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen;
iteration = pbkd2_params->iterations;
} else {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
salt.data = (unsigned char *)pbe_params->pSalt;
salt.len = (unsigned int)pbe_params->ulSaltLen;
@@ -4379,8 +4424,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
break;
}
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
/* make sure we don't have any class, key_type, or value fields */
@@ -4493,8 +4537,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
/* if there was no error,
@@ -4512,6 +4555,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
break;
case nsc_ssl:
rsa_pms = (SSL3RSAPreMasterSecret *)buf;
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_VERSION))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ goto loser;
+ }
version = (CK_VERSION *)pMechanism->pParameter;
rsa_pms->client_version[0] = version->major;
rsa_pms->client_version[1] = version->minor;
@@ -4530,6 +4577,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
crv = nsc_parameter_gen(key_type, key);
break;
case nsc_jpake:
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_NSS_JPAKERound1Params))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ goto loser;
+ }
crv = jpake_Round1(hashType,
(CK_NSS_JPAKERound1Params *)pMechanism->pParameter,
key);
@@ -4537,34 +4588,30 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
/* Add the class, key_type, and value */
crv = sftk_AddAttributeType(key, CKA_CLASS, &objclass, sizeof(CK_OBJECT_CLASS));
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE));
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
if (key_length != 0) {
crv = sftk_AddAttributeType(key, CKA_VALUE, buf, key_length);
if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
+ goto loser;
}
}
/* get the session */
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- sftk_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
+ crv = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
/*
@@ -4581,6 +4628,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
if (crv == CKR_OK) {
*phKey = key->handle;
}
+loser:
sftk_FreeObject(key);
return crv;
}
@@ -6610,7 +6658,6 @@ 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 isDH = PR_FALSE;
HASH_HashType tlsPrfHash = HASH_AlgNULL;
@@ -6628,6 +6675,11 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if (!slot) {
return CKR_SESSION_HANDLE_INVALID;
}
+ if (!pMechanism) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
+
/*
* now lets create an object to hang the attributes off of
*/
@@ -6801,6 +6853,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
(mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
(CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
@@ -7068,6 +7124,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
(CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
@@ -7111,6 +7171,13 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
crv = CKR_HOST_MEMORY;
break;
}
+
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_SSL3_KEY_MAT_PARAMS))) {
+ MD5_DestroyContext(md5, PR_TRUE);
+ SHA1_DestroyContext(sha, PR_TRUE);
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;
PORT_Memcpy(srcrdata,
@@ -7305,6 +7372,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
CK_ULONG len;
if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
pMechanism->pParameter;
mode = NSS_DES_EDE3;
@@ -7354,10 +7425,18 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) {
mode = NSS_AES;
iv = NULL;
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
data = stringPtr->pData;
len = stringPtr->ulLen;
} else {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
aesEncryptPtr =
(CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
mode = NSS_AES_CBC;
@@ -7390,6 +7469,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
CK_ULONG len;
if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
pMechanism->pParameter;
aesEncryptPtr = NULL;
@@ -7398,6 +7481,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
len = stringPtr->ulLen;
iv = NULL;
} else {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = NULL;
aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
pMechanism->pParameter;
@@ -7431,6 +7518,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
CK_ULONG len;
if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
mode = NSS_SEED;
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
pMechanism->pParameter;
@@ -7439,6 +7530,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
len = stringPtr->ulLen;
iv = NULL;
} else {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
mode = NSS_SEED_CBC;
aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
pMechanism->pParameter;
@@ -7530,6 +7625,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if (crv != CKR_OK)
break;
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
if (keySize == 0)
@@ -7556,6 +7655,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if (crv != CKR_OK)
break;
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
if (keySize == 0)
@@ -7582,6 +7685,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
if (crv != CKR_OK)
break;
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen);
if (keySize == 0)
@@ -7606,6 +7713,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
break;
case CKM_EXTRACT_KEY_FROM_KEY: {
+ if (BAD_PARAM_CAST(pMechanism, sizeof(CK_EXTRACT_PARAMS))) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
/* the following assumes 8 bits per byte */
CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */