File nss-fips-safe-memset.patch of Package mozilla-nss.20241108081452

Index: nss/lib/freebl/aeskeywrap.c
===================================================================
--- nss.orig/lib/freebl/aeskeywrap.c
+++ nss/lib/freebl/aeskeywrap.c
@@ -513,7 +513,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
         PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
         rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
                          outLen);
-        PORT_Memset(iv, 0, sizeof(iv));
+        PORT_SafeZero(iv, sizeof(iv));
         return rv;
     }
 
@@ -529,7 +529,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
     PORT_ZFree(newBuf, paddedInputLen);
     /* a little overkill, we only need to clear out the length, but this
      * is easier to verify we got it all */
-    PORT_Memset(iv, 0, sizeof(iv));
+    PORT_SafeZero(iv, sizeof(iv));
     return rv;
 }
 
@@ -632,12 +632,12 @@ AESKeyWrap_DecryptKWP(AESKeyWrapContext
 loser:
     /* if we failed, make sure we don't return any data to the user */
     if ((rv != SECSuccess) && (output == newBuf)) {
-        PORT_Memset(newBuf, 0, paddedLen);
+        PORT_SafeZero(newBuf, paddedLen);
     }
     /* clear out CSP sensitive data from the heap and stack */
     if (allocBuf) {
         PORT_ZFree(allocBuf, paddedLen);
     }
-    PORT_Memset(iv, 0, sizeof(iv));
+    PORT_SafeZero(iv, sizeof(iv));
     return rv;
 }
Index: nss/lib/freebl/blapii.h
===================================================================
--- nss.orig/lib/freebl/blapii.h
+++ nss/lib/freebl/blapii.h
@@ -113,10 +113,10 @@ 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); \
+#define BLAPI_CLEAR_STACK(stack_size)                   \
+    {                                                   \
+        volatile char _stkclr[stack_size];              \
+        PORT_SafeZero((void *)&_stkclr[0], stack_size); \
     }
 #endif
 
Index: nss/lib/freebl/drbg.c
===================================================================
--- nss.orig/lib/freebl/drbg.c
+++ nss/lib/freebl/drbg.c
@@ -218,7 +218,7 @@ prng_initEntropy(void)
     SHA256_Update(&ctx, block, sizeof(block));
     SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
                sizeof(globalrng->previousEntropyHash));
-    PORT_Memset(block, 0, sizeof(block));
+    PORT_SafeZero(block, sizeof(block));
     SHA256_DestroyContext(&ctx, PR_FALSE);
     coRNGInitEntropy.status = PR_SUCCESS;
     __sync_synchronize ();
@@ -270,8 +270,8 @@ prng_getEntropy(PRUint8 *buffer, size_t
     }
 
 out:
-    PORT_Memset(hash, 0, sizeof hash);
-    PORT_Memset(block, 0, sizeof block);
+    PORT_SafeZero(hash, sizeof hash);
+    PORT_SafeZero(block, sizeof block);
     return rv;
 }
 
@@ -417,8 +417,8 @@ prng_Hashgen(RNGContext *rng, PRUint8 *r
         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);
+    PORT_SafeZero(data, sizeof data);
+    PORT_SafeZero(thisHash, sizeof thisHash);
 }
 
 /*
@@ -479,7 +479,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);
+    PORT_SafeZero(H, sizeof H);
     if (!rng->isValid) {
         PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
Index: nss/lib/freebl/dsa.c
===================================================================
--- nss.orig/lib/freebl/dsa.c
+++ nss/lib/freebl/dsa.c
@@ -471,7 +471,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt
     err = MP_OKAY;
     signature->len = dsa_signature_len;
 cleanup:
-    PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
+    PORT_SafeZero(localDigestData, DSA_MAX_SUBPRIME_LEN);
     mp_clear(&p);
     mp_clear(&q);
     mp_clear(&g);
@@ -532,7 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECIt
         rv = dsa_SignDigest(key, signature, digest, kSeed);
     } while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
              --retries > 0);
-    PORT_Memset(kSeed, 0, sizeof kSeed);
+    PORT_SafeZero(kSeed, sizeof kSeed);
     return rv;
 }
 
@@ -673,7 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, cons
         verified = SECSuccess; /* Signature verified. */
     }
 cleanup:
