Commit 888f7ca4 authored by Robert Relyea's avatar Robert Relyea

Bug 1697303 NSS needs to update it's csp clearing to FIPS 180-3 standards.

FIPS 180-3 updated the standard for clearing sensitive key material in FIPS modules. I've done a complete review of the portions of NSS affected by the FIPS requirements and identified all the areas where we need to update. The report is available here: https://docs.google.com/document/d/1v9kedUiwVYYIUagyT_vQdtrktjGUrA3SFsVP-LA6vOw/edit?usp=sharing

This patch does the following:
    - Clears the stack in gcm and ecc to deal with large stack leakages.
This only happens in FIPS enabled case. The size of the stack is based on the
size of the leakage, with some extra to make sure we reach down into that area.
Most of the leakage happens in either auto generated code or machine dependent
acceleration code.
    - Clears hash related data that wasn't cleared previously
    - Clears public key exponents that wasn't cleared previously.
    - Clears components that should have been cleared previously but wasn't.

Usually clearing takes one of the following forms:
    PORT_Free(x) -> PORT_Free(x, size). This means we need to know what
the size is supposed to be. In some cases we need to add code to preserve
the size.
    PORT_Free(x.data) -> SECITEM_ZfreeItem(&x, PR_FALSE). In this case x is
a SECITEM, which carries the length. PR_FALSE means clear and free the data in
the item, not the item itself. The code should have had SECITEM_FreeItem before
anyway.
    SECIEM_FreeItem(item, bool) -> SECITEM_ZfreeItem(item, bool). Simply change
the normal SECITEM free call to the one that clears the item.
    PR_ArenaFree(arena, PR_FALSE) -> PR_ArenaFree(arena, PR_TRUE). The bool here
means whether or not to clear as well as free the data in the arena.
    PORT_Memset(value, 0, size). This the obvious clear operation. It happens
if the variable is a stack variable, or if the memory isn't cleared with one
of the three clearing functions above.

In addition this patch fixes the following:
    - moves the determination if whether or not a slot is in FIPS mode by
slotID to a macro. NSS allows user defined slots to be opened. If you open a
user defined slot using the FIPS slot, the resulting slots will also be FIPS
slots. In areas where the semantics change based on the slot, these slots should
have the FIPS semantics. Directly checking if the slot is the FIPS slot now
only happens when we really mean the main FIPS slot and not just any FIPS slot.
    - In handling the clearing of PSS and OAEP, I identified an issue. These
functions where holding a pointer to the pMechanismParams in their C_XXXXInit
calls for later use in the C_XXXXUpdate/C_XXXXFinal/C_XXXX calls. The problem
is applications are allowed to free their pMechanismParams once C_XXXXInit is
complete. We need to make a copy of the params to use them.

Differential Revision: https://phabricator.services.mozilla.com/D108223

