diff options
-rw-r--r-- | lib/freebl/blapii.h | 10 | ||||
-rw-r--r-- | lib/freebl/drbg.c | 6 | ||||
-rw-r--r-- | lib/freebl/dsa.c | 12 | ||||
-rw-r--r-- | lib/freebl/ec.c | 10 | ||||
-rw-r--r-- | lib/freebl/ecl/ecp_jm.c | 5 | ||||
-rw-r--r-- | lib/freebl/gcm.c | 16 | ||||
-rw-r--r-- | lib/freebl/hmacct.c | 5 | ||||
-rw-r--r-- | lib/freebl/mpi/mpmontg.c | 6 | ||||
-rw-r--r-- | lib/freebl/pqg.c | 45 | ||||
-rw-r--r-- | lib/freebl/rijndael.c | 24 | ||||
-rw-r--r-- | lib/freebl/rsa.c | 2 | ||||
-rw-r--r-- | lib/freebl/rsapkcs.c | 8 | ||||
-rw-r--r-- | lib/freebl/shvfy.c | 13 | ||||
-rw-r--r-- | lib/freebl/unix_urandom.c | 1 | ||||
-rw-r--r-- | lib/softoken/fipstokn.c | 6 | ||||
-rw-r--r-- | lib/softoken/lowkey.c | 8 | ||||
-rw-r--r-- | lib/softoken/lowpbe.c | 39 | ||||
-rw-r--r-- | lib/softoken/pkcs11.c | 21 | ||||
-rw-r--r-- | lib/softoken/pkcs11c.c | 467 | ||||
-rw-r--r-- | lib/softoken/pkcs11i.h | 33 | ||||
-rw-r--r-- | lib/softoken/pkcs11u.c | 21 | ||||
-rw-r--r-- | lib/softoken/sftkdb.c | 33 | ||||
-rw-r--r-- | lib/softoken/sftkhmac.c | 6 | ||||
-rw-r--r-- | lib/softoken/sftkike.c | 4 | ||||
-rw-r--r-- | lib/softoken/sftkpwd.c | 15 | ||||
-rw-r--r-- | lib/softoken/tlsprf.c | 2 | ||||
-rw-r--r-- | lib/util/secalgid.c | 2 | ||||
-rw-r--r-- | lib/util/secdig.c | 2 |
28 files changed, 466 insertions, 356 deletions
diff --git a/lib/freebl/blapii.h b/lib/freebl/blapii.h index e3177097f..7db57cdb0 100644 --- a/lib/freebl/blapii.h +++ b/lib/freebl/blapii.h @@ -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_ */ diff --git a/lib/freebl/drbg.c b/lib/freebl/drbg.c index 85e9e61b6..3ed1751c3 100644 --- a/lib/freebl/drbg.c +++ b/lib/freebl/drbg.c @@ -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); diff --git a/lib/freebl/dsa.c b/lib/freebl/dsa.c index 389c9de24..b81d9a370 100644 --- a/lib/freebl/dsa.c +++ b/lib/freebl/dsa.c @@ -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); diff --git a/lib/freebl/ec.c b/lib/freebl/ec.c index 7f4e903a0..73a625a69 100644 --- a/lib/freebl/ec.c +++ b/lib/freebl/ec.c @@ -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) { diff --git a/lib/freebl/ecl/ecp_jm.c b/lib/freebl/ecl/ecp_jm.c index bd13fa050..799842171 100644 --- a/lib/freebl/ecl/ecp_jm.c +++ b/lib/freebl/ecl/ecp_jm.c @@ -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; } diff --git a/lib/freebl/gcm.c b/lib/freebl/gcm.c index c2cc18d91..ac461b488 100644 --- a/lib/freebl/gcm.c +++ b/lib/freebl/gcm.c @@ -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) { diff --git a/lib/freebl/hmacct.c b/lib/freebl/hmacct.c index fac323e85..a1b2ba35a 100644 --- a/lib/freebl/hmacct.c +++ b/lib/freebl/hmacct.c @@ -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; } diff --git a/lib/freebl/mpi/mpmontg.c b/lib/freebl/mpi/mpmontg.c index 3acdc9fef..79104f7b9 100644 --- a/lib/freebl/mpi/mpmontg.c +++ b/lib/freebl/mpi/mpmontg.c @@ -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; } diff --git a/lib/freebl/pqg.c b/lib/freebl/pqg.c index 626b2fb85..1b03278a2 100644 --- a/lib/freebl/pqg.c +++ b/lib/freebl/pqg.c @@ -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(¶ms->prime, PR_FALSE); /* don't free prime */ - SECITEM_FreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */ - SECITEM_FreeItem(¶ms->base, PR_FALSE); /* don't free base */ + SECITEM_ZfreeItem(¶ms->prime, PR_FALSE); /* don't free prime */ + SECITEM_ZfreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */ + SECITEM_ZfreeItem(¶ms->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); } } diff --git a/lib/freebl/rijndael.c b/lib/freebl/rijndael.c index 449557cbe..546731f9d 100644 --- a/lib/freebl/rijndael.c +++ b/lib/freebl/rijndael.c @@ -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; } diff --git a/lib/freebl/rsa.c b/lib/freebl/rsa.c index a08636de6..5a4e4096f 100644 --- a/lib/freebl/rsa.c +++ b/lib/freebl/rsa.c @@ -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); } diff --git a/lib/freebl/rsapkcs.c b/lib/freebl/rsapkcs.c index 0bf1f97cb..469db3fef 100644 --- a/lib/freebl/rsapkcs.c +++ b/lib/freebl/rsapkcs.c @@ -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; } diff --git a/lib/freebl/shvfy.c b/lib/freebl/shvfy.c index 98db4614b..da42467fd 100644 --- a/lib/freebl/shvfy.c +++ b/lib/freebl/shvfy.c @@ -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; diff --git a/lib/freebl/unix_urandom.c b/lib/freebl/unix_urandom.c index 720fa80bb..73006cdbb 100644 --- a/lib/freebl/unix_urandom.c +++ b/lib/freebl/unix_urandom.c @@ -22,6 +22,7 @@ RNG_SystemInfoForRNG(void) return; } RNG_RandomUpdate(bytes, numBytes); + PORT_Memset(bytes, 0, sizeof bytes); } size_t diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c index 6ffec5de1..1dabc59e2 100644 --- a/lib/softoken/fipstokn.c +++ b/lib/softoken/fipstokn.c @@ -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 */ diff --git a/lib/softoken/lowkey.c b/lib/softoken/lowkey.c index e9bbff1d9..1eba1ad8f 100644 --- a/lib/softoken/lowkey.c +++ b/lib/softoken/lowkey.c @@ -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; } diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c index 0d8e02ddf..2ce6c415e 100644 --- a/lib/softoken/lowpbe.c +++ b/lib/softoken/lowpbe.c @@ -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, 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; @@ -1398,13 +1399,13 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de 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; @@ -1438,7 +1439,7 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy, v = CBC_PadBuffer(NULL, dup_src->data, dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */); if (v == NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); + SECITEM_ZfreeItem(dup_src, PR_TRUE); return NULL; } dup_src->data = (unsigned char *)v; @@ -1478,12 +1479,12 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy, } if ((rv != SECSuccess) && (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; @@ -1521,7 +1522,7 @@ sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op, } if ((rv != SECSuccess) && (dest)) { - SECITEM_FreeItem(dest, PR_TRUE); + SECITEM_ZfreeItem(dest, PR_TRUE); dest = NULL; } diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c index 33dacc6da..ba17298a9 100644 --- a/lib/softoken/pkcs11.c +++ b/lib/softoken/pkcs11.c @@ -1177,7 +1177,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP crv = sftk_forceAttribute(object, CKA_NSS_DB, sftk_item_expand(&mod)); if (mod.data) - PORT_Free(mod.data); + SECITEM_ZfreeItem(&mod, PR_FALSE); if (crv != CKR_OK) return crv; @@ -1497,7 +1497,7 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object) case CKO_SECRET_KEY: /* make sure the required fields exist */ return sftk_handleSecretKeyObject(session, object, key_type, - (PRBool)(session->slot->slotID == FIPS_SLOT_ID)); + (PRBool)(sftk_isFIPS(session->slot->slotID))); default: break; } @@ -1939,7 +1939,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, } *crvp = crv; if (crv != CKR_OK) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); return NULL; } @@ -2099,7 +2099,7 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) } *crvp = crv; if (crv != CKR_OK) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); return NULL; } return privKey; @@ -2604,7 +2604,7 @@ static PLHashTable *nscSlotHashTable[2] = { NULL, NULL }; static unsigned int sftk_GetModuleIndex(CK_SLOT_ID slotID) { - if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) { + if (sftk_isFIPS(slotID)) { return NSC_FIPS_MODULE; } return NSC_NON_FIPS_MODULE; @@ -4031,6 +4031,7 @@ NSC_InitPIN(CK_SESSION_HANDLE hSession, if (tokenRemoved) { sftk_CloseAllSessions(slot, PR_FALSE); } + PORT_Memset(newPinStr, 0, ulPinLen); sftk_freeDB(handle); handle = NULL; @@ -4122,10 +4123,12 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, /* change the data base password */ PR_Lock(slot->pwCheckLock); rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved); + PORT_Memset(newPinStr, 0, ulNewLen); + PORT_Memset(oldPinStr, 0, ulOldLen); if (tokenRemoved) { sftk_CloseAllSessions(slot, PR_FALSE); } - if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) { + if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID))) { PR_Sleep(loginWaitTime); } PR_Unlock(slot->pwCheckLock); @@ -4361,6 +4364,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, handle = sftk_getKeyDB(slot); if (handle == NULL) { + PORT_Memset(pinStr, 0, ulPinLen); return CKR_USER_TYPE_INVALID; } @@ -4375,7 +4379,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, * key database */ if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION)) /* fips always needs to authenticate, even if there isn't a db */ - || (slot->slotID == FIPS_SLOT_ID)) { + || (sftk_isFIPS(slot->slotID))) { /* should this be a fixed password? */ if (ulPinLen == 0) { sftkdb_ClearPassword(handle); @@ -4406,7 +4410,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, if (tokenRemoved) { sftk_CloseAllSessions(slot, PR_FALSE); } - if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) { + if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID))) { PR_Sleep(loginWaitTime); } PR_Unlock(slot->pwCheckLock); @@ -4427,6 +4431,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, crv = CKR_PIN_INCORRECT; done: + PORT_Memset(pinStr, 0, ulPinLen); if (handle) { sftk_freeDB(handle); } diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c index 9709f4339..977880ed2 100644 --- a/lib/softoken/pkcs11c.c +++ b/lib/softoken/pkcs11c.c @@ -103,6 +103,13 @@ sftk_Space(void *data, PRBool freeit) PORT_Free(data); } +static void +sftk_ZSpace(void *data, PRBool freeit) +{ + size_t len = *(size_t *)data; + PORT_ZFree(data, len); +} + /* * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by * Deprecating a full des key to 40 bit key strenth. @@ -117,6 +124,7 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) unsigned int leng, i; DESContext *descx; SECStatus rv; + CK_RV crv = CKR_OK; /* zero the parity bits */ for (i = 0; i < 8; i++) { @@ -125,12 +133,16 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) /* encrypt with key 1 */ descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE); - if (descx == NULL) - return CKR_HOST_MEMORY; + if (descx == NULL) { + crv = CKR_HOST_MEMORY; + goto done; + } rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8); DES_DestroyContext(descx, PR_TRUE); - if (rv != SECSuccess) - return sftk_MapCryptError(PORT_GetError()); + if (rv != SECSuccess) { + crv = sftk_MapCryptError(PORT_GetError()); + goto done; + } /* xor source with des, zero the parity bits and deprecate the key*/ for (i = 0; i < 8; i++) { @@ -143,16 +155,23 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) /* encrypt with key 2 */ descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE); - if (descx == NULL) - return CKR_HOST_MEMORY; + if (descx == NULL) { + crv = CKR_HOST_MEMORY; + goto done; + } rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8); DES_DestroyContext(descx, PR_TRUE); - if (rv != SECSuccess) - return sftk_MapCryptError(PORT_GetError()); + if (rv != SECSuccess) { + crv = sftk_MapCryptError(PORT_GetError()); + goto done; + } /* set the corret parity on our new des key */ sftk_FormatDESKey(deskey, 8); - return CKR_OK; +done: + PORT_Memset(enc_src, 0, sizeof enc_src); + PORT_Memset(enc_dest, 0, sizeof enc_dest); + return crv; } /* NSC_DestroyObject destroys an object. */ @@ -566,31 +585,38 @@ sftk_RSADecrypt(NSSLOWKEYPrivateKey *key, unsigned char *output, return rv; } +static void +sftk_freeRSAOAEPInfo(SFTKOAEPInfo *info, PRBool freeit) +{ + PORT_ZFree(info->params.pSourceData, info->params.ulSourceDataLen); + PORT_ZFree(info, sizeof(SFTKOAEPInfo)); +} + static SECStatus -sftk_RSAEncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output, +sftk_RSAEncryptOAEP(SFTKOAEPInfo *info, unsigned char *output, unsigned int *outputLen, unsigned int maxLen, const unsigned char *input, unsigned int inputLen) { HASH_HashType hashAlg; HASH_HashType maskHashAlg; - PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); - if (info->key->keyType != NSSLOWKEYRSAKey) { + PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey); + if (info->key.pub->keyType != NSSLOWKEYRSAKey) { PORT_SetError(SEC_ERROR_INVALID_KEY); return SECFailure; } - hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); - maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); + hashAlg = GetHashTypeFromMechanism(info->params.hashAlg); + maskHashAlg = GetHashTypeFromMechanism(info->params.mgf); - return RSA_EncryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, - (const unsigned char *)info->params->pSourceData, - info->params->ulSourceDataLen, NULL, 0, + return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg, + (const unsigned char *)info->params.pSourceData, + info->params.ulSourceDataLen, NULL, 0, output, outputLen, maxLen, input, inputLen); } static SECStatus -sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output, +sftk_RSADecryptOAEP(SFTKOAEPInfo *info, unsigned char *output, unsigned int *outputLen, unsigned int maxLen, const unsigned char *input, unsigned int inputLen) { @@ -598,18 +624,18 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output, HASH_HashType hashAlg; HASH_HashType maskHashAlg; - PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); - if (info->key->keyType != NSSLOWKEYRSAKey) { + PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey); + if (info->key.priv->keyType != NSSLOWKEYRSAKey) { PORT_SetError(SEC_ERROR_INVALID_KEY); return SECFailure; } - hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); - maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); + hashAlg = GetHashTypeFromMechanism(info->params.hashAlg); + maskHashAlg = GetHashTypeFromMechanism(info->params.mgf); - rv = RSA_DecryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, - (const unsigned char *)info->params->pSourceData, - info->params->ulSourceDataLen, + rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg, + (const unsigned char *)info->params.pSourceData, + info->params.ulSourceDataLen, output, outputLen, maxLen, input, inputLen); if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { sftk_fatalError = PR_TRUE; @@ -670,8 +696,10 @@ sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx, { ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE); if (ctx->adOverflow != NULL) { - PORT_Free(ctx->adOverflow); + PORT_ZFree(ctx->adOverflow, ctx->adLen); ctx->adOverflow = NULL; + } else { + PORT_Memset(ctx->ad, 0, ctx->adLen); } ctx->adLen = 0; if (freeit) { @@ -840,40 +868,54 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, } context->multi = PR_FALSE; context->rsa = PR_TRUE; - if (isEncrypt) { - SFTKOAEPEncryptInfo *info = PORT_New(SFTKOAEPEncryptInfo); - if (info == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - info->params = pMechanism->pParameter; - info->key = sftk_GetPubKey(key, CKK_RSA, &crv); - if (info->key == NULL) { - PORT_Free(info); - crv = CKR_KEY_HANDLE_INVALID; - break; + { + SFTKOAEPInfo *info; + CK_RSA_PKCS_OAEP_PARAMS *params = + (CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter; + /* make a copy of the source data value for future + * use (once the user has reclaimed his data in pParameter)*/ + void *newSource = NULL; + if (params->pSourceData) { + newSource = PORT_Alloc(params->ulSourceDataLen); + if (newSource == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + PORT_Memcpy(newSource, params->pSourceData, params->ulSourceDataLen); } - context->update = (SFTKCipher)sftk_RSAEncryptOAEP; - context->maxLen = nsslowkey_PublicModulusLen(info->key); - context->cipherInfo = info; - } else { - SFTKOAEPDecryptInfo *info = PORT_New(SFTKOAEPDecryptInfo); + info = PORT_New(SFTKOAEPInfo); if (info == NULL) { + PORT_ZFree(newSource, params->ulSourceDataLen); crv = CKR_HOST_MEMORY; break; } - info->params = pMechanism->pParameter; - info->key = sftk_GetPrivKey(key, CKK_RSA, &crv); - if (info->key == NULL) { - PORT_Free(info); - crv = CKR_KEY_HANDLE_INVALID; - break; + info->params = *params; + info->params.pSourceData = newSource; + info->isEncrypt = isEncrypt; + + /* now setup encryption and decryption contexts */ + if (isEncrypt) { + info->key.pub = sftk_GetPubKey(key, CKK_RSA, &crv); + if (info->key.pub == NULL) { + sftk_freeRSAOAEPInfo(info, PR_TRUE); + crv = CKR_KEY_HANDLE_INVALID; + break; + } + context->update = (SFTKCipher)sftk_RSAEncryptOAEP; + context->maxLen = nsslowkey_PublicModulusLen(info->key.pub); + } else { + info->key.priv = sftk_GetPrivKey(key, CKK_RSA, &crv); + if (info->key.priv == NULL) { + sftk_freeRSAOAEPInfo(info, PR_TRUE); + crv = CKR_KEY_HANDLE_INVALID; + break; + } + context->update = (SFTKCipher)sftk_RSADecryptOAEP; + context->maxLen = nsslowkey_PrivateModulusLen(info->key.priv); } - context->update = (SFTKCipher)sftk_RSADecryptOAEP; - context->maxLen = nsslowkey_PrivateModulusLen(info->key); context->cipherInfo = info; } - context->destroy = (SFTKDestroy)sftk_Space; + context->destroy = (SFTKDestroy)sftk_freeRSAOAEPInfo; break; #ifndef NSS_DISABLE_DEPRECATED_RC2 case CKM_RC2_CBC_PAD: @@ -2058,7 +2100,7 @@ sftk_doMACInit(CK_MECHANISM_TYPE mech, SFTKSessionContext *session, CK_RV crv; sftk_MACCtx *context; CK_ULONG *intpointer; - PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID); + PRBool isFIPS = sftk_isFIPS(key->slot->slotID); /* Set up the initial context. */ crv = sftk_MAC_Create(mech, key, &context); @@ -2146,6 +2188,7 @@ sftk_SSLMACSign(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int *sigLen, info->update(info->hashContext, hash, hashLen); info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH); PORT_Memcpy(sig, tmpBuf, info->macSize); + PORT_Memset(tmpBuf, 0, info->macSize); *sigLen = info->macSize; return SECSuccess; } @@ -2156,13 +2199,16 @@ sftk_SSLMACVerify(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int sigLen, { unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH]; unsigned int out; + int cmp; info->begin(info->hashContext); info->update(info->hashContext, info->key, info->keySize); info->update(info->hashContext, ssl_pad_2, info->padSize); info->update(info->hashContext, hash, hashLen); info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH); - return (NSS_SecureMemcmp(sig, tmpBuf, info->macSize) == 0) ? SECSuccess : SECFailure; + cmp = NSS_SecureMemcmp(sig, tmpBuf, info->macSize); + PORT_Memset(tmpBuf, 0, info->macSize); + return (cmp == 0) ? SECSuccess : SECFailure; } /* @@ -2205,6 +2251,7 @@ sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid, sftk_FreeAttribute(keyval); return CKR_HOST_MEMORY; } + sslmacinfo->size = sizeof(SFTKSSLMACInfo); sslmacinfo->macSize = mac_size; sslmacinfo->hashContext = context->hashInfo; PORT_Memcpy(sslmacinfo->key, keyval->attrib.pValue, @@ -2216,7 +2263,7 @@ sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid, sslmacinfo->padSize = padSize; sftk_FreeAttribute(keyval); context->cipherInfo = (void *)sslmacinfo; - context->destroy = (SFTKDestroy)sftk_Space; + context->destroy = (SFTKDestroy)sftk_ZSpace; context->update = (SFTKCipher)sftk_SSLMACSign; context->verify = (SFTKVerify)sftk_SSLMACVerify; context->maxLen = mac_size; @@ -2529,7 +2576,7 @@ RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, loser: SGN_DestroyDigestInfo(di); if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); } return rv; } @@ -2577,14 +2624,14 @@ sftk_RSASignRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, } static SECStatus -sftk_RSASignPSS(SFTKHashSignInfo *info, unsigned char *sig, +sftk_RSASignPSS(SFTKPSSSignInfo *info, unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, const unsigned char *hash, unsigned int hashLen) { SECStatus rv = SECFailure; HASH_HashType hashAlg; HASH_HashType maskHashAlg; - CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params; + CK_RSA_PKCS_PSS_PARAMS *params = &info->params; PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); if (info->key->keyType != NSSLOWKEYRSAKey) { @@ -2706,6 +2753,7 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, CK_RV crv = CKR_OK; NSSLOWKEYPrivateKey *privKey; SFTKHashSignInfo *info = NULL; + SFTKPSSSignInfo *pinfo = NULL; CHECK_FORK(); @@ -2814,21 +2862,22 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, crv = CKR_MECHANISM_PARAM_INVALID; break; } - info = PORT_New(SFTKHashSignInfo); - if (info == NULL) { + pinfo = PORT_New(SFTKPSSSignInfo); + if (pinfo == NULL) { crv = CKR_HOST_MEMORY; break; } - info->params = pMechanism->pParameter; - info->key = sftk_GetPrivKey(key, CKK_RSA, &crv); - if (info->key == NULL) { - PORT_Free(info); + pinfo->size = sizeof(SFTKPSSSignInfo); + pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; + pinfo->key = sftk_GetPrivKey(key, CKK_RSA, &crv); + if (pinfo->key == NULL) { + crv = CKR_KEY_TYPE_INCONSISTENT; break; } - context->cipherInfo = info; - context->destroy = (SFTKDestroy)sftk_Space; + context->cipherInfo = pinfo; + context->destroy = (SFTKDestroy)sftk_ZSpace; context->update = (SFTKCipher)sftk_RSASignPSS; - context->maxLen = nsslowkey_PrivateModulusLen(info->key); + context->maxLen = nsslowkey_PrivateModulusLen(pinfo->key); break; #define INIT_DSA_SIG_MECH(mmm) \ @@ -3059,6 +3108,8 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, if (crv != CKR_OK) { if (info) PORT_Free(info); + if (pinfo) + PORT_ZFree(pinfo, pinfo->size); sftk_FreeContext(context); sftk_FreeSession(session); return crv; @@ -3272,6 +3323,7 @@ NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate. * Keeping "too small" CK_RV intact is a standard violation, but allows * application read EXACT signature length */ + PORT_Memset(tmpbuf, 0, sizeof tmpbuf); } else { /* must be block cipher MACing */ outlen = context->macSize; @@ -3433,7 +3485,7 @@ RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key, PR_FALSE /*XXX: unsafeAllowMissingParameters*/); } - PORT_Free(pkcs1DigestInfoData); + PORT_ZFree(pkcs1DigestInfoData, bufferSize); return rv; } @@ -3466,13 +3518,13 @@ sftk_RSACheckSignRaw(NSSLOWKEYPublicKey *key, const unsigned char *sig, } static SECStatus -sftk_RSACheckSignPSS(SFTKHashVerifyInfo *info, const unsigned char *sig, +sftk_RSACheckSignPSS(SFTKPSSVerifyInfo *info, const unsigned char *sig, unsigned int sigLen, const unsigned char *digest, unsigned int digestLen) { HASH_HashType hashAlg; HASH_HashType maskHashAlg; - CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params; + CK_RSA_PKCS_PSS_PARAMS *params = &info->params; PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); if (info->key->keyType != NSSLOWKEYRSAKey) { @@ -3501,6 +3553,7 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, CK_RV crv = CKR_OK; NSSLOWKEYPublicKey *pubKey; SFTKHashVerifyInfo *info = NULL; + SFTKPSSVerifyInfo *pinfo = NULL; CHECK_FORK(); @@ -3552,16 +3605,12 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, context->verify = (SFTKVerify)sftk_RSACheckSignRaw; finish_rsa: if (key_type != CKK_RSA) { - if (info) - PORT_Free(info); crv = CKR_KEY_TYPE_INCONSISTENT; break; } context->rsa = PR_TRUE; pubKey = sftk_GetPubKey(key, CKK_RSA, &crv); if (pubKey == NULL) { - if (info) - PORT_Free(info); crv = CKR_KEY_TYPE_INCONSISTENT; break; } @@ -3592,19 +3641,20 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, crv = CKR_MECHANISM_PARAM_INVALID; break; } - info = PORT_New(SFTKHashVerifyInfo); - if (info == NULL) { + pinfo = PORT_New(SFTKPSSVerifyInfo); + if (pinfo == NULL) { crv = CKR_HOST_MEMORY; break; } - info->params = pMechanism->pParameter; - info->key = sftk_GetPubKey(key, CKK_RSA, &crv); - if (info->key == NULL) { - PORT_Free(info); + pinfo->size = sizeof(SFTKPSSVerifyInfo); + pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; + pinfo->key = sftk_GetPubKey(key, CKK_RSA, &crv); + if (pinfo->key == NULL) { + crv = CKR_KEY_TYPE_INCONSISTENT; break; } - context->cipherInfo = info; - context->destroy = (SFTKDestroy)sftk_Space; + context->cipherInfo = pinfo; + context->destroy = (SFTKDestroy)sftk_ZSpace; context->verify = (SFTKVerify)sftk_RSACheckSignPSS; break; @@ -3690,6 +3740,8 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, if (crv != CKR_OK) { if (info) PORT_Free(info); + if (pinfo) + PORT_ZFree(pinfo, pinfo->size); sftk_FreeContext(context); sftk_FreeSession(session); return crv; @@ -3776,6 +3828,7 @@ NSC_VerifyFinal(CK_SESSION_HANDLE hSession, if (SECSuccess != (context->verify)(context->cipherInfo, pSignature, ulSignatureLen, tmpbuf, digestLen)) crv = sftk_MapCryptError(PORT_GetError()); + PORT_Memset(tmpbuf, 0, sizeof tmpbuf); } else if (ulSignatureLen != context->macSize) { /* must be block cipher MACing */ crv = CKR_SIGNATURE_LEN_RANGE; @@ -4756,6 +4809,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession, *phKey = key->handle; } loser: + PORT_Memset(buf, 0, sizeof buf); sftk_FreeObject(key); return crv; } @@ -5055,7 +5109,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot, if (isDerivable) { SFTKAttribute *pubAttribute = NULL; CK_OBJECT_HANDLE newKey; - PRBool isFIPS = (slot->slotID == FIPS_SLOT_ID); + PRBool isFIPS = sftk_isFIPS(slot->slotID); CK_RV crv2; CK_OBJECT_CLASS secret = CKO_SECRET_KEY; CK_KEY_TYPE generic = CKK_GENERIC_SECRET; @@ -5141,8 +5195,8 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot, crv = CKR_GENERAL_ERROR; } done: - PORT_Free(subPrime.data); - PORT_Free(prime.data); + SECITEM_ZfreeItem(&subPrime, PR_FALSE); + SECITEM_ZfreeItem(&prime, PR_FALSE); } /* clean up before we return */ sftk_FreeAttribute(pubAttribute); @@ -5296,18 +5350,18 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len); if (bitSize < 2) { crv = CKR_ATTRIBUTE_VALUE_INVALID; - PORT_Free(pubExp.data); + SECITEM_ZfreeItem(&pubExp, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT, sftk_item_expand(&pubExp)); if (crv != CKR_OK) { - PORT_Free(pubExp.data); + SECITEM_ZfreeItem(&pubExp, PR_FALSE); break; } rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); - PORT_Free(pubExp.data); + SECITEM_ZfreeItem(&pubExp, PR_FALSE); if (rsaPriv == NULL) { if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { sftk_fatalError = PR_TRUE; @@ -5370,37 +5424,37 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, crv = sftk_Attribute2SSecItem(NULL, &pqgParam.subPrime, publicKey, CKA_SUBPRIME); if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); break; } crv = sftk_Attribute2SSecItem(NULL, &pqgParam.base, publicKey, CKA_BASE); if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_PRIME, sftk_item_expand(&pqgParam.prime)); if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_SUBPRIME, sftk_item_expand(&pqgParam.subPrime)); if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_BASE, sftk_item_expand(&pqgParam.base)); if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } @@ -5411,34 +5465,34 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, pqgParam.subPrime.len); if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) { crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } bitSize = sftk_GetLengthInBits(pqgParam.prime.data, pqgParam.prime.len); if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) { crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } bitSize = sftk_GetLengthInBits(pqgParam.base.data, pqgParam.base.len); if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) { crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); break; } /* Generate the key */ rv = DSA_NewKey(&pqgParam, &dsaPriv); - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); + SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); + SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { @@ -5481,41 +5535,41 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, break; crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE); if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_PRIME, sftk_item_expand(&dhParam.prime)); if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); break; } crv = sftk_AddAttributeType(privateKey, CKA_BASE, sftk_item_expand(&dhParam.base)); if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); break; } bitSize = sftk_GetLengthInBits(dhParam.prime.data, dhParam.prime.len); if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) { crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); break; } bitSize = sftk_GetLengthInBits(dhParam.base.data, dhParam.base.len); if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) { crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); break; } rv = DH_NewKey(&dhParam, &dhPriv); - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); + SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); + SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { sftk_fatalError = PR_TRUE; @@ -5557,13 +5611,13 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS, sftk_item_expand(&ecEncodedParams)); if (crv != CKR_OK) { - PORT_Free(ecEncodedParams.data); + SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); break; } /* Decode ec params before calling EC_NewKey */ rv = EC_DecodeParams(&ecEncodedParams, &ecParams); - PORT_Free(ecEncodedParams.data); + SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); if (rv != SECSuccess) { crv = sftk_MapCryptError(PORT_GetError()); break; @@ -5594,7 +5648,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, } crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, sftk_item_expand(pubValue)); - SECITEM_FreeItem(pubValue, PR_TRUE); + SECITEM_ZfreeItem(pubValue, PR_TRUE); } if (crv != CKR_OK) goto ecgn_done; @@ -6865,6 +6919,7 @@ sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo, } crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize); + PORT_Memset(tmpdata, 0, sizeof tmpdata); return crv; } @@ -7127,7 +7182,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, if (key == NULL) { return CKR_HOST_MEMORY; } - isFIPS = (slot->slotID == FIPS_SLOT_ID); + isFIPS = sftk_isFIPS(slot->slotID); /* * load the template values into the object @@ -7358,11 +7413,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter; - PORT_Memcpy(crsrdata, - ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); - if (ssl3_master->pVersion) { SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue; @@ -7383,6 +7433,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, crv = CKR_MECHANISM_PARAM_INVALID; break; } + PORT_Memcpy(crsrdata, + ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); if (isTLS) { SECStatus status; @@ -7404,6 +7458,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); } if (status != SECSuccess) { + PORT_Memset(crsrdata, 0, sizeof crsrdata); crv = CKR_FUNCTION_FAILED; break; } @@ -7411,11 +7466,13 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, /* now allocate the hash contexts */ md5 = MD5_NewContext(); if (md5 == NULL) { + PORT_Memset(crsrdata, 0, sizeof crsrdata); crv = CKR_HOST_MEMORY; break; } sha = SHA1_NewContext(); if (sha == NULL) { + PORT_Memset(crsrdata, 0, sizeof crsrdata); PORT_Free(md5); crv = CKR_HOST_MEMORY; break; @@ -7438,10 +7495,13 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, } PORT_Free(md5); PORT_Free(sha); + PORT_Memset(crsrdata, 0, sizeof crsrdata); + PORT_Memset(sha_out, 0, sizeof sha_out); } /* store the results */ crv = sftk_forceAttribute(key, CKA_VALUE, key_block, SSL3_MASTER_SECRET_LENGTH); + PORT_Memset(key_block, 0, sizeof key_block); if (crv != CKR_OK) break; keyType = CKK_GENERIC_SECRET; @@ -7560,6 +7620,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, /* Store the results */ crv = sftk_forceAttribute(key, CKA_VALUE, key_block, SSL3_MASTER_SECRET_LENGTH); + PORT_Memset(key_block, 0, sizeof key_block); break; } @@ -7572,7 +7633,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, CK_ULONG effKeySize; unsigned int block_needed; unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; - 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))) { @@ -7636,11 +7696,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata, - ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); - /* * clear out our returned keys so we can recover on failure */ @@ -7664,6 +7719,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, if (ssl3_keys->bIsExport) { MD5_DestroyContext(md5, PR_TRUE); SHA1_DestroyContext(sha, PR_TRUE); + PORT_Memset(srcrdata, 0, sizeof srcrdata); crv = CKR_MECHANISM_PARAM_INVALID; break; } @@ -7727,6 +7783,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, PORT_Assert(outLen == MD5_LENGTH); block_bytes += outLen; } + PORT_Memset(sha_out, 0, sizeof sha_out); } /* @@ -7805,6 +7862,8 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, crv = CKR_FUNCTION_FAILED; sftk_freeSSLKeys(hSession, ssl3_keys_out); } + PORT_Memset(srcrdata, 0, sizeof srcrdata); + PORT_Memset(key_block, 0, sizeof key_block); MD5_DestroyContext(md5, PR_TRUE); SHA1_DestroyContext(sha, PR_TRUE); sftk_FreeObject(key); @@ -8230,83 +8289,27 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, MD2_DestroyContext(md2, PR_TRUE); crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - case CKM_MD5_KEY_DERIVATION: - if (keySize == 0) - keySize = MD5_LENGTH; - if (keySize > MD5_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - MD5_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - case CKM_SHA1_KEY_DERIVATION: - if (keySize == 0) - keySize = SHA1_LENGTH; - if (keySize > SHA1_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - SHA1_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - - case CKM_SHA224_KEY_DERIVATION: - if (keySize == 0) - keySize = SHA224_LENGTH; - if (keySize > SHA224_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - SHA224_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - - case CKM_SHA256_KEY_DERIVATION: - if (keySize == 0) - keySize = SHA256_LENGTH; - if (keySize > SHA256_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - SHA256_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - - case CKM_SHA384_KEY_DERIVATION: - if (keySize == 0) - keySize = SHA384_LENGTH; - if (keySize > SHA384_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - SHA384_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; - - case CKM_SHA512_KEY_DERIVATION: - if (keySize == 0) - keySize = SHA512_LENGTH; - if (keySize > SHA512_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - SHA512_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); - break; + PORT_Memset(key_block, 0, MD2_LENGTH); + break; +#define DERIVE_KEY_HASH(hash) \ + case CKM_##hash##_KEY_DERIVATION: \ + if (keySize == 0) \ + keySize = hash##_LENGTH; \ + if (keySize > hash##_LENGTH) { \ + crv = CKR_TEMPLATE_INCONSISTENT; \ + break; \ + } \ + hash##_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, \ + att->attrib.ulValueLen); \ + crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); \ + PORT_Memset(key_block, 0, hash##_LENGTH); \ + break; + DERIVE_KEY_HASH(MD5) + DERIVE_KEY_HASH(SHA1) + DERIVE_KEY_HASH(SHA224) + DERIVE_KEY_HASH(SHA256) + DERIVE_KEY_HASH(SHA384) + DERIVE_KEY_HASH(SHA512) case CKM_DH_PKCS_DERIVE: { SECItem derived, dhPublic; @@ -8350,22 +8353,22 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, /* either p or q was even and therefore not prime, * we can stop processing here and fail now */ crv = CKR_ARGUMENTS_BAD; - PORT_Free(dhPrime.data); - PORT_Free(dhSubPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); break; } /* first make sure the primes are really prime */ if (!KEA_PrimeCheck(&dhPrime)) { crv = CKR_ARGUMENTS_BAD; - PORT_Free(dhPrime.data); - PORT_Free(dhSubPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); break; } if (!KEA_PrimeCheck(&dhSubPrime)) { crv = CKR_ARGUMENTS_BAD; - PORT_Free(dhPrime.data); - PORT_Free(dhSubPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); break; } if (isFIPS || !isSafe) { @@ -8377,8 +8380,8 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, * we receive the subprime value */ if (!KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime)) { crv = CKR_ARGUMENTS_BAD; - PORT_Free(dhPrime.data); - PORT_Free(dhSubPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); break; } } @@ -8386,29 +8389,29 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, /* In FIPS mode we only accept approved primes, or * primes with the full subprime value */ crv = CKR_ARGUMENTS_BAD; - PORT_Free(dhPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); break; } /* checks are complete, no need for the subPrime any longer */ - PORT_Free(dhSubPrime.data); + SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); } /* now that the prime is validated, get the private value */ crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE); if (crv != CKR_OK) { - PORT_Free(dhPrime.data); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); break; } /* calculate private value - oct */ rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); - PORT_Free(dhPrime.data); - PORT_ZFree(dhValue.data, dhValue.len); + SECITEM_ZfreeItem(&dhPrime, PR_FALSE); + SECITEM_ZfreeItem(&dhValue, PR_FALSE); if (rv == SECSuccess) { sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len); - PORT_ZFree(derived.data, derived.len); + SECITEM_ZfreeItem(&derived, PR_FALSE); crv = CKR_OK; } else crv = CKR_HOST_MEMORY; @@ -8475,7 +8478,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, withCofactor, &tmp); - PORT_ZFree(ecScalar.data, ecScalar.len); + SECITEM_ZfreeItem(&ecScalar, PR_FALSE); ecScalar.data = NULL; if (privKey != sourceKey->objectInfo) { nsslowkey_DestroyPrivateKey(privKey); @@ -8547,11 +8550,11 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, ec_loser: crv = CKR_ARGUMENTS_BAD; - PORT_Free(ecScalar.data); + SECITEM_ZfreeItem(&ecScalar, PR_FALSE); if (privKey != sourceKey->objectInfo) nsslowkey_DestroyPrivateKey(privKey); if (arena) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); } break; } diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h index 2aabb37e4..26efe158b 100644 --- a/lib/softoken/pkcs11i.h +++ b/lib/softoken/pkcs11i.h @@ -105,8 +105,9 @@ typedef struct SFTKSessionContextStr SFTKSessionContext; typedef struct SFTKSearchResultsStr SFTKSearchResults; typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo; typedef struct SFTKHashSignInfoStr SFTKHashSignInfo; -typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo; -typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo; +typedef struct SFTKOAEPInfoStr SFTKOAEPInfo; +typedef struct SFTKPSSSignInfoStr SFTKPSSSignInfo; +typedef struct SFTKPSSVerifyInfoStr SFTKPSSVerifyInfo; typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo; typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info; typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo; @@ -388,21 +389,33 @@ struct SFTKHashSignInfoStr { NSSLOWKEYPrivateKey *key; }; -/** - * Contexts for RSA-OAEP - */ -struct SFTKOAEPEncryptInfoStr { - CK_RSA_PKCS_OAEP_PARAMS *params; +struct SFTKPSSVerifyInfoStr { + size_t size; /* must be first */ + CK_RSA_PKCS_PSS_PARAMS params; NSSLOWKEYPublicKey *key; }; -struct SFTKOAEPDecryptInfoStr { - CK_RSA_PKCS_OAEP_PARAMS *params; +struct SFTKPSSSignInfoStr { + size_t size; /* must be first */ + CK_RSA_PKCS_PSS_PARAMS params; NSSLOWKEYPrivateKey *key; }; +/** + * Contexts for RSA-OAEP + */ +struct SFTKOAEPInfoStr { + CK_RSA_PKCS_OAEP_PARAMS params; + PRBool isEncrypt; + union { + NSSLOWKEYPublicKey *pub; + NSSLOWKEYPrivateKey *priv; + } key; +}; + /* context for the Final SSLMAC message */ struct SFTKSSLMACInfoStr { + size_t size; /* must be first */ void *hashContext; SFTKBegin begin; SFTKHash update; @@ -481,6 +494,8 @@ struct SFTKItemTemplateStr { /* slot helper macros */ #define sftk_SlotFromSession(sp) ((sp)->slot) #define sftk_isToken(id) (((id)&SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC) +#define sftk_isFIPS(id) \ + (((id) == FIPS_SLOT_ID) || ((id) >= SFTK_MIN_FIPS_USER_SLOT_ID)) /* the session hash multiplier (see bug 201081) */ #define SHMULTIPLIER 1791398085 diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c index 7d969a1bc..4b314f4b8 100644 --- a/lib/softoken/pkcs11u.c +++ b/lib/softoken/pkcs11u.c @@ -155,16 +155,19 @@ sftk_NewAttribute(SFTKObject *object, static void sftk_DestroyAttribute(SFTKAttribute *attribute) { - if (attribute->freeData) { - if (attribute->attrib.pValue) { - /* clear out the data in the attribute value... it may have been - * sensitive data */ - PORT_Memset(attribute->attrib.pValue, 0, - attribute->attrib.ulValueLen); + if (attribute->attrib.pValue) { + /* clear out the data in the attribute value... it may have been + * sensitive data */ + PORT_Memset(attribute->attrib.pValue, 0, attribute->attrib.ulValueLen); + if (attribute->freeData) { + PORT_Free(attribute->attrib.pValue); + attribute->attrib.pValue = NULL; + attribute->freeData = PR_FALSE; } - PORT_Free(attribute->attrib.pValue); } - PORT_Free(attribute); + if (attribute->freeAttr) { + PORT_Free(attribute); + } } /* @@ -864,7 +867,7 @@ sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type) if (attribute == NULL) return; sftk_DeleteAttribute(object, attribute); - sftk_FreeAttribute(attribute); + sftk_DestroyAttribute(attribute); } CK_RV diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c index 5c4608a9b..cfa056396 100644 --- a/lib/softoken/sftkdb.c +++ b/lib/softoken/sftkdb.c @@ -162,7 +162,7 @@ sftk_SDBULong2ULong(unsigned char *data) */ static CK_ATTRIBUTE * sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count, - unsigned char **dataOut) + unsigned char **dataOut, int *dataOutSize) { int i; int ulongCount = 0; @@ -170,6 +170,7 @@ sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count, CK_ATTRIBUTE *ntemplate; *dataOut = NULL; + *dataOutSize = 0; /* first count the number of CK_ULONG attributes */ for (i = 0; i < count; i++) { @@ -201,6 +202,7 @@ sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count, return NULL; } *dataOut = data; + *dataOutSize = SDB_ULONG_SIZE * ulongCount; /* copy the old template, fixup the actual ulongs */ for (i = 0; i < count; i++) { ntemplate[i] = template[i]; @@ -400,7 +402,7 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID, } PORT_Assert(template[i].ulValueLen >= plainText->len); if (template[i].ulValueLen < plainText->len) { - SECITEM_FreeItem(plainText, PR_TRUE); + SECITEM_ZfreeItem(plainText, PR_TRUE); PORT_Memset(template[i].pValue, 0, template[i].ulValueLen); template[i].ulValueLen = -1; crv = CKR_GENERAL_ERROR; @@ -410,7 +412,7 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID, /* copy the plain text back into the template */ PORT_Memcpy(template[i].pValue, plainText->data, plainText->len); template[i].ulValueLen = plainText->len; - SECITEM_FreeItem(plainText, PR_TRUE); + SECITEM_ZfreeItem(plainText, PR_TRUE); } /* make sure signed attributes are valid */ if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) { @@ -1293,7 +1295,7 @@ loser: } if (arena) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); } if (crv == CKR_OK) { *objectID |= (handle->type | SFTK_TOKEN_TYPE); @@ -1308,6 +1310,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template, unsigned char *data = NULL; CK_ATTRIBUTE *ntemplate = NULL; CK_RV crv; + int dataSize; SDB *db; if (handle == NULL) { @@ -1316,7 +1319,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template, db = SFTK_GET_SDB(handle); if (count != 0) { - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); + ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize); if (ntemplate == NULL) { return CKR_HOST_MEMORY; } @@ -1326,7 +1329,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template, count, find); if (data) { PORT_Free(ntemplate); - PORT_Free(data); + PORT_ZFree(data, dataSize); } return crv; } @@ -1373,6 +1376,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID, CK_RV crv, crv2; CK_ATTRIBUTE *ntemplate; unsigned char *data = NULL; + int dataSize = 0; SDB *db; if (handle == NULL) { @@ -1413,7 +1417,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID, if (count == 0) { return CKR_OK; } - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); + ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize); if (ntemplate == NULL) { return CKR_HOST_MEMORY; } @@ -1426,7 +1430,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID, crv = crv2; if (data) { PORT_Free(ntemplate); - PORT_Free(data); + PORT_ZFree(data, dataSize); } return crv; } @@ -1442,6 +1446,7 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, CK_RV crv = CKR_OK; CK_OBJECT_HANDLE objectID = (object->handle & SFTK_OBJ_ID_MASK); PRBool inTransaction = PR_FALSE; + int dataSize; if (handle == NULL) { return CKR_TOKEN_WRITE_PROTECTED; @@ -1463,7 +1468,7 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, return CKR_USER_NOT_LOGGED_IN; } - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); + ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize); if (ntemplate == NULL) { return CKR_HOST_MEMORY; } @@ -1498,7 +1503,7 @@ loser: } if (data) { PORT_Free(ntemplate); - PORT_Free(data); + PORT_ZFree(data, dataSize); } if (arena) { PORT_FreeArena(arena, PR_FALSE); @@ -1602,13 +1607,13 @@ sftkdb_CloseDB(SFTKDBHandle *handle) (*handle->db->sdb_Close)(handle->db); } if (handle->passwordKey.data) { - PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len); + SECITEM_ZfreeItem(&handle->passwordKey, PR_FALSE); } if (handle->passwordLock) { SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock)); } if (handle->updatePasswordKey) { - SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE); + SECITEM_ZfreeItem(handle->updatePasswordKey, PR_TRUE); } if (handle->updateID) { PORT_Free(handle->updateID); @@ -2690,6 +2695,10 @@ sftkdb_ResetKeyDB(SFTKDBHandle *handle) /* set error */ return SECFailure; } + if (handle->passwordKey.data) { + SECITEM_ZfreeItem(&handle->passwordKey, PR_FALSE); + handle->passwordKey.data = NULL; + } return SECSuccess; } diff --git a/lib/softoken/sftkhmac.c b/lib/softoken/sftkhmac.c index b9ee7d054..1b38b06f9 100644 --- a/lib/softoken/sftkhmac.c +++ b/lib/softoken/sftkhmac.c @@ -69,6 +69,7 @@ SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key) ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx)); if (!ctx) { + PORT_Memset(secret, 0, secretLength); return NULL; } @@ -76,6 +77,7 @@ SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key) ctx->secretLength = secretLength; ctx->hash = HASH_GetRawHashObject(alg); ctx->totalLength = params->ulBodyTotalLen; + PORT_Memset(secret, 0, secretLength); return ctx; } @@ -188,7 +190,7 @@ sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength, void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free) { - PORT_Free(pctx); + PORT_ZFree(pctx, sizeof(sftk_MACConstantTimeCtx)); } CK_RV @@ -217,7 +219,7 @@ CK_RV sftk_MAC_Init(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, SFTKObject *key) { SFTKAttribute *keyval = NULL; - PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID); + PRBool isFIPS = sftk_isFIPS(key->slot->slotID); CK_RV ret = CKR_OK; /* Find the actual value of the key. */ diff --git a/lib/softoken/sftkike.c b/lib/softoken/sftkike.c index 049675ff8..2183add69 100644 --- a/lib/softoken/sftkike.c +++ b/lib/softoken/sftkike.c @@ -465,7 +465,7 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, SFTKObject *newKeyObj = NULL; unsigned char outKeyData[HASH_LENGTH_MAX]; unsigned char *newInKey = NULL; - unsigned int newInKeySize; + unsigned int newInKeySize = 0; unsigned int macSize; CK_RV crv = CKR_OK; prfContext context; @@ -545,7 +545,7 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, macSize); fail: if (newInKey) { - PORT_Free(newInKey); + PORT_ZFree(newInKey, newInKeySize); } if (newKeyValue) { sftk_FreeAttribute(newKeyValue); diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c index b41cf9dab..e0ff76f08 100644 --- a/lib/softoken/sftkpwd.c +++ b/lib/softoken/sftkpwd.c @@ -252,7 +252,7 @@ sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue, loser: if (localArena) { - PORT_FreeArena(localArena, PR_FALSE); + PORT_FreeArena(localArena, PR_TRUE); } return rv; @@ -419,7 +419,7 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SFTKDBHandle *handle, SDB *db, loser: if ((arena == NULL) && signature) { - SECITEM_FreeItem(cipher, PR_TRUE); + SECITEM_ZfreeItem(signature, PR_TRUE); } if (cipher) { SECITEM_FreeItem(cipher, PR_TRUE); @@ -486,7 +486,7 @@ loser: HMAC_Destroy(hashCx, PR_TRUE); } if (key) { - SECITEM_FreeItem(key, PR_TRUE); + SECITEM_ZfreeItem(key, PR_TRUE); } return rv; } @@ -526,11 +526,12 @@ sftkdb_VerifyAttribute(SFTKDBHandle *handle, } loser: + PORT_Memset(signData, 0, sizeof signData); if (signValue.param) { nsspkcs5_DestroyPBEParameter(signValue.param); } if (signValue.arena) { - PORT_FreeArena(signValue.arena, PR_FALSE); + PORT_FreeArena(signValue.arena, PR_TRUE); } return rv; } @@ -608,6 +609,7 @@ sftkdb_SignAttribute(PLArenaPool *arena, SFTKDBHandle *keyDB, SDB *db, } loser: + PORT_Memset(signData, 0, sizeof signData); if (param) { nsspkcs5_DestroyPBEParameter(param); } @@ -1079,7 +1081,7 @@ sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw, done: if (result) { - SECITEM_FreeItem(result, PR_TRUE); + SECITEM_ZfreeItem(result, PR_TRUE); } return rv; } @@ -1273,8 +1275,7 @@ sftk_convertAttributes(SFTKDBHandle *handle, CK_OBJECT_HANDLE id, } /* free up our mess */ - /* NOTE: at this point we know we've cleared out any unencrypted data */ - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); return CKR_OK; loser: diff --git a/lib/softoken/tlsprf.c b/lib/softoken/tlsprf.c index b96733b1f..042cf194f 100644 --- a/lib/softoken/tlsprf.c +++ b/lib/softoken/tlsprf.c @@ -174,7 +174,7 @@ sftk_TLSPRFInit(SFTKSessionContext *context, prf_cx->cxDataLen = 0; prf_cx->cxBufSize = blockSize - offsetof(TLSPRFContext, cxBuf); prf_cx->cxRv = SECSuccess; - prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID); + prf_cx->cxIsFIPS = sftk_isFIPS(key->slot->slotID); prf_cx->cxBufPtr = prf_cx->cxBuf; prf_cx->cxHashAlg = hash_alg; prf_cx->cxOutLen = out_len; diff --git a/lib/util/secalgid.c b/lib/util/secalgid.c index 718bb03ea..b3e8e89db 100644 --- a/lib/util/secalgid.c +++ b/lib/util/secalgid.c @@ -110,7 +110,7 @@ SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *to, void SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit) { - SECITEM_FreeItem(&algid->parameters, PR_FALSE); + SECITEM_ZfreeItem(&algid->parameters, PR_FALSE); SECITEM_FreeItem(&algid->algorithm, PR_FALSE); if (freeit == PR_TRUE) PORT_Free(algid); diff --git a/lib/util/secdig.c b/lib/util/secdig.c index f4deec54b..28377c2f8 100644 --- a/lib/util/secdig.c +++ b/lib/util/secdig.c @@ -135,7 +135,7 @@ void SGN_DestroyDigestInfo(SGNDigestInfo *di) { if (di && di->arena) { - PORT_FreeArena(di->arena, PR_FALSE); + PORT_FreeArena(di->arena, PR_TRUE); } return; |