diff options
author | Kevin Jacobs <kjacobs@mozilla.com> | 2019-09-30 22:16:21 +0000 |
---|---|---|
committer | Kevin Jacobs <kjacobs@mozilla.com> | 2019-09-30 22:16:21 +0000 |
commit | 3246acfff91e20b7bc18184da77206812eb756c3 (patch) | |
tree | b2c3b6b4f898c1ea42e9a7be79e0f5b2a0e361a2 | |
parent | b5eecf2f86646f45923664c494b1a430619d3742 (diff) | |
download | nss-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.cc | 84 | ||||
-rw-r--r-- | lib/softoken/pkcs11c.c | 149 |
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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, encrypted, &encrypted_len, + sizeof(encrypted), kInput, input_len); + EXPECT_EQ(SECFailure, rv); + + param.len++; + rv = PK11_Encrypt(key.get(), CKM_AES_CBC, ¶m, 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, ¶m, encrypted, &encrypted_len, + sizeof(encrypted), kInput, input_len); + EXPECT_EQ(SECFailure, rv); + + param.len++; + rv = PK11_Encrypt(key.get(), CKM_AES_ECB, ¶m, 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, ¶m, encrypted, &encrypted_len, + sizeof(encrypted), kInput, input_len); + EXPECT_EQ(SECFailure, rv); + + param.len++; + rv = PK11_Encrypt(key.get(), CKM_AES_CTS, ¶m, 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 */ |