From 76da775313bd40a1353a9d2f6cc43ebe1a287574 Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <hpj@cl.no>
Date: Wed, 20 Nov 2019 10:04:25 +0100
Subject: [PATCH 07/10] 29

---
 nss/lib/freebl/aeskeywrap.c |  1 +
 nss/lib/freebl/cts.c        | 18 +++++++++------
 nss/lib/freebl/dh.c         |  4 ++++
 nss/lib/freebl/ec.c         |  2 +-
 nss/lib/freebl/gcm.c        | 45 +++++++++++++++++++++++++++++++++----
 5 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/nss/lib/freebl/aeskeywrap.c b/nss/lib/freebl/aeskeywrap.c
index ee909db..b9f0439 100644
--- a/nss/lib/freebl/aeskeywrap.c
+++ b/nss/lib/freebl/aeskeywrap.c
@@ -100,6 +100,7 @@ AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
 {
     if (cx) {
         AES_DestroyContext(&cx->aescx, PR_FALSE);
+	memset(cx->iv, 0, sizeof (cx->iv));
         /*  memset(cx, 0, sizeof *cx); */
         if (freeit) {
             PORT_Free(cx->mem);
diff --git a/nss/lib/freebl/cts.c b/nss/lib/freebl/cts.c
index 774294b..a12e620 100644
--- a/nss/lib/freebl/cts.c
+++ b/nss/lib/freebl/cts.c
@@ -37,6 +37,7 @@ CTS_CreateContext(void *context, freeblCipherFunc cipher,
 void
 CTS_DestroyContext(CTSContext *cts, PRBool freeit)
 {
+    PORT_Memset(cts, 0, sizeof(CTSContext));
     if (freeit) {
         PORT_Free(cts);
     }
@@ -135,7 +136,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
     PORT_Memset(lastBlock + inlen, 0, blocksize - inlen);
     rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock,
                         blocksize, blocksize);
-    PORT_Memset(lastBlock, 0, blocksize);
+    PORT_Memset(lastBlock, 0, MAX_BLOCK_SIZE);
     if (rv == SECSuccess) {
         *outlen = written + blocksize;
     } else {
@@ -230,13 +231,15 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
     rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
                         fullblocks, blocksize);
     if (rv != SECSuccess) {
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
     *outlen = fullblocks; /* AES low level doesn't set outlen */
     inbuf += fullblocks;
     inlen -= fullblocks;
     if (inlen == 0) {
-        return SECSuccess;
+        rv = SECSuccess;
+        goto cleanup;
     }
     outbuf += fullblocks;
 
@@ -280,9 +283,9 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
     rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
                         blocksize, blocksize);
     if (rv != SECSuccess) {
-        PORT_Memset(lastBlock, 0, blocksize);
         PORT_Memset(saveout, 0, *outlen);
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
     /* make up for the out of order CBC decryption */
     XOR_BLOCK(Pn, Cn_2, blocksize);
@@ -297,7 +300,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
     /* clear last block. At this point last block contains Pn xor Cn_1 xor
      * Cn_2, both of with an attacker would know, so we need to clear this
      * buffer out */
-    PORT_Memset(lastBlock, 0, blocksize);
+cleanup:
+    PORT_Memset(lastBlock, 0, MAX_BLOCK_SIZE);
     /* Cn, Cn_1, and Cn_2 have encrypted data, so no need to clear them */
-    return SECSuccess;
+    return rv;
 }
diff --git a/nss/lib/freebl/dh.c b/nss/lib/freebl/dh.c
index b2d6d74..5ff9551 100644
--- a/nss/lib/freebl/dh.c
+++ b/nss/lib/freebl/dh.c
@@ -192,6 +192,10 @@ cleanup:
         rv = SECFailure;
     }
     if (rv) {
+        SECITEM_ZfreeItem(&key->prime, PR_FALSE);
+        SECITEM_ZfreeItem(&key->base, PR_FALSE);
+        SECITEM_ZfreeItem(&key->publicValue, PR_FALSE);
+        SECITEM_ZfreeItem(&key->privateValue, PR_FALSE);
         *privKey = NULL;
         PORT_FreeArena(arena, PR_TRUE);
     }
diff --git a/nss/lib/freebl/ec.c b/nss/lib/freebl/ec.c
index ddbcc23..94fbc72 100644
--- a/nss/lib/freebl/ec.c
+++ b/nss/lib/freebl/ec.c
@@ -958,7 +958,7 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
     ECParams *ecParams = NULL;
     SECItem pointC = { siBuffer, NULL, 0 };
     int slen;       /* length in bytes of a half signature (r or s) */
-    int flen;       /* length in bytes of the field size */
+    int flen = 0;   /* length in bytes of the field size */
     unsigned olen;  /* length in bytes of the base point order */
     unsigned obits; /* length in bits  of the base point order */
 
diff --git a/nss/lib/freebl/gcm.c b/nss/lib/freebl/gcm.c
index 0f42525..4d960f7 100644
--- a/nss/lib/freebl/gcm.c
+++ b/nss/lib/freebl/gcm.c
@@ -141,6 +141,9 @@ bmul(uint64_t x, uint64_t y, uint64_t *r_high, uint64_t *r_low)
 
     *r_high = (uint64_t)(r >> 64);
     *r_low = (uint64_t)r;
+
+    /* Zeroization */
+    x1 = x2 = x3 = x4 = x5 = y1 = y2 = y3 = y4 = y5 = r = z = 0;
 }
 
 SECStatus
@@ -179,6 +182,12 @@ gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf,
     }
     ghash->x_low = ci_low;
     ghash->x_high = ci_high;
+
+    /* Zeroization */
+    ci_low = ci_high = z2_low = z2_high = z0_low = z0_high = z1a_low = z1a_high = 0;
+    z_low = z_high = 0;
+    i = 0;
+
     return SECSuccess;
 }
 #else
