- rebase to upstream NSS 3.124 - backport ml-dsa support that is not upstream yet. - pick up in process patches upstream including eddsa
190 lines
7.2 KiB
Diff
190 lines
7.2 KiB
Diff
# HG changeset patch
|
|
# User Robert Relyea <rrelyea@redhat.com>
|
|
# Date 1780434653 25200
|
|
# Tue Jun 02 14:10:53 2026 -0700
|
|
# Branch NSS_3_124_BRANCH
|
|
# Node ID 19e655733f3af71e3d517ada0d31ad0697d40f3f
|
|
# Parent 567ea70a139936a15e80b0c88104ea44936dfc30
|
|
nss-3.124-indicators-prf.patch
|
|
|
|
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
|
--- a/lib/softoken/pkcs11u.c
|
|
+++ b/lib/softoken/pkcs11u.c
|
|
@@ -16,37 +16,47 @@
|
|
#include "secoid.h"
|
|
#include "softkver.h"
|
|
|
|
#if !defined(NSS_FIPS_DISABLED) && defined(NSS_ENABLE_FIPS_INDICATORS)
|
|
/* handle special cases. Classes require existing code to already be
|
|
* in place for that class */
|
|
typedef enum {
|
|
SFTKFIPSNone = 0,
|
|
- SFTKFIPSDH, /* allow only specific primes */
|
|
- SFTKFIPSECC, /* not just keys but specific curves */
|
|
- SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
|
|
- SFTKFIPSRSAPSS,
|
|
- SFTKFIPSTlsKeyCheck
|
|
+ SFTKFIPSDH, /* allow only specific primes */
|
|
+ SFTKFIPSECC, /* not just keys but specific curves */
|
|
+ SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
|
|
+ SFTKFIPSRSAPSS, /* make sure salt isn't too big */
|
|
+ SFTKFIPSPBKDF2, /* handle pbkdf2 FIPS restrictions */
|
|
+ SFTKFIPSTlsKeyCheck, /* check the output of TLS prf functions */
|
|
+ SFTKFIPSChkHash, /* make sure the base hash of KDF functions is FIPS */
|
|
+ SFTKFIPSChkHashTls, /* make sure the base hash of TLS KDF functions is FIPS */
|
|
+ SFTKFIPSChkHashSp800, /* make sure the base hash of SP-800-108 KDF functions is FIPS */
|
|
+ SFTKFIPSRSAOAEP, /* make sure that both hashes use the same FIPS compliant algorithm */
|
|
} SFTKFIPSSpecialClass;
|
|
|
|
typedef struct SFTKFIPSAlgorithmListStr SFTKFIPSAlgorithmList;
|
|
struct SFTKFIPSAlgorithmListStr {
|
|
CK_MECHANISM_TYPE type;
|
|
CK_MECHANISM_INFO info;
|
|
CK_ULONG step;
|
|
SFTKFIPSSpecialClass special;
|
|
+ size_t offset;
|
|
};
|
|
/* this file should be supplied by the vendor and include all the
|
|
* algorithms which have Algorithm certs and have been reviewed by
|
|
* the lab. A blank file is included for the base so that FIPS mode
|
|
* will still be compiled and run, but FIPS indicators will always
|
|
* return PR_FALSE
|
|
*/
|
|
#include "fips_algorithms.h"
|
|
+
|
|
+#ifndef SFTKFIPS_PBKDF2_MIN_PW_LEN /* allow fips_algorithms.h to override */
|
|
+#define SFTKFIPS_PBKDF2_MIN_PW_LEN 8
|
|
+#endif
|
|
#define NSS_HAS_FIPS_INDICATORS 1
|
|
#endif
|
|
|
|
/*
|
|
* ******************** Error mapping *******************************
|
|
*/
|
|
/*
|
|
* map all the SEC_ERROR_xxx error codes that may be returned by freebl
|
|
@@ -2566,25 +2576,49 @@ sftk_checkKeyLength(CK_ULONG keyLength,
|
|
return PR_TRUE;
|
|
}
|
|
if (((keyLength - min) % step) != 0) {
|
|
return PR_FALSE;
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
+PRBool
|
|
+sftk_checkFIPSHash(CK_MECHANISM_TYPE hash, PRBool allowSmall, PRBool allowCMAC)
|
|
+{
|
|
+ switch (hash) {
|
|
+ case CKM_AES_CMAC:
|
|
+ return allowCMAC;
|
|
+ case CKM_SHA_1:
|
|
+ case CKM_SHA_1_HMAC:
|
|
+ case CKM_SHA224:
|
|
+ case CKM_SHA224_HMAC:
|
|
+ return allowSmall;
|
|
+ case CKM_SHA256:
|
|
+ case CKM_SHA256_HMAC:
|
|
+ case CKM_SHA384:
|
|
+ case CKM_SHA384_HMAC:
|
|
+ case CKM_SHA512:
|
|
+ case CKM_SHA512_HMAC:
|
|
+ return PR_TRUE;
|
|
+ }
|
|
+ return PR_FALSE;
|
|
+}
|
|
+
|
|
/*
|
|
* handle specialized FIPS semantics that are too complicated to
|
|
* handle with just a table. NOTE: this means any additional semantics
|
|
* would have to be coded here before they can be added to the table */
|
|
static PRBool
|
|
sftk_handleSpecial(SFTKSlot *slot, CK_MECHANISM *mech,
|
|
SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source,
|
|
CK_ULONG keyLength, CK_ULONG targetKeyLength)
|
|
{
|
|
+ PRBool allowSmall = PR_FALSE;
|
|
+ PRBool allowCMAC = PR_FALSE;
|
|
switch (mechInfo->special) {
|
|
case SFTKFIPSDH: {
|
|
SECItem dhPrime;
|
|
SECItem dhBase;
|
|
SECItem dhGenerator;
|
|
PRBool fipsOk = PR_FALSE;
|
|
const SECItem *dhSubPrime;
|
|
CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
|
|
@@ -2644,18 +2678,72 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
|
return PR_FALSE;
|
|
}
|
|
/* cap the salt based on the hash */
|
|
if (pss->sLen > hashObj->length) {
|
|
return PR_FALSE;
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
+ case SFTKFIPSPBKDF2: {
|
|
+ /* from NIST SP 800-132
|
|
+ * PBKDF2 must have the following addition restrictions
|
|
+ * (independent of keysize).
|
|
+ * 1. iteration count must be at least 1000.
|
|
+ * 2. salt must be at least 128 bits (16 bytes).
|
|
+ * 3. password must match the length specified in the SP
|
|
+ */
|
|
+ CK_PKCS5_PBKD2_PARAMS2 *pbkdf2 = (CK_PKCS5_PBKD2_PARAMS2 *)
|
|
+ mech->pParameter;
|
|
+ if (mech->ulParameterLen != sizeof(*pbkdf2)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ if (pbkdf2->iterations < 1000) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ if (pbkdf2->ulSaltSourceDataLen < 16) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ if (pbkdf2->ulPasswordLen < SFTKFIPS_PBKDF2_MIN_PW_LEN) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ return PR_TRUE;
|
|
+ }
|
|
+ /* check the hash mechanisms to make sure they themselves are FIPS */
|
|
+ case SFTKFIPSChkHashSp800:
|
|
+ allowCMAC = PR_TRUE;
|
|
+ case SFTKFIPSChkHash:
|
|
+ allowSmall = PR_TRUE;
|
|
+ case SFTKFIPSChkHashTls:
|
|
+ if (mech->ulParameterLen < mechInfo->offset + sizeof(CK_ULONG)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ return sftk_checkFIPSHash(*(CK_MECHANISM_TYPE *)(((char *)mech->pParameter) + mechInfo->offset), allowSmall, allowCMAC);
|
|
case SFTKFIPSTlsKeyCheck:
|
|
- return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
|
|
+ if (mech->mechanism != CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
|
|
+ /* unless the mechnism has a built-in hash, check the hash */
|
|
+ if (mech->ulParameterLen < mechInfo->offset + sizeof(CK_ULONG)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ if (!sftk_checkFIPSHash(*(CK_MECHANISM_TYPE *)(((char *)mech->pParameter) + mechInfo->offset), PR_FALSE, PR_FALSE)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ }
|
|
+ return PR_TRUE;
|
|
+ case SFTKFIPSRSAOAEP:
|
|
+ CK_RSA_PKCS_OAEP_PARAMS *rsaoaep = (CK_RSA_PKCS_OAEP_PARAMS *)
|
|
+ mech->pParameter;
|
|
+
|
|
+ HASH_HashType hash_msg = sftk_GetHashTypeFromMechanism(rsaoaep->hashAlg);
|
|
+ HASH_HashType hash_pad = sftk_GetHashTypeFromMechanism(rsaoaep->mgf);
|
|
+ /* message hash and mask generation function must be the same */
|
|
+ if (hash_pad != hash_msg)
|
|
+ return PR_FALSE;
|
|
+
|
|
+ return sftk_checkFIPSHash(rsaoaep->hashAlg, PR_FALSE, PR_FALSE);
|
|
default:
|
|
break;
|
|
}
|
|
/* if we didn't understand the special processing, mark it non-fips */
|
|
return PR_FALSE;
|
|
}
|
|
#endif
|
|
|