-    PORT_Memset(localDigestData, 0, sizeof localDigestData);
+    PORT_SafeZero(localDigestData, sizeof localDigestData);
     mp_clear(&p);
     mp_clear(&q);
     mp_clear(&g);
Index: nss/lib/freebl/gcm.c
===================================================================
--- nss.orig/lib/freebl/gcm.c
+++ nss/lib/freebl/gcm.c
@@ -507,7 +507,7 @@ gcmHash_Final(gcmHashContext *ghash, uns
     rv = SECSuccess;
 
 cleanup:
-    PORT_Memset(T, 0, sizeof(T));
+    PORT_SafeZero(T, sizeof(T));
     return rv;
 }
 
@@ -629,15 +629,15 @@ GCM_CreateContext(void *context, freeblC
     if (rv != SECSuccess) {
         goto loser;
     }
-    PORT_Memset(H, 0, AES_BLOCK_SIZE);
+    PORT_SafeZero(H, AES_BLOCK_SIZE);
     gcm->ctr_context_init = PR_TRUE;
     return gcm;
 
 loser:
-    PORT_Memset(H, 0, AES_BLOCK_SIZE);
+    PORT_SafeZero(H, AES_BLOCK_SIZE);
     if (ghash && ghash->mem) {
         void *mem = ghash->mem;
-        PORT_Memset(ghash, 0, sizeof(gcmHashContext));
+        PORT_SafeZero(ghash, sizeof(gcmHashContext));
         PORT_Free(mem);
     }
     if (gcm) {
@@ -717,11 +717,11 @@ gcm_InitCounter(GCMContext *gcm, const u
         goto loser;
     }
 
-    PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+    PORT_SafeZero(&ctrParams, sizeof ctrParams);
     return SECSuccess;
 
 loser:
-    PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+    PORT_SafeZero(&ctrParams, sizeof ctrParams);
     if (freeCtr) {
         CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
     }
@@ -1212,10 +1212,10 @@ GCM_DecryptAEAD(GCMContext *gcm, unsigne
         /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
         CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
         PORT_SetError(SEC_ERROR_BAD_DATA);
-        PORT_Memset(tag, 0, sizeof(tag));
+        PORT_SafeZero(tag, sizeof(tag));
         return SECFailure;
     }
-    PORT_Memset(tag, 0, sizeof(tag));
+    PORT_SafeZero(tag, sizeof(tag));
     /* finish the decryption */
     rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
                     inbuf, inlen, AES_BLOCK_SIZE);
Index: nss/lib/freebl/hmacct.c
===================================================================
--- nss.orig/lib/freebl/hmacct.c
+++ nss/lib/freebl/hmacct.c
@@ -274,10 +274,10 @@ 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);
+    PORT_SafeZero(lengthBytes, sizeof lengthBytes);
+    PORT_SafeZero(hmacPad, sizeof hmacPad);
+    PORT_SafeZero(firstBlock, sizeof firstBlock);
+    PORT_SafeZero(macOut, sizeof macOut);
 
     return SECSuccess;
 }
