File bmo1990242.patch of Package mozilla-nss.41114

From 8dc8570390aac6947e6c686d18e3dbf7d7a10999 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 | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c
index bb5c23084..d719f3b54 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) {
@@ -1362,6 +1367,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
     unsigned char saltData[SDB_MAX_META_DATA_LEN];
     unsigned char valueData[SDB_MAX_META_DATA_LEN];
     int iterationCount = getPBEIterationCount();
+    int preferred_salt_length;
     CK_RV crv;
     SDB *db;
 
@@ -1393,7 +1399,18 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
             goto loser;
         }
     } else {
-        salt.len = SHA1_LENGTH;
+        salt.len = 0;
+    }
+
+    preferred_salt_length = SHA384_LENGTH;
+
+    /* Prefer SHA-1 if the password is NULL */
+    if (!newPin || *newPin == 0) {
+        preferred_salt_length = SHA1_LENGTH;
+    }
+
+    if (salt.len != preferred_salt_length) {
+        salt.len = preferred_salt_length;
         RNG_GenerateGlobalRandomBytes(salt.data, salt.len);
     }
 
-- 
2.47.0

openSUSE Build Service is sponsored by