summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Relyea <rrelyea@redhat.com>2021-03-11 15:29:22 -0800
committerRobert Relyea <rrelyea@redhat.com>2021-03-11 15:29:22 -0800
commit680869d066952c05d4f38887eaea5aabe1e7f311 (patch)
tree1d301cf4df3baae61e07162efbdac5080e742607
parente5ee7af7dc4e9204e1807d08eb7b804451473f1c (diff)
downloadnss-hg-680869d066952c05d4f38887eaea5aabe1e7f311.tar.gz
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
-rw-r--r--lib/freebl/blapii.h10
-rw-r--r--lib/freebl/drbg.c6
-rw-r--r--lib/freebl/dsa.c12
-rw-r--r--lib/freebl/ec.c10
-rw-r--r--lib/freebl/ecl/ecp_jm.c5
-rw-r--r--lib/freebl/gcm.c16
-rw-r--r--lib/freebl/hmacct.c5
-rw-r--r--lib/freebl/mpi/mpmontg.c6
-rw-r--r--lib/freebl/pqg.c45
-rw-r--r--lib/freebl/rijndael.c24
-rw-r--r--lib/freebl/rsa.c2
-rw-r--r--lib/freebl/rsapkcs.c8
-rw-r--r--lib/freebl/shvfy.c13
-rw-r--r--lib/freebl/unix_urandom.c1
-rw-r--r--lib/softoken/fipstokn.c6
-rw-r--r--lib/softoken/lowkey.c8
-rw-r--r--lib/softoken/lowpbe.c39
-rw-r--r--lib/softoken/pkcs11.c21
-rw-r--r--lib/softoken/pkcs11c.c467
-rw-r--r--lib/softoken/pkcs11i.h33
-rw-r--r--lib/softoken/pkcs11u.c21
-rw-r--r--lib/softoken/sftkdb.c33
-rw-r--r--lib/softoken/sftkhmac.c6
-rw-r--r--lib/softoken/sftkike.c4
-rw-r--r--lib/softoken/sftkpwd.c15
-rw-r--r--lib/softoken/tlsprf.c2
-rw-r--r--lib/util/secalgid.c2
-rw-r--r--lib/util/secdig.c2
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(&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);
}
}
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;