int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, const EVP_MD **pmgf1md, int *psaltlen) { if (pss == NULL) return 0; *pmd = rsa_algor_to_md(pss->hashAlgorithm); if (*pmd == NULL) return 0; *pmgf1md = rsa_algor_to_md(pss->maskHash); if (*pmgf1md == NULL) return 0; if (pss->saltLength) { *psaltlen = ASN1_INTEGER_get(pss->saltLength); if (*psaltlen < 0) { RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_SALT_LENGTH); return 0; } } else { *psaltlen = 20; } /* * low-level routines support only trailer field 0xbc (value 1) and * PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_TRAILER); return 0; } return 1; }
int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); /* Decode PSS parameters */ int ret = 0; X509_ALGOR *maskHash; RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); goto err; } const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); if (mgf1md == NULL || md == NULL) { goto err; } int saltlen = 20; if (pss->saltLength != NULL) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); goto err; } } /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); goto err; } EVP_PKEY_CTX *pctx; if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) || !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { goto err; } ret = 1; err: RSA_PSS_PARAMS_free(pss); X509_ALGOR_free(maskHash); return ret; }
static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; X509_ALGOR *cmsalg; int nid; int rv = -1; unsigned char *label = NULL; int labellen = 0; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_OAEP_PARAMS *oaep; X509_ALGOR *maskHash; pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!pkctx) return 0; if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) return -1; nid = OBJ_obj2nid(cmsalg->algorithm); if (nid == NID_rsaEncryption) return 1; if (nid != NID_rsaesOaep) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); return -1; } /* Decode OAEP parameters */ oaep = rsa_oaep_decode(cmsalg, &maskHash); if (oaep == NULL) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash); if (!mgf1md) goto err; md = rsa_algor_to_md(oaep->hashFunc); if (!md) goto err; if (oaep->pSourceFunc) { X509_ALGOR *plab = oaep->pSourceFunc; if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); goto err; } if (plab->parameter->type != V_ASN1_OCTET_STRING) { RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); goto err; } label = plab->parameter->value.octet_string->data; /* Stop label being freed when OAEP parameters are freed */ plab->parameter->value.octet_string->data = NULL; labellen = plab->parameter->value.octet_string->length; } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) goto err; /* Carry on */ rv = 1; err: RSA_OAEP_PARAMS_free(oaep); X509_ALGOR_free(maskHash); return rv; }
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) goto err; md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) goto err; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* * Could perform more salt length sanity checks but the main RSA * routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* * low-level routines support only trailer field 0xbc (value 1) and * PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (pkey) { if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; } else { const EVP_MD *checkmd; if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 1; err: RSA_PSS_PARAMS_free(pss); X509_ALGOR_free(maskHash); return rv; }
/* From PSS AlgorithmIdentifier set public key parameters. */ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { int ret = 0; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS); goto err; } mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); if (!mgf1md) { goto err; } md = rsa_algor_to_md(pss->hashAlgorithm); if (!md) { goto err; } saltlen = 20; if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH); goto err; } } /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER); goto err; } if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) || !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) || !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) || !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) { goto err; } ret = 1; err: RSA_PSS_PARAMS_free(pss); if (maskHash) { X509_ALGOR_free(maskHash); } return ret; }