Index: nss/lib/freebl/intel-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/intel-gcm-wrap.c
+++ nss/lib/freebl/intel-gcm-wrap.c
@@ -195,7 +195,7 @@ intel_aes_gcmInitCounter(intel_AES_GCMCo
 void
 intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
 {
-    PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
+    PORT_SafeZero(gcm, sizeof(intel_AES_GCMContext));
     if (freeit) {
         PORT_Free(gcm);
     }
Index: nss/lib/freebl/ppc-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/ppc-gcm-wrap.c
+++ nss/lib/freebl/ppc-gcm-wrap.c
@@ -169,7 +169,7 @@ ppc_aes_gcmInitCounter(ppc_AES_GCMContex
 void
 ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
 {
-    PORT_Memset(gcm, 0, sizeof(ppc_AES_GCMContext));
+    PORT_SafeZero(gcm, sizeof(ppc_AES_GCMContext));
     if (freeit) {
         PORT_Free(gcm);
     }
Index: nss/lib/freebl/pqg.c
===================================================================
--- nss.orig/lib/freebl/pqg.c
+++ nss/lib/freebl/pqg.c
@@ -703,7 +703,7 @@ cleanup:
     mp_clear(&a);
     mp_clear(&z);
     mp_clear(&two_length_minus_1);
-    PORT_Memset(x, 0, sizeof(x));
+    PORT_SafeZero(x, sizeof(x));
     if (err) {
         MP_TO_SEC_ERROR(err);
         rv = SECFailure;
@@ -859,7 +859,7 @@ cleanup:
     mp_clear(&c);
     mp_clear(&c0);
     mp_clear(&one);
-    PORT_Memset(x, 0, sizeof(x));
+    PORT_SafeZero(x, sizeof(x));
     if (err) {
         MP_TO_SEC_ERROR(err);
         rv = SECFailure;
@@ -1072,7 +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);
+    PORT_SafeZero(V_j, sizeof V_j);
     mp_clear(&W);
     mp_clear(&X);
     mp_clear(&c);
@@ -1221,7 +1221,7 @@ makeGfromIndex(HASH_HashType hashtype,
 /* step 11.
  * return valid G */
 cleanup:
-    PORT_Memset(data, 0, sizeof(data));
+    PORT_SafeZero(data, sizeof(data));
     if (hashcx) {
         hashobj->destroy(hashcx, PR_TRUE);
     }
Index: nss/lib/freebl/rijndael.c
===================================================================
--- nss.orig/lib/freebl/rijndael.c
+++ nss/lib/freebl/rijndael.c
@@ -1251,7 +1251,7 @@ AES_DestroyContext(AESContext *cx, PRBoo
         cx->worker_cx = NULL;
         cx->destroy = NULL;
     }
-    PORT_Memset(cx, 0, sizeof(AESContext));
+    PORT_SafeZero(cx, sizeof(AESContext));
     if (freeit) {
         PORT_Free(mem);
     } else {
Index: nss/lib/freebl/rsa.c
===================================================================
--- nss.orig/lib/freebl/rsa.c
+++ nss/lib/freebl/rsa.c
@@ -145,8 +145,8 @@ rsa_build_from_primes(const mp_int *p, c
     /* 2.  Compute phi = (p-1)*(q-1) */
     CHECK_MPI_OK(mp_sub_d(p, 1, &psub1));
     CHECK_MPI_OK(mp_sub_d(q, 1, &qsub1));
+    CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
     if (needPublicExponent || needPrivateExponent) {
-        CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
         /* 3.  Compute d = e**-1 mod(phi) */
         /*     or      e = d**-1 mod(phi) as necessary */
         if (needPublicExponent) {
@@ -180,6 +180,15 @@ rsa_build_from_primes(const mp_int *p, c
         goto cleanup;
     }
 
+    /* make sure we weren't passed in a d or e = 1 mod phi */
+    /* just need to check d, because if one is = 1 mod phi, they both are */
+    CHECK_MPI_OK(mp_mod(d, &phi, &tmp));
+    if (mp_cmp_d(&tmp, 2) <= 0) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        rv = SECFailure;
+        goto cleanup;
+    }
+
     /* 4.  Compute exponent1 = d mod (p-1) */
     CHECK_MPI_OK(mp_mod(d, &psub1, &tmp));
     MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena);
@@ -1251,6 +1260,8 @@ rsa_PrivateKeyOpCRTCheckedPubKey(RSAPriv
     /* Perform a public key operation v = m ** e mod n */
     CHECK_MPI_OK(mp_exptmod(m, &e, &n, &v));
     if (mp_cmp(&v, c) != 0) {
+        /* this error triggers a fips fatal error lock */
+        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         rv = SECFailure;
     }
 cleanup:
Index: nss/lib/freebl/rsapkcs.c
===================================================================
--- nss.orig/lib/freebl/rsapkcs.c
+++ nss/lib/freebl/rsapkcs.c
@@ -978,14 +978,14 @@ rsa_GetHMACContext(const SECHashObject *
     /* now create the hmac key */
     hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
     if (hmac == NULL) {
-        PORT_Memset(keyHash, 0, sizeof(keyHash));
+        PORT_SafeZero(keyHash, sizeof(keyHash));
         return NULL;
     }
     HMAC_Begin(hmac);
     HMAC_Update(hmac, input, inputLen);
     rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
     if (rv != SECSuccess) {
-        PORT_Memset(keyHash, 0, sizeof(keyHash));
+        PORT_SafeZero(keyHash, sizeof(keyHash));
         HMAC_Destroy(hmac, PR_TRUE);
         return NULL;
     }
@@ -993,7 +993,7 @@ rsa_GetHMACContext(const SECHashObject *
      * reuse the original context allocated above so we don't
      * need to allocate and free another one */
     rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
-    PORT_Memset(keyHash, 0, sizeof(keyHash));
+    PORT_SafeZero(keyHash, sizeof(keyHash));
     if (rv != SECSuccess) {
         HMAC_Destroy(hmac, PR_TRUE);
         return NULL;
@@ -1043,7 +1043,7 @@ rsa_HMACPrf(HMACContext *hmac, const cha
             return rv;
         }
         PORT_Memcpy(output, hmacLast, left);
-        PORT_Memset(hmacLast, 0, sizeof(hmacLast));
+        PORT_SafeZero(hmacLast, sizeof(hmacLast));
     }
     return rv;
 }
@@ -1088,7 +1088,7 @@ rsa_GetErrorLength(HMACContext *hmac, in
         outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
                                 candidate, outLength);
     }
-    PORT_Memset(out, 0, sizeof(out));
+    PORT_SafeZero(out, sizeof(out));
     return outLength;
 }
 
Index: nss/lib/freebl/shvfy.c
===================================================================
--- nss.orig/lib/freebl/shvfy.c
+++ nss/lib/freebl/shvfy.c
@@ -365,7 +365,7 @@ blapi_SHVerifyDSACheck(PRFileDesc *shFD,
 
     /* verify the hash against the check file */
     rv = DSA_VerifyDigest(key, signature, &hash);
-    PORT_Memset(hashBuf, 0, sizeof hashBuf);
+    PORT_SafeZero(hashBuf, sizeof hashBuf);
     return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
 }
 #endif
@@ -427,7 +427,7 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD
     if (rv == SECSuccess) {
         result = SECITEM_ItemsAreEqual(signature, &hash);
     }
-    PORT_Memset(hashBuf, 0, sizeof hashBuf);
+    PORT_SafeZero(hashBuf, sizeof hashBuf);
     return result;
 }
 
@@ -451,7 +451,7 @@ blapi_SHVerifyFile(const char *shName, P
 #ifndef NSS_STRICT_INTEGRITY
     DSAPublicKey key;
 
-    PORT_Memset(&key, 0, sizeof(key));
+    PORT_SafeZero(&key, sizeof(key));
 #endif
 
     /* If our integrity check was never ran or failed, fail any other
@@ -600,7 +600,7 @@ blapi_SHVerifyFile(const char *shName, P
     shFD = NULL;
 
 loser:
-    PORT_Memset(&header, 0, sizeof header);
+    PORT_SafeZero(&header, sizeof header);
     if (checkName != NULL) {
         PORT_Free(checkName);
     }
Index: nss/lib/freebl/tlsprfalg.c
===================================================================
--- nss.orig/lib/freebl/tlsprfalg.c
+++ nss/lib/freebl/tlsprfalg.c
@@ -82,8 +82,8 @@ loser:
     /* clear out state so it's not left on the stack */
     if (cx)
         HMAC_Destroy(cx, PR_TRUE);
-    PORT_Memset(state, 0, sizeof(state));
-    PORT_Memset(outbuf, 0, sizeof(outbuf));
+    PORT_SafeZero(state, sizeof(state));
+    PORT_SafeZero(outbuf, sizeof(outbuf));
     return rv;
 }
 
Index: nss/lib/freebl/unix_urandom.c
===================================================================
--- nss.orig/lib/freebl/unix_urandom.c
+++ nss/lib/freebl/unix_urandom.c
@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
         return;
     }
     RNG_RandomUpdate(bytes, numBytes);
-    PORT_Memset(bytes, 0, sizeof bytes);
+    PORT_SafeZero(bytes, sizeof bytes);
 }
 
 size_t
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -5105,7 +5105,7 @@ pairwise_signverify_mech (CK_SESSION_HAN
     if ((signature_length >= pairwise_digest_length) &&
         (PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
         PORT_Free(signature);
-        return CKR_DEVICE_ERROR;
+        return CKR_GENERAL_ERROR;
     }
 
     /* Verify the known hash using the public key. */
Index: nss/lib/util/secport.h
===================================================================
--- nss.orig/lib/util/secport.h
+++ nss/lib/util/secport.h
@@ -36,6 +36,9 @@
 #include <sys/types.h>
 
 #include <ctype.h>
+/* ask for Annex K for memset_s. will set the appropriate #define
+ * if Annex K is supported */
+#define __STDC_WANT_LIB_EXT1__ 1
 #include <string.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -178,6 +181,39 @@ SEC_END_PROTOS
 #define PORT_Memmove memmove
 #define PORT_Memset memset
 
+/* there are cases where the compiler optimizes away our attempt to clear
+ * out our stack variables. There are multiple solutions for this problem,
+ * but they aren't universally accepted on all platforms. This attempts
+ * to select the best solution available given our os, compilier, and libc */
+#ifdef __STDC_LIB_EXT1__
+/* if the os implements C11 annex K, use memset_s */
+#define PORT_SafeZero(p, n) memset_s(p, n, 0, n)
+#else
+#ifdef XP_WIN
+/* windows has a secure zero funtion */
+#define PORT_SafeZero(p, n) SecureZeroMemory(p, n)
+#else
+/* _DEFAULT_SORUCE  == BSD source in GCC based environments
+ * if other environmens support explicit_bzero, their defines
+ * should be added here */
+#if defined(_DEFAULT_SOURCE) || defined(_BSD_SOURCE)
+#define PORT_SafeZero(p, n) explicit_bzero(p, n)
+#else
+/* if the os doesn't support one of the above, but does support
+ * memset_explicit, you can add the definition for memset with the
+ * appropriate define check here */
+/* define an explicitly implementated Safe zero if the OS
+ * doesn't provide one */
+#define PORT_SafeZero(p, n)                                \
+    if (p != NULL) {                                       \
+        volatile unsigned char *__vl = (unsigned char *)p; \
+        size_t __nl = n;                                   \
+        while (__nl--) *__vl++ = 0;                        \
+    }
+#endif /* no explicit_bzero */
+#endif /* no windows SecureZeroMemory */
+#endif /* no memset_s */
+
 #define PORT_Strcasecmp PL_strcasecmp
 #define PORT_Strcat strcat
 #define PORT_Strchr strchr
openSUSE Build Service is sponsored by