import UBI nss-3.112.0-4.el8_10

This commit is contained in:
eabdullin 2025-09-09 12:33:39 +00:00
parent ebdfa6e8e7
commit 5e4a09a3e2
42 changed files with 126226 additions and 4304 deletions

3
.gitignore vendored
View File

@ -3,4 +3,5 @@ SOURCES/blank-cert9.db
SOURCES/blank-key3.db
SOURCES/blank-key4.db
SOURCES/blank-secmod.db
SOURCES/nss-3.101.tar.gz
SOURCES/nss-3.112.tar.gz
SOURCES/nss_compat_test_pkcs12.tar

View File

@ -3,4 +3,5 @@ b5570125fbf6bfb410705706af48217a0817c03a SOURCES/blank-cert9.db
7f78b5bcecdb5005e7b803604b2ec9d1a9df2fb5 SOURCES/blank-key3.db
f9c9568442386da370193474de1b25c3f68cdaf6 SOURCES/blank-key4.db
bd748cf6e1465a1bbe6e751b72ffc0076aff0b50 SOURCES/blank-secmod.db
90f6f1d5440e7cc72cd27f2ecf2e8f3f680a00aa SOURCES/nss-3.101.tar.gz
b39d802c6469170df86317c81cb4f61238405ab4 SOURCES/nss-3.112.tar.gz
ba1cfaa454a2096cd9d8faaa132f3523fd7aa258 SOURCES/nss_compat_test_pkcs12.tar

View File

