67466513bc
Fix CVE 2023-0767 Fix FIPS review comments.
398 lines
15 KiB
Diff
398 lines
15 KiB
Diff
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
|
--- a/lib/softoken/pkcs11c.c
|
|
+++ b/lib/softoken/pkcs11c.c
|
|
@@ -232,57 +232,26 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSes
|
|
* be in the data base.
|
|
*/
|
|
status = sftk_FreeObject(object);
|
|
|
|
return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
|
|
}
|
|
|
|
/*
|
|
- ************** Crypto Functions: Utilities ************************
|
|
- */
|
|
-/*
|
|
- * Utility function for converting PSS/OAEP parameter types into
|
|
- * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447.
|
|
- */
|
|
-static HASH_HashType
|
|
-GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
|
|
-{
|
|
- switch (mech) {
|
|
- case CKM_SHA_1:
|
|
- case CKG_MGF1_SHA1:
|
|
- return HASH_AlgSHA1;
|
|
- case CKM_SHA224:
|
|
- case CKG_MGF1_SHA224:
|
|
- return HASH_AlgSHA224;
|
|
- case CKM_SHA256:
|
|
- case CKG_MGF1_SHA256:
|
|
- return HASH_AlgSHA256;
|
|
- case CKM_SHA384:
|
|
- case CKG_MGF1_SHA384:
|
|
- return HASH_AlgSHA384;
|
|
- case CKM_SHA512:
|
|
- case CKG_MGF1_SHA512:
|
|
- return HASH_AlgSHA512;
|
|
- default:
|
|
- return HASH_AlgNULL;
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
* Returns true if "params" contains a valid set of PSS parameters
|
|
*/
|
|
static PRBool
|
|
sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params)
|
|
{
|
|
if (!params) {
|
|
return PR_FALSE;
|
|
}
|
|
- if (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
|
|
- GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
|
|
+ if (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
|
|
+ sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
|
|
return PR_FALSE;
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
/*
|
|
* Returns true if "params" contains a valid set of OAEP parameters
|
|
*/
|
|
@@ -293,18 +262,18 @@ sftk_ValidateOaepParams(const CK_RSA_PKC
|
|
return PR_FALSE;
|
|
}
|
|
/* The requirements of ulSourceLen/pSourceData come from PKCS #11, which
|
|
* state:
|
|
* If the parameter is empty, pSourceData must be NULL and
|
|
* ulSourceDataLen must be zero.
|
|
*/
|
|
if (params->source != CKZ_DATA_SPECIFIED ||
|
|
- (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
|
|
- (GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
|
|
+ (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
|
|
+ (sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
|
|
(params->ulSourceDataLen == 0 && params->pSourceData != NULL) ||
|
|
(params->ulSourceDataLen != 0 && params->pSourceData == NULL)) {
|
|
return PR_FALSE;
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
/*
|
|
@@ -606,18 +575,18 @@ sftk_RSAEncryptOAEP(SFTKOAEPInfo *info,
|
|
HASH_HashType maskHashAlg;
|
|
|
|
PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey);
|
|
if (info->key.pub->keyType != NSSLOWKEYRSAKey) {
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
return SECFailure;
|
|
}
|
|
|
|
- hashAlg = GetHashTypeFromMechanism(info->params.hashAlg);
|
|
- maskHashAlg = GetHashTypeFromMechanism(info->params.mgf);
|
|
+ hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
|
|
+ maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
|
|
|
|
return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg,
|
|
(const unsigned char *)info->params.pSourceData,
|
|
info->params.ulSourceDataLen, NULL, 0,
|
|
output, outputLen, maxLen, input, inputLen);
|
|
}
|
|
|
|
static SECStatus
|
|
@@ -630,18 +599,18 @@ sftk_RSADecryptOAEP(SFTKOAEPInfo *info,
|
|
HASH_HashType maskHashAlg;
|
|
|
|
PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey);
|
|
if (info->key.priv->keyType != NSSLOWKEYRSAKey) {
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
return SECFailure;
|
|
}
|
|
|
|
- hashAlg = GetHashTypeFromMechanism(info->params.hashAlg);
|
|
- maskHashAlg = GetHashTypeFromMechanism(info->params.mgf);
|
|
+ hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
|
|
+ maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
|
|
|
|
rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg,
|
|
(const unsigned char *)info->params.pSourceData,
|
|
info->params.ulSourceDataLen,
|
|
output, outputLen, maxLen, input, inputLen);
|
|
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
|
|
sftk_fatalError = PR_TRUE;
|
|
}
|
|
@@ -2646,18 +2615,18 @@ sftk_RSASignPSS(SFTKPSSSignInfo *info, u
|
|
CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
|
|
|
|
PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
|
|
if (info->key->keyType != NSSLOWKEYRSAKey) {
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
return SECFailure;
|
|
}
|
|
|
|
- hashAlg = GetHashTypeFromMechanism(params->hashAlg);
|
|
- maskHashAlg = GetHashTypeFromMechanism(params->mgf);
|
|
+ hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
|
|
+ maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
|
|
|
|
rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL,
|
|
params->sLen, sig, sigLen, maxLen, hash, hashLen);
|
|
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
|
|
sftk_fatalError = PR_TRUE;
|
|
}
|
|
return rv;
|
|
}
|
|
@@ -3021,17 +2990,17 @@ NSC_SignInit(CK_SESSION_HANDLE hSession,
|
|
tlsPrfHash = HASH_AlgNULL;
|
|
if (tls12_mac_params->ulMacLength != 12) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
} else {
|
|
/* The hash function for the TLS 1.2 PRF */
|
|
tlsPrfHash =
|
|
- GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism);
|
|
+ sftk_GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism);
|
|
if (tlsPrfHash == HASH_AlgNULL ||
|
|
tls12_mac_params->ulMacLength < 12) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
}
|
|
if (tls12_mac_params->ulServerOrClient == 1) {
|
|
label = "server finished";
|
|
@@ -3539,18 +3508,18 @@ sftk_RSACheckSignPSS(SFTKPSSVerifyInfo *
|
|
CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
|
|
|
|
PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey);
|
|
if (info->key->keyType != NSSLOWKEYRSAKey) {
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
return SECFailure;
|
|
}
|
|
|
|
- hashAlg = GetHashTypeFromMechanism(params->hashAlg);
|
|
- maskHashAlg = GetHashTypeFromMechanism(params->mgf);
|
|
+ hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
|
|
+ maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
|
|
|
|
return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg,
|
|
params->sLen, sig, sigLen, digest, digestLen);
|
|
}
|
|
|
|
/* NSC_VerifyInit initializes a verification operation,
|
|
* where the signature is an appendix to the data,
|
|
* and plaintext cannot be recovered from the signature (e.g. DSA) */
|
|
@@ -6951,17 +6920,17 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
|
unsigned genLen = 0;
|
|
unsigned char hashbuf[HASH_LENGTH_MAX];
|
|
unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH];
|
|
unsigned char *keyBlockAlloc = NULL; /* allocated keyBlock */
|
|
unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */
|
|
const unsigned char *prk; /* psuedo-random key */
|
|
CK_ULONG prkLen;
|
|
const unsigned char *okm; /* output keying material */
|
|
- HASH_HashType hashType = GetHashTypeFromMechanism(params->prfHashMechanism);
|
|
+ HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism);
|
|
SFTKObject *saltKey = NULL;
|
|
CK_RV crv = CKR_OK;
|
|
|
|
/* Spec says it should be the base hash, but also accept the HMAC */
|
|
if (hashType == HASH_AlgNULL) {
|
|
hashType = sftk_HMACMechanismToHash(params->prfHashMechanism);
|
|
}
|
|
rawHash = HASH_GetRawHashObject(hashType);
|
|
@@ -7389,17 +7358,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
|
if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
|
|
(mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
|
|
if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
|
|
(CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
|
|
- tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
|
|
+ tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
|
|
if (tlsPrfHash == HASH_AlgNULL) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
} else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) ||
|
|
(mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) {
|
|
tlsPrfHash = HASH_AlgSHA256;
|
|
}
|
|
@@ -7607,17 +7576,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
|
break;
|
|
}
|
|
|
|
status = TLS_PRF(&pms, "extended master secret",
|
|
&seed, &master, isFIPS);
|
|
} else {
|
|
const SECHashObject *hashObj;
|
|
|
|
- tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
|
|
+ tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism);
|
|
if (tlsPrfHash == HASH_AlgNULL) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
|
|
hashObj = HASH_GetRawHashObject(tlsPrfHash);
|
|
if (seed.len != hashObj->length) {
|
|
crv = CKR_TEMPLATE_INCONSISTENT;
|
|
@@ -7665,17 +7634,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
|
|
|
if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
|
|
if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
|
|
(CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
|
|
- tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
|
|
+ tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
|
|
if (tlsPrfHash == HASH_AlgNULL) {
|
|
crv = CKR_MECHANISM_PARAM_INVALID;
|
|
break;
|
|
}
|
|
} else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
|
|
tlsPrfHash = HASH_AlgSHA256;
|
|
}
|
|
|
|
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
|
|
--- a/lib/softoken/pkcs11i.h
|
|
+++ b/lib/softoken/pkcs11i.h
|
|
@@ -908,16 +908,19 @@ sftk_MACConstantTimeCtx *sftk_HMACConsta
|
|
sftk_MACConstantTimeCtx *sftk_SSLv3MACConstantTime_New(
|
|
CK_MECHANISM_PTR mech, SFTKObject *key);
|
|
void sftk_HMACConstantTime_Update(void *pctx, const void *data, unsigned int len);
|
|
void sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len);
|
|
void sftk_MACConstantTime_EndHash(
|
|
void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
|
|
void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
|
|
|
|
+/* Crypto Utilities */
|
|
+HASH_HashType sftk_GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech);
|
|
+
|
|
/****************************************
|
|
* implement TLS Pseudo Random Function (PRF)
|
|
*/
|
|
|
|
extern CK_RV
|
|
sftk_TLSPRFInit(SFTKSessionContext *context,
|
|
SFTKObject *key,
|
|
CK_KEY_TYPE key_type,
|
|
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
|
--- a/lib/softoken/pkcs11u.c
|
|
+++ b/lib/softoken/pkcs11u.c
|
|
@@ -95,16 +95,17 @@ CK_RV
|
|
sftk_MapVerifyError(int error)
|
|
{
|
|
CK_RV crv = sftk_MapCryptError(error);
|
|
if (crv == CKR_DEVICE_ERROR)
|
|
crv = CKR_SIGNATURE_INVALID;
|
|
return crv;
|
|
}
|
|
|
|
+
|
|
/*
|
|
* ******************** Attribute Utilities *******************************
|
|
*/
|
|
|
|
/*
|
|
* create a new attribute with type, value, and length. Space is allocated
|
|
* to hold value.
|
|
*/
|
|
@@ -2243,17 +2244,49 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
|
|
flags = CKF_MESSAGE_VERIFY;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
+/*
|
|
+ * ******************** Hash Utilities **************************
|
|
+ */
|
|
+/*
|
|
+ * Utility function for converting PSS/OAEP parameter types into
|
|
+ * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447.
|
|
+ */
|
|
+HASH_HashType
|
|
+sftk_GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
|
|
+{
|
|
+ switch (mech) {
|
|
+ case CKM_SHA_1:
|
|
+ case CKG_MGF1_SHA1:
|
|
+ return HASH_AlgSHA1;
|
|
+ case CKM_SHA224:
|
|
+ case CKG_MGF1_SHA224:
|
|
+ return HASH_AlgSHA224;
|
|
+ case CKM_SHA256:
|
|
+ case CKG_MGF1_SHA256:
|
|
+ return HASH_AlgSHA256;
|
|
+ case CKM_SHA384:
|
|
+ case CKG_MGF1_SHA384:
|
|
+ return HASH_AlgSHA384;
|
|
+ case CKM_SHA512:
|
|
+ case CKG_MGF1_SHA512:
|
|
+ return HASH_AlgSHA512;
|
|
+ default:
|
|
+ return HASH_AlgNULL;
|
|
+ }
|
|
+}
|
|
+
|
|
#ifdef NSS_HAS_FIPS_INDICATORS
|
|
+/**************** FIPS Indicator Utilities *************************/
|
|
/* sigh, we probably need a version of this in secutil so that both
|
|
* softoken and NSS can use it */
|
|
static SECOidTag
|
|
sftk_quickGetECCCurveOid(SFTKObject *source)
|
|
{
|
|
SFTKAttribute *attribute = sftk_FindAttribute(source, CKA_EC_PARAMS);
|
|
unsigned char *encoded;
|
|
int len;
|
|
@@ -2379,16 +2412,39 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
|
if (mech->ulParameterLen == 0) {
|
|
/* AEAD ciphers are only in FIPS mode if we are using the
|
|
* MESSAGE interface. This takes an empty parameter
|
|
* in the init function */
|
|
return PR_TRUE;
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
+ case SFTKFIPSRSAPSS: {
|
|
+ /* PSS salt must not be greater than the length of the
|
|
+ * underlying hash. We verify that the underlying hash of the
|
|
+ * parameters matches Hash of the combined hash mechanisms, so
|
|
+ * we don't need to look at the specific PSS mechanism */
|
|
+ CK_RSA_PKCS_PSS_PARAMS *pss = (CK_RSA_PKCS_PSS_PARAMS *)
|
|
+ mech->pParameter;
|
|
+ const SECHashObject *hashObj = NULL;
|
|
+ if (mech->ulParameterLen != sizeof(*pss)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ /* we use the existing hash utilities to find the length of
|
|
+ * the hash */
|
|
+ hashObj = HASH_GetRawHashObject(sftk_GetHashTypeFromMechanism(
|
|
+ pss->hashAlg));
|
|
+ if (hashObj == NULL) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ if (pss->sLen > hashObj->length) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ return PR_TRUE;
|
|
+ }
|
|
default:
|
|
break;
|
|
}
|
|
/* if we didn't understand the special processing, mark it non-fips */
|
|
return PR_FALSE;
|
|
}
|
|
#endif
|
|
|