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; |