Update NSS to 3.48 while keeping vc2013 hackfix and no-sslkeylogfile intact.

This commit is contained in:
Roy Tam 2020-01-03 13:36:26 +08:00
commit 171849c8e5
351 changed files with 115185 additions and 57946 deletions

View file

@ -30,6 +30,7 @@
#include "lowpbe.h" /* We do PBE below */
#include "pkcs11t.h"
#include "secoid.h"
#include "cmac.h"
#include "alghmac.h"
#include "softoken.h"
#include "secasn1.h"
@ -39,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...
@ -782,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;
@ -895,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 =
@ -924,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;
@ -987,6 +1002,10 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
if (pMechanism->ulParameterLen < 8) {
crv = CKR_DOMAIN_PARAMS_INVALID;
break;
}
t = NSS_DES_CBC;
goto finish_des;
case CKM_DES3_ECB:
@ -1004,6 +1023,10 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
if (pMechanism->ulParameterLen < 8) {
crv = CKR_DOMAIN_PARAMS_INVALID;
break;
}
t = NSS_DES_EDE3_CBC;
finish_des:
context->blockSize = 8;
@ -1121,6 +1144,13 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
case CKM_AES_CTS:
case CKM_AES_CTR:
case CKM_AES_GCM:
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))) ||
((pMechanism->mechanism == CKM_AES_CBC || pMechanism->mechanism == CKM_AES_CTS) && BAD_PARAM_CAST(pMechanism, AES_BLOCK_SIZE))) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
if (pMechanism->mechanism == CKM_AES_GCM) {
context->multi = PR_FALSE;
}
@ -1347,8 +1377,11 @@ NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
/* do it: NOTE: this assumes buf size in is >= buf size out! */
rv = (*context->update)(context->cipherInfo, pEncryptedPart,
&outlen, maxout, pPart, ulPartLen);
if (rv != SECSuccess) {
return sftk_MapCryptError(PORT_GetError());
}
*pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen);
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
return CKR_OK;
}
/* NSC_EncryptFinal finishes a multiple-part encryption operation. */
@ -1428,26 +1461,29 @@ NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
return crv;
if (!pEncryptedData) {
*pulEncryptedDataLen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize;
goto finish;
outlen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize;
goto done;
}
if (context->doPad) {
if (context->multi) {
CK_ULONG updateLen = maxoutlen;
CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final
* code deal with it */
sftk_FreeSession(session);
crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
pulEncryptedDataLen);
if (crv != CKR_OK)
*pulEncryptedDataLen = 0;
maxoutlen -= *pulEncryptedDataLen;
pEncryptedData += *pulEncryptedDataLen;
&updateLen);
if (crv != CKR_OK) {
updateLen = 0;
}
maxoutlen -= updateLen;
pEncryptedData += updateLen;
finalLen = maxoutlen;
crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
if (crv2 == CKR_OK)
*pulEncryptedDataLen += finalLen;
if (crv == CKR_OK && crv2 == CKR_OK) {
*pulEncryptedDataLen = updateLen + finalLen;
}
return crv == CKR_OK ? crv2 : crv;
}
/* doPad without multi means that padding must be done on the first
@ -1473,14 +1509,15 @@ NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
rv = (*context->update)(context->cipherInfo, pEncryptedData,
&outlen, maxoutlen, pText.data, pText.len);
crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
*pulEncryptedDataLen = (CK_ULONG)outlen;
if (pText.data != pData)
PORT_ZFree(pText.data, pText.len);
fail:
sftk_TerminateOp(session, SFTK_ENCRYPT, context);
finish:
done:
sftk_FreeSession(session);
if (crv == CKR_OK) {
*pulEncryptedDataLen = (CK_ULONG)outlen;
}
return crv;
}
@ -1569,8 +1606,73 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
/* do it: NOTE: this assumes buf size in is >= buf size out! */
rv = (*context->update)(context->cipherInfo, pPart, &outlen,
maxout, pEncryptedPart, ulEncryptedPartLen);
if (rv != SECSuccess) {
return sftk_MapDecryptError(PORT_GetError());
}
*pulPartLen = (CK_ULONG)(outlen + padoutlen);
return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
return CKR_OK;
}
/* From ssl3con.c: Constant-time helper macro that copies the MSB of x to all
* other bits. */
#define DUPLICATE_MSB_TO_ALL(x) ((unsigned int)((int)(x) >> (sizeof(int) * 8 - 1)))
/* CK_RVToMask returns, in constant time, a mask value of
* all ones if rv == CKR_OK. Otherwise it returns zero. */
static unsigned int
CK_RVToMask(CK_RV rv)
{
unsigned int good;
/* rv ^ CKR_OK is zero iff rv == CKR_OK. Subtracting one results
* in the MSB being set to one iff it was zero before. */
good = rv ^ CKR_OK;
good--;
return DUPLICATE_MSB_TO_ALL(good);
}
/* Constant-time helper macro that selects l or r depending on all-1 or all-0
* mask m */
#define CT_SEL(m, l, r) (((m) & (l)) | (~(m) & (r)))
/* Constant-time helper macro that returns all-1s if x is not 0; and all-0s
* otherwise. */
#define CT_NOT_ZERO(x) (DUPLICATE_MSB_TO_ALL(((x) | (0 - x))))
/* sftk_CheckCBCPadding checks, in constant time, the padding validity and
* accordingly sets the pad length. */
static CK_RV
sftk_CheckCBCPadding(CK_BYTE_PTR pLastPart,
unsigned int blockSize, unsigned int *outPadSize)
{
PORT_Assert(outPadSize);
unsigned int padSize = (unsigned int)pLastPart[blockSize - 1];
/* If padSize <= blockSize, set goodPad to all-1s and all-0s otherwise.*/
unsigned int goodPad = DUPLICATE_MSB_TO_ALL(~(blockSize - padSize));
/* padSize should not be 0 */
goodPad &= CT_NOT_ZERO(padSize);
unsigned int i;
for (i = 0; i < blockSize; i++) {
/* If i < padSize, set loopMask to all-1s and all-0s otherwise.*/
unsigned int loopMask = DUPLICATE_MSB_TO_ALL(~(padSize - 1 - i));
/* Get the padding value (should be padSize) from buffer */
unsigned int padVal = pLastPart[blockSize - 1 - i];
/* Update goodPad only if i < padSize */
goodPad &= CT_SEL(loopMask, ~(padVal ^ padSize), goodPad);
}
/* If any of the final padding bytes had the wrong value, one or more
* of the lower eight bits of |goodPad| will be cleared. We AND the
* bottom 8 bits together and duplicate the result to all the bits. */
goodPad &= goodPad >> 4;
goodPad &= goodPad >> 2;
goodPad &= goodPad >> 1;
goodPad <<= sizeof(goodPad) * 8 - 1;
goodPad = DUPLICATE_MSB_TO_ALL(goodPad);
/* Set outPadSize to padSize or 0 */
*outPadSize = CT_SEL(goodPad, padSize, 0);
/* Return OK if the pad is valid */
return CT_SEL(goodPad, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
}
/* NSC_DecryptFinal finishes a multiple-part decryption operation. */
@ -1611,24 +1713,10 @@ NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
if (rv != SECSuccess) {
crv = sftk_MapDecryptError(PORT_GetError());
} else {
unsigned int padSize =
(unsigned int)pLastPart[context->blockSize - 1];
if ((padSize > context->blockSize) || (padSize == 0)) {
crv = CKR_ENCRYPTED_DATA_INVALID;
} else {
unsigned int i;
unsigned int badPadding = 0; /* used as a boolean */
for (i = 0; i < padSize; i++) {
badPadding |=
(unsigned int)pLastPart[context->blockSize - 1 - i] ^
padSize;
}
if (badPadding) {
crv = CKR_ENCRYPTED_DATA_INVALID;
} else {
*pulLastPartLen = outlen - padSize;
}
}
unsigned int padSize = 0;
crv = sftk_CheckCBCPadding(&pLastPart[outlen - context->blockSize], context->blockSize, &padSize);
/* Update pulLastPartLen, in constant time, if crv is OK */
*pulLastPartLen = CT_SEL(CK_RVToMask(crv), outlen - padSize, *pulLastPartLen);
}
}
}
@ -1661,52 +1749,48 @@ NSC_Decrypt(CK_SESSION_HANDLE hSession,
return crv;
if (!pData) {
*pulDataLen = ulEncryptedDataLen + context->blockSize;
goto finish;
*pulDataLen = (CK_ULONG)(ulEncryptedDataLen + context->blockSize);
goto done;
}
if (context->doPad && context->multi) {
CK_ULONG updateLen = maxoutlen;
CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final
* code deal with it */
sftk_FreeSession(session);
crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
if (crv != CKR_OK)
*pulDataLen = 0;
maxoutlen -= *pulDataLen;
pData += *pulDataLen;
pData, &updateLen);
if (crv == CKR_OK) {
maxoutlen -= updateLen;
pData += updateLen;
}
finalLen = maxoutlen;
crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
if (crv2 == CKR_OK)
*pulDataLen += finalLen;
return crv == CKR_OK ? crv2 : crv;
if (crv == CKR_OK) {
*pulDataLen = CT_SEL(CK_RVToMask(crv2), updateLen + finalLen, *pulDataLen);
return crv2;
} else {
return crv;
}
}
rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
pEncryptedData, ulEncryptedDataLen);
/* XXX need to do MUCH better error mapping than this. */
crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
if (rv == SECSuccess && context->doPad) {
unsigned int padding = pData[outlen - 1];
if (padding > context->blockSize || !padding) {
crv = CKR_ENCRYPTED_DATA_INVALID;
if (rv == SECSuccess) {
if (context->doPad) {
unsigned int padSize = 0;
crv = sftk_CheckCBCPadding(&pData[outlen - context->blockSize], context->blockSize, &padSize);
/* Update pulDataLen, in constant time, if crv is OK */
*pulDataLen = CT_SEL(CK_RVToMask(crv), outlen - padSize, *pulDataLen);
} else {
unsigned int i;
unsigned int badPadding = 0; /* used as a boolean */
for (i = 0; i < padding; i++) {
badPadding |= (unsigned int)pData[outlen - 1 - i] ^ padding;
}
if (badPadding) {
crv = CKR_ENCRYPTED_DATA_INVALID;
} else {
outlen -= padding;
}
*pulDataLen = (CK_ULONG)outlen;
}
}
*pulDataLen = (CK_ULONG)outlen;
sftk_TerminateOp(session, SFTK_DECRYPT, context);
finish:
done:
sftk_FreeSession(session);
return crv;
}
@ -1920,54 +2004,55 @@ sftk_HMACCmp(CK_ULONG *copyLen, unsigned char *sig, unsigned int sigLen,
}
/*
* common HMAC initalization routine
* common HMAC + CMAC initialization routine
*/
static CK_RV
sftk_doHMACInit(SFTKSessionContext *context, HASH_HashType hash,
SFTKObject *key, CK_ULONG mac_size)
sftk_doMACInit(CK_MECHANISM_TYPE mech, SFTKSessionContext *session,
SFTKObject *key, CK_ULONG mac_size)
{
SFTKAttribute *keyval;
HMACContext *HMACcontext;
CK_RV crv;
sftk_MACCtx *context;
CK_ULONG *intpointer;
const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
/* required by FIPS 198 Section 4 */
if (isFIPS && (mac_size < 4 || mac_size < hashObj->length / 2)) {
/* Set up the initial context. */
crv = sftk_MAC_Create(mech, key, &context);
if (crv != CKR_OK) {
return crv;
}
session->hashInfo = context;
session->multi = PR_TRUE;
/* Required by FIPS 198 Section 4. Delay this check until after the MAC
* has been initialized to steal the output size of the MAC. */
if (isFIPS && (mac_size < 4 || mac_size < context->mac_size / 2)) {
sftk_MAC_Destroy(context, PR_TRUE);
return CKR_BUFFER_TOO_SMALL;
}
keyval = sftk_FindAttribute(key, CKA_VALUE);
if (keyval == NULL)
return CKR_KEY_SIZE_RANGE;
/* Configure our helper functions appropriately. Note that these casts
* ignore the return values. */
session->hashUpdate = (SFTKHash)sftk_MAC_Update;
session->end = (SFTKEnd)sftk_MAC_Finish;
session->hashdestroy = (SFTKDestroy)sftk_MAC_Destroy;
HMACcontext = HMAC_Create(hashObj,
(const unsigned char *)keyval->attrib.pValue,
keyval->attrib.ulValueLen, isFIPS);
context->hashInfo = HMACcontext;
context->multi = PR_TRUE;
sftk_FreeAttribute(keyval);
if (context->hashInfo == NULL) {
if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
return CKR_KEY_SIZE_RANGE;
}
return CKR_HOST_MEMORY;
}
context->hashUpdate = (SFTKHash)HMAC_Update;
context->end = (SFTKEnd)HMAC_Finish;
context->hashdestroy = (SFTKDestroy)HMAC_Destroy;
intpointer = PORT_New(CK_ULONG);
if (intpointer == NULL) {
sftk_MAC_Destroy(context, PR_TRUE);
return CKR_HOST_MEMORY;
}
*intpointer = mac_size;
context->cipherInfo = intpointer;
context->destroy = (SFTKDestroy)sftk_Space;
context->update = (SFTKCipher)sftk_SignCopy;
context->verify = (SFTKVerify)sftk_HMACCmp;
context->maxLen = hashObj->length;
HMAC_Begin(HMACcontext);
session->cipherInfo = intpointer;
/* Since we're only "hashing", copy the result from session->end to the
* caller using sftk_SignCopy. */
session->update = (SFTKCipher)sftk_SignCopy;
session->verify = (SFTKVerify)sftk_HMACCmp;
session->destroy = (SFTKDestroy)sftk_Space;
session->maxLen = context->mac_size;
return CKR_OK;
}
@ -2123,9 +2208,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 =
@ -2145,12 +2234,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;
@ -2707,18 +2802,19 @@ NSC_SignInit(CK_SESSION_HANDLE hSession,
break;
#define INIT_HMAC_MECH(mmm) \
case CKM_##mmm##_HMAC_GENERAL: \
PORT_Assert(pMechanism->pParameter); \
if (!pMechanism->pParameter) { \
crv = CKR_MECHANISM_PARAM_INVALID; \
break; \
} \
crv = sftk_doHMACInit(context, HASH_Alg##mmm, key, \
*(CK_ULONG *)pMechanism->pParameter); \
break; \
case CKM_##mmm##_HMAC: \
crv = sftk_doHMACInit(context, HASH_Alg##mmm, key, mmm##_LENGTH); \
#define INIT_HMAC_MECH(mmm) \
case CKM_##mmm##_HMAC_GENERAL: \
PORT_Assert(pMechanism->pParameter); \
if (!pMechanism->pParameter) { \
crv = CKR_MECHANISM_PARAM_INVALID; \
break; \
} \
crv = sftk_doMACInit(pMechanism->mechanism, context, key, \
*(CK_ULONG *)pMechanism->pParameter); \
break; \
case CKM_##mmm##_HMAC: \
crv = sftk_doMACInit(pMechanism->mechanism, context, key, \
mmm##_LENGTH); \
break;
INIT_HMAC_MECH(MD2)
@ -2730,17 +2826,27 @@ NSC_SignInit(CK_SESSION_HANDLE hSession,
case CKM_SHA_1_HMAC_GENERAL:
PORT_Assert(pMechanism->pParameter);
if (!pMechanism->pParameter) {
if (!pMechanism->pParameter || pMechanism->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
crv = sftk_doHMACInit(context, HASH_AlgSHA1, key,
*(CK_ULONG *)pMechanism->pParameter);
crv = sftk_doMACInit(pMechanism->mechanism, context, key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
crv = sftk_doHMACInit(context, HASH_AlgSHA1, key, SHA1_LENGTH);
crv = sftk_doMACInit(pMechanism->mechanism, context, key, SHA1_LENGTH);
break;
case CKM_AES_CMAC_GENERAL:
PORT_Assert(pMechanism->pParameter);
if (!pMechanism->pParameter || pMechanism->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
crv = sftk_doMACInit(pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_AES_CMAC:
crv = sftk_doMACInit(pMechanism->mechanism, context, key, AES_BLOCK_SIZE);
break;
case CKM_SSL3_MD5_MAC:
PORT_Assert(pMechanism->pParameter);
if (!pMechanism->pParameter) {
@ -3414,11 +3520,11 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
crv = sftk_doHMACInit(context, HASH_AlgSHA1, key,
*(CK_ULONG *)pMechanism->pParameter);
crv = sftk_doMACInit(pMechanism->mechanism, context, key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
crv = sftk_doHMACInit(context, HASH_AlgSHA1, key, SHA1_LENGTH);
crv = sftk_doMACInit(pMechanism->mechanism, context, key, SHA1_LENGTH);
break;
case CKM_SSL3_MD5_MAC:
@ -3744,11 +3850,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;
@ -4048,6 +4160,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;
@ -4127,10 +4243,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;
@ -4157,6 +4273,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;
@ -4203,11 +4322,12 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
break;
default:
crv = CKR_MECHANISM_INVALID;
nsspkcs5_DestroyPBEParameter(params);
break;
}
if (crv == CKR_OK) {
*pbe = params;
} else {
nsspkcs5_DestroyPBEParameter(params);
}
return crv;
}
@ -4272,12 +4392,12 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
if (crv != CKR_OK)
if (crv != CKR_OK) {
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 */
@ -4390,8 +4510,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
if (crv != CKR_OK) {
sftk_FreeObject(key);
return crv;
if (pbe_param) {
nsspkcs5_DestroyPBEParameter(pbe_param);
}
goto loser;
}
/* if there was no error,
@ -4409,6 +4531,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;
@ -4427,6 +4553,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);
@ -4434,34 +4564,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;
}
/*
@ -4478,6 +4604,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession,
if (crv == CKR_OK) {
*phKey = key->handle;
}
loser:
sftk_FreeObject(key);
return crv;
}
@ -5591,8 +5718,8 @@ NSC_WrapKey(CK_SESSION_HANDLE hSession,
}
key = sftk_ObjectFromHandle(hKey, session);
sftk_FreeSession(session);
if (key == NULL) {
sftk_FreeSession(session);
return CKR_KEY_HANDLE_INVALID;
}
@ -5698,7 +5825,7 @@ NSC_WrapKey(CK_SESSION_HANDLE hSession,
break;
}
sftk_FreeObject(key);
sftk_FreeSession(session);
return sftk_mapWrap(crv);
}
@ -6507,7 +6634,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;
@ -6525,6 +6651,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
*/
@ -6698,6 +6829,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);
@ -6965,6 +7100,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);
@ -7008,6 +7147,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,
@ -7202,6 +7348,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;
@ -7251,10 +7401,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;
@ -7287,6 +7445,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;
@ -7295,6 +7457,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;
@ -7328,6 +7494,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;
@ -7336,6 +7506,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;
@ -7427,6 +7601,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)
@ -7453,6 +7631,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)
@ -7479,6 +7661,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)
@ -7503,6 +7689,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 */