diff --git a/SOURCES/nss-3.79-fips.patch b/SOURCES/nss-3.79-fips.patch new file mode 100644 index 0000000..17d20f1 --- /dev/null +++ b/SOURCES/nss-3.79-fips.patch @@ -0,0 +1,710 @@ +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,80 @@ 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 ++#endif ++ + size_t + RNG_SystemRNG(void *dest, size_t maxLen) + { ++#ifndef NSS_FIPS_140_3 + int fd; + int bytes; ++#endif + size_t fileBytes = 0; + unsigned char *buffer = dest; + + #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, GRND_RANDOM); ++ 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 +103,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/fips_algorithms.h b/lib/softoken/fips_algorithms.h +--- a/lib/softoken/fips_algorithms.h ++++ b/lib/softoken/fips_algorithms.h +@@ -49,33 +49,46 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] + #define CKF_KEK (CKF_WRAP | CKF_UNWRAP) + #define CKF_KEA CKF_DERIVE + #define CKF_KDF CKF_DERIVE + #define CKF_HSH CKF_DIGEST + #define CK_MAX 0xffffffffUL + /* mechanisms using the same key types share the same key type + * limits */ + #define RSA_FB_KEY 2048, 4096 /* min, max */ +-#define RSA_FB_STEP 1024 ++#define RSA_FB_STEP 1 ++#define RSA_LEGACY_FB_KEY 1024, 1792 /* min, max */ ++#define RSA_LEGACY_FB_STEP 256 ++ + #define DSA_FB_KEY 2048, 4096 /* min, max */ + #define DSA_FB_STEP 1024 + #define DH_FB_KEY 2048, 4096 /* min, max */ + #define DH_FB_STEP 1024 + #define EC_FB_KEY 256, 521 /* min, max */ + #define EC_FB_STEP 1 /* key limits handled by special operation */ + #define AES_FB_KEY 128, 256 + #define AES_FB_STEP 64 + { CKM_RSA_PKCS_KEY_PAIR_GEN, { RSA_FB_KEY, CKF_KPG }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_RSA_PKCS_OAEP, { RSA_FB_KEY, CKF_ENC }, RSA_FB_STEP, SFTKFIPSNone }, ++ { CKM_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ + /* -------------- RSA Multipart Signing Operations -------------------- */ + { CKM_SHA224_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { 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, SFTKFIPSNone }, ++ { CKM_SHA256_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA384_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, ++ { CKM_SHA512_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, + { CKM_SHA224_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA256_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA384_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + { CKM_SHA512_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, + /* ------------------------- DSA Operations --------------------------- */ + { CKM_DSA_KEY_PAIR_GEN, { DSA_FB_KEY, CKF_KPG }, DSA_FB_STEP, SFTKFIPSNone }, + { CKM_DSA, { DSA_FB_KEY, CKF_SGN }, DSA_FB_STEP, SFTKFIPSNone }, + { CKM_DSA_PARAMETER_GEN, { DSA_FB_KEY, CKF_KPG }, DSA_FB_STEP, SFTKFIPSNone }, +@@ -95,76 +108,73 @@ 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 }, + /* ------------------------- RC2 Operations --------------------------- */ + /* ------------------------- AES Operations --------------------------- */ + { CKM_AES_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_ECB, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CBC, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_MAC, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_MAC_GENERAL, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CMAC, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CMAC_GENERAL, { AES_FB_KEY, CKF_SGN }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CBC_PAD, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CTS, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_CTR, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_GCM, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSAEAD }, + { CKM_AES_KEY_WRAP, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_KEY_WRAP_PAD, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, + { CKM_AES_KEY_WRAP_KWP, { AES_FB_KEY, CKF_ENC }, AES_FB_STEP, SFTKFIPSNone }, +- { CKM_AES_XCBC_MAC_96, { 96, 96, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_AES_XCBC_MAC, { 128, 128, CKF_SGN }, 1, SFTKFIPSNone }, + /* ------------------------- Hashing Operations ----------------------- */ + { CKM_SHA224, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, + { CKM_SHA224_HMAC, { 112, 224, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA224_HMAC_GENERAL, { 112, 224, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA256, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA256_HMAC, { 128, 256, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA256_HMAC_GENERAL, { 128, 256, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_HMAC, { 112, 256, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_HMAC_GENERAL, { 112, 256, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA384, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA384_HMAC, { 192, 384, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA384_HMAC_GENERAL, { 192, 384, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_HMAC, { 112, 384, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_HMAC_GENERAL, { 112, 384, CKF_SGN }, 1, SFTKFIPSNone }, + { CKM_SHA512, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone }, +- { CKM_SHA512_HMAC, { 256, 512, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_SHA512_HMAC_GENERAL, { 256, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_HMAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_HMAC_GENERAL, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, + /* --------------------- Secret Key Operations ------------------------ */ +- { CKM_GENERIC_SECRET_KEY_GEN, { 8, 256, CKF_GEN }, 1, SFTKFIPSNone }, ++ { CKM_GENERIC_SECRET_KEY_GEN, { 112, 256, CKF_GEN }, 1, SFTKFIPSNone }, + /* ---------------------- SSL/TLS operations ------------------------- */ + { CKM_SHA224_KEY_DERIVATION, { 112, 224, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA256_KEY_DERIVATION, { 128, 256, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA384_KEY_DERIVATION, { 192, 284, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SHA512_KEY_DERIVATION, { 256, 512, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA256_KEY_DERIVATION, { 112, 256, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA384_KEY_DERIVATION, { 112, 284, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SHA512_KEY_DERIVATION, { 112, 512, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SSL3_PRE_MASTER_KEY_GEN, { 384, 384, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_TLS12_MASTER_KEY_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_TLS12_MASTER_KEY_DERIVE_DH, { DH_FB_KEY, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_TLS12_KEY_AND_MAC_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_TLS_PRF_GENERAL, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone }, +- { CKM_TLS_MAC, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_TLS_PRF_GENERAL, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, ++ { CKM_TLS_MAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone }, + /* sigh, is this algorithm really tested. ssl doesn't seem to have a + * way of turning the extension off */ + { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, { 192, 1024, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH, { 192, 1024, CKF_DERIVE }, 1, SFTKFIPSNone }, + + /* ------------------------- HKDF Operations -------------------------- */ +- { CKM_HKDF_DERIVE, { 8, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_HKDF_DATA, { 8, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_HKDF_DERIVE, { 112, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_HKDF_DATA, { 112, 255 * 64 * 8, CKF_KDF }, 1, SFTKFIPSNone }, + { CKM_HKDF_KEY_GEN, { 160, 224, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_HKDF_KEY_GEN, { 256, 512, CKF_GEN }, 128, SFTKFIPSNone }, + /* ------------------ NIST 800-108 Key Derivations ------------------- */ +- { CKM_SP800_108_COUNTER_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SP800_108_FEEDBACK_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_COUNTER_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_FEEDBACK_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSNone }, + /* --------------------IPSEC ----------------------- */ +- { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_KDF }, 1, SFTKFIPSNone }, +- { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 8, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE_PRF_DERIVE, { 112, 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE1_PRF_DERIVE, { 112, 64, CKF_KDF }, 1, SFTKFIPSNone }, ++ { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone }, + /* ------------------ PBE Key Derivations ------------------- */ +- { CKM_PKCS5_PBKD2, { 1, 256, CKF_GEN }, 1, SFTKFIPSNone }, ++ { CKM_PKCS5_PBKD2, { 112, 256, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, { 224, 224, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, { 256, 256, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, { 384, 384, CKF_GEN }, 1, SFTKFIPSNone }, + { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, { 512, 512, CKF_GEN }, 1, SFTKFIPSNone } + }; + const int SFTK_NUMBER_FIPS_ALGORITHMS = PR_ARRAY_SIZE(sftk_fips_mechs); +diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c +--- a/lib/softoken/lowpbe.c ++++ b/lib/softoken/lowpbe.c +@@ -1765,27 +1765,29 @@ SECStatus + sftk_fips_pbkdf_PowerUpSelfTests(void) + { + SECItem *result; + SECItem inKey; + NSSPKCS5PBEParameter pbe_params; + 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(); + + inKey.data = (unsigned char *)inKeyData; + inKey.len = sizeof(TEST_KEY) - 1; + + pbe_params.salt.data = (unsigned char *)saltData; +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=¶ms->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 + * + */ diff --git a/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch b/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch index ad11348..d562b3b 100644 --- a/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch +++ b/SOURCES/nss-3.79-rhel-8-fips-signature-policy.patch @@ -556,43 +556,6 @@ diff -up ./lib/pk11wrap/pk11pars.c.sign_policy ./lib/pk11wrap/pk11pars.c } /* Policy operations: -diff -up ./lib/softoken/fips_algorithms.h.sign_policy ./lib/softoken/fips_algorithms.h ---- ./lib/softoken/fips_algorithms.h.sign_policy 2022-05-26 02:54:33.000000000 -0700 -+++ ./lib/softoken/fips_algorithms.h 2022-06-20 16:47:35.026785647 -0700 -@@ -54,7 +54,9 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] - /* mechanisms using the same key types share the same key type - * limits */ - #define RSA_FB_KEY 2048, 4096 /* min, max */ --#define RSA_FB_STEP 1024 -+#define RSA_FB_STEP 1 -+#define RSA_LEGACY_FB_KEY 1024, 1792 /* min, max */ -+#define RSA_LEGACY_FB_STEP 256 - #define DSA_FB_KEY 2048, 4096 /* min, max */ - #define DSA_FB_STEP 1024 - #define DH_FB_KEY 2048, 4096 /* min, max */ -@@ -66,6 +68,7 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] - { CKM_RSA_PKCS_KEY_PAIR_GEN, { RSA_FB_KEY, CKF_KPG }, RSA_FB_STEP, SFTKFIPSNone }, - { CKM_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, - { CKM_RSA_PKCS_OAEP, { RSA_FB_KEY, CKF_ENC }, RSA_FB_STEP, SFTKFIPSNone }, -+ { CKM_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, - /* -------------- RSA Multipart Signing Operations -------------------- */ - { CKM_SHA224_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, - { CKM_SHA256_RSA_PKCS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, -@@ -75,6 +78,14 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] - { CKM_SHA256_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, - { CKM_SHA384_RSA_PKCS_PSS, { RSA_FB_KEY, CKF_SGN }, RSA_FB_STEP, SFTKFIPSNone }, - { CKM_SHA512_RSA_PKCS_PSS, { 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, SFTKFIPSNone }, -+ { CKM_SHA256_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, -+ { CKM_SHA384_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, -+ { CKM_SHA512_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSNone }, - /* ------------------------- DSA Operations --------------------------- */ - { CKM_DSA_KEY_PAIR_GEN, { DSA_FB_KEY, CKF_KPG }, DSA_FB_STEP, SFTKFIPSNone }, - { CKM_DSA, { DSA_FB_KEY, CKF_SGN }, DSA_FB_STEP, SFTKFIPSNone }, diff -up ./lib/ssl/ssl3con.c.sign_policy ./lib/ssl/ssl3con.c --- ./lib/ssl/ssl3con.c.sign_policy 2022-06-20 16:47:34.998785473 -0700 +++ ./lib/ssl/ssl3con.c 2022-06-20 16:47:35.028785660 -0700 diff --git a/SPECS/nss.spec b/SPECS/nss.spec index dd32c68..1bed25e 100644 --- a/SPECS/nss.spec +++ b/SPECS/nss.spec @@ -63,7 +63,7 @@ print(string.sub(hash, 0, 16)) Summary: Network Security Services Name: nss Version: %{nss_version} -Release: 8%{?dist} +Release: 9%{?dist} License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Requires: nspr >= %{nspr_version}%{nspr_release} @@ -165,7 +165,8 @@ Patch63: nss-3.79-fix-client-cert-crash.patch Patch64: nss-3.79-rhel-8-fips-signature-policy.patch Patch65: nss-3.79-enable-POST-rerun.patch Patch66: nss-3.79-increase-pbe-cache.patch -Patch67: /nss-3.79-pkcs12-fix-null-password.patch +Patch67: nss-3.79-pkcs12-fix-null-password.patch +Patch68: nss-3.79-fips.patch %description Network Security Services (NSS) is a set of libraries designed to @@ -320,7 +321,8 @@ export NSS_FIPS_VERSION="%{name}\ %{version}-%{srpmhash}" eval $(sed -n 's/^\(\(NAME\|VERSION_ID\)=.*\)/OS_\1/p' /etc/os-release | sed -e 's/ /\\ /g') 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 # Enable compiler optimizations and disable debugging code export BUILD_OPT=1 @@ -942,6 +944,9 @@ update-crypto-policies --no-reload &> /dev/null || : %changelog +* Fri Aug 5 2022 Bob Relyea - 3.79.0-9 +- FIPS 140-3 changes + * Wed Jul 13 2022 Bob Relyea - 3.79.0-8 - Update fips default for pk12util to AES rather than TDES - Fix bug in pkcs12 files with null passwords