@ -21,8 +21,17 @@ typedef enum {
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 */
#ifndef NSS_DISABLE_KYBER
SFKFIPSMLKEM, /* make sure the keys are only mlkem and not kyber */
#endif
} SFTKFIPSSpecialClass;
#ifdef NSS_DISABLE_KYBER
/* if kyber is disable, we don't need to check that we are using
* a kyber key in the ML_KEM code */
#define SFTKFIPSMLKEM SFTKFIPSNone
#endif
/* set according to your security policy */
#define SFTKFIPS_PBKDF2_MIN_PW_LEN 8
@ -64,6 +73,10 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
#define CKF_KDF CKF_DERIVE
#define CKF_HSH CKF_DIGEST
#define CK_MAX 0xffffffffUL
#define CK_ALL_KEY 1, CK_MAX /* key limits are handled by special ops or the
* implementation itself */
#define CK_ALL_STEP 1
/* mechanisms using the same key types share the same key type
* limits */
#define RSA_FB_KEY 2048, 4096 /* min, max */
@ -87,14 +100,6 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
{ CKM_SHA256_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone },
{ CKM_SHA384_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone },
{ CKM_SHA512_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone },
{ CKM_SHA224_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone },
{ CKM_SHA256_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone },
{ CKM_SHA384_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone },
{ CKM_SHA512_RSA_PKCS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone },
{ CKM_SHA224_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA256_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA384_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA512_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA224_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA256_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSRSAPSS },
{ CKM_SHA384_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSRSAPSS },
@ -110,6 +115,12 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
{ CKM_ECDSA_SHA256, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
{ CKM_ECDSA_SHA384, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
{ CKM_ECDSA_SHA512, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
/* only allowed keys are implented for ML_DSA */
{ CKM_ML_DSA_KEY_PAIR_GEN, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSNone },
{ CKM_ML_DSA, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSNone },
/* only allowed keys are implented for ML_KEM */
{ CKM_ML_KEM_KEY_PAIR_GEN, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSMLKEM },
{ CKM_ML_KEM, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSMLKEM },
/* ------------------------- RC2 Operations --------------------------- */
/* ------------------------- AES Operations --------------------------- */
{ CKM_AES_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
@ -172,6 +183,9 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
{ CKM_PKCS5_PBKD2, { 112, 256, CKF_GEN }, 1, SFTKFIPSPBKDF2 },
/* the deprecated mechanisms, don't use for some reason we are supposed
* to set the FIPS indicators on these (sigh) */
/* NOTE: CKM_NSS_ML_KEM_KEY_GEN and the KYBER equivalent does not do
* pairwise consistency checks on key gen, so are not FIPS */
{ CKM_NSS_ML_KEM, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSNone },
{ CKM_NSS_AES_KEY_WRAP, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
{ CKM_NSS_AES_KEY_WRAP_PAD, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
{ CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256, { 384, 384, CKF_DERIVE }, 1, SFTKFIPSTlsKeyCheck },
@ -186,5 +200,12 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
{ CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
/* concatentate fuctions used in hybrid operations */
/* The following functions add data at the end of a base key. If the base
* key is FIPS, and the resulting keys are strong enough, then the
* resulting key will also be FIPS and the resulting operations will be
* FIPS approved. */
{ CKM_CONCATENATE_BASE_AND_KEY, { 112, CK_MAX, CKF_DERIVE }, 1, SFTKFIPSNone },
{ CKM_CONCATENATE_BASE_AND_DATA, { 112, CK_MAX, CKF_DERIVE }, 1, SFTKFIPSNone },
};
const int SFTK_NUMBER_FIPS_ALGORITHMS = PR_ARRAY_SIZE(sftk_fips_mechs);

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +0,0 @@
diff -up ./lib/pk11wrap/pk11pars.c.ems ./lib/pk11wrap/pk11pars.c
--- ./lib/pk11wrap/pk11pars.c.ems 2024-06-11 13:09:25.956760476 -0700
+++ ./lib/pk11wrap/pk11pars.c 2024-06-11 13:09:52.837067481 -0700
@@ -433,6 +433,8 @@ static const oidValDef kxOptList[] = {
{ CIPHER_NAME("ECDHE-RSA"), SEC_OID_TLS_ECDHE_RSA, NSS_USE_ALG_IN_SSL_KX },
{ CIPHER_NAME("ECDH-ECDSA"), SEC_OID_TLS_ECDH_ECDSA, NSS_USE_ALG_IN_SSL_KX },
{ CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("TLS-REQUIRE-EMS"), SEC_OID_TLS_REQUIRE_EMS, NSS_USE_ALG_IN_SSL_KX },
+
};
static const oidValDef smimeKxOptList[] = {
diff -up ./lib/pk11wrap/secmodti.h.add_ems_policy ./lib/pk11wrap/secmodti.h
--- ./lib/pk11wrap/secmodti.h.add_ems_policy 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/pk11wrap/secmodti.h 2023-06-12 17:18:35.129938514 -0700
@@ -202,4 +202,10 @@ struct PK11GenericObjectStr {
/* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */
#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
+/* this oid value could change values if it's added after other new
+ * upstream oids. We protect applications by hiding the define in a private
+ * header file that only NSS sees. Currently it's only available through
+ * the policy code */
+#define SEC_OID_TLS_REQUIRE_EMS SEC_OID_PRIVATE_1
+
#endif /* _SECMODTI_H_ */
diff -up ./lib/ssl/ssl3con.c.add_ems_policy ./lib/ssl/ssl3con.c
--- ./lib/ssl/ssl3con.c.add_ems_policy 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/ssl/ssl3con.c 2023-06-12 17:18:35.130938525 -0700
@@ -36,6 +36,7 @@
#include "pk11func.h"
#include "secmod.h"
#include "blapi.h"
+#include "secmodti.h" /* until SEC_OID_TLS_REQUIRE_EMS is upstream */
#include <stdio.h>
@@ -3480,6 +3481,29 @@ ssl3_ComputeMasterSecretInt(sslSocket *s
CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
unsigned int master_params_len;
+ /* if we are using TLS and we aren't using the extended master secret,
+ * and SEC_OID_TLS_REQUIRE_EMS policy is true, fail. The caller will
+ * send and alert (eventually). In the RSA Server case, the alert
+ * won't happen until Finish time because the upper level code
+ * can't tell a difference between this failure and an RSA decrypt
+ * failure, so it will proceed with a faux key */
+ if (isTLS) {
+ PRUint32 policy;
+ SECStatus rv;
+
+ /* first fetch the policy for this algorithm */
+ rv = NSS_GetAlgorithmPolicy(SEC_OID_TLS_REQUIRE_EMS, &policy);
+ /* we only look at the policy if we can fetch it. */
+ if (rv == SECSuccess) {
+ if (policy & NSS_USE_ALG_IN_SSL_KX) {
+ /* just set the error, we don't want to map any errors
+ * set by NSS_GetAlgorithmPolicy here */
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+ return SECFailure;
+ }
+ }
+ }
+
if (isTLS12) {
if (isDH)
master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH;
diff -up ./lib/util/secoid.c.ems ./lib/util/secoid.c
--- ./lib/util/secoid.c.ems 2024-06-11 13:11:28.078155282 -0700
+++ ./lib/util/secoid.c 2024-06-11 13:12:58.511188172 -0700
@@ -1890,6 +1890,12 @@ const static SECOidData oids[SEC_OID_TOT
ODE(SEC_OID_RC2_64_CBC, "RC2-64-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
ODE(SEC_OID_RC2_128_CBC, "RC2-128-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
ODE(SEC_OID_ECDH_KEA, "ECDH", CKM_ECDH1_DERIVE, INVALID_CERT_EXTENSION),
+
+ /* this will change upstream. for now apps shouldn't use it */
+ /* we need it for the policy code. */
+ ODE(SEC_OID_PRIVATE_1,
+ "TLS Require EMS", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
};
/* PRIVATE EXTENDED SECOID Table
@@ -2198,6 +2204,10 @@ SECOID_Init(void)
/* turn off NSS_USE_POLICY_IN_SSL by default */
xOids[SEC_OID_APPLY_SSL_POLICY].notPolicyFlags = NSS_USE_POLICY_IN_SSL;
+ /* turn off TLS REQUIRE EMS by default */
+ xOids[SEC_OID_PRIVATE_1].notPolicyFlags = ~0;
+
+
envVal = PR_GetEnvSecure("NSS_HASH_ALG_SUPPORT");
if (envVal)
diff -up ./lib/util/secoidt.h.ems ./lib/util/secoidt.h
--- ./lib/util/secoidt.h.ems 2024-06-11 13:16:13.212411967 -0700
+++ ./lib/util/secoidt.h 2024-06-11 13:16:48.098810434 -0700
@@ -530,6 +530,9 @@ typedef enum {
SEC_OID_RC2_64_CBC = 385,
SEC_OID_RC2_128_CBC = 386,
SEC_OID_ECDH_KEA = 387,
+ /* this will change upstream. for now apps shouldn't use it */
+ /* give it an obscure name here */
+ SEC_OID_PRIVATE_1 = 388,
SEC_OID_TOTAL
} SECOidTag;

View File

@ -1,20 +0,0 @@
diff -up ./lib/softoken/pkcs11u.c.fipsrsaoaep ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.fipsrsaoaep 2024-10-24 09:27:17.971673855 +0200
+++ ./lib/softoken/pkcs11u.c 2024-10-24 09:23:35.006352872 +0200
@@ -2565,6 +2565,16 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
}
}
return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
+ 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;
}

View File

@ -1,59 +0,0 @@
diff --git a/lib/freebl/chacha20poly1305.c b/lib/freebl/chacha20poly1305.c
--- a/lib/freebl/chacha20poly1305.c
+++ b/lib/freebl/chacha20poly1305.c
@@ -213,27 +213,31 @@
{
#ifdef NSS_X64
#ifndef NSS_DISABLE_AVX2
if (avx2_support()) {
Hacl_Chacha20_Vec256_chacha20_encrypt_256(len, output, block, k, nonce, ctr);
+ return;
}
#endif
#ifndef NSS_DISABLE_SSE3
if (ssse3_support() && sse4_1_support() && avx_support()) {
Hacl_Chacha20_Vec128_chacha20_encrypt_128(len, output, block, k, nonce, ctr);
+ return;
}
#endif
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
if (ppc_crypto_support()) {
chacha20vsx(len, output, block, k, nonce, ctr);
- } else
+ return;
+ }
#endif
{
Hacl_Chacha20_chacha20_encrypt(len, output, block, k, nonce, ctr);
+ return;
}
}
#endif /* NSS_DISABLE_CHACHAPOLY */
SECStatus
@@ -449,20 +453,18 @@
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
(uint8_t *)input, output, outTag);
goto finish;
}
#endif
-
- else
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
if (ppc_crypto_support()) {
Chacha20Poly1305_vsx_aead_encrypt(
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
(uint8_t *)input, output, outTag);
goto finish;
- } else
+ }
#endif
{
Hacl_Chacha20Poly1305_32_aead_encrypt(
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
(uint8_t *)input, output, outTag);

View File

@ -1,133 +0,0 @@
diff --git a/lib/certhigh/certvfypkix.c b/lib/certhigh/certvfypkix.c
--- a/lib/certhigh/certvfypkix.c
+++ b/lib/certhigh/certvfypkix.c
@@ -37,11 +37,11 @@
pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
PRInt32 parallelFnInvocationCount;
#endif /* PKIX_OBJECT_LEAK_TEST */
-static PRBool usePKIXValidationEngine = PR_FALSE;
+static PRBool usePKIXValidationEngine = PR_TRUE;
#endif /* NSS_DISABLE_LIBPKIX */
/*
* FUNCTION: CERT_SetUsePKIXForValidation
* DESCRIPTION:
diff --git a/lib/nss/nssinit.c b/lib/nss/nssinit.c
--- a/lib/nss/nssinit.c
+++ b/lib/nss/nssinit.c
@@ -762,13 +762,13 @@
PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
if (pkixError != NULL) {
goto loser;
} else {
- char *ev = PR_GetEnvSecure("NSS_ENABLE_PKIX_VERIFY");
+ char *ev = PR_GetEnvSecure("NSS_DISABLE_PKIX_VERIFY");
if (ev && ev[0]) {
- CERT_SetUsePKIXForValidation(PR_TRUE);
+ CERT_SetUsePKIXForValidation(PR_FALSE);
}
}
#endif /* NSS_DISABLE_LIBPKIX */
}
diff --git a/tests/all.sh b/tests/all.sh
--- a/tests/all.sh
+++ b/tests/all.sh
@@ -141,17 +141,22 @@
########################################################################
run_cycle_standard()
{
TEST_MODE=STANDARD
+ NSS_DISABLE_LIBPKIX_VERIFY="1"
+ export NSS_DISABLE_LIBPKIX_VERIFY
+
TESTS="${ALL_TESTS}"
TESTS_SKIP="libpkix pkits"
NSS_DEFAULT_DB_TYPE=${NSS_DEFAULT_DB_TYPE:-"sql"}
export NSS_DEFAULT_DB_TYPE
run_tests
+
+ unset NSS_DISABLE_LIBPKIX_VERIFY
}
############################ run_cycle_pkix ############################
# run test suites with PKIX enabled
########################################################################
@@ -165,13 +170,10 @@
HOSTDIR="${HOSTDIR}/pkix"
mkdir -p "${HOSTDIR}"
init_directories
- NSS_ENABLE_PKIX_VERIFY="1"
- export NSS_ENABLE_PKIX_VERIFY
-
TESTS="${ALL_TESTS}"
TESTS_SKIP="cipher dbtests sdr crmf smime merge multinit"
export -n NSS_SSL_RUN
diff --git a/tests/common/init.sh b/tests/common/init.sh
--- a/tests/common/init.sh
+++ b/tests/common/init.sh
@@ -138,12 +138,12 @@
echo "NSS_TEST_DISABLE_CRL=${NSS_TEST_DISABLE_CRL}"
echo "NSS_SSL_TESTS=\"${NSS_SSL_TESTS}\""
echo "NSS_SSL_RUN=\"${NSS_SSL_RUN}\""
echo "NSS_DEFAULT_DB_TYPE=${NSS_DEFAULT_DB_TYPE}"
echo "export NSS_DEFAULT_DB_TYPE"
- echo "NSS_ENABLE_PKIX_VERIFY=${NSS_ENABLE_PKIX_VERIFY}"
- echo "export NSS_ENABLE_PKIX_VERIFY"
+ echo "NSS_DISABLE_PKIX_VERIFY=${NSS_DISABLE_PKIX_VERIFY}"
+ echo "export NSS_DISABLE_PKIX_VERIFY"
echo "init_directories"
}
# Exit shellfunction to clean up at exit (error, regular or signal)
Exit()
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
--- a/tests/ssl/ssl.sh
+++ b/tests/ssl/ssl.sh
@@ -960,13 +960,12 @@
ssl_policy_pkix_ocsp()
{
#verbose="-v"
html_head "Check that OCSP doesn't break if we disable sha1 $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE"
- PKIX_SAVE=${NSS_ENABLE_PKIX_VERIFY-"unset"}
- NSS_ENABLE_PKIX_VERIFY="1"
- export NSS_ENABLE_PKIX_VERIFY
+ PKIX_SAVE=${NSS_DISABLE_LIBPKIX_VERIFY-"unset"}
+ unset NSS_DISABLE_LIBPKIX_VERIFY
testname=""
if [ ! -f "${P_R_SERVERDIR}/pkcs11.txt" ] ; then
html_failed "${SCRIPTNAME}: ${P_R_SERVERDIR} is not initialized"
@@ -987,16 +986,14 @@
grep 12276 ${P_R_SERVERDIR}/vfy.out
RET=$?
html_msg $RET $RET_EXP "${testname}" \
"produced a returncode of $RET, expected is $RET_EXP"
- if [ "${PKIX_SAVE}" = "unset" ]; then
- unset NSS_ENABLE_PKIX_VERIFY
- else
- NSS_ENABLE_PKIX_VERIFY=${PKIX_SAVE}
- export NSS_ENABLE_PKIX_VERIFY
+ if [ "{PKIX_SAVE}" != "unset" ]; then
+ export NSS_DISABLE_LIBPKIX_VERIFY=${PKIX_SAVE}
fi
+
cp ${P_R_SERVERDIR}/pkcs11.txt.sav ${P_R_SERVERDIR}/pkcs11.txt
html "</TABLE><BR>"
}

View File

@ -1,45 +0,0 @@
diff -up ./lib/pk11wrap/pk11pars.c.no_signature_policy ./lib/pk11wrap/pk11pars.c
--- ./lib/pk11wrap/pk11pars.c.no_signature_policy 2023-06-21 08:54:54.802785229 +0200
+++ ./lib/pk11wrap/pk11pars.c 2023-06-21 08:58:24.748282499 +0200
@@ -395,12 +395,9 @@ static const oidValDef signOptList[] = {
/* Signatures */
{ CIPHER_NAME("DSA"), SEC_OID_ANSIX9_DSA_SIGNATURE,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
+ { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, 0},
+ { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0},
+ { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, 0},
{ CIPHER_NAME("ED25519"), SEC_OID_ED25519_PUBLIC_KEY,
NSS_USE_ALG_IN_SIGNATURE },
};
typedef struct {
@@ -416,7 +413,7 @@ static const algListsDef algOptLists[] =
{ macOptList, PR_ARRAY_SIZE(macOptList), "MAC", PR_FALSE },
{ cipherOptList, PR_ARRAY_SIZE(cipherOptList), "CIPHER", PR_FALSE },
{ kxOptList, PR_ARRAY_SIZE(kxOptList), "OTHER-KX", PR_FALSE },
{ smimeKxOptList, PR_ARRAY_SIZE(smimeKxOptList), "SMIME-KX", PR_TRUE },
- { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_FALSE },
+ { signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_TRUE },
};
static const optionFreeDef sslOptList[] = {
diff -up ./tests/ssl/sslpolicy.txt.no_signature_policy ./tests/ssl/sslpolicy.txt
--- ./tests/ssl/sslpolicy.txt.no_signature_policy 2023-06-21 09:00:17.720181306 +0200
+++ ./tests/ssl/sslpolicy.txt 2023-06-21 09:00:55.637501208 +0200
@@ -193,7 +193,9 @@
1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-ede3-cbc:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly Narrow
1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly
0 noECC SSL3 d disallow=dsa Disallow DSA Signatures Explicitly
- 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly
+# rsa-pkcs, rsa-pss, and ecdsa policy checking reverted in rhel8 for binary
+# compatibility reasons
+# 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-verify Restrict RSA keys on signature verification
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-sign Restrict RSA keys on signing
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-ssl Restrict RSA keys when used in SSL

View File

@ -1,12 +0,0 @@
diff -up ./tests/ssl/sslpolicy.txt.rsa_disable_test ./tests/ssl/sslpolicy.txt
--- ./tests/ssl/sslpolicy.txt.rsa_disable_test 2024-06-19 11:17:10.261637015 -0700
+++ ./tests/ssl/sslpolicy.txt 2024-06-19 11:18:22.797425628 -0700
@@ -197,7 +197,7 @@
# compatibility reasons
# 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-verify Restrict RSA keys on signature verification
- 1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-sign Restrict RSA keys on signing
+ 0 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-sign Restrict RSA keys on signing
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-ssl Restrict RSA keys when used in SSL
0 noECC SSL3 d allow=rsa-min=1023 Restrict RSA keys when used in SSL
# test default settings

View File

@ -1,89 +0,0 @@
diff -up ./lib/pkcs12/p12plcy.c.no_p12_smime_policy ./lib/pkcs12/p12plcy.c
--- ./lib/pkcs12/p12plcy.c.no_p12_smime_policy 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/pkcs12/p12plcy.c 2024-07-17 11:26:00.334836451 -0700
@@ -37,6 +37,7 @@ static pkcs12SuiteMap pkcs12SuiteMaps[]
static PRBool
sec_PKCS12Allowed(SECOidTag alg, PRUint32 needed)
{
+#ifdef notdef
PRUint32 policy;
SECStatus rv;
@@ -48,6 +49,9 @@ sec_PKCS12Allowed(SECOidTag alg, PRUint3
return PR_TRUE;
}
return PR_FALSE;
+#else
+ return PR_TRUE;
+#endif
}
PRBool
diff -up ./lib/smime/smimeutil.c.no_p12_smime_policy ./lib/smime/smimeutil.c
--- ./lib/smime/smimeutil.c.no_p12_smime_policy 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/smime/smimeutil.c 2024-07-17 11:27:04.716617111 -0700
@@ -202,6 +202,7 @@ smime_get_policy_tag_from_key_length(SEC
PRBool
smime_allowed_by_policy(SECOidTag algtag, PRUint32 neededPolicy)
{
+#ifdef notdef
PRUint32 policyFlags;
/* some S/MIME algs map to the same underlying KEA mechanism,
@@ -221,6 +222,7 @@ smime_allowed_by_policy(SECOidTag algtag
PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
return PR_FALSE;
}
+#endif
return PR_TRUE;
}
@@ -485,6 +487,7 @@ smime_init_once(void *arg)
return PR_FAILURE;
}
+#ifdef notdef
/* At initialization time, we need to set up the defaults. We first
* look to see if the system or application has set up certain algorithms
* by policy. If they have set up values by policy we'll only allow those
@@ -497,6 +500,11 @@ smime_init_once(void *arg)
PORT_Free(tags);
tags = NULL;
}
+#else
+ /* just initialize the old maps */
+ rv = SECSuccess;
+ tagCount = 0;
+#endif
if ((rv != SECSuccess) || (tagCount == 0)) {
/* No algorithms have been enabled by policy (either by the system
* or by the application, we then will use the traditional default
diff -up ./smime/smime.sh.no_p12_smime_policy ./smime/smime.sh
--- ./tests/smime/smime.sh.no_p12_smime_policy 2024-07-17 12:27:36.262106070 -0
700
+++ ./tests/smime/smime.sh 2024-07-17 12:29:08.251207306 -0700
@@ -872,8 +872,8 @@ smime_init
smime_main
smime_data_tb
smime_p7
-if [ "${TEST_MODE}" = "SHARED_DB" ] ; then
- smime_policy
-fi
+#if [ "${TEST_MODE}" = "SHARED_DB" ] ; then
+# smime_policy
+#fi
smime_cleanup
diff -up ./tools/tools.sh.no_p12_smime_policy ./tools/tools.sh
--- ./tests/tools/tools.sh.no_p12_smime_policy 2024-07-17 12:27:36.262106070 -0
700
+++ ./tests/tools/tools.sh 2024-07-17 12:28:32.418778346 -0700
@@ -586,7 +586,7 @@ tools_p12()
tools_p12_import_pbmac1_samples
if [ "${TEST_MODE}" = "SHARED_DB" ] ; then
tools_p12_import_rsa_pss_private_key
- tools_p12_policy
+#tools_p12_policy
fi
}

View File

@ -1,13 +0,0 @@
diff -up ./lib/pk11wrap/pk11pars.c.enable_kyber_policy ./lib/pk11wrap/pk11pars.c
--- ./lib/pk11wrap/pk11pars.c.enable_kyber_policy 2024-06-12 14:44:24.680338868 -0700
+++ ./lib/pk11wrap/pk11pars.c 2024-06-12 14:44:48.368609356 -0700
@@ -245,7 +245,8 @@ static const oidValDef curveOptList[] =
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("CURVE25519"), SEC_OID_CURVE25519,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
- { CIPHER_NAME("XYBER768D00"), SEC_OID_XYBER768D00, 0 },
+ { CIPHER_NAME("XYBER768D00"), SEC_OID_XYBER768D00,
+ NSS_USE_ALG_IN_SSL_KX },
/* ANSI X9.62 named elliptic curves (characteristic two field) */
{ CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },

View File

@ -1,12 +0,0 @@
diff -up ./lib/softoken/pkcs11u.c.fips_check_curver25519 ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.fips_check_curver25519 2024-11-11 11:24:25.186654635 +0100
+++ ./lib/softoken/pkcs11u.c 2024-11-07 10:26:03.806562274 +0100
@@ -2356,7 +2356,7 @@ sftk_getKeyLength(SFTKObject *source)
* key length is CKA_VALUE, which is the default */
keyType = CKK_INVALID_KEY_TYPE;
}
- if (keyType == CKK_EC) {
+ if (keyType == CKK_EC || keyType == CKK_EC_EDWARDS || keyType == CKK_EC_MONTGOMERY) {
SECOidTag curve = sftk_quickGetECCCurveOid(source);
switch (curve) {
case SEC_OID_CURVE25519:

View File

@ -1,190 +0,0 @@
diff -up ./lib/softoken/pkcs11c.c.fips_indicators ./lib/softoken/pkcs11c.c
--- ./lib/softoken/pkcs11c.c.fips_indicators 2024-06-12 13:38:15.995811284 -0700
+++ ./lib/softoken/pkcs11c.c 2024-06-12 13:41:30.008188930 -0700
@@ -453,7 +453,7 @@ sftk_InitGeneric(SFTKSession *session, C
context->blockSize = 0;
context->maxLen = 0;
context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism,
- operation, key);
+ operation, key, 0);
*contextPtr = context;
return CKR_OK;
}
@@ -4885,7 +4885,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
crv = sftk_handleObject(key, session);
/* we need to do this check at the end, so we can check the generated
* key length against fips requirements */
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key, 0);
session->lastOpWasFIPS = key->isFIPS;
sftk_FreeSession(session);
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
@@ -6020,7 +6020,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
return crv;
}
/* we need to do this check at the end to make sure the generated key meets the key length requirements */
- privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey);
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey, 0);
publicKey->isFIPS = privateKey->isFIPS;
session->lastOpWasFIPS = privateKey->isFIPS;
sftk_FreeSession(session);
@@ -7220,6 +7220,10 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
return CKR_TEMPLATE_INCONSISTENT;
}
+ if (!params->bExpand) {
+ keySize = hashLen;
+ }
+
/* sourceKey is NULL if we are called from the POST, skip the
* sensitiveCheck */
if (sourceKey != NULL) {
@@ -7269,7 +7273,8 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
mech.pParameter = params;
mech.ulParameterLen = sizeof(*params);
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
- CKA_DERIVE, saltKey);
+ CKA_DERIVE, saltKey,
+ keySize);
}
saltKeySource = saltKey->source;
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
@@ -7336,7 +7341,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
/* HKDF-Expand */
if (!params->bExpand) {
okm = prk;
- keySize = genLen = hashLen;
+ genLen = hashLen;
} else {
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
@@ -7583,7 +7588,8 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
return CKR_KEY_HANDLE_INVALID;
}
}
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey);
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey,
+ keySize);
switch (mechanism) {
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
diff -up ./lib/softoken/pkcs11i.h.fips_indicators ./lib/softoken/pkcs11i.h
--- ./lib/softoken/pkcs11i.h.fips_indicators 2024-06-12 13:38:15.988811198 -0700
+++ ./lib/softoken/pkcs11i.h 2024-06-12 13:38:15.996811296 -0700
@@ -979,7 +979,8 @@ CK_FLAGS sftk_AttributeToFlags(CK_ATTRIB
/* check the FIPS table to determine if this current operation is allowed by
* FIPS security policy */
PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech,
- CK_ATTRIBUTE_TYPE op, SFTKObject *source);
+ CK_ATTRIBUTE_TYPE op, SFTKObject *source,
+ CK_ULONG targetKeySize);
/* add validation objects to the slot */
CK_RV sftk_CreateValidationObjects(SFTKSlot *slot);
diff -up ./lib/softoken/pkcs11u.c.fips_indicators ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.fips_indicators 2024-06-12 13:38:15.990811223 -0700
+++ ./lib/softoken/pkcs11u.c 2024-06-12 13:38:15.996811296 -0700
@@ -2336,7 +2336,7 @@ sftk_quickGetECCCurveOid(SFTKObject *sou
static CK_ULONG
sftk_getKeyLength(SFTKObject *source)
{
- CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
+ CK_KEY_TYPE keyType = CKK_INVALID_KEY_TYPE;
CK_ATTRIBUTE_TYPE keyAttribute;
CK_ULONG keyLength = 0;
SFTKAttribute *attribute;
@@ -2398,13 +2398,29 @@ sftk_getKeyLength(SFTKObject *source)
return keyLength;
}
+PRBool
+sftk_CheckFIPSHash(CK_MECHANISM_TYPE hash)
+{
+ switch (hash) {
+ case CKM_SHA256:
+ case CKG_MGF1_SHA256:
+ case CKM_SHA384:
+ case CKG_MGF1_SHA384:
+ case CKM_SHA512:
+ case CKG_MGF1_SHA512:
+ 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)
+ SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source,
+ CK_ULONG keyLength, CK_ULONG targetKeyLength)
{
switch (mechInfo->special) {
case SFTKFIPSDH: {
@@ -2464,10 +2480,15 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
if (hashObj == NULL) {
return PR_FALSE;
}
+ /* cap the salt for legacy keys */
+ if ((keyLength <= 1024) && (pss->sLen > 63)) {
+ return PR_FALSE;
+ }
+ /* cap the salt for based on the hash */
if (pss->sLen > hashObj->length) {
return PR_FALSE;
}
- return PR_TRUE;
+ return sftk_CheckFIPSHash(pss->hashAlg);
}
case SFTKFIPSPBKDF2: {
/* PBKDF2 must have the following addition restrictions
@@ -2492,6 +2513,13 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
}
return PR_TRUE;
}
+ /* check the hash mechanisms to make sure they themselves are FIPS */
+ case SFTKFIPSChkHash:
+ if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) {
+ return PR_FALSE;
+ }
+ return sftk_CheckFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
+ + mechInfo->offset));
default:
break;
}
@@ -2502,7 +2530,7 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
PRBool
sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op,
- SFTKObject *source)
+ SFTKObject *source, CK_ULONG targetKeyLength)
{
#ifndef NSS_HAS_FIPS_INDICATORS
return PR_FALSE;
@@ -2534,13 +2562,17 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
SFTKFIPSAlgorithmList *mechs = &sftk_fips_mechs[i];
/* if we match the number of records exactly, then we are an
* approved algorithm in the approved mode with an approved key */
- if (((mech->mechanism == mechs->type) &&
- (opFlags == (mechs->info.flags & opFlags)) &&
- (keyLength <= mechs->info.ulMaxKeySize) &&
- (keyLength >= mechs->info.ulMinKeySize) &&
- ((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
+ if ((mech->mechanism == mechs->type) &&
+ (opFlags == (mechs->info.flags & opFlags)) &&
+ (keyLength <= mechs->info.ulMaxKeySize) &&
+ (keyLength >= mechs->info.ulMinKeySize) &&
+ (((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
+ ((targetKeyLength == 0) ||
+ ((targetKeyLength <= mechs->info.ulMaxKeySize) &&
+ (targetKeyLength >= mechs->info.ulMinKeySize) &&
+ ((targetKeyLength - mechs->info.ulMinKeySize) % mechs->step) == 0)) &&
((mechs->special == SFTKFIPSNone) ||
- sftk_handleSpecial(slot, mech, mechs, source))) {
+ sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
return PR_TRUE;
}
}

View File

@ -1,490 +0,0 @@
diff -up ./lib/freebl/dh.c.fips-review ./lib/freebl/dh.c
--- ./lib/freebl/dh.c.fips-review 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/freebl/dh.c 2024-06-12 12:04:10.639360404 -0700
@@ -445,7 +445,7 @@ cleanup:
PRBool
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
{
- mp_int p, q, y, r;
+ mp_int p, q, y, r, psub1;
mp_err err;
int cmp = 1; /* default is false */
if (!Y || !prime || !subPrime) {
@@ -456,13 +456,30 @@ KEA_Verify(SECItem *Y, SECItem *prime, S
MP_DIGITS(&q) = 0;
MP_DIGITS(&y) = 0;
MP_DIGITS(&r) = 0;
+ MP_DIGITS(&psub1) = 0;
CHECK_MPI_OK(mp_init(&p));
CHECK_MPI_OK(mp_init(&q));
CHECK_MPI_OK(mp_init(&y));
CHECK_MPI_OK(mp_init(&r));
+ CHECK_MPI_OK(mp_init(&psub1));
SECITEM_TO_MPINT(*prime, &p);
SECITEM_TO_MPINT(*subPrime, &q);
SECITEM_TO_MPINT(*Y, &y);
+ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1));
+ /*
+ * We check that the public value isn't zero (which isn't in the
+ * group), one (subgroup of order one) or p-1 (subgroup of order 2). We
+ * also check that the public value is less than p, to avoid being fooled
+ * by values like p+1 or 2*p-1.
+ * This check is required by SP-800-56Ar3. It's also done in derive,
+ * but this is only called in various FIPS cases, so put it here to help
+ * reviewers find it.
+ */
+ if (mp_cmp_d(&y, 1) <= 0 ||
+ mp_cmp(&y, &psub1) >= 0) {
+ err = MP_BADARG;
+ goto cleanup;
+ }
/* compute r = y**q mod p */
CHECK_MPI_OK(mp_exptmod(&y, &q, &p, &r));
/* compare to 1 */
@@ -472,6 +489,7 @@ cleanup:
mp_clear(&q);
mp_clear(&y);
mp_clear(&r);
+ mp_clear(&psub1);
if (err) {
MP_TO_SEC_ERROR(err);
return PR_FALSE;
diff -up ./lib/softoken/pkcs11c.c.fips-review ./lib/softoken/pkcs11c.c
--- ./lib/softoken/pkcs11c.c.fips-review 2024-06-12 12:04:10.638360392 -0700
+++ ./lib/softoken/pkcs11c.c 2024-06-12 13:06:35.410551333 -0700
@@ -43,6 +43,7 @@
#include "prprf.h"
#include "prenv.h"
+#include "prerror.h"
#define __PASTE(x, y) x##y
#define BAD_PARAM_CAST(pMech, typeSize) (!pMech->pParameter || pMech->ulParameterLen < typeSize)
@@ -4882,6 +4883,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
* handle the base object stuff
*/
crv = sftk_handleObject(key, session);
+ /* we need to do this check at the end, so we can check the generated
+ * key length against fips requirements */
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
+ session->lastOpWasFIPS = key->isFIPS;
sftk_FreeSession(session);
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
@@ -4889,9 +4894,6 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
}
- /* we need to do this check at the end, so we can check the generated key length against
- * fips requirements */
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
if (crv == CKR_OK) {
*phKey = key->handle;
}
@@ -5199,60 +5201,68 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
if (isDerivable) {
SFTKAttribute *pubAttribute = NULL;
- CK_OBJECT_HANDLE newKey;
PRBool isFIPS = sftk_isFIPS(slot->slotID);
- CK_RV crv2;
- CK_OBJECT_CLASS secret = CKO_SECRET_KEY;
- CK_KEY_TYPE generic = CKK_GENERIC_SECRET;
- CK_ULONG keyLen = 128;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_ATTRIBUTE template[] = {
- { CKA_CLASS, &secret, sizeof(secret) },
- { CKA_KEY_TYPE, &generic, sizeof(generic) },
- { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) },
- { CKA_DERIVE, &ckTrue, sizeof(ckTrue) }
- };
- CK_ULONG templateCount = PR_ARRAY_SIZE(template);
- CK_ECDH1_DERIVE_PARAMS ecParams;
+ NSSLOWKEYPrivateKey *lowPrivKey = NULL;
+ ECPrivateKey *ecPriv;
+ SECItem *lowPubValue = NULL;
+ SECItem item;
+ SECStatus rv;
crv = CKR_OK; /*paranoia, already get's set before we drop to the end */
- /* FIPS 140-2 requires we verify that the resulting key is a valid key.
- * The easiest way to do this is to do a derive operation, which checks
- * the validity of the key */
-
+ /* FIPS 140-3 requires we verify that the resulting key is a valid key
+ * by recalculating the public can an compare it to our own public
+ * key. */
+ lowPrivKey = sftk_GetPrivKey(privateKey, keyType, &crv);
+ if (lowPrivKey == NULL) {
+ return sftk_MapCryptError(PORT_GetError());
+ }
+ /* recalculate the public key from the private key */
switch (keyType) {
- case CKK_DH:
- mech.mechanism = CKM_DH_PKCS_DERIVE;
- pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE);
- if (pubAttribute == NULL) {
- return CKR_DEVICE_ERROR;
- }
- mech.pParameter = pubAttribute->attrib.pValue;
- mech.ulParameterLen = pubAttribute->attrib.ulValueLen;
- break;
- case CKK_EC:
- mech.mechanism = CKM_ECDH1_DERIVE;
- pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT);
- if (pubAttribute == NULL) {
- return CKR_DEVICE_ERROR;
- }
- ecParams.kdf = CKD_NULL;
- ecParams.ulSharedDataLen = 0;
- ecParams.pSharedData = NULL;
- ecParams.ulPublicDataLen = pubAttribute->attrib.ulValueLen;
- ecParams.pPublicData = pubAttribute->attrib.pValue;
- mech.pParameter = &ecParams;
- mech.ulParameterLen = sizeof(ecParams);
- break;
- default:
- return CKR_DEVICE_ERROR;
+ case CKK_DH:
+ rv = DH_Derive(&lowPrivKey->u.dh.base, &lowPrivKey->u.dh.prime,
+ &lowPrivKey->u.dh.privateValue, &item, 0);
+ if (rv != SECSuccess) {
+ return CKR_GENERAL_ERROR;
+ }
+ lowPubValue = SECITEM_DupItem(&item);
+ SECITEM_ZfreeItem(&item, PR_FALSE);
+ pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE);
+ break;
+ case CKK_EC:
+ rv = EC_NewKeyFromSeed(&lowPrivKey->u.ec.ecParams, &ecPriv,
+ lowPrivKey->u.ec.privateValue.data,
+ lowPrivKey->u.ec.privateValue.len);
+ if (rv != SECSuccess) {
+ return CKR_GENERAL_ERROR;
+ }
+ /* make sure it has the same encoding */
+ if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
+ lowPrivKey->u.ec.ecParams.type != ec_params_named) {
+ lowPubValue = SECITEM_DupItem(&ecPriv->publicValue);
+ } else {
+ lowPubValue = SEC_ASN1EncodeItem(NULL, NULL, &ecPriv->publicValue,
+ SEC_ASN1_GET(SEC_OctetStringTemplate));;
+ }
+ pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT);
+ /* clear out our generated private key */
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
+ break;
+ default:
+ return CKR_DEVICE_ERROR;
}
- crv = NSC_DeriveKey(hSession, &mech, privateKey->handle, template, templateCount, &newKey);
- if (crv != CKR_OK) {
- sftk_FreeAttribute(pubAttribute);
- return crv;
+ /* now compare new public key with our already generated key */
+ if ((pubAttribute == NULL) || (lowPubValue == NULL) ||
+ (pubAttribute->attrib.ulValueLen != lowPubValue->len) ||
+ (PORT_Memcmp(pubAttribute->attrib.pValue, lowPubValue->data,
+ lowPubValue->len) != 0)) {
+ if (pubAttribute) sftk_FreeAttribute(pubAttribute);
+ if (lowPubValue) SECITEM_ZfreeItem(lowPubValue, PR_TRUE);
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return CKR_GENERAL_ERROR;
}
+ SECITEM_ZfreeItem(lowPubValue, PR_TRUE);
+
/* FIPS requires full validation, but in fipx mode NSC_Derive
* only does partial validation with approved primes, now handle
* full validation */
@@ -5260,44 +5270,78 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
SECItem pubKey;
SECItem prime;
SECItem subPrime;
+ SECItem base;
+ SECItem generator;
const SECItem *subPrimePtr = &subPrime;
pubKey.data = pubAttribute->attrib.pValue;
pubKey.len = pubAttribute->attrib.ulValueLen;
- prime.data = subPrime.data = NULL;
- prime.len = subPrime.len = 0;
+ base.data = prime.data = subPrime.data = NULL;
+ base.len = prime.len = subPrime.len = 0;
crv = sftk_Attribute2SecItem(NULL, &prime, privateKey, CKA_PRIME);
if (crv != CKR_OK) {
goto done;
}
- crv = sftk_Attribute2SecItem(NULL, &prime, privateKey, CKA_PRIME);
+ crv = sftk_Attribute2SecItem(NULL, &base, privateKey, CKA_BASE);
+ if (crv != CKR_OK) {
+ goto done;
+ }
/* we ignore the return code an only look at the length */
- if (subPrime.len == 0) {
- /* subprime not supplied, In this case look it up.
- * This only works with approved primes, but in FIPS mode
- * that's the only kine of prime that will get here */
- subPrimePtr = sftk_VerifyDH_Prime(&prime, isFIPS);
- if (subPrimePtr == NULL) {
- crv = CKR_GENERAL_ERROR;
+ /* do we have a known prime ? */
+ subPrimePtr = sftk_VerifyDH_Prime(&prime, &generator, isFIPS);
+ if (subPrimePtr == NULL) {
+ if (subPrime.len == 0) {
+ /* if not a known prime, subprime must be supplied */
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto done;
+ } else {
+ /* not a known prime, check for primality of prime
+ * and subPrime */
+ if (!KEA_PrimeCheck(&prime)) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto done;
+ }
+ if (!KEA_PrimeCheck(&subPrime)) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto done;
+ }
+ /* if we aren't using a defined group, make sure base is in the
+ * subgroup. If it's not, then our key could fail or succeed sometimes.
+ * This makes the failure reliable */
+ if (!KEA_Verify(&base, &prime, (SECItem *)subPrimePtr)) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+ subPrimePtr = &subPrime;
+ } else {
+ /* we're using a known group, make sure we are using the known generator for that group */
+ if (SECITEM_CompareItem(&generator, &base) != 0) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
goto done;
}
+ if (subPrime.len != 0) {
+ /* we have a known prime and a supplied subPrime,
+ * make sure the subPrime matches the subPrime for
+ * the known Prime */
+ if (SECITEM_CompareItem(subPrimePtr, &subPrime) != 0) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto done;
+ }
+ }
}
if (!KEA_Verify(&pubKey, &prime, (SECItem *)subPrimePtr)) {
- crv = CKR_GENERAL_ERROR;
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
}
done:
+ SECITEM_ZfreeItem(&base, PR_FALSE);
SECITEM_ZfreeItem(&subPrime, PR_FALSE);
SECITEM_ZfreeItem(&prime, PR_FALSE);
}
/* clean up before we return */
sftk_FreeAttribute(pubAttribute);
- crv2 = NSC_DestroyObject(hSession, newKey);
if (crv != CKR_OK) {
return crv;
}
- if (crv2 != CKR_OK) {
- return crv2;
- }
}
return CKR_OK;
@@ -5925,8 +5969,8 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
* created and linked.
*/
crv = sftk_handleObject(publicKey, session);
- sftk_FreeSession(session);
if (crv != CKR_OK) {
+ sftk_FreeSession(session);
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
sftk_FreeObject(privateKey);
@@ -5968,6 +6012,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
}
if (crv != CKR_OK) {
+ sftk_FreeSession(session);
NSC_DestroyObject(hSession, publicKey->handle);
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
@@ -5977,6 +6022,8 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
/* we need to do this check at the end to make sure the generated key meets the key length requirements */
privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey);
publicKey->isFIPS = privateKey->isFIPS;
+ session->lastOpWasFIPS = privateKey->isFIPS;
+ sftk_FreeSession(session);
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
@@ -8610,7 +8657,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
/* if the prime is an approved prime, we can skip all the other
* checks. */
- subPrime = sftk_VerifyDH_Prime(&dhPrime, isFIPS);
+ subPrime = sftk_VerifyDH_Prime(&dhPrime, NULL, isFIPS);
if (subPrime == NULL) {
SECItem dhSubPrime;
/* If the caller set the subprime value, it means that
@@ -8792,6 +8839,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
secretlen = tmp.len;
} else {
secretlen = keySize;
+ key->isFIPS = PR_FALSE;
crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
&tmp, mechParams->pSharedData,
mechParams->ulSharedDataLen, mechParams->kdf);
diff -up ./lib/softoken/pkcs11i.h.fips-review ./lib/softoken/pkcs11i.h
--- ./lib/softoken/pkcs11i.h.fips-review 2024-06-12 12:04:10.638360392 -0700
+++ ./lib/softoken/pkcs11i.h 2024-06-12 12:04:10.640360416 -0700
@@ -971,7 +971,7 @@ char **NSC_ModuleDBFunc(unsigned long fu
/* dh verify functions */
/* verify that dhPrime matches one of our known primes, and if so return
* it's subprime value */
-const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, PRBool isFIPS);
+const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *generator, PRBool isFIPS);
/* check if dhSubPrime claims dhPrime is a safe prime. */
SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe);
/* map an operation Attribute to a Mechanism flag */
diff -up ./lib/softoken/pkcs11u.c.fips-review ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.fips-review 2024-06-12 12:04:10.638360392 -0700
+++ ./lib/softoken/pkcs11u.c 2024-06-12 12:04:10.640360416 -0700
@@ -2409,15 +2409,27 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
switch (mechInfo->special) {
case SFTKFIPSDH: {
SECItem dhPrime;
+ SECItem dhBase;
+ SECItem dhGenerator;
+ PRBool val = PR_FALSE;
const SECItem *dhSubPrime;
CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
source, CKA_PRIME);
if (crv != CKR_OK) {
return PR_FALSE;
}
- dhSubPrime = sftk_VerifyDH_Prime(&dhPrime, PR_TRUE);
+ crv = sftk_Attribute2SecItem(NULL, &dhBase, source, CKA_BASE);
+ if (crv != CKR_OK) {
+ return PR_FALSE;
+ }
+ dhSubPrime = sftk_VerifyDH_Prime(&dhPrime, &dhGenerator, PR_TRUE);
+ val = (dhSubPrime) ? PR_TRUE : PR_FALSE;
+ if (val && (SECITEM_CompareItem(&dhBase, &dhGenerator) != 0)) {
+ val = PR_FALSE;
+ }
SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
- return (dhSubPrime) ? PR_TRUE : PR_FALSE;
+ SECITEM_ZfreeItem(&dhBase, PR_FALSE);
+ return val;
}
case SFTKFIPSNone:
return PR_FALSE;
diff -up ./lib/softoken/sftkdhverify.c.fips-review ./lib/softoken/sftkdhverify.c
--- ./lib/softoken/sftkdhverify.c.fips-review 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/sftkdhverify.c 2024-06-12 12:04:10.641360427 -0700
@@ -6726,11 +6726,20 @@ static const SECItem subprime_tls_8192 =
(unsigned char *)subprime_tls_8192_data,
sizeof(subprime_tls_8192_data) };
+/* generator for all the groups is 2 */
+static const unsigned char generator_2_data[] = { 2 };
+
+
+static const SECItem generator_2 =
+ { siBuffer,
+ (unsigned char *)generator_2_data,
+ sizeof(generator_2_data) };
+
/*
* verify that dhPrime matches one of our known primes
*/
const SECItem *
-sftk_VerifyDH_Prime(SECItem *dhPrime, PRBool isFIPS)
+sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *g, PRBool isFIPS)
{
/* use the length to decide which primes to check */
switch (dhPrime->len) {
@@ -6741,56 +6750,67 @@ sftk_VerifyDH_Prime(SECItem *dhPrime, PR
}
if (PORT_Memcmp(dhPrime->data, prime_ike_1536,
sizeof(prime_ike_1536)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_1536;
}
break;
case 2048 / PR_BITS_PER_BYTE:
if (PORT_Memcmp(dhPrime->data, prime_tls_2048,
sizeof(prime_tls_2048)) == 0) {
+ if (g) *g = generator_2;
return &subprime_tls_2048;
}
if (PORT_Memcmp(dhPrime->data, prime_ike_2048,
sizeof(prime_ike_2048)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_2048;
}
break;
case 3072 / PR_BITS_PER_BYTE:
if (PORT_Memcmp(dhPrime->data, prime_tls_3072,
sizeof(prime_tls_3072)) == 0) {
+ if (g) *g = generator_2;
return &subprime_tls_3072;
}
if (PORT_Memcmp(dhPrime->data, prime_ike_3072,
sizeof(prime_ike_3072)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_3072;
}
break;
case 4096 / PR_BITS_PER_BYTE:
if (PORT_Memcmp(dhPrime->data, prime_tls_4096,
sizeof(prime_tls_4096)) == 0) {
+ if (g) *g = generator_2;
return &subprime_tls_4096;
}
if (PORT_Memcmp(dhPrime->data, prime_ike_4096,
sizeof(prime_ike_4096)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_4096;
}
break;
case 6144 / PR_BITS_PER_BYTE:
if (PORT_Memcmp(dhPrime->data, prime_tls_6144,
sizeof(prime_tls_6144)) == 0) {
+ if (g) *g = generator_2;
return &subprime_tls_6144;
}
if (PORT_Memcmp(dhPrime->data, prime_ike_6144,
sizeof(prime_ike_6144)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_6144;
}
break;
case 8192 / PR_BITS_PER_BYTE:
if (PORT_Memcmp(dhPrime->data, prime_tls_8192,
sizeof(prime_tls_8192)) == 0) {
+ if (g) *g = generator_2;
return &subprime_tls_8192;
}
if (PORT_Memcmp(dhPrime->data, prime_ike_8192,
sizeof(prime_ike_8192)) == 0) {
+ if (g) *g = generator_2;
return &subprime_ike_8192;
}
break;
diff -up ./lib/softoken/sftkike.c.fips-review ./lib/softoken/sftkike.c
--- ./lib/softoken/sftkike.c.fips-review 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/sftkike.c 2024-06-12 12:04:10.641360427 -0700
@@ -516,6 +516,11 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession,
goto fail;
}
} else {
+ /* ikev1 isn't validated, if we use this function in ikev1 mode,
+ * mark the resulting key as not FIPS */
+ if (!params->bRekey) {
+ outKey->isFIPS = PR_FALSE;
+ }
crv = prf_init(&context, inKey->attrib.pValue,
inKey->attrib.ulValueLen);
if (crv != CKR_OK) {

View File

@ -1,126 +0,0 @@
diff --git a/gtests/ssl_gtest/tls_subcerts_unittest.cc b/gtests/ssl_gtest/tls_subcerts_unittest.cc
--- a/gtests/ssl_gtest/tls_subcerts_unittest.cc
+++ b/gtests/ssl_gtest/tls_subcerts_unittest.cc
@@ -371,16 +371,21 @@ static void GenerateWeakRsaKey(ScopedSEC
// Fail to connect with a weak RSA key.
TEST_P(TlsConnectTls13, DCWeakKey) {
Reset(kPssDelegatorId);
EnsureTlsSetup();
static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
ssl_sig_rsa_pss_pss_sha256};
client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
+ PRInt32 keySizeFlags;
+ ASSERT_EQ(SECSuccess, NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &keySizeFlags));
+ // turn off the signing key sizes so we actually test the ssl tests
+ ASSERT_EQ(SECSuccess,
+ NSS_OptionSet(NSS_KEY_SIZE_POLICY_FLAGS, NSS_KEY_SIZE_POLICY_SSL_FLAG ));
#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY
// save the MIN POLICY length.
PRInt32 minRsa;
ASSERT_EQ(SECSuccess, NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minRsa));
#if RSA_MIN_MODULUS_BITS >= 2048
ASSERT_EQ(SECSuccess,
NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, RSA_MIN_MODULUS_BITS + 1024));
@@ -408,16 +413,17 @@ TEST_P(TlsConnectTls13, DCWeakKey) {
client_->EnableDelegatedCredentials();
auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_delegated_credentials_xtn);
ConnectExpectAlert(client_, kTlsAlertInsufficientSecurity);
#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY
ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, minRsa));
#endif
+ ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_KEY_SIZE_POLICY_FLAGS, keySizeFlags));
}
class ReplaceDCSigScheme : public TlsHandshakeFilter {
public:
ReplaceDCSigScheme(const std::shared_ptr<TlsAgent>& a)
: TlsHandshakeFilter(a, {ssl_hs_certificate_verify}) {}
protected:
diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
--- a/lib/cryptohi/seckey.c
+++ b/lib/cryptohi/seckey.c
@@ -1134,22 +1134,31 @@ SECKEY_PrivateKeyStrengthInBits(const SE
return 0;
}
/* interpret modulus length as key strength */
switch (privk->keyType) {
case rsaKey:
case rsaPssKey:
case rsaOaepKey:
- /* some tokens don't export CKA_MODULUS on the private key,
- * PK11_SignatureLen works around this if necessary */
- bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE;
- if (bitSize == -1) {
- bitSize = 0;
+ rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
+ CKA_MODULUS, NULL, &params);
+ if ((rv != SECSuccess) || (params.data == NULL)) {
+ /* some tokens don't export CKA_MODULUS on the private key,
+ * PK11_SignatureLen works around this if necessary. This
+ * method is less percise because it returns bytes instead
+ * bits, so we only do it if we can't get the modulus */
+ bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE;
+ if (bitSize == -1) {
+ return 0;
+ }
+ return bitSize;
}
+ bitSize = SECKEY_BigIntegerBitLength(&params);
+ PORT_Free(params.data);
return bitSize;
case dsaKey:
case fortezzaKey:
case dhKey:
case keaKey:
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_PRIME, NULL, &params);
if ((rv != SECSuccess) || (params.data == NULL)) {
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -1277,27 +1277,39 @@ ssl3_SignHashesWithPrivKey(SSL3Hashes *h
PORT_SetError(SEC_ERROR_INVALID_KEY);
goto done;
}
PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
if (useRsaPss || hash->hashAlg == ssl_hash_none) {
CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
int signatureLen = PK11_SignatureLen(key);
+ PRInt32 optval;
SECItem *params = NULL;
CK_RSA_PKCS_PSS_PARAMS pssParams;
SECItem pssParamsItem = { siBuffer,
(unsigned char *)&pssParams,
sizeof(pssParams) };
if (signatureLen <= 0) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
goto done;
}
+ /* since we are calling PK11_SignWithMechanism directly, we need to check the
+ * key policy ourselves (which is already checked in SGN_Digest */
+ rv = NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optval);
+ if ((rv == SECSuccess) &&
+ ((optval & NSS_KEY_SIZE_POLICY_SIGN_FLAG) == NSS_KEY_SIZE_POLICY_SIGN_FLAG)) {
+ rv = SECKEY_EnforceKeySize(key->keyType, SECKEY_PrivateKeyStrengthInBits(key),
+ SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
+ if (rv != SECSuccess) {
+ goto done; /* error code already set */
+ }
+ }
buf->len = (unsigned)signatureLen;
buf->data = (unsigned char *)PORT_Alloc(signatureLen);
if (!buf->data)
goto done; /* error code was set. */
if (useRsaPss) {
pssParams.hashAlg = ssl3_GetHashMechanismByHashType(hash->hashAlg);

View File

@ -1,43 +0,0 @@
diff --git a/lib/util/nsshash.c b/lib/util/nsshash.c
--- a/lib/util/nsshash.c
+++ b/lib/util/nsshash.c
@@ -102,16 +102,19 @@ HASH_GetHashOidTagByHashType(HASH_HashTy
SECOidTag
HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
{
SECOidTag hashOid = SEC_OID_UNKNOWN;
switch (hmacOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
+ case SEC_OID_HMAC_MD5:
+ hashOid = SEC_OID_MD5;
+ break;
case SEC_OID_HMAC_SHA1:
hashOid = SEC_OID_SHA1;
break;
case SEC_OID_HMAC_SHA224:
hashOid = SEC_OID_SHA224;
break;
case SEC_OID_HMAC_SHA256:
hashOid = SEC_OID_SHA256;
@@ -145,16 +148,19 @@ HASH_GetHashOidTagByHMACOidTag(SECOidTag
SECOidTag
HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
{
SECOidTag hmacOid = SEC_OID_UNKNOWN;
switch (hashOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
+ case SEC_OID_MD5:
+ hmacOid = SEC_OID_HMAC_MD5;
+ break;
case SEC_OID_SHA1:
hmacOid = SEC_OID_HMAC_SHA1;
break;
case SEC_OID_SHA224:
hmacOid = SEC_OID_HMAC_SHA224;
break;
case SEC_OID_SHA256:
hmacOid = SEC_OID_HMAC_SHA256;

View File

@ -1,121 +0,0 @@
diff --git a/lib/pk11wrap/pk11mech.c b/lib/pk11wrap/pk11mech.c
--- a/lib/pk11wrap/pk11mech.c
+++ b/lib/pk11wrap/pk11mech.c
@@ -1710,20 +1710,26 @@ PK11_ParamToAlgid(SECOidTag algTag, SECI
case CKM_BATON_ECB96:
case CKM_BATON_CBC128:
case CKM_BATON_COUNTER:
case CKM_BATON_SHUFFLE:
case CKM_JUNIPER_ECB128:
case CKM_JUNIPER_CBC128:
case CKM_JUNIPER_COUNTER:
case CKM_JUNIPER_SHUFFLE:
- newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (newParams == NULL)
- break;
+ /* if no parameters have been supplied, then encode a NULL params
+ */
+ if (param && param->len > 0) {
+ newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
+ SEC_ASN1_GET(SEC_OctetStringTemplate));
+ if (newParams == NULL)
+ break;
+ } else {
+ newParams = NULL;
+ }
rv = SECSuccess;
break;
}
if (rv != SECSuccess) {
if (newParams)
SECITEM_FreeItem(newParams, PR_TRUE);
return rv;
diff --git a/lib/pk11wrap/pk11pbe.c b/lib/pk11wrap/pk11pbe.c
--- a/lib/pk11wrap/pk11pbe.c
+++ b/lib/pk11wrap/pk11pbe.c
@@ -765,45 +765,53 @@ sec_pkcs5CreateAlgorithmID(SECOidTag alg
* algorithm is). We use choose this algorithm oid based on the
* cipherAlgorithm to determine what this should be (MAC1 or PBES2).
*/
if (algorithm == SEC_OID_PKCS5_PBKDF2) {
/* choose mac or pbes */
algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
}
+ SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
+
/* set the PKCS5v2 specific parameters */
if (keyLength == 0) {
- SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
if (hashAlg != SEC_OID_UNKNOWN) {
keyLength = HASH_ResultLenByOidTag(hashAlg);
} else {
keyLength = sec_pkcs5v2_default_key_length(cipherAlgorithm);
}
if (keyLength <= 0) {
goto loser;
}
}
/* currently SEC_OID_HMAC_SHA1 is the default */
if (prfAlg == SEC_OID_UNKNOWN) {
prfAlg = SEC_OID_HMAC_SHA1;
}
- /* build the PKCS5v2 cipher algorithm id */
- cipherParams = pk11_GenerateNewParamWithKeyLen(
- PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
- if (!cipherParams) {
- goto loser;
+ /* build the PKCS5v2 cipher algorithm id, if cipher
+ * is an HMAC, the cipherParams should be NULL */
+ if (hashAlg == SEC_OID_UNKNOWN) {
+ cipherParams = pk11_GenerateNewParamWithKeyLen(
+ PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
+ if (!cipherParams) {
+ goto loser;
+ }
+ } else {
+ cipherParams = NULL;
}
PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));
rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
poolp, &pbeV2_param.cipherAlgId);
- SECITEM_FreeItem(cipherParams, PR_TRUE);
+ if (cipherParams) {
+ SECITEM_FreeItem(cipherParams, PR_TRUE);
+ }
if (rv != SECSuccess) {
goto loser;
}
}
/* generate the parameter */
pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration,
keyLength, prfAlg);
diff --git a/lib/util/secalgid.c b/lib/util/secalgid.c
--- a/lib/util/secalgid.c
+++ b/lib/util/secalgid.c
@@ -50,17 +50,18 @@ SECOID_SetAlgorithmID(PLArenaPool *arena
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid))
return SECFailure;
if ((secoid_IsRSAPKCS1(which)) ||
- (HASH_GetHashTypeByOidTag(which) != HASH_AlgNULL)) {
+ (HASH_GetHashTypeByOidTag(which) != HASH_AlgNULL) /* ||
+ (HASH_GetHashOidTagByHMACOidTag(which) != SEC_OID_UNKNOWN) */) {
add_null_param = PR_TRUE;
} else {
add_null_param = PR_FALSE;
}
if (params) {
/*
* I am specifically *not* enforcing the following assertion

View File

@ -1,12 +0,0 @@
diff -up ./lib/pkcs12/p12local.c.long_pw_fix ./lib/pkcs12/p12local.c
--- ./lib/pkcs12/p12local.c.long_pw_fix 2024-09-06 17:58:39.905517185 -0700
+++ ./lib/pkcs12/p12local.c 2024-09-06 17:59:19.568985976 -0700
@@ -102,7 +102,7 @@ sec_pkcs12_integrity_key(PK11SlotInfo *s
*hmacMech = PK11_AlgtagToMechanism(hmacAlg);
/* pkcs12v2 hmac uses UTF8 rather than unicode */
if (!sec_pkcs12_convert_item_to_unicode(NULL, &utf8Pw, pwitem,
- PR_TRUE, PR_FALSE, PR_FALSE)) {
+ PR_FALSE, PR_FALSE, PR_FALSE)) {
return NULL;
}
symKey = PK11_PBEKeyGen(slot, prfAlgid, &utf8Pw, PR_FALSE, pwarg);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c
--- a/cmd/selfserv/selfserv.c
+++ b/cmd/selfserv/selfserv.c
@@ -2078,13 +2078,13 @@
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return SECFailure;
}
- *usedLen = outputLen;
-
- int ret = uncompress(output, (unsigned long *)usedLen, input->data, input->len);
+ unsigned long outputLenUL = outputLen;
+ int ret = uncompress(output, &outputLenUL, input->data, input->len);
+ *usedLen = outputLenUL;
if (ret != Z_OK) {
PR_SetError(SEC_ERROR_BAD_DATA, 0);
return SECFailure;
}
@@ -2100,11 +2100,13 @@
}
unsigned long maxCompressedLen = compressBound(input->len);
SECITEM_AllocItem(NULL, output, maxCompressedLen);
- int ret = compress(output->data, (unsigned long *)&output->len, input->data, input->len);
+ unsigned long outputLenUL = output->len;
+ int ret = compress(output->data, &outputLenUL, input->data, input->len);
+ output->len = outputLenUL;
if (ret != Z_OK) {
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
return SECFailure;
}
diff --git a/cmd/tstclnt/tstclnt.c b/cmd/tstclnt/tstclnt.c
--- a/cmd/tstclnt/tstclnt.c
+++ b/cmd/tstclnt/tstclnt.c
@@ -1375,11 +1375,13 @@
}
unsigned long maxCompressedLen = compressBound(input->len);
SECITEM_AllocItem(NULL, output, maxCompressedLen);
- int ret = compress(output->data, (unsigned long *)&output->len, input->data, input->len);
+ unsigned long outputLenUL = output->len;
+ int ret = compress(output->data, &outputLenUL, input->data, input->len);
+ output->len = outputLenUL;
if (ret != Z_OK) {
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
return SECFailure;
}
@@ -1394,13 +1396,13 @@
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return SECFailure;
}
- *usedLen = outputLen;
-
- int ret = uncompress(output, (unsigned long *)usedLen, input->data, input->len);
+ unsigned long outputLenUL = outputLen;
+ int ret = uncompress(output, &outputLenUL, input->data, input->len);
+ *usedLen = outputLenUL;
if (ret != Z_OK) {
PR_SetError(SEC_ERROR_BAD_DATA, 0);
return SECFailure;
}

View File

@ -1,14 +1,24 @@
diff -up ./gtests/ssl_gtest/manifest.mn.disable_ech ./gtests/ssl_gtest/manifest.mn
--- ./gtests/ssl_gtest/manifest.mn.disable_ech 2024-06-12 13:29:17.162207862 -0700
+++ ./gtests/ssl_gtest/manifest.mn 2024-06-12 13:30:25.699047788 -0700
@@ -59,7 +59,6 @@ CPPSRCS = \
diff --git a/gtests/ssl_gtest/manifest.mn b/gtests/ssl_gtest/manifest.mn
--- a/gtests/ssl_gtest/manifest.mn
+++ b/gtests/ssl_gtest/manifest.mn
@@ -50,17 +50,16 @@ CPPSRCS = \
ssl_staticrsa_unittest.cc \
ssl_tls13compat_unittest.cc \
ssl_v2_client_hello_unittest.cc \
ssl_version_unittest.cc \
ssl_versionpolicy_unittest.cc \
test_io.cc \
tls_agent.cc \
tls_connect.cc \
- tls_ech_unittest.cc \
tls_filter.cc \
tls_hkdf_unittest.cc \
tls_mlkem_unittest.cc \
tls_protect.cc \
tls_psk_unittest.cc \
tls_subcerts_unittest.cc \
- tls_ech_unittest.cc \
tls_xyber_unittest.cc \
$(SSLKEYLOGFILE_FILES) \
$(NULL)
diff -up ./lib/ssl/sslsock.c.disable_ech ./lib/ssl/sslsock.c
--- ./lib/ssl/sslsock.c.disable_ech 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/ssl/sslsock.c 2024-06-12 13:29:17.162207862 -0700

View File

@ -0,0 +1,33 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1752601914 25200
# Tue Jul 15 10:51:54 2025 -0700
# Branch RHEL_8
# Node ID 89a40126836b8e2a5d98e250262c498e304fcdcc
# Parent ef820c54bad5f034231f51df2b14f88863170cfb
nss-3.66-disable-external-host-test.patch
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
--- a/tests/ssl/ssl.sh
+++ b/tests/ssl/ssl.sh
@@ -1595,17 +1595,19 @@ ssl_run_tests()
{
for SSL_TEST in ${NSS_SSL_TESTS}
do
case "${SSL_TEST}" in
"policy")
if using_sql ; then
ssl_policy_listsuites
ssl_policy_selfserv
- ssl_policy_pkix_ocsp
+ # requires access to external servers, which fails
+ # when running in brew
+ #ssl_policy_pkix_ocsp
ssl_policy
fi
;;
"crl")
ssl_crl_ssl
ssl_crl_cache
;;
"iopr")

