diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 7a11fa46..3040df63 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3680,6 +3680,58 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, } + +static CK_RV +pkcs15_prkey_check_pss_param(CK_MECHANISM_PTR pMechanism, CK_ULONG hlen) +{ + CK_RSA_PKCS_PSS_PARAMS *pss_param; + + if (pMechanism->pParameter == NULL) + return CKR_OK; // Support applications that don't provide CK_RSA_PKCS_PSS_PARAMS + + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) + return CKR_MECHANISM_PARAM_INVALID; + + pss_param = (CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; + + // Hash parameter must match mechanisms or length of data supplied for CKM_RSA_PKCS_PSS + switch(pss_param->hashAlg) { + case CKM_SHA_1: + if (hlen != 20) + return CKR_MECHANISM_PARAM_INVALID; + break; + case CKM_SHA256: + if (hlen != 32) + return CKR_MECHANISM_PARAM_INVALID; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + // SmartCards typically only support MGFs based on the same hash as the + // message digest + switch(pss_param->mgf) { + case CKG_MGF1_SHA1: + if (hlen != 20) + return CKR_MECHANISM_PARAM_INVALID; + break; + case CKG_MGF1_SHA256: + if (hlen != 32) + return CKR_MECHANISM_PARAM_INVALID; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + // SmartCards typically support only a salt length equal to the hash length + if (pss_param->sLen != hlen) + return CKR_MECHANISM_PARAM_INVALID; + + return CKR_OK; +} + + + static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData, @@ -3729,12 +3781,27 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512; break; case CKM_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_NONE; break; case CKM_SHA1_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, 20); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA1; break; case CKM_SHA256_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, 32); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA256; break; case CKM_RIPEMD160_RSA_PKCS: