| Index: nss/lib/softoken/pkcs11c.c
|
| diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c
|
| index 992fba41c6129e771d582c61362b7e7aa9999d3e..f0d36cc71f3fcf6b7722b622da460879bb3d9760 100644
|
| --- a/nss/lib/softoken/pkcs11c.c
|
| +++ b/nss/lib/softoken/pkcs11c.c
|
| @@ -36,6 +36,7 @@
|
| #include "secerr.h"
|
|
|
| #include "prprf.h"
|
| +#include "prenv.h"
|
|
|
| #define __PASTE(x,y) x##y
|
|
|
| @@ -666,40 +667,40 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
|
|
|
| static SFTKChaCha20Poly1305Info *
|
| sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
| - unsigned int keyLen,
|
| - const CK_NSS_AEAD_PARAMS* params)
|
| + unsigned int keyLen,
|
| + const CK_NSS_AEAD_PARAMS *params)
|
| {
|
| SFTKChaCha20Poly1305Info *ctx;
|
|
|
| - if (params->ulIvLen != sizeof(ctx->nonce)) {
|
| - PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| - return NULL;
|
| + if (params->ulNonceLen != sizeof(ctx->nonce)) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| + return NULL;
|
| }
|
|
|
| ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
| if (ctx == NULL) {
|
| - return NULL;
|
| + return NULL;
|
| }
|
|
|
| if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
|
| - params->ulTagLen) != SECSuccess) {
|
| - PORT_Free(ctx);
|
| - return NULL;
|
| + params->ulTagLen) != SECSuccess) {
|
| + PORT_Free(ctx);
|
| + return NULL;
|
| }
|
|
|
| - memcpy(ctx->nonce, params->pIv, sizeof(ctx->nonce));
|
| + PORT_Memcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce));
|
|
|
| if (params->ulAADLen > sizeof(ctx->ad)) {
|
| - /* Need to allocate an overflow buffer for the additional data. */
|
| - ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
|
| - if (!ctx->adOverflow) {
|
| - PORT_Free(ctx);
|
| - return NULL;
|
| - }
|
| - memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
|
| + /* Need to allocate an overflow buffer for the additional data. */
|
| + ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
|
| + if (!ctx->adOverflow) {
|
| + PORT_Free(ctx);
|
| + return NULL;
|
| + }
|
| + PORT_Memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
|
| } else {
|
| - ctx->adOverflow = NULL;
|
| - memcpy(ctx->ad, params->pAAD, params->ulAADLen);
|
| + ctx->adOverflow = NULL;
|
| + PORT_Memcpy(ctx->ad, params->pAAD, params->ulAADLen);
|
| }
|
| ctx->adLen = params->ulAADLen;
|
|
|
| @@ -708,51 +709,51 @@ sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
|
|
| static void
|
| sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
|
| - PRBool freeit)
|
| + PRBool freeit)
|
| {
|
| ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE);
|
| if (ctx->adOverflow != NULL) {
|
| - PORT_Free(ctx->adOverflow);
|
| - ctx->adOverflow = NULL;
|
| + PORT_Free(ctx->adOverflow);
|
| + ctx->adOverflow = NULL;
|
| }
|
| ctx->adLen = 0;
|
| if (freeit) {
|
| - PORT_Free(ctx);
|
| + PORT_Free(ctx);
|
| }
|
| }
|
|
|
| static SECStatus
|
| sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| - unsigned char *output, unsigned int *outputLen,
|
| - unsigned int maxOutputLen,
|
| - const unsigned char *input, unsigned int inputLen)
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen)
|
| {
|
| const unsigned char *ad = ctx->adOverflow;
|
|
|
| if (ad == NULL) {
|
| - ad = ctx->ad;
|
| + ad = ctx->ad;
|
| }
|
|
|
| return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
|
| - maxOutputLen, input, inputLen, ctx->nonce,
|
| - sizeof(ctx->nonce), ad, ctx->adLen);
|
| + maxOutputLen, input, inputLen, ctx->nonce,
|
| + sizeof(ctx->nonce), ad, ctx->adLen);
|
| }
|
|
|
| static SECStatus
|
| sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| - unsigned char *output, unsigned int *outputLen,
|
| - unsigned int maxOutputLen,
|
| - const unsigned char *input, unsigned int inputLen)
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen)
|
| {
|
| const unsigned char *ad = ctx->adOverflow;
|
|
|
| if (ad == NULL) {
|
| - ad = ctx->ad;
|
| + ad = ctx->ad;
|
| }
|
|
|
| return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
|
| - maxOutputLen, input, inputLen, ctx->nonce,
|
| - sizeof(ctx->nonce), ad, ctx->adLen);
|
| + maxOutputLen, input, inputLen, ctx->nonce,
|
| + sizeof(ctx->nonce), ad, ctx->adLen);
|
| }
|
|
|
| /** NSC_CryptInit initializes an encryption/Decryption operation.
|
| @@ -972,7 +973,6 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
| break;
|
| }
|
| t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
|
| - if (crv != CKR_OK) break;
|
| goto finish_des;
|
| case CKM_DES_ECB:
|
| if (key_type != CKK_DES) {
|
| @@ -1171,8 +1171,7 @@ finish_des:
|
| crv = sftk_MapCryptError(PORT_GetError());
|
| break;
|
| }
|
| - context->update = (SFTKCipher) (isEncrypt ?
|
| - sftk_ChaCha20Poly1305_Encrypt :
|
| + context->update = (SFTKCipher) (isEncrypt ? sftk_ChaCha20Poly1305_Encrypt :
|
| sftk_ChaCha20Poly1305_Decrypt);
|
| context->destroy = (SFTKDestroy) sftk_ChaCha20Poly1305_DestroyContext;
|
| break;
|
| @@ -2216,10 +2215,10 @@ static DERTemplate SECAlgorithmIDTemplate[] = {
|
| { DER_SEQUENCE,
|
| 0, NULL, sizeof(SECAlgorithmID) },
|
| { DER_OBJECT_ID,
|
| - offsetof(SECAlgorithmID,algorithm), },
|
| + offsetof(SECAlgorithmID,algorithm) },
|
| { DER_OPTIONAL | DER_ANY,
|
| - offsetof(SECAlgorithmID,parameters), },
|
| - { 0, }
|
| + offsetof(SECAlgorithmID,parameters) },
|
| + { 0 }
|
| };
|
|
|
| /*
|
| @@ -2231,10 +2230,10 @@ static DERTemplate SGNDigestInfoTemplate[] = {
|
| 0, NULL, sizeof(SGNDigestInfo) },
|
| { DER_INLINE,
|
| offsetof(SGNDigestInfo,digestAlgorithm),
|
| - SECAlgorithmIDTemplate, },
|
| + SECAlgorithmIDTemplate },
|
| { DER_OCTET_STRING,
|
| - offsetof(SGNDigestInfo,digest), },
|
| - { 0, }
|
| + offsetof(SGNDigestInfo,digest) },
|
| + { 0 }
|
| };
|
|
|
| /*
|
| @@ -3859,6 +3858,7 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
|
| SECOidData *oid;
|
| CK_PBE_PARAMS *pbe_params = NULL;
|
| NSSPKCS5PBEParameter *params = NULL;
|
| + HASH_HashType hashType = HASH_AlgSHA1;
|
| CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
|
| SECItem salt;
|
| CK_ULONG iteration = 0;
|
| @@ -3872,6 +3872,28 @@ 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) {
|
| + return CKR_MECHANISM_PARAM_INVALID;
|
| + }
|
| + switch (pbkd2_params->prf) {
|
| + case CKP_PKCS5_PBKD2_HMAC_SHA1:
|
| + hashType = HASH_AlgSHA1;
|
| + break;
|
| + case CKP_PKCS5_PBKD2_HMAC_SHA224:
|
| + hashType = HASH_AlgSHA224;
|
| + break;
|
| + case CKP_PKCS5_PBKD2_HMAC_SHA256:
|
| + hashType = HASH_AlgSHA256;
|
| + break;
|
| + case CKP_PKCS5_PBKD2_HMAC_SHA384:
|
| + hashType = HASH_AlgSHA384;
|
| + break;
|
| + case CKP_PKCS5_PBKD2_HMAC_SHA512:
|
| + hashType = HASH_AlgSHA512;
|
| + break;
|
| + default:
|
| + return CKR_MECHANISM_PARAM_INVALID;
|
| + }
|
| if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) {
|
| return CKR_MECHANISM_PARAM_INVALID;
|
| }
|
| @@ -3884,7 +3906,7 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
|
| salt.len = (unsigned int)pbe_params->ulSaltLen;
|
| iteration = pbe_params->ulIteration;
|
| }
|
| - params=nsspkcs5_NewParam(oid->offset, &salt, iteration);
|
| + params=nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration);
|
| if (params == NULL) {
|
| return CKR_MECHANISM_INVALID;
|
| }
|
| @@ -3907,14 +3929,6 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
|
| *key_length = params->keyLen;
|
| break;
|
| case SEC_OID_PKCS5_PBKDF2:
|
| - /* sigh, PKCS #11 currently only defines SHA1 for the KDF hash type.
|
| - * we do the check here because this where we would handle multiple
|
| - * hash types in the future */
|
| - if (pbkd2_params == NULL ||
|
| - pbkd2_params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1) {
|
| - crv = CKR_MECHANISM_PARAM_INVALID;
|
| - break;
|
| - }
|
| /* key type must already be set */
|
| if (*key_type == CKK_INVALID_KEY_TYPE) {
|
| crv = CKR_TEMPLATE_INCOMPLETE;
|
| @@ -4166,14 +4180,15 @@ jpake1:
|
| */
|
| crv = sftk_handleObject(key,session);
|
| sftk_FreeSession(session);
|
| - if (sftk_isTrue(key,CKA_SENSITIVE)) {
|
| - sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
|
| + if (crv == CKR_OK && sftk_isTrue(key,CKA_SENSITIVE)) {
|
| + crv = sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
|
| }
|
| - if (!sftk_isTrue(key,CKA_EXTRACTABLE)) {
|
| - sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
|
| + if (crv == CKR_OK && !sftk_isTrue(key,CKA_EXTRACTABLE)) {
|
| + crv = sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
|
| + }
|
| + if (crv == CKR_OK) {
|
| + *phKey = key->handle;
|
| }
|
| -
|
| - *phKey = key->handle;
|
| sftk_FreeObject(key);
|
| return crv;
|
| }
|
| @@ -4880,7 +4895,7 @@ dhgn_done:
|
| break;
|
| }
|
|
|
| - if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) {
|
| + if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT")) {
|
| crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
|
| sftk_item_expand(&ecPriv->publicValue));
|
| } else {
|
| @@ -4972,41 +4987,46 @@ ecgn_done:
|
| return crv;
|
| }
|
| if (sftk_isTrue(privateKey,CKA_SENSITIVE)) {
|
| - sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
|
| + crv = sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
|
| &cktrue,sizeof(CK_BBOOL));
|
| }
|
| - if (sftk_isTrue(publicKey,CKA_SENSITIVE)) {
|
| - sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
|
| + if (crv == CKR_OK && sftk_isTrue(publicKey,CKA_SENSITIVE)) {
|
| + crv = sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
|
| &cktrue,sizeof(CK_BBOOL));
|
| }
|
| - if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
|
| - sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
|
| + if (crv == CKR_OK && !sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
|
| + crv = sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
|
| &cktrue,sizeof(CK_BBOOL));
|
| }
|
| - if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
|
| - sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
|
| + if (crv == CKR_OK && !sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
|
| + crv = sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
|
| &cktrue,sizeof(CK_BBOOL));
|
| }
|
|
|
| - /* Perform FIPS 140-2 pairwise consistency check. */
|
| - crv = sftk_PairwiseConsistencyCheck(hSession,
|
| - publicKey, privateKey, key_type);
|
| + if (crv == CKR_OK) {
|
| + /* Perform FIPS 140-2 pairwise consistency check. */
|
| + crv = sftk_PairwiseConsistencyCheck(hSession,
|
| + publicKey, privateKey, key_type);
|
| + if (crv != CKR_OK) {
|
| + if (sftk_audit_enabled) {
|
| + char msg[128];
|
| + PR_snprintf(msg,sizeof msg,
|
| + "C_GenerateKeyPair(hSession=0x%08lX, "
|
| + "pMechanism->mechanism=0x%08lX)=0x%08lX "
|
| + "self-test: pair-wise consistency test failed",
|
| + (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
|
| + (PRUint32)crv);
|
| + sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
|
| + }
|
| + return crv;
|
| + }
|
| + }
|
| +
|
| if (crv != CKR_OK) {
|
| NSC_DestroyObject(hSession,publicKey->handle);
|
| sftk_FreeObject(publicKey);
|
| NSC_DestroyObject(hSession,privateKey->handle);
|
| sftk_FreeObject(privateKey);
|
| - if (sftk_audit_enabled) {
|
| - char msg[128];
|
| - PR_snprintf(msg,sizeof msg,
|
| - "C_GenerateKeyPair(hSession=0x%08lX, "
|
| - "pMechanism->mechanism=0x%08lX)=0x%08lX "
|
| - "self-test: pair-wise consistency test failed",
|
| - (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
|
| - (PRUint32)crv);
|
| - sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
|
| - }
|
| - return crv;
|
| }
|
|
|
| *phPrivateKey = privateKey->handle;
|
|
|