File nss-fips-zeroization.patch of Package mozilla-nss

diff --git a/nss/lib/freebl/aeskeywrap.c b/nss/lib/freebl/aeskeywrap.c
index 79ff8a8..9158521 100644
--- a/nss/lib/freebl/aeskeywrap.c
+++ b/nss/lib/freebl/aeskeywrap.c
@@ -93,6 +93,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);
diff --git a/nss/lib/freebl/cts.c b/nss/lib/freebl/cts.c
index 99ccebb..456b179 100644
--- a/nss/lib/freebl/cts.c
+++ b/nss/lib/freebl/cts.c
@@ -41,6 +41,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);
     }
@@ -139,7 +140,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 {
@@ -234,13 +235,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;
 
@@ -284,9 +287,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);
@@ -301,7 +304,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 97025c7..28eefb1 100644
--- a/nss/lib/freebl/dh.c
+++ b/nss/lib/freebl/dh.c
@@ -194,6 +194,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 669c9b1..dd4afe3 100644
--- a/nss/lib/freebl/ec.c
+++ b/nss/lib/freebl/ec.c
@@ -970,7 +970,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 cf8e027..1934aa5 100644
--- a/nss/lib/freebl/gcm.c
+++ b/nss/lib/freebl/gcm.c
@@ -37,6 +37,12 @@ static SECStatus gcmHash_Reset(gcmHashContext *ghash,
                                const unsigned char *inbuf,
                                unsigned int inbufLen, unsigned int blocksize);
 
+/* the ALGORITHM_1 implementation lacks any data structure zeroizations and is
+ * slower (see below) - cancel compilation if it somehow got requested */
+#ifdef GCM_USE_ALGORITHM_1
+#error "ALGORITHM_1 is not supported in this build"
+#endif
+
 /* compile time defines to select how the GF2 multiply is calculated.
  * There are currently 2 algorithms implemented here: MPI and ALGORITHM_1.
  *
@@ -271,6 +277,7 @@ gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
     }
     rv = SECSuccess;
 cleanup:
+    mp_zero(&ghash->C_i);
     PORT_Memset(tmp_buf, 0, sizeof(tmp_buf));
     if (rv != SECSuccess) {
         MP_TO_SEC_ERROR(err);
@@ -287,7 +294,8 @@ gcm_zeroX(gcmHashContext *ghash)
 
 #endif
 
-#ifdef GCM_USE_ALGORITHM_1
+#if 0
+/* ifdef GCM_USE_ALGORITHM_1 */
 /* use algorithm 1 of McGrew & Viega "The Galois/Counter Mode of Operation" */
 
 #define GCM_ARRAY_SIZE (MAX_BLOCK_SIZE / sizeof(unsigned long))
@@ -854,11 +862,13 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
     /* verify the block */
     rv = gcmHash_Update(&gcm->ghash_context, inbuf, inlen, blocksize);
     if (rv != SECSuccess) {
-        return SECFailure;
+        rv = SECFailure;
+        goto cleanup;
     }
     rv = gcm_GetTag(gcm, tag, &len, blocksize, blocksize);
     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
@@ -866,10 +876,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, blocksize);
diff --git a/nss/lib/freebl/mpi/mpi.c b/nss/lib/freebl/mpi/mpi.c
index f6f7543..fefcf4f 100644
--- a/nss/lib/freebl/mpi/mpi.c
+++ b/nss/lib/freebl/mpi/mpi.c
@@ -12,6 +12,10 @@
 #include <c_asm.h>
 #endif
 
+#if !MP_CRYPTO
+#error "MP_CRYPTO has to be defined to make sure data is zeroed before being freed"
+#endif
+
 #if defined(__arm__) && \
     ((defined(__thumb__) && !defined(__thumb2__)) || defined(__ARM_ARCH_3__))
 /* 16-bit thumb or ARM v3 doesn't work inlined assember version */
openSUSE Build Service is sponsored by