File nss-fips-pw-hash.patch of Package mozilla-nss

From e326b28d027bd587cde89ce9b44f34771d5dc426 Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <hpj@hpjansson.org>
Date: Tue, 23 Sep 2025 17:06:55 +0200
Subject: [PATCH] Bug 1990242 Move NSS DB password hash away from SHA-1

When the database password is set or changed, migrate the database to
a new passwordToKey function using SHA-384.

SHA-1-based databases will still be supported. The hash function to use
is determined by the size of the stored salt.

An empty password will always use SHA-1.
---
 lib/softoken/sftkpwd.c | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c
index bb5c23084..ea43f967b 100644
--- a/lib/softoken/sftkpwd.c
+++ b/lib/softoken/sftkpwd.c
@@ -93,35 +93,40 @@ static SECStatus
 sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt,
                      const char *pw, SECItem *key)
 {
-    SHA1Context *cx = NULL;
+    HASH_HashType hType;
+    const SECHashObject *hashObj;
+    void *ctx = NULL;
     SECStatus rv = SECFailure;
 
+    hType = salt->len == SHA384_LENGTH ? HASH_AlgSHA384 : HASH_AlgSHA1;
+    hashObj = HASH_GetRawHashObject(hType);
+
     if (!pw) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
-    key->data = PORT_Alloc(SHA1_LENGTH);
+    key->data = PORT_Alloc(hashObj->length);
     if (key->data == NULL) {
         goto loser;
     }
-    key->len = SHA1_LENGTH;
+    key->len = hashObj->length;
 
-    cx = SHA1_NewContext();
-    if (cx == NULL) {
+    ctx = hashObj->create();
+    if (ctx == NULL) {
         goto loser;
     }
-    SHA1_Begin(cx);
+    hashObj->begin(ctx);
     if (salt && salt->data) {
-        SHA1_Update(cx, salt->data, salt->len);
+        hashObj->update(ctx, salt->data, salt->len);
     }
-    SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw));
-    SHA1_End(cx, key->data, &key->len, key->len);
+    hashObj->update(ctx, (unsigned char *)pw, PORT_Strlen(pw));
+    hashObj->end(ctx, key->data, &key->len, key->len);
     rv = SECSuccess;
 
 loser:
-    if (cx) {
-        SHA1_DestroyContext(cx, PR_TRUE);
+    if (ctx) {
+        hashObj->destroy(ctx, PR_TRUE);
     }
     if (rv != SECSuccess) {
         if (key->data != NULL) {
@@ -1392,7 +1397,17 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
         if (rv == SECFailure) {
             goto loser;
         }
-    } else {
+    }
+
+    /* The new password will be hashed with either SHA-1 or SHA-384. If
+     * we're setting an empty password, there is no protection, so we use
+     * SHA-1 to maximize backwards compatibility. Otherwise, use SHA-384.
+     *
+     * The salt length determines the algorithm to use. */
+    if ((crv != CKR_OK || salt.len == SHA1_LENGTH) && newPin && *newPin != 0) {
+        salt.len = SHA384_LENGTH;
+        RNG_GenerateGlobalRandomBytes(salt.data, salt.len);
+    } else if (crv != CKR_OK) {
         salt.len = SHA1_LENGTH;
         RNG_GenerateGlobalRandomBytes(salt.data, salt.len);
     }
-- 
2.47.0

openSUSE Build Service is sponsored by