diff options
Diffstat (limited to 'providers/implementations/signature/rsa_sig.c')
-rw-r--r-- | providers/implementations/signature/rsa_sig.c | 1072 |
1 files changed, 869 insertions, 203 deletions
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c index 919ef17269bd..e75b90840b9a 100644 --- a/providers/implementations/signature/rsa_sig.c +++ b/providers/implementations/signature/rsa_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,6 +18,7 @@ #include <openssl/core_dispatch.h> #include <openssl/core_names.h> #include <openssl/err.h> +#include <openssl/obj_mac.h> #include <openssl/rsa.h> #include <openssl/params.h> #include <openssl/evp.h> @@ -39,16 +40,21 @@ static OSSL_FUNC_signature_sign_init_fn rsa_sign_init; static OSSL_FUNC_signature_verify_init_fn rsa_verify_init; static OSSL_FUNC_signature_verify_recover_init_fn rsa_verify_recover_init; static OSSL_FUNC_signature_sign_fn rsa_sign; +static OSSL_FUNC_signature_sign_message_update_fn rsa_signverify_message_update; +static OSSL_FUNC_signature_sign_message_final_fn rsa_sign_message_final; static OSSL_FUNC_signature_verify_fn rsa_verify; static OSSL_FUNC_signature_verify_recover_fn rsa_verify_recover; +static OSSL_FUNC_signature_verify_message_update_fn rsa_signverify_message_update; +static OSSL_FUNC_signature_verify_message_final_fn rsa_verify_message_final; static OSSL_FUNC_signature_digest_sign_init_fn rsa_digest_sign_init; -static OSSL_FUNC_signature_digest_sign_update_fn rsa_digest_signverify_update; +static OSSL_FUNC_signature_digest_sign_update_fn rsa_digest_sign_update; static OSSL_FUNC_signature_digest_sign_final_fn rsa_digest_sign_final; static OSSL_FUNC_signature_digest_verify_init_fn rsa_digest_verify_init; -static OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_signverify_update; +static OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_verify_update; static OSSL_FUNC_signature_digest_verify_final_fn rsa_digest_verify_final; static OSSL_FUNC_signature_freectx_fn rsa_freectx; static OSSL_FUNC_signature_dupctx_fn rsa_dupctx; +static OSSL_FUNC_signature_query_key_types_fn rsa_sigalg_query_key_types; static OSSL_FUNC_signature_get_ctx_params_fn rsa_get_ctx_params; static OSSL_FUNC_signature_gettable_ctx_params_fn rsa_gettable_ctx_params; static OSSL_FUNC_signature_set_ctx_params_fn rsa_set_ctx_params; @@ -57,6 +63,8 @@ static OSSL_FUNC_signature_get_ctx_md_params_fn rsa_get_ctx_md_params; static OSSL_FUNC_signature_gettable_ctx_md_params_fn rsa_gettable_ctx_md_params; static OSSL_FUNC_signature_set_ctx_md_params_fn rsa_set_ctx_md_params; static OSSL_FUNC_signature_settable_ctx_md_params_fn rsa_settable_ctx_md_params; +static OSSL_FUNC_signature_set_ctx_params_fn rsa_sigalg_set_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn rsa_sigalg_settable_ctx_params; static OSSL_ITEM padding_item[] = { { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, @@ -79,13 +87,39 @@ typedef struct { int operation; /* + * Flag to determine if a full sigalg is run (1) or if a composable + * signature algorithm is run (0). + * + * When a full sigalg is run (1), this currently affects the following + * other flags, which are to remain untouched after their initialization: + * + * - flag_allow_md (initialized to 0) + */ + unsigned int flag_sigalg : 1; + /* * Flag to determine if the hash function can be changed (1) or not (0) * Because it's dangerous to change during a DigestSign or DigestVerify * operation, this flag is cleared by their Init function, and set again * by their Final function. + * Implementations of full sigalgs (such as RSA-SHA256) hard-code this + * flag to not allow changes (0). */ unsigned int flag_allow_md : 1; unsigned int mgf1_md_set : 1; + /* + * Flags to say what are the possible next external calls in what + * consitutes the life cycle of an algorithm. The relevant calls are: + * - init + * - update + * - final + * - oneshot + * All other external calls are regarded as utilitarian and are allowed + * at any time (they may be affected by other flags, like flag_allow_md, + * though). + */ + unsigned int flag_allow_update : 1; + unsigned int flag_allow_final : 1; + unsigned int flag_allow_oneshot : 1; /* main digest */ EVP_MD *md; @@ -104,9 +138,23 @@ typedef struct { /* Minimum salt length or -1 if no PSS parameter restriction */ int min_saltlen; + /* Signature, for verification */ + unsigned char *sig; + size_t siglen; + +#ifdef FIPS_MODULE + /* + * FIPS 140-3 IG 2.4.B mandates that verification based on a digest of a + * message is not permitted. However, signing based on a digest is still + * permitted. + */ + int verify_message; +#endif + /* Temp buffer */ unsigned char *tbuf; + OSSL_FIPS_IND_DECLARE } PROV_RSA_CTX; /* True if PSS parameters are restricted */ @@ -114,8 +162,14 @@ typedef struct { static size_t rsa_get_md_size(const PROV_RSA_CTX *prsactx) { - if (prsactx->md != NULL) - return EVP_MD_get_size(prsactx->md); + int md_size; + + if (prsactx->md != NULL) { + md_size = EVP_MD_get_size(prsactx->md); + if (md_size <= 0) + return 0; + return md_size; + } return 0; } @@ -123,30 +177,30 @@ static int rsa_check_padding(const PROV_RSA_CTX *prsactx, const char *mdname, const char *mgf1_mdname, int mdnid) { - switch(prsactx->pad_mode) { - case RSA_NO_PADDING: - if (mdname != NULL || mdnid != NID_undef) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); - return 0; - } - break; - case RSA_X931_PADDING: - if (RSA_X931_hash_id(mdnid) == -1) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST); + switch (prsactx->pad_mode) { + case RSA_NO_PADDING: + if (mdname != NULL || mdnid != NID_undef) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); + return 0; + } + break; + case RSA_X931_PADDING: + if (RSA_X931_hash_id(mdnid) == -1) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST); + return 0; + } + break; + case RSA_PKCS1_PSS_PADDING: + if (rsa_pss_restricted(prsactx)) + if ((mdname != NULL && !EVP_MD_is_a(prsactx->md, mdname)) + || (mgf1_mdname != NULL + && !EVP_MD_is_a(prsactx->mgf1_md, mgf1_mdname))) { + ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); return 0; } - break; - case RSA_PKCS1_PSS_PADDING: - if (rsa_pss_restricted(prsactx)) - if ((mdname != NULL && !EVP_MD_is_a(prsactx->md, mdname)) - || (mgf1_mdname != NULL - && !EVP_MD_is_a(prsactx->mgf1_md, mgf1_mdname))) { - ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); - return 0; - } - break; - default: - break; + break; + default: + break; } return 1; @@ -182,15 +236,18 @@ static void *rsa_newctx(void *provctx, const char *propq) || (propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL)) { OPENSSL_free(prsactx); - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } + OSSL_FIPS_IND_INIT(prsactx) prsactx->libctx = PROV_LIBCTX_OF(provctx); prsactx->flag_allow_md = 1; +#ifdef FIPS_MODULE + prsactx->verify_message = 1; +#endif prsactx->propq = propq_copy; - /* Maximum for sign, auto for verify */ - prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; + /* Maximum up to digest length for sign, auto for verify */ + prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; prsactx->min_saltlen = -1; return prsactx; } @@ -198,13 +255,43 @@ static void *rsa_newctx(void *provctx, const char *propq) static int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx) { int saltlen = ctx->saltlen; - + int saltlenMax = -1; + + /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection + * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the + * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of + * the hash function output block (in bytes)." + * + * Provide a way to use at most the digest length, so that the default does + * not violate FIPS 186-4. */ if (saltlen == RSA_PSS_SALTLEN_DIGEST) { - saltlen = EVP_MD_get_size(ctx->md); - } else if (saltlen == RSA_PSS_SALTLEN_AUTO || saltlen == RSA_PSS_SALTLEN_MAX) { - saltlen = RSA_size(ctx->rsa) - EVP_MD_get_size(ctx->md) - 2; + if ((saltlen = EVP_MD_get_size(ctx->md)) <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return -1; + } + } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) { + saltlen = RSA_PSS_SALTLEN_MAX; + if ((saltlenMax = EVP_MD_get_size(ctx->md)) <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return -1; + } + } + if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) { + int mdsize, rsasize; + + if ((mdsize = EVP_MD_get_size(ctx->md)) <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return -1; + } + if ((rsasize = RSA_size(ctx->rsa)) <= 2 || rsasize - 2 < mdsize) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return -1; + } + saltlen = rsasize - mdsize - 2; if ((RSA_bits(ctx->rsa) & 0x7) == 1) saltlen--; + if (saltlenMax >= 0 && saltlen > saltlenMax) + saltlen = saltlenMax; } if (saltlen < 0) { ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); @@ -230,11 +317,11 @@ static unsigned char *rsa_generate_signature_aid(PROV_RSA_CTX *ctx, int ret; if (!WPACKET_init_der(&pkt, aid_buf, buf_len)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB); return NULL; } - switch(ctx->pad_mode) { + switch (ctx->pad_mode) { case RSA_PKCS1_PADDING: ret = ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, ctx->mdnid); @@ -281,41 +368,68 @@ static unsigned char *rsa_generate_signature_aid(PROV_RSA_CTX *ctx, } static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, - const char *mdprops) + const char *mdprops, const char *desc) { + EVP_MD *md = NULL; + if (mdprops == NULL) mdprops = ctx->propq; if (mdname != NULL) { - EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); - int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); - int md_nid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md, - sha1_allowed); + int md_nid; size_t mdname_len = strlen(mdname); - if (md == NULL - || md_nid <= 0 - || !rsa_check_padding(ctx, mdname, NULL, md_nid) - || mdname_len >= sizeof(ctx->mdname)) { - if (md == NULL) - ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, - "%s could not be fetched", mdname); - if (md_nid <= 0) - ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, - "digest=%s", mdname); - if (mdname_len >= sizeof(ctx->mdname)) - ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, - "%s exceeds name buffer length", mdname); - EVP_MD_free(md); - return 0; + md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); + + if (md == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s could not be fetched", mdname); + goto err; + } + md_nid = ossl_digest_rsa_sign_get_md_nid(md); + if (md_nid == NID_undef) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, + "digest=%s", mdname); + goto err; + } + /* + * XOF digests are not allowed except for RSA PSS. + * We don't support XOF digests with RSA PSS (yet), so just fail. + * When we do support them, uncomment the second clause. + */ + if (EVP_MD_xof(md) + /* && ctx->pad_mode != RSA_PKCS1_PSS_PADDING */) { + ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); + goto err; + } +#ifdef FIPS_MODULE + { + int sha1_allowed + = ((ctx->operation + & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0); + + if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx), + OSSL_FIPS_IND_SETTABLE1, + ctx->libctx, + md_nid, sha1_allowed, desc, + ossl_fips_config_signature_digest_check)) + goto err; + } +#endif + + if (!rsa_check_padding(ctx, mdname, NULL, md_nid)) + goto err; + if (mdname_len >= sizeof(ctx->mdname)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s exceeds name buffer length", mdname); + goto err; } if (!ctx->flag_allow_md) { if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest %s != %s", mdname, ctx->mdname); - EVP_MD_free(md); - return 0; + goto err; } EVP_MD_free(md); return 1; @@ -323,8 +437,7 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, if (!ctx->mgf1_md_set) { if (!EVP_MD_up_ref(md)) { - EVP_MD_free(md); - return 0; + goto err; } EVP_MD_free(ctx->mgf1_md); ctx->mgf1_md = md; @@ -342,6 +455,9 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, } return 1; +err: + EVP_MD_free(md); + return 0; } static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, @@ -360,7 +476,7 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, return 0; } /* The default for mgf1 is SHA1 - so allow SHA1 */ - if ((mdnid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md, 1)) <= 0 + if ((mdnid = ossl_digest_rsa_sign_get_md_nid(md)) <= 0 || !rsa_check_padding(ctx, NULL, mdname, mdnid)) { if (mdnid <= 0) ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, @@ -383,10 +499,13 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, return 1; } -static int rsa_signverify_init(void *vprsactx, void *vrsa, - const OSSL_PARAM params[], int operation) +static int +rsa_signverify_init(PROV_RSA_CTX *prsactx, void *vrsa, + OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params, + const OSSL_PARAM params[], int operation, + const char *desc) { - PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + int protect; if (!ossl_prov_is_running() || prsactx == NULL) return 0; @@ -397,19 +516,21 @@ static int rsa_signverify_init(void *vprsactx, void *vrsa, } if (vrsa != NULL) { - if (!ossl_rsa_check_key(prsactx->libctx, vrsa, operation)) - return 0; - if (!RSA_up_ref(vrsa)) return 0; RSA_free(prsactx->rsa); prsactx->rsa = vrsa; } + if (!ossl_rsa_key_op_get_protect(prsactx->rsa, operation, &protect)) + return 0; prsactx->operation = operation; + prsactx->flag_allow_update = 1; + prsactx->flag_allow_final = 1; + prsactx->flag_allow_oneshot = 1; - /* Maximum for sign, auto for verify */ - prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; + /* Maximize up to digest length for sign, auto for verify */ + prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; prsactx->min_saltlen = -1; switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { @@ -462,7 +583,7 @@ static int rsa_signverify_init(void *vprsactx, void *vrsa, /* call rsa_setup_mgf1_md before rsa_setup_md to avoid duplication */ if (!rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq) - || !rsa_setup_md(prsactx, mdname, prsactx->propq) + || !rsa_setup_md(prsactx, mdname, prsactx->propq, desc) || !rsa_check_parameters(prsactx, min_saltlen)) return 0; } @@ -474,9 +595,15 @@ static int rsa_signverify_init(void *vprsactx, void *vrsa, return 0; } - if (!rsa_set_ctx_params(prsactx, params)) + OSSL_FIPS_IND_SET_APPROVED(prsactx) + if (!set_ctx_params(prsactx, params)) return 0; - +#ifdef FIPS_MODULE + if (!ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND_GET(prsactx), + OSSL_FIPS_IND_SETTABLE0, prsactx->libctx, + prsactx->rsa, desc, protect)) + return 0; +#endif return 1; } @@ -484,10 +611,8 @@ static int setup_tbuf(PROV_RSA_CTX *ctx) { if (ctx->tbuf != NULL) return 1; - if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) return 0; - } return 1; } @@ -504,17 +629,54 @@ static void free_tbuf(PROV_RSA_CTX *ctx) ctx->tbuf = NULL; } -static int rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) +#ifdef FIPS_MODULE +static int rsa_pss_saltlen_check_passed(PROV_RSA_CTX *ctx, const char *algoname, int saltlen) { - if (!ossl_prov_is_running()) - return 0; - return rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_SIGN); + int mdsize = rsa_get_md_size(ctx); + /* + * Perform the check if the salt length is compliant to FIPS 186-5. + * + * According to FIPS 186-5 5.4 (g), the salt length shall be between zero + * and the output block length of the digest function (inclusive). + */ + int approved = (saltlen >= 0 && saltlen <= mdsize); + + if (!approved) { + if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE3, + ctx->libctx, + algoname, "PSS Salt Length", + ossl_fips_config_rsa_pss_saltlen_check)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); + return 0; + } + } + + return 1; } +#endif -static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, - size_t sigsize, const unsigned char *tbs, size_t tbslen) +static int rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + +#ifdef FIPS_MODULE + if (prsactx != NULL) + prsactx->verify_message = 1; +#endif + + return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params, + EVP_PKEY_OP_SIGN, "RSA Sign Init"); +} + +/* + * Sign tbs without digesting it first. This is suitable for "primitive" + * signing and signing the digest of a message, i.e. should be used with + * implementations of the keytype related algorithms. + */ +static int rsa_sign_directly(PROV_RSA_CTX *prsactx, + unsigned char *sig, size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) +{ int ret; size_t rsasize = RSA_size(prsactx->rsa); size_t mdsize = rsa_get_md_size(prsactx); @@ -568,7 +730,7 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, return 0; } if (!setup_tbuf(prsactx)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return 0; } memcpy(prsactx->tbuf, tbs, tbslen); @@ -577,7 +739,6 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, sig, prsactx->rsa, RSA_X931_PADDING); clean_tbuf(prsactx); break; - case RSA_PKCS1_PADDING: { unsigned int sltmp; @@ -593,46 +754,55 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, break; case RSA_PKCS1_PSS_PADDING: - /* Check PSS restrictions */ - if (rsa_pss_restricted(prsactx)) { - switch (prsactx->saltlen) { - case RSA_PSS_SALTLEN_DIGEST: - if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) { - ERR_raise_data(ERR_LIB_PROV, - PROV_R_PSS_SALTLEN_TOO_SMALL, - "minimum salt length set to %d, " - "but the digest only gives %d", - prsactx->min_saltlen, - EVP_MD_get_size(prsactx->md)); - return 0; - } - /* FALLTHRU */ - default: - if (prsactx->saltlen >= 0 - && prsactx->saltlen < prsactx->min_saltlen) { - ERR_raise_data(ERR_LIB_PROV, - PROV_R_PSS_SALTLEN_TOO_SMALL, - "minimum salt length set to %d, but the" - "actual salt length is only set to %d", - prsactx->min_saltlen, - prsactx->saltlen); - return 0; + { + int saltlen; + + /* Check PSS restrictions */ + if (rsa_pss_restricted(prsactx)) { + switch (prsactx->saltlen) { + case RSA_PSS_SALTLEN_DIGEST: + if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) { + ERR_raise_data(ERR_LIB_PROV, + PROV_R_PSS_SALTLEN_TOO_SMALL, + "minimum salt length set to %d, " + "but the digest only gives %d", + prsactx->min_saltlen, + EVP_MD_get_size(prsactx->md)); + return 0; + } + /* FALLTHRU */ + default: + if (prsactx->saltlen >= 0 + && prsactx->saltlen < prsactx->min_saltlen) { + ERR_raise_data(ERR_LIB_PROV, + PROV_R_PSS_SALTLEN_TOO_SMALL, + "minimum salt length set to %d, but the" + "actual salt length is only set to %d", + prsactx->min_saltlen, + prsactx->saltlen); + return 0; + } + break; } - break; } + if (!setup_tbuf(prsactx)) + return 0; + saltlen = prsactx->saltlen; + if (!ossl_rsa_padding_add_PKCS1_PSS_mgf1(prsactx->rsa, + prsactx->tbuf, tbs, + prsactx->md, prsactx->mgf1_md, + &saltlen)) { + ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); + return 0; + } +#ifdef FIPS_MODULE + if (!rsa_pss_saltlen_check_passed(prsactx, "RSA Sign", saltlen)) + return 0; +#endif + ret = RSA_private_encrypt(RSA_size(prsactx->rsa), prsactx->tbuf, + sig, prsactx->rsa, RSA_NO_PADDING); + clean_tbuf(prsactx); } - if (!setup_tbuf(prsactx)) - return 0; - if (!RSA_padding_add_PKCS1_PSS_mgf1(prsactx->rsa, - prsactx->tbuf, tbs, - prsactx->md, prsactx->mgf1_md, - prsactx->saltlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); - return 0; - } - ret = RSA_private_encrypt(RSA_size(prsactx->rsa), prsactx->tbuf, - sig, prsactx->rsa, RSA_NO_PADDING); - clean_tbuf(prsactx); break; default: @@ -657,21 +827,112 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, return 1; } +static int rsa_signverify_message_update(void *vprsactx, + const unsigned char *data, + size_t datalen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL || prsactx->mdctx == NULL) + return 0; + + if (!prsactx->flag_allow_update) { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return 0; + } + prsactx->flag_allow_oneshot = 0; + + return EVP_DigestUpdate(prsactx->mdctx, data, datalen); +} + +static int rsa_sign_message_final(void *vprsactx, unsigned char *sig, + size_t *siglen, size_t sigsize) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + if (!ossl_prov_is_running() || prsactx == NULL) + return 0; + if (prsactx->mdctx == NULL) + return 0; + if (!prsactx->flag_allow_final) { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return 0; + } + + /* + * If sig is NULL then we're just finding out the sig size. Other fields + * are ignored. Defer to rsa_sign. + */ + if (sig != NULL) { + /* + * The digests used here are all known (see rsa_get_md_nid()), so they + * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. + */ + if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) + return 0; + + prsactx->flag_allow_update = 0; + prsactx->flag_allow_oneshot = 0; + prsactx->flag_allow_final = 0; + } + + return rsa_sign_directly(prsactx, sig, siglen, sigsize, digest, dlen); +} + +/* + * If signing a message, digest tbs and sign the result. + * Otherwise, sign tbs directly. + */ +static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (!ossl_prov_is_running() || prsactx == NULL) + return 0; + if (!prsactx->flag_allow_oneshot) { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return 0; + } + + if (prsactx->operation == EVP_PKEY_OP_SIGNMSG) { + /* + * If |sig| is NULL, the caller is only looking for the sig length. + * DO NOT update the input in this case. + */ + if (sig == NULL) + return rsa_sign_message_final(prsactx, sig, siglen, sigsize); + + return rsa_signverify_message_update(prsactx, tbs, tbslen) + && rsa_sign_message_final(prsactx, sig, siglen, sigsize); + } + return rsa_sign_directly(prsactx, sig, siglen, sigsize, tbs, tbslen); +} + static int rsa_verify_recover_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { - if (!ossl_prov_is_running()) - return 0; - return rsa_signverify_init(vprsactx, vrsa, params, - EVP_PKEY_OP_VERIFYRECOVER); + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + +#ifdef FIPS_MODULE + if (prsactx != NULL) + prsactx->verify_message = 0; +#endif + + return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params, + EVP_PKEY_OP_VERIFYRECOVER, "RSA VerifyRecover Init"); } +/* + * There is no message variant of verify recover, so no need for + * 'rsa_verify_recover_directly', just use this function, er, directly. + */ static int rsa_verify_recover(void *vprsactx, - unsigned char *rout, - size_t *routlen, + unsigned char *rout, size_t *routlen, size_t routsize, - const unsigned char *sig, - size_t siglen) + const unsigned char *sig, size_t siglen) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; @@ -753,15 +1014,21 @@ static int rsa_verify_recover(void *vprsactx, static int rsa_verify_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { - if (!ossl_prov_is_running()) - return 0; - return rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + +#ifdef FIPS_MODULE + if (prsactx != NULL) + prsactx->verify_message = 0; +#endif + + return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params, + EVP_PKEY_OP_VERIFY, "RSA Verify Init"); } -static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) +static int rsa_verify_directly(PROV_RSA_CTX *prsactx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) { - PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; size_t rslen; if (!ossl_prov_is_running()) @@ -785,6 +1052,7 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, case RSA_PKCS1_PSS_PADDING: { int ret; + int saltlen; size_t mdsize; /* @@ -807,14 +1075,19 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } - ret = RSA_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs, - prsactx->md, prsactx->mgf1_md, - prsactx->tbuf, - prsactx->saltlen); + saltlen = prsactx->saltlen; + ret = ossl_rsa_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs, + prsactx->md, prsactx->mgf1_md, + prsactx->tbuf, + &saltlen); if (ret <= 0) { ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } +#ifdef FIPS_MODULE + if (!rsa_pss_saltlen_check_passed(prsactx, "RSA Verify", saltlen)) + return 0; +#endif return 1; } default: @@ -842,22 +1115,94 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, return 1; } +static int rsa_verify_set_sig(void *vprsactx, + const unsigned char *sig, size_t siglen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + OSSL_PARAM params[2]; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, + (unsigned char *)sig, siglen); + params[1] = OSSL_PARAM_construct_end(); + return rsa_sigalg_set_ctx_params(prsactx, params); +} + +static int rsa_verify_message_final(void *vprsactx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + if (!ossl_prov_is_running() || prsactx == NULL) + return 0; + if (prsactx->mdctx == NULL) + return 0; + if (!prsactx->flag_allow_final) { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return 0; + } + + /* + * The digests used here are all known (see rsa_get_md_nid()), so they + * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. + */ + if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) + return 0; + + prsactx->flag_allow_update = 0; + prsactx->flag_allow_final = 0; + prsactx->flag_allow_oneshot = 0; + + return rsa_verify_directly(prsactx, prsactx->sig, prsactx->siglen, + digest, dlen); +} + +/* + * If verifying a message, digest tbs and verify the result. + * Otherwise, verify tbs directly. + */ +static int rsa_verify(void *vprsactx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (!ossl_prov_is_running() || prsactx == NULL) + return 0; + if (!prsactx->flag_allow_oneshot) { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return 0; + } + + if (prsactx->operation == EVP_PKEY_OP_VERIFYMSG) + return rsa_verify_set_sig(prsactx, sig, siglen) + && rsa_signverify_message_update(prsactx, tbs, tbslen) + && rsa_verify_message_final(prsactx); + return rsa_verify_directly(prsactx, sig, siglen, tbs, tbslen); +} + +/* DigestSign/DigestVerify wrappers */ + static int rsa_digest_signverify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[], - int operation) + int operation, const char *desc) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - if (!ossl_prov_is_running()) - return 0; +#ifdef FIPS_MODULE + if (prsactx != NULL) + prsactx->verify_message = 1; +#endif - if (!rsa_signverify_init(vprsactx, vrsa, params, operation)) + if (!rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params, + operation, desc)) return 0; if (mdname != NULL /* was rsa_setup_md already called in rsa_signverify_init()? */ && (mdname[0] == '\0' || OPENSSL_strcasecmp(prsactx->mdname, mdname) != 0) - && !rsa_setup_md(prsactx, mdname, prsactx->propq)) + && !rsa_setup_md(prsactx, mdname, prsactx->propq, desc)) return 0; prsactx->flag_allow_md = 0; @@ -879,53 +1224,48 @@ static int rsa_digest_signverify_init(void *vprsactx, const char *mdname, return 0; } -static int rsa_digest_signverify_update(void *vprsactx, - const unsigned char *data, - size_t datalen) -{ - PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - - if (prsactx == NULL || prsactx->mdctx == NULL) - return 0; - - return EVP_DigestUpdate(prsactx->mdctx, data, datalen); -} - static int rsa_digest_sign_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { if (!ossl_prov_is_running()) return 0; return rsa_digest_signverify_init(vprsactx, mdname, vrsa, - params, EVP_PKEY_OP_SIGN); + params, EVP_PKEY_OP_SIGNMSG, + "RSA Digest Sign Init"); +} + +static int rsa_digest_sign_update(void *vprsactx, const unsigned char *data, + size_t datalen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL) + return 0; + /* Sigalg implementations shouldn't do digest_sign */ + if (prsactx->flag_sigalg) + return 0; + + return rsa_signverify_message_update(prsactx, data, datalen); } static int rsa_digest_sign_final(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - unsigned char digest[EVP_MAX_MD_SIZE]; - unsigned int dlen = 0; + int ok = 0; - if (!ossl_prov_is_running() || prsactx == NULL) + if (prsactx == NULL) return 0; - prsactx->flag_allow_md = 1; - if (prsactx->mdctx == NULL) + /* Sigalg implementations shouldn't do digest_sign */ + if (prsactx->flag_sigalg) return 0; - /* - * If sig is NULL then we're just finding out the sig size. Other fields - * are ignored. Defer to rsa_sign. - */ - if (sig != NULL) { - /* - * The digests used here are all known (see rsa_get_md_nid()), so they - * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. - */ - if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) - return 0; - } - return rsa_sign(vprsactx, sig, siglen, sigsize, digest, (size_t)dlen); + if (rsa_sign_message_final(prsactx, sig, siglen, sigsize)) + ok = 1; + + prsactx->flag_allow_md = 1; + + return ok; } static int rsa_digest_verify_init(void *vprsactx, const char *mdname, @@ -934,33 +1274,43 @@ static int rsa_digest_verify_init(void *vprsactx, const char *mdname, if (!ossl_prov_is_running()) return 0; return rsa_digest_signverify_init(vprsactx, mdname, vrsa, - params, EVP_PKEY_OP_VERIFY); + params, EVP_PKEY_OP_VERIFYMSG, + "RSA Digest Verify Init"); } -int rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, - size_t siglen) +static int rsa_digest_verify_update(void *vprsactx, const unsigned char *data, + size_t datalen) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - unsigned char digest[EVP_MAX_MD_SIZE]; - unsigned int dlen = 0; - if (!ossl_prov_is_running()) + if (prsactx == NULL) return 0; + /* Sigalg implementations shouldn't do digest_sign */ + if (prsactx->flag_sigalg) + return 0; + + return rsa_signverify_message_update(prsactx, data, datalen); +} + +int rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, + size_t siglen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + int ok = 0; if (prsactx == NULL) return 0; - prsactx->flag_allow_md = 1; - if (prsactx->mdctx == NULL) + /* Sigalg implementations shouldn't do digest_verify */ + if (prsactx->flag_sigalg) return 0; - /* - * The digests used here are all known (see rsa_get_md_nid()), so they - * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. - */ - if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) - return 0; + if (rsa_verify_set_sig(prsactx, sig, siglen) + && rsa_verify_message_final(vprsactx)) + ok = 1; + + prsactx->flag_allow_md = 1; - return rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); + return ok; } static void rsa_freectx(void *vprsactx) @@ -973,6 +1323,7 @@ static void rsa_freectx(void *vprsactx) EVP_MD_CTX_free(prsactx->mdctx); EVP_MD_free(prsactx->md); EVP_MD_free(prsactx->mgf1_md); + OPENSSL_free(prsactx->sig); OPENSSL_free(prsactx->propq); free_tbuf(prsactx); RSA_free(prsactx->rsa); @@ -989,10 +1340,8 @@ static void *rsa_dupctx(void *vprsactx) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); - if (dstctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (dstctx == NULL) return NULL; - } *dstctx = *srcctx; dstctx->rsa = NULL; @@ -1111,6 +1460,9 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) case RSA_PSS_SALTLEN_AUTO: value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO; break; + case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: + value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX; + break; default: { int len = BIO_snprintf(p->data, p->data_size, "%d", @@ -1128,6 +1480,14 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) } } +#ifdef FIPS_MODULE + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE); + if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->verify_message)) + return 0; +#endif + + if (!OSSL_FIPS_IND_GET_CTX_PARAM(prsactx, params)) + return 0; return 1; } @@ -1137,6 +1497,10 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), +#ifdef FIPS_MODULE + OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL), +#endif + OSSL_FIPS_IND_GETTABLE_CTX_PARAM() OSSL_PARAM_END }; @@ -1146,6 +1510,25 @@ static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx, return known_gettable_ctx_params; } +#ifdef FIPS_MODULE +static int rsa_x931_padding_allowed(PROV_RSA_CTX *ctx) +{ + int approved = ((ctx->operation & EVP_PKEY_OP_SIGN) == 0); + + if (!approved) { + if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2, + ctx->libctx, + "RSA Sign set ctx", "X931 Padding", + ossl_fips_config_rsa_sign_x931_disallowed)) { + ERR_raise(ERR_LIB_PROV, + PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + } + return 1; +} +#endif + static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; @@ -1159,9 +1542,25 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) if (prsactx == NULL) return 0; - if (params == NULL) + if (ossl_param_is_empty(params)) return 1; + if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0, params, + OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)) + return 0; + + if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE1, params, + OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)) + return 0; + + if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE2, params, + OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK)) + return 0; + + if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE3, params, + OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK)) + return 0; + pad_mode = prsactx->pad_mode; saltlen = prsactx->saltlen; @@ -1221,7 +1620,8 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) goto bad_pad; case RSA_PKCS1_PSS_PADDING: if ((prsactx->operation - & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)) == 0) { + & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG + | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYMSG)) == 0) { err_extra_text = "PSS padding only allowed for sign and verify operations"; goto bad_pad; @@ -1234,6 +1634,16 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) err_extra_text = "No padding not allowed with RSA-PSS"; goto cont; case RSA_X931_PADDING: +#ifdef FIPS_MODULE + /* X9.31 only allows sizes of 1024 + 256 * s (bits) */ + if ((RSA_bits(prsactx->rsa) & 0xFF) != 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + /* RSA Signing with X9.31 padding is not allowed in FIPS 140-3 */ + if (!rsa_x931_padding_allowed(prsactx)) + return 0; +#endif err_extra_text = "X.931 padding not allowed with RSA-PSS"; cont: if (RSA_test_flags(prsactx->rsa, @@ -1274,6 +1684,8 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) saltlen = RSA_PSS_SALTLEN_MAX; else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0) saltlen = RSA_PSS_SALTLEN_AUTO; + else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0) + saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; else saltlen = atoi(p->data); break; @@ -1282,11 +1694,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) } /* - * RSA_PSS_SALTLEN_MAX seems curiously named in this check. - * Contrary to what it's name suggests, it's the currently - * lowest saltlen number possible. + * RSA_PSS_SALTLEN_AUTO_DIGEST_MAX seems curiously named in this check. + * Contrary to what it's name suggests, it's the currently lowest + * saltlen number possible. */ - if (saltlen < RSA_PSS_SALTLEN_MAX) { + if (saltlen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return 0; } @@ -1294,7 +1706,9 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) if (rsa_pss_restricted(prsactx)) { switch (saltlen) { case RSA_PSS_SALTLEN_AUTO: - if (prsactx->operation == EVP_PKEY_OP_VERIFY) { + case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: + if ((prsactx->operation + & (EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYMSG)) == 0) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "Cannot use autodetected salt length"); return 0; @@ -1359,7 +1773,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) return 0; if (pmdname != NULL) { - if (!rsa_setup_md(prsactx, pmdname, pmdprops)) + if (!rsa_setup_md(prsactx, pmdname, pmdprops, "RSA Sign Set Ctx")) return 0; } else { if (!rsa_check_padding(prsactx, NULL, NULL, prsactx->mdnid)) @@ -1375,6 +1789,10 @@ static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK) OSSL_PARAM_END }; @@ -1383,6 +1801,10 @@ static const OSSL_PARAM settable_ctx_params_no_digest[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK) OSSL_PARAM_END }; @@ -1449,13 +1871,13 @@ const OSSL_DISPATCH ossl_rsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))rsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, - (void (*)(void))rsa_digest_signverify_update }, + (void (*)(void))rsa_digest_sign_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))rsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))rsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, - (void (*)(void))rsa_digest_signverify_update }, + (void (*)(void))rsa_digest_verify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, (void (*)(void))rsa_digest_verify_final }, { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx }, @@ -1474,5 +1896,249 @@ const OSSL_DISPATCH ossl_rsa_signature_functions[] = { (void (*)(void))rsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))rsa_settable_ctx_md_params }, - { 0, NULL } + OSSL_DISPATCH_END }; + +/* ------------------------------------------------------------------ */ + +/* + * So called sigalgs (composite RSA+hash) implemented below. They + * are pretty much hard coded, and rely on the hash implementation + * being available as per what OPENSSL_NO_ macros allow. + */ + +static OSSL_FUNC_signature_query_key_types_fn rsa_sigalg_query_key_types; +static OSSL_FUNC_signature_settable_ctx_params_fn rsa_sigalg_settable_ctx_params; +static OSSL_FUNC_signature_set_ctx_params_fn rsa_sigalg_set_ctx_params; + +/* + * rsa_sigalg_signverify_init() is almost like rsa_digest_signverify_init(), + * just doesn't allow fetching an MD from whatever the user chooses. + */ +static int rsa_sigalg_signverify_init(void *vprsactx, void *vrsa, + OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params, + const OSSL_PARAM params[], + const char *mdname, + int operation, int pad_mode, + const char *desc) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (!ossl_prov_is_running()) + return 0; + + if (!rsa_signverify_init(prsactx, vrsa, set_ctx_params, params, operation, + desc)) + return 0; + + /* PSS is currently not supported as a sigalg */ + if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) { + ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (!rsa_setup_md(prsactx, mdname, NULL, desc)) + return 0; + + prsactx->pad_mode = pad_mode; + prsactx->flag_sigalg = 1; + prsactx->flag_allow_md = 0; + + if (prsactx->mdctx == NULL) { + prsactx->mdctx = EVP_MD_CTX_new(); + if (prsactx->mdctx == NULL) + goto error; + } + + if (!EVP_DigestInit_ex2(prsactx->mdctx, prsactx->md, params)) + goto error; + + return 1; + + error: + EVP_MD_CTX_free(prsactx->mdctx); + prsactx->mdctx = NULL; + return 0; +} + +static const char **rsa_sigalg_query_key_types(void) +{ + static const char *keytypes[] = { "RSA", NULL }; + + return keytypes; +} + +static const OSSL_PARAM settable_sigalg_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *rsa_sigalg_settable_ctx_params(void *vprsactx, + ossl_unused void *provctx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx != NULL && prsactx->operation == EVP_PKEY_OP_VERIFYMSG) + return settable_sigalg_ctx_params; + return NULL; +} + +static int rsa_sigalg_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + const OSSL_PARAM *p; + + if (prsactx == NULL) + return 0; + if (ossl_param_is_empty(params)) + return 1; + + if (prsactx->operation == EVP_PKEY_OP_VERIFYMSG) { + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE); + if (p != NULL) { + OPENSSL_free(prsactx->sig); + prsactx->sig = NULL; + prsactx->siglen = 0; + if (!OSSL_PARAM_get_octet_string(p, (void **)&prsactx->sig, + 0, &prsactx->siglen)) + return 0; + } + } + return 1; +} + +#define IMPL_RSA_SIGALG(md, MD) \ + static OSSL_FUNC_signature_sign_init_fn rsa_##md##_sign_init; \ + static OSSL_FUNC_signature_sign_message_init_fn \ + rsa_##md##_sign_message_init; \ + static OSSL_FUNC_signature_verify_init_fn rsa_##md##_verify_init; \ + static OSSL_FUNC_signature_verify_message_init_fn \ + rsa_##md##_verify_message_init; \ + \ + static int \ + rsa_##md##_sign_init(void *vprsactx, void *vrsa, \ + const OSSL_PARAM params[]) \ + { \ + static const char desc[] = "RSA Sigalg Sign Init"; \ + \ + return rsa_sigalg_signverify_init(vprsactx, vrsa, \ + rsa_sigalg_set_ctx_params, \ + params, #MD, \ + EVP_PKEY_OP_SIGN, \ + RSA_PKCS1_PADDING, \ + desc); \ + } \ + \ + static int \ + rsa_##md##_sign_message_init(void *vprsactx, void *vrsa, \ + const OSSL_PARAM params[]) \ + { \ + static const char desc[] = "RSA Sigalg Sign Message Init"; \ + \ + return rsa_sigalg_signverify_init(vprsactx, vrsa, \ + rsa_sigalg_set_ctx_params, \ + params, #MD, \ + EVP_PKEY_OP_SIGNMSG, \ + RSA_PKCS1_PADDING, \ + desc); \ + } \ + \ + static int \ + rsa_##md##_verify_init(void *vprsactx, void *vrsa, \ + const OSSL_PARAM params[]) \ + { \ + static const char desc[] = "RSA Sigalg Verify Init"; \ + \ + return rsa_sigalg_signverify_init(vprsactx, vrsa, \ + rsa_sigalg_set_ctx_params, \ + params, #MD, \ + EVP_PKEY_OP_VERIFY, \ + RSA_PKCS1_PADDING, \ + desc); \ + } \ + \ + static int \ + rsa_##md##_verify_recover_init(void *vprsactx, void *vrsa, \ + const OSSL_PARAM params[]) \ + { \ + static const char desc[] = "RSA Sigalg Verify Recover Init"; \ + \ + return rsa_sigalg_signverify_init(vprsactx, vrsa, \ + rsa_sigalg_set_ctx_params, \ + params, #MD, \ + EVP_PKEY_OP_VERIFYRECOVER, \ + RSA_PKCS1_PADDING, \ + desc); \ + } \ + \ + static int \ + rsa_##md##_verify_message_init(void *vprsactx, void *vrsa, \ + const OSSL_PARAM params[]) \ + { \ + static const char desc[] = "RSA Sigalg Verify Message Init"; \ + \ + return rsa_sigalg_signverify_init(vprsactx, vrsa, \ + rsa_sigalg_set_ctx_params, \ + params, #MD, \ + EVP_PKEY_OP_VERIFYMSG, \ + RSA_PKCS1_PADDING, \ + desc); \ + } \ + \ + const OSSL_DISPATCH ossl_rsa_##md##_signature_functions[] = { \ + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx }, \ + { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ + (void (*)(void))rsa_##md##_sign_init }, \ + { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \ + (void (*)(void))rsa_##md##_sign_message_init }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \ + (void (*)(void))rsa_signverify_message_update }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \ + (void (*)(void))rsa_sign_message_final }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ + (void (*)(void))rsa_##md##_verify_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY, \ + (void (*)(void))rsa_verify }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \ + (void (*)(void))rsa_##md##_verify_message_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \ + (void (*)(void))rsa_signverify_message_update }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \ + (void (*)(void))rsa_verify_message_final }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, \ + (void (*)(void))rsa_##md##_verify_recover_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, \ + (void (*)(void))rsa_verify_recover }, \ + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx }, \ + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))rsa_dupctx }, \ + { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \ + (void (*)(void))rsa_sigalg_query_key_types }, \ + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ + (void (*)(void))rsa_get_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ + (void (*)(void))rsa_gettable_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ + (void (*)(void))rsa_sigalg_set_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ + (void (*)(void))rsa_sigalg_settable_ctx_params }, \ + OSSL_DISPATCH_END \ + } + +#if !defined(OPENSSL_NO_RMD160) && !defined(FIPS_MODULE) +IMPL_RSA_SIGALG(ripemd160, RIPEMD160); +#endif +IMPL_RSA_SIGALG(sha1, SHA1); +IMPL_RSA_SIGALG(sha224, SHA2-224); +IMPL_RSA_SIGALG(sha256, SHA2-256); +IMPL_RSA_SIGALG(sha384, SHA2-384); +IMPL_RSA_SIGALG(sha512, SHA2-512); +IMPL_RSA_SIGALG(sha512_224, SHA2-512/224); +IMPL_RSA_SIGALG(sha512_256, SHA2-512/256); +IMPL_RSA_SIGALG(sha3_224, SHA3-224); +IMPL_RSA_SIGALG(sha3_256, SHA3-256); +IMPL_RSA_SIGALG(sha3_384, SHA3-384); +IMPL_RSA_SIGALG(sha3_512, SHA3-512); +#if !defined(OPENSSL_NO_SM3) && !defined(FIPS_MODULE) +IMPL_RSA_SIGALG(sm3, SM3); +#endif |