You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
8.3 KiB
190 lines
8.3 KiB
diff -up ./lib/softoken/pkcs11c.c.fips_indicators ./lib/softoken/pkcs11c.c |
|
--- ./lib/softoken/pkcs11c.c.fips_indicators 2023-11-27 11:21:42.459523398 -0800 |
|
+++ ./lib/softoken/pkcs11c.c 2023-11-27 11:22:56.821120920 -0800 |
|
@@ -450,7 +450,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; |
|
} |
|
@@ -4816,7 +4816,7 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi |
|
crv = sftk_handleObject(key, session); |
|
/* we need to do this check at the end, so we can check the generated |
|
* key length against fips requirements */ |
|
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key); |
|
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key, 0); |
|
session->lastOpWasFIPS = key->isFIPS; |
|
sftk_FreeSession(session); |
|
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) { |
|
@@ -5836,7 +5836,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS |
|
return crv; |
|
} |
|
/* we need to do this check at the end to make sure the generated key meets the key length requirements */ |
|
- privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey); |
|
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey, 0); |
|
publicKey->isFIPS = privateKey->isFIPS; |
|
session->lastOpWasFIPS = privateKey->isFIPS; |
|
sftk_FreeSession(session); |
|
@@ -7036,6 +7036,10 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_ |
|
return CKR_TEMPLATE_INCONSISTENT; |
|
} |
|
|
|
+ if (!params->bExpand) { |
|
+ keySize = hashLen; |
|
+ } |
|
+ |
|
/* sourceKey is NULL if we are called from the POST, skip the |
|
* sensitiveCheck */ |
|
if (sourceKey != NULL) { |
|
@@ -7085,7 +7089,8 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_ |
|
mech.pParameter = params; |
|
mech.ulParameterLen = sizeof(*params); |
|
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech, |
|
- CKA_DERIVE, saltKey); |
|
+ CKA_DERIVE, saltKey, |
|
+ keySize); |
|
} |
|
saltKeySource = saltKey->source; |
|
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE); |
|
@@ -7152,7 +7157,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 |
|
@@ -7398,7 +7403,8 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession |
|
return CKR_KEY_HANDLE_INVALID; |
|
} |
|
} |
|
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey); |
|
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey, |
|
+ keySize); |
|
|
|
switch (mechanism) { |
|
/* get a public key from a private key. nsslowkey_ConvertToPublickey() |
|
diff -up ./lib/softoken/pkcs11i.h.fips_indicators ./lib/softoken/pkcs11i.h |
|
--- ./lib/softoken/pkcs11i.h.fips_indicators 2023-11-27 11:21:42.450523326 -0800 |
|
+++ ./lib/softoken/pkcs11i.h 2023-11-27 11:22:56.821120920 -0800 |
|
@@ -979,7 +979,8 @@ CK_FLAGS sftk_AttributeToFlags(CK_ATTRIB |
|
/* check the FIPS table to determine if this current operation is allowed by |
|
* FIPS security policy */ |
|
PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, |
|
- CK_ATTRIBUTE_TYPE op, SFTKObject *source); |
|
+ CK_ATTRIBUTE_TYPE op, SFTKObject *source, |
|
+ CK_ULONG targetKeySize); |
|
/* add validation objects to the slot */ |
|
CK_RV sftk_CreateValidationObjects(SFTKSlot *slot); |
|
|
|
diff -up ./lib/softoken/pkcs11u.c.fips_indicators ./lib/softoken/pkcs11u.c |
|
--- ./lib/softoken/pkcs11u.c.fips_indicators 2023-11-27 11:21:42.451523334 -0800 |
|
+++ ./lib/softoken/pkcs11u.c 2023-11-27 11:31:51.812419789 -0800 |
|
@@ -2330,7 +2330,7 @@ sftk_quickGetECCCurveOid(SFTKObject *sou |
|
static CK_ULONG |
|
sftk_getKeyLength(SFTKObject *source) |
|
{ |
|
- CK_KEY_TYPE keyType = CK_INVALID_HANDLE; |
|
+ CK_KEY_TYPE keyType = CKK_INVALID_KEY_TYPE; |
|
CK_ATTRIBUTE_TYPE keyAttribute; |
|
CK_ULONG keyLength = 0; |
|
SFTKAttribute *attribute; |
|
@@ -2392,13 +2392,29 @@ sftk_getKeyLength(SFTKObject *source) |
|
return keyLength; |
|
} |
|
|
|
+PRBool |
|
+sftk_CheckFIPSHash(CK_MECHANISM_TYPE hash) |
|
+{ |
|
+ switch (hash) { |
|
+ case CKM_SHA256: |
|
+ case CKG_MGF1_SHA256: |
|
+ case CKM_SHA384: |
|
+ case CKG_MGF1_SHA384: |
|
+ case CKM_SHA512: |
|
+ case CKG_MGF1_SHA512: |
|
+ return PR_TRUE; |
|
+ } |
|
+ return PR_FALSE; |
|
+} |
|
+ |
|
/* |
|
* handle specialized FIPS semantics that are too complicated to |
|
* handle with just a table. NOTE: this means any additional semantics |
|
* would have to be coded here before they can be added to the table */ |
|
static PRBool |
|
sftk_handleSpecial(SFTKSlot *slot, CK_MECHANISM *mech, |
|
- SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source) |
|
+ SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source, |
|
+ CK_ULONG keyLength, CK_ULONG targetKeyLength) |
|
{ |
|
switch (mechInfo->special) { |
|
case SFTKFIPSDH: { |
|
@@ -2458,10 +2474,15 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME |
|
if (hashObj == NULL) { |
|
return PR_FALSE; |
|
} |
|
+ /* cap the salt for legacy keys */ |
|
+ if ((keyLength <= 1024) && (pss->sLen > 63)) { |
|
+ return PR_FALSE; |
|
+ } |
|
+ /* cap the salt for based on the hash */ |
|
if (pss->sLen > hashObj->length) { |
|
return PR_FALSE; |
|
} |
|
- return PR_TRUE; |
|
+ return sftk_CheckFIPSHash(pss->hashAlg); |
|
} |
|
case SFTKFIPSPBKDF2: { |
|
/* PBKDF2 must have the following addition restrictions |
|
@@ -2486,6 +2507,13 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME |
|
} |
|
return PR_TRUE; |
|
} |
|
+ /* check the hash mechanisms to make sure they themselves are FIPS */ |
|
+ case SFTKFIPSChkHash: |
|
+ if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) { |
|
+ return PR_FALSE; |
|
+ } |
|
+ return sftk_CheckFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter) |
|
+ + mechInfo->offset)); |
|
default: |
|
break; |
|
} |
|
@@ -2496,7 +2524,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; |
|
@@ -2528,13 +2556,17 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_ |
|
SFTKFIPSAlgorithmList *mechs = &sftk_fips_mechs[i]; |
|
/* if we match the number of records exactly, then we are an |
|
* approved algorithm in the approved mode with an approved key */ |
|
- if (((mech->mechanism == mechs->type) && |
|
- (opFlags == (mechs->info.flags & opFlags)) && |
|
- (keyLength <= mechs->info.ulMaxKeySize) && |
|
- (keyLength >= mechs->info.ulMinKeySize) && |
|
- ((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) && |
|
+ if ((mech->mechanism == mechs->type) && |
|
+ (opFlags == (mechs->info.flags & opFlags)) && |
|
+ (keyLength <= mechs->info.ulMaxKeySize) && |
|
+ (keyLength >= mechs->info.ulMinKeySize) && |
|
+ (((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) && |
|
+ ((targetKeyLength == 0) || |
|
+ ((targetKeyLength <= mechs->info.ulMaxKeySize) && |
|
+ (targetKeyLength >= mechs->info.ulMinKeySize) && |
|
+ ((targetKeyLength - mechs->info.ulMinKeySize) % mechs->step) == 0)) && |
|
((mechs->special == SFTKFIPSNone) || |
|
- sftk_handleSpecial(slot, mech, mechs, source))) { |
|
+ sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) { |
|
return PR_TRUE; |
|
} |
|
}
|
|
|