View File

@ -43,11 +43,11 @@ diff -r 699541a7793b lib/util/secoid.c
if (oids[i].desc && strstr(arg, oids[i].desc)) {
xOids[i].notPolicyFlags = notEnable |
(xOids[i].notPolicyFlags & ~(DEF_FLAGS));
diff -up ./tests/tools/pkcs12policy.txt.disable_md5_test ./tests/tools/pkcs12policy.txt
--- ./tests/tools/pkcs12policy.txt.disable_md5_test 2024-06-07 09:26:03.000000000 -0700
+++ ./tests/tools/pkcs12policy.txt 2024-06-19 11:15:46.666728170 -0700
@@ -91,21 +91,21 @@
0 18 allow_all disallow=rc2 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC4 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC SHA-1 disallow rc2 (read), RC4 and RC2
diff -up ./tests/tools/pkcs12policy.txt.disable_md5 ./tests/tools/pkcs12policy.txt
--- ./tests/tools/pkcs12policy.txt.disable_md5 2025-05-23 06:07:49.000000000 -0700
+++ ./tests/tools/pkcs12policy.txt 2025-06-21 13:46:53.055812187 -0700
@@ -95,21 +95,12 @@
0 17 allow_all disallow=rc2 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC4 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC SHA-1 disallow rc2 (read), RC4 and RC2
# integrity policy check the various has based controls.
# NOTE: md4, md2, and md5 are turned off by policy by default for encrypting
-# (decrypting is fine). To be enabled, you must allow=all or allow=mdX on the
@ -58,24 +58,15 @@ diff -up ./tests/tools/pkcs12policy.txt.disable_md5_test ./tests/tools/pkcs12pol
- 0 0 allow=all allow=tls PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Allow all encrypt, use default decrypt with multiple hashes
- 0 0 allow=all allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Allow all with multiple hashes
- 28 x disallow=sha1_allow=md2 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on write
+ 0 0 allow=md2/pkcs12 allow=tls PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Allow all encrypt, use default decrypt with multiple hashes
+ 0 0 allow=md2/pkcs12 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Allow all with multiple hashes
+ 28 x disallow=sha1_allow=md2/pkcs12 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on write
27 x disallow=md2 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on write
- 29 x disallow=sha256_allow=md2 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on write
- 0 19 allow=all disallow=sha1 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on read
- 0 18 allow=all disallow=md2 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on read
- 0 17 allow=all disallow=md2 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on read
- 0 17 allow=all disallow=sha256 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on read
- 0 0 allow=all disallow=md2/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on read
- 0 0 allow=all disallow=sha1/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on read
- 0 0 allow=all disallow=sha256/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on read
+ 29 x disallow=sha256_allow=md2/pkcs12 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on write
+ 0 19 allow=all:md2/pkcs12 disallow=sha1 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on read
+ 0 18 allow=md2/pkcs12 disallow=md2 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on read
+ 0 17 allow=md2/pkcs12 disallow=sha256 PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on read
+ 0 0 allow=md2/pkcs12 disallow=md2/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow md2 on read
+ 0 0 allow=md2/pkcs12 disallow=sha1/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha1 on read
+ 0 0 allow=md2/pkcs12 disallow=sha256/pkcs12-encrypt PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on read
0 0 allow=all allow=all AES-128-CBC AES-128-CBC HMAC_SHA-256
29 x disallow=hmac-sha256 allow=all AES-128-CBC AES-128-CBC HMAC_SHA-256
0 18 allow=all disallow=hmac-sha256 AES-128-CBC AES-128-CBC HMAC_SHA-256
+ 27 x disallow=sha256_allow=md2 allow=all PKCS_#12_V2_PBE_With_SHA-1_And_128_Bit_RC2_CBC PKCS_#5_Password_Based_Encryption_with_MD2_and_DES-CBC SHA-256 Disallow sha256 on write
0 0 allow=all allow=all AES-128-CBC AES-128-CBC HMAC_SHA-256 Allow all with hmac
29 x disallow=hmac-sha256 allow=all AES-128-CBC AES-128-CBC HMAC_SHA-256 Disallow hmac on write
0 17 allow=all disallow=hmac-sha256 AES-128-CBC AES-128-CBC HMAC_SHA-256 Disallow hmac on read

View File

@ -0,0 +1,62 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1752601818 25200
# Tue Jul 15 10:50:18 2025 -0700
# Branch RHEL_8
# Node ID ef820c54bad5f034231f51df2b14f88863170cfb
# Parent 5c09db329be3e1e2b19c92f9e6224cdad04d65ba
nss-3.101-disable-signature-policies.patch
diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c
--- a/lib/pk11wrap/pk11pars.c
+++ b/lib/pk11wrap/pk11pars.c
@@ -448,22 +448,19 @@ static const oidValDef smimeKxOptList[]
{ CIPHER_NAME("ECDH"), SEC_OID_ECDH_KEA, NSS_USE_ALG_IN_SMIME_KX },
{ CIPHER_NAME("DH"), SEC_OID_X942_DIFFIE_HELMAN_KEY, NSS_USE_ALG_IN_SMIME_KX },
};
static const oidValDef signOptList[] = {
/* Signatures */
{ CIPHER_NAME("DSA"), SEC_OID_ANSIX9_DSA_SIGNATURE,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
- { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
+ { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, 0},
+ { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0},
+ { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, 0},
{ CIPHER_NAME("ED25519"), SEC_OID_ED25519_PUBLIC_KEY,
NSS_USE_ALG_IN_SIGNATURE },
};
typedef struct {
const oidValDef *list;
PRUint32 entries;
const char *description;
diff --git a/tests/ssl/sslpolicy.txt b/tests/ssl/sslpolicy.txt
--- a/tests/ssl/sslpolicy.txt
+++ b/tests/ssl/sslpolicy.txt
@@ -188,17 +188,19 @@
1 noECC SSL3 d disallow=rsa/ssl-key-exchange Disallow Key Exchange Explicitly
1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:dh-dss:des-ede3-cbc:tls-version-min=ssl3.0:tls-version-max=ssl3.0 Disallow Key Exchange Implicitly Narrow
1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=ssl2.0:tls-version-max=tls1.2 Disallow Key Exchange Signatures Implicitly
# turn off version
1 noECC SSL3 d allow=tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Exlicitly
1 noECC SSL3 d disallow=all_allow=hmac-sha1:sha256:rsa-pkcs:rsa:des-ede3-cbc:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly Narrow
1 noECC SSL3 d disallow=all_allow=md2/all:md4/all:md5/all:sha1/all:sha256/all:sha384/all:sha512/all:rsa-pkcs/all:rsa-pss/all:ecdsa/all:dsa/all:hmac-sha1/all:hmac-sha224/all:hmac-sha256/all:hmac-sha384/all:hmac-sha512/all:hmac-md5/all:camellia128-cbc/all:camellia192-cbc/all:camellia256-cbc/all:seed-cbc/all:des-ede3-cbc/all:des-40-cbc/all:des-cbc/all:null-cipher/all:rc2/all:rc4/all:idea/all:rsa/all:rsa-export/all:dhe-rsa/all:dhe-dss/all:ecdhe-ecdsa/all:ecdhe-rsa/all:ecdh-ecdsa/all:ecdh-rsa/all:tls-version-min=tls1.0:tls-version-max=tls1.2 Disallow Version Implicitly
0 noECC SSL3 d disallow=dsa Disallow DSA Signatures Explicitly
- 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly
+# rsa-pkcs, rsa-pss, and ecdsa policy checking reverted in rhel8 for binary
+# compatibility reasons
+# 1 noECC SSL3 d disallow=rsa-pkcs Disallow RSA PKCS 1 Signatures Explicitly
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-verify Restrict RSA keys on signature verification
0 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-sign Restrict RSA keys on signing
1 noECC SSL3 d allow=rsa-min=16384:key-size-flags=key-size-ssl Restrict RSA keys when used in SSL
0 noECC SSL3 d allow=rsa-min=1023 Restrict RSA keys when used in SSL
# test default settings
# NOTE: tstclient will attempt to overide the defaults, so we detect we
# were successful by locking in our settings
0 noECC SSL3 d allow=all_disable=all Disable all by default, application override

View File

@ -0,0 +1,160 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1752603323 25200
# Tue Jul 15 11:15:23 2025 -0700
# Branch RHEL_8
# Node ID 66485f8ab28943977de80c0e22c800bea996e3c9
# Parent c36fc2df3a13b0672f9a11b500e6e3ddc7115490
nss-3.112-el8-no-p12-smime-policy.patch
diff --git a/lib/pkcs12/p12plcy.c b/lib/pkcs12/p12plcy.c
--- a/lib/pkcs12/p12plcy.c
+++ b/lib/pkcs12/p12plcy.c
@@ -32,27 +32,31 @@ static pkcs12SuiteMap pkcs12SuiteMaps[]
{ SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE },
{ SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE }
};
/* determine if algid is an algorithm which is allowed */
static PRBool
sec_PKCS12Allowed(SECOidTag alg, PRUint32 needed)
{
+#ifdef notdef
PRUint32 policy;
SECStatus rv;
rv = NSS_GetAlgorithmPolicy(alg, &policy);
if (rv != SECSuccess) {
return PR_FALSE;
}
if ((policy & needed) == needed) {
return PR_TRUE;
}
return PR_FALSE;
+#else
+ return PR_TRUE;
+#endif
}
PRBool
SEC_PKCS12CipherAllowed(SECOidTag pbeAlg, SECOidTag hmacAlg)
{
SECOidTag cipherAlg = SEC_PKCS5GetCryptoFromAlgTag(pbeAlg);
SECOidTag hashAlg = SEC_PKCS5GetHashFromAlgTag(pbeAlg);
if (cipherAlg == SEC_OID_UNKNOWN) {
diff --git a/lib/smime/smimeutil.c b/lib/smime/smimeutil.c
--- a/lib/smime/smimeutil.c
+++ b/lib/smime/smimeutil.c
@@ -197,16 +197,17 @@ smime_get_policy_tag_from_key_length(SEC
return SEC_OID_UNKNOWN;
}
return algtag;
}
PRBool
smime_allowed_by_policy(SECOidTag algtag, PRUint32 neededPolicy)
{
+#ifdef notdef
PRUint32 policyFlags;
/* some S/MIME algs map to the same underlying KEA mechanism,
* collaps them here */
if ((neededPolicy & (NSS_USE_ALG_IN_SMIME_KX | NSS_USE_ALG_IN_SMIME_KX_LEGACY)) != 0) {
CK_MECHANISM_TYPE mechType = PK11_AlgtagToMechanism(algtag);
switch (mechType) {
case CKM_ECDH1_DERIVE:
@@ -216,16 +217,17 @@ smime_allowed_by_policy(SECOidTag algtag
}
}
if ((NSS_GetAlgorithmPolicy(algtag, &policyFlags) == SECFailure) ||
((policyFlags & neededPolicy) != neededPolicy)) {
PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
return PR_FALSE;
}
+#endif
return PR_TRUE;
}
/*
* We'll need this for the fake policy oids for RC2, but the
* rest of these should be moved to pk11wrap for generic
* algtag to key size values. We already need this for
* sec_pkcs5v2_key_length_by oid.
@@ -480,28 +482,34 @@ smime_init_once(void *arg)
return PR_FAILURE;
}
algorithm_list_lock = PZ_NewLock(nssILockCache);
if (algorithm_list_lock == NULL) {
*error = PORT_GetError();
return PR_FAILURE;
}
+#ifdef notdef
/* At initialization time, we need to set up the defaults. We first
* look to see if the system or application has set up certain algorithms
* by policy. If they have set up values by policy we'll only allow those
* algorithms. We'll then look to see if any algorithms are enabled by
* the application. */
rv = NSS_GetAlgorithmPolicyAll(NSS_USE_ALG_IN_SMIME_LEGACY,
NSS_USE_ALG_IN_SMIME_LEGACY,
&tags, &tagCount);
if (tags) {
PORT_Free(tags);
tags = NULL;
}
+#else
+ /* just initialize the old maps */
+ rv = SECSuccess;
+ tagCount = 0;
+#endif
if ((rv != SECSuccess) || (tagCount == 0)) {
/* No algorithms have been enabled by policy (either by the system
* or by the application, we then will use the traditional default
* algorithms from the policy map */
for (i = smime_legacy_map_count - 1; i >= 0; i--) {
SECOidTag policytag = smime_legacy_map[i].policytag;
/* this enables the algorithm by policy. We need this or
* the policy code will reject attempts to use it */
diff --git a/tests/smime/smime.sh b/tests/smime/smime.sh
--- a/tests/smime/smime.sh
+++ b/tests/smime/smime.sh
@@ -867,13 +867,13 @@ smime_cleanup()
}
################## main #################################################
smime_init
smime_main
smime_data_tb
smime_p7
-if using_sql ; then
- smime_policy
-fi
+#if using_sql ; then
+# smime_policy
+#fi
smime_cleanup
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
--- a/tests/tools/tools.sh
+++ b/tests/tools/tools.sh
@@ -590,17 +590,17 @@ tools_p12()
tools_p12_export_list_import_most_ciphers
fi
tools_p12_export_with_none_ciphers
tools_p12_export_with_invalid_ciphers
tools_p12_import_old_files
tools_p12_import_pbmac1_samples
if using_sql; then
tools_p12_import_rsa_pss_private_key
- tools_p12_policy
+#tools_p12_policy
fi
}
############################## tools_sign ##############################
# local shell function pk12util uses a hardcoded tmp file, if this exists
# and is owned by another user we don't get reasonable errormessages
########################################################################
check_tmpfile()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,888 @@
diff --git a/lib/freebl/stubs.c b/lib/freebl/stubs.c
--- a/lib/freebl/stubs.c
+++ b/lib/freebl/stubs.c
@@ -485,17 +485,17 @@ PR_GetLibraryFilePathname_stub(const cha
extern int
PORT_GetError_stub(void)
{
STUB_SAFE_CALL0(PORT_GetError_Util);
return errno;
}
extern void
-PORT_SafeZero(void *p, size_t n)
+PORT_SafeZero_stub(void *p, size_t n)
{
STUB_SAFE_CALL2(PORT_SafeZero, p, n);
/* just use a generic call in the case where we are running
* standalone freebl */
if (p != NULL) {
volatile unsigned char *__vl = (unsigned char *)p;
size_t __nl = n;
while (__nl--)
diff --git a/lib/freebl/stubs.h b/lib/freebl/stubs.h
--- a/lib/freebl/stubs.h
+++ b/lib/freebl/stubs.h
@@ -22,17 +22,17 @@
#define PORT_Alloc PORT_Alloc_stub
#define PORT_ArenaAlloc PORT_ArenaAlloc_stub
#define PORT_ArenaZAlloc PORT_ArenaZAlloc_stub
#define PORT_Free PORT_Free_stub
#define PORT_FreeArena PORT_FreeArena_stub
#define PORT_GetError PORT_GetError_stub
#define PORT_NewArena PORT_NewArena_stub
-#define PORT_SaveZero PORT_SaveZero_stub
+#define PORT_SafeZero PORT_SafeZero_stub
#define PORT_SetError PORT_SetError_stub
#define PORT_ZAlloc PORT_ZAlloc_stub
#define PORT_ZFree PORT_ZFree_stub
#define PORT_ZAllocAligned PORT_ZAllocAligned_stub
#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_stub
#define SECITEM_AllocItem SECITEM_AllocItem_stub
#define SECITEM_CompareItem SECITEM_CompareItem_stub
diff --git a/lib/freebl/unix_fips140_3.c b/lib/freebl/unix_fips140_3.c
--- a/lib/freebl/unix_fips140_3.c
+++ b/lib/freebl/unix_fips140_3.c
@@ -25,17 +25,17 @@ RNG_SystemInfoForRNG(void)
{
PRUint8 bytes[SYSTEM_RNG_SEED_COUNT];
size_t numBytes = RNG_SystemRNG(bytes, SYSTEM_RNG_SEED_COUNT);
if (!numBytes) {
/* error is set */
return;
}
RNG_RandomUpdate(bytes, numBytes);
- PORT_SaveZero(bytes, sizeof(bytes));
+ PORT_SafeZero(bytes, sizeof(bytes));
}
static unsigned int rng_grndFlags = 0;
static PRCallOnceType rng_KernelFips;
static PRStatus
rng_getKernelFips()
{
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -535,17 +535,17 @@ sftk_InitGeneric(SFTKSession *session, C
context->cipherInfo = NULL;
context->hashInfo = NULL;
context->doPad = PR_FALSE;
context->padDataLength = 0;
context->key = key;
context->blockSize = 0;
context->maxLen = 0;
context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism,
- operation, key);
+ operation, key, 0);
*contextPtr = context;
return CKR_OK;
}
static int
sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
{
switch (mechanism) {
@@ -4794,16 +4794,17 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
goto loser;
}
/* make sure we don't have any class, key_type, or value fields */
sftk_DeleteAttributeType(key, CKA_CLASS);
sftk_DeleteAttributeType(key, CKA_KEY_TYPE);
sftk_DeleteAttributeType(key, CKA_VALUE);
+
/* Now Set up the parameters to generate the key (based on mechanism) */
key_gen_type = nsc_bulk; /* bulk key by default */
switch (pMechanism->mechanism) {
case CKM_CDMF_KEY_GEN:
case CKM_DES_KEY_GEN:
case CKM_DES2_KEY_GEN:
case CKM_DES3_KEY_GEN:
checkWeak = PR_TRUE;
@@ -4990,16 +4991,20 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
crv = CKR_SESSION_HANDLE_INVALID;
goto loser;
}
/*
* handle the base object stuff
*/
crv = sftk_handleObject(key, session);
+ /* we need to do this check at the end, so we can check the generated key length against
+ * fips requirements */
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key, 0);
+ session->lastOpWasFIPS = key->isFIPS;
sftk_FreeSession(session);
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
}
if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
}
if (crv == CKR_OK) {
@@ -6077,18 +6082,18 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
}
/*
* handle the base object cleanup for the private Key
* If we have any problems, we destroy the public Key we've
* created and linked.
*/
crv = sftk_handleObject(publicKey, session);
- sftk_FreeSession(session);
if (crv != CKR_OK) {
+ sftk_FreeSession(session);
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
sftk_FreeObject(privateKey);
return crv;
}
if (sftk_isTrue(privateKey, CKA_SENSITIVE)) {
crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE,
&cktrue, sizeof(CK_BBOOL));
@@ -6120,22 +6125,29 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
(PRUint32)hSession, (PRUint32)pMechanism->mechanism,
(PRUint32)crv);
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
}
}
}
if (crv != CKR_OK) {
+ sftk_FreeSession(session);
NSC_DestroyObject(hSession, publicKey->handle);
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
sftk_FreeObject(privateKey);
return crv;
}
+ /* we need to do this check at the end to make sure the generated key meets the key length requirements */
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey, 0);
+ publicKey->isFIPS = privateKey->isFIPS;
+ session->lastOpWasFIPS = privateKey->isFIPS;
+
+ sftk_FreeSession(session);
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
sftk_FreeObject(publicKey);
sftk_FreeObject(privateKey);
return CKR_OK;
}
@@ -7321,30 +7333,35 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
return CKR_MECHANISM_PARAM_INVALID;
}
if ((params->bExpand && keySize == 0) ||
(!params->bExpand && keySize > hashLen) ||
(params->bExpand && keySize > 255 * hashLen)) {
return CKR_TEMPLATE_INCONSISTENT;
}
+ if (!params->bExpand) {
+ keySize = hashLen;
+ }
+
/* sourceKey is NULL if we are called from the POST, skip the
* sensitiveCheck */
if (sourceKey != NULL) {
crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData);
if (crv != CKR_OK)
return crv;
}
/* HKDF-Extract(salt, base key value) */
if (params->bExtract) {
CK_BYTE *salt;
CK_ULONG saltLen;
HMACContext *hmac;
unsigned int bufLen;
+ SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
switch (params->ulSaltType) {
case CKF_HKDF_SALT_NULL:
saltLen = hashLen;
salt = hashbuf;
memset(salt, 0, saltLen);
break;
case CKF_HKDF_SALT_DATA:
@@ -7369,31 +7386,57 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
/* if the base key is not fips, but the salt key is, the
* resulting key can be fips */
if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) {
CK_MECHANISM mech;
mech.mechanism = CKM_HKDF_DERIVE;
mech.pParameter = params;
mech.ulParameterLen = sizeof(*params);
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
- CKA_DERIVE, saltKey);
+ CKA_DERIVE, saltKey,
+ keySize*PR_BITS_PER_BYTE);
}
+ saltKeySource = saltKey->source;
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
if (saltKey_att == NULL) {
sftk_FreeObject(saltKey);
return CKR_KEY_HANDLE_INVALID;
}
/* save the resulting salt */
salt = saltKey_att->attrib.pValue;
saltLen = saltKey_att->attrib.ulValueLen;
break;
default:
return CKR_MECHANISM_PARAM_INVALID;
break;
}
+ /* only TLS style usage is FIPS approved,
+ * turn off the FIPS indicator for other usages */
+ if (isFIPS && key && sourceKey) {
+ PRBool fipsOK = PR_FALSE;
+ /* case one: mix the kea with a previous or default
+ * salt */
+ if ((sourceKey->source == SFTK_SOURCE_KEA) &&
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
+ (saltLen == rawHash->length)) {
+ fipsOK = PR_TRUE;
+ }
+ /* case two: restart, remix the previous secret as a salt */
+ if ((sourceKey->objclass == CKO_DATA) &&
+ (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
+ (sourceKeyLen == rawHash->length) &&
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
+ (saltLen == rawHash->length)) {
+ fipsOK = PR_TRUE;
+ }
+ if (!fipsOK) {
+ key->isFIPS = PR_FALSE;
+ }
+ }
+ if (key) key->source = SFTK_SOURCE_HKDF_EXTRACT;
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
if (saltKey_att) {
sftk_FreeAttribute(saltKey_att);
}
if (saltKey) {
sftk_FreeObject(saltKey);
}
@@ -7411,26 +7454,50 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
/* PRK = base key value */
prk = sourceKeyBytes;
prkLen = sourceKeyLen;
}
/* HKDF-Expand */
if (!params->bExpand) {
okm = prk;
- keySize = genLen = hashLen;
+ genLen = hashLen;
} else {
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
* key material = T(1) | ... | T(n)
*/
HMACContext *hmac;
CK_BYTE bi;
unsigned iterations;
+ /* only TLS style usage is FIPS approved,
+ * turn off the FIPS indicator for other usages */
+ if (isFIPS && key && key->isFIPS && sourceKey) {
+ unsigned char *info=&params->pInfo[3];
+ /* only one case,
+ * 1) Expand only
+ * 2) with a key whose source was
+ * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT
+ * 3) source key length == rawHash->length
+ * 4) Info has tls or dtls
+ * If any of those conditions aren't met, then we turn
+ * off the fips indicator */
+ if (params->bExtract ||
+ ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) &&
+ (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) ||
+ (sourceKeyLen != rawHash->length) ||
+ (params->ulInfoLen < 7) ||
+ ((PORT_Memcmp(info,"tls",3) != 0) &&
+ (PORT_Memcmp(info,"dtls",4) != 0))) {
+ key->isFIPS = PR_FALSE;
+ }
+ }
+ if (key) key->source = SFTK_SOURCE_HKDF_EXPAND;
+
genLen = PR_ROUNDUP(keySize, hashLen);
iterations = genLen / hashLen;
if (genLen > sizeof(keyBlock)) {
keyBlockAlloc = PORT_Alloc(genLen);
if (keyBlockAlloc == NULL) {
return CKR_HOST_MEMORY;
}
@@ -7635,17 +7702,18 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
/* get the value of the base key */
att = sftk_FindAttribute(sourceKey, CKA_VALUE);
if (att == NULL) {
sftk_FreeObject(key);
sftk_FreeObject(sourceKey);
return CKR_KEY_HANDLE_INVALID;
}
}
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey);
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey,
+ keySize*PR_BITS_PER_BYTE);
switch (mechanism) {
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
* will generate the public portion if it doesn't already exist. */
case CKM_NSS_PUB_FROM_PRIV: {
NSSLOWKEYPrivateKey *privKey;
NSSLOWKEYPublicKey *pubKey;
int error;
@@ -8797,16 +8865,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
/* calculate private value - oct */
rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
SECITEM_ZfreeItem(&dhValue, PR_FALSE);
if (rv == SECSuccess) {
+ key->source = SFTK_SOURCE_KEA;
sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
SECITEM_ZfreeItem(&derived, PR_FALSE);
crv = CKR_OK;
} else
crv = CKR_HOST_MEMORY;
break;
}
@@ -8894,16 +8963,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
* tmp is the raw data created by ECDH_Derive,
* secret and secretlen are the values we will
* eventually pass as our generated key.
*/
secret = tmp.data;
secretlen = tmp.len;
} else {
secretlen = keySize;
+ key->isFIPS = PR_FALSE;
crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
&tmp, mechParams->pSharedData,
mechParams->ulSharedDataLen, mechParams->kdf);
PORT_ZFree(tmp.data, tmp.len);
if (crv != CKR_OK) {
break;
}
tmp.data = secret;
@@ -8927,16 +8997,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
}
PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen);
secret = keyData;
} else {
secret += (secretlen - keySize);
}
secretlen = keySize;
}
+ key->source = SFTK_SOURCE_KEA;
sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
PORT_ZFree(tmp.data, tmp.len);
if (keyData) {
PORT_ZFree(keyData, keySize);
}
break;
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
--- a/lib/softoken/pkcs11i.h
+++ b/lib/softoken/pkcs11i.h
@@ -147,16 +147,26 @@ typedef enum {
*/
typedef enum {
SFTK_DestroyFailure,
SFTK_Destroyed,
SFTK_Busy
} SFTKFreeStatus;
/*
+ * Source of various objects
+ */
+typedef enum {
+ SFTK_SOURCE_DEFAULT=0,
+ SFTK_SOURCE_KEA,
+ SFTK_SOURCE_HKDF_EXPAND,
+ SFTK_SOURCE_HKDF_EXTRACT
+} SFTKSource;
+
+/*
* attribute values of an object.
*/
struct SFTKAttributeStr {
SFTKAttribute *next;
SFTKAttribute *prev;
PRBool freeAttr;
PRBool freeData;
/*must be called handle to make sftkqueue_find work */
@@ -189,16 +199,17 @@ struct SFTKObjectStr {
CK_OBJECT_CLASS objclass;
CK_OBJECT_HANDLE handle;
int refCount;
PZLock *refLock;
SFTKSlot *slot;
void *objectInfo;
SFTKFree infoFree;
PRBool isFIPS;
+ SFTKSource source;
};
struct SFTKTokenObjectStr {
SFTKObject obj;
SECItem dbKey;
};
struct SFTKSessionObjectStr {
@@ -963,15 +974,16 @@ char **NSC_ModuleDBFunc(unsigned long fu
const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *generator, PRBool isFIPS);
/* check if dhSubPrime claims dhPrime is a safe prime. */
SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe);
/* map an operation Attribute to a Mechanism flag */
CK_FLAGS sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE op);
/* check the FIPS table to determine if this current operation is allowed by
* FIPS security policy */
PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech,
- CK_ATTRIBUTE_TYPE op, SFTKObject *source);
+ CK_ATTRIBUTE_TYPE op, SFTKObject *source,
+ CK_ULONG targetKeySize);
/* add validation objects to the slot */
CK_RV sftk_CreateValidationObjects(SFTKSlot *slot);
SEC_END_PROTOS
#endif /* _PKCS11I_H_ */
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
--- a/lib/softoken/pkcs11u.c
+++ b/lib/softoken/pkcs11u.c
@@ -1098,16 +1098,17 @@ sftk_NewObject(SFTKSlot *slot)
sessObject->attrList[i].freeData = PR_FALSE;
}
sessObject->optimizeSpace = slot->optimizeSpace;
object->handle = 0;
object->next = object->prev = NULL;
object->slot = slot;
object->isFIPS = sftk_isFIPS(slot->slotID);
+ object->source = SFTK_SOURCE_DEFAULT;
object->refCount = 1;
sessObject->sessionList.next = NULL;
sessObject->sessionList.prev = NULL;
sessObject->sessionList.parent = object;
sessObject->session = NULL;
sessObject->wasDerived = PR_FALSE;
if (!hasLocks)
@@ -1683,16 +1684,17 @@ fail:
CK_RV
sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject)
{
SFTKAttribute *attribute;
SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
unsigned int i;
destObject->isFIPS = srcObject->isFIPS;
+ destObject->source = srcObject->source;
if (src_so == NULL) {
return sftk_CopyTokenObject(destObject, srcObject);
}
PZ_Lock(src_so->attributeLock);
for (i = 0; i < src_so->hashSize; i++) {
attribute = src_so->head[i];
do {
@@ -2068,16 +2070,17 @@ sftk_NewTokenObject(SFTKSlot *slot, SECI
/* every object must have a class, if we can't get it, the object
* doesn't exist */
crv = handleToClass(slot, handle, &object->objclass);
if (crv != CKR_OK) {
goto loser;
}
object->slot = slot;
object->isFIPS = sftk_isFIPS(slot->slotID);
+ object->source = SFTK_SOURCE_DEFAULT;
object->objectInfo = NULL;
object->infoFree = NULL;
if (!hasLocks) {
object->refLock = PZ_NewLock(nssILockRefLock);
}
if (object->refLock == NULL) {
goto loser;
}
@@ -2234,16 +2237,25 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
break;
case CKA_DERIVE:
flags = CKF_DERIVE;
break;
/* fake attribute to select digesting */
case CKA_DIGEST:
flags = CKF_DIGEST;
break;
+ /* fake attribute to select key gen */
+ case CKA_NSS_GENERATE:
+ flags = CKF_GENERATE;
+ break;
+ /* fake attribute to select key pair gen */
+ case CKA_NSS_GENERATE_KEY_PAIR:
+ flags = CKF_GENERATE_KEY_PAIR;
+ break;
+ /* fake attributes to to handle MESSAGE* flags */
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
flags = CKF_MESSAGE_ENCRYPT;
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
flags = CKF_MESSAGE_DECRYPT;
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
flags = CKF_MESSAGE_SIGN;
@@ -2319,20 +2331,20 @@ sftk_quickGetECCCurveOid(SFTKObject *sou
}
/* This function currently only returns valid lengths for
* FIPS approved ECC curves. If we want to make this generic
* in the future, that Curve determination can be done in
* the sftk_handleSpecial. Since it's currently only used
* in FIPS indicators, it's currently only compiled with
* the FIPS indicator code */
-static int
+static CK_ULONG
sftk_getKeyLength(SFTKObject *source)
{
- CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
+ CK_KEY_TYPE keyType = CKK_INVALID_KEY_TYPE;
CK_ATTRIBUTE_TYPE keyAttribute;
CK_ULONG keyLength = 0;
SFTKAttribute *attribute;
CK_RV crv;
/* If we don't have a key, then it doesn't have a length.
* this may be OK (say we are hashing). The mech info will
* sort this out because algorithms which expect no keys
@@ -2342,17 +2354,17 @@ sftk_getKeyLength(SFTKObject *source)
}
crv = sftk_GetULongAttribute(source, CKA_KEY_TYPE, &keyType);
if (crv != CKR_OK) {
/* sometimes we're passed a data object, in that case the
* key length is CKA_VALUE, which is the default */
keyType = CKK_INVALID_KEY_TYPE;
}
- if (keyType == CKK_EC) {
+ if (keyType == CKK_EC || keyType == CKK_EC_EDWARDS || keyType == CKK_EC_MONTGOMERY) {
SECOidTag curve = sftk_quickGetECCCurveOid(source);
switch (curve) {
case SEC_OID_CURVE25519:
/* change when we start algorithm testing on curve25519 */
return 0;
case SEC_OID_SECG_EC_SECP256R1:
return 256;
case SEC_OID_SECG_EC_SECP384R1:
@@ -2384,24 +2396,65 @@ sftk_getKeyLength(SFTKObject *source)
attribute = sftk_FindAttribute(source, keyAttribute);
if (attribute) {
keyLength = attribute->attrib.ulValueLen * 8;
sftk_FreeAttribute(attribute);
}
return keyLength;
}
+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;
+}
+
+PRBool
+sftk_checkKeyLength(CK_ULONG keyLength, CK_ULONG min,
+ CK_ULONG max, CK_ULONG step)
+{
+ if (keyLength > max) {
+ return PR_FALSE;
+ }
+ if (keyLength < min ) {
+ return PR_FALSE;
+ }
+ if (((keyLength - min) % step) != 0) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
/*
* 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)
+ 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,
@@ -2451,32 +2504,97 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
}
/* we use the existing hash utilities to find the length of
* the hash */
hashObj = HASH_GetRawHashObject(sftk_GetHashTypeFromMechanism(
pss->hashAlg));
if (hashObj == NULL) {
return PR_FALSE;
}
+ /* cap the salt for legacy keys */
+ if ((keyLength <= 1024) && (pss->sLen > 63)) {
+ return PR_FALSE;
+ }
+ /* cap the salt for based on the hash */
if (pss->sLen > hashObj->length) {
return PR_FALSE;
}
+ /* Our code makes sure pss->hashAlg matches the explicit
+ * hash in the mechanism, and only mechanisms with approved
+ * hashes are included, so no need to check pss->hashAlg
+ * here */
+ return PR_TRUE;
+ }
+ case SFTKFIPSPBKDF2: {
+ /* 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_PARAMS *pbkdf2 = (CK_PKCS5_PBKD2_PARAMS *)
+ 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_ULONG *)(((char *)mech->pParameter)
+ + mechInfo->offset), allowSmall, allowCMAC);
+ case SFTKFIPSTlsKeyCheck:
+ 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_ULONG *)(((char *)mech->pParameter)
+ + mechInfo->offset), PR_FALSE, PR_FALSE)) {
+ return PR_FALSE;
+ }
+ }
+ return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
+ 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
PRBool
sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op,
- SFTKObject *source)
+ SFTKObject *source, CK_ULONG targetKeyLength)
{
#ifndef NSS_HAS_FIPS_INDICATORS
return PR_FALSE;
#else
int i;
CK_FLAGS opFlags;
CK_ULONG keyLength;
@@ -2498,23 +2616,25 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
}
keyLength = sftk_getKeyLength(source);
/* check against our algorithm array */
for (i = 0; i < SFTK_NUMBER_FIPS_ALGORITHMS; i++) {
SFTKFIPSAlgorithmList *mechs = &sftk_fips_mechs[i];
/* if we match the number of records exactly, then we are an
* approved algorithm in the approved mode with an approved key */
- if (((mech->mechanism == mechs->type) &&
- (opFlags == (mechs->info.flags & opFlags)) &&
- (keyLength <= mechs->info.ulMaxKeySize) &&
- (keyLength >= mechs->info.ulMinKeySize) &&
- ((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
- ((mechs->special == SFTKFIPSNone) ||
- sftk_handleSpecial(slot, mech, mechs, source))) {
+ if ((mech->mechanism == mechs->type) &&
+ (opFlags == (mechs->info.flags & opFlags)) &&
+ sftk_checkKeyLength(keyLength, mechs->info.ulMinKeySize,
+ mechs->info.ulMaxKeySize, mechs->step) &&
+ ((targetKeyLength == 0) || (mechs->special == SFTKFIPSTlsKeyCheck)
+ || sftk_checkKeyLength(targetKeyLength, mechs->info.ulMinKeySize,
+ mechs->info.ulMaxKeySize, mechs->step)) &&
+ ((mechs->special == SFTKFIPSNone) ||
+ sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
return PR_TRUE;
}
}
return PR_FALSE;
#endif
}
/*
diff --git a/lib/softoken/sftkike.c b/lib/softoken/sftkike.c
--- a/lib/softoken/sftkike.c
+++ b/lib/softoken/sftkike.c
@@ -511,16 +511,22 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession,
}
/* key as the data */
crv = prf_update(&context, inKey->attrib.pValue,
inKey->attrib.ulValueLen);
if (crv != CKR_OK) {
goto fail;
}
} else {
+ /* ikev1 isn't validated, if we use this function in ikev1 mode,
+ * mark the resulting key as not FIPS */
+ if (!params->bRekey) {
+ outKey->isFIPS = PR_FALSE;
+ }
+
crv = prf_init(&context, inKey->attrib.pValue,
inKey->attrib.ulValueLen);
if (crv != CKR_OK) {
goto fail;
}
if (newKeyValue) {
crv = prf_update(&context, newKeyValue->attrib.pValue,
newKeyValue->attrib.ulValueLen);
diff --git a/lib/softoken/sftkmessage.c b/lib/softoken/sftkmessage.c
--- a/lib/softoken/sftkmessage.c
+++ b/lib/softoken/sftkmessage.c
@@ -178,16 +178,48 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
CHECK_FORK();
/* make sure we're legal */
crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);
if (crv != CKR_OK)
return crv;
+ if (context->isFIPS && (contextType == SFTK_MESSAGE_ENCRYPT)) {
+ if ((pParameter == NULL) || (ulParameterLen != sizeof(CK_GCM_MESSAGE_PARAMS))) {
+ context->isFIPS = PR_FALSE;
+ } else {
+ CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
+ switch (p->ivGenerator) {
+ default:
+ case CKG_NO_GENERATE:
+ context->isFIPS = PR_FALSE;
+ break;
+ case CKG_GENERATE_RANDOM:
+ if ((p->ulIvLen < 96/PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 0)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ case CKG_GENERATE_COUNTER_XOR:
+ if ((p->ulIvLen != 96/PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ case CKG_GENERATE_COUNTER:
+ if ((p->ulIvFixedBits < 32) ||
+ ((p->ulIvLen*PR_BITS_PER_BYTE - p->ulIvFixedBits) < 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ }
+ }
+ }
+
if (!pOuttext) {
*pulOuttextLen = ulIntextLen;
return CKR_OK;
}
rv = (*context->aeadUpdate)(context->cipherInfo, pOuttext, &outlen,
maxout, pIntext, ulIntextLen,
pParameter, ulParameterLen,
pAssociatedData, ulAssociatedDataLen);
diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h
--- a/lib/util/pkcs11n.h
+++ b/lib/util/pkcs11n.h
@@ -148,16 +148,18 @@
/*
* NSS-defined certificate types
*
*/
#define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
/* FAKE PKCS #11 defines */
#define CKA_DIGEST 0x81000000L
+#define CKA_NSS_GENERATE 0x81000001L
+#define CKA_NSS_GENERATE_KEY_PAIR 0x81000002L
#define CKA_NSS_MESSAGE 0x82000000L
#define CKA_NSS_MESSAGE_MASK 0xff000000L
#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
/*
* NSS-defined object attributes
*
*/

View File

@ -0,0 +1,44 @@
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
--- a/lib/softoken/fipstokn.c
+++ b/lib/softoken/fipstokn.c
@@ -244,17 +244,17 @@ fc_getAttribute(CK_ATTRIBUTE_PTR pTempla
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
#define CK_NEED_ARG_LIST 1
#include "pkcs11f.h"
/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
static CK_FUNCTION_LIST_3_0 sftk_fipsTable = {
- { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+ { 3, 0 },
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(F, name) \
,
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
--- a/lib/softoken/pkcs11.c
+++ b/lib/softoken/pkcs11.c
@@ -107,17 +107,17 @@ static PRIntervalTime loginWaitTime;
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
#define CK_NEED_ARG_LIST 1
#include "pkcs11f.h"
#endif
/* build the crypto module table */
static CK_FUNCTION_LIST_3_0 sftk_funcList = {
- { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+ { 3, 0 },
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
#define CK_PKCS11_FUNCTION_INFO(func) \
__PASTE(NS, func) \
,
#include "pkcs11f.h"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1752603075 25200
# Tue Jul 15 11:11:15 2025 -0700
# Branch RHEL_8
# Node ID 688a6b5db483a4168d15e09d5b243fca79b5b01d
# Parent a87aba54de420d418961245be6e55d354bebd77b
nss-3.101-revert-libpkix-default.patch
diff --git a/lib/certhigh/certvfypkix.c b/lib/certhigh/certvfypkix.c
--- a/lib/certhigh/certvfypkix.c
+++ b/lib/certhigh/certvfypkix.c
@@ -34,17 +34,17 @@ extern PKIX_UInt32
pkix_pl_lifecycle_ObjectLeakCheck(int *);
extern SECStatus
pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
PRInt32 parallelFnInvocationCount;
#endif /* PKIX_OBJECT_LEAK_TEST */
-static PRBool usePKIXValidationEngine = PR_TRUE;
+static PRBool usePKIXValidationEngine = PR_FALSE;
#endif /* NSS_DISABLE_LIBPKIX */
/*
* FUNCTION: CERT_SetUsePKIXForValidation
* DESCRIPTION:
*
* Enables or disables use of libpkix for certificate validation
*
diff --git a/lib/nss/nssinit.c b/lib/nss/nssinit.c
--- a/lib/nss/nssinit.c
+++ b/lib/nss/nssinit.c
@@ -759,19 +759,19 @@ nss_Init(const char *configdir, const ch
#ifndef NSS_DISABLE_LIBPKIX
pkixError = PKIX_Initialize(PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION,
PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
if (pkixError != NULL) {
goto loser;
} else {
- char *ev = PR_GetEnvSecure("NSS_DISABLE_PKIX_VERIFY");
+ char *ev = PR_GetEnvSecure("NSS_ENABLE_PKIX_VERIFY");
if (ev && ev[0]) {
- CERT_SetUsePKIXForValidation(PR_FALSE);
+ CERT_SetUsePKIXForValidation(PR_TRUE);
}
}
#endif /* NSS_DISABLE_LIBPKIX */
}
/*
* Now mark the appropriate init state. If initContextPtr was passed
* in, then return the new context pointer and add it to the
diff --git a/tests/all.sh b/tests/all.sh
--- a/tests/all.sh
+++ b/tests/all.sh
@@ -138,28 +138,23 @@ run_tests()
########################## run_cycle_standard ##########################
# run test suites with sql database (no PKIX)
########################################################################
run_cycle_standard()
{
TEST_MODE=STANDARD
- NSS_DISABLE_LIBPKIX_VERIFY="1"
- export NSS_DISABLE_LIBPKIX_VERIFY
-
TESTS="${ALL_TESTS}"
TESTS_SKIP="libpkix pkits"
NSS_DEFAULT_DB_TYPE=${NSS_DEFAULT_DB_TYPE:-"sql"}
export NSS_DEFAULT_DB_TYPE
run_tests
-
- unset NSS_DISABLE_LIBPKIX_VERIFY
}
############################ run_cycle_pkix ############################
# run test suites with PKIX enabled
########################################################################
run_cycle_pkix()
{
TEST_MODE=PKIX
@@ -167,16 +162,19 @@ run_cycle_pkix()
TABLE_ARGS="bgcolor=cyan"
html_head "Testing with PKIX"
html "</TABLE><BR>"
HOSTDIR="${HOSTDIR}/pkix"
mkdir -p "${HOSTDIR}"
init_directories
+ NSS_ENABLE_PKIX_VERIFY="1"
+ export NSS_ENABLE_PKIX_VERIFY
+
TESTS="${ALL_TESTS}"
TESTS_SKIP="cipher dbtests sdr crmf smime merge multinit"
export -n NSS_SSL_RUN
# use the default format. (unset for the shell, export -n for binaries)
export -n NSS_DEFAULT_DB_TYPE
unset NSS_DEFAULT_DB_TYPE
diff --git a/tests/common/init.sh b/tests/common/init.sh
--- a/tests/common/init.sh
+++ b/tests/common/init.sh
@@ -135,18 +135,18 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOU
{
echo "HOSTDIR=\"${HOSTDIR}\""
echo "TABLE_ARGS="
echo "NSS_TEST_DISABLE_CRL=${NSS_TEST_DISABLE_CRL}"
echo "NSS_SSL_TESTS=\"${NSS_SSL_TESTS}\""
echo "NSS_SSL_RUN=\"${NSS_SSL_RUN}\""
echo "NSS_DEFAULT_DB_TYPE=${NSS_DEFAULT_DB_TYPE}"
echo "export NSS_DEFAULT_DB_TYPE"
- echo "NSS_DISABLE_PKIX_VERIFY=${NSS_DISABLE_PKIX_VERIFY}"
- echo "export NSS_DISABLE_PKIX_VERIFY"
+ echo "NSS_ENABLE_PKIX_VERIFY=${NSS_ENABLE_PKIX_VERIFY}"
+ echo "export NSS_ENABLE_PKIX_VERIFY"
echo "init_directories"
}
# Exit shellfunction to clean up at exit (error, regular or signal)
Exit()
{
if [ -n "$1" ] ; then
echo "$SCRIPTNAME: Exit: $* - FAILED"
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
--- a/tests/ssl/ssl.sh
+++ b/tests/ssl/ssl.sh
@@ -957,18 +957,19 @@ ssl_policy_listsuites()
html "</TABLE><BR>"
}
ssl_policy_pkix_ocsp()
{
#verbose="-v"
html_head "Check that OCSP doesn't break if we disable sha1 $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE"
- PKIX_SAVE=${NSS_DISABLE_LIBPKIX_VERIFY-"unset"}
- unset NSS_DISABLE_LIBPKIX_VERIFY
+ PKIX_SAVE=${NSS_ENABLE_PKIX_VERIFY-"unset"}
+ NSS_ENABLE_PKIX_VERIFY="1"
+ export NSS_ENABLE_PKIX_VERIFY
testname=""
if [ ! -f "${P_R_SERVERDIR}/pkcs11.txt" ] ; then
html_failed "${SCRIPTNAME}: ${P_R_SERVERDIR} is not initialized"
return 1;
fi
@@ -983,20 +984,22 @@ ssl_policy_pkix_ocsp()
vfyserv -o wrong.host.badssl.com -d ${P_R_SERVERDIR} 2>&1 | tee ${P_R_SERVERDIR}/vfy.out
# make sure we have the domain mismatch, not bad signature error
echo "grep -E '12276|5961' ${P_R_SERVERDIR}/vfy.out"
grep -E '12276|5961' ${P_R_SERVERDIR}/vfy.out
RET=$?
html_msg $RET $RET_EXP "${testname}" \
"produced a returncode of $RET, expected is $RET_EXP"
- if [ "{PKIX_SAVE}" != "unset" ]; then
- export NSS_DISABLE_LIBPKIX_VERIFY=${PKIX_SAVE}
+ if [ "${PKIX_SAVE}" = "unset" ]; then
+ unset NSS_ENABLE_PKIX_VERIFY
+ else
+ NSS_ENABLE_PKIX_VERIFY=${PKIX_SAVE}
+ export NSS_ENABLE_PKIX_VERIFY
fi
-
cp ${P_R_SERVERDIR}/pkcs11.txt.sav ${P_R_SERVERDIR}/pkcs11.txt
html "</TABLE><BR>"
}
############################## ssl_policy_selfserv #####################
# local shell function to perform SSL Policy tests, using selfserv

View File

@ -1,14 +0,0 @@
diff -up ./tests/ssl/ssl.sh.brew ./tests/ssl/ssl.sh
--- ./tests/ssl/ssl.sh.brew 2021-06-12 11:37:46.153265942 -0700
+++ ./tests/ssl/ssl.sh 2021-06-12 11:39:43.069925034 -0700
@@ -1641,7 +1641,9 @@ ssl_run_tests()
if [ "${TEST_MODE}" = "SHARED_DB" ] ; then
ssl_policy_listsuites
ssl_policy_selfserv
- ssl_policy_pkix_ocsp
+ # requires access to external servers, which fails
+ # when running in brew
+ #ssl_policy_pkix_ocsp
ssl_policy
fi
;;

View File

@ -1,20 +0,0 @@
diff -up ./doc/pk12util.xml.camellia ./doc/pk12util.xml
--- ./doc/pk12util.xml.camellia 2022-01-26 09:46:39.794919455 -0800
+++ ./doc/pk12util.xml 2022-01-26 09:54:58.277019760 -0800
@@ -317,7 +317,7 @@ Certificate Friendly Name: Thawte Fre
<refsection id="encryption">
<title>Password Encryption</title>
- <para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using PKCS #12 SHA-1 and 3-key triple DES for private key encryption. When not in FIPS mode, PKCS #12 SHA-1 and 40-bit RC4 is used for certificate encryption. When in FIPS mode, there is no certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
+ <para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using AES-256-CBC for private key encryption and AES-128-CBC for certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
<para>The private key is always protected with strong encryption by default.</para>
<para>Several types of ciphers are supported.</para>
<variablelist>
@@ -327,6 +327,7 @@ Certificate Friendly Name: Thawte Fre
<listitem>
<itemizedlist>
<listitem><para>PBES2 with AES-CBC-Pad as underlying encryption scheme (<userinput>"AES-128-CBC"</userinput>, <userinput>"AES-192-CBC"</userinput>, and <userinput>"AES-256-CBC"</userinput>)</para></listitem>
+ <listitem><para>PBES2 with CAMELLIA-CBC-Pad as underlying encryption scheme (<userinput>"CAMELLIA-128-CBC"</userinput>, <userinput>"CAMELLIA-192-CBC"</userinput>, and <userinput>"CAMELLIA-256-CBC"</userinput>)</para></listitem>
</itemizedlist>
</listitem>
</varlistentry>

View File

@ -1,578 +0,0 @@
diff --git a/lib/freebl/config.mk b/lib/freebl/config.mk
--- a/lib/freebl/config.mk
+++ b/lib/freebl/config.mk
@@ -85,9 +85,13 @@ EXTRA_SHARED_LIBS += \
$(NULL)
endif
endif
ifeq ($(OS_ARCH), Darwin)
EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib
endif
+ifdef NSS_FIPS_140_3
+DEFINES += -DNSS_FIPS_140_3
endif
+
+endif
diff --git a/lib/freebl/unix_urandom.c b/lib/freebl/unix_urandom.c
--- a/lib/freebl/unix_urandom.c
+++ b/lib/freebl/unix_urandom.c
@@ -20,53 +20,110 @@ RNG_SystemInfoForRNG(void)
if (!numBytes) {
/* error is set */
return;
}
RNG_RandomUpdate(bytes, numBytes);
PORT_Memset(bytes, 0, sizeof bytes);
}
+#ifdef NSS_FIPS_140_3
+#include <sys/random.h>
+#include "prinit.h"
+
+static int rng_grndFlags= 0;
+static PRCallOnceType rng_KernelFips;
+
+static PRStatus
+rng_getKernelFips()
+{
+#ifdef LINUX
+ FILE *f;
+ char d;
+ size_t size;
+
+ f = fopen("/proc/sys/crypto/fips_enabled", "r");
+ if (!f)
+ return PR_FAILURE;
+
+ size = fread(&d, 1, 1, f);
+ fclose(f);
+ if (size != 1)
+ return PR_SUCCESS;
+ if (d != '1')
+ return PR_SUCCESS;
+ /* if the kernel is in FIPS mode, set the GRND_RANDOM flag */
+ rng_grndFlags = GRND_RANDOM;
+#endif /* LINUX */
+ return PR_SUCCESS;
+}
+#endif
+
size_t
RNG_SystemRNG(void *dest, size_t maxLen)
{
+ size_t fileBytes = 0;
+ unsigned char *buffer = dest;
+#ifndef NSS_FIPS_140_3
int fd;
int bytes;
- size_t fileBytes = 0;
- unsigned char *buffer = dest;
+#else
+ PR_CallOnce(&rng_KernelFips, rng_getKernelFips);
+#endif
#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25))))
int result;
-
while (fileBytes < maxLen) {
size_t getBytes = maxLen - fileBytes;
if (getBytes > GETENTROPY_MAX_BYTES) {
getBytes = GETENTROPY_MAX_BYTES;
}
+#ifdef NSS_FIPS_140_3
+ /* FIP 140-3 requires full kernel reseeding for chained entropy sources
+ * so we need to use getrandom with GRND_RANDOM.
+ * getrandom returns -1 on failure, otherwise returns
+ * the number of bytes, which can be less than getBytes */
+ result = getrandom(buffer, getBytes, rng_grndFlags);
+ if (result < 0) {
+ break;
+ }
+ fileBytes += result;
+ buffer += result;
+#else
+ /* get entropy returns 0 on success and always return
+ * getBytes on success */
result = getentropy(buffer, getBytes);
if (result == 0) { /* success */
fileBytes += getBytes;
buffer += getBytes;
} else {
break;
}
+#endif
}
if (fileBytes == maxLen) { /* success */
return maxLen;
}
+#ifdef NSS_FIPS_140_3
+ /* in FIPS 104-3 we don't fallback, just fail */
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ return 0;
+#else
/* If we failed with an error other than ENOSYS, it means the destination
* buffer is not writeable. We don't need to try writing to it again. */
if (errno != ENOSYS) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
return 0;
}
+#endif /*!NSS_FIPS_140_3 */
+#endif /* platorm has getentropy */
+#ifndef NSS_FIPS_140_3
/* ENOSYS means the kernel doesn't support getentropy()/getrandom().
* Reset the number of bytes to get and fall back to /dev/urandom. */
fileBytes = 0;
-#endif
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
return 0;
}
while (fileBytes < maxLen) {
bytes = read(fd, buffer, maxLen - fileBytes);
if (bytes <= 0) {
@@ -76,9 +133,10 @@ RNG_SystemRNG(void *dest, size_t maxLen)
buffer += bytes;
}
(void)close(fd);
if (fileBytes != maxLen) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
return 0;
}
return fileBytes;
+#endif
}
diff --git a/lib/softoken/config.mk b/lib/softoken/config.mk
--- a/lib/softoken/config.mk
+++ b/lib/softoken/config.mk
@@ -58,8 +58,12 @@ endif
ifdef NSS_ENABLE_FIPS_INDICATORS
DEFINES += -DNSS_ENABLE_FIPS_INDICATORS
endif
ifdef NSS_FIPS_MODULE_ID
DEFINES += -DNSS_FIPS_MODULE_ID=\"${NSS_FIPS_MODULE_ID}\"
endif
+ifdef NSS_FIPS_140_3
+DEFINES += -DNSS_FIPS_140_3
+endif
+
diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c
--- a/lib/softoken/lowpbe.c
+++ b/lib/softoken/lowpbe.c
@@ -1766,16 +1766,20 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
unsigned char iteration_count = 5;
unsigned char keyLen = 64;
char *inKeyData = TEST_KEY;
- static const unsigned char saltData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+ static const unsigned char saltData[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ };
+
static const unsigned char pbkdf_known_answer[] = {
- 0x31, 0xf0, 0xe5, 0x39, 0x9f, 0x39, 0xb9, 0x29,
- 0x68, 0xac, 0xf2, 0xe9, 0x53, 0x9b, 0xb4, 0x9c,
- 0x28, 0x59, 0x8b, 0x5c, 0xd8, 0xd4, 0x02, 0x37,
- 0x18, 0x22, 0xc1, 0x92, 0xd0, 0xfa, 0x72, 0x90,
- 0x2c, 0x8d, 0x19, 0xd4, 0x56, 0xfb, 0x16, 0xfa,
- 0x8d, 0x5c, 0x06, 0x33, 0xd1, 0x5f, 0x17, 0xb1,
- 0x22, 0xd9, 0x9c, 0xaf, 0x5e, 0x3f, 0xf3, 0x66,
- 0xc6, 0x14, 0xfe, 0x83, 0xfa, 0x1a, 0x2a, 0xc5
+ 0x73, 0x8c, 0xfa, 0x02, 0xe8, 0xdb, 0x43, 0xe4,
+ 0x99, 0xc5, 0xfd, 0xd9, 0x4d, 0x8e, 0x3e, 0x7b,
+ 0xc4, 0xda, 0x22, 0x1b, 0xe1, 0xae, 0x23, 0x7a,
+ 0x21, 0x27, 0xbd, 0xcc, 0x78, 0xc4, 0xe6, 0xc5,
+ 0x33, 0x38, 0x35, 0xe0, 0x68, 0x1a, 0x1e, 0x06,
+ 0xad, 0xaf, 0x7f, 0xd7, 0x3f, 0x0e, 0xc0, 0x90,
+ 0x17, 0x97, 0x73, 0x75, 0x7b, 0x88, 0x49, 0xd8,
+ 0x6f, 0x78, 0x5a, 0xde, 0x50, 0x20, 0x55, 0x33
};
sftk_PBELockInit();
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -4609,16 +4609,17 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
goto loser;
}
/* make sure we don't have any class, key_type, or value fields */
sftk_DeleteAttributeType(key, CKA_CLASS);
sftk_DeleteAttributeType(key, CKA_KEY_TYPE);
sftk_DeleteAttributeType(key, CKA_VALUE);
+
/* Now Set up the parameters to generate the key (based on mechanism) */
key_gen_type = nsc_bulk; /* bulk key by default */
switch (pMechanism->mechanism) {
case CKM_CDMF_KEY_GEN:
case CKM_DES_KEY_GEN:
case CKM_DES2_KEY_GEN:
case CKM_DES3_KEY_GEN:
checkWeak = PR_TRUE;
@@ -4812,16 +4813,19 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
crv = sftk_handleObject(key, session);
sftk_FreeSession(session);
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
}
if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
}
+ /* we need to do this check at the end, so we can check the generated key length against
+ * fips requirements */
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
if (crv == CKR_OK) {
*phKey = key->handle;
}
loser:
PORT_Memset(buf, 0, sizeof buf);
sftk_FreeObject(key);
return crv;
}
@@ -5780,16 +5784,19 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
if (crv != CKR_OK) {
NSC_DestroyObject(hSession, publicKey->handle);
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
sftk_FreeObject(privateKey);
return crv;
}
+ /* we need to do this check at the end to make sure the generated key meets the key length requirements */
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey);
+ publicKey->isFIPS = privateKey->isFIPS;
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
sftk_FreeObject(publicKey);
sftk_FreeObject(privateKey);
return CKR_OK;
}
@@ -6990,16 +6997,17 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
}
/* HKDF-Extract(salt, base key value) */
if (params->bExtract) {
CK_BYTE *salt;
CK_ULONG saltLen;
HMACContext *hmac;
unsigned int bufLen;
+ SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
switch (params->ulSaltType) {
case CKF_HKDF_SALT_NULL:
saltLen = hashLen;
salt = hashbuf;
memset(salt, 0, saltLen);
break;
case CKF_HKDF_SALT_DATA:
@@ -7026,29 +7034,54 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) {
CK_MECHANISM mech;
mech.mechanism = CKM_HKDF_DERIVE;
mech.pParameter = params;
mech.ulParameterLen = sizeof(*params);
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
CKA_DERIVE, saltKey);
}
+ saltKeySource = saltKey->source;
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
if (saltKey_att == NULL) {
sftk_FreeObject(saltKey);
return CKR_KEY_HANDLE_INVALID;
}
/* save the resulting salt */
salt = saltKey_att->attrib.pValue;
saltLen = saltKey_att->attrib.ulValueLen;
break;
default:
return CKR_MECHANISM_PARAM_INVALID;
break;
}
+ /* only TLS style usage is FIPS approved,
+ * turn off the FIPS indicator for other usages */
+ if (isFIPS && key && sourceKey) {
+ PRBool fipsOK = PR_FALSE;
+ /* case one: mix the kea with a previous or default
+ * salt */
+ if ((sourceKey->source == SFTK_SOURCE_KEA) &&
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
+ (saltLen == rawHash->length)) {
+ fipsOK = PR_TRUE;
+ }
+ /* case two: restart, remix the previous secret as a salt */
+ if ((sourceKey->objclass == CKO_DATA) &&
+ (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
+ (sourceKeyLen == rawHash->length) &&
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
+ (saltLen == rawHash->length)) {
+ fipsOK = PR_TRUE;
+ }
+ if (!fipsOK) {
+ key->isFIPS = PR_FALSE;
+ }
+ }
+ if (key) key->source = SFTK_SOURCE_HKDF_EXTRACT;
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
if (saltKey_att) {
sftk_FreeAttribute(saltKey_att);
}
if (saltKey) {
sftk_FreeObject(saltKey);
}
@@ -7076,16 +7109,40 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
* key material = T(1) | ... | T(n)
*/
HMACContext *hmac;
CK_BYTE bi;
unsigned iterations;
+ /* only TLS style usage is FIPS approved,
+ * turn off the FIPS indicator for other usages */
+ if (isFIPS && key && key->isFIPS && sourceKey) {
+ unsigned char *info=&params->pInfo[3];
+ /* only one case,
+ * 1) Expand only
+ * 2) with a key whose source was
+ * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT
+ * 3) source key length == rawHash->length
+ * 4) Info has tls or dtls
+ * If any of those conditions aren't met, then we turn
+ * off the fips indicator */
+ if (params->bExtract ||
+ ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) &&
+ (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) ||
+ (sourceKeyLen != rawHash->length) ||
+ (params->ulInfoLen < 7) ||
+ ((PORT_Memcmp(info,"tls",3) != 0) &&
+ (PORT_Memcmp(info,"dtls",4) != 0))) {
+ key->isFIPS = PR_FALSE;
+ }
+ }
+ if (key) key->source = SFTK_SOURCE_HKDF_EXPAND;
+
genLen = PR_ROUNDUP(keySize, hashLen);
iterations = genLen / hashLen;
if (genLen > sizeof(keyBlock)) {
keyBlockAlloc = PORT_Alloc(genLen);
if (keyBlockAlloc == NULL) {
return CKR_HOST_MEMORY;
}
@@ -8434,16 +8491,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
/* calculate private value - oct */
rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
SECITEM_ZfreeItem(&dhValue, PR_FALSE);
if (rv == SECSuccess) {
+ key->source = SFTK_SOURCE_KEA;
sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
SECITEM_ZfreeItem(&derived, PR_FALSE);
crv = CKR_OK;
} else
crv = CKR_HOST_MEMORY;
break;
}
@@ -8564,16 +8622,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
}
PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen);
secret = keyData;
} else {
secret += (secretlen - keySize);
}
secretlen = keySize;
}
+ key->source = SFTK_SOURCE_KEA;
sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
PORT_ZFree(tmp.data, tmp.len);
if (keyData) {
PORT_ZFree(keyData, keySize);
}
break;
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
--- a/lib/softoken/pkcs11i.h
+++ b/lib/softoken/pkcs11i.h
@@ -147,16 +147,26 @@ typedef enum {
*/
typedef enum {
SFTK_DestroyFailure,
SFTK_Destroyed,
SFTK_Busy
} SFTKFreeStatus;
/*
+ * Source of various objects
+ */
+typedef enum {
+ SFTK_SOURCE_DEFAULT=0,
+ SFTK_SOURCE_KEA,
+ SFTK_SOURCE_HKDF_EXPAND,
+ SFTK_SOURCE_HKDF_EXTRACT
+} SFTKSource;
+
+/*
* attribute values of an object.
*/
struct SFTKAttributeStr {
SFTKAttribute *next;
SFTKAttribute *prev;
PRBool freeAttr;
PRBool freeData;
/*must be called handle to make sftkqueue_find work */
@@ -189,16 +199,17 @@ struct SFTKObjectStr {
CK_OBJECT_CLASS objclass;
CK_OBJECT_HANDLE handle;
int refCount;
PZLock *refLock;
SFTKSlot *slot;
void *objectInfo;
SFTKFree infoFree;
PRBool isFIPS;
+ SFTKSource source;
};
struct SFTKTokenObjectStr {
SFTKObject obj;
SECItem dbKey;
};
struct SFTKSessionObjectStr {
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
--- a/lib/softoken/pkcs11u.c
+++ b/lib/softoken/pkcs11u.c
@@ -1090,16 +1090,17 @@ sftk_NewObject(SFTKSlot *slot)
sessObject->attrList[i].freeData = PR_FALSE;
}
sessObject->optimizeSpace = slot->optimizeSpace;
object->handle = 0;
object->next = object->prev = NULL;
object->slot = slot;
object->isFIPS = sftk_isFIPS(slot->slotID);
+ object->source = SFTK_SOURCE_DEFAULT;
object->refCount = 1;
sessObject->sessionList.next = NULL;
sessObject->sessionList.prev = NULL;
sessObject->sessionList.parent = object;
sessObject->session = NULL;
sessObject->wasDerived = PR_FALSE;
if (!hasLocks)
@@ -1674,16 +1675,17 @@ fail:
CK_RV
sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject)
{
SFTKAttribute *attribute;
SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
unsigned int i;
destObject->isFIPS = srcObject->isFIPS;
+ destObject->source = srcObject->source;
if (src_so == NULL) {
return sftk_CopyTokenObject(destObject, srcObject);
}
PZ_Lock(src_so->attributeLock);
for (i = 0; i < src_so->hashSize; i++) {
attribute = src_so->head[i];
do {
@@ -2059,16 +2061,17 @@ sftk_NewTokenObject(SFTKSlot *slot, SECI
/* every object must have a class, if we can't get it, the object
* doesn't exist */
crv = handleToClass(slot, handle, &object->objclass);
if (crv != CKR_OK) {
goto loser;
}
object->slot = slot;
object->isFIPS = sftk_isFIPS(slot->slotID);
+ object->source = SFTK_SOURCE_DEFAULT;
object->objectInfo = NULL;
object->infoFree = NULL;
if (!hasLocks) {
object->refLock = PZ_NewLock(nssILockRefLock);
}
if (object->refLock == NULL) {
goto loser;
}
@@ -2225,16 +2228,25 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
break;
case CKA_DERIVE:
flags = CKF_DERIVE;
break;
/* fake attribute to select digesting */
case CKA_DIGEST:
flags = CKF_DIGEST;
break;
+ /* fake attribute to select key gen */
+ case CKA_NSS_GENERATE:
+ flags = CKF_GENERATE;
+ break;
+ /* fake attribute to select key pair gen */
+ case CKA_NSS_GENERATE_KEY_PAIR:
+ flags = CKF_GENERATE_KEY_PAIR;
+ break;
+ /* fake attributes to to handle MESSAGE* flags */
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
flags = CKF_MESSAGE_ENCRYPT;
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
flags = CKF_MESSAGE_DECRYPT;
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
flags = CKF_MESSAGE_SIGN;
@@ -2278,17 +2290,17 @@ sftk_quickGetECCCurveOid(SFTKObject *sou
}
/* This function currently only returns valid lengths for
* FIPS approved ECC curves. If we want to make this generic
* in the future, that Curve determination can be done in
* the sftk_handleSpecial. Since it's currently only used
* in FIPS indicators, it's currently only compiled with
* the FIPS indicator code */
-static int
+static CK_ULONG
sftk_getKeyLength(SFTKObject *source)
{
CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
CK_ATTRIBUTE_TYPE keyAttribute;
CK_ULONG keyLength = 0;
SFTKAttribute *attribute;
CK_RV crv;
diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h
--- a/lib/util/pkcs11n.h
+++ b/lib/util/pkcs11n.h
@@ -58,16 +58,18 @@
/*
* NSS-defined certificate types
*
*/
#define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
/* FAKE PKCS #11 defines */
#define CKA_DIGEST 0x81000000L
+#define CKA_NSS_GENERATE 0x81000001L
+#define CKA_NSS_GENERATE_KEY_PAIR 0x81000002L
#define CKA_NSS_MESSAGE 0x82000000L
#define CKA_NSS_MESSAGE_MASK 0xff000000L
#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
/*
* NSS-defined object attributes
*
*/

View File

@ -1,42 +0,0 @@
diff --git a/lib/softoken/sftkmessage.c b/lib/softoken/sftkmessage.c
--- a/lib/softoken/sftkmessage.c
+++ b/lib/softoken/sftkmessage.c
@@ -146,16 +146,38 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
CHECK_FORK();
/* make sure we're legal */
crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);
if (crv != CKR_OK)
return crv;
+ if (context->isFIPS && (contextType == SFTK_MESSAGE_ENCRYPT)) {
+ if ((pParameter == NULL) || (ulParameterLen != sizeof(CK_GCM_MESSAGE_PARAMS))) {
+ context->isFIPS = PR_FALSE;
+ } else {
+ CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
+ switch (p->ivGenerator) {
+ case CKG_NO_GENERATE:
+ context->isFIPS = PR_FALSE;
+ break;
+ case CKG_GENERATE_RANDOM:
+ if ((p->ulIvLen < 12) || (p->ulIvFixedBits != 0)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ default:
+ if ((p->ulIvLen < 12) || (p->ulIvFixedBits < 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ }
+ }
+ }
+
if (!pOuttext) {
*pulOuttextLen = ulIntextLen;
return CKR_OK;
}
rv = (*context->aeadUpdate)(context->cipherInfo, pOuttext, &outlen,
maxout, pIntext, ulIntextLen,
pParameter, ulParameterLen,
pAssociatedData, ulAssociatedDataLen);

View File

@ -1,176 +0,0 @@
diff -up ./lib/softoken/pkcs11c.c.fips_2 ./lib/softoken/pkcs11c.c
--- ./lib/softoken/pkcs11c.c.fips_2 2024-01-19 09:21:19.632889660 -0800
+++ ./lib/softoken/pkcs11c.c 2024-01-19 09:22:18.541471306 -0800
@@ -7090,7 +7090,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
mech.ulParameterLen = sizeof(*params);
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
CKA_DERIVE, saltKey,
- keySize);
+ keySize*PR_BITS_PER_BYTE);
}
saltKeySource = saltKey->source;
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
@@ -7404,7 +7404,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
}
}
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey,
- keySize);
+ keySize*PR_BITS_PER_BYTE);
switch (mechanism) {
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
diff -up ./lib/softoken/pkcs11u.c.fips_2 ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.fips_2 2024-01-19 09:21:19.633889670 -0800
+++ ./lib/softoken/pkcs11u.c 2024-01-19 09:28:00.082843565 -0800
@@ -2393,20 +2393,43 @@ sftk_getKeyLength(SFTKObject *source)
}
PRBool
-sftk_CheckFIPSHash(CK_MECHANISM_TYPE hash)
+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 CKG_MGF1_SHA256:
+ case CKM_SHA256_HMAC:
case CKM_SHA384:
- case CKG_MGF1_SHA384:
+ case CKM_SHA384_HMAC:
case CKM_SHA512:
- case CKG_MGF1_SHA512:
+ case CKM_SHA512_HMAC:
return PR_TRUE;
}
return PR_FALSE;
}
+PRBool
+sftk_checkKeyLength(CK_ULONG keyLength, CK_ULONG min,
+ CK_ULONG max, CK_ULONG step)
+{
+ if (keyLength > max) {
+ return PR_FALSE;
+ }
+ if (keyLength < min ) {
+ return PR_FALSE;
+ }
+ if (((keyLength - min) % step) != 0) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
/*
* handle specialized FIPS semantics that are too complicated to
* handle with just a table. NOTE: this means any additional semantics
@@ -2416,6 +2439,8 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
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;
@@ -2482,7 +2507,11 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
if (pss->sLen > hashObj->length) {
return PR_FALSE;
}
- return sftk_CheckFIPSHash(pss->hashAlg);
+ /* Our code makes sure pss->hashAlg matches the explicit
+ * hash in the mechanism, and only mechanisms with approved
+ * hashes are included, so no need to check pss->hashAlg
+ * here */
+ return PR_TRUE;
}
case SFTKFIPSPBKDF2: {
/* PBKDF2 must have the following addition restrictions
@@ -2508,12 +2537,28 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
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_ULONG *)(((char *)mech->pParameter)
- + mechInfo->offset));
+ return sftk_checkFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
+ + mechInfo->offset), allowSmall, allowCMAC);
+ case SFTKFIPSTlsKeyCheck:
+ 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_ULONG *)(((char *)mech->pParameter)
+ + mechInfo->offset), PR_FALSE, PR_FALSE)) {
+ return PR_FALSE;
+ }
+ }
+ return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
default:
break;
}
@@ -2558,13 +2603,11 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
* approved algorithm in the approved mode with an approved key */
if ((mech->mechanism == mechs->type) &&
(opFlags == (mechs->info.flags & opFlags)) &&
- (keyLength <= mechs->info.ulMaxKeySize) &&
- (keyLength >= mechs->info.ulMinKeySize) &&
- (((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
- ((targetKeyLength == 0) ||
- ((targetKeyLength <= mechs->info.ulMaxKeySize) &&
- (targetKeyLength >= mechs->info.ulMinKeySize) &&
- ((targetKeyLength - mechs->info.ulMinKeySize) % mechs->step) == 0)) &&
+ sftk_checkKeyLength(keyLength, mechs->info.ulMinKeySize,
+ mechs->info.ulMaxKeySize, mechs->step) &&
+ ((targetKeyLength == 0) || (mechs->special == SFTKFIPSTlsKeyCheck)
+ || sftk_checkKeyLength(targetKeyLength, mechs->info.ulMinKeySize,
+ mechs->info.ulMaxKeySize, mechs->step)) &&
((mechs->special == SFTKFIPSNone) ||
sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
return PR_TRUE;
diff -up ./lib/softoken/sftkmessage.c.fips_2 ./lib/softoken/sftkmessage.c
--- ./lib/softoken/sftkmessage.c.fips_2 2024-01-19 09:21:19.634889680 -0800
+++ ./lib/softoken/sftkmessage.c 2024-01-19 09:22:18.541471306 -0800
@@ -157,16 +157,25 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
} else {
CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
switch (p->ivGenerator) {
+ default:
case CKG_NO_GENERATE:
context->isFIPS = PR_FALSE;
break;
case CKG_GENERATE_RANDOM:
- if ((p->ulIvLen < 12) || (p->ulIvFixedBits != 0)) {
+ if ((p->ulIvLen < 96/PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 0)) {
context->isFIPS = PR_FALSE;
}
break;
- default:
- if ((p->ulIvLen < 12) || (p->ulIvFixedBits < 32)) {
+ case CKG_GENERATE_COUNTER_XOR:
+ if ((p->ulIvLen != 96/PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ case CKG_GENERATE_COUNTER:
+ if ((p->ulIvFixedBits < 32) ||
+ ((p->ulIvLen*PR_BITS_PER_BYTE - p->ulIvFixedBits) < 32)) {
context->isFIPS = PR_FALSE;
}
}

View File

@ -1,506 +0,0 @@
diff -up ./lib/freebl/aeskeywrap.c.safe_zero ./lib/freebl/aeskeywrap.c
--- ./lib/freebl/aeskeywrap.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/aeskeywrap.c 2023-11-22 14:42:24.246388369 -0800
@@ -512,7 +512,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
outLen);
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -528,7 +528,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
PORT_ZFree(newBuf, paddedInputLen);
/* a little overkill, we only need to clear out the length, but this
* is easier to verify we got it all */
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -631,12 +631,12 @@ AESKeyWrap_DecryptKWP(AESKeyWrapContext
loser:
/* if we failed, make sure we don't return any data to the user */
if ((rv != SECSuccess) && (output == newBuf)) {
- PORT_Memset(newBuf, 0, paddedLen);
+ PORT_SafeZero(newBuf, paddedLen);
}
/* clear out CSP sensitive data from the heap and stack */
if (allocBuf) {
PORT_ZFree(allocBuf, paddedLen);
}
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
diff -up ./lib/freebl/blapii.h.safe_zero ./lib/freebl/blapii.h
--- ./lib/freebl/blapii.h.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/blapii.h 2023-11-22 14:42:24.246388369 -0800
@@ -101,10 +101,10 @@ PRBool ppc_crypto_support();
#ifdef NSS_FIPS_DISABLED
#define BLAPI_CLEAR_STACK(stack_size)
#else
-#define BLAPI_CLEAR_STACK(stack_size) \
- { \
- volatile char _stkclr[stack_size]; \
- PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
+#define BLAPI_CLEAR_STACK(stack_size) \
+ { \
+ volatile char _stkclr[stack_size]; \
+ PORT_SafeZero((void *)&_stkclr[0], stack_size); \
}
#endif
diff -up ./lib/freebl/drbg.c.safe_zero ./lib/freebl/drbg.c
--- ./lib/freebl/drbg.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/drbg.c 2023-11-22 14:42:24.246388369 -0800
@@ -197,7 +197,7 @@ prng_initEntropy(void)
SHA256_Update(&ctx, block, sizeof(block));
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
sizeof(globalrng->previousEntropyHash));
- PORT_Memset(block, 0, sizeof(block));
+ PORT_SafeZero(block, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
return PR_SUCCESS;
}
@@ -246,8 +246,8 @@ prng_getEntropy(PRUint8 *buffer, size_t
}
out:
- PORT_Memset(hash, 0, sizeof hash);
- PORT_Memset(block, 0, sizeof block);
+ PORT_SafeZero(hash, sizeof hash);
+ PORT_SafeZero(block, sizeof block);
return rv;
}
@@ -393,8 +393,8 @@ prng_Hashgen(RNGContext *rng, PRUint8 *r
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
SHA256_DestroyContext(&ctx, PR_FALSE);
}
- PORT_Memset(data, 0, sizeof data);
- PORT_Memset(thisHash, 0, sizeof thisHash);
+ PORT_SafeZero(data, sizeof data);
+ PORT_SafeZero(thisHash, sizeof thisHash);
}
/*
@@ -455,7 +455,7 @@ prng_generateNewBytes(RNGContext *rng,
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
/* if the prng failed, don't return any output, signal softoken */
- PORT_Memset(H, 0, sizeof H);
+ PORT_SafeZero(H, sizeof H);
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
diff -up ./lib/freebl/dsa.c.safe_zero ./lib/freebl/dsa.c
--- ./lib/freebl/dsa.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/dsa.c 2023-11-22 14:42:24.246388369 -0800
@@ -471,7 +471,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt
err = MP_OKAY;
signature->len = dsa_signature_len;
cleanup:
- PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
+ PORT_SafeZero(localDigestData, DSA_MAX_SUBPRIME_LEN);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
@@ -532,7 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECIt
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
- PORT_Memset(kSeed, 0, sizeof kSeed);
+ PORT_SafeZero(kSeed, sizeof kSeed);
return rv;
}
@@ -673,7 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, cons
verified = SECSuccess; /* Signature verified. */
}
cleanup:
- PORT_Memset(localDigestData, 0, sizeof localDigestData);
+ PORT_SafeZero(localDigestData, sizeof localDigestData);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
diff -up ./lib/freebl/gcm.c.safe_zero ./lib/freebl/gcm.c
--- ./lib/freebl/gcm.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/gcm.c 2023-11-22 14:42:24.246388369 -0800
@@ -480,7 +480,7 @@ gcmHash_Final(gcmHashContext *ghash, uns
rv = SECSuccess;
cleanup:
- PORT_Memset(T, 0, sizeof(T));
+ PORT_SafeZero(T, sizeof(T));
return rv;
}
@@ -596,15 +596,15 @@ GCM_CreateContext(void *context, freeblC
if (rv != SECSuccess) {
goto loser;
}
- PORT_Memset(H, 0, AES_BLOCK_SIZE);
+ PORT_SafeZero(H, AES_BLOCK_SIZE);
gcm->ctr_context_init = PR_TRUE;
return gcm;
loser:
- PORT_Memset(H, 0, AES_BLOCK_SIZE);
+ PORT_SafeZero(H, AES_BLOCK_SIZE);
if (ghash && ghash->mem) {
void *mem = ghash->mem;
- PORT_Memset(ghash, 0, sizeof(gcmHashContext));
+ PORT_SafeZero(ghash, sizeof(gcmHashContext));
PORT_Free(mem);
}
if (gcm) {
@@ -682,11 +682,11 @@ gcm_InitCounter(GCMContext *gcm, const u
goto loser;
}
- PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+ PORT_SafeZero(&ctrParams, sizeof ctrParams);
return SECSuccess;
loser:
- PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+ PORT_SafeZero(&ctrParams, sizeof ctrParams);
if (freeCtr) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
@@ -866,10 +866,10 @@ GCM_DecryptUpdate(GCMContext *gcm, unsig
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));
+ PORT_SafeZero(tag, sizeof(tag));
return SECFailure;
}
- PORT_Memset(tag, 0, sizeof(tag));
+ PORT_SafeZero(tag, sizeof(tag));
/* finish the decryption */
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);
@@ -1159,10 +1159,10 @@ GCM_DecryptAEAD(GCMContext *gcm, unsigne
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
PORT_SetError(SEC_ERROR_BAD_DATA);
- PORT_Memset(tag, 0, sizeof(tag));
+ PORT_SafeZero(tag, sizeof(tag));
return SECFailure;
}
- PORT_Memset(tag, 0, sizeof(tag));
+ PORT_SafeZero(tag, sizeof(tag));
/* finish the decryption */
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);
diff -up ./lib/freebl/hmacct.c.safe_zero ./lib/freebl/hmacct.c
--- ./lib/freebl/hmacct.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/hmacct.c 2023-11-22 14:42:24.246388369 -0800
@@ -274,10 +274,10 @@ MAC(unsigned char *mdOut,
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
hashObj->destroy(mdState, PR_TRUE);
- PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
- PORT_Memset(hmacPad, 0, sizeof hmacPad);
- PORT_Memset(firstBlock, 0, sizeof firstBlock);
- PORT_Memset(macOut, 0, sizeof macOut);
+ PORT_SafeZero(lengthBytes, sizeof lengthBytes);
+ PORT_SafeZero(hmacPad, sizeof hmacPad);
+ PORT_SafeZero(firstBlock, sizeof firstBlock);
+ PORT_SafeZero(macOut, sizeof macOut);
return SECSuccess;
}
diff -up ./lib/freebl/intel-gcm-wrap.c.safe_zero ./lib/freebl/intel-gcm-wrap.c
--- ./lib/freebl/intel-gcm-wrap.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/intel-gcm-wrap.c 2023-11-22 14:42:24.246388369 -0800
@@ -195,7 +195,7 @@ intel_aes_gcmInitCounter(intel_AES_GCMCo
void
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
{
- PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
+ PORT_SafeZero(gcm, sizeof(intel_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}
diff -up ./lib/freebl/ppc-gcm-wrap.c.safe_zero ./lib/freebl/ppc-gcm-wrap.c
--- ./lib/freebl/ppc-gcm-wrap.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/ppc-gcm-wrap.c 2023-11-22 14:42:24.246388369 -0800
@@ -169,7 +169,7 @@ ppc_aes_gcmInitCounter(ppc_AES_GCMContex
void
ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
{
- PORT_Memset(gcm, 0, sizeof(ppc_AES_GCMContext));
+ PORT_SafeZero(gcm, sizeof(ppc_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}
diff -up ./lib/freebl/pqg.c.safe_zero ./lib/freebl/pqg.c
--- ./lib/freebl/pqg.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/pqg.c 2023-11-22 14:42:24.246388369 -0800
@@ -703,7 +703,7 @@ cleanup:
mp_clear(&a);
mp_clear(&z);
mp_clear(&two_length_minus_1);
- PORT_Memset(x, 0, sizeof(x));
+ PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -859,7 +859,7 @@ cleanup:
mp_clear(&c);
mp_clear(&c0);
mp_clear(&one);
- PORT_Memset(x, 0, sizeof(x));
+ PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -1072,7 +1072,7 @@ makePfromQandSeed(
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
cleanup:
- PORT_Memset(V_j, 0, sizeof V_j);
+ PORT_SafeZero(V_j, sizeof V_j);
mp_clear(&W);
mp_clear(&X);
mp_clear(&c);
@@ -1221,7 +1221,7 @@ makeGfromIndex(HASH_HashType hashtype,
/* step 11.
* return valid G */
cleanup:
- PORT_Memset(data, 0, sizeof(data));
+ PORT_SafeZero(data, sizeof(data));
if (hashcx) {
hashobj->destroy(hashcx, PR_TRUE);
}
diff -up ./lib/freebl/rijndael.c.safe_zero ./lib/freebl/rijndael.c
--- ./lib/freebl/rijndael.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/rijndael.c 2023-11-22 14:42:24.247388378 -0800
@@ -1114,7 +1114,7 @@ AES_DestroyContext(AESContext *cx, PRBoo
cx->worker_cx = NULL;
cx->destroy = NULL;
}
- PORT_Memset(cx, 0, sizeof(AESContext));
+ PORT_SafeZero(cx, sizeof(AESContext));
if (freeit) {
PORT_Free(mem);
} else {
diff -up ./lib/freebl/rsa.c.safe_zero ./lib/freebl/rsa.c
--- ./lib/freebl/rsa.c.safe_zero 2023-11-22 14:41:24.066840894 -0800
+++ ./lib/freebl/rsa.c 2023-11-22 14:42:24.247388378 -0800
@@ -143,8 +143,8 @@ rsa_build_from_primes(const mp_int *p, c
/* 2. Compute phi = (p-1)*(q-1) */
CHECK_MPI_OK(mp_sub_d(p, 1, &psub1));
CHECK_MPI_OK(mp_sub_d(q, 1, &qsub1));
+ CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
if (needPublicExponent || needPrivateExponent) {
- CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
/* 3. Compute d = e**-1 mod(phi) */
/* or e = d**-1 mod(phi) as necessary */
if (needPublicExponent) {
@@ -165,6 +165,15 @@ rsa_build_from_primes(const mp_int *p, c
goto cleanup;
}
+ /* make sure we weren't passed in a d or e = 1 mod phi */
+ /* just need to check d, because if one is = 1 mod phi, they both are */
+ CHECK_MPI_OK(mp_mod(d, &phi, &tmp));
+ if (mp_cmp_d(&tmp, 2) <= 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ goto cleanup;
+ }
+
/* 4. Compute exponent1 = d mod (p-1) */
CHECK_MPI_OK(mp_mod(d, &psub1, &tmp));
MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena);
@@ -1152,6 +1161,8 @@ rsa_PrivateKeyOpCRTCheckedPubKey(RSAPriv
/* Perform a public key operation v = m ** e mod n */
CHECK_MPI_OK(mp_exptmod(m, &e, &n, &v));
if (mp_cmp(&v, c) != 0) {
+ /* this error triggers a fips fatal error lock */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
}
cleanup:
diff -up ./lib/freebl/rsapkcs.c.safe_zero ./lib/freebl/rsapkcs.c
--- ./lib/freebl/rsapkcs.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/rsapkcs.c 2023-11-22 14:42:24.247388378 -0800
@@ -977,14 +977,14 @@ rsa_GetHMACContext(const SECHashObject *
/* now create the hmac key */
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
if (hmac == NULL) {
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
return NULL;
}
HMAC_Begin(hmac);
HMAC_Update(hmac, input, inputLen);
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
if (rv != SECSuccess) {
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
}
@@ -992,7 +992,7 @@ rsa_GetHMACContext(const SECHashObject *
* reuse the original context allocated above so we don't
* need to allocate and free another one */
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
if (rv != SECSuccess) {
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
@@ -1042,7 +1042,7 @@ rsa_HMACPrf(HMACContext *hmac, const cha
return rv;
}
PORT_Memcpy(output, hmacLast, left);
- PORT_Memset(hmacLast, 0, sizeof(hmacLast));
+ PORT_SafeZero(hmacLast, sizeof(hmacLast));
}
return rv;
}
@@ -1087,7 +1087,7 @@ rsa_GetErrorLength(HMACContext *hmac, in
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
candidate, outLength);
}
- PORT_Memset(out, 0, sizeof(out));
+ PORT_SafeZero(out, sizeof(out));
return outLength;
}
diff -up ./lib/freebl/shvfy.c.safe_zero ./lib/freebl/shvfy.c
--- ./lib/freebl/shvfy.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/shvfy.c 2023-11-22 14:42:24.247388378 -0800
@@ -365,7 +365,7 @@ blapi_SHVerifyDSACheck(PRFileDesc *shFD,
/* verify the hash against the check file */
rv = DSA_VerifyDigest(key, signature, &hash);
- PORT_Memset(hashBuf, 0, sizeof hashBuf);
+ PORT_SafeZero(hashBuf, sizeof hashBuf);
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
}
#endif
@@ -427,7 +427,7 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD
if (rv == SECSuccess) {
result = SECITEM_ItemsAreEqual(signature, &hash);
}
- PORT_Memset(hashBuf, 0, sizeof hashBuf);
+ PORT_SafeZero(hashBuf, sizeof hashBuf);
return result;
}
@@ -451,7 +451,7 @@ blapi_SHVerifyFile(const char *shName, P
#ifndef NSS_STRICT_INTEGRITY
DSAPublicKey key;
- PORT_Memset(&key, 0, sizeof(key));
+ PORT_SafeZero(&key, sizeof(key));
#endif
/* If our integrity check was never ran or failed, fail any other
@@ -597,7 +597,7 @@ blapi_SHVerifyFile(const char *shName, P
shFD = NULL;
loser:
- PORT_Memset(&header, 0, sizeof header);
+ PORT_SafeZero(&header, sizeof header);
if (checkName != NULL) {
PORT_Free(checkName);
}
diff -up ./lib/freebl/tlsprfalg.c.safe_zero ./lib/freebl/tlsprfalg.c
--- ./lib/freebl/tlsprfalg.c.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/freebl/tlsprfalg.c 2023-11-22 14:42:24.247388378 -0800
@@ -82,8 +82,8 @@ loser:
/* clear out state so it's not left on the stack */
if (cx)
HMAC_Destroy(cx, PR_TRUE);
- PORT_Memset(state, 0, sizeof(state));
- PORT_Memset(outbuf, 0, sizeof(outbuf));
+ PORT_SafeZero(state, sizeof(state));
+ PORT_SafeZero(outbuf, sizeof(outbuf));
return rv;
}
diff -up ./lib/freebl/unix_urandom.c.safe_zero ./lib/freebl/unix_urandom.c
--- ./lib/freebl/unix_urandom.c.safe_zero 2023-11-22 14:42:24.247388378 -0800
+++ ./lib/freebl/unix_urandom.c 2023-11-22 14:44:15.519400684 -0800
@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
- PORT_Memset(bytes, 0, sizeof bytes);
+ PORT_SafeZero(bytes, sizeof bytes);
}
#ifdef NSS_FIPS_140_3
diff -up ./lib/softoken/pkcs11c.c.safe_zero ./lib/softoken/pkcs11c.c
--- ./lib/softoken/pkcs11c.c.safe_zero 2023-11-22 14:41:24.069840921 -0800
+++ ./lib/softoken/pkcs11c.c 2023-11-22 14:42:24.248388387 -0800
@@ -5092,7 +5092,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
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;
+ return CKR_GENERAL_ERROR;
}
/* Verify the known hash using the public key. */
diff -up ./lib/util/secport.h.safe_zero ./lib/util/secport.h
--- ./lib/util/secport.h.safe_zero 2023-06-04 01:42:53.000000000 -0700
+++ ./lib/util/secport.h 2023-11-22 14:42:24.248388387 -0800
@@ -36,6 +36,9 @@
#include <sys/types.h>
#include <ctype.h>
+/* ask for Annex K for memset_s. will set the appropriate #define
+ * if Annex K is supported */
+#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
@@ -182,6 +185,39 @@ SEC_END_PROTOS
#endif /*SUNOS4*/
#define PORT_Memset memset
+/* there are cases where the compiler optimizes away our attempt to clear
+ * out our stack variables. There are multiple solutions for this problem,
+ * but they aren't universally accepted on all platforms. This attempts
+ * to select the best solution available given our os, compilier, and libc */
+#ifdef __STDC_LIB_EXT1__
+/* if the os implements C11 annex K, use memset_s */
+#define PORT_SafeZero(p, n) memset_s(p, n, 0, n)
+#else
+#ifdef XP_WIN
+/* windows has a secure zero funtion */
+#define PORT_SafeZero(p, n) SecureZeroMemory(p, n)
+#else
+/* _DEFAULT_SORUCE == BSD source in GCC based environments
+ * if other environmens support explicit_bzero, their defines
+ * should be added here */
+#if defined(_DEFAULT_SOURCE) || defined(_BSD_SOURCE)
+#define PORT_SafeZero(p, n) explicit_bzero(p, n)
+#else
+/* if the os doesn't support one of the above, but does support
+ * memset_explicit, you can add the definition for memset with the
+ * appropriate define check here */
+/* define an explicitly implementated Safe zero if the OS
+ * doesn't provide one */
+#define PORT_SafeZero(p, n) \
+ if (p != NULL) { \
+ volatile unsigned char *__vl = (unsigned char *)p; \
+ size_t __nl = n; \
+ while (__nl--) *__vl++ = 0; \
+ }
+#endif /* no explicit_bzero */
+#endif /* no windows SecureZeroMemory */
+#endif /* no memset_s */
+
#define PORT_Strcasecmp PL_strcasecmp
#define PORT_Strcat strcat
#define PORT_Strchr strchr

View File

@ -1,42 +0,0 @@
diff -up ./lib/softoken/pkcs11u.c.pkcs12_indicator ./lib/softoken/pkcs11u.c
--- ./lib/softoken/pkcs11u.c.pkcs12_indicator 2023-08-03 10:50:37.067109367 -0700
+++ ./lib/softoken/pkcs11u.c 2023-08-03 11:41:55.641541953 -0700
@@ -2429,7 +2429,7 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
return PR_FALSE;
case SFTKFIPSECC:
/* we've already handled the curve selection in the 'getlength'
- * function */
+ * function */
return PR_TRUE;
case SFTKFIPSAEAD: {
if (mech->ulParameterLen == 0) {
@@ -2463,6 +2463,29 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
}
return PR_TRUE;
}
+ case SFTKFIPSPBKDF2: {
+ /* 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_PARAMS *pbkdf2 = (CK_PKCS5_PBKD2_PARAMS *)
+ 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;
+ }
default:
break;
}

View File

@ -1,7 +1,7 @@
%global nspr_build_version 4.35.0-1
%global nspr_release -1
%global nspr_build_version 4.36.0-2
%global nspr_release -2
%global nspr_version 4.35.0
%global nss_version 3.101.0
%global nss_version 3.112.0
%global unsupported_tools_directory %{_libdir}/nss/unsupported-tools
%global saved_files_dir %{_libdir}/nss/saved
%global dracutlibdir %{_prefix}/lib/dracut
@ -63,7 +63,7 @@ print(string.sub(hash, 0, 16))
Summary: Network Security Services
Name: nss
Version: %{nss_version}
Release: 11%{?dist}
Release: 4%{?dist}
License: MPLv2.0
URL: http://www.mozilla.org/projects/security/pki/nss/
Requires: nspr >= %{nspr_version}%{nspr_release}
@ -109,6 +109,7 @@ Source25: key3.db.xml
Source26: key4.db.xml
Source27: secmod.db.xml
Source28: nss-p11-kit.config
Source29: nss_compat_test_pkcs12.tar
# fips algorithms are tied to the red hat validation, others
# will have their own validation
Source30: fips_algorithms.h
@ -149,10 +150,9 @@ Patch12: nss-gcm-param-default-pkcs11v2.patch
Patch13: rhbz1185708-enable-ecc-3des-ciphers-by-default.patch
# Local patch: ignore rsa, rsa-pss, ecdsa policies until crypto-policies
# is updated.
Patch14: nss-3.101-disable-signature-policies.patch
Patch15: nss-3.101-el8-fix-rsa-policy-test.patch
Patch14: nss-3.112-disable-signature-policies.patch
# Local patch: disable tests that require external reference so brew completes
Patch16: nss-3.66-disable-external-host-test.patch
Patch16: nss-3.112-disable-external-host-test.patch
# Local patch: restore old pkcs 12 defaults on old version of rhel
Patch17: nss-3.101-el8-restore-old-pkcs12-default.patch
# Local Patch: restore expired distrusted certs for now
@ -169,45 +169,32 @@ Patch20: nss-3.101-ec-dbm-test.patch
Patch30: nss-3.101-extend-db-dump-time.patch
# Local patch: disable MD5 (also MD2 and MD4) completely
# https://bugzilla.redhat.com/show_bug.cgi?id=1849938
Patch32: nss-3.101-disable-md5.patch
Patch32: nss-3.112-disable-md5.patch
Patch34: nss-3.71-fix-lto-gtests.patch
Patch35: nss-3.71-camellia-pkcs12-doc.patch
Patch36: nss-3.101-disable-ech.patch
Patch36: nss-3.112-disable-ech.patch
Patch37: nss-3.112-revert-libpkix-default.patch
# patches that expect to be upstreamed
# https://bugzilla.mozilla.org/show_bug.cgi?id=1767883
Patch50: nss-3.79-fips.patch
# https://bugzilla.mozilla.org/show_bug.cgi?id=1836781
# https://bugzilla.mozilla.org/show_bug.cgi?id=1836925
Patch51: nss-3.101-fips-review.patches
Patch52: nss-3.90-pbkdf2-indicator.patch
Patch50: nss-3.112-fips.patch
# ems policy. needs to upstream
Patch60: nss-3.101-add-ems-policy.patch
Patch70: nss-3.90-fips-safe-memset.patch
Patch71: nss-3.101-fips-indicators.patch
Patch72: nss-3.90-aes-gmc-indicator.patch
Patch73: nss-3.90-fips-indicators2.patch
Patch74: nss-3.90-dh-test-update.patch
Patch75: nss-3.90-ppc_no_init.patch
Patch76: nss-3.101-enable-kyber-policy.patch
Patch78: nss-3.101-fix-pkcs12-md5-decode.patch
Patch80: nss-3.101-el8-no-p12-smime-policy.patch
Patch81: nss-3.101-fix-missing-size-checks.patch
# https://bugzilla.mozilla.org/show_bug.cgi?id=1905691
Patch82: nss-3.101-chacha-timing-fix.patch
Patch83: nss-3.101-add-certificate-compression-test.patch
Patch84: nss-3.101-fix-pkcs12-pbkdf1-encoding.patch
# https://bugzilla.mozilla.org/show_bug.cgi?id=676100
Patch80: nss-3.112-el8-no-p12-smime-policy.patch
Patch85: nss-3.101-fix-cms-abi-break.patch
Patch86: nss-3.101-long-pwd-fix.patch
Patch87: nss-3.101-fix-shlibsign-fips.patch
Patch88: nss-3.101-fips-check-ec25519-size.patch
Patch89: nss-3.101-allow-fips-rsa-oaep.patch
#revert patches
Patch300: nss-3.101-default-libpkix.patch
# Post Quantum specific
Patch91: nss-3.112-replace-xyber-with-mlkem-256.patch
Patch92: nss-3.112-add-sec384r1-mlkem-1024.patch
Patch93: nss-3.112-add-ml-dsa-base-el8.patch
Patch94: nss-3.112-add-ml-dsa-gtests-el8.patch
Patch95: nss-3.112-add-ml-dsa-ssl-support-el8.patch
Patch96: nss-3.112-fips-and-fixes-el8.patch
Patch97: nss-3.112-big-endian-compression-fix.patch
Patch98: nss-3.112-fix-get-interface.patch
%description
Network Security Services (NSS) is a set of libraries designed to
@ -335,12 +322,14 @@ Header and library files for doing development with Network Security Services.
%prep
%autosetup -N -n %{name}-%{nss_archive_version}
pushd nss
%autopatch -M 299 -p1
%patch -P 300 -p1 -R
popd
tar xvf %{SOURCE29}
# copy the fips_algorithms.h for this release
# this file is release specific and matches what
# each vendors claim in their own FIPS certification
@ -375,6 +364,8 @@ export FIPS_MODULE_OS="$OS_NAME\ ${OS_VERSION_ID%%.*}"
export NSS_FIPS_MODULE_ID="${FIPS_MODULE_OS}\ ${NSS_FIPS_VERSION}"
export NSS_FIPS_140_3=1
export NSS_ENABLE_FIPS_INDICATORS=1
export NSS_DISABLE_KYBER=1
export NSS_ENABLE_ML_DSA=1
# Enable compiler optimizations and disable debugging code
export BUILD_OPT=1
@ -535,6 +526,8 @@ done
# Begin -- copied from the build section
export FREEBL_NO_DEPEND=1
export NSS_DISABLE_KYBER=1
export NSS_ENABLE_ML_DSA=1
export BUILD_OPT=1
@ -908,6 +901,7 @@ update-crypto-policies --no-reload &> /dev/null || :
%{_includedir}/nss3/eccutil.h
%{_includedir}/nss3/hasht.h
%{_includedir}/nss3/kyber.h
%{_includedir}/nss3/ml_dsat.h
%{_includedir}/nss3/nssb64.h
%{_includedir}/nss3/nssb64t.h
%{_includedir}/nss3/nsshash.h
@ -1002,6 +996,22 @@ update-crypto-policies --no-reload &> /dev/null || :
%changelog
* Thu Aug 7 2025 Bob Relyea <rrelyea@redhat.com> - 3.112.0-4
- fix interface issue when pulling 3.0 pkcs#11 interfaces explicitly
* Fri Aug 1 2025 Bob Relyea <rrelyea@redhat.com> - 3.112.0-3
- restore CONCATENATE functions accidentally remvoed in the last patch
- fix big endian issue in tstclnt and selfserv in certificate compression
* Wed Jul 30 2025 Bob Relyea <rrelyea@redhat.com> - 3.112.0-2
- add fips required changes.
- fix bugs found by QE
* Wed Jul 16 2025 Bob Relyea <rrelyea@redhat.com> - 3.112.0-1
- rebase to NSS 3.112
- add ml-kem-1024 support
- add ml-dsa support
* Tue Nov 12 2024 Frantisek Krenzelok <krenzelok.frantisek@gmail.com> - 3.101.0-11
- don't define -DNSS_NO_INIT_SUPPORT for legacydb on pcc systems