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