nss/nss-3.79-rsa-pss-salt-fips.patch
Bob Relyea 67466513bc Resolves: rhbz#2176630 rhbz#2153473 rhbz#2174613
Fix CVE 2023-0767
Fix FIPS review comments.
2023-03-11 11:19:28 -08:00

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