From 2c6094baca6476d8b024dc7d9f461dae597ae797 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 6 May 2020 21:44:58 +0200 Subject: [PATCH] EVP: For SIGNATURE operations, pass the propquery early Instead of passing it with signature->digest_verify_init() and signature->digest_sign_init(), we pass it with signature->newctx(). This allows the digests that are indicated by RSA PSS parameters to have a useful propquery. Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/11710) --- crypto/evp/m_sigver.c | 9 +++-- crypto/evp/signature.c | 3 +- include/openssl/core_numbers.h | 9 ++--- providers/implementations/signature/dsa.c | 15 ++++++-- providers/implementations/signature/ecdsa.c | 12 ++++-- providers/implementations/signature/eddsa.c | 4 +- providers/implementations/signature/rsa.c | 42 +++++++++++++++------ 7 files changed, 65 insertions(+), 29 deletions(-) diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index c77683a69d..44e7cab1af 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -71,6 +71,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, locpctx = ctx->pctx; evp_pkey_ctx_free_old_ops(locpctx); + if (props == NULL) + props = locpctx->propquery; + /* * TODO when we stop falling back to legacy, this and the ERR_pop_to_mark() * calls can be removed. @@ -142,7 +145,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX : EVP_PKEY_OP_SIGNCTX; locpctx->op.sig.sigprovctx - = signature->newctx(ossl_provider_ctx(signature->prov)); + = signature->newctx(ossl_provider_ctx(signature->prov), props); if (locpctx->op.sig.sigprovctx == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; @@ -182,14 +185,14 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, goto err; } ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx, - mdname, props, provkey); + mdname, provkey); } else { if (signature->digest_sign_init == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; } ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx, - mdname, props, provkey); + mdname, provkey); } return ret ? 1 : 0; diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c index b7a7f79606..595a93e66e 100644 --- a/crypto/evp/signature.c +++ b/crypto/evp/signature.c @@ -417,7 +417,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) /* No more legacy from here down to legacy: */ ctx->op.sig.signature = signature; - ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov)); + ctx->op.sig.sigprovctx = + signature->newctx(ossl_provider_ctx(signature->prov), ctx->propquery); if (ctx->op.sig.sigprovctx == NULL) { /* The provider key can stay in the cache */ EVPerr(0, EVP_R_INITIALIZATION_ERROR); diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 6af086fc2b..3d91741601 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -524,7 +524,8 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keyexch_gettable_ctx_params, # define OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS 24 # define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS 25 -OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx, + const char *propq)) OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey)) OSSL_CORE_MAKE_FUNC(int, OP_signature_sign, (void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize, @@ -545,8 +546,7 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_verify_recover, (void *ctx, const unsigned char *sig, size_t siglen)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign_init, - (void *ctx, const char *mdname, const char *props, - void *provkey)) + (void *ctx, const char *mdname, void *provkey)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign_update, (void *ctx, const unsigned char *data, size_t datalen)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign_final, @@ -556,8 +556,7 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign, (void *ctx, unsigned char *sigret, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_init, - (void *ctx, const char *mdname, const char *props, - void *provkey)) + (void *ctx, const char *mdname, void *provkey)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_update, (void *ctx, const unsigned char *data, size_t datalen)) OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_final, diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index f0662d1ee8..bfab22488f 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -63,6 +63,7 @@ static OSSL_OP_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params; typedef struct { OPENSSL_CTX *libctx; + char *propq; DSA *dsa; /* @@ -131,7 +132,7 @@ static int dsa_get_md_nid(const EVP_MD *md) return mdnid; } -static void *dsa_newctx(void *provctx) +static void *dsa_newctx(void *provctx, const char *propq) { PROV_DSA_CTX *pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX)); @@ -140,12 +141,20 @@ static void *dsa_newctx(void *provctx) pdsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); pdsactx->flag_allow_md = 1; + if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { + OPENSSL_free(pdsactx); + pdsactx = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } return pdsactx; } static int dsa_setup_md(PROV_DSA_CTX *ctx, const char *mdname, const char *mdprops) { + if (mdprops == NULL) + mdprops = ctx->propq; + if (mdname != NULL) { EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = dsa_get_md_nid(md); @@ -234,7 +243,7 @@ static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, } static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, - const char *props, void *vdsa) + void *vdsa) { PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; @@ -242,7 +251,7 @@ static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, if (!dsa_signature_init(vpdsactx, vdsa)) return 0; - if (!dsa_setup_md(pdsactx, mdname, props)) + if (!dsa_setup_md(pdsactx, mdname, NULL)) return 0; pdsactx->mdctx = EVP_MD_CTX_new(); diff --git a/providers/implementations/signature/ecdsa.c b/providers/implementations/signature/ecdsa.c index e05830f500..267950d537 100644 --- a/providers/implementations/signature/ecdsa.c +++ b/providers/implementations/signature/ecdsa.c @@ -60,6 +60,7 @@ static OSSL_OP_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_params; typedef struct { OPENSSL_CTX *libctx; + char *propq; EC_KEY *ec; char mdname[OSSL_MAX_NAME_SIZE]; @@ -90,7 +91,7 @@ typedef struct { BIGNUM *r; } PROV_ECDSA_CTX; -static void *ecdsa_newctx(void *provctx) +static void *ecdsa_newctx(void *provctx, const char *propq) { PROV_ECDSA_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX)); @@ -98,6 +99,11 @@ static void *ecdsa_newctx(void *provctx) return NULL; ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { + OPENSSL_free(ctx); + ctx = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } return ctx; } @@ -203,7 +209,7 @@ static void free_md(PROV_ECDSA_CTX *ctx) } static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, - const char *props, void *ec) + void *ec) { PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; int md_nid = NID_undef; @@ -214,7 +220,7 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, if (!ecdsa_signature_init(vctx, ec)) return 0; - ctx->md = EVP_MD_fetch(ctx->libctx, mdname, props); + ctx->md = EVP_MD_fetch(ctx->libctx, mdname, ctx->propq); if ((md_nid = get_md_nid(ctx->md)) == NID_undef) goto error; diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c index 1a7bf94702..4ecc5266e2 100644 --- a/providers/implementations/signature/eddsa.c +++ b/providers/implementations/signature/eddsa.c @@ -36,7 +36,7 @@ typedef struct { ECX_KEY *key; } PROV_EDDSA_CTX; -static void *eddsa_newctx(void *provctx) +static void *eddsa_newctx(void *provctx, const char *propq_unused) { PROV_EDDSA_CTX *peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); @@ -51,7 +51,7 @@ static void *eddsa_newctx(void *provctx) } static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, - const char *props, void *vedkey) + void *vedkey) { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; ECX_KEY *edkey = (ECX_KEY *)vedkey; diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c index a59b234a2c..27e35be3c9 100644 --- a/providers/implementations/signature/rsa.c +++ b/providers/implementations/signature/rsa.c @@ -73,6 +73,7 @@ static OSSL_ITEM padding_item[] = { typedef struct { OPENSSL_CTX *libctx; + char *propq; RSA *rsa; int operation; @@ -180,7 +181,7 @@ static int rsa_check_padding(int mdnid, int padding) return 1; } -static void *rsa_newctx(void *provctx) +static void *rsa_newctx(void *provctx, const char *propq) { PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); @@ -189,6 +190,11 @@ static void *rsa_newctx(void *provctx) prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); prsactx->flag_allow_md = 1; + if (propq != NULL && (prsactx->propq = OPENSSL_strdup(propq)) == NULL) { + OPENSSL_free(prsactx); + prsactx = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } return prsactx; } @@ -219,6 +225,9 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, const char *mdprops) { + if (mdprops == NULL) + mdprops = ctx->propq; + if (mdname != NULL) { EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = rsa_get_md_nid(md); @@ -260,12 +269,15 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, } static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, - const char *props) + const char *mdprops) { + if (mdprops == NULL) + mdprops = ctx->propq; + if (ctx->mgf1_mdname[0] != '\0') EVP_MD_free(ctx->mgf1_md); - if ((ctx->mgf1_md = EVP_MD_fetch(ctx->libctx, mdname, props)) == NULL) + if ((ctx->mgf1_md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) return 0; OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); @@ -592,14 +604,13 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, } static int rsa_digest_signverify_init(void *vprsactx, const char *mdname, - const char *props, void *vrsa, - int operation) + void *vrsa, int operation) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; prsactx->flag_allow_md = 0; if (!rsa_signature_init(vprsactx, vrsa, operation) - || !rsa_setup_md(prsactx, mdname, props)) + || !rsa_setup_md(prsactx, mdname, NULL)) return 0; prsactx->mdctx = EVP_MD_CTX_new(); @@ -706,6 +717,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->propq); free_tbuf(prsactx); OPENSSL_clear_free(prsactx, sizeof(prsactx)); @@ -869,8 +881,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) return 0; - if (propsp != NULL - && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) + + if (propsp == NULL) + pmdprops = NULL; + else if (!OSSL_PARAM_get_utf8_string(propsp, + &pmdprops, sizeof(mdprops))) return 0; /* TODO(3.0) PSS check needs more work */ @@ -883,7 +898,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) } /* non-PSS code follows */ - if (!rsa_setup_md(prsactx, mdname, mdprops)) + if (!rsa_setup_md(prsactx, mdname, pmdprops)) return 0; } @@ -1054,8 +1069,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) return 0; - if (propsp != NULL - && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) + + if (propsp == NULL) + pmdprops = NULL; + else if (!OSSL_PARAM_get_utf8_string(propsp, + &pmdprops, sizeof(mdprops))) return 0; if (prsactx->pad_mode != RSA_PKCS1_PSS_PADDING) { @@ -1073,7 +1091,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) } /* non-PSS code follows */ - if (!rsa_setup_mgf1_md(prsactx, mdname, mdprops)) + if (!rsa_setup_mgf1_md(prsactx, mdname, pmdprops)) return 0; }