--HG--
extra : rebase_source : 7ac6f9d40bffbaf1a45e9e0996893afe618d4fc5
parent f945d56b
......@@ -98,4 +98,14 @@ PRBool arm_sha1_support();
PRBool arm_sha2_support();
PRBool ppc_crypto_support();
#ifdef NSS_FIPS_DISABLED
#define BLAPI_CLEAR_STACK(stack_size)
#else
#define BLAPI_CLEAR_STACK(stack_size) \
{ \
volatile char _stkclr[stack_size]; \
PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
}
#endif
#endif /* _BLAPII_H_ */
......@@ -145,6 +145,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
requested_bytes += hash_return_len;
no_of_bytes_to_return -= hash_return_len;
}
SHA256_DestroyContext(&ctx, PR_FALSE);
return SECSuccess;
}
......@@ -197,6 +198,7 @@ prng_initEntropy(void)
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
sizeof(globalrng->previousEntropyHash));
PORT_Memset(block, 0, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
return PR_SUCCESS;
}
......@@ -244,6 +246,7 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
}
out:
PORT_Memset(hash, 0, sizeof hash);
PORT_Memset(block, 0, sizeof block);
return rv;
}
......@@ -388,6 +391,7 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
* This increments data if no_of_returned_bytes is not zero */
carry = no_of_returned_bytes;
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
SHA256_DestroyContext(&ctx, PR_FALSE);
}
PORT_Memset(data, 0, sizeof data);
PORT_Memset(thisHash, 0, sizeof thisHash);
......@@ -430,6 +434,7 @@ prng_generateNewBytes(RNGContext *rng,
SHA256_End(&ctx, w, NULL, sizeof w);
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
PORT_Memset(w, 0, sizeof w);
SHA256_DestroyContext(&ctx, PR_FALSE);
#undef w
}
......@@ -450,6 +455,7 @@ prng_generateNewBytes(RNGContext *rng,
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
/* if the prng failed, don't return any output, signal softoken */
PORT_Memset(H, 0, sizeof H);
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
......
......@@ -260,7 +260,7 @@ DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
PORT_SetError(SEC_ERROR_NEED_RANDOM);
loser:
if (arena != NULL) {
SECITEM_FreeItem(seed, PR_FALSE);
SECITEM_ZfreeItem(seed, PR_FALSE);
}
return SECFailure;
}
......@@ -295,7 +295,7 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
rv = dsa_NewKeyExtended(params, &seed, privKey);
}
}
SECITEM_FreeItem(&seed, PR_FALSE);
SECITEM_ZfreeItem(&seed, PR_FALSE);
return rv;
}
......@@ -403,6 +403,8 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
CHECK_MPI_OK(mp_exptmod(&g, &t, &p, &r)); /* r = g**t mod p */
/* r is now g**(k+q*fuzz) == g**k mod p */
CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q */
/* make sure fuzz is cleared off the stack and not optimized away */
*(volatile mp_digit *)&fuzz = 0;
/*
** FIPS 186-1, Section 5, Step 2
......@@ -415,14 +417,14 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
goto cleanup;
}
SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
SECITEM_FreeItem(&t2, PR_FALSE);
SECITEM_ZfreeItem(&t2, PR_FALSE);
if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
rv = SECFailure;
goto cleanup;
}
SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */
SECITEM_FreeItem(&t2, PR_FALSE);
SECITEM_ZfreeItem(&t2, PR_FALSE);
/* Using mp_invmod on k directly would leak bits from k. */
CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */
......@@ -530,6 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
PORT_Memset(kSeed, 0, sizeof kSeed);
return rv;
}
......@@ -670,6 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
verified = SECSuccess; /* Signature verified. */
}
cleanup:
PORT_Memset(localDigestData, 0, sizeof localDigestData);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
......
......@@ -7,6 +7,7 @@
#endif
#include "blapi.h"
#include "blapii.h"
#include "prerr.h"
#include "secerr.h"
#include "secmpi.h"
......@@ -146,6 +147,10 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
CHECK_MPI_OK(ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy));
}
/* our ECC codes uses large stack variables to store intermediate results,
* clear our stack before returning to prevent CSP leakage */
BLAPI_CLEAR_STACK(2048)
/* Construct the SECItem representation of point Q */
pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK(mp_to_fixlen_octets(&Qx, pointQ->data + 1,
......@@ -531,7 +536,6 @@ ECDH_Derive(SECItem *publicValue,
unsigned int len = 0;
SECItem pointQ = { siBuffer, NULL, 0 };
mp_int k; /* to hold the private value */
mp_int cofactor;
mp_err err = MP_OKAY;
#if EC_DEBUG
int i;
......@@ -596,11 +600,13 @@ ECDH_Derive(SECItem *publicValue,
(mp_size)privateValue->len));
if (withCofactor && (ecParams->cofactor != 1)) {
mp_int cofactor;
/* multiply k with the cofactor */
MP_DIGITS(&cofactor) = 0;
CHECK_MPI_OK(mp_init(&cofactor));
mp_set(&cofactor, ecParams->cofactor);
CHECK_MPI_OK(mp_mul(&k, &cofactor, &k));
mp_clear(&cofactor);
}
/* Multiply our private key and peer's public point */
......@@ -858,7 +864,7 @@ cleanup:
mp_clear(&ar);
if (t2) {
PORT_Free(t2);
PORT_ZFree(t2, 2 * ecParams->order.len);
}
if (kGpoint.data) {
......
......@@ -192,7 +192,7 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
mp_int raz4;
mp_int scratch[MAX_SCRATCH];
signed char *naf = NULL;
int i, orderBitSize;
int i, orderBitSize = 0;
MP_DIGITS(&rz) = 0;
MP_DIGITS(&raz4) = 0;
......@@ -289,6 +289,9 @@ CLEANUP:
mp_clear(&tpy);
mp_clear(&rz);
mp_clear(&raz4);
if (naf) {
memset(naf, 0, orderBitSize + 1);
}
free(naf);
return res;
}
......@@ -593,15 +593,19 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
if (rv != SECSuccess) {
goto loser;
}
PORT_Memset(H, 0, AES_BLOCK_SIZE);
gcm->ctr_context_init = PR_TRUE;
return gcm;
loser:
PORT_Memset(H, 0, AES_BLOCK_SIZE);
if (ghash && ghash->mem) {
PORT_Free(ghash->mem);
void *mem = ghash->mem;
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
PORT_Free(mem);
}
if (gcm) {
PORT_Free(gcm);
PORT_ZFree(gcm, sizeof(GCMContext));
}
return NULL;
}
......@@ -675,9 +679,11 @@ gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
goto loser;
}
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
return SECSuccess;
loser:
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
if (freeCtr) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
......@@ -687,13 +693,15 @@ loser:
void
GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
{
/* these two are statically allocated and will be freed when we free
void *mem = gcm->ghash_context->mem;
/* ctr_context is statically allocated and will be freed when we free
* gcm. call their destroy functions to free up any locally
* allocated data (like mp_int's) */
if (gcm->ctr_context_init) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
PORT_Free(gcm->ghash_context->mem);
PORT_Memset(gcm->ghash_context, 0, sizeof(gcmHashContext));
PORT_Free(mem);
PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
if (freeit) {
......
......@@ -274,6 +274,11 @@ MAC(unsigned char *mdOut,
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
hashObj->destroy(mdState, PR_TRUE);
PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
PORT_Memset(hmacPad, 0, sizeof hmacPad);
PORT_Memset(firstBlock, 0, sizeof firstBlock);
PORT_Memset(macOut, 0, sizeof macOut);
return SECSuccess;
}
......
......@@ -1006,7 +1006,11 @@ CLEANUP:
mp_clear(&accum[2]);
mp_clear(&accum[3]);
mp_clear(&tmp);
/* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
/* zero required by FIPS here, can't use PORT_ZFree
* because mpi doesn't link with util */
if (powers) {
PORT_Memset(powers, 0, num_powers * sizeof(mp_digit));
}
free(powersArray);
return res;
}
......
......@@ -711,7 +711,7 @@ cleanup:
if (rv == SECFailure) {
mp_zero(prime);
if (prime_seed->data) {
SECITEM_FreeItem(prime_seed, PR_FALSE);
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
}
*prime_gen_counter = 0;
}
......@@ -867,7 +867,7 @@ cleanup:
if (rv == SECFailure) {
mp_zero(prime);
if (prime_seed->data) {
SECITEM_FreeItem(prime_seed, PR_FALSE);
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
}
*prime_gen_counter = 0;
}
......@@ -905,6 +905,7 @@ findQfromSeed(
*typePtr = FIPS186_1_TYPE;
return SECSuccess;
}
mp_zero(Q_);
return SECFailure;
}
/* 1024 could use FIPS186_1 or FIPS186_3 algorithms, we need to try
......@@ -954,21 +955,23 @@ findQfromSeed(
if ((offset < 0) ||
(PORT_Memcmp(&seed->data[offset], qseed.data, qseed.len) != 0)) {
/* we found q, but the seeds don't match. This isn't an
* accident, someone has been tweeking with the seeds, just
* fail a this point. */
* accident, someone has been tweeking with the seeds, just
* fail a this point. */
SECITEM_FreeItem(&qseed, PR_FALSE);
mp_zero(Q_);
return SECFailure;
}
*qseed_len = qseed.len;
*hashtypePtr = hashtype;
*typePtr = FIPS186_3_ST_TYPE;
*qgen_counter = count;
SECITEM_FreeItem(&qseed, PR_FALSE);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
return SECSuccess;
}
SECITEM_FreeItem(&qseed, PR_FALSE);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
}
/* no hash algorithms found which match seed to Q, fail */
mp_zero(Q_);
return SECFailure;
}
......@@ -1069,6 +1072,7 @@ makePfromQandSeed(
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
cleanup:
PORT_Memset(V_j, 0, sizeof V_j);
mp_clear(&W);
mp_clear(&X);
mp_clear(&c);
......@@ -1077,8 +1081,12 @@ cleanup:
mp_clear(&tmp);
if (err) {
MP_TO_SEC_ERROR(err);
mp_zero(P);
return SECFailure;
}
if (rv != SECSuccess) {
mp_zero(P);
}
return rv;
}
......@@ -1128,6 +1136,9 @@ cleanup:
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv != SECSuccess) {
mp_zero(G);
}
return rv;
}
......@@ -1534,10 +1545,10 @@ generate_G:
*pVfy = verify;
cleanup:
if (pseed.data) {
PORT_Free(pseed.data);
SECITEM_ZfreeItem(&pseed, PR_FALSE);
}
if (qseed.data) {
PORT_Free(qseed.data);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
}
mp_clear(&P);
mp_clear(&Q);
......@@ -1558,7 +1569,7 @@ cleanup:
}
}
if (hit.data) {
SECITEM_FreeItem(&hit, PR_FALSE);
SECITEM_ZfreeItem(&hit, PR_FALSE);
}
return rv;
}
......@@ -1869,7 +1880,7 @@ cleanup:
mp_clear(&r);
mp_clear(&h);
if (pseed_.data) {
SECITEM_FreeItem(&pseed_, PR_FALSE);
SECITEM_ZfreeItem(&pseed_, PR_FALSE);
}
if (err) {
MP_TO_SEC_ERROR(err);
......@@ -1887,11 +1898,11 @@ PQG_DestroyParams(PQGParams *params)
if (params == NULL)
return;
if (params->arena != NULL) {
PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
PORT_FreeArena(params->arena, PR_TRUE);
} else {
SECITEM_FreeItem(&params->prime, PR_FALSE); /* don't free prime */
SECITEM_FreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
SECITEM_FreeItem(&params->base, PR_FALSE); /* don't free base */
SECITEM_ZfreeItem(&params->prime, PR_FALSE); /* don't free prime */
SECITEM_ZfreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
SECITEM_ZfreeItem(&params->base, PR_FALSE); /* don't free base */
PORT_Free(params);
}
}
......@@ -1906,10 +1917,10 @@ PQG_DestroyVerify(PQGVerify *vfy)
if (vfy == NULL)
return;
if (vfy->arena != NULL) {
PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
PORT_FreeArena(vfy->arena, PR_TRUE);
} else {
SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
SECITEM_ZfreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
SECITEM_ZfreeItem(&vfy->h, PR_FALSE); /* don't free h */
PORT_Free(vfy);
}
}
......@@ -957,6 +957,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
} else {
rijndael_invkey_expansion(cx, key, Nk);
}
BLAPI_CLEAR_STACK(256)
}
cx->worker_cx = cx;
cx->destroy = NULL;
......@@ -1118,6 +1119,7 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
/* Check args */
SECStatus rv;
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
......@@ -1152,8 +1154,10 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
}
#endif
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}
/*
......@@ -1167,6 +1171,7 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
SECStatus rv;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
......@@ -1181,8 +1186,10 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
return SECFailure;
}
*outputLen = inputLen;
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}
/*
......@@ -1197,6 +1204,7 @@ AES_AEAD(AESContext *cx, unsigned char *output,
void *params, unsigned int paramsLen,
const unsigned char *aad, unsigned int aadLen)
{
SECStatus rv;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0) || (aad == NULL && aadLen != 0) || params == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
......@@ -1232,7 +1240,9 @@ AES_AEAD(AESContext *cx, unsigned char *output,
}
#endif
return (*cx->worker_aead)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, params, paramsLen, aad, aadLen,
AES_BLOCK_SIZE);
rv = (*cx->worker_aead)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, params, paramsLen, aad, aadLen,
AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}
......@@ -1593,7 +1593,7 @@ RSA_Cleanup(void)
mp_clear(&bp->f);
mp_clear(&bp->g);
}
SECITEM_FreeItem(&rsabp->modulus, PR_FALSE);
SECITEM_ZfreeItem(&rsabp->modulus, PR_FALSE);
PORT_Free(rsabp);
}
......
......@@ -147,7 +147,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
padLen = modulusLen - data->len - 3;
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}
PORT_Memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
......@@ -176,7 +176,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
padLen = modulusLen - (data->len + 3);
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}
j = modulusLen - 2;
......@@ -205,7 +205,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
}
}
if (rv != SECSuccess) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
......@@ -216,7 +216,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
default:
PORT_Assert(0);
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}
......
......@@ -18,6 +18,7 @@
#include "hasht.h"
#include "pqg.h"
#include "blapii.h"
#include "secitem.h"
#ifndef NSS_FIPS_DISABLED
......@@ -494,6 +495,8 @@ blapi_SHVerifyFile(const char *shName, PRBool self)
#endif /* DEBUG_SHVERIFY */
loser:
PORT_Memset(buf, 0, sizeof buf);
PORT_Memset(hashBuf, 0, sizeof hashBuf);
if (checkName != NULL) {
PORT_Free(checkName);
}
......@@ -509,19 +512,19 @@ loser:
}
}
if (signature.data != NULL) {
PORT_Free(signature.data);
SECITEM_ZfreeItem(&signature, PR_FALSE);
}
if (key.params.prime.data != NULL) {
PORT_Free(key.params.prime.data);
SECITEM_ZfreeItem(&key.params.prime, PR_FALSE);
}
if (key.params.subPrime.data != NULL) {
PORT_Free(key.params.subPrime.data);
SECITEM_ZfreeItem(&key.params.subPrime, PR_FALSE);
}
if (key.params.base.data != NULL) {
PORT_Free(key.params.base.data);
SECITEM_ZfreeItem(&key.params.base, PR_FALSE);
}
if (key.publicValue.data != NULL) {
PORT_Free(key.publicValue.data);
SECITEM_ZfreeItem(&key.publicValue, PR_FALSE);
}
return result;
......
......@@ -22,6 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
PORT_Memset(bytes, 0, sizeof bytes);
}
size_t
......
......@@ -650,7 +650,7 @@ FC_GetMechanismList(CK_SLOT_ID slotID,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */
......@@ -666,7 +666,7 @@ FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */
......@@ -682,7 +682,7 @@ FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */
......
......@@ -220,7 +220,7 @@ void
nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
if (pubk && pubk->arena) {
PORT_FreeArena(pubk->arena, PR_FALSE);
PORT_FreeArena(pubk->arena, PR_TRUE);
}
}
unsigned
......@@ -310,7 +310,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue);
SECITEM_FreeItem(&publicValue, PR_FALSE);
SECITEM_ZfreeItem(&publicValue, PR_FALSE);
if (rv != SECSuccess) {
break;
}
......@@ -349,7 +349,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue);
SECITEM_FreeItem(&publicValue, PR_FALSE);
SECITEM_ZfreeItem(&publicValue, PR_FALSE);
if (rv != SECSuccess) {
break;
}
......@@ -394,7 +394,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
......
......@@ -164,11 +164,11 @@ nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
}
if (pre_hash != NULL) {
SECITEM_FreeItem(pre_hash, PR_TRUE);
SECITEM_ZfreeItem(pre_hash, PR_TRUE);
}
if ((rv != SECSuccess) && (hash != NULL)) {
SECITEM_FreeItem(hash, PR_TRUE);
SECITEM_ZfreeItem(hash, PR_TRUE);
hash = NULL;
}
......@@ -297,7 +297,7 @@ nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
if (hash != newHash)
SECITEM_FreeItem(hash, PR_TRUE);
SECITEM_ZfreeItem(hash, PR_TRUE);
return newHash;
}
......@@ -403,7 +403,7 @@ loser:
PORT_ZFree(T, hLen);
}
if (rv != SECSuccess) {
SECITEM_FreeItem(result, PR_TRUE);
SECITEM_ZfreeItem(result, PR_TRUE);
result = NULL;
} else {
result->len = dkLen;
......@@ -598,7 +598,7 @@ sftk_clearPBECommonCacheItemsLocked(KDFCacheItem *item)
item->hash = NULL;
}
if (item->salt) {
SECITEM_FreeItem(item->salt, PR_TRUE);
SECITEM_ZfreeItem(item->salt, PR_TRUE);
item->salt = NULL;
}
if (item->pwItem) {
......@@ -1159,6 +1159,7 @@ nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
}
loser:
PORT_Memset(&pbev2_param, 0, sizeof(pbev2_param));
if (rv == SECSuccess) {
pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
} else {
......@@ -1177,7 +1178,7 @@ void
nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
{
if (pbe_param != NULL) {
PORT_FreeArena(pbe_param->poolp, PR_FALSE);
PORT_FreeArena(pbe_param->poolp, PR_TRUE);
}
}
......@@ -1213,7 +1214,7 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
dummy = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, DES_BLOCK_SIZE);
if (dummy == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)dummy;
......@@ -1247,13 +1248,13 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
loser:
if (crv != CKR_OK) {
if (dest != NULL) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
}
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
......@@ -1289,7 +1290,7 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
dummy = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, AES_BLOCK_SIZE);
if (dummy == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)dummy;
......@@ -1322,13 +1323,13 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
loser:
if (crv != CKR_OK) {
if (dest != NULL) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
}
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
......@@ -1364,7 +1365,7 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de
dummy = CBC_PadBuffer(NULL, dup_src->data,