Hello community,

here is the log from the commit of package mozilla-nss for openSUSE:Factory 
checked in at 2020-06-30 21:52:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mozilla-nss (Old)
 and      /work/SRC/openSUSE:Factory/.mozilla-nss.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mozilla-nss"

Tue Jun 30 21:52:57 2020 rev:159 rq:817441 version:3.53.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/mozilla-nss/mozilla-nss.changes  2020-06-05 
20:02:36.828412875 +0200
+++ /work/SRC/openSUSE:Factory/.mozilla-nss.new.3060/mozilla-nss.changes        
2020-06-30 21:52:58.474110783 +0200
@@ -1,0 +2,59 @@
+Sat Jun 27 21:16:07 UTC 2020 - Wolfgang Rosenauer <w...@rosenauer.org>
+
+- add FIPS mode patches from SLE stream
+  nss-fips-aes-keywrap-post.patch
+  nss-fips-approved-crypto-non-ec.patch
+  nss-fips-cavs-dsa-fixes.patch
+  nss-fips-cavs-general.patch
+  nss-fips-cavs-kas-ecc.patch
+  nss-fips-cavs-kas-ffc.patch
+  nss-fips-cavs-keywrap.patch
+  nss-fips-cavs-rsa-fixes.patch
+  nss-fips-combined-hash-sign-dsa-ecdsa.patch
+  nss-fips-constructor-self-tests.patch
+  nss-fips-detect-fips-mode-fixes.patch
+  nss-fips-dsa-kat.patch
+  nss-fips-gcm-ctr.patch
+  nss-fips-pairwise-consistency-check.patch
+  nss-fips-rsa-keygen-strictness.patch
+  nss-fips-tls-allow-md5-prf.patch
+  nss-fips-use-getrandom.patch
+  nss-fips-use-strong-random-pool.patch
+  nss-fips-zeroization.patch
+  nss-fix-dh-pkcs-derive-inverted-logic.patch
+
+-------------------------------------------------------------------
+Tue Jun 23 05:40:12 UTC 2020 - Wolfgang Rosenauer <w...@rosenauer.org>
+
+- update to NSS 3.53.1
+  * required for Firefox 78
+  * CVE-2020-12402 - Use constant-time GCD and modular inversion in MPI.
+    (bmo#1631597, bsc#1173032)
+
+-------------------------------------------------------------------
+Sun Jun 21 04:44:40 UTC 2020 - Michel Normand <norm...@linux.vnet.ibm.com>
+
+- Add ppc-old-abi-v3.patch as per upstream bug
+  https://bugzilla.mozilla.org/show_bug.cgi?id=1642174
+
+-------------------------------------------------------------------
+Thu Jun 11 20:09:44 UTC 2020 - Wolfgang Rosenauer <w...@rosenauer.org>
+
+- update to NSS 3.53
+  Notable changes
+  * SEED is now moved into a new freebl directory freebl/deprecated
+    bmo#1636389
+  * SEED will be disabled by default in a future release of NSS. At
+    that time, users will need to set the compile-time flag
+    (bmo#1622033) to disable that deprecation in order to use the
+    algorithm.
+  * Algorithms marked as deprecated will ultimately be removed
+  * Several root certificates in the Mozilla program now set the
+    CKA_NSS_SERVER_DISTRUST_AFTER attribute, which NSS consumers
+    can query to further refine trust decisions. (bmo#1618404,
+    bmo#1621159). If a builtin certificate has a
+    CKA_NSS_SERVER_DISTRUST_AFTER timestamp before the SCT or
+    NotBefore date of a certificate that builtin issued, then clients
+    can elect not to trust it.
+
+-------------------------------------------------------------------

Old:
----
  nss-3.52.1.tar.gz

New:
----
  nss-3.53.1.tar.gz
  nss-fips-aes-keywrap-post.patch
  nss-fips-approved-crypto-non-ec.patch
  nss-fips-cavs-dsa-fixes.patch
  nss-fips-cavs-general.patch
  nss-fips-cavs-kas-ecc.patch
  nss-fips-cavs-kas-ffc.patch
  nss-fips-cavs-keywrap.patch
  nss-fips-cavs-rsa-fixes.patch
  nss-fips-combined-hash-sign-dsa-ecdsa.patch
  nss-fips-constructor-self-tests.patch
  nss-fips-detect-fips-mode-fixes.patch
  nss-fips-dsa-kat.patch
  nss-fips-gcm-ctr.patch
  nss-fips-pairwise-consistency-check.patch
  nss-fips-rsa-keygen-strictness.patch
  nss-fips-tls-allow-md5-prf.patch
  nss-fips-use-getrandom.patch
  nss-fips-use-strong-random-pool.patch
  nss-fips-zeroization.patch
  nss-fix-dh-pkcs-derive-inverted-logic.patch
  ppc-old-abi-v3.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mozilla-nss.spec ++++++
--- /var/tmp/diff_new_pack.toDILa/_old  2020-06-30 21:53:07.798139636 +0200
+++ /var/tmp/diff_new_pack.toDILa/_new  2020-06-30 21:53:07.798139636 +0200
@@ -17,14 +17,14 @@
 #
 
 
-%global nss_softokn_fips_version 3.52
+%global nss_softokn_fips_version 3.53
 %define NSPR_min_version 4.25
 %define nspr_ver %(rpm -q --queryformat '%%{VERSION}' mozilla-nspr)
 %define nssdbdir %{_sysconfdir}/pki/nssdb
 Name:           mozilla-nss
-Version:        3.52.1
+Version:        3.53.1
 Release:        0
-%define underscore_version 3_52_1
+%define underscore_version 3_53_1
 Summary:        Network Security Services
 License:        MPL-2.0
 Group:          System/Libraries
@@ -49,7 +49,33 @@
 Patch5:         malloc.patch
 Patch6:         bmo-1400603.patch
 Patch7:         nss-sqlitename.patch
+Patch8:         ppc-old-abi-v3.patch
+Patch11:        nss-fips-use-getrandom.patch
+Patch13:        nss-fips-dsa-kat.patch
+Patch15:        nss-fips-pairwise-consistency-check.patch
+Patch16:        nss-fips-rsa-keygen-strictness.patch
+Patch19:        nss-fips-cavs-keywrap.patch
+Patch20:        nss-fips-cavs-kas-ffc.patch
+Patch21:        nss-fips-cavs-kas-ecc.patch
+Patch22:        nss-fips-gcm-ctr.patch
+Patch23:        nss-fips-constructor-self-tests.patch
+Patch24:        nss-fips-cavs-general.patch
+Patch25:        nss-fips-cavs-dsa-fixes.patch
+Patch26:        nss-fips-cavs-rsa-fixes.patch
+Patch27:        nss-fips-approved-crypto-non-ec.patch
+Patch29:        nss-fips-zeroization.patch
+Patch30:        nss-fips-tls-allow-md5-prf.patch
+Patch31:        nss-fips-use-strong-random-pool.patch
+Patch32:        nss-fips-detect-fips-mode-fixes.patch
+Patch34:        nss-fips-combined-hash-sign-dsa-ecdsa.patch
+Patch35:        nss-fix-dh-pkcs-derive-inverted-logic.patch
+Patch36:        nss-fips-aes-keywrap-post.patch
+%if 0%{?sle_version} >= 120000 && 0%{?sle_version} < 150000
+# aarch64 + gcc4.8 fails to build on SLE-12 due to undefined references
+BuildRequires:  gcc9-c++
+%else
 BuildRequires:  gcc-c++
+%endif
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(nspr) >= %{NSPR_min_version}
 BuildRequires:  pkgconfig(sqlite3)
@@ -179,6 +205,30 @@
 %endif
 %patch6 -p1
 %patch7 -p1
+%patch8 -p1
+
+# FIPS patches
+%patch11 -p1
+%patch13 -p1
+%patch15 -p1
+%patch16 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+
 # additional CA certificates
 #cd security/nss/lib/ckfw/builtins
 #cat %{SOURCE2} >> certdata.txt
@@ -191,6 +241,12 @@
 %else
 %global _lto_cflags %{_lto_cflags} -ffat-lto-objects
 %endif
+%if 0%{?sle_version} >= 120000 && 0%{?sle_version} < 150000
+export CC=gcc-9
+# Yes, they use both...
+export CXX=g++-9
+export CCC=g++-9
+%endif
 cd nss
 modified="$(sed -n '/^----/n;s/ - .*$//;p;q' "%{SOURCE99}")"
 DATE="\"$(date -d "${modified}" "+%%b %%e %%Y")\""
@@ -211,7 +267,7 @@
 export NSS_USE_SYSTEM_SQLITE=1
 #export SQLITE_LIB_NAME=nsssqlite3
 MAKE_FLAGS="BUILD_OPT=1"
-make --jobs=1 nss_build_all $MAKE_FLAGS
+make %{?_smp_mflags} nss_build_all $MAKE_FLAGS
 # run testsuite
 %if 0%{?run_testsuite}
 export BUILD_OPT=1



++++++ nss-3.52.1.tar.gz -> nss-3.53.1.tar.gz ++++++
/work/SRC/openSUSE:Factory/mozilla-nss/nss-3.52.1.tar.gz 
/work/SRC/openSUSE:Factory/.mozilla-nss.new.3060/nss-3.53.1.tar.gz differ: char 
5, line 1

++++++ nss-fips-aes-keywrap-post.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1589854460 -7200
#      Tue May 19 04:14:20 2020 +0200
# Node ID ce99bba6375432c55a73c1367f619dfef7c7e9fc
# Parent  2b4f407fb1f8824fed4df9c4c3f15a2493e71677
commit e78f5a6a2124ce88002796d6aaefc6232f132526
Author: Hans Petter Jansson <h...@cl.no>
    AES Keywrap POST.

diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c
--- a/lib/freebl/fipsfreebl.c
+++ b/lib/freebl/fipsfreebl.c
@@ -110,6 +110,9 @@
 #define FIPS_AES_192_KEY_SIZE 24   /* 192-bits */
 #define FIPS_AES_256_KEY_SIZE 32   /* 256-bits */
 
+/* FIPS preprocessor directives for AES Keywrap */
+#define FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE 24  /* 192-bits */
+
 /* FIPS preprocessor directives for message digests             */
 #define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
 
@@ -299,6 +302,9 @@
 
     static const PRUint8 aes_gcm_known_aad[] = { "MozillaallizoM" };
 
+    /* AES Keywrap Known Initialization Vector (64 bits) */
+    static const PRUint8 aes_key_wrap_iv[] = { "WrapparW" };
+
     /* AES Known Ciphertext (128-bit key). */
     static const PRUint8 aes_ecb128_known_ciphertext[] = {
         0x3c, 0xa5, 0x96, 0xf3, 0x34, 0x6a, 0x96, 0xc1,
@@ -353,6 +359,25 @@
         0xf4, 0xb0, 0xc1, 0x8c, 0x86, 0x51, 0xf5, 0xa1
     };
 
+    /* AES Keywrap Known Ciphertexts. */
+    static const PRUint8 aes_kw128_known_ciphertext[] = {
+        0xd7, 0xec, 0x33, 0x3a, 0x35, 0x50, 0x91, 0x4d,
+        0x04, 0x69, 0x1f, 0xbc, 0x9b, 0x3a, 0x51, 0x9d,
+        0xf3, 0x45, 0x01, 0xec, 0xaa, 0x43, 0x33, 0x42
+    };
+
+    static const PRUint8 aes_kw192_known_ciphertext[] = {
+        0x18, 0x44, 0xab, 0x72, 0xbd, 0x35, 0x6c, 0x8f,
+        0x34, 0x34, 0x2e, 0x0b, 0xb0, 0x19, 0xd3, 0x46,
+        0x3e, 0x53, 0x4f, 0x2f, 0x43, 0xcc, 0xf5, 0x8c
+    };
+
+    static const PRUint8 aes_kw256_known_ciphertext[] = {
+        0x3e, 0xaf, 0xf3, 0x36, 0xaf, 0xc3, 0x68, 0xab,
+        0x5a, 0x07, 0xed, 0x64, 0x5b, 0xf8, 0x81, 0x0d,
+        0x9e, 0x67, 0x75, 0xbd, 0x66, 0xe1, 0x52, 0xdc
+    };
+
     const PRUint8 *aes_ecb_known_ciphertext =
         (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext 
: (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext : 
aes_ecb256_known_ciphertext;
 
@@ -362,10 +387,14 @@
     const PRUint8 *aes_gcm_known_ciphertext =
         (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_gcm128_known_ciphertext 
: (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_gcm192_known_ciphertext : 
aes_gcm256_known_ciphertext;
 
+    const PRUint8 *aes_keywrap_known_ciphertext =
+        (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_kw128_known_ciphertext : 
(aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_kw192_known_ciphertext : 
aes_kw256_known_ciphertext;
+
     /* AES variables. */
     PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2];
     PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2];
     AESContext *aes_context;
+    AESKeyWrapContext *aes_keywrap_context;
     unsigned int aes_bytes_encrypted;
     unsigned int aes_bytes_decrypted;
     CK_NSS_GCM_PARAMS gcmParams;
@@ -554,6 +583,52 @@
         return (SECFailure);
     }
 
+    /********************************/
+    /* AES Keywrap En/Decrypt Test. */
+    /********************************/
+
+    /* Create encryption context */
+    aes_keywrap_context = AESKeyWrap_CreateContext(aes_known_key, 
aes_key_wrap_iv, PR_TRUE,
+                                                   aes_key_size);
+    if (aes_keywrap_context == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return (SECFailure);
+    }
+
+    aes_status = AESKeyWrap_Encrypt(aes_keywrap_context,
+                                    aes_computed_ciphertext, 
&aes_bytes_encrypted,
+                                    FIPS_AES_ENCRYPT_LENGTH * 2,
+                                    aes_known_plaintext, 
FIPS_AES_ENCRYPT_LENGTH);
+
+    AESKeyWrap_DestroyContext(aes_keywrap_context, PR_TRUE);
+
+    if ((aes_status != SECSuccess) ||
+        (aes_bytes_encrypted != FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE) ||
+        (PORT_Memcmp (aes_computed_ciphertext, aes_keywrap_known_ciphertext,
+                      FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE) != 0)) {
+        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+        return (SECFailure);
+    }
+
+    /* Create decryption context */
+    aes_keywrap_context = AESKeyWrap_CreateContext(aes_known_key, 
aes_key_wrap_iv, PR_FALSE,
+                                                   aes_key_size);
+
+    aes_status = AESKeyWrap_Decrypt(aes_keywrap_context,
+                                    aes_computed_plaintext, 
&aes_bytes_decrypted,
+                                    FIPS_AES_ENCRYPT_LENGTH,
+                                    aes_computed_ciphertext, 
aes_bytes_encrypted);
+
+    AESKeyWrap_DestroyContext(aes_keywrap_context, PR_TRUE);
+
+    if ((aes_status != SECSuccess) ||
+        (aes_bytes_decrypted != FIPS_AES_ENCRYPT_LENGTH) ||
+        (PORT_Memcmp (aes_computed_plaintext, aes_known_plaintext,
+                      FIPS_AES_ENCRYPT_LENGTH) != 0)) {
+        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+        return (SECFailure);
+    }
+
     return (SECSuccess);
 }
 
++++++ nss-fips-approved-crypto-non-ec.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1590413430 -7200
#      Mon May 25 15:30:30 2020 +0200
# Node ID 2d4483f4a1259f965f32ff4c65436e92aef83be7
# Parent  3f4d682c9a1e8b3d939c744ee249e23179db5191
imported patch nss-fips-approved-crypto-non-ec.patch

diff --git a/lib/freebl/alg2268.c b/lib/freebl/alg2268.c
--- a/lib/freebl/alg2268.c
+++ b/lib/freebl/alg2268.c
@@ -16,6 +16,8 @@
 #include <stddef.h> /* for ptrdiff_t */
 #endif
 
+#include "fips.h"
+
 /*
 ** RC2 symmetric block cypher
 */
@@ -119,6 +121,7 @@
 RC2Context *
 RC2_AllocateContext(void)
 {
+    IN_FIPS_RETURN(NULL);
     return PORT_ZNew(RC2Context);
 }
 SECStatus
@@ -133,6 +136,8 @@
 #endif
     PRUint8 tmpB;
 
+    IN_FIPS_RETURN(SECFailure);
+
     if (!key || !cx || !len || len > (sizeof cx->B) ||
         efLen8 > (sizeof cx->B)) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -204,7 +209,11 @@
 RC2_CreateContext(const unsigned char *key, unsigned int len,
                   const unsigned char *iv, int mode, unsigned efLen8)
 {
-    RC2Context *cx = PORT_ZNew(RC2Context);
+    RC2Context *cx;
+
+    IN_FIPS_RETURN(NULL);
+
+    cx = PORT_ZNew(RC2Context);
     if (cx) {
         SECStatus rv = RC2_InitContext(cx, key, len, iv, mode, efLen8, 0);
         if (rv != SECSuccess) {
@@ -456,7 +465,11 @@
             unsigned int *outputLen, unsigned int maxOutputLen,
             const unsigned char *input, unsigned int inputLen)
 {
-    SECStatus rv = SECSuccess;
+    SECStatus rv;
+
+    IN_FIPS_RETURN(SECFailure);
+
+    rv = SECSuccess;
     if (inputLen) {
         if (inputLen % RC2_BLOCK_SIZE) {
             PORT_SetError(SEC_ERROR_INPUT_LEN);
@@ -490,7 +503,11 @@
             unsigned int *outputLen, unsigned int maxOutputLen,
             const unsigned char *input, unsigned int inputLen)
 {
-    SECStatus rv = SECSuccess;
+    SECStatus rv;
+
+    IN_FIPS_RETURN(SECFailure);
+
+    rv = SECSuccess;
     if (inputLen) {
         if (inputLen % RC2_BLOCK_SIZE) {
             PORT_SetError(SEC_ERROR_INPUT_LEN);
diff --git a/lib/freebl/arcfour.c b/lib/freebl/arcfour.c
--- a/lib/freebl/arcfour.c
+++ b/lib/freebl/arcfour.c
@@ -13,6 +13,7 @@
 
 #include "prtypes.h"
 #include "blapi.h"
+#include "fips.h"
 
 /* Architecture-dependent defines */
 
@@ -108,6 +109,7 @@
 RC4Context *
 RC4_AllocateContext(void)
 {
+    IN_FIPS_RETURN(NULL);
     return PORT_ZNew(RC4Context);
 }
 
@@ -121,6 +123,8 @@
     PRUint8 K[256];
     PRUint8 *L;
 
+    IN_FIPS_RETURN(SECFailure);
+
     /* verify the key length. */
     PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE);
     if (len == 0 || len >= ARCFOUR_STATE_SIZE) {
@@ -162,7 +166,11 @@
 RC4Context *
 RC4_CreateContext(const unsigned char *key, int len)
 {
-    RC4Context *cx = RC4_AllocateContext();
+    RC4Context *cx;
+
+    IN_FIPS_RETURN(NULL);
+
+    cx = RC4_AllocateContext();
     if (cx) {
         SECStatus rv = RC4_InitContext(cx, key, len, NULL, 0, 0, 0);
         if (rv != SECSuccess) {
@@ -176,6 +184,7 @@
 void
 RC4_DestroyContext(RC4Context *cx, PRBool freeit)
 {
+    IN_FIPS_RETURN();
     if (freeit)
         PORT_ZFree(cx, sizeof(*cx));
 }
@@ -548,6 +557,8 @@
             unsigned int *outputLen, unsigned int maxOutputLen,
             const unsigned char *input, unsigned int inputLen)
 {
+    IN_FIPS_RETURN(SECFailure);
+
     PORT_Assert(maxOutputLen >= inputLen);
     if (maxOutputLen < inputLen) {
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -571,6 +582,8 @@
             unsigned int *outputLen, unsigned int maxOutputLen,
             const unsigned char *input, unsigned int inputLen)
 {
+    IN_FIPS_RETURN(SECFailure);
+
     PORT_Assert(maxOutputLen >= inputLen);
     if (maxOutputLen < inputLen) {
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
diff --git a/lib/freebl/deprecated/seed.c b/lib/freebl/deprecated/seed.c
--- a/lib/freebl/deprecated/seed.c
+++ b/lib/freebl/deprecated/seed.c
@@ -17,6 +17,8 @@
 #include "seed.h"
 #include "secerr.h"
 
+#include "../fips.h"
+
 static const seed_word SS[4][256] = {
     { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
       0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
@@ -301,6 +303,8 @@
     seed_word K0, K1, K2, K3;
     seed_word t0, t1;
 
+    IN_FIPS_RETURN();
+
     char2word(rawkey, K0);
     char2word(rawkey + 4, K1);
     char2word(rawkey + 8, K2);
@@ -349,6 +353,8 @@
     seed_word L0, L1, R0, R1;
     seed_word t0, t1;
 
+    IN_FIPS_RETURN();
+
     char2word(s, L0);
     char2word(s + 4, L1);
     char2word(s + 8, R0);
@@ -385,6 +391,8 @@
     seed_word L0, L1, R0, R1;
     seed_word t0, t1;
 
+    IN_FIPS_RETURN();
+
     char2word(s, L0);
     char2word(s + 4, L1);
     char2word(s + 8, R0);
@@ -419,6 +427,8 @@
                  size_t inLen,
                  const SEED_KEY_SCHEDULE *ks, int enc)
 {
+    IN_FIPS_RETURN();
+
     if (enc) {
         while (inLen > 0) {
             SEED_encrypt(in, out, ks);
@@ -445,6 +455,8 @@
     unsigned char tmp[SEED_BLOCK_SIZE];
     const unsigned char *iv = ivec;
 
+    IN_FIPS_RETURN();
+
     if (enc) {
         while (len >= SEED_BLOCK_SIZE) {
             for (n = 0; n < SEED_BLOCK_SIZE; ++n) {
@@ -528,6 +540,7 @@
 SEEDContext *
 SEED_AllocateContext(void)
 {
+    IN_FIPS_RETURN(NULL);
     return PORT_ZNew(SEEDContext);
 }
 
@@ -536,6 +549,8 @@
                  unsigned int keylen, const unsigned char *iv,
                  int mode, unsigned int encrypt, unsigned int unused)
 {
+    IN_FIPS_RETURN(SECFailure);
+
     if (!cx) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
@@ -567,10 +582,14 @@
 SEED_CreateContext(const unsigned char *key, const unsigned char *iv,
                    int mode, PRBool encrypt)
 {
-    SEEDContext *cx = PORT_ZNew(SEEDContext);
-    SECStatus rv = SEED_InitContext(cx, key, SEED_KEY_LENGTH, iv, mode,
-                                    encrypt, 0);
+    SEEDContext *cx;
+    SECStatus rv;
 
+    IN_FIPS_RETURN(NULL);
+
+    cx = PORT_ZNew(SEEDContext);
+    rv = SEED_InitContext(cx, key, SEED_KEY_LENGTH, iv, mode,
+                          encrypt, 0);
     if (rv != SECSuccess) {
         PORT_ZFree(cx, sizeof *cx);
         cx = NULL;
@@ -595,6 +614,8 @@
              unsigned int maxOutLen, const unsigned char *in,
              unsigned int inLen)
 {
+    IN_FIPS_RETURN(SECFailure);
+
     if (!cx) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
@@ -635,6 +656,8 @@
              unsigned int maxOutLen, const unsigned char *in,
              unsigned int inLen)
 {
+    IN_FIPS_RETURN(SECFailure);
+
     if (!cx) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
diff --git a/lib/freebl/fips.h b/lib/freebl/fips.h
--- a/lib/freebl/fips.h
+++ b/lib/freebl/fips.h
@@ -8,8 +8,20 @@
 #ifndef FIPS_H
 #define FIPS_H
 
+#include "hasht.h"
+#include "secerr.h"
+
+#define IN_FIPS_RETURN(rv) \
+    do { \
+       if (FIPS_mode()) { \
+           PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); \
+           return rv; \
+       } \
+    } while (0)
+
 int    FIPS_mode(void);
 char*  FIPS_rngDev(void);
+PRBool FIPS_hashAlgApproved(HASH_HashType hashAlg);
 
 #endif
 
diff --git a/lib/freebl/md2.c b/lib/freebl/md2.c
--- a/lib/freebl/md2.c
+++ b/lib/freebl/md2.c
@@ -13,6 +13,8 @@
 
 #include "blapi.h"
 
+#include "fips.h"
+
 #define MD2_DIGEST_LEN 16
 #define MD2_BUFSIZE 16
 #define MD2_X_SIZE 48  /* The X array, [CV | INPUT | TMP VARS] */
@@ -66,7 +68,11 @@
 MD2_Hash(unsigned char *dest, const char *src)
 {
     unsigned int len;
-    MD2Context *cx = MD2_NewContext();
+    MD2Context *cx;
+
+    IN_FIPS_RETURN(SECFailure);
+
+    cx = MD2_NewContext();
     if (!cx) {
         PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
         return SECFailure;
@@ -81,7 +87,11 @@
 MD2Context *
 MD2_NewContext(void)
 {
-    MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
+    MD2Context *cx;
+
+    IN_FIPS_RETURN(NULL);
+
+    cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
     if (cx == NULL) {
         PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
         return NULL;
@@ -99,6 +109,8 @@
 void
 MD2_Begin(MD2Context *cx)
 {
+    IN_FIPS_RETURN();
+
     memset(cx, 0, sizeof(*cx));
     cx->unusedBuffer = MD2_BUFSIZE;
 }
@@ -196,6 +208,8 @@
 {
     PRUint32 bytesToConsume;
 
+    IN_FIPS_RETURN();
+
     /* Fill the remaining input buffer. */
     if (cx->unusedBuffer != MD2_BUFSIZE) {
         bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer);
@@ -226,6 +240,9 @@
         unsigned int *digestLen, unsigned int maxDigestLen)
 {
     PRUint8 padStart;
+
+    IN_FIPS_RETURN();
+
     if (maxDigestLen < MD2_BUFSIZE) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return;
diff --git a/lib/freebl/md5.c b/lib/freebl/md5.c
--- a/lib/freebl/md5.c
+++ b/lib/freebl/md5.c
@@ -15,6 +15,8 @@
 #include "blapi.h"
 #include "blapii.h"
 
+#include "fips.h"
+
 #define MD5_HASH_LEN 16
 #define MD5_BUFFER_SIZE 64
 #define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8)
@@ -195,6 +197,7 @@
 SECStatus
 MD5_Hash(unsigned char *dest, const char *src)
 {
+    IN_FIPS_RETURN(SECFailure);
     return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
 }
 
@@ -204,6 +207,8 @@
     unsigned int len;
     MD5Context cx;
 
+    IN_FIPS_RETURN(SECFailure);
+
     MD5_Begin(&cx);
     MD5_Update(&cx, src, src_length);
     MD5_End(&cx, dest, &len, MD5_HASH_LEN);
@@ -215,7 +220,11 @@
 MD5_NewContext(void)
 {
     /* no need to ZAlloc, MD5_Begin will init the context */
-    MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
+    MD5Context *cx;
+
+    IN_FIPS_RETURN(NULL);
+
+    cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
     if (cx == NULL) {
         PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
         return NULL;
@@ -226,7 +235,8 @@
 void
 MD5_DestroyContext(MD5Context *cx, PRBool freeit)
 {
-    memset(cx, 0, sizeof *cx);
+    if (cx)
+        memset(cx, 0, sizeof *cx);
     if (freeit) {
         PORT_Free(cx);
     }
@@ -235,6 +245,8 @@
 void
 MD5_Begin(MD5Context *cx)
 {
+    IN_FIPS_RETURN();
+
     cx->lsbInput = 0;
     cx->msbInput = 0;
     /*  memset(cx->inBuf, 0, sizeof(cx->inBuf)); */
@@ -425,6 +437,8 @@
     PRUint32 inBufIndex = cx->lsbInput & 63;
     const PRUint32 *wBuf;
 
+    IN_FIPS_RETURN();
+
     /* Add the number of input bytes to the 64-bit input counter. */
     addto64(cx->msbInput, cx->lsbInput, inputLen);
     if (inBufIndex) {
@@ -498,6 +512,8 @@
     PRUint32 lowInput, highInput;
     PRUint32 inBufIndex = cx->lsbInput & 63;
 
+    IN_FIPS_RETURN();
+
     if (maxDigestLen < MD5_HASH_LEN) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return;
@@ -546,6 +562,8 @@
 #endif
     PRUint32 cv[4];
 
+    IN_FIPS_RETURN();
+
     if (maxDigestLen < MD5_HASH_LEN) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return;
diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c
--- a/lib/freebl/nsslowhash.c
+++ b/lib/freebl/nsslowhash.c
@@ -12,6 +12,7 @@
 #include "plhash.h"
 #include "nsslowhash.h"
 #include "blapii.h"
+#include "fips.h"
 
 struct NSSLOWInitContextStr {
     int count;
@@ -92,6 +93,12 @@
 {
     NSSLOWHASHContext *context;
 
+    /* return with an error if unapproved hash is requested in FIPS mode */
+    if (!FIPS_hashAlgApproved(hashType)) {
+       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+       return NULL;
+    }
+
     if (post_failed) {
         PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
         return NULL;
diff --git a/lib/freebl/rawhash.c b/lib/freebl/rawhash.c
--- a/lib/freebl/rawhash.c
+++ b/lib/freebl/rawhash.c
@@ -10,6 +10,7 @@
 #include "hasht.h"
 #include "blapi.h" /* below the line */
 #include "secerr.h"
+#include "fips.h"
 
 static void *
 null_hash_new_context(void)
@@ -146,7 +147,8 @@
 const SECHashObject *
 HASH_GetRawHashObject(HASH_HashType hashType)
 {
-    if (hashType <= HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
+    if (hashType <= HASH_AlgNULL || hashType >= HASH_AlgTOTAL
+        || (!FIPS_hashAlgApproved(hashType))) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return NULL;
     }
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -7282,7 +7282,7 @@
             } else {
                 /* now allocate the hash contexts */
                 md5 = MD5_NewContext();
-                if (md5 == NULL) {
+                if (md5 == NULL && !isTLS) {
                     crv = CKR_HOST_MEMORY;
                     break;
                 }
++++++ nss-fips-cavs-dsa-fixes.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574237264 -3600
#      Wed Nov 20 09:07:44 2019 +0100
# Node ID 0e904e6179d1db21965df2c405c80c3fc0258658
# Parent  969310ea4c573aac64bf08846b8938b8fa783870
[PATCH] 24
>From ef2620b770082c77dbbbccae2e773157897b005d Mon Sep 17 00:00:00 2001
---
 nss/cmd/fipstest/fipstest.c | 112 ++++++++++++++++++++++++++++++++----
 1 file changed, 101 insertions(+), 11 deletions(-)

diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -5576,7 +5576,7 @@
 void
 dsa_pqggen_test(char *reqfn)
 {
-    char buf[800]; /* holds one line from the input REQUEST file
+    char buf[2048]; /* holds one line from the input REQUEST file
                          * or to the output RESPONSE file.
                          * 800 to hold seed = (384 public key (x2 for HEX)
                          */
@@ -5592,6 +5592,13 @@
     PQGVerify *vfy = NULL;
     unsigned int keySizeIndex = 0;
     dsa_pqg_type type = FIPS186_1;
+    SECItem P = { 0, 0, 0 };
+    SECItem Q = { 0, 0, 0 };
+    SECItem firstseed = { 0, 0, 0 };
+    SECItem pseed = { 0, 0, 0 };
+    SECItem qseed = { 0, 0, 0 };
+    SECItem index = { 0, 0, 0 };
+    HASH_HashType hashtype = HASH_AlgNULL;
 
     dsareq = fopen(reqfn, "r");
     dsaresp = stdout;
@@ -5612,8 +5619,8 @@
                 output_g = 1;
                 exit(1);
             } else if (strncmp(&buf[1], "A.2.3", 5) == 0) {
-                fprintf(stderr, "NSS only Generates G with P&Q\n");
-                exit(1);
+                type = A_2_3;
+                output_g = 1;
             } else if (strncmp(&buf[1], "A.1.2.1", 7) == 0) {
                 type = A_1_2_1;
                 output_g = 0;
@@ -5627,14 +5634,17 @@
 
         /* [Mod = ... ] */
         if (buf[0] == '[') {
+            int hashbits;
 
             if (type == FIPS186_1) {
                 N = 160;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
                 }
-            } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
-                goto loser;
+            } else if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d", &L, &N, 
&hashbits) != 3) {
+                goto loser;
+            } else {
+                hashtype = sha_get_hashType (hashbits);
             }
 
             fputs(buf, dsaresp);
@@ -5656,7 +5666,7 @@
             continue;
         }
         /* N = ... */
-        if (buf[0] == 'N') {
+        if (buf[0] == 'N' && type != A_2_3) {
             if (strncmp(buf, "Num", 3) == 0) {
                 if (sscanf(buf, "Num = %d", &count) != 1) {
                     goto loser;
@@ -5671,7 +5681,10 @@
                     rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
                                              &pqg, &vfy);
                 } else {
-                    rv = PQG_ParamGenV2(L, N, N, &pqg, &vfy);
+                    if (firstseed.data)
+                        SECITEM_ZfreeItem(&firstseed, PR_FALSE);
+
+                    rv = FREEBL_Test_PQG_ParamGenV2_p(L, N, 0, &pqg, &vfy, 
&firstseed, hashtype);
                 }
                 if (rv != SECSuccess) {
                     fprintf(dsaresp,
@@ -5682,6 +5695,10 @@
                 fprintf(dsaresp, "P = %s\n", buf);
                 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
                 fprintf(dsaresp, "Q = %s\n", buf);
+                if (firstseed.data) {
+                    to_hex_str(buf, firstseed.data, firstseed.len);
+                    fprintf(dsaresp, "firstseed = %s\n", buf);
+                }
                 if (output_g) {
                     to_hex_str(buf, pqg->base.data, pqg->base.len);
                     fprintf(dsaresp, "G = %s\n", buf);
@@ -5697,13 +5714,13 @@
                     }
                     fprintf(dsaresp, "%s\n", buf);
                 } else {
-                    unsigned int seedlen = vfy->seed.len / 2;
-                    unsigned int pgen_counter = vfy->counter >> 16;
-                    unsigned int qgen_counter = vfy->counter & 0xffff;
+                    unsigned int seedlen = (vfy->seed.len - firstseed.len) / 2;
+                    unsigned int pgen_counter = vfy->counter & 0xffff;
+                    unsigned int qgen_counter = vfy->counter >> 16;
                     /*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
-                    to_hex_str(buf, vfy->seed.data, seedlen);
+                    to_hex_str(buf, vfy->seed.data + firstseed.len, seedlen);
                     fprintf(dsaresp, "pseed = %s\n", buf);
-                    to_hex_str(buf, vfy->seed.data + seedlen, seedlen);
+                    to_hex_str(buf, vfy->seed.data + firstseed.len + seedlen, 
seedlen);
                     fprintf(dsaresp, "qseed = %s\n", buf);
                     fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter);
                     fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter);
@@ -5723,12 +5740,85 @@
                     vfy = NULL;
                 }
             }
-
+            continue;
+        }
+
+        if (parse_secitem ("P", buf, &P)) {
+            fputs(buf, dsaresp);
+            continue;
+        }
+        if (parse_secitem ("Q", buf, &Q)) {
+            fputs(buf, dsaresp);
+            continue;
+        }
+        if (parse_secitem ("firstseed", buf, &firstseed)) {
+            fputs(buf, dsaresp);
+            continue;
+        }
+        if (parse_secitem ("pseed", buf, &pseed)) {
+            fputs(buf, dsaresp);
+            continue;
+        }
+        if (parse_secitem ("qseed", buf, &qseed)) {
+            fputs(buf, dsaresp);
+            continue;
+        }
+        if (parse_secitem ("index", buf, &index) && type == A_2_3) {
+            SECStatus rv;
+            PLArenaPool *arena;
+
+            fputs(buf, dsaresp);
+
+            arena = PORT_NewArena (NSS_FREEBL_DEFAULT_CHUNKSIZE);
+            pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
+            pqg->arena = arena;
+
+            arena = PORT_NewArena (NSS_FREEBL_DEFAULT_CHUNKSIZE);
+            vfy = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
+            vfy->arena = arena;
+
+            SECITEM_CopyItem(pqg->arena, &pqg->prime, &P);
+            SECITEM_CopyItem(pqg->arena, &pqg->subPrime, &Q);
+
+            SECITEM_AllocItem(vfy->arena, &vfy->seed, firstseed.len + 
pseed.len + qseed.len);
+            memcpy (vfy->seed.data, firstseed.data, firstseed.len);
+            memcpy (vfy->seed.data + firstseed.len, pseed.data, pseed.len);
+            memcpy (vfy->seed.data + firstseed.len + pseed.len, qseed.data, 
qseed.len);
+
+            SECITEM_AllocItem(vfy->arena, &vfy->h, 1);
+            vfy->h.data [0] = index.data [0];
+
+            rv = FREEBL_Test_PQG_ParamGenV2_p(L, N, 0, &pqg, &vfy, &firstseed, 
hashtype);
+            if (rv != SECSuccess) {
+                fprintf(dsaresp,
+                        "ERROR: Unable to verify PQG parameters");
+                goto loser;
+            }
+
+            to_hex_str(buf, pqg->base.data, pqg->base.len);
+            fprintf(dsaresp, "G = %s\n\n", buf);
+
+            PQG_DestroyParams(pqg);
+            pqg = NULL;
+            PQG_DestroyVerify(vfy);
+            vfy = NULL;
             continue;
         }
     }
 loser:
     fclose(dsareq);
+    if (P.data)
+        SECITEM_ZfreeItem(&P, PR_FALSE);
+    if (Q.data)
+        SECITEM_ZfreeItem(&Q, PR_FALSE);
+    if (firstseed.data)
+        SECITEM_ZfreeItem(&firstseed, PR_FALSE);
+    if (pseed.data)
+        SECITEM_ZfreeItem(&pseed, PR_FALSE);
+    if (qseed.data)
+        SECITEM_ZfreeItem(&qseed, PR_FALSE);
+    if (index.data)
+        SECITEM_ZfreeItem(&index, PR_FALSE);
     if (pqg != NULL) {
         PQG_DestroyParams(pqg);
     }
++++++ nss-fips-cavs-general.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1590413427 -7200
#      Mon May 25 15:30:27 2020 +0200
# Node ID 969310ea4c573aac64bf08846b8938b8fa783870
# Parent  60c5e5d73ce1177fa66d8fd6cf49d9b371ca9be4
imported patch nss-fips-cavs-general.patch

diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <dlfcn.h>
 
 #include "secitem.h"
 #include "blapi.h"
@@ -18,6 +19,9 @@
 #include "lowkeyi.h"
 #include "softoken.h"
 #include "pkcs11t.h"
+
+#include "../../lib/freebl/fips.h"
+
 #define __PASTE(x, y) x##y
 #undef CK_PKCS11_FUNCTION_INFO
 #undef CK_NEED_ARG_LIST
@@ -55,6 +59,10 @@
 #define RSA_MAX_TEST_EXPONENT_BYTES 8
 #define PQG_TEST_SEED_BYTES 20
 
+SECStatus (*FREEBL_Test_PQG_ParamGenV2_p) (unsigned int L, unsigned int N, 
unsigned int seedBytes,
+                                           PQGParams **pParams, PQGVerify 
**pVfy,
+                                           SECItem *firstseed, HASH_HashType 
hashtype);
+
 SECStatus
 hex_to_byteval(const char *c2, unsigned char *byteval)
 {
@@ -168,6 +176,62 @@
     return PR_TRUE;
 }
 
+#if 0
+
+static void
+dump_secitem (FILE *out, SECItem *secitem)
+{
+    char buf [4096];
+
+    to_hex_str(buf, secitem->data, secitem->len);
+    fputs (buf, out);
+}
+
+static void
+dump_labeled_secitem (FILE *out, const char *name, SECItem *secitem)
+{
+    fprintf (out, "%s = ", name);
+    dump_secitem (out, secitem);
+    fputs ("\n", out);
+}
+
+#endif
+
+static int
+parse_secitem (const char *name, const char *buf, SECItem *secitem)
+{
+    if (!strncmp (buf, name, strlen (name))) {
+        int i, j, len;
+
+        i = strlen (name);
+        while (isspace(buf[i]) || buf[i] == '=') {
+            i++;
+        }
+
+        len = strspn (&buf[i], "0123456789abcdefABCDEF");
+        if (!len)
+            return 0;
+
+        if (secitem->data) {
+            SECITEM_ZfreeItem(secitem, PR_FALSE);
+            secitem->data = NULL;
+        }
+
+        len = (len + 1) / 2;
+        SECITEM_AllocItem(NULL, secitem, len);
+        secitem->len = len;
+
+        memset(secitem->data, 0, secitem->len);
+        for (j = 0; j < secitem->len; i += 2, j++) {
+            hex_to_byteval(&buf[i], &secitem->data[j]);
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
+
 SECStatus
 tdea_encrypt_buf(
     int mode,
@@ -8930,41 +8994,6 @@
     }
 }
 
-static int
-parse_secitem (const char *name, const char *buf, SECItem *secitem)
-{
-    if (!strncmp (buf, name, strlen (name))) {
-        int i, j, len;
-
-        i = strlen (name);
-        while (isspace(buf[i]) || buf[i] == '=') {
-            i++;
-        }
-
-        len = strspn (&buf[i], "0123456789abcdefABCDEF");
-        if (!len)
-            return 0;
-
-        if (secitem->data) {
-            SECITEM_ZfreeItem(secitem, PR_FALSE);
-            secitem->data = NULL;
-        }
-
-        len = (len + 1) / 2;
-        SECITEM_AllocItem(NULL, secitem, len);
-        secitem->len = len;
-
-        memset(secitem->data, 0, secitem->len);
-        for (j = 0; j < secitem->len; i += 2, j++) {
-            hex_to_byteval(&buf[i], &secitem->data[j]);
-        }
-
-        return 1;
-    }
-
-    return 0;
-}
-
 void
 kas_ffc_test(char *reqfn, int do_validity)
 {
@@ -9387,12 +9416,34 @@
     free_param_specs (pspecs);
 }
 
+static void
+init_functions (void)
+{
+    void *freebl_so;
+
+    freebl_so = dlopen ("libfreeblpriv3.so", RTLD_LAZY);
+    if (freebl_so == NULL)
+    {
+        fprintf (stderr, "Failed to load libfreeblpriv3.so.");
+        exit (1);
+    }
+
+    FREEBL_Test_PQG_ParamGenV2_p = dlsym (freebl_so, 
"FREEBL_Test_PQG_ParamGenV2");
+
+    if (FREEBL_Test_PQG_ParamGenV2_p == NULL)
+    {
+        fprintf (stderr, "Failed to bind FREEBL_TEST_PQG_ParamGenV2.");
+        exit (1);
+    }
+}
+
 int
 main(int argc, char **argv)
 {
     if (argc < 2)
         exit(-1);
 
+    init_functions();
     RNG_RNGInit();
     SECOID_Init();
 
diff --git a/lib/freebl/freebl.def b/lib/freebl/freebl.def
--- a/lib/freebl/freebl.def
+++ b/lib/freebl/freebl.def
@@ -21,6 +21,7 @@
 LIBRARY freebl3 ;-
 EXPORTS        ;-
 FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
 ;+    local:
 ;+       *;
 ;+};
diff --git a/lib/freebl/freebl_hash.def b/lib/freebl/freebl_hash.def
--- a/lib/freebl/freebl_hash.def
+++ b/lib/freebl/freebl_hash.def
@@ -21,6 +21,7 @@
 LIBRARY freebl3 ;-
 EXPORTS        ;-
 FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
 ;+    local:
 ;+       *;
 ;+};
diff --git a/lib/freebl/freebl_hash_vector.def 
b/lib/freebl/freebl_hash_vector.def
--- a/lib/freebl/freebl_hash_vector.def
+++ b/lib/freebl/freebl_hash_vector.def
@@ -21,6 +21,7 @@
 LIBRARY freebl3 ;-
 EXPORTS        ;-
 FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
 ;+    local:
 ;+       *;
 ;+};
diff --git a/lib/freebl/pqg.c b/lib/freebl/pqg.c
--- a/lib/freebl/pqg.c
+++ b/lib/freebl/pqg.c
@@ -1231,7 +1231,8 @@
 **/
 static SECStatus
 pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
-             unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
+             unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy,
+             SECItem *firstseed_out, HASH_HashType hashtype)
 {
     unsigned int n;       /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     unsigned int seedlen; /* Per FIPS 186-3 app A.1.1.2  (was 'g' 186-1)*/
@@ -1239,7 +1240,6 @@
     unsigned int offset;  /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     unsigned int outlen;  /* Per FIPS 186-3, appendix A.1.1.2. */
     unsigned int maxCount;
-    HASH_HashType hashtype = HASH_AlgNULL;
     SECItem *seed; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
     PLArenaPool *arena = NULL;
     PQGParams *params = NULL;
@@ -1290,7 +1290,8 @@
         /* fill in P Q,  */
         SECITEM_TO_MPINT((*pParams)->prime, &P);
         SECITEM_TO_MPINT((*pParams)->subPrime, &Q);
-        hashtype = getFirstHash(L, N);
+        if (hashtype == HASH_AlgNULL)
+            hashtype = getFirstHash(L, N);
         CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &(*pVfy)->seed,
                                     (*pVfy)->h.data[0], &G));
         MPINT_TO_SECITEM(&G, &(*pParams)->base, (*pParams)->arena);
@@ -1330,7 +1331,8 @@
     /* Select Hash and Compute lengths. */
     /* getFirstHash gives us the smallest acceptable hash for this key
      * strength */
-    hashtype = getFirstHash(L, N);
+    if (hashtype == HASH_AlgNULL)
+        hashtype = getFirstHash(L, N);
     outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE;
 
     /* Step 3: n = Ceil(L/outlen)-1; (same as n = Floor((L-1)/outlen)) */
@@ -1532,6 +1534,10 @@
     verify->counter = counter;
     *pParams = params;
     *pVfy = verify;
+
+    if (firstseed_out)
+        SECITEM_CopyItem (NULL, firstseed_out, &firstseed);
+
 cleanup:
     if (pseed.data) {
         PORT_Free(pseed.data);
@@ -1576,7 +1582,7 @@
     L = 512 + (j * 64); /* bits in P */
     seedBytes = L / 8;
     return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
-                        pParams, pVfy);
+                        pParams, pVfy, NULL, HASH_AlgNULL);
 }
 
 SECStatus
@@ -1591,7 +1597,7 @@
     }
     L = 512 + (j * 64); /* bits in P */
     return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
-                        pParams, pVfy);
+                        pParams, pVfy, NULL, HASH_AlgNULL);
 }
 
 SECStatus
@@ -1609,7 +1615,26 @@
         /* error code already set */
         return SECFailure;
     }
-    return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy);
+    return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy, 
NULL, HASH_AlgNULL);
+}
+
+SECStatus
+FREEBL_Test_PQG_ParamGenV2 (unsigned int L, unsigned int N, unsigned int 
seedBytes,
+                            PQGParams **pParams, PQGVerify **pVfy, SECItem 
*firstseed_out,
+                            HASH_HashType hashtype)
+{
+    if (N == 0) {
+        N = pqg_get_default_N(L);
+    }
+    if (seedBytes == 0) {
+        /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
+        seedBytes = N / 8;
+    }
+    if (pqg_validate_dsa2(L, N) != SECSuccess) {
+        /* error code already set */
+        return SECFailure;
+    }
+    return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy, 
firstseed_out, hashtype);
 }
 
 /*
++++++ nss-fips-cavs-kas-ecc.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574234615 -3600
#      Wed Nov 20 08:23:35 2019 +0100
# Node ID f5cf5d16deb68e65b5dd4e799d9e8e3098400d62
# Parent  af7d3ee4e96cf685be0b95dff7aa5a1d3ab64a89
[PATCH] 21
>From 4c27df62aa425745620f45710465b0264acacbb0 Mon Sep 17 00:00:00 2001
---
 nss/cmd/fipstest/fipstest.c | 304 ++++++++++++++++++++++++++++++++++++
 nss/cmd/fipstest/kas.sh     |  22 +++
 2 files changed, 326 insertions(+)

diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -9092,6 +9092,301 @@
     }
 }
 
+typedef struct
+{
+    char param_name [2];
+    ECParams *ecparams;
+    int hash_len;
+    HASH_HashType hash_type;
+}
+ParamSpec;
+
+#define PARAM_SPECS_MAX 12
+
+static int
+find_free_param_spec (const ParamSpec *pspecs)
+{
+    int i;
+
+    for (i = 0; i < PARAM_SPECS_MAX; i++)
+    {
+        if (pspecs [i].param_name [0] == 0
+            && pspecs [i].param_name [1] == 0)
+            return i;
+    }
+
+    return 0;
+}
+
+static int
+find_param_spec (const ParamSpec *pspecs, char *name)
+{
+    int i;
+
+    for (i = 0; i < PARAM_SPECS_MAX; i++)
+    {
+        if (pspecs [i].param_name [0] == name [0]
+            && pspecs [i].param_name [1] == name [1])
+            return i;
+    }
+
+    return 0;
+}
+
+static void
+free_param_specs (ParamSpec *pspecs)
+{
+    int i;
+
+    for (i = 0; i < PARAM_SPECS_MAX; i++)
+    {
+        if (pspecs [i].ecparams)
+            PORT_FreeArena(pspecs [i].ecparams->arena, PR_FALSE);
+    }
+}
+
+#define CURVE_NAME_MAX 64
+
+static ECParams *
+get_and_decode_nistp_params (int n)
+{
+    char curve_name [CURVE_NAME_MAX];
+    SECItem *encodedparams;
+    ECParams *ecparams = NULL;
+
+    snprintf (curve_name, CURVE_NAME_MAX, "nistp%d", n);
+
+    encodedparams = getECParams (curve_name);
+    if (!encodedparams)
+        return NULL;
+
+    EC_DecodeParams (encodedparams, &ecparams);
+    SECITEM_FreeItem(encodedparams, PR_TRUE);
+    return ecparams;
+}
+
+void
+kas_ecc_test(char *reqfn, int do_validity)
+{
+    char buf[2048];
+    FILE *req;  /* input stream from the REQUEST file */
+    FILE *resp; /* output stream to the RESPONSE file */
+    ParamSpec pspecs [PARAM_SPECS_MAX];
+    SECItem x_ephem_cavs;
+    SECItem y_ephem_cavs;
+    SECItem x_ephem_iut;
+    SECItem y_ephem_iut;
+    SECItem d_ephem_iut;
+    SECItem cavs_hash_zz;
+    SECItem publicValue;
+    int current_pspec_def = -1;
+
+    req = fopen(reqfn, "r");
+    resp = stdout;
+    memset(&pspecs, 0, sizeof (pspecs));
+    memset(&x_ephem_cavs, 0, sizeof(x_ephem_cavs));
+    memset(&y_ephem_cavs, 0, sizeof(y_ephem_cavs));
+    memset(&x_ephem_iut, 0, sizeof(x_ephem_iut));
+    memset(&y_ephem_iut, 0, sizeof(y_ephem_iut));
+    memset(&d_ephem_iut, 0, sizeof(d_ephem_iut));
+    memset(&cavs_hash_zz, 0, sizeof(cavs_hash_zz));
+    memset(&publicValue, 0, sizeof(publicValue));
+
+    while (fgets(buf, sizeof buf, req) != NULL) {
+        /* [xx] or
+         * [xx - SHAxxx] or
+         * [SHA(s) supported (Used for hashing Z):  SHAxxx] */
+        if (buf[0] == '[') {
+            char tbuf [2];
+            int num;
+
+            if (strlen (buf) >= 4 && buf [3] == ']'
+                && sscanf(buf, "[%c%c]", &tbuf [0], &tbuf [1]) == 2) {
+                int i = current_pspec_def = find_free_param_spec (pspecs);
+                if (i < 0)
+                    goto out;
+
+                pspecs [i].param_name [0] = tbuf [0];
+                pspecs [i].param_name [1] = tbuf [1];
+
+                fputs(buf, resp);
+                continue;
+            }
+
+            if (strlen (buf) >= 6 && buf [3] == ' ' && buf [4] == '-'
+                && sscanf(buf, "[%c%c - ", &tbuf [0], &tbuf [1]) == 2) {
+                current_pspec_def = find_param_spec (pspecs, tbuf);
+                if (current_pspec_def < 0)
+                    goto out;
+
+                fputs(buf, resp);
+                continue;
+            }
+
+            if (!strncmp(buf, "[Curve selected:", strlen ("[Curve 
selected:"))) {
+                char *p = buf + strlen ("[Curve selected:");
+                p += strcspn (p, "0123456789");
+                if (!*p)
+                    goto out;
+                if (sscanf(p, "%d", &num) != 1)
+                    goto out;
+
+                if (current_pspec_def < 0)
+                    goto out;
+
+                pspecs [current_pspec_def].ecparams = 
get_and_decode_nistp_params (num);
+                if (!pspecs [current_pspec_def].ecparams)
+                    goto out;
+
+                fputs(buf, resp);
+                continue;
+            }
+
+            if (sscanf(buf, "[SHA(s) supported (Used for hashing Z): SHA%d", 
&num) == 1) {
+                if (current_pspec_def < 0)
+                    goto out;
+
+                pspecs [current_pspec_def].hash_len = num;
+                pspecs [current_pspec_def].hash_type = sha_get_hashType(num);
+                fputs(buf, resp);
+                continue;
+            }
+
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("QeCAVSx", buf, &x_ephem_cavs)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("QeCAVSy", buf, &y_ephem_cavs)) {
+            fputs(buf, resp);
+
+            if (!do_validity) {
+                SECItem ZZ;
+                unsigned char ZZ_hash_buf [1024];
+                int field_len;
+                int len;
+                ECPrivateKey *privKey;
+
+                field_len = (pspecs [current_pspec_def].ecparams->fieldID.size 
+ 7) >> 3;
+
+                if (EC_NewKey(pspecs [current_pspec_def].ecparams, &privKey) 
!= SECSuccess)
+                    goto out;
+
+                len = privKey->publicValue.len;
+                if (len % 2 == 0) {
+                    goto out;
+                }
+                len = (len - 1) / 2;
+                if (privKey->publicValue.data[0] !=
+                    EC_POINT_FORM_UNCOMPRESSED) {
+                    goto out;
+                }
+
+                to_hex_str(buf, &privKey->publicValue.data[1], len);
+                fprintf (resp, "QeIUTx = %s\n", buf);
+                to_hex_str(buf, &privKey->publicValue.data[1 + len], len);
+                fprintf (resp, "QeIUTy = %s\n", buf);
+
+                SECITEM_AllocItem(NULL, &publicValue, 1 + 2 * field_len);
+                publicValue.len = 1 + 2 * field_len;
+                publicValue.data [0] = EC_POINT_FORM_UNCOMPRESSED;
+                memcpy (&publicValue.data [1], x_ephem_cavs.data + 
x_ephem_cavs.len - field_len, field_len);
+                memcpy (&publicValue.data [1 + field_len], y_ephem_cavs.data + 
y_ephem_cavs.len - field_len, field_len);
+
+                if (ECDH_Derive (&publicValue, pspecs 
[current_pspec_def].ecparams, &privKey->privateValue, PR_TRUE, &ZZ) != 
SECSuccess) {
+                    goto out;
+                }
+
+                SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+                publicValue.data = NULL;
+
+                fips_hashBuf_zeropad(pspecs [current_pspec_def].hash_type, 
ZZ_hash_buf, ZZ.data, ZZ.len, len);
+
+                to_hex_str(buf, ZZ_hash_buf, pspecs 
[current_pspec_def].hash_len / 8);
+                fprintf (resp, "HashZZ = %s\n", buf);
+
+                PORT_FreeArena(privKey->ecParams.arena, PR_TRUE);
+            }
+
+            continue;
+        } else if (parse_secitem ("deIUT", buf, &d_ephem_iut)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("QeIUTx", buf, &x_ephem_iut)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("QeIUTy", buf, &y_ephem_iut)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("CAVSHashZZ", buf, &cavs_hash_zz)) {
+            if (do_validity) {
+                SECItem ZZ;
+                unsigned char ZZ_hash_buf [1024];
+                char Z_buf [1024];
+                int field_len;
+
+                field_len = (pspecs [current_pspec_def].ecparams->fieldID.size 
+ 7) >> 3;
+
+                SECITEM_AllocItem(NULL, &publicValue, 1 + 2 * field_len);
+                publicValue.len = 1 + 2 * field_len;
+                publicValue.data [0] = EC_POINT_FORM_UNCOMPRESSED;
+                memcpy (&publicValue.data [1], x_ephem_cavs.data + 
x_ephem_cavs.len - field_len, field_len);
+                memcpy (&publicValue.data [1 + field_len], y_ephem_cavs.data + 
y_ephem_cavs.len - field_len, field_len);
+
+                if (ECDH_Derive (&publicValue, pspecs 
[current_pspec_def].ecparams, &d_ephem_iut, PR_TRUE, &ZZ) != SECSuccess) {
+                    goto out;
+                }
+
+                SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+                publicValue.data = NULL;
+
+                fputs(buf, resp);
+
+                fips_hashBuf_zeropad(pspecs [current_pspec_def].hash_type, 
ZZ_hash_buf, ZZ.data, ZZ.len, field_len);
+                to_hex_str(Z_buf, ZZ_hash_buf, pspecs 
[current_pspec_def].hash_len / 8);
+                fprintf(resp, "IUTHashZZ = %s\n", Z_buf);
+
+                fprintf(resp, "Result = %s\n",
+                        (cavs_hash_zz.len == pspecs 
[current_pspec_def].hash_len / 8
+                         && memcmp (cavs_hash_zz.data, ZZ_hash_buf, pspecs 
[current_pspec_def].hash_len / 8) == 0) ? "P" : "F");
+            } else {
+                fputs(buf, resp);
+            }
+            continue;
+        } else {
+            /* Comments, blank lines, ... */
+            fputs(buf, resp);
+        }
+    }
+
+out:
+    fclose(req);
+
+    if (d_ephem_iut.data) {
+        SECITEM_ZfreeItem(&d_ephem_iut, PR_FALSE);
+    }
+    if (x_ephem_iut.data) {
+        SECITEM_ZfreeItem(&x_ephem_iut, PR_FALSE);
+    }
+    if (y_ephem_iut.data) {
+        SECITEM_ZfreeItem(&y_ephem_iut, PR_FALSE);
+    }
+    if (x_ephem_cavs.data) {
+        SECITEM_ZfreeItem(&x_ephem_cavs, PR_FALSE);
+    }
+    if (y_ephem_cavs.data) {
+        SECITEM_ZfreeItem(&y_ephem_cavs, PR_FALSE);
+    }
+    if (cavs_hash_zz.data) {
+        SECITEM_ZfreeItem(&cavs_hash_zz, PR_FALSE);
+    }
+    if (publicValue.data) {
+        SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+    }
+
+    free_param_specs (pspecs);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -9287,6 +9582,15 @@
         } else {
             kas_ffc_test(argv[3], PR_FALSE);
         }
+    } else if (strcmp(argv[1], "kasecc") == 0) {
+        /***************/
+        /* KAS ECC */
+        /***************/
+        if (strcmp(argv[2], "validity") == 0) {
+            kas_ecc_test(argv[3], PR_TRUE);
+        } else {
+            kas_ecc_test(argv[3], PR_FALSE);
+        }
     }
     return 0;
 }
diff --git a/cmd/fipstest/kas.sh b/cmd/fipstest/kas.sh
--- a/cmd/fipstest/kas.sh
+++ b/cmd/fipstest/kas.sh
@@ -27,6 +27,16 @@
 KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
 "
 
+kas_requests_ecc_function="
+KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
+KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
+"
+
+kas_requests_ecc_validity="
+KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
+KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
+"
+
 if [ ${COMMAND} = "verify" ]; then
     for request in $kas_requests; do
        sh ./validate1.sh ${TESTDIR} $request
@@ -45,3 +55,15 @@
     echo $request $response
     fipstest kasffc validity ${REQDIR}/$request > ${RSPDIR}/$response
 done
+
+for request in $kas_requests_ecc_function; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest kasecc function ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
+for request in $kas_requests_ecc_validity; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest kasecc validity ${REQDIR}/$request > ${RSPDIR}/$response
+done
++++++ nss-fips-cavs-kas-ffc.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574234297 -3600
#      Wed Nov 20 08:18:17 2019 +0100
# Node ID af7d3ee4e96cf685be0b95dff7aa5a1d3ab64a89
# Parent  5d6e015d1af40b5f5b990d0cf4d97932774c2a61
[PATCH] 20
>From ac98082c3bc0c9f85213078b730980483062f25c Mon Sep 17 00:00:00 2001
---
 nss/cmd/fipstest/fipstest.c | 194 ++++++++++++++++++++++++++++++++++++
 nss/cmd/fipstest/kas.sh     |  47 +++++++++
 2 files changed, 241 insertions(+)
 create mode 100644 nss/cmd/fipstest/kas.sh

diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -2258,6 +2258,29 @@
     return rv;
 }
 
+SECStatus
+fips_hashBuf_zeropad(HASH_HashType type, unsigned char *hashBuf,
+                     unsigned char *msg, int len, int pad_to_len)
+{
+    unsigned char buf [8192];
+
+    if (pad_to_len > 8192)
+    {
+        fprintf (stderr, "Internal buffer too small.\n");
+        exit (1);
+    }
+
+    if (len > pad_to_len)
+    {
+        fprintf (stderr, "Value to hash exceeds maximum length.\n");
+        exit (1);
+    }
+
+    memset (buf, 0, pad_to_len - len);
+    memcpy (buf + (pad_to_len - len), msg, len);
+    return fips_hashBuf (type, hashBuf, buf, pad_to_len);
+}
+
 int
 fips_hashLen(HASH_HashType type)
 {
@@ -8907,6 +8930,168 @@
     }
 }
 
+static int
+parse_secitem (const char *name, const char *buf, SECItem *secitem)
+{
+    if (!strncmp (buf, name, strlen (name))) {
+        int i, j, len;
+
+        i = strlen (name);
+        while (isspace(buf[i]) || buf[i] == '=') {
+            i++;
+        }
+
+        len = strspn (&buf[i], "0123456789abcdefABCDEF");
+        if (!len)
+            return 0;
+
+        if (secitem->data) {
+            SECITEM_ZfreeItem(secitem, PR_FALSE);
+            secitem->data = NULL;
+        }
+
+        len = (len + 1) / 2;
+        SECITEM_AllocItem(NULL, secitem, len);
+        secitem->len = len;
+
+        memset(secitem->data, 0, secitem->len);
+        for (j = 0; j < secitem->len; i += 2, j++) {
+            hex_to_byteval(&buf[i], &secitem->data[j]);
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
+
+void
+kas_ffc_test(char *reqfn, int do_validity)
+{
+    char buf[1024];
+    FILE *req;  /* input stream from the REQUEST file */
+    FILE *resp; /* output stream to the RESPONSE file */
+    PQGParams keyParams;
+    HASH_HashType hashType = HASH_AlgNULL;
+    int hashNum = 0;
+    SECItem y_ephem_cavs;
+    SECItem x_ephem_iut;
+    SECItem y_ephem_iut;
+    SECItem cavs_hash_zz;
+
+    req = fopen(reqfn, "r");
+    resp = stdout;
+    memset(&keyParams, 0, sizeof(keyParams));
+    memset(&y_ephem_cavs, 0, sizeof(y_ephem_cavs));
+    memset(&x_ephem_iut, 0, sizeof(x_ephem_iut));
+    memset(&y_ephem_iut, 0, sizeof(y_ephem_iut));
+    memset(&cavs_hash_zz, 0, sizeof(cavs_hash_zz));
+
+    while (fgets(buf, sizeof buf, req) != NULL) {
+        /* [xx] or
+         * [xx - SHAxxx] or
+         * [SHA(s) supported (Used for hashing Z):  SHAxxx] */
+        if (buf[0] == '[') {
+            unsigned char tbuf [2];
+
+            if (sscanf(buf, "[%c%c - SHA%d]", &tbuf [0], &tbuf [1],
+                       &hashNum) != 3) {
+                fputs(buf, resp);
+                continue;
+            }
+
+            fputs(buf, resp);
+
+            hashType = sha_get_hashType(hashNum);
+            if (hashType == HASH_AlgNULL) {
+                fprintf(resp, "ERROR: invalid hash (SHA-%d)", hashNum);
+                goto out;
+            }
+
+            continue;
+        } else if (parse_secitem ("YephemCAVS", buf, &y_ephem_cavs)) {
+            fputs(buf, resp);
+
+            if (!do_validity) {
+                SECItem ZZ;
+                unsigned char ZZ_hash_buf [1024];
+                DHParams dh_params;
+                DHPrivateKey *dh_privKey;
+
+                dh_params.prime = keyParams.prime;
+                dh_params.base = keyParams.base;
+
+                DH_NewKey (&dh_params, &dh_privKey);
+                DH_Derive(&y_ephem_cavs, &keyParams.prime, 
&dh_privKey->privateValue, &ZZ, 0);
+
+                fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, 
keyParams.prime.len);
+
+                to_hex_str(buf, dh_privKey->publicValue.data, 
dh_privKey->publicValue.len);
+                fprintf(resp, "YephemIUT = %s\n", buf);
+
+                to_hex_str(buf, ZZ_hash_buf, hashNum / 8);
+                fprintf(resp, "HashZZ = %s\n", buf);
+
+                PORT_FreeArena(dh_privKey->arena, PR_TRUE);
+            }
+
+            continue;
+        } else if (parse_secitem ("XephemIUT", buf, &x_ephem_iut)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("YephemIUT", buf, &y_ephem_iut)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("CAVSHashZZ", buf, &cavs_hash_zz)) {
+            if (do_validity) {
+                SECItem ZZ;
+                unsigned char ZZ_hash_buf [1024];
+                char Z_buf [1024];
+
+                DH_Derive(&y_ephem_cavs, &keyParams.prime, &x_ephem_iut, &ZZ, 
0);
+
+                fputs(buf, resp);
+
+                to_hex_str(Z_buf, ZZ.data, ZZ.len);
+
+                fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, 
keyParams.prime.len);
+                to_hex_str(Z_buf, ZZ_hash_buf, hashNum / 8);
+                fprintf(resp, "IUTHashZZ = %s\n", Z_buf);
+
+                fprintf(resp, "Result = %s\n",
+                        (cavs_hash_zz.len == hashNum / 8 && memcmp 
(cavs_hash_zz.data, ZZ_hash_buf, hashNum / 8) == 0) ? "P" : "F");
+            } else {
+                fputs(buf, resp);
+            }
+            continue;
+        } else if (parse_secitem ("P", buf, &keyParams.prime)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("Q", buf, &keyParams.subPrime)) {
+            fputs(buf, resp);
+            continue;
+        } else if (parse_secitem ("G", buf, &keyParams.base)) {
+            fputs(buf, resp);
+            continue;
+        } else {
+            /* Comments, blank lines, ... */
+            fputs(buf, resp);
+        }
+    }
+
+out:
+    fclose(req);
+    if (keyParams.prime.data) { /* P */
+        SECITEM_ZfreeItem(&keyParams.prime, PR_FALSE);
+    }
+    if (keyParams.subPrime.data) { /* Q */
+        SECITEM_ZfreeItem(&keyParams.subPrime, PR_FALSE);
+    }
+    if (keyParams.base.data) { /* G */
+        SECITEM_ZfreeItem(&keyParams.base, PR_FALSE);
+    }
+}
+
 int
 main(int argc, char **argv)
 {
@@ -9093,6 +9278,15 @@
         /* AES Keywrap */
         /***************/
         keywrap(argv[2]);
+    } else if (strcmp(argv[1], "kasffc") == 0) {
+        /***************/
+        /* KAS FFC */
+        /***************/
+        if (strcmp(argv[2], "validity") == 0) {
+            kas_ffc_test(argv[3], PR_TRUE);
+        } else {
+            kas_ffc_test(argv[3], PR_FALSE);
+        }
     }
     return 0;
 }
diff --git a/cmd/fipstest/kas.sh b/cmd/fipstest/kas.sh
new file mode 100644
--- /dev/null
+++ b/cmd/fipstest/kas.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# 
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path.  Then run this script in the
+# directory where the REQUEST (.req) files reside.  The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KAS
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+kas_requests_ffc_function="
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req
+"
+
+kas_requests_ffc_validity="
+KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req
+KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $kas_requests; do
+       sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
+
+for request in $kas_requests_ffc_function; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest kasffc function ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
+for request in $kas_requests_ffc_validity; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest kasffc validity ${REQDIR}/$request > ${RSPDIR}/$response
+done
++++++ nss-fips-cavs-keywrap.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574234023 -3600
#      Wed Nov 20 08:13:43 2019 +0100
# Node ID 5d6e015d1af40b5f5b990d0cf4d97932774c2a61
# Parent  2f570c6952d8edfc1ad9061cd3830f202eec1960
[PATCH 1/2] 19
>From f4cbaf95fcf2519029bb3c4407b2f15aa27c94c1 Mon Sep 17 00:00:00 2001
---
 nss/cmd/fipstest/fipstest.c | 160 ++++++++++++++++++++++++++++++++++++
 nss/cmd/fipstest/keywrap.sh |  40 +++++++++
 2 files changed, 200 insertions(+)
 create mode 100644 nss/cmd/fipstest/keywrap.sh

diff -r 2f570c6952d8 -r 5d6e015d1af4 cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c   Sun Mar 15 21:54:30 2020 +0100
+++ b/cmd/fipstest/fipstest.c   Wed Nov 20 08:13:43 2019 +0100
@@ -8752,6 +8752,161 @@
     return;
 }
 
+void
+keywrap (char *reqfn)
+{
+    char buf[1024];
+    FILE *req;  /* input stream from the REQUEST file */
+    FILE *resp; /* output stream to the RESPONSE file */
+    int i, j;
+    AESKeyWrapContext *ctx = NULL;
+    unsigned char key_data [1024];
+    int key_data_len = 0;
+
+    req = fopen(reqfn, "r");
+    resp = stdout;
+
+    while (fgets(buf, sizeof buf, req) != NULL) {
+        /* K = ... */
+        if (buf[0] == 'K') {
+            /* Skip to value */
+            for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+                ;
+
+            if (i == 1) {
+                /* Unknown variable starting with 'K' */
+                fputs(buf, resp);
+                continue;
+            }
+
+            for (j = 0; isxdigit(buf[i]) && j < sizeof key_data; i += 2, j++) {
+                hex_to_byteval(&buf[i], &key_data[j]);
+            }
+
+            key_data_len = j;
+
+            fputs(buf, resp);
+            continue;
+        }
+        /* C = ... */
+        /* This means we're doing decryption */
+        /* Make sure we don't pick up COUNT = ... here */
+        else if (buf[0] == 'C' && (isspace (buf[1]) || buf[1] == '=')) {
+            unsigned char data_in [1024];
+            unsigned char data_out [1024];
+            unsigned int data_in_len, data_out_len;
+
+            if (key_data_len <= 0) {
+                fprintf(resp, "ERROR: No key specified\n");
+                goto out;
+            }
+
+            /* Skip to value */
+            for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+                ;
+
+            if (i == 1) {
+                /* Unknown variable starting with 'C' */
+                fputs(buf, resp);
+                continue;
+            }
+
+            fputs(buf, resp);
+
+            for (j = 0; isxdigit(buf[i]) && j < sizeof data_in; i += 2, j++) {
+                hex_to_byteval(&buf[i], &data_in[j]);
+            }
+
+            data_in_len = j;
+
+            if (ctx) {
+                AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+                ctx = NULL;
+            }
+
+            ctx = AESKeyWrap_CreateContext(key_data, NULL, PR_FALSE, 
key_data_len);
+            if (!ctx) {
+                fprintf(resp, "ERROR: Unable to create context\n");
+                goto out;
+            }
+
+            if (AESKeyWrap_Decrypt(ctx, data_out, &data_out_len, 1024, 
data_in, data_in_len)
+                != SECSuccess) {
+                fprintf(resp, "FAIL\n");
+                continue;
+            }
+
+            fputs("P = ", resp);
+            to_hex_str(buf, data_out, data_out_len);
+            fputs(buf, resp);
+            fputc('\n', resp);
+        }
+        /* P = ... */
+        /* This means we're doing encryption */
+        else if (buf[0] == 'P') {
+            unsigned char data_in [1024];
+            unsigned char data_out [1024];
+            unsigned int data_in_len, data_out_len;
+
+            if (key_data_len <= 0) {
+                fprintf(resp, "ERROR: No key specified\n");
+                goto out;
+            }
+
+            /* Skip to value */
+            for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+                ;
+
+            if (i == 1) {
+                /* Unknown variable starting with 'P' */
+                fputs(buf, resp);
+                continue;
+            }
+
+            fputs(buf, resp);
+
+            for (j = 0; isxdigit(buf[i]) && j < sizeof data_in; i += 2, j++) {
+                hex_to_byteval(&buf[i], &data_in[j]);
+            }
+
+            data_in_len = j;
+
+            if (ctx) {
+                AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+                ctx = NULL;
+            }
+
+            ctx = AESKeyWrap_CreateContext(key_data, NULL, PR_TRUE, 
key_data_len);
+            if (!ctx) {
+                fprintf(resp, "ERROR: Unable to create context\n");
+                goto out;
+            }
+
+            if (AESKeyWrap_Encrypt(ctx, data_out, &data_out_len, 1024, 
data_in, data_in_len)
+                != SECSuccess) {
+                fprintf(resp, "FAIL\n");
+                continue;
+            }
+
+            fputs("C = ", resp);
+            to_hex_str(buf, data_out, data_out_len);
+            fputs(buf, resp);
+            fputc('\n', resp);
+        }
+        /* Comments, blank lines, ... */
+        else {
+            fputs(buf, resp);
+            continue;
+        }
+    }
+
+out:
+    fclose(req);
+    if (ctx) {
+        AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+    }
+}
+
 int
 main(int argc, char **argv)
 {
@@ -8933,6 +9088,11 @@
         ikev2(argv[2]);
     } else if (strcmp(argv[1], "kbkdf") == 0) {
         kbkdf(argv[2]);
+    } else if (strcmp(argv[1], "keywrap") == 0) {
+        /***************/
+        /* AES Keywrap */
+        /***************/
+        keywrap(argv[2]);
     }
     return 0;
 }
diff -r 2f570c6952d8 -r 5d6e015d1af4 cmd/fipstest/keywrap.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/fipstest/keywrap.sh   Wed Nov 20 08:13:43 2019 +0100
@@ -0,0 +1,40 @@
+#!/bin/sh
+# 
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST AES keywrap Algorithm Validation 
Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path.  Then run this script in the
+# directory where the REQUEST (.req) files reside.  The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KeyWrap38F
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+keywrap_requests="
+KW_AD_128.req
+KW_AD_192.req
+KW_AD_256.req
+KW_AE_128.req
+KW_AE_192.req
+KW_AE_256.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $keywrap_requests; do
+       sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
+
+for request in $keywrap_requests; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest keywrap ${REQDIR}/$request > ${RSPDIR}/$response
+done
++++++ nss-fips-cavs-rsa-fixes.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574237297 -3600
#      Wed Nov 20 09:08:17 2019 +0100
# Node ID 3f4d682c9a1e8b3d939c744ee249e23179db5191
# Parent  0e904e6179d1db21965df2c405c80c3fc0258658
[PATCH] 25
>From 9b4636ad75add2ac09ce1844b3071785d563c275 Mon Sep 17 00:00:00 2001
---
 nss/cmd/fipstest/fipstest.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -6536,7 +6536,7 @@
             /* Output the signature */
             fputs(buf, rsaresp);
             to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
-            fprintf(rsaresp, "S = %s\n", buf);
+            fprintf(rsaresp, "S = %s\n\n", buf);
 
             /* Perform RSA verification with the RSA public key. */
             rv = RSA_HashCheckSign(shaOid,
@@ -9536,6 +9536,7 @@
     init_functions();
     RNG_RNGInit();
     SECOID_Init();
+    BL_Init();
 
     /*************/
     /*   TDEA    */
++++++ nss-fips-combined-hash-sign-dsa-ecdsa.patch ++++++
>From 7f3606a84f6c62b002246ee73121279e59f83437 Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <h...@cl.no>
Date: Thu, 28 May 2020 22:44:22 +0200
Subject: [PATCH] CKM_(EC)DSA_SHAxxx mechs: Add some missing pieces.

This includes pairwise consistency checks and entry points for
power-on self tests.
---
 cmd/lib/pk11table.c     |   8 ++
 lib/pk11wrap/pk11mech.c |   8 ++
 lib/softoken/pkcs11c.c  | 213 +++++++++++++++++++++++++++-------------
 lib/softoken/softoken.h |  10 ++
 4 files changed, 169 insertions(+), 70 deletions(-)

diff --git a/cmd/lib/pk11table.c b/cmd/lib/pk11table.c
index f7a45fa..d302436 100644
--- a/cmd/lib/pk11table.c
+++ b/cmd/lib/pk11table.c
@@ -273,6 +273,10 @@ const Constant _consts[] = {
     mkEntry(CKM_DSA_KEY_PAIR_GEN, Mechanism),
     mkEntry(CKM_DSA, Mechanism),
     mkEntry(CKM_DSA_SHA1, Mechanism),
+    mkEntry(CKM_DSA_SHA224, Mechanism),
+    mkEntry(CKM_DSA_SHA256, Mechanism),
+    mkEntry(CKM_DSA_SHA384, Mechanism),
+    mkEntry(CKM_DSA_SHA512, Mechanism),
     mkEntry(CKM_DH_PKCS_KEY_PAIR_GEN, Mechanism),
     mkEntry(CKM_DH_PKCS_DERIVE, Mechanism),
     mkEntry(CKM_X9_42_DH_DERIVE, Mechanism),
@@ -438,6 +442,10 @@ const Constant _consts[] = {
     mkEntry(CKM_EC_KEY_PAIR_GEN, Mechanism),
     mkEntry(CKM_ECDSA, Mechanism),
     mkEntry(CKM_ECDSA_SHA1, Mechanism),
+    mkEntry(CKM_ECDSA_SHA224, Mechanism),
+    mkEntry(CKM_ECDSA_SHA256, Mechanism),
+    mkEntry(CKM_ECDSA_SHA384, Mechanism),
+    mkEntry(CKM_ECDSA_SHA512, Mechanism),
     mkEntry(CKM_ECDH1_DERIVE, Mechanism),
     mkEntry(CKM_ECDH1_COFACTOR_DERIVE, Mechanism),
     mkEntry(CKM_ECMQV_DERIVE, Mechanism),
diff --git a/lib/pk11wrap/pk11mech.c b/lib/pk11wrap/pk11mech.c
index d94d59a..ac280f0 100644
--- a/lib/pk11wrap/pk11mech.c
+++ b/lib/pk11wrap/pk11mech.c
@@ -376,6 +376,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
             return CKK_RSA;
         case CKM_DSA:
         case CKM_DSA_SHA1:
+        case CKM_DSA_SHA224:
+        case CKM_DSA_SHA256:
+        case CKM_DSA_SHA384:
+        case CKM_DSA_SHA512:
         case CKM_DSA_KEY_PAIR_GEN:
             return CKK_DSA;
         case CKM_DH_PKCS_DERIVE:
@@ -386,6 +390,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
             return CKK_KEA;
         case CKM_ECDSA:
         case CKM_ECDSA_SHA1:
+        case CKM_ECDSA_SHA224:
+        case CKM_ECDSA_SHA256:
+        case CKM_ECDSA_SHA384:
+        case CKM_ECDSA_SHA512:
         case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
         case CKM_ECDH1_DERIVE:
             return CKK_EC; /* CKK_ECDSA is deprecated */
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
index 08f94bc..ec6b205 100644
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -2606,7 +2606,7 @@ nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int 
sigLen,
 static SECStatus
 nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
                   unsigned int *sigLen, unsigned int maxSigLen,
-                  void *dataBuf, unsigned int dataLen)
+                  const void *dataBuf, unsigned int dataLen)
 {
     SECItem signature, digest;
     SECStatus rv;
@@ -2624,6 +2624,22 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
     return rv;
 }
 
+SECStatus
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+             unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+             const unsigned char *hash, unsigned int hashLen)
+{
+    SECStatus rv;
+
+    rv = nsc_DSA_Sign_Stub(key, sig, sigLen, maxLen, hash, hashLen);
+
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+        sftk_fatalError = PR_TRUE;
+    }
+
+    return rv;
+}
+
 static SECStatus
 nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
                     void *dataBuf, unsigned int dataLen)
@@ -2641,7 +2657,7 @@ nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int 
sigLen,
 static SECStatus
 nsc_ECDSASignStub(void *ctx, void *sigBuf,
                   unsigned int *sigLen, unsigned int maxSigLen,
-                  void *dataBuf, unsigned int dataLen)
+                  const void *dataBuf, unsigned int dataLen)
 {
     SECItem signature, digest;
     SECStatus rv;
@@ -2659,6 +2675,22 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
     return rv;
 }
 
+SECStatus
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+               unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+               const unsigned char *hash, unsigned int hashLen)
+{
+    SECStatus rv;
+
+    rv = nsc_ECDSASignStub(key, sig, sigLen, maxLen, hash, hashLen);
+
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+        sftk_fatalError = PR_TRUE;
+    }
+
+    return rv;
+}
+
 /* NSC_SignInit setups up the signing operations. There are three basic
  * types of signing:
  *      (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
@@ -3511,6 +3543,22 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
         info->hashOid = SEC_OID_##mmm;                    \
         goto finish_rsa;
 
+#define INIT_DSA_VFY_MECH(mmm)                            \
+    case CKM_DSA_##mmm:                                   \
+        context->multi = PR_TRUE;                         \
+        crv = sftk_doSub##mmm(context);                   \
+        if (crv != CKR_OK)                                \
+            break;                                        \
+        goto finish_dsa;
+
+#define INIT_ECDSA_VFY_MECH(mmm)                          \
+    case CKM_ECDSA_##mmm:                                 \
+        context->multi = PR_TRUE;                         \
+        crv = sftk_doSub##mmm(context);                   \
+        if (crv != CKR_OK)                                \
+            break;                                        \
+        goto finish_ecdsa;
+
     switch (pMechanism->mechanism) {
         INIT_RSA_VFY_MECH(MD5)
         INIT_RSA_VFY_MECH(MD2)
@@ -3575,13 +3623,15 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
             context->destroy = (SFTKDestroy)sftk_Space;
             context->verify = (SFTKVerify)sftk_RSACheckSignPSS;
             break;
-        case CKM_DSA_SHA1:
-            context->multi = PR_TRUE;
-            crv = sftk_doSubSHA1(context);
-            if (crv != CKR_OK)
-                break;
-        /* fall through */
+
+        INIT_DSA_VFY_MECH(SHA1)
+        INIT_DSA_VFY_MECH(SHA224)
+        INIT_DSA_VFY_MECH(SHA256)
+        INIT_DSA_VFY_MECH(SHA384)
+        INIT_DSA_VFY_MECH(SHA512)
+
         case CKM_DSA:
+        finish_dsa:
             if (key_type != CKK_DSA) {
                 crv = CKR_KEY_TYPE_INCONSISTENT;
                 break;
@@ -3594,13 +3644,15 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
             context->verify = (SFTKVerify)nsc_DSA_Verify_Stub;
             context->destroy = sftk_Null;
             break;
-        case CKM_ECDSA_SHA1:
-            context->multi = PR_TRUE;
-            crv = sftk_doSubSHA1(context);
-            if (crv != CKR_OK)
-                break;
-        /* fall through */
+
+        INIT_ECDSA_VFY_MECH(SHA1)
+        INIT_ECDSA_VFY_MECH(SHA224)
+        INIT_ECDSA_VFY_MECH(SHA256)
+        INIT_ECDSA_VFY_MECH(SHA384)
+        INIT_ECDSA_VFY_MECH(SHA512)
+
         case CKM_ECDSA:
+        finish_ecdsa:
             if (key_type != CKK_EC) {
                 crv = CKR_KEY_TYPE_INCONSISTENT;
                 break;
@@ -4733,6 +4785,73 @@ loser:
 #define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
 #define PAIRWISE_MESSAGE_LENGTH 20           /* 160-bits */
 
+static CK_RV
+pairwise_signverify_mech (CK_SESSION_HANDLE hSession,
+                          SFTKObject *publicKey, SFTKObject *privateKey,
+                          CK_MECHANISM mech,
+                          CK_ULONG signature_length,
+                          CK_ULONG pairwise_digest_length)
+{
+    /* Variables used for Signature/Verification functions. */
+    /* Must be at least 256 bits for DSA2 digest */
+    unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World 
through NSS!";
+    unsigned char *signature;
+    CK_RV crv;
+
+    /* Allocate space for signature data. */
+    signature = (unsigned char *)PORT_ZAlloc(signature_length);
+    if (signature == NULL) {
+        return CKR_HOST_MEMORY;
+    }
+
+    /* Sign the known hash using the private key. */
+    crv = NSC_SignInit(hSession, &mech, privateKey->handle);
+    if (crv != CKR_OK) {
+        PORT_Free(signature);
+        return crv;
+    }
+
+    crv = NSC_Sign(hSession,
+                   known_digest,
+                   pairwise_digest_length,
+                   signature,
+                   &signature_length);
+    if (crv != CKR_OK) {
+        PORT_Free(signature);
+        return crv;
+    }
+
+    /* detect trivial signing transforms */
+    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;
+    }
+
+    /* Verify the known hash using the public key. */
+    crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
+    if (crv != CKR_OK) {
+        PORT_Free(signature);
+        return crv;
+    }
+
+    crv = NSC_Verify(hSession,
+                     known_digest,
+                     pairwise_digest_length,
+                     signature,
+                     signature_length);
+
+    /* Free signature data. */
+    PORT_Free(signature);
+
+    if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
+        (crv == CKR_SIGNATURE_INVALID)) {
+        return CKR_GENERAL_ERROR;
+    }
+
+    return crv;
+}
+
 /*
  * FIPS 140-2 pairwise consistency check utilized to validate key pair.
  *
@@ -4780,8 +4899,6 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
 
     /* Variables used for Signature/Verification functions. */
     /* Must be at least 256 bits for DSA2 digest */
-    unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World 
through NSS!";
-    unsigned char *signature;
     CK_ULONG signature_length;
 
     if (keyType == CKK_RSA) {
@@ -4935,76 +5052,32 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE 
hSession,
         }
     }
 
+#define SIGNVERIFY_CHECK_MECH(vfymech)                                         
      \
+    mech.mechanism = vfymech;                                                  
      \
+    crv = pairwise_signverify_mech (hSession, publicKey, privateKey,           
      \
+                                    mech, signature_length, 
pairwise_digest_length); \
+    if (crv != CKR_OK)                                                         
      \
+        return crv;
+
     if (canSignVerify) {
-        /* Determine length of signature. */
         switch (keyType) {
             case CKK_RSA:
                 signature_length = modulusLen;
-                mech.mechanism = CKM_RSA_PKCS;
+                SIGNVERIFY_CHECK_MECH(CKM_SHA224_RSA_PKCS)
                 break;
             case CKK_DSA:
                 signature_length = DSA_MAX_SIGNATURE_LEN;
                 pairwise_digest_length = subPrimeLen;
-                mech.mechanism = CKM_DSA;
+                SIGNVERIFY_CHECK_MECH(CKM_DSA_SHA224)
                 break;
             case CKK_EC:
                 signature_length = MAX_ECKEY_LEN * 2;
-                mech.mechanism = CKM_ECDSA;
+                SIGNVERIFY_CHECK_MECH(CKM_ECDSA_SHA224)
                 break;
             default:
                 return CKR_DEVICE_ERROR;
         }
 
-        /* Allocate space for signature data. */
-        signature = (unsigned char *)PORT_ZAlloc(signature_length);
-        if (signature == NULL) {
-            return CKR_HOST_MEMORY;
-        }
-
-        /* Sign the known hash using the private key. */
-        crv = NSC_SignInit(hSession, &mech, privateKey->handle);
-        if (crv != CKR_OK) {
-            PORT_Free(signature);
-            return crv;
-        }
-
-        crv = NSC_Sign(hSession,
-                       known_digest,
-                       pairwise_digest_length,
-                       signature,
-                       &signature_length);
-        if (crv != CKR_OK) {
-            PORT_Free(signature);
-            return crv;
-        }
-
-        /* detect trivial signing transforms */
-        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;
-        }
-
-        /* Verify the known hash using the public key. */
-        crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
-        if (crv != CKR_OK) {
-            PORT_Free(signature);
-            return crv;
-        }
-
-        crv = NSC_Verify(hSession,
-                         known_digest,
-                         pairwise_digest_length,
-                         signature,
-                         signature_length);
-
-        /* Free signature data. */
-        PORT_Free(signature);
-
-        if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
-            (crv == CKR_SIGNATURE_INVALID)) {
-            return CKR_GENERAL_ERROR;
-        }
         if (crv != CKR_OK) {
             return crv;
         }
diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h
index 30586fc..d5aaffa 100644
--- a/lib/softoken/softoken.h
+++ b/lib/softoken/softoken.h
@@ -35,6 +35,16 @@ RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
                   const unsigned char *sig, unsigned int sigLen,
                   const unsigned char *hash, unsigned int hashLen);
 
+extern SECStatus
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+             unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+             const unsigned char *hash, unsigned int hashLen);
+
+extern SECStatus
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+               unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+               const unsigned char *hash, unsigned int hashLen);
+
 /*
 ** Prepare a buffer for padded CBC encryption, growing to the appropriate
 ** boundary, filling with the appropriate padding.
-- 
2.26.2

++++++ nss-fips-constructor-self-tests.patch ++++++
++++ 1450 lines (skipped)

++++++ nss-fips-detect-fips-mode-fixes.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1584305671 -3600
#      Sun Mar 15 21:54:31 2020 +0100
# Node ID 715834d4a258c535f3abbf116d69d5e77392593b
# Parent  4ddd7d49eeed4ea32850daf41a472ccb50dee45e
commit facacdb9078693d7a4219e84f73ea7b8f977ddc2
Author: Hans Petter Jansson <h...@cl.no>
    Patch 32: nss-fips-detect-fips-mode-fixes.patch

diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c
--- a/lib/freebl/nsslowhash.c
+++ b/lib/freebl/nsslowhash.c
@@ -2,10 +2,15 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#define _GNU_SOURCE 1
+#include <stdlib.h>
+
 #ifdef FREEBL_NO_DEPEND
 #include "stubs.h"
 #endif
+
 #include "prtypes.h"
+#include "prenv.h"
 #include "secerr.h"
 #include "blapi.h"
 #include "hasht.h"
@@ -24,6 +29,23 @@
 };
 
 #ifndef NSS_FIPS_DISABLED
+
+static PRBool
+getFIPSEnv(void)
+{
+    char *fipsEnv = secure_getenv("NSS_FIPS");
+    if (!fipsEnv) {
+        return PR_FALSE;
+    }
+    if ((strcasecmp(fipsEnv, "fips") == 0) ||
+        (strcasecmp(fipsEnv, "true") == 0) ||
+        (strcasecmp(fipsEnv, "on") == 0) ||
+        (strcasecmp(fipsEnv, "1") == 0)) {
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}
+
 static int
 nsslow_GetFIPSEnabled(void)
 {
@@ -45,6 +67,7 @@
 #endif /* LINUX */
     return 1;
 }
+
 #endif /* NSS_FIPS_DISABLED */
 
 static NSSLOWInitContext dummyContext = { 0 };
@@ -60,7 +83,7 @@
 #ifndef NSS_FIPS_DISABLED
     /* make sure the FIPS product is installed if we are trying to
      * go into FIPS mode */
-    if (nsslow_GetFIPSEnabled()) {
+    if (nsslow_GetFIPSEnabled() || getFIPSEnv()) {
         if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
             post_failed = PR_TRUE;
diff --git a/lib/sysinit/nsssysinit.c b/lib/sysinit/nsssysinit.c
--- a/lib/sysinit/nsssysinit.c
+++ b/lib/sysinit/nsssysinit.c
@@ -178,16 +178,16 @@
     f = fopen("/proc/sys/crypto/fips_enabled", "r");
     if (!f) {
         /* if we don't have a proc flag, fall back to the
-     * environment variable */
+         * environment variable */
         return getFIPSEnv();
     }
 
     size = fread(&d, 1, 1, f);
     fclose(f);
     if (size != 1)
-        return PR_FALSE;
+        return getFIPSEnv();
     if (d != '1')
-        return PR_FALSE;
+        return getFIPSEnv();
     return PR_TRUE;
 #else
     return PR_FALSE;
++++++ nss-fips-dsa-kat.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@suse.com>
# Date 1505605677 -7200
#      Sun Sep 17 01:47:57 2017 +0200
# Node ID 4ae6bed68a83c01f6d2ce7a37bdb0bdb0556416f
# Parent  5e191a391c38967e49a1d005800713ccd1010b09
[PATCH 2/6] Make DSA KAT FIPS compliant (1024 -> 2048 bit key).
>From b88701933a284ba8640df66b954c04d36ee592c9 Mon Sep 17 00:00:00 2001
---
 nss/lib/freebl/dsa.c        |   2 +-
 nss/lib/freebl/fipsfreebl.c | 143 +++++++++++++++++++++++++++-----------------
 2 files changed, 90 insertions(+), 55 deletions(-)

diff --git a/lib/freebl/dsa.c b/lib/freebl/dsa.c
--- a/lib/freebl/dsa.c
+++ b/lib/freebl/dsa.c
@@ -533,7 +533,7 @@
     return rv;
 }
 
-/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
+/* For FIPS compliance testing. Seed must be the same size as subprime. */
 SECStatus
 DSA_SignDigestWithSeed(DSAPrivateKey *key,
                        SECItem *signature,
diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c
--- a/lib/freebl/fipsfreebl.c
+++ b/lib/freebl/fipsfreebl.c
@@ -124,11 +124,11 @@
 
 /* FIPS preprocessor directives for DSA.                        */
 #define FIPS_DSA_TYPE siBuffer
-#define FIPS_DSA_DIGEST_LENGTH 20    /*  160-bits */
-#define FIPS_DSA_SUBPRIME_LENGTH 20  /*  160-bits */
-#define FIPS_DSA_SIGNATURE_LENGTH 40 /*  320-bits */
-#define FIPS_DSA_PRIME_LENGTH 128    /* 1024-bits */
-#define FIPS_DSA_BASE_LENGTH 128     /* 1024-bits */
+#define FIPS_DSA_DIGEST_LENGTH 28    /*  224-bits */
+#define FIPS_DSA_SUBPRIME_LENGTH 28  /*  224-bits */
+#define FIPS_DSA_SIGNATURE_LENGTH 56 /*  448-bits */
+#define FIPS_DSA_PRIME_LENGTH 256    /* 2048-bits */
+#define FIPS_DSA_BASE_LENGTH 256     /* 2048-bits */
 
 /* FIPS preprocessor directives for RNG.                        */
 #define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */
@@ -1445,70 +1445,105 @@
 static SECStatus
 freebl_fips_DSA_PowerUpSelfTest(void)
 {
-    /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
+    /* DSA Known P (2048-bits), Q (224-bits), and G (2048-bits) Values. */
     static const PRUint8 dsa_P[] = {
-        0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28,
-        0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63,
-        0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0,
-        0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c,
-        0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91,
-        0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0,
-        0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7,
-        0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63,
-        0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7,
-        0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56,
-        0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b,
-        0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4,
-        0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6,
-        0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64,
-        0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a,
-        0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15
+        0xfe, 0x9f, 0xba, 0xff, 0x39, 0xa6, 0x00, 0x77, 
+        0x93, 0xfe, 0xa4, 0x58, 0x17, 0xf8, 0x37, 0x54, 
+        0x76, 0x39, 0x18, 0xcb, 0xbe, 0xca, 0x62, 0x8b, 
+        0x85, 0xbc, 0x60, 0x23, 0xf4, 0x7a, 0xb5, 0x75,
+        0x31, 0xf4, 0x82, 0x83, 0x63, 0xc2, 0xdb, 0x8e,
+        0x50, 0x67, 0xd6, 0xd9, 0xae, 0xa0, 0xd6, 0x13,
+        0xc2, 0x35, 0x5b, 0x76, 0xf1, 0x00, 0x9c, 0x37,
+        0xcb, 0x46, 0x3f, 0x6e, 0xef, 0xca, 0xff, 0xcc,
+        0x1e, 0x15, 0xa1, 0x96, 0x70, 0x4c, 0xc9, 0x4d,
+        0x7e, 0xde, 0x00, 0x1e, 0x76, 0x68, 0x35, 0x1c,
+        0x31, 0x25, 0x37, 0x91, 0x98, 0x64, 0x40, 0x4c,
+        0xf1, 0xc3, 0x0e, 0xf7, 0xf3, 0x16, 0x17, 0x79,
+        0x7a, 0xa3, 0x11, 0x9a, 0xba, 0x72, 0x67, 0xe9,
+        0x70, 0xd0, 0x16, 0x6a, 0x1a, 0x53, 0x4e, 0x1b,
+        0xca, 0xb2, 0x79, 0xd8, 0x8c, 0x60, 0x53, 0xdb,
+        0x48, 0x1c, 0x00, 0x2e, 0xd3, 0x29, 0x35, 0x14,
+        0x6d, 0xd6, 0x23, 0x7c, 0x1c, 0xf3, 0x0d, 0x6a,
+        0x7e, 0xb7, 0x09, 0x7d, 0xf2, 0x06, 0x29, 0x1c,
+        0x1a, 0xdf, 0xd9, 0xe6, 0xb9, 0x2e, 0xd6, 0xb8,
+        0xbf, 0xc5, 0xcd, 0xe7, 0xf4, 0xf9, 0x91, 0x38,
+        0x2f, 0x61, 0xf9, 0xfe, 0xce, 0x16, 0x85, 0xc8,
+        0xb7, 0xdd, 0x54, 0xe0, 0xa1, 0x54, 0x4f, 0xb3,
+        0xdb, 0x72, 0xf3, 0xb9, 0xaa, 0xfe, 0x7b, 0xdd,
+        0x5e, 0x59, 0x44, 0x6c, 0x4a, 0xfe, 0x67, 0x9b,
+        0xcf, 0x78, 0x05, 0xd4, 0xc8, 0x98, 0xb3, 0x60,
+        0x46, 0x44, 0x4e, 0x0b, 0xec, 0x19, 0x6c, 0xda,
+        0xd6, 0x40, 0x3c, 0xd9, 0x96, 0xc8, 0x4a, 0x3b,
+        0xc9, 0xb5, 0x52, 0x89, 0x2e, 0x68, 0xb9, 0xa0,
+        0xd3, 0xbc, 0xa8, 0xd7, 0x6a, 0x7d, 0xe1, 0xf4,
+        0x8c, 0x68, 0x3e, 0xc1, 0x5a, 0xac, 0x46, 0x6d,
+        0xad, 0xe3, 0x89, 0x7f, 0x92, 0xa6, 0x29, 0xb2,
+        0xc3, 0x3b, 0x20, 0x5f, 0x71, 0x00, 0x27, 0x87
     };
 
     static const PRUint8 dsa_Q[] = {
-        0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
-        0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
-        0x91, 0x99, 0x8b, 0xcf
+        0xbc, 0xc9, 0xda, 0xca, 0xf9, 0x6b, 0xfa, 0x7e,
+        0xbd, 0x9b, 0xfb, 0x48, 0x35, 0x1e, 0xe5, 0x8c,
+        0x64, 0x46, 0xc7, 0x04, 0xb2, 0x44, 0x70, 0x9b,
+        0x0a, 0x3f, 0x03, 0x01
     };
 
     static const PRUint8 dsa_G[] = {
-        0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4,
-        0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6,
-        0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3,
-        0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17,
-        0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d,
-        0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a,
-        0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24,
-        0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25,
-        0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb,
-        0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79,
-        0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac,
-        0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25,
-        0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27,
-        0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed,
-        0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f,
-        0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38
+        0x5d, 0x23, 0xd1, 0xc5, 0x2e, 0x7e, 0x22, 0x3b,
+        0x98, 0x03, 0xc3, 0xc0, 0x9d, 0xbe, 0x8f, 0x68,
+        0x6b, 0xd0, 0xbf, 0x72, 0x20, 0x89, 0x5c, 0x8f,
+        0x4c, 0x8e, 0x66, 0xfe, 0x8e, 0xfc, 0x02, 0x21,
+        0xf3, 0xea, 0xc5, 0x23, 0x96, 0x9b, 0xa4, 0x2e,
+        0xac, 0x35, 0x9f, 0x70, 0x90, 0x79, 0xd9, 0x42,
+        0xfa, 0x0e, 0x4c, 0x1f, 0x55, 0xcf, 0x8b, 0xb5,
+        0x98, 0x71, 0xfa, 0xf1, 0xbc, 0xfd, 0xc7, 0x2b,
+        0x5a, 0xa6, 0x53, 0x86, 0xf1, 0xa3, 0xd5, 0xbc,
+        0xad, 0x08, 0x80, 0x23, 0x40, 0xea, 0xc9, 0x2f,
+        0x58, 0xfb, 0xa9, 0xda, 0x8d, 0xc5, 0xfa, 0x46,
+        0x0a, 0x0a, 0xe8, 0x03, 0xef, 0x04, 0x53, 0x09,
+        0xc4, 0x7f, 0x69, 0x59, 0x68, 0xb5, 0x52, 0x91,
+        0x3d, 0xe1, 0xbc, 0xa0, 0x6b, 0x41, 0xec, 0x07,
+        0x0b, 0xf5, 0xf5, 0x62, 0xf5, 0xeb, 0xb7, 0x7e,
+        0xc5, 0x32, 0x3d, 0x1e, 0x03, 0xda, 0x75, 0x24,
+        0xb6, 0xe5, 0xb9, 0xfd, 0x36, 0x3d, 0xa4, 0xbf,
+        0xc4, 0xee, 0x3b, 0xb5, 0x14, 0x85, 0x5c, 0x2d,
+        0x80, 0xb2, 0x55, 0xb6, 0x70, 0x21, 0xf2, 0x94,
+        0x63, 0xa5, 0xc2, 0x6f, 0xee, 0x34, 0x81, 0xae,
+        0xc6, 0x0f, 0xf3, 0xef, 0xb4, 0xde, 0xa5, 0x58,
+        0x6f, 0x57, 0xc1, 0x51, 0x0a, 0xe4, 0x4e, 0xf0,
+        0xed, 0xee, 0x42, 0xdc, 0xff, 0x4b, 0x14, 0xa3,
+        0xcc, 0x6e, 0xa8, 0x0c, 0x29, 0x81, 0xdb, 0xce,
+        0x78, 0x4d, 0x43, 0xe0, 0xe1, 0x60, 0xc8, 0x3e,
+        0x54, 0x00, 0x29, 0x20, 0x25, 0x40, 0x22, 0xac,
+        0xfa, 0x75, 0xb1, 0x4e, 0xcc, 0x61, 0x54, 0x27,
+        0x2c, 0x95, 0xaf, 0x4c, 0x02, 0xa7, 0x55, 0xbd,
+        0xed, 0xe2, 0x25, 0xfc, 0xba, 0xd2, 0x5b, 0xd7,
+        0x33, 0xa1, 0xe9, 0xb4, 0x7f, 0x7e, 0xfe, 0xbb,
+        0xfa, 0x54, 0xce, 0x3c, 0xbc, 0xd1, 0x03, 0x50,
+        0x9d, 0xa9, 0x38, 0x9a, 0xf8, 0x67, 0xb1, 0xa3
     };
 
-    /* DSA Known Random Values (known random key block       is 160-bits)  */
-    /*                     and (known random signature block is 160-bits). */
+    /* DSA Known Random Values (known random key block       is 224-bits)  */
+    /*                     and (known random signature block is 224-bits). */
     static const PRUint8 dsa_known_random_key_block[] = {
-        "Mozilla Rules World!"
+        "Mozilla Rules World! Always."
     };
     static const PRUint8 dsa_known_random_signature_block[] = {
-        "Random DSA Signature"
+        "Random DSA Signature, Longer"
     };
 
-    /* DSA Known Digest (160-bits) */
-    static const PRUint8 dsa_known_digest[] = { "DSA Signature Digest" };
+    /* DSA Known Digest (224-bits) */
+    static const PRUint8 dsa_known_digest[] = { "DSA Signature Digest, Longer" 
};
 
-    /* DSA Known Signature (320-bits). */
+    /* DSA Known Signature (448-bits). */
     static const PRUint8 dsa_known_signature[] = {
-        0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
-        0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
-        0x22, 0x2a, 0x03, 0xce, 0x48, 0x15, 0x11, 0x72,
-        0x7b, 0x7e, 0xf5, 0x7a, 0xf3, 0x10, 0x3b, 0xde,
-        0x34, 0xc1, 0x9e, 0xd7, 0x27, 0x9e, 0x77, 0x38
+        0x27, 0x04, 0xff, 0xd5, 0x2d, 0x80, 0x32, 0xea,
+        0xac, 0xb5, 0x8b, 0x47, 0x17, 0xb1, 0x80, 0xed,
+        0xd6, 0x0f, 0x72, 0x75, 0xe5, 0xba, 0x08, 0xc9,
+        0x29, 0xc8, 0xc7, 0x75, 0x84, 0x60, 0x5a, 0xe9,
+        0x55, 0xa4, 0x1c, 0xf0, 0xe3, 0xce, 0x4c, 0x8e,
+        0x83, 0x3e, 0x7a, 0x77, 0x56, 0x7f, 0x83, 0xad,
+        0x68, 0x36, 0x13, 0xa9, 0xd6, 0x08, 0x1f, 0x19
     };
 
     /* DSA variables. */
@@ -1550,7 +1585,7 @@
     dsa_signature_item.len = sizeof dsa_computed_signature;
 
     dsa_digest_item.data = (unsigned char *)dsa_known_digest;
-    dsa_digest_item.len = SHA1_LENGTH;
+    dsa_digest_item.len = SHA224_LENGTH;
 
     /* Perform DSA signature process. */
     dsa_status = DSA_SignDigestWithSeed(dsa_private_key,
++++++ nss-fips-gcm-ctr.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574234739 -3600
#      Wed Nov 20 08:25:39 2019 +0100
# Node ID 5396ffb26887cc0cd42b9f12cc6c8e3dfdaf194b
# Parent  f5cf5d16deb68e65b5dd4e799d9e8e3098400d62
[PATCH] 22
>From 41dd171b242b0cb550d12760da110db7e2c21daf Mon Sep 17 00:00:00 2001
---
 nss/lib/freebl/gcm.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff -r f5cf5d16deb6 -r 5396ffb26887 lib/freebl/gcm.c
--- a/lib/freebl/gcm.c  Wed Nov 20 08:23:35 2019 +0100
+++ b/lib/freebl/gcm.c  Wed Nov 20 08:25:39 2019 +0100
@@ -532,8 +532,14 @@
     unsigned char tagKey[MAX_BLOCK_SIZE];
     PRBool ctr_context_init;
     gcmIVContext gcm_iv;
+    unsigned long long gcm_iv_bytes;
 };
 
+/* NIST SP-800-38D limits the use of GCM with a single IV to 2^39 - 256
+ * bits which translates to 2^32 - 2 128bit blocks or 2^36 - 32 bytes
+ */
+#define MAX_GCM_BYTES_PER_IV    ((1ULL << 36) - 32)
+
 SECStatus gcm_InitCounter(GCMContext *gcm, const unsigned char *iv,
                           unsigned int ivLen, unsigned int tagBits,
                           const unsigned char *aad, unsigned int aadLen);
@@ -669,6 +675,8 @@
         goto loser;
     }
 
+    gcm->gcm_iv_bytes = MAX_GCM_BYTES_PER_IV;
+
     /* finally mix in the AAD data */
     rv = gcmHash_Reset(ghash, aad, aadLen);
     if (rv != SECSuccess) {
@@ -766,6 +774,13 @@
         return SECFailure;
     }
 
+    /* bail out if this invocation requests processing more than what is
+     * considered to be a safe limit */
+    if (gcm->gcm_iv_bytes < (unsigned long long)inlen) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
     tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
     if (UINT_MAX - inlen < tagBytes) {
         PORT_SetError(SEC_ERROR_INPUT_LEN);
@@ -794,6 +809,7 @@
         *outlen = 0;
         return SECFailure;
     };
+    gcm->gcm_iv_bytes -= inlen;
     *outlen += len;
     return SECSuccess;
 }
++++++ nss-fips-pairwise-consistency-check.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574138371 -3600
#      Tue Nov 19 05:39:31 2019 +0100
# Node ID 557f9009507c9e70941dbe39965028049e1ef5a2
# Parent  4ae6bed68a83c01f6d2ce7a37bdb0bdb0556416f
[PATCH 07/22] 15
>From 2a162c34b7aad7399f33069cd9930fd92714861c Mon Sep 17 00:00:00 2001
---
 nss/lib/softoken/pkcs11c.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -4730,8 +4730,8 @@
     return crv;
 }
 
-#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
-#define PAIRWISE_MESSAGE_LENGTH 20         /* 160-bits */
+#define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
+#define PAIRWISE_MESSAGE_LENGTH 20           /* 160-bits */
 
 /*
  * FIPS 140-2 pairwise consistency check utilized to validate key pair.
@@ -5591,6 +5591,7 @@
                             (PRUint32)crv);
                 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, 
msg);
             }
+            sftk_fatalError = PR_TRUE;
         }
     }
 
++++++ nss-fips-rsa-keygen-strictness.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1584305670 -3600
#      Sun Mar 15 21:54:30 2020 +0100
# Node ID 2f570c6952d8edfc1ad9061cd3830f202eec1960
# Parent  557f9009507c9e70941dbe39965028049e1ef5a2
commit 4b8c0eac6b092717157b4141c82b4d76ccdc91b3
Author: Hans Petter Jansson <h...@cl.no>
    Patch 16: nss-fips-rsa-keygen-strictness.patch

diff --git a/lib/freebl/mpi/mpprime.c b/lib/freebl/mpi/mpprime.c
--- a/lib/freebl/mpi/mpprime.c
+++ b/lib/freebl/mpi/mpprime.c
@@ -14,6 +14,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "../fips.h"
+
 #define SMALL_TABLE 0 /* determines size of hard-wired prime table */
 
 #define RANDOM() rand()
@@ -451,6 +453,25 @@
     } else
         num_tests = 50;
 
+    /* FIPS 186-4 mandates more M-R tests for probable primes generation - make
+     * sure the minimums are observed (see Appendix C, tables C.1 and C.2).
+     * For DSA this is handled in pqg_ParamGen() through the use of
+     * prime_testcount_p() and prime_testcount_q() respectively.
+     * For RSA this unfortunately seems to be the right place to prevent larger
+     * code changes. On the other hand, it seems to generally speed things up,
+     * since there are measurably less errors while calculating inverse modulo 
in
+     * rsa_build_from_primes().
+     */
+    if (FIPS_mode()) {
+        if (nBits >= 1536)
+            i = 4;
+        else
+            i = 5;
+        if (i > num_tests)
+            num_tests = i;
+        i = 0;
+    }
+
     if (strong)
         --nBits;
     MP_CHECKOK(mpl_set_bit(start, nBits - 1, 1));
diff --git a/lib/freebl/rsa.c b/lib/freebl/rsa.c
--- a/lib/freebl/rsa.c
+++ b/lib/freebl/rsa.c
@@ -16,11 +16,13 @@
 #include "prinit.h"
 #include "blapi.h"
 #include "mpi.h"
+#include "mpi-priv.h"
 #include "mpprime.h"
 #include "mplogic.h"
 #include "secmpi.h"
 #include "secitem.h"
 #include "blapii.h"
+#include "fips.h"
 
 /*
 ** Number of times to attempt to generate a prime (p or q) from a random
@@ -143,11 +145,24 @@
             err = mp_invmod(d, &phi, e);
         } else {
             err = mp_invmod(e, &phi, d);
-        }
+            /* FIPS 186-4 (B.3.1.3.a) places additional requirements on the
+             * private exponent d:
+             *   2^(n/2) < d < lcm(p-1, q-1) = phi
+             */
+            if (FIPS_mode() && (MP_OKAY == err)) {
+                CHECK_MPI_OK( mp_2expt(&tmp, keySizeInBits / 2) );
+                if ((mp_cmp(d, &tmp) <= 0) || (mp_cmp(d, &phi) >= 0)) {
+                    /* new set of p, q is needed for another calculation of d 
*/
+                    err = MP_UNDEF;
+                }
+            }
+       }
     } else {
         err = MP_OKAY;
     }
-    /*     Verify that phi(n) and e have no common divisors */
+    /*     Verify that phi(n) and e have no common divisors
+     *     This is also the coprimality constraint from FIPS 186-4 (B.3.1.2.a)
+     */
     if (err != MP_OKAY) {
         if (err == MP_UNDEF) {
             PORT_SetError(SEC_ERROR_NEED_RANDOM);
@@ -280,10 +295,12 @@
     mp_int q = { 0, 0, 0, NULL };
     mp_int e = { 0, 0, 0, NULL };
     mp_int d = { 0, 0, 0, NULL };
+    mp_int u = { 0, 0, 0, NULL };
+    mp_int v = { 0, 0, 0, NULL };
     int kiter;
     int max_attempts;
     mp_err err = MP_OKAY;
-    SECStatus rv = SECSuccess;
+    SECStatus rv = SECFailure;
     int prerr = 0;
     RSAPrivateKey *key = NULL;
     PLArenaPool *arena = NULL;
@@ -301,11 +318,40 @@
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         goto cleanup;
     }
+
+    MP_DIGITS(&p) = 0;
+    MP_DIGITS(&q) = 0;
+    MP_DIGITS(&d) = 0;
+    MP_DIGITS(&u) = 0;
+    MP_DIGITS(&v) = 0;
+    CHECK_MPI_OK(mp_init(&p));
+    CHECK_MPI_OK(mp_init(&q));
+    CHECK_MPI_OK(mp_init(&d));
+    CHECK_MPI_OK(mp_init(&u));
+    CHECK_MPI_OK(mp_init(&v));
+
 #ifndef NSS_FIPS_DISABLED
-    /* Check that the exponent is not smaller than 65537  */
-    if (mp_cmp_d(&e, 0x10001) < 0) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        goto cleanup;
+    if (FIPS_mode()) {
+        /* Check that the exponent is not smaller than 65537  */
+        if (mp_cmp_d(&e, 0x10001) < 0) {
+            PORT_SetError(SEC_ERROR_INVALID_ARGS);
+            goto cleanup;
+        }
+
+        /* FIPS 186-4 requires 2^16 < e < 2^256 (B.3.1.1.b) */
+        CHECK_MPI_OK( mp_2expt(&v, 256) );
+        if (!(mp_cmp(&e, &v) < 0 )) {
+            err = MP_BADARG;
+            goto cleanup;
+        }
+
+        /* FIPS 186-4 mandates keys to be either 2048, 3072 or 4096 bits long.
+         * We also allow a key length of 4096, since this is needed in order to
+         * pass the CAVS RSA SigGen test. */
+        if (keySizeInBits < 2048) {
+            PORT_SetError(SEC_ERROR_INVALID_ARGS);
+            goto cleanup;
+        }
     }
 #endif
 
@@ -323,12 +369,7 @@
     key->arena = arena;
     /* length of primes p and q (in bytes) */
     primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE);
-    MP_DIGITS(&p) = 0;
-    MP_DIGITS(&q) = 0;
-    MP_DIGITS(&d) = 0;
-    CHECK_MPI_OK(mp_init(&p));
-    CHECK_MPI_OK(mp_init(&q));
-    CHECK_MPI_OK(mp_init(&d));
+
     /* 3.  Set the version number (PKCS1 v1.5 says it should be zero) */
     SECITEM_AllocItem(arena, &key->version, 1);
     key->version.data[0] = 0;
@@ -339,13 +380,64 @@
         PORT_SetError(0);
         CHECK_SEC_OK(generate_prime(&p, primeLen));
         CHECK_SEC_OK(generate_prime(&q, primeLen));
-        /* Assure p > q */
+        /* Assure p >= q */
         /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
          * implementation optimization that requires p > q. We can remove
          * this code in the future.
          */
         if (mp_cmp(&p, &q) < 0)
             mp_exch(&p, &q);
+
+        /* FIPS 186-4 puts additional requirements on the primes (B.3.1.2.a-d)
+         * (n = key bit length):
+         * 1) both (p-1) and (q-1) are coprime to e (B.3.1.2.a), i.e.:
+         *    gcd(p-1,e) = 1, gcd(q-1,e) = 1
+         *    this is ensured in rsa_build_from_primes(), where
+         *    phi = lcm(p-1)(q-1) is tested for coprimality to e
+         * 2) magnitude constraint (B.3.1.2.b and B.3.1.2.c):
+         *    both p and q are from open the interval
+         *    I = ( sqrt(2) * 2^(n/2 - 1) ,  2^(n/2 - 1) )
+         * 3) minimum distance (B.3.1.2.d): abs(p-q) > 2 ^ (n/2 - 100)
+         */
+        if (FIPS_mode()) {
+            /* 2 */
+            /* in order not to constrain the selection too much,
+             * expand the inequality:
+             *   x > 2^(1/2) * 2^(n/2 - 1)
+             *         = 2^(1/2 + k) * 2^(n/2 - k - 1)
+             *         =      y(k)   *     r(k)
+             * for z(k) >= y(k) it clearly holds:
+             *   x > z(k) * r(k)
+             * one suitable z(k) such that z(k)/y(k) - 1 = o(1) is
+             * ceil(y(k)) for big-enough k
+             * ceil(y(30))/y(30) - 1 < 10^-10, so lets use that
+             * 2^30.5 = 1518500249.98802484622388101120...
+             * the magic constant is thus z(30) = 1518500250 < 2^31
+             *
+             * Additionally, since p >= q is required above, the
+             * condtitions can be shortened to:
+             *   1518500250 * 2^(n/2 - 31) = v < q 
+             *                               p < u = 2^(n/2 - 1)
+             */
+            CHECK_MPI_OK( mp_2expt(&u, keySizeInBits / 2 - 31) );
+            CHECK_MPI_OK( mp_mul_d(&u, 1518500250, &v) );
+            CHECK_MPI_OK( mp_2expt(&u, keySizeInBits / 2) );
+            if ((mp_cmp(&q, &v) <= 0) || (mp_cmp(&p, &u) >= 0)) {
+                prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values 
*/
+                kiter++;
+                continue;
+            }
+            /* 3 */
+            CHECK_MPI_OK( mp_sub(&p, &q, &u) );
+            CHECK_MPI_OK( mp_abs(&u, &u) );
+            CHECK_MPI_OK( mp_2expt(&v, keySizeInBits / 2 - 100) );
+            if (mp_cmp(&u, &v) < 0) {
+                prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values 
*/
+                kiter++;
+                continue;
+            }
+        }
+
         /* Attempt to use these primes to generate a key */
         rv = rsa_build_from_primes(&p, &q,
                                    &e, PR_FALSE, /* needPublicExponent=false */
@@ -368,7 +460,9 @@
     mp_clear(&q);
     mp_clear(&e);
     mp_clear(&d);
-    if (err) {
+    mp_clear(&u);
+    mp_clear(&v);
+    if (err != MP_OKAY) {
         MP_TO_SEC_ERROR(err);
         rv = SECFailure;
     }
++++++ nss-fips-tls-allow-md5-prf.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574240734 -3600
#      Wed Nov 20 10:05:34 2019 +0100
# Node ID 0efca22bbafd7575b20461f255c46157c9321822
# Parent  3a2cb65dc157344cdad19e8e16e9c33e36f82d96
[PATCH] 30
>From ca3b695ac461eccf4ed97e1b3fe0a311c80a792f Mon Sep 17 00:00:00 2001
---
 nss/lib/freebl/md5.c       | 67 ++++++++++++++++++++++++++------------
 nss/lib/freebl/rawhash.c   | 37 +++++++++++++++++++++
 nss/lib/freebl/tlsprfalg.c |  5 ++-
 nss/lib/softoken/pkcs11c.c |  4 +--
 4 files changed, 90 insertions(+), 23 deletions(-)

diff --git a/lib/freebl/md5.c b/lib/freebl/md5.c
--- a/lib/freebl/md5.c
+++ b/lib/freebl/md5.c
@@ -217,13 +217,11 @@
 }
 
 MD5Context *
-MD5_NewContext(void)
+MD5_NewContext_NonFIPS(void)
 {
     /* no need to ZAlloc, MD5_Begin will init the context */
     MD5Context *cx;
 
-    IN_FIPS_RETURN(NULL);
-
     cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
     if (cx == NULL) {
         PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
@@ -232,6 +230,13 @@
     return cx;
 }
 
+MD5Context *
+MD5_NewContext(void)
+{
+    IN_FIPS_RETURN(NULL);
+    return MD5_NewContext_NonFIPS();
+}
+
 void
 MD5_DestroyContext(MD5Context *cx, PRBool freeit)
 {
@@ -243,10 +248,8 @@
 }
 
 void
-MD5_Begin(MD5Context *cx)
+MD5_Begin_NonFIPS(MD5Context *cx)
 {
-    IN_FIPS_RETURN();
-
     cx->lsbInput = 0;
     cx->msbInput = 0;
     /*  memset(cx->inBuf, 0, sizeof(cx->inBuf)); */
@@ -256,6 +259,13 @@
     cx->cv[3] = CV0_4;
 }
 
+void
+MD5_Begin(MD5Context *cx)
+{
+    IN_FIPS_RETURN();
+    MD5_Begin_NonFIPS(cx);
+}
+
 #define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s))
 
 #if defined(SOLARIS) || defined(HPUX)
@@ -431,14 +441,12 @@
 }
 
 void
-MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
+MD5_Update_NonFIPS(MD5Context *cx, const unsigned char *input, unsigned int 
inputLen)
 {
     PRUint32 bytesToConsume;
     PRUint32 inBufIndex = cx->lsbInput & 63;
     const PRUint32 *wBuf;
 
-    IN_FIPS_RETURN();
-
     /* Add the number of input bytes to the 64-bit input counter. */
     addto64(cx->msbInput, cx->lsbInput, inputLen);
     if (inBufIndex) {
@@ -487,6 +495,13 @@
         memcpy(cx->inBuf, input, inputLen);
 }
 
+void
+MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
+{
+    IN_FIPS_RETURN();
+    MD5_Update_NonFIPS(cx, input, inputLen);
+}
+
 static const unsigned char padbytes[] = {
     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -503,8 +518,8 @@
 };
 
 void
-MD5_End(MD5Context *cx, unsigned char *digest,
-        unsigned int *digestLen, unsigned int maxDigestLen)
+MD5_End_NonFIPS(MD5Context *cx, unsigned char *digest,
+                       unsigned int *digestLen, unsigned int maxDigestLen)
 {
 #ifndef IS_LITTLE_ENDIAN
     PRUint32 tmp;
@@ -512,8 +527,6 @@
     PRUint32 lowInput, highInput;
     PRUint32 inBufIndex = cx->lsbInput & 63;
 
-    IN_FIPS_RETURN();
-
     if (maxDigestLen < MD5_HASH_LEN) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return;
@@ -525,10 +538,10 @@
     lowInput <<= 3;
 
     if (inBufIndex < MD5_END_BUFFER) {
-        MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex);
+        MD5_Update_NonFIPS(cx, padbytes, MD5_END_BUFFER - inBufIndex);
     } else {
-        MD5_Update(cx, padbytes,
-                   MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex);
+        MD5_Update_NonFIPS(cx, padbytes,
+                           MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex);
     }
 
     /* Store the number of bytes input (before padding) in final 64 bits. */
@@ -554,16 +567,22 @@
 }
 
 void
-MD5_EndRaw(MD5Context *cx, unsigned char *digest,
-           unsigned int *digestLen, unsigned int maxDigestLen)
+MD5_End(MD5Context *cx, unsigned char *digest,
+        unsigned int *digestLen, unsigned int maxDigestLen)
+{
+    IN_FIPS_RETURN();
+    MD5_End_NonFIPS(cx, digest, digestLen, maxDigestLen);
+}
+
+void
+MD5_EndRaw_NonFIPS(MD5Context *cx, unsigned char *digest,
+                          unsigned int *digestLen, unsigned int maxDigestLen)
 {
 #ifndef IS_LITTLE_ENDIAN
     PRUint32 tmp;
 #endif
     PRUint32 cv[4];
 
-    IN_FIPS_RETURN();
-
     if (maxDigestLen < MD5_HASH_LEN) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return;
@@ -581,6 +600,14 @@
         *digestLen = MD5_HASH_LEN;
 }
 
+void
+MD5_EndRaw(MD5Context *cx, unsigned char *digest,
+           unsigned int *digestLen, unsigned int maxDigestLen)
+{
+    IN_FIPS_RETURN();
+    MD5_EndRaw_NonFIPS(cx, digest, digestLen, maxDigestLen);
+}
+
 unsigned int
 MD5_FlattenSize(MD5Context *cx)
 {
diff --git a/lib/freebl/rawhash.c b/lib/freebl/rawhash.c
--- a/lib/freebl/rawhash.c
+++ b/lib/freebl/rawhash.c
@@ -154,3 +154,40 @@
     }
     return &SECRawHashObjects[hashType];
 }
+
+/* Defined in md5.c */
+
+MD5Context *MD5_NewContext_NonFIPS(void);
+void MD5_Begin_NonFIPS(MD5Context *cx);
+void MD5_Update_NonFIPS(MD5Context *cx, const unsigned char *input, unsigned 
int inputLen);
+void MD5_End_NonFIPS(MD5Context *cx, unsigned char *digest,
+                            unsigned int *digestLen, unsigned int 
maxDigestLen);
+void MD5_EndRaw_NonFIPS(MD5Context *cx, unsigned char *digest,
+                               unsigned int *digestLen, unsigned int 
maxDigestLen);
+
+static const SECHashObject SECRawHashObjectMD5NonFIPS = {
+    MD5_LENGTH,
+    (void *(*)(void))MD5_NewContext_NonFIPS,
+    (void *(*)(void *))null_hash_clone_context,
+    (void (*)(void *, PRBool))MD5_DestroyContext,
+    (void (*)(void *))MD5_Begin_NonFIPS,
+    (void (*)(void *, const unsigned char *, unsigned int))MD5_Update_NonFIPS,
+    (void (*)(void *, unsigned char *, unsigned int *, unsigned 
int))MD5_End_NonFIPS,
+    MD5_BLOCK_LENGTH,
+    HASH_AlgMD5,
+    (void (*)(void *, unsigned char *, unsigned int *, unsigned 
int))MD5_EndRaw_NonFIPS
+};
+
+const SECHashObject *
+HASH_GetRawHashObjectNonFIPS(HASH_HashType hashType)
+{
+    if (hashType <= HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return NULL;
+    }
+
+    if (hashType == HASH_AlgMD5)
+      return &SECRawHashObjectMD5NonFIPS;
+
+    return &SECRawHashObjects[hashType];
+}
diff --git a/lib/freebl/tlsprfalg.c b/lib/freebl/tlsprfalg.c
--- a/lib/freebl/tlsprfalg.c
+++ b/lib/freebl/tlsprfalg.c
@@ -12,6 +12,9 @@
 #include "hasht.h"
 #include "alghmac.h"
 
+/* To get valid MD5 object in FIPS mode */
+const SECHashObject *HASH_GetRawHashObjectNonFIPS(HASH_HashType hashType);
+
 #define PHASH_STATE_MAX_LEN HASH_LENGTH_MAX
 
 /* TLS P_hash function */
@@ -27,7 +30,7 @@
     SECStatus status;
     HMACContext *cx;
     SECStatus rv = SECFailure;
-    const SECHashObject *hashObj = HASH_GetRawHashObject(hashType);
+    const SECHashObject *hashObj = HASH_GetRawHashObjectNonFIPS(hashType);
 
     PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
     PORT_Assert((seed != NULL) && (seed->data != NULL));
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -6953,7 +6953,7 @@
     SFTKAttribute *att2 = NULL;
     unsigned char *buf;
     SHA1Context *sha;
-    MD5Context *md5;
+    MD5Context *md5 = NULL;
     MD2Context *md2;
     CK_ULONG macSize;
     CK_ULONG tmpKeySize;
@@ -7484,7 +7484,7 @@
             }
             sftk_FreeAttribute(att2);
             md5 = MD5_NewContext();
-            if (md5 == NULL) {
+            if (md5 == NULL && !isTLS) {
                 crv = CKR_HOST_MEMORY;
                 break;
             }
++++++ nss-fips-use-getrandom.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1574137588 -3600
#      Tue Nov 19 05:26:28 2019 +0100
# Node ID 5e191a391c38967e49a1d005800713ccd1010b09
# Parent  92da25f8ea7d41e938858872e2b6a2fb1aa53bb2
commit c2a88344b616c75b1873fb163491d7362a4c3e5b
Author: Hans Petter Jansson <h...@cl.no>
    11

diff --git a/coreconf/Linux.mk b/coreconf/Linux.mk
--- a/coreconf/Linux.mk
+++ b/coreconf/Linux.mk
@@ -184,6 +184,18 @@
 LDFLAGS        += -Wl,-z,relro
 endif
 
+#
+# On Linux 3.17 or later, use getrandom() to obtain entropy where possible.
+# Set NSS_USE_GETRANDOM to 0 in the environment to override this.
+#
+ifneq ($(OS_TARGET),Android)
+ifeq (3.17,$(firstword $(sort 3.17 $(OS_RELEASE))))
+ifneq ($(NSS_USE_GETRANDOM),0)
+       DEFINES         += -DNSS_USE_GETRANDOM
+endif
+endif
+endif
+
 USE_SYSTEM_ZLIB = 1
 ZLIB_LIBS = -lz
 
diff --git a/lib/freebl/unix_rand.c b/lib/freebl/unix_rand.c
--- a/lib/freebl/unix_rand.c
+++ b/lib/freebl/unix_rand.c
@@ -13,6 +13,10 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#ifdef NSS_USE_GETRANDOM
+# include <sys/syscall.h>
+# include <linux/random.h>
+#endif
 #include <dirent.h>
 #include "secrng.h"
 #include "secerr.h"
@@ -21,6 +25,43 @@
 #include "prprf.h"
 #include "prenv.h"
 
+#ifdef NSS_USE_GETRANDOM
+#  ifndef __NR_getrandom
+#    if defined __x86_64__
+#      define __NR_getrandom 318
+#    elif defined(__i386__)
+#      define __NR_getrandom 355
+#    elif defined(__arm__)
+#      define __NR_getrandom 384
+#    elif defined(__aarch64__)
+#      define __NR_getrandom 278
+#    elif defined(__ia64__)
+#      define __NR_getrandom 1339
+#    elif defined(__m68k__)
+#      define __NR_getrandom 352
+#    elif defined(__s390x__)
+#      define __NR_getrandom 349
+#    elif defined(__powerpc__)
+#      define __NR_getrandom 359
+#    elif defined _MIPS_SIM
+#      if _MIPS_SIM == _MIPS_SIM_ABI32
+#        define __NR_getrandom 4353
+#      endif
+#      if _MIPS_SIM == _MIPS_SIM_NABI32
+#        define __NR_getrandom 6317
+#      endif
+#      if _MIPS_SIM == _MIPS_SIM_ABI64
+#        define __NR_getrandom 5313
+#      endif
+#    else
+#      warning "__NR_getrandom unknown for your architecture"
+#    endif
+#  endif
+#  ifndef GRND_RANDOM
+#    define GRND_RANDOM 0x02
+#  endif
+#endif
+
 size_t RNG_FileUpdate(const char *fileName, size_t limit);
 
 /*
@@ -862,6 +903,26 @@
 size_t
 RNG_SystemRNG(void *dest, size_t maxLen)
 {
+#ifdef NSS_USE_GETRANDOM
+    unsigned char *buf = dest;
+    size_t inBytes = 0;
+    int ret;
+
+    do {
+        ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes, 0);
+
+        if (0 < ret)
+            inBytes += ret;
+    } while ((0 < ret || EINTR == errno || ERESTART == errno)
+             && inBytes < maxLen);
+
+    if (inBytes != maxLen) {
+         PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */
+         inBytes = 0;
+    }
+
+    return inBytes;
+#else
     FILE *file;
     int fd;
     int bytes;
@@ -895,4 +956,5 @@
         fileBytes = 0;
     }
     return fileBytes;
+#endif
 }
++++++ nss-fips-use-strong-random-pool.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574240799 -3600
#      Wed Nov 20 10:06:39 2019 +0100
# Node ID 4ddd7d49eeed4ea32850daf41a472ccb50dee45e
# Parent  0efca22bbafd7575b20461f255c46157c9321822
[PATCH] 31
>From a7cbf64ba8ac07a4a1fdea91f39da56d86af03bf Mon Sep 17 00:00:00 2001
---
 nss/lib/freebl/unix_rand.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/freebl/unix_rand.c b/lib/freebl/unix_rand.c
--- a/lib/freebl/unix_rand.c
+++ b/lib/freebl/unix_rand.c
@@ -24,6 +24,7 @@
 #include "prthread.h"
 #include "prprf.h"
 #include "prenv.h"
+#include "fips.h"
 
 #ifdef NSS_USE_GETRANDOM
 #  ifndef __NR_getrandom
@@ -779,7 +780,7 @@
     }
 
     /* grab some data from system's PRNG before any other files. */
-    bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT);
+    bytes = RNG_FileUpdate(FIPS_mode() ? "/dev/random" : "/dev/urandom", 
SYSTEM_RNG_SEED_COUNT);
     if (!bytes) {
         PORT_SetError(SEC_ERROR_NEED_RANDOM);
     }
@@ -909,7 +910,8 @@
     int ret;
 
     do {
-        ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes, 0);
+        ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes,
+                      FIPS_mode () ? GRND_RANDOM : 0);
 
         if (0 < ret)
             inBytes += ret;
@@ -929,7 +931,7 @@
     size_t fileBytes = 0;
     unsigned char *buffer = dest;
 
-    file = fopen("/dev/urandom", "r");
+    file = fopen(FIPS_mode() ? "/dev/random" : "/dev/urandom", "r");
     if (file == NULL) {
         PORT_SetError(SEC_ERROR_NEED_RANDOM);
         return 0;
++++++ nss-fips-zeroization.patch ++++++
# HG changeset patch
# User Hans Petter Jansson <h...@cl.no>
# Date 1574240665 -3600
#      Wed Nov 20 10:04:25 2019 +0100
# Node ID 3a2cb65dc157344cdad19e8e16e9c33e36f82d96
# Parent  2d4483f4a1259f965f32ff4c65436e92aef83be7
[PATCH 07/10] 29
>From 76da775313bd40a1353a9d2f6cc43ebe1a287574 Mon Sep 17 00:00:00 2001
---
 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/lib/freebl/aeskeywrap.c b/lib/freebl/aeskeywrap.c
--- a/lib/freebl/aeskeywrap.c
+++ b/lib/freebl/aeskeywrap.c
@@ -102,6 +102,7 @@
 {
     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/lib/freebl/cts.c b/lib/freebl/cts.c
--- a/lib/freebl/cts.c
+++ b/lib/freebl/cts.c
@@ -37,6 +37,7 @@
 void
 CTS_DestroyContext(CTSContext *cts, PRBool freeit)
 {
+    PORT_Memset(cts, 0, sizeof(CTSContext));
     if (freeit) {
         PORT_Free(cts);
     }
@@ -135,7 +136,7 @@
     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 @@
     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 @@
     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 @@
     /* 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/lib/freebl/dh.c b/lib/freebl/dh.c
--- a/lib/freebl/dh.c
+++ b/lib/freebl/dh.c
@@ -192,6 +192,10 @@
         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/lib/freebl/ec.c b/lib/freebl/ec.c
--- a/lib/freebl/ec.c
+++ b/lib/freebl/ec.c
@@ -958,7 +958,7 @@
     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/lib/freebl/gcm.c b/lib/freebl/gcm.c
--- a/lib/freebl/gcm.c
+++ b/lib/freebl/gcm.c
@@ -162,6 +162,9 @@
 
     *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
@@ -200,6 +203,12 @@
     }
     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
@@ -239,6 +248,10 @@
     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
@@ -324,6 +337,20 @@
         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 */
@@ -859,11 +886,13 @@
     /* 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
@@ -871,10 +900,18 @@
     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);
++++++ nss-fix-dh-pkcs-derive-inverted-logic.patch ++++++
# HG changeset patch
# User M. Sirringhaus <msirringh...@suse.de>
# Date 1590586654 -7200
#      Wed May 27 15:37:34 2020 +0200
# Node ID 582ed54a5cda147cd5996603d6066817edb687fa
# Parent  ce99bba6375432c55a73c1367f619dfef7c7e9fc
imported patch nss-fix-dh-pkcs-derive-inverted-logic.patch

diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -8316,7 +8316,7 @@
             if (crv == CKR_OK) {
                 rv = KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime);
                 PORT_Free(dhSubPrime.data);
-                if (rv != SECSuccess) {
+                if (rv == PR_FALSE) {
                     crv = CKR_ARGUMENTS_BAD;
                     PORT_Free(dhPrime.data);
                     PORT_Free(dhValue.data);
++++++ nss-sqlitename.patch ++++++
--- /var/tmp/diff_new_pack.toDILa/_old  2020-06-30 21:53:08.054140428 +0200
+++ /var/tmp/diff_new_pack.toDILa/_new  2020-06-30 21:53:08.054140428 +0200
@@ -1,32 +1,29 @@
 # HG changeset patch
-# Parent  b96f2a8d5f606fd982a8fe3655c4b71e282c3976
+# User M. Sirringhaus <msirringh...@suse.de>
+# Date 1590407652 -7200
+#      Mon May 25 13:54:12 2020 +0200
+# Node ID b1d7045b31cf4090c0b78003c77a2eb6c8c57436
+# Parent  e3d3ed5e142b172289d9d4a1c7fc63dfd4359410
 Index: security/nss/lib/sqlite/manifest.mn
 ===================================================================
 RCS file: /cvsroot/mozilla/security/nss/lib/sqlite/manifest.mn,v
 retrieving revision 1.5
 
-diff --git a/lib/sqlite/manifest.mn b/lib/sqlite/manifest.mn
---- a/lib/sqlite/manifest.mn
-+++ b/lib/sqlite/manifest.mn
-@@ -1,19 +1,20 @@
- # 
- # This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- CORE_DEPTH = ../..
+diff -r e3d3ed5e142b -r b1d7045b31cf lib/sqlite/manifest.mn
+--- a/lib/sqlite/manifest.mn   Mon Sep 18 11:24:00 2017 +0200
++++ b/lib/sqlite/manifest.mn   Mon May 25 13:54:12 2020 +0200
+@@ -6,11 +6,11 @@
  
  MODULE = nss
  
 -LIBRARY_NAME = sqlite
 +LIBRARY_NAME = nsssqlite
  LIBRARY_VERSION = 3
- MAPFILE = $(OBJDIR)/sqlite.def
+-MAPFILE = $(OBJDIR)/$(LIBRARY_NAME).def
++MAPFILE = $(OBJDIR)/sqlite.def
+ RES = $(NULL)
+-
 +MAPFILE_SOURCE = sqlite.def
  DEFINES += -DSQLITE_THREADSAFE=1
  
- EXPORTS = \
-       $(NULL)
- 
  PRIVATE_EXPORTS = \
-       sqlite3.h \
-       $(NULL)

++++++ ppc-old-abi-v3.patch ++++++
>From a7a862bab5e4aae4615ddae3cbe230345f92ed0d Mon Sep 17 00:00:00 2001
From: Lauri Kasanen <c...@gmx.com>
Date: Mon, 1 Jun 2020 12:11:45 +0300
Subject: [PATCH v3] Bug 1642174 /usr/bin/ld: 
OBJS/Linux_SINGLE_SHLIB/sha512-p8.o:
 ABI version 2 is not compatible with ABI version 1 output

Don't try to build the SHA-2 accelerated asm on old-ABI ppc.

Currently make only, I don't have enough gyp-fu to do that side.
However, the reporters of 1642174 and 1635625 both used make, not gyp.

Signed-off-by: Lauri Kasanen <c...@gmx.com>
---
 lib/freebl/Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/freebl/Makefile b/lib/freebl/Makefile
index 5f7384429..e0461c7d3 100644
--- a/lib/freebl/Makefile
+++ b/lib/freebl/Makefile
@@ -267,9 +267,12 @@ ifeq ($(CPU_ARCH),arm)
 endif
 ifeq ($(CPU_ARCH),ppc)
     EXTRA_SRCS += gcm-ppc.c
-    ASFILES += sha512-p8.s
 ifdef USE_64
     DEFINES += -DNSS_NO_INIT_SUPPORT
+    PPC_ABI := $(shell $(CC) -dM -E - < /dev/null | awk '$$2 == "_CALL_ELF" 
{print $$3}')
+    ifeq ($(PPC_ABI),2)
+        ASFILES += sha512-p8.s
+    endif
 endif # USE_64
 endif # ppc
 endif # Linux
-- 
2.19.1

++++++ system-nspr.patch ++++++
--- /var/tmp/diff_new_pack.toDILa/_old  2020-06-30 21:53:08.094140552 +0200
+++ /var/tmp/diff_new_pack.toDILa/_new  2020-06-30 21:53:08.094140552 +0200
@@ -1,25 +1,17 @@
-# HG changeset patch
-# Parent  bbf8e741ac966df6cf513ea042d1351eb279c122
-
 diff --git a/Makefile b/Makefile
+index eb4ed1a..de9c13d 100644
 --- a/Makefile
 +++ b/Makefile
-@@ -42,17 +42,17 @@ include $(CORE_DEPTH)/coreconf/rules.mk
+@@ -48,12 +48,10 @@ include $(CORE_DEPTH)/coreconf/rules.mk
  #######################################################################
  
- 
- 
- #######################################################################
- # (7) Execute "local" rules. (OPTIONAL).                              #
- #######################################################################
- 
--nss_build_all: build_nspr all latest
-+nss_build_all: all latest
- 
- nss_clean_all: clobber_nspr clobber
+ nss_build_all:
+-      $(MAKE) build_nspr
+       $(MAKE) all
+       $(MAKE) latest
+ 
+ nss_clean_all:
+-      $(MAKE) clobber_nspr
+       $(MAKE) clobber
  
  NSPR_CONFIG_STATUS = $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/config.status
- NSPR_CONFIGURE = $(CORE_DEPTH)/../nspr/configure
- 
- #
- # Translate coreconf build options to NSPR configure options.


Reply via email to