X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fpmeth_lib.c;h=f4bc49fe0fb86d53be555283742849701de59676;hp=7563c800f791e3df492734a45b3f245339d9ddc4;hb=4fe54d674f14e7964f982285d1aeb86698a33c3c;hpb=2555285fa5e4248ad4a5a0bc14ae4606443856c2 diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 7563c800f7..f4bc49fe0f 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -23,6 +23,8 @@ #include "internal/provider.h" #include "evp_local.h" +#ifndef FIPS_MODE + typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void); typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); @@ -30,50 +32,50 @@ static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; /* This array needs to be in order of NIDs */ static pmeth_fn standard_methods[] = { -#ifndef OPENSSL_NO_RSA +# ifndef OPENSSL_NO_RSA rsa_pkey_method, -#endif -#ifndef OPENSSL_NO_DH +# endif +# ifndef OPENSSL_NO_DH dh_pkey_method, -#endif -#ifndef OPENSSL_NO_DSA +# endif +# ifndef OPENSSL_NO_DSA dsa_pkey_method, -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC ec_pkey_method, -#endif +# endif hmac_pkey_method, -#ifndef OPENSSL_NO_CMAC +# ifndef OPENSSL_NO_CMAC cmac_pkey_method, -#endif -#ifndef OPENSSL_NO_RSA +# endif +# ifndef OPENSSL_NO_RSA rsa_pss_pkey_method, -#endif -#ifndef OPENSSL_NO_DH +# endif +# ifndef OPENSSL_NO_DH dhx_pkey_method, -#endif -#ifndef OPENSSL_NO_SCRYPT +# endif +# ifndef OPENSSL_NO_SCRYPT scrypt_pkey_method, -#endif +# endif tls1_prf_pkey_method, -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC ecx25519_pkey_method, ecx448_pkey_method, -#endif +# endif hkdf_pkey_method, -#ifndef OPENSSL_NO_POLY1305 +# ifndef OPENSSL_NO_POLY1305 poly1305_pkey_method, -#endif -#ifndef OPENSSL_NO_SIPHASH +# endif +# ifndef OPENSSL_NO_SIPHASH siphash_pkey_method, -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC ed25519_pkey_method, ed448_pkey_method, -#endif -#ifndef OPENSSL_NO_SM2 +# endif +# ifndef OPENSSL_NO_SM2 sm2_pkey_method, -#endif +# endif }; DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func); @@ -112,10 +114,27 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) return (**ret)(); } +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + + pmeth = OPENSSL_zalloc(sizeof(*pmeth)); + if (pmeth == NULL) { + EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + return pmeth; +} +#endif /* FIPS_MODE */ + static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, EVP_PKEY *pkey, ENGINE *e, const char *name, const char *propquery, int id) + { EVP_PKEY_CTX *ret; const EVP_PKEY_METHOD *pmeth = NULL; @@ -127,11 +146,28 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, if (pkey == NULL && e == NULL && id == -1) goto common; + /* + * If the key doesn't contain anything legacy, then it must be provided, + * so we extract the necessary information and use that. + */ + if (pkey != NULL && pkey->ameth == NULL) { + /* If we have an engine, something went wrong somewhere... */ + if (!ossl_assert(e == NULL)) + return NULL; + name = evp_first_name(pkey->pkeys[0].keymgmt->prov, + pkey->pkeys[0].keymgmt->name_id); + /* + * TODO: I wonder if the EVP_PKEY should have the name and propquery + * that were used when building it.... /RL + */ + goto common; + } +#ifndef FIPS_MODE /* TODO(3.0) Legacy code should be removed when all is provider based */ /* BEGIN legacy */ if (id == -1) { if (pkey == NULL) - return 0; + return NULL; id = pkey->type; } @@ -150,19 +186,8 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, return NULL; if (e == NULL) name = OBJ_nid2sn(id); - propquery = NULL; - /* - * We were called using legacy data, or an EVP_PKEY, but an EVP_PKEY - * isn't tied to a specific library context, so we fall back to the - * default library context. - * TODO(v3.0): an EVP_PKEY that doesn't originate from a leagacy key - * structure only has the pkeys[] cache, where the first element is - * considered the "origin". Investigate if that could be a suitable - * way to find a library context. - */ - libctx = NULL; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE if (e == NULL && pkey != NULL) e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine; /* Try to find an ENGINE which implements this method */ @@ -182,29 +207,29 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, if (e) pmeth = ENGINE_get_pkey_meth(e, id); else -#endif +# endif pmeth = EVP_PKEY_meth_find(id); if (pmeth == NULL) { -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE ENGINE_finish(e); -#endif +# endif EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); return NULL; } /* END legacy */ - +#endif /* FIPS_MODE */ common: ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ENGINE_finish(e); #endif EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } ret->libctx = libctx; - ret->algorithm = name; + ret->keytype = name; ret->propquery = propquery; ret->engine = e; ret->pmeth = pmeth; @@ -224,44 +249,68 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, return ret; } +/*- All methods below can also be used in FIPS_MODE */ + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx, + const char *name, + const char *propquery) +{ + return int_ctx_new(libctx, NULL, NULL, name, propquery, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey, + const char *propquery) +{ + return int_ctx_new(libctx, pkey, NULL, NULL, propquery, -1); +} + void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) { - if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { - if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL) - ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx); - EVP_KEYEXCH_free(ctx->op.kex.exchange); - ctx->op.kex.exchprovctx = NULL; - ctx->op.kex.exchange = NULL; - } else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { if (ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL) ctx->op.sig.signature->freectx(ctx->op.sig.sigprovctx); EVP_SIGNATURE_free(ctx->op.sig.signature); ctx->op.sig.sigprovctx = NULL; ctx->op.sig.signature = NULL; - } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + } else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL) + ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx); + EVP_KEYEXCH_free(ctx->op.kex.exchange); + ctx->op.kex.exchprovctx = NULL; + ctx->op.kex.exchange = NULL; + } +/* TODO(3.0): add dependancies and uncomment this when available for fips mode */ +#ifndef FIPS_MODE + else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL) ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx); EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher); ctx->op.ciph.ciphprovctx = NULL; ctx->op.ciph.cipher = NULL; } +#endif } -EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { - EVP_PKEY_METHOD *pmeth; + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); - pmeth = OPENSSL_zalloc(sizeof(*pmeth)); - if (pmeth == NULL) { - EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } + evp_pkey_ctx_free_old_ops(ctx); + EVP_KEYMGMT_free(ctx->keymgmt); - pmeth->pkey_id = id; - pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; - return pmeth; + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) + ENGINE_finish(ctx->engine); +#endif + OPENSSL_free(ctx); } +#ifndef FIPS_MODE + void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth) { @@ -330,13 +379,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) return int_ctx_new(NULL, NULL, e, NULL, NULL, id); } -EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx, - const char *name, - const char *propquery) -{ - return int_ctx_new(libctx, NULL, NULL, name, propquery, -1); -} - EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) { EVP_PKEY_CTX *rctx; @@ -347,13 +389,13 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) || (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx) && pctx->op.sig.sigprovctx == NULL))) return NULL; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a pkey context using an ENGINE */ if (pctx->engine && !ENGINE_init(pctx->engine)) { EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); return 0; } -#endif +# endif rctx = OPENSSL_zalloc(sizeof(*rctx)); if (rctx == NULL) { EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE); @@ -365,7 +407,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) rctx->pkey = pctx->pkey; rctx->operation = pctx->operation; rctx->libctx = pctx->libctx; - rctx->algorithm = pctx->algorithm; + rctx->keytype = pctx->keytype; rctx->propquery = pctx->propquery; if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) { @@ -431,9 +473,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) } rctx->pmeth = pctx->pmeth; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE rctx->engine = pctx->engine; -#endif +# endif if (pctx->peerkey) EVP_PKEY_up_ref(pctx->peerkey); @@ -500,27 +542,40 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx) return NULL; return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); } +#endif -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) { - if (ctx == NULL) - return; - if (ctx->pmeth && ctx->pmeth->cleanup) - ctx->pmeth->cleanup(ctx); - - evp_pkey_ctx_free_old_ops(ctx); - EVP_KEYMGMT_free(ctx->keymgmt); - - EVP_PKEY_free(ctx->pkey); - EVP_PKEY_free(ctx->peerkey); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(ctx->engine); -#endif - OPENSSL_free(ctx); + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchprovctx != NULL + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->set_ctx_params != NULL) + return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx, + params); + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx != NULL + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->set_ctx_params != NULL) + return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx, + params); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->set_ctx_params != NULL) + return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx, + params); + return 0; } +#ifndef FIPS_MODE int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) { + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchprovctx != NULL + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->get_ctx_params != NULL) + return ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.exchprovctx, + params); if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) && ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL @@ -538,6 +593,10 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx) { + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->gettable_ctx_params != NULL) + return ctx->op.kex.exchange->gettable_ctx_params(); if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) && ctx->op.sig.signature != NULL && ctx->op.sig.signature->gettable_ctx_params != NULL) @@ -551,29 +610,6 @@ const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx) return NULL; } -int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) -{ - if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) - && ctx->op.kex.exchprovctx != NULL - && ctx->op.kex.exchange != NULL - && ctx->op.kex.exchange->set_ctx_params != NULL) - return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx, - params); - if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL - && ctx->op.sig.signature != NULL - && ctx->op.sig.signature->set_ctx_params != NULL) - return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx, - params); - if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) - && ctx->op.ciph.ciphprovctx != NULL - && ctx->op.ciph.cipher != NULL - && ctx->op.ciph.cipher->set_ctx_params != NULL) - return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx, - params); - return 0; -} - const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) { if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) @@ -592,7 +628,53 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) return NULL; } -#ifndef OPENSSL_NO_DH +/* + * Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params(). + * + * Return 1 on success, 0 or negative for errors. + * + * In particular they return -2 if any of the params is not supported. + * + * They are not available in FIPS_MODE as they depend on + * - EVP_PKEY_CTX_{get,set}_params() + * - EVP_PKEY_CTX_{gettable,settable}_params() + * + */ +int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + const OSSL_PARAM *p; + + if (ctx == NULL || params == NULL) + return 0; + + for (p = params; p->key != NULL; p++) { + /* Check the ctx actually understands this parameter */ + if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_settable_params(ctx), + p->key) == NULL ) + return -2; + } + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + const OSSL_PARAM *p; + + if (ctx == NULL || params == NULL) + return 0; + + for (p = params; p->key != NULL; p++ ) { + /* Check the ctx actually understands this parameter */ + if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_gettable_params(ctx), + p->key) == NULL ) + return -2; + } + + return EVP_PKEY_CTX_get_params(ctx, params); +} + +# ifndef OPENSSL_NO_DH int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) { OSSL_PARAM dh_pad_params[2]; @@ -614,7 +696,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) return EVP_PKEY_CTX_set_params(ctx, dh_pad_params); } -#endif +# endif int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) { @@ -653,8 +735,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { - OSSL_PARAM sig_md_params[3], *p = sig_md_params; - size_t mdsize; + OSSL_PARAM sig_md_params[2], *p = sig_md_params; const char *name; if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { @@ -670,9 +751,7 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) if (md == NULL) { name = ""; - mdsize = 0; } else { - mdsize = EVP_MD_size(md); name = EVP_MD_name(md); } @@ -681,10 +760,7 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) * Cast away the const. This is read * only so should be safe */ - (char *)name, - strlen(name) + 1); - *p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, - &mdsize); + (char *)name, 0); *p++ = OSSL_PARAM_construct_end(); return EVP_PKEY_CTX_set_params(ctx, sig_md_params); @@ -693,42 +769,81 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { - switch (cmd) { -#ifndef OPENSSL_NO_DH - case EVP_PKEY_CTRL_DH_PAD: - return EVP_PKEY_CTX_set_dh_pad(ctx, p1); -#endif - case EVP_PKEY_CTRL_MD: - return EVP_PKEY_CTX_set_signature_md(ctx, p2); - case EVP_PKEY_CTRL_GET_MD: - return EVP_PKEY_CTX_get_signature_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_PADDING: - return EVP_PKEY_CTX_set_rsa_padding(ctx, p1); - case EVP_PKEY_CTRL_GET_RSA_PADDING: - return EVP_PKEY_CTX_get_rsa_padding(ctx, p2); - case EVP_PKEY_CTRL_RSA_OAEP_MD: - return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: - return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_MGF1_MD: - return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: - return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_OAEP_LABEL: - return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1); - case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: - return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2); - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: -#ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_DECRYPT: - case EVP_PKEY_CTRL_CMS_ENCRYPT: -#endif - if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) - return 1; - ERR_raise(ERR_LIB_EVP, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; +# ifndef OPENSSL_NO_DH + if (keytype == EVP_PKEY_DH) { + switch (cmd) { + case EVP_PKEY_CTRL_DH_PAD: + return EVP_PKEY_CTX_set_dh_pad(ctx, p1); + } + } +# endif +# ifndef OPENSSL_NO_EC + if (keytype == EVP_PKEY_EC) { + switch (cmd) { + case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: + if (p1 == -2) { + return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx); + } else if (p1 < -1 || p1 > 1) { + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else { + return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, p1); + } + case EVP_PKEY_CTRL_EC_KDF_TYPE: + if (p1 == -2) { + return EVP_PKEY_CTX_get_ecdh_kdf_type(ctx); + } else { + return EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, p1); + } + case EVP_PKEY_CTRL_GET_EC_KDF_MD: + return EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_MD: + return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: + return EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_OUTLEN: + return EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, p1); + case EVP_PKEY_CTRL_GET_EC_KDF_UKM: + return EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_UKM: + return EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p2, p1); + } + } +# endif + if (keytype == -1) { + switch (cmd) { + case EVP_PKEY_CTRL_MD: + return EVP_PKEY_CTX_set_signature_md(ctx, p2); + case EVP_PKEY_CTRL_GET_MD: + return EVP_PKEY_CTX_get_signature_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_PADDING: + return EVP_PKEY_CTX_set_rsa_padding(ctx, p1); + case EVP_PKEY_CTRL_GET_RSA_PADDING: + return EVP_PKEY_CTX_get_rsa_padding(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_MGF1_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1); + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2); + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: +# ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: +# endif + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 1; + ERR_raise(ERR_LIB_EVP, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } } return 0; } @@ -789,76 +904,43 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, const char *value) { -#ifndef OPENSSL_NO_DH - if (strcmp(name, "dh_pad") == 0) { - int pad; - - pad = atoi(value); - return EVP_PKEY_CTX_set_dh_pad(ctx, pad); - } -#endif - if (strcmp(name, "digest") == 0) { - int ret; - EVP_MD *md; - - if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) || ctx->op.sig.signature == NULL) - return 0; - md = EVP_MD_fetch(ossl_provider_library_context(ctx->op.sig.signature->prov), - value, NULL); - if (md == NULL) - return 0; - ret = EVP_PKEY_CTX_set_signature_md(ctx, md); - EVP_MD_meth_free(md); - return ret; - } - - if (strcmp(name, "rsa_padding_mode") == 0) { - int pm; - - if (strcmp(value, "pkcs1") == 0) { - pm = RSA_PKCS1_PADDING; - } else if (strcmp(value, "sslv23") == 0) { - pm = RSA_SSLV23_PADDING; - } else if (strcmp(value, "none") == 0) { - pm = RSA_NO_PADDING; - } else if (strcmp(value, "oeap") == 0) { - pm = RSA_PKCS1_OAEP_PADDING; - } else if (strcmp(value, "oaep") == 0) { - pm = RSA_PKCS1_OAEP_PADDING; - } else if (strcmp(value, "x931") == 0) { - pm = RSA_X931_PADDING; - } else if (strcmp(value, "pss") == 0) { - pm = RSA_PKCS1_PSS_PADDING; - } else { - ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); - return -2; - } - return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); - } - - if (strcmp(name, "rsa_mgf1_md") == 0) - return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, value, NULL); - - if (strcmp(name, "rsa_oaep_md") == 0) - return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, value, NULL); - - if (strcmp(name, "rsa_oaep_label") == 0) { - unsigned char *lab; - long lablen; - int ret; - - lab = OPENSSL_hexstr2buf(value, &lablen); - if (lab == NULL) + if (strcmp(name, "rsa_padding_mode") == 0) + name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE; + else if (strcmp(name, "rsa_mgf1_md") == 0) + name = OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST; + else if (strcmp(name, "rsa_oaep_md") == 0) + name = OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST; + else if (strcmp(name, "rsa_oaep_label") == 0) + name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL; +# ifndef OPENSSL_NO_DH + else if (strcmp(name, "dh_pad") == 0) + name = OSSL_EXCHANGE_PARAM_PAD; +# endif +# ifndef OPENSSL_NO_EC + else if (strcmp(name, "ecdh_cofactor_mode") == 0) + name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE; + else if (strcmp(name, "ecdh_kdf_md") == 0) + name = OSSL_EXCHANGE_PARAM_KDF_TYPE; +# endif + + { + /* + * TODO(3.0) reduce the code above to only translate known legacy + * string to the corresponding core name (see core_names.h), but + * otherwise leave it to this code block to do the actual work. + */ + const OSSL_PARAM *settable = EVP_PKEY_CTX_settable_params(ctx); + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int rv = 0; + + if (!OSSL_PARAM_allocate_from_text(¶ms[0], settable, name, value, + strlen(value))) return 0; - ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); - if (ret <= 0) - OPENSSL_free(lab); - return ret; + if (EVP_PKEY_CTX_set_params(ctx, params)) + rv = 1; + OPENSSL_free(params[0].data); + return rv; } - - - - return 0; } int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, @@ -1363,3 +1445,5 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, if (pdigest_custom != NULL) *pdigest_custom = pmeth->digest_custom; } + +#endif /* FIPS_MODE */