@@ -218,6 +227,10 @@ bmul32(uint32_t x, uint32_t y, uint32_t *r_high, uint32_t *r_low)
     z = z0 | z1 | z2 | z3;
     *r_high = (uint32_t)(z >> 32);
     *r_low = (uint32_t)z;
+
+    /* Zeroization */
+    x0 = x1 = x2 = x3 = y0 = y1 = y2 = y3 = 0;
+    z0 = z1 = z2 = z3 = z = 0;
 }
 
 SECStatus
@@ -303,6 +316,20 @@ gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf,
         ghash->x_high = z_high_h;
         ghash->x_low = z_high_l;
     }
+
+    /* Zeroization */
+    ci_low = ci_high = z_high_h = z_high_l = z_low_h = z_low_l = 0;
+
+    ci_high_h = ci_high_l = ci_low_h = ci_low_l
+        = b_a_h = b_a_l = a_a_h = a_a_l = b_b_h = b_b_l
+        = a_b_h = a_b_l = b_c_h = b_c_l = a_c_h = a_c_l = c_c_h = c_c_l
+        = ci_highXlow_h = ci_highXlow_l = c_a_h = c_a_l = c_b_h = c_b_l
+        = h_high_h = h_high_l = h_low_h = h_low_l = h_highXlow_h = h_highXlow_l
+        = h_highX_xored
+        = 0;
+
+    i = 0;
+
     return SECSuccess;
 }
 #endif /* HAVE_INT128_SUPPORT */
@@ -760,11 +787,13 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
     /* verify the block */
     rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen);
     if (rv != SECSuccess) {
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
     rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE);
     if (rv != SECSuccess) {
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
     /* Don't decrypt if we can't authenticate the encrypted data!
      * This assumes that if tagBits is not a multiple of 8, intag will
@@ -772,10 +801,18 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
     if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
         /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
         PORT_SetError(SEC_ERROR_BAD_DATA);
-        PORT_Memset(tag, 0, sizeof(tag));
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
+cleanup:
+    tagBytes = 0;
     PORT_Memset(tag, 0, sizeof(tag));
+    intag = NULL;
+    len = 0;
+    if (rv != SECSuccess) {
+        return rv;
+    }
+
     /* finish the decryption */
     return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
                       inbuf, inlen, AES_BLOCK_SIZE);
-- 
2.21.0

