SHA256
1
0
forked from pool/mozilla-nss

Accepting request 1191334 from mozilla:Factory

OBS-URL: https://build.opensuse.org/request/show/1191334
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mozilla-nss?expand=0&rev=220
This commit is contained in:
Dominique Leuenberger 2024-08-05 15:20:45 +00:00 committed by Git OBS Bridge
commit 2112765af8
15 changed files with 1104 additions and 288 deletions

View File

@ -2,7 +2,7 @@ Index: nss/tests/ssl/ssl.sh
===================================================================
--- nss.orig/tests/ssl/ssl.sh
+++ nss/tests/ssl/ssl.sh
@@ -1696,6 +1696,7 @@ ssl_run_tests()
@@ -1661,6 +1661,7 @@ ssl_run_tests()
################################# main #################################

View File

@ -1,3 +1,41 @@
-------------------------------------------------------------------
Fri Aug 2 08:04:51 UTC 2024 - Martin Sirringhaus <martin.sirringhaus@suse.com>
- update to NSS 3.102.1
* bmo#1905691 - ChaChaXor to return after the function
- update to NSS 3.102
* bmo#1880351 - Add Valgrind annotations to freebl Chacha20-Poly1305.
* bmo#1901932 - missing sqlite header.
* bmo#1901080 - GLOBALTRUST 2020: Set Distrust After for TLS and S/MIME.
* bmo#1615298 - improve certutil keyUsage, extKeyUsage, and nsCertType keyword handling.
* bmo#1660676 - correct length of raw SPKI data before printing in pp utility.
-------------------------------------------------------------------
Mon Jul 29 12:44:11 UTC 2024 - Martin Sirringhaus <martin.sirringhaus@suse.com>
- Require `sed` for mozilla-nss-sysinit, as setup-nsssysinit.sh
depends on it and will create a broken, empty config, if sed is
missing (bsc#1227918)
-------------------------------------------------------------------
Wed Jul 10 13:21:13 UTC 2024 - Hans Petter Jansson <hpj@suse.com>
- Added nss-fips-safe-memset.patch, fixing bsc#1222811.
- Removed some dead code from nss-fips-constructor-self-tests.patch.
- Rebased nss-fips-approved-crypto-non-ec.patch on above changes.
- Added nss-fips-aes-gcm-restrict.patch, fixing bsc#1222830.
- Updated nss-fips-approved-crypto-non-ec.patch, fixing bsc#1222813,
bsc#1222814, bsc#1222821, bsc#1222822, bsc#1224118.
- Updated nss-fips-approved-crypto-non-ec.patch and
nss-fips-constructor-self-tests.patch, fixing bsc#1222807,
bsc#1222828, bsc#1222834.
- Updated nss-fips-approved-crypto-non-ec.patch, fixing bsc#1222804,
bsc#1222826, bsc#1222833, bsc#1224113, bsc#1224115, bsc#1224116.
-------------------------------------------------------------------
Mon Jul 1 09:50:57 UTC 2024 - Martin Sirringhaus <martin.sirringhaus@suse.com>

View File

@ -17,15 +17,15 @@
#
%global nss_softokn_fips_version 3.101.1
%global nss_softokn_fips_version 3.102.1
%define NSPR_min_version 4.35
%define nspr_ver %(rpm -q --queryformat '%%{VERSION}' mozilla-nspr)
%define nssdbdir %{_sysconfdir}/pki/nssdb
%global crypto_policies_version 20210118
%global crypto_policies_version 20210218
Name: mozilla-nss
Version: 3.101.1
Version: 3.102.1
Release: 0
%define underscore_version 3_101_1
%define underscore_version 3_102_1
Summary: Network Security Services
License: MPL-2.0
Group: System/Libraries
@ -81,6 +81,8 @@ Patch47: nss-fips-pct-pubkeys.patch
Patch48: nss-fips-test.patch
Patch49: nss-allow-slow-tests-s390x.patch
Patch50: nss-fips-bsc1223724.patch
Patch51: nss-fips-aes-gcm-restrict.patch
Patch52: nss-fips-safe-memset.patch
%if 0%{?sle_version} >= 120000 && 0%{?sle_version} < 150000
# aarch64 + gcc4.8 fails to build on SLE-12 due to undefined references
BuildRequires: gcc9-c++
@ -150,6 +152,7 @@ applications that use NSS.
Summary: System NSS Initialization
Group: System/Management
Requires: mozilla-nss >= %{version}
Requires(post): sed
Requires(post): coreutils
%description sysinit
@ -245,6 +248,11 @@ cd nss
%patch -P 49 -p1
%endif
%patch -P 50 -p1
%patch -P 51 -p1
%if 0%{?sle_version} >= 150000
# glibc on SLE-12 is too old and doesn't have explicit_bzero yet.
%patch -P 52 -p1
%endif
# additional CA certificates
#cd security/nss/lib/ckfw/builtins

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f20e8c5daafd89419d229ec8c54100a5c320dce1467377c9dfcd5e4d8446b468
size 76462490

3
nss-3.102.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:54982d3587e41579c94f2036ba084438b073f8456bbd873b7a942c057e9737cc
size 76460182

View File

@ -0,0 +1,42 @@
Index: nss/lib/softoken/sftkmessage.c
===================================================================
--- nss.orig/lib/softoken/sftkmessage.c
+++ nss/lib/softoken/sftkmessage.c
@@ -151,6 +151,37 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
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;
+ }
+ }
+ }
+ }
+
if (!pOuttext) {
*pulOuttextLen = ulIntextLen;
return CKR_OK;

View File

@ -213,7 +213,7 @@ Index: nss/lib/freebl/fips.h
===================================================================
--- nss.orig/lib/freebl/fips.h
+++ nss/lib/freebl/fips.h
@@ -8,9 +8,21 @@
@@ -8,8 +8,20 @@
#ifndef FIPS_H
#define FIPS_H
@ -230,7 +230,6 @@ Index: nss/lib/freebl/fips.h
+
int FIPS_mode(void);
int FIPS_mode_allow_tests(void);
char* FIPS_rngDev(void);
+PRBool FIPS_hashAlgApproved(HASH_HashType hashAlg);
#endif
@ -369,17 +368,27 @@ Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -4823,6 +4823,9 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
@@ -452,7 +452,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;
}
@@ -4877,6 +4877,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
goto loser;
}
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_GEN_MECHANISM, key);
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_GEN_MECHANISM,
+ key, key_length * PR_BITS_PER_BYTE);
+ session->lastOpWasFIPS = key->isFIPS;
+
/*
* handle the base object stuff
*/
@@ -4837,6 +4840,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
@@ -4891,6 +4895,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
if (crv == CKR_OK) {
*phKey = key->handle;
}
@ -387,7 +396,16 @@ Index: nss/lib/softoken/pkcs11c.c
loser:
PORT_Memset(buf, 0, sizeof buf);
sftk_FreeObject(key);
@@ -5808,11 +5812,11 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
@@ -5318,7 +5323,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
int i;
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- unsigned int bitSize;
+ unsigned int bitSize = 0;
/* RSA */
int public_modulus_bits = 0;
@@ -5921,11 +5926,11 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
* created and linked.
*/
crv = sftk_handleObject(publicKey, session);
@ -400,7 +418,7 @@ Index: nss/lib/softoken/pkcs11c.c
return crv;
}
if (sftk_isTrue(privateKey, CKA_SENSITIVE)) {
@@ -5856,13 +5860,19 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
@@ -5969,13 +5974,19 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession, privateKey->handle);
sftk_FreeObject(privateKey);
@ -408,8 +426,8 @@ Index: nss/lib/softoken/pkcs11c.c
return crv;
}
+ publicKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_PAIR_GEN_MECHANISM, publicKey);
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_PAIR_GEN_MECHANISM, privateKey);
+ publicKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_PAIR_GEN_MECHANISM, publicKey, bitSize);
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_KEY_PAIR_GEN_MECHANISM, privateKey, bitSize);
+ session->lastOpWasFIPS = privateKey->isFIPS;
+
*phPrivateKey = privateKey->handle;
@ -420,7 +438,51 @@ Index: nss/lib/softoken/pkcs11c.c
return CKR_OK;
}
@@ -7568,7 +7578,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
@@ -7167,6 +7178,14 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
return CKR_TEMPLATE_INCONSISTENT;
}
+ if (!params->bExpand) {
+ keySize = hashLen;
+ }
+
+ if (!params->bExpand) {
+ keySize = hashLen;
+ }
+
/* sourceKey is NULL if we are called from the POST, skip the
* sensitiveCheck */
if (sourceKey != NULL) {
@@ -7215,7 +7234,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*PR_BITS_PER_BYTE);
}
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
if (saltKey_att == NULL) {
@@ -7257,7 +7277,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
@@ -7480,7 +7500,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*PR_BITS_PER_BYTE);
switch (mechanism) {
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
@@ -7681,7 +7702,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
} else {
/* now allocate the hash contexts */
md5 = MD5_NewContext();
@ -429,7 +491,7 @@ Index: nss/lib/softoken/pkcs11c.c
PORT_Memset(crsrdata, 0, sizeof crsrdata);
crv = CKR_HOST_MEMORY;
break;
@@ -7957,6 +7967,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
@@ -8070,6 +8091,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
PORT_Assert(i <= sizeof key_block);
}
@ -499,7 +561,40 @@ Index: nss/lib/softoken/fips_algorithms.h
===================================================================
--- nss.orig/lib/softoken/fips_algorithms.h
+++ nss/lib/softoken/fips_algorithms.h
@@ -58,18 +58,35 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
@@ -14,7 +14,12 @@ typedef enum {
SFTKFIPSDH, /* allow only specific primes */
SFTKFIPSECC, /* not just keys but specific curves */
SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
- SFTKFIPSRSAPSS
+ SFTKFIPSRSAPSS, /* make sure salt isn't too big */
+ SFTKFIPSPBKDF2, /* handle pbkdf2 FIPS restrictions */
+ SFTKFIPSTlsKeyCheck, /* check the output of TLS prf functions */
+ SFTKFIPSChkHash, /* make sure the base hash of KDF functions is FIPS */
+ SFTKFIPSChkHashTls, /* make sure the base hash of TLS KDF functions is FIPS */
+ SFTKFIPSChkHashSp800, /* make sure the base hash of SP-800-108 KDF functions is FIPS */
} SFTKFIPSSpecialClass;
typedef struct SFTKFIPSAlgorithmListStr SFTKFIPSAlgorithmList;
@@ -23,6 +28,7 @@ struct SFTKFIPSAlgorithmListStr {
CK_MECHANISM_INFO info;
CK_ULONG step;
SFTKFIPSSpecialClass special;
+ size_t offset;
};
SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
@@ -46,7 +52,9 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
#define CKF_KPG CKF_GENERATE_KEY_PAIR
#define CKF_GEN CKF_GENERATE
#define CKF_SGN (CKF_SIGN | CKF_VERIFY)
-#define CKF_ENC (CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP)
+#define CKF_ENC (CKF_ENCRYPT | CKF_DECRYPT )
+#define CKF_ECW (CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP)
+#define CKF_WRP (CKF_WRAP | CKF_UNWRAP)
#define CKF_KEK (CKF_WRAP | CKF_UNWRAP)
#define CKF_KEA CKF_DERIVE
#define CKF_KDF CKF_DERIVE
@@ -58,18 +66,38 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
#define RSA_FB_STEP 1
#define RSA_LEGACY_FB_KEY 1024, 1792 /* min, max */
#define RSA_LEGACY_FB_STEP 256
@ -522,6 +617,8 @@ Index: nss/lib/softoken/fips_algorithms.h
{ CKM_RSA_PKCS_PSS, { RSA_LEGACY_FB_KEY, CKF_VERIFY }, RSA_LEGACY_FB_STEP, SFTKFIPSRSAPSS },
+#endif
+
+#if 0
+ /* Not used anywhere - bsc#1224116 */
+ { CKM_SHA_1_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
+ { CKM_SHA224_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
+ { CKM_SHA256_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
@ -534,11 +631,12 @@ Index: nss/lib/softoken/fips_algorithms.h
+ { CKM_SHA3_256_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
+ { CKM_SHA3_384_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
+ { CKM_SHA3_512_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
+
+#endif
+
/* -------------- 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 },
@@ -88,13 +105,12 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
@@ -88,21 +116,33 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
{ 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 },
/* ------------------------- DSA Operations --------------------------- */
@ -550,18 +648,28 @@ Index: nss/lib/softoken/fips_algorithms.h
- { CKM_DSA_SHA384, { DSA_FB_KEY, CKF_SGN }, DSA_FB_STEP, SFTKFIPSNone },
- { CKM_DSA_SHA512, { DSA_FB_KEY, CKF_SGN }, DSA_FB_STEP, SFTKFIPSNone },
+
+#if 0
+ /* Non-approved: FIPS 186-5 - bsc#1222804 */
+ { CKM_DSA_SHA224, { DSA_FB_KEY, CKF_VERIFY }, DSA_FB_STEP, SFTKFIPSNone },
+ { CKM_DSA_SHA256, { DSA_FB_KEY, CKF_VERIFY }, DSA_FB_STEP, SFTKFIPSNone },
+ { CKM_DSA_SHA384, { DSA_FB_KEY, CKF_VERIFY }, DSA_FB_STEP, SFTKFIPSNone },
+ { CKM_DSA_SHA512, { DSA_FB_KEY, CKF_VERIFY }, DSA_FB_STEP, SFTKFIPSNone },
+#endif
+
/* -------------------- Diffie Hellman Operations --------------------- */
/* no diffie hellman yet */
{ CKM_DH_PKCS_KEY_PAIR_GEN, { DH_FB_KEY, CKF_KPG }, DH_FB_STEP, SFTKFIPSDH },
@@ -102,7 +118,10 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
{ CKM_DH_PKCS_DERIVE, { DH_FB_KEY, CKF_KEA }, DH_FB_STEP, SFTKFIPSDH },
/* -------------------- Elliptic Curve Operations --------------------- */
{ CKM_EC_KEY_PAIR_GEN, { EC_FB_KEY, CKF_KPG }, EC_FB_STEP, SFTKFIPSECC },
+
+ /* Only approved with cofactor=1; our approved curves satisfy this.
+ * See lib/freebl/ecl-ecl-curve.h - bsc#1224113 */
{ CKM_ECDH1_DERIVE, { EC_FB_KEY, CKF_KEA }, EC_FB_STEP, SFTKFIPSECC },
+
+ /* Approved; equivalent to CKM_ECDH1_DERIVE in our circumstances - bsc#1224113 */
+ { CKM_ECDH1_COFACTOR_DERIVE, { EC_FB_KEY, CKF_KEA }, EC_FB_STEP, SFTKFIPSECC },
+
+#if 0
+ /* Doesn't consider hash algo. Non-approved */
{ CKM_ECDSA, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
@ -569,7 +677,7 @@ Index: nss/lib/softoken/fips_algorithms.h
{ CKM_ECDSA_SHA224, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
{ CKM_ECDSA_SHA256, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
{ CKM_ECDSA_SHA384, { EC_FB_KEY, CKF_SGN }, EC_FB_STEP, SFTKFIPSECC },
@@ -112,8 +131,11 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
@@ -112,19 +152,30 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
{ 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 },
@ -581,10 +689,21 @@ Index: nss/lib/softoken/fips_algorithms.h
{ 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 },
@@ -123,8 +145,11 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
{ 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_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_GCM, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSAEAD },
+ { CKM_AES_KEY_WRAP, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
+ { CKM_AES_KEY_WRAP_PAD, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
+
+ /* Aliases for above (without _NSS_) - bsc#1224115 */
+ { 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_AES_KEY_WRAP_KWP, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
+#if 0
+ /* Not approved in FIPS mode */
{ CKM_AES_XCBC_MAC_96, { 96, 96, CKF_SGN }, 1, SFTKFIPSNone },
@ -593,40 +712,56 @@ Index: nss/lib/softoken/fips_algorithms.h
/* ------------------------- Hashing Operations ----------------------- */
{ CKM_SHA224, { 0, 0, CKF_HSH }, 1, SFTKFIPSNone },
{ CKM_SHA224_HMAC, { 112, 224, CKF_SGN }, 1, SFTKFIPSNone },
@@ -139,41 +164,56 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
@@ -139,44 +190,86 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[]
{ CKM_SHA512_HMAC, { 256, 512, CKF_SGN }, 1, SFTKFIPSNone },
{ CKM_SHA512_HMAC_GENERAL, { 256, 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, 512, CKF_GEN }, 1, SFTKFIPSNone },
/* ---------------------- SSL/TLS operations ------------------------- */
+#if 0
+ /* Non-approved: SP 800-1400 - bsc#1222833 */
{ 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, 384, CKF_KDF }, 1, SFTKFIPSNone },
{ CKM_SHA512_KEY_DERIVATION, { 256, 512, CKF_KDF }, 1, SFTKFIPSNone },
+#endif
+#if 0
+ /* Non-approved: bsc#1222826 */
{ 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 },
+#endif
+ { CKM_TLS12_MASTER_KEY_DERIVE_DH, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
{ CKM_TLS12_KEY_AND_MAC_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_TLS12_KEY_AND_MAC_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSTlsKeyCheck,
+ offsetof(CK_TLS12_KEY_MAT_PARAMS, prfHashMechanism) },
{ CKM_TLS_PRF_GENERAL, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone },
- { CKM_TLS_MAC, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone },
+ { CKM_TLS_MAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSNone },
+ { CKM_TLS_MAC, { 112, 512, CKF_SGN }, 1, SFTKFIPSChkHashTls,
+ offsetof(CK_TLS_MAC_PARAMS, prfHashMechanism) },
+
+ { CKM_NSS_TLS_PRF_GENERAL_SHA256, { 8, 512, CKF_SGN }, 1, SFTKFIPSNone },
+#if 0
+ /* Non-approved: bsc#1222826 */
+ { CKM_TLS_MASTER_KEY_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256, { 128, 384, CKF_KDF }, 1, SFTKFIPSNone },
+#endif
+ { CKM_TLS_MASTER_KEY_DERIVE_DH, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_TLS_KEY_AND_MAC_DERIVE, { 384, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256, { 128, 384, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256, { 128, 384, CKF_KDF }, 1, SFTKFIPSTlsKeyCheck },
+
+ { CKM_SSL3_PRE_MASTER_KEY_GEN, { 128, 512, CKF_GEN }, 1, SFTKFIPSNone },
+ { CKM_TLS_PRE_MASTER_KEY_GEN, { 128, 512, CKF_GEN }, 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 },
- { 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 },
+ { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, { 192, 1024, CKF_KDF }, 1, SFTKFIPSChkHashTls,
+ offsetof(CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS, prfHashMechanism) },
+ { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH, { 192, 1024, CKF_DERIVE }, 1, SFTKFIPSChkHashTls,
+ offsetof(CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS, prfHashMechanism) },
/* ------------------------- HKDF Operations -------------------------- */
+#if 0
@ -643,32 +778,49 @@ Index: nss/lib/softoken/fips_algorithms.h
- { 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 },
+ { CKM_SP800_108_COUNTER_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
+ offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
+ { CKM_SP800_108_FEEDBACK_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
+ offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
+ { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
+ offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
+ { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
+ offsetof(CK_SP800_108_KDF_PARAMS, prfType) },
+ { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 112, CK_MAX, CKF_KDF }, 1, SFTKFIPSChkHashSp800,
+ 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) },
/* --------------------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, 112, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_IKE1_PRF_DERIVE, { 112, 112, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSNone },
+ { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSChkHash,
+ offsetof(CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS, prfMechanism) },
+ { CKM_NSS_IKE_PRF_DERIVE, { 112, 112, CKF_KDF }, 1, SFTKFIPSChkHash,
+ offsetof(CK_NSS_IKE_PRF_DERIVE_PARAMS, prfMechanism) },
+ { CKM_NSS_IKE1_PRF_DERIVE, { 112, 112, CKF_KDF }, 1, SFTKFIPSChkHash,
+ offsetof(CK_NSS_IKE1_PRF_DERIVE_PARAMS, prfMechanism) },
+ { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 112, 255 * 64, CKF_KDF }, 1, SFTKFIPSChkHash,
+ offsetof(CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS, prfMechanism) },
/* ------------------ PBE Key Derivations ------------------- */
- { CKM_PKCS5_PBKD2, { 1, 256, CKF_GEN }, 1, SFTKFIPSNone },
+ { CKM_PKCS5_PBKD2, { 112, 256, CKF_GEN }, 1, SFTKFIPSNone },
+
+#if 0
+ /* Non-approved: SP 800-1400 - bsc#1222833 */
{ 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 }
+#endif
};
const int SFTK_NUMBER_FIPS_ALGORITHMS = PR_ARRAY_SIZE(sftk_fips_mechs);
Index: nss/lib/softoken/pkcs11u.c
===================================================================
--- nss.orig/lib/softoken/pkcs11u.c
+++ nss/lib/softoken/pkcs11u.c
@@ -2242,6 +2242,12 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
@@ -2248,6 +2248,12 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
case CKA_NSS_MESSAGE | CKA_VERIFY:
flags = CKF_MESSAGE_VERIFY;
break;
@ -681,7 +833,157 @@ Index: nss/lib/softoken/pkcs11u.c
default:
break;
}
@@ -2462,18 +2468,35 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
@@ -2324,7 +2330,7 @@ sftk_quickGetECCCurveOid(SFTKObject *sou
static int
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;
@@ -2386,14 +2392,55 @@ sftk_getKeyLength(SFTKObject *source)
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;
@@ -2409,10 +2456,27 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
}
case SFTKFIPSNone:
return PR_FALSE;
- case SFTKFIPSECC:
+ case SFTKFIPSECC: {
+ if (mech->mechanism == CKM_ECDH1_DERIVE
+ || mech->mechanism == CKM_ECDH1_COFACTOR_DERIVE)
+ {
+ CK_ECDH1_DERIVE_PARAMS *mechParams;
+
+ /* Check mechanism parameters */
+ mechParams = (CK_ECDH1_DERIVE_PARAMS *) mech->pParameter;
+
+ /* A non-NULL KDF corresponds to use of ECDH ANSI X9.63,
+ * but full CAVP testing of this implementation is impossible.
+ * For this reason, it is not FIPS approved. See pkcs11c.c:NSC_DeriveKey()
+ * lines ~ 8747-8770. bsc#1224118 */
+ if (mechParams->kdf != CKD_NULL)
+ return PR_FALSE;
+ }
+
/* we've already handled the curve selection in the 'getlength'
- * function */
+ * function */
return PR_TRUE;
+ }
case SFTKFIPSAEAD: {
if (mech->ulParameterLen == 0) {
/* AEAD ciphers are only in FIPS mode if we are using the
@@ -2440,11 +2504,44 @@ 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;
}
+ /* 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;
}
+ /* 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 mechanism 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;
}
@@ -2455,7 +2552,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;
@@ -2468,18 +2565,35 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
if (!sftk_isFIPS(slot->slotID)) {
return PR_FALSE;
}
@ -721,6 +1023,28 @@ Index: nss/lib/softoken/pkcs11u.c
keyLength = sftk_getKeyLength(source);
/* check against our algorithm array */
@@ -2487,13 +2601,15 @@ 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)) &&
+ 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))) {
+ sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
return PR_TRUE;
}
}
Index: nss/lib/util/pkcs11t.h
===================================================================
--- nss.orig/lib/util/pkcs11t.h
@ -737,7 +1061,7 @@ Index: nss/lib/softoken/pkcs11.c
===================================================================
--- nss.orig/lib/softoken/pkcs11.c
+++ nss/lib/softoken/pkcs11.c
@@ -570,17 +570,17 @@ static const struct mechanismList mechan
@@ -573,17 +573,17 @@ static const struct mechanismList mechan
{ CKM_TLS_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
{ CKM_TLS12_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
{ CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256,
@ -760,3 +1084,17 @@ Index: nss/lib/softoken/pkcs11.c
PR_FALSE },
{ CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
{ 48, 128, CKF_DERIVE },
Index: nss/lib/softoken/pkcs11i.h
===================================================================
--- nss.orig/lib/softoken/pkcs11i.h
+++ nss/lib/softoken/pkcs11i.h
@@ -968,7 +968,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);

View File

@ -2,7 +2,7 @@ Index: nss/lib/pk11wrap/pk11skey.c
===================================================================
--- nss.orig/lib/pk11wrap/pk11skey.c
+++ nss/lib/pk11wrap/pk11skey.c
@@ -520,6 +520,14 @@ PK11_ImportDataKey(PK11SlotInfo *slot, C
@@ -521,6 +521,14 @@ PK11_ImportDataKey(PK11SlotInfo *slot, C
CK_OBJECT_HANDLE handle;
PK11GenericObject *genObject;

View File

@ -68,16 +68,7 @@ Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -2677,7 +2677,7 @@ nsc_DSA_Verify_Stub(void *ctx, void *sig
static SECStatus
nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
- void *dataBuf, unsigned int dataLen)
+ const void *dataBuf, unsigned int dataLen)
{
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
@@ -2690,6 +2690,22 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBu
@@ -2744,6 +2744,38 @@ nsc_EDDSASignStub(void *ctx, void *sigBu
return rv;
}
@ -97,22 +88,6 @@ Index: nss/lib/softoken/pkcs11c.c
+ return rv;
+}
+
static SECStatus
nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
void *dataBuf, unsigned int dataLen)
@@ -2703,7 +2719,7 @@ nsc_ECDSAVerifyStub(void *ctx, void *sig
static SECStatus
nsc_ECDSASignStub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
- void *dataBuf, unsigned int dataLen)
+ const void *dataBuf, unsigned int dataLen)
{
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
@@ -2744,6 +2760,22 @@ nsc_EDDSASignStub(void *ctx, void *sigBu
return rv;
}
+SECStatus
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
@ -155,7 +130,7 @@ Index: nss/lib/softoken/pkcs11c.c
switch (pMechanism->mechanism) {
INIT_RSA_VFY_MECH(MD5)
INIT_RSA_VFY_MECH(MD2)
@@ -4904,6 +4952,73 @@ loser:
@@ -4905,6 +4953,73 @@ loser:
#define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
@ -229,7 +204,7 @@ Index: nss/lib/softoken/pkcs11c.c
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
*
@@ -4957,8 +5072,6 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
@@ -4958,8 +5073,6 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
/* Variables used for Signature/Verification functions. */
/* Must be at least 256 bits for DSA2 digest */
@ -238,7 +213,7 @@ Index: nss/lib/softoken/pkcs11c.c
CK_ULONG signature_length;
if (keyType == CKK_RSA) {
@@ -5112,80 +5225,36 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
@@ -5113,80 +5226,36 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
}
}

View File

@ -449,7 +449,7 @@ Index: nss/lib/freebl/fips.h
===================================================================
--- /dev/null
+++ nss/lib/freebl/fips.h
@@ -0,0 +1,16 @@
@@ -0,0 +1,15 @@
+/*
+ * PKCS #11 FIPS Power-Up Self Test.
+ *
@ -462,7 +462,6 @@ Index: nss/lib/freebl/fips.h
+
+int FIPS_mode(void);
+int FIPS_mode_allow_tests(void);
+char* FIPS_rngDev(void);
+
+#endif
+
@ -484,7 +483,94 @@ Index: nss/lib/freebl/fipsfreebl.c
/*
* different platforms have different ways of calling and initial entry point
* when the dll/.so is loaded. Most platforms support either a posix pragma
@@ -1807,17 +1814,19 @@ freebl_fips_RNG_PowerUpSelfTest(void)
@@ -1663,38 +1670,39 @@ freebl_fips_DH_PowerUpSelfTest(void)
{
/* DH Known P (2048-bits) */
static const PRUint8 dh_known_P[] = {
- 0xc2, 0x79, 0xbb, 0x76, 0x32, 0x0d, 0x43, 0xfd,
- 0x1b, 0x8c, 0xa2, 0x3c, 0x00, 0xdd, 0x6d, 0xef,
- 0xf8, 0x1a, 0xd9, 0xc1, 0xa2, 0xf5, 0x73, 0x2b,
- 0xdb, 0x1a, 0x3e, 0x84, 0x90, 0xeb, 0xe7, 0x8e,
- 0x5f, 0x5c, 0x6b, 0xb6, 0x61, 0x89, 0xd1, 0x03,
- 0xb0, 0x5f, 0x91, 0xe4, 0xd2, 0x82, 0x90, 0xfc,
- 0x3c, 0x49, 0x69, 0x59, 0xc1, 0x51, 0x6a, 0x85,
- 0x71, 0xe7, 0x5d, 0x72, 0x5a, 0x45, 0xad, 0x01,
- 0x6f, 0x82, 0xae, 0xec, 0x91, 0x08, 0x2e, 0x7c,
- 0x64, 0x93, 0x46, 0x1c, 0x68, 0xef, 0xc2, 0x03,
- 0x28, 0x1d, 0x75, 0x3a, 0xeb, 0x9c, 0x46, 0xf0,
- 0xc9, 0xdb, 0x99, 0x95, 0x13, 0x66, 0x4d, 0xd5,
- 0x1a, 0x78, 0x92, 0x51, 0x89, 0x72, 0x28, 0x7f,
- 0x20, 0x70, 0x41, 0x49, 0xa2, 0x86, 0xe9, 0xf9,
- 0x78, 0x5f, 0x8d, 0x2e, 0x5d, 0xfa, 0xdb, 0x57,
- 0xd4, 0x71, 0xdf, 0x66, 0xe3, 0x9e, 0x88, 0x70,
- 0xa4, 0x21, 0x44, 0x6a, 0xc7, 0xae, 0x30, 0x2c,
- 0x9c, 0x1f, 0x91, 0x57, 0xc8, 0x24, 0x34, 0x2d,
- 0x7a, 0x4a, 0x43, 0xc2, 0x5f, 0xab, 0x64, 0x2e,
- 0xaa, 0x28, 0x32, 0x95, 0x42, 0x7b, 0xa0, 0xcc,
- 0xdf, 0xfd, 0x22, 0xc8, 0x56, 0x84, 0xc1, 0x62,
- 0x15, 0xb2, 0x77, 0x86, 0x81, 0xfc, 0xa5, 0x12,
- 0x3c, 0xca, 0x28, 0x17, 0x8f, 0x03, 0x16, 0x6e,
- 0xb8, 0x24, 0xfa, 0x1b, 0x15, 0x02, 0xfd, 0x8b,
- 0xb6, 0x0a, 0x1a, 0xf7, 0x47, 0x41, 0xc5, 0x2b,
- 0x37, 0x3e, 0xa1, 0xbf, 0x68, 0xda, 0x1c, 0x55,
- 0x44, 0xc3, 0xee, 0xa1, 0x63, 0x07, 0x11, 0x3b,
- 0x5f, 0x00, 0x84, 0xb4, 0xc4, 0xe4, 0xa7, 0x97,
- 0x29, 0xf8, 0xce, 0xab, 0xfc, 0x27, 0x3e, 0x34,
- 0xe4, 0xc7, 0x81, 0x52, 0x32, 0x0e, 0x27, 0x3c,
- 0xa6, 0x70, 0x3f, 0x4a, 0x54, 0xda, 0xdd, 0x60,
- 0x26, 0xb3, 0x6e, 0x45, 0x26, 0x19, 0x41, 0x6f
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
};
static const PRUint8 dh_known_Y_1[] = {
@@ -1740,10 +1748,10 @@ freebl_fips_DH_PowerUpSelfTest(void)
};
static const PRUint8 dh_known_hash_result[] = {
- 0x93, 0xa2, 0x89, 0x1c, 0x8a, 0xc3, 0x70, 0xbf,
- 0xa7, 0xdf, 0xb6, 0xd7, 0x82, 0xfb, 0x87, 0x81,
- 0x09, 0x47, 0xf3, 0x9f, 0x5a, 0xbf, 0x4f, 0x3f,
- 0x8e, 0x5e, 0x06, 0xca, 0x30, 0xa7, 0xaf, 0x10
+ 0x40, 0xe3, 0x7a, 0x34, 0x83, 0x2d, 0x94, 0x57,
+ 0x99, 0x3d, 0x66, 0xec, 0x54, 0xdf, 0x82, 0x4a,
+ 0x37, 0x0d, 0xf9, 0x01, 0xb3, 0xbc, 0x54, 0xe5,
+ 0x5e, 0x63, 0xd3, 0x46, 0x4e, 0xa3, 0xe2, 0x8a
};
/* DH variables. */
@@ -1807,17 +1815,19 @@ freebl_fips_RNG_PowerUpSelfTest(void)
return (SECSuccess);
}
@ -505,7 +591,7 @@ Index: nss/lib/freebl/fipsfreebl.c
#define DO_FREEBL 1
#define DO_REST 2
@@ -1929,11 +1938,13 @@ static PRBool self_tests_ran = PR_FALSE;
@@ -1929,11 +1939,13 @@ static PRBool self_tests_ran = PR_FALSE;
static PRBool self_tests_freebl_success = PR_FALSE;
static PRBool self_tests_success = PR_FALSE;
@ -520,7 +606,7 @@ Index: nss/lib/freebl/fipsfreebl.c
{
SECStatus rv;
/* if the freebl self tests didn't run, there is something wrong with
@@ -1946,7 +1957,7 @@ BL_POSTRan(PRBool freebl_only)
@@ -1946,7 +1958,7 @@ BL_POSTRan(PRBool freebl_only)
return PR_TRUE;
}
/* if we only care about the freebl tests, we are good */
@ -529,7 +615,7 @@ Index: nss/lib/freebl/fipsfreebl.c
return PR_TRUE;
}
/* run the rest of the self tests */
@@ -1965,32 +1976,16 @@ BL_POSTRan(PRBool freebl_only)
@@ -1965,32 +1977,16 @@ BL_POSTRan(PRBool freebl_only)
return PR_TRUE;
}
@ -567,7 +653,7 @@ Index: nss/lib/freebl/fipsfreebl.c
self_tests_freebl_ran = PR_TRUE; /* we are running the tests */
if (!freebl_only) {
@@ -2002,20 +1997,55 @@ bl_startup_tests(void)
@@ -2002,20 +1998,55 @@ bl_startup_tests(void)
/* always run the post tests */
rv = freebl_fipsPowerUpSelfTest(freebl_only ? DO_FREEBL : DO_FREEBL | DO_REST);
if (rv != SECSuccess) {
@ -625,7 +711,7 @@ Index: nss/lib/freebl/fipsfreebl.c
}
/*
@@ -2024,19 +2054,12 @@ bl_startup_tests(void)
@@ -2024,19 +2055,12 @@ bl_startup_tests(void)
* power on selftest failed.
*/
SECStatus
@ -647,7 +733,7 @@ Index: nss/lib/freebl/fipsfreebl.c
if (rerun) {
/* reset the flags */
self_tests_freebl_ran = PR_FALSE;
@@ -2050,10 +2073,104 @@ BL_FIPSEntryOK(PRBool freebl_only, PRBoo
@@ -2050,10 +2074,89 @@ BL_FIPSEntryOK(PRBool freebl_only, PRBoo
return SECSuccess;
}
/* standalone freebl can initialize */
@ -707,21 +793,6 @@ Index: nss/lib/freebl/fipsfreebl.c
+ return fips;
+}
+
+/* returns string specifying what system RNG file to use for seeding */
+char *
+FIPS_rngDev(void)
+{
+ switch (FIPS_mode()) {
+ case 0:
+ return RNG_DEV_FIPS0;
+ case 1:
+ return RNG_DEV_FIPS1;
+ default:
+ fatal("Fatal error: internal error at %s:%u"
+ , __FILE__, __LINE__);
+ }
+}
+
+/* either returns the input or aborts if in FIPS and the algorithm is not
+ * approved */
+PRBool
@ -861,7 +932,7 @@ Index: nss/lib/freebl/manifest.mn
$(NULL)
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
@@ -198,6 +199,7 @@ ALL_HDRS = \
@@ -194,6 +195,7 @@ ALL_HDRS = \
shsign.h \
vis_proto.h \
seed.h \
@ -1110,7 +1181,7 @@ Index: nss/lib/softoken/fipstest.c
===================================================================
--- nss.orig/lib/softoken/fipstest.c
+++ nss/lib/softoken/fipstest.c
@@ -683,6 +683,327 @@ sftk_fips_HKDF_PowerUpSelfTest(void)
@@ -683,6 +683,175 @@ sftk_fips_HKDF_PowerUpSelfTest(void)
return (SECSuccess);
}
@ -1282,163 +1353,11 @@ Index: nss/lib/softoken/fipstest.c
+
+ return (SECSuccess);
+}
+
+#define FIPS_ECDSA_DIGEST_LENGTH 28 /* 224-bits */
+#define FIPS_ECDSA_SIGNATURE_LENGTH 64 /* 512-bits */
+
+/* Similar to freebl_fips_ECDSA_PowerUpSelfTest, but using ECDSA_HashSign() */
+static SECStatus
+sftk_fips_ECDSA_PowerUpSelfTest(void)
+{
+ /* EC Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
+ static const unsigned char p256_prime[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+ static const unsigned char p256_a[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC
+ };
+ static const unsigned char p256_b[] = {
+ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76,
+ 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE,
+ 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
+ };
+ static const unsigned char p256_base[] = {
+ 0x04,
+ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63,
+ 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1,
+ 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
+ 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C,
+ 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6,
+ 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5
+ };
+ static const unsigned char p256_order[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9,
+ 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+ };
+ static const unsigned char p256_encoding[] = {
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
+ };
+ static ECParams ec_known_P256_Params = {
+ NULL, ec_params_named, /* arena, type */
+ /* fieldID */
+ { 256, ec_field_plain, /* size and type */
+ { { siBuffer, (unsigned char *)p256_prime, sizeof(p256_prime) } }, /* u.prime */
+ 0,
+ 0,
+ 0 },
+ /* curve */
+ { /* a = curvea b = curveb */
+ /* curve.a */
+ { siBuffer, (unsigned char *)p256_a, sizeof(p256_a) },
+ /* curve.b */
+ { siBuffer, (unsigned char *)p256_b, sizeof(p256_b) },
+ /* curve.seed */
+ { siBuffer, NULL, 0 } },
+ /* base = 04xy*/
+ { siBuffer, (unsigned char *)p256_base, sizeof(p256_base) },
+ /* order */
+ { siBuffer, (unsigned char *)p256_order, sizeof(p256_order) },
+ 1, /* cofactor */
+ /* DEREncoding */
+ { siBuffer, (unsigned char *)p256_encoding, sizeof(p256_encoding) },
+ ECCurve_X9_62_PRIME_256V1,
+ /* curveOID */
+ { siBuffer, (unsigned char *)(p256_encoding) + 2, sizeof(p256_encoding) - 2 },
+ };
+ /* ECDSA Known Seed info for curves nistp256 and nistk283 */
+ static const PRUint8 ecdsa_Known_Seed[] = {
+ 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11,
+ 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1,
+ 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc,
+ 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f
+ };
+ /* ECDSA Known Digest (224-bits) */
+ static const PRUint8 ecdsa_known_digest[] = { "ECDSA Signature Digest, Longer" };
+ /* ECDSA variables. */
+ ECPrivateKey *ecdsa_private_key;
+ SECStatus ecdsa_status;
+ SECItem ecdsa_signature_item;
+ SECItem ecdsa_digest_item;
+ ECPublicKey ecdsa_public_key;
+ PRUint8 ecdsa_computed_signature[2 * MAX_ECKEY_LEN];
+ NSSLOWKEYPrivateKey lowkey_priv;
+
+ /*********************************************/
+ /* Generate an ECDSA public/private key pair */
+ /*********************************************/
+
+ ecdsa_status = EC_NewKeyFromSeed(&ec_known_P256_Params,
+ &ecdsa_private_key,
+ ecdsa_Known_Seed,
+ sizeof (ecdsa_Known_Seed));
+
+ if (ecdsa_status != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ /* Construct public key from private key. */
+ ecdsa_public_key.ecParams = ecdsa_private_key->ecParams;
+ ecdsa_public_key.publicValue = ecdsa_private_key->publicValue;
+
+ /* Validate public key value. */
+ ecdsa_status = EC_ValidatePublicKey(&ecdsa_public_key.ecParams,
+ &ecdsa_public_key.publicValue);
+ if (ecdsa_status != SECSuccess) {
+ goto loser;
+ }
+
+ /***********************************/
+ /* ECDSA pairwise consistency test */
+ /***********************************/
+
+ ecdsa_signature_item.data = ecdsa_computed_signature;
+ ecdsa_signature_item.len = sizeof ecdsa_computed_signature;
+
+ ecdsa_digest_item.data = (unsigned char *)ecdsa_known_digest;
+ ecdsa_digest_item.len = SHA224_LENGTH;
+
+ /* Perform ECDSA signature process. */
+ lowkey_priv.u.ec = *ecdsa_private_key;
+ ecdsa_status = ECDSA_HashSign (SEC_OID_SHA224, &lowkey_priv,
+ ecdsa_signature_item.data, &ecdsa_signature_item.len,
+ sizeof ecdsa_computed_signature,
+ ecdsa_digest_item.data, SHA224_LENGTH);
+
+ /* Check that operation succeeded and that signature is different from hash */
+ if ((ecdsa_status != SECSuccess) ||
+ (ecdsa_signature_item.len != FIPS_ECDSA_SIGNATURE_LENGTH) ||
+ (PORT_Memcmp(ecdsa_computed_signature, ecdsa_known_digest,
+ PR_MIN (FIPS_ECDSA_SIGNATURE_LENGTH, FIPS_ECDSA_DIGEST_LENGTH)) == 0)) {
+ ecdsa_status = SECFailure;
+ } else {
+ /* Perform ECDSA verification process. */
+ ecdsa_status = ECDSA_VerifyDigest(&ecdsa_public_key,
+ &ecdsa_signature_item,
+ &ecdsa_digest_item);
+ }
+
+loser:
+ /* Free the memory for the private key arena */
+ PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE);
+
+ if (ecdsa_status != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ return (SECSuccess);
+}
+
static PRBool sftk_self_tests_ran = PR_FALSE;
static PRBool sftk_self_tests_success = PR_FALSE;
@@ -694,7 +1015,6 @@ void
@@ -694,7 +863,6 @@ void
sftk_startup_tests_with_rerun(PRBool rerun)
{
SECStatus rv;
@ -1446,7 +1365,7 @@ Index: nss/lib/softoken/fipstest.c
PORT_Assert(!sftk_self_tests_ran);
PORT_Assert(!sftk_self_tests_success);
@@ -706,6 +1026,7 @@ sftk_startup_tests_with_rerun(PRBool rer
@@ -706,6 +874,7 @@ sftk_startup_tests_with_rerun(PRBool rer
if (rv != SECSuccess) {
return;
}
@ -1454,7 +1373,7 @@ Index: nss/lib/softoken/fipstest.c
/* make sure freebl is initialized, or our RSA check
* may fail. This is normally done at freebl load time, but it's
* possible we may have shut freebl down without unloading it. */
@@ -723,12 +1044,21 @@ sftk_startup_tests_with_rerun(PRBool rer
@@ -723,12 +892,15 @@ sftk_startup_tests_with_rerun(PRBool rer
if (rv != SECSuccess) {
return;
}
@ -1469,18 +1388,12 @@ Index: nss/lib/softoken/fipstest.c
return;
}
+
+ /* check the ECDSA combined functions in softoken */
+ rv = sftk_fips_ECDSA_PowerUpSelfTest();
+ if (rv != SECSuccess) {
+ return;
+ }
+
+ /* Checksum is done by fips_initTestSoftoken() in fips.c */
+
rv = sftk_fips_IKE_PowerUpSelfTests();
if (rv != SECSuccess) {
return;
@@ -766,17 +1096,10 @@ sftk_startup_tests(void)
@@ -766,17 +938,10 @@ sftk_startup_tests(void)
CK_RV
sftk_FIPSEntryOK(PRBool rerun)
{
@ -1499,7 +1412,7 @@ Index: nss/lib/softoken/fipstest.c
if (rerun) {
sftk_self_tests_ran = PR_FALSE;
sftk_self_tests_success = PR_FALSE;
@@ -787,6 +1110,17 @@ sftk_FIPSEntryOK(PRBool rerun)
@@ -787,6 +952,17 @@ sftk_FIPSEntryOK(PRBool rerun)
}
return CKR_OK;
}
@ -1632,7 +1545,7 @@ Index: nss/lib/freebl/ldvector.c
ED_VerifyMessage,
ED_DerivePublicKey,
/* End of version 3.028 */
+
+
+ /* SUSE patch: Goes last */
+ BL_FIPSRepeatIntegrityCheck
};

View File

@ -14,7 +14,7 @@ Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -4843,8 +4843,8 @@ loser:
@@ -4897,8 +4897,8 @@ loser:
return crv;
}
@ -25,7 +25,7 @@ Index: nss/lib/softoken/pkcs11c.c
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
@@ -5847,6 +5847,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
@@ -5960,6 +5960,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
(PRUint32)crv);
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
}

View File

@ -2,7 +2,7 @@ Index: nss/lib/softoken/lowpbe.c
===================================================================
--- nss.orig/lib/softoken/lowpbe.c
+++ nss/lib/softoken/lowpbe.c
@@ -1756,7 +1756,7 @@ loser:
@@ -1755,7 +1755,7 @@ loser:
return ret_algid;
}
@ -11,7 +11,7 @@ Index: nss/lib/softoken/lowpbe.c
SECStatus
sftk_fips_pbkdf_PowerUpSelfTests(void)
{
@@ -1766,16 +1766,22 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
@@ -1765,16 +1765,22 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
unsigned char iteration_count = 5;
unsigned char keyLen = 64;
char *inKeyData = TEST_KEY;
@ -43,7 +43,7 @@ Index: nss/lib/softoken/lowpbe.c
};
sftk_PBELockInit();
@@ -1804,11 +1810,12 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
@@ -1803,11 +1809,12 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
* for NSSPKCS5_PBKDF2 */
pbe_params.iter = iteration_count;
pbe_params.keyLen = keyLen;

View File

@ -5,15 +5,7 @@ Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -20,6 +20,7 @@
#include <limits.h> /* for UINT_MAX and ULONG_MAX */
+#include "lowkeyti.h"
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
@@ -4965,6 +4966,88 @@ pairwise_signverify_mech (CK_SESSION_HAN
@@ -5020,6 +5020,88 @@ pairwise_signverify_mech (CK_SESSION_HAN
return crv;
}
@ -102,7 +94,7 @@ Index: nss/lib/softoken/pkcs11c.c
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
*
@@ -5311,6 +5394,30 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
@@ -5370,6 +5452,30 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
}
}

View File

@ -65,7 +65,7 @@ Index: nss/lib/freebl/rsa.c
/* The minimal required randomness is 64 bits */
/* EXP_BLINDING_RANDOMNESS_LEN is the length of the randomness in mp_digits */
@@ -149,11 +151,24 @@ rsa_build_from_primes(const mp_int *p, c
@@ -151,11 +153,24 @@ rsa_build_from_primes(const mp_int *p, c
err = mp_invmod(d, &phi, e);
} else {
err = mp_invmod(e, &phi, d);
@ -92,7 +92,7 @@ Index: nss/lib/freebl/rsa.c
if (err != MP_OKAY) {
if (err == MP_UNDEF) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
@@ -286,10 +301,12 @@ RSA_NewKey(int keySizeInBits, SECItem *p
@@ -288,10 +303,12 @@ RSA_NewKey(int keySizeInBits, SECItem *p
mp_int q = { 0, 0, 0, NULL };
mp_int e = { 0, 0, 0, NULL };
mp_int d = { 0, 0, 0, NULL };
@ -106,7 +106,7 @@ Index: nss/lib/freebl/rsa.c
int prerr = 0;
RSAPrivateKey *key = NULL;
PLArenaPool *arena = NULL;
@@ -307,11 +324,40 @@ RSA_NewKey(int keySizeInBits, SECItem *p
@@ -309,11 +326,40 @@ RSA_NewKey(int keySizeInBits, SECItem *p
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
@ -151,7 +151,7 @@ Index: nss/lib/freebl/rsa.c
}
#endif
@@ -329,12 +375,7 @@ RSA_NewKey(int keySizeInBits, SECItem *p
@@ -331,12 +377,7 @@ RSA_NewKey(int keySizeInBits, SECItem *p
key->arena = arena;
/* length of primes p and q (in bytes) */
primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE);
@ -165,7 +165,7 @@ Index: nss/lib/freebl/rsa.c
/* 3. Set the version number (PKCS1 v1.5 says it should be zero) */
SECITEM_AllocItem(arena, &key->version, 1);
key->version.data[0] = 0;
@@ -345,13 +386,64 @@ RSA_NewKey(int keySizeInBits, SECItem *p
@@ -347,13 +388,64 @@ RSA_NewKey(int keySizeInBits, SECItem *p
PORT_SetError(0);
CHECK_SEC_OK(generate_prime(&p, primeLen));
CHECK_SEC_OK(generate_prime(&q, primeLen));
@ -231,7 +231,7 @@ Index: nss/lib/freebl/rsa.c
/* Attempt to use these primes to generate a key */
rv = rsa_build_from_primes(&p, &q,
&e, PR_FALSE, /* needPublicExponent=false */
@@ -374,7 +466,9 @@ cleanup:
@@ -376,7 +468,9 @@ cleanup:
mp_clear(&q);
mp_clear(&e);
mp_clear(&d);

510
nss-fips-safe-memset.patch Normal file
View File

@ -0,0 +1,510 @@
Index: nss/lib/freebl/aeskeywrap.c
===================================================================
--- nss.orig/lib/freebl/aeskeywrap.c
+++ nss/lib/freebl/aeskeywrap.c
@@ -513,7 +513,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;
}
@@ -529,7 +529,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;
}
@@ -632,12 +632,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;
}
Index: nss/lib/freebl/blapii.h
===================================================================
--- nss.orig/lib/freebl/blapii.h
+++ nss/lib/freebl/blapii.h
@@ -113,10 +113,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
Index: nss/lib/freebl/drbg.c
===================================================================
--- nss.orig/lib/freebl/drbg.c
+++ nss/lib/freebl/drbg.c
@@ -259,7 +259,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);
coRNGInitEntropy.status = PR_SUCCESS;
__sync_synchronize ();
@@ -311,8 +311,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;
}
@@ -458,8 +458,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);
}
/*
@@ -520,7 +520,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);
Index: nss/lib/freebl/dsa.c
===================================================================
--- nss.orig/lib/freebl/dsa.c
+++ nss/lib/freebl/dsa.c
@@ -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);
Index: nss/lib/freebl/gcm.c
===================================================================
--- nss.orig/lib/freebl/gcm.c
+++ nss/lib/freebl/gcm.c
@@ -507,7 +507,7 @@ gcmHash_Final(gcmHashContext *ghash, uns
rv = SECSuccess;
cleanup:
- PORT_Memset(T, 0, sizeof(T));
+ PORT_SafeZero(T, sizeof(T));
return rv;
}
@@ -629,15 +629,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) {
@@ -717,11 +717,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);
}
@@ -1212,10 +1212,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);
Index: nss/lib/freebl/hmacct.c
===================================================================
--- nss.orig/lib/freebl/hmacct.c
+++ nss/lib/freebl/hmacct.c
@@ -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;
}
Index: nss/lib/freebl/intel-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/intel-gcm-wrap.c
+++ nss/lib/freebl/intel-gcm-wrap.c
@@ -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);
}
Index: nss/lib/freebl/ppc-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/ppc-gcm-wrap.c
+++ nss/lib/freebl/ppc-gcm-wrap.c
@@ -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);
}
Index: nss/lib/freebl/pqg.c
===================================================================
--- nss.orig/lib/freebl/pqg.c
+++ nss/lib/freebl/pqg.c
@@ -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);
}
Index: nss/lib/freebl/rijndael.c
===================================================================
--- nss.orig/lib/freebl/rijndael.c
+++ nss/lib/freebl/rijndael.c
@@ -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 {
Index: nss/lib/freebl/rsa.c
===================================================================
--- nss.orig/lib/freebl/rsa.c
+++ nss/lib/freebl/rsa.c
@@ -145,8 +145,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) {
@@ -180,6 +180,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);
@@ -1251,6 +1260,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:
Index: nss/lib/freebl/rsapkcs.c
===================================================================
--- nss.orig/lib/freebl/rsapkcs.c
+++ nss/lib/freebl/rsapkcs.c
@@ -978,14 +978,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;
}
@@ -993,7 +993,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;
@@ -1043,7 +1043,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;
}
@@ -1088,7 +1088,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;
}
Index: nss/lib/freebl/shvfy.c
===================================================================
--- nss.orig/lib/freebl/shvfy.c
+++ nss/lib/freebl/shvfy.c
@@ -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
@@ -600,7 +600,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);
}
Index: nss/lib/freebl/tlsprfalg.c
===================================================================
--- nss.orig/lib/freebl/tlsprfalg.c
+++ nss/lib/freebl/tlsprfalg.c
@@ -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;
}
Index: nss/lib/freebl/unix_urandom.c
===================================================================
--- nss.orig/lib/freebl/unix_urandom.c
+++ nss/lib/freebl/unix_urandom.c
@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
- PORT_Memset(bytes, 0, sizeof bytes);
+ PORT_SafeZero(bytes, sizeof bytes);
}
size_t
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -4994,7 +4994,7 @@ pairwise_signverify_mech (CK_SESSION_HAN
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. */
Index: nss/lib/util/secport.h
===================================================================
--- nss.orig/lib/util/secport.h
+++ nss/lib/util/secport.h
@@ -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