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