From e74bd29053a543ab4908ae8545b46f2e38c98bab Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 7 May 2019 12:39:58 +0200 Subject: [PATCH] Prepare EVP_MAC infrastructure for moving all MACs to providers Quite a few adaptations are needed, most prominently the added code to allow provider based MACs. As part of this, all the old information functions are gone, except for EVP_MAC_name(). Some of them will reappear later, for example EVP_MAC_do_all() in some form. MACs by EVP_PKEY was particularly difficult to deal with, as they need to allocate and deallocate EVP_MAC_CTXs "under the hood", and thereby implicitly fetch the corresponding EVP_MAC. This means that EVP_MACs can't be constant in a EVP_MAC_CTX, as their reference count may need to be incremented and decremented as part of the allocation or deallocation of the EVP_MAC_CTX. It may be that other provider based EVP operation types may need to be handled in a similar manner. Reviewed-by: Matt Caswell Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/8877) --- apps/list.c | 4 + crypto/cmac/cm_ameth.c | 3 + crypto/evp/build.info | 2 +- crypto/evp/evp_locl.h | 2 +- crypto/evp/mac_lib.c | 162 +++++-------- crypto/evp/mac_meth.c | 195 +++++++++++++++ crypto/evp/p_lib.c | 32 ++- crypto/evp/pkey_mac.c | 186 +++++++++++--- crypto/include/internal/evp_int.h | 40 ++- crypto/provider_core.c | 7 +- doc/internal/man3/ossl_provider_new.pod | 9 + doc/man3/EVP_MAC.pod | 309 ++++++++++++------------ doc/man7/provider-mac.pod | 255 +++++++++++++++++++ include/internal/provider.h | 1 + include/openssl/core_names.h | 20 ++ include/openssl/core_numbers.h | 36 +++ include/openssl/crypto.h | 4 +- include/openssl/evp.h | 60 ++--- ssl/ssl_init.c | 3 +- util/libcrypto.num | 30 ++- 20 files changed, 982 insertions(+), 378 deletions(-) create mode 100644 crypto/evp/mac_meth.c create mode 100644 doc/man7/provider-mac.pod diff --git a/apps/list.c b/apps/list.c index c22a2c6267..555ce7e815 100644 --- a/apps/list.c +++ b/apps/list.c @@ -229,6 +229,7 @@ static void list_digests(void) sk_EVP_MD_pop_free(digests, EVP_MD_meth_free); } +#if 0 /* Temporarly disabled */ static void list_mac_fn(const EVP_MAC *m, const char *from, const char *to, void *arg) { @@ -242,6 +243,7 @@ static void list_mac_fn(const EVP_MAC *m, BIO_printf(arg, "%s => %s\n", from, to); } } +#endif static void list_missing_help(void) { @@ -704,8 +706,10 @@ opthelp: list_type(FT_md, one); if (todo.digest_algorithms) list_digests(); +#if 0 /* Temporarly disabled */ if (todo.mac_algorithms) EVP_MAC_do_all_sorted(list_mac_fn, bio_out); +#endif if (todo.cipher_commands) list_type(FT_cipher, one); if (todo.cipher_algorithms) diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c index ed513b113f..b1ee0d3d2f 100644 --- a/crypto/cmac/cm_ameth.c +++ b/crypto/cmac/cm_ameth.c @@ -25,7 +25,10 @@ static int cmac_size(const EVP_PKEY *pkey) static void cmac_key_free(EVP_PKEY *pkey) { EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey); + EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx); + EVP_MAC_CTX_free(cmctx); + EVP_MAC_free(mac); } const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { diff --git a/crypto/evp/build.info b/crypto/evp/build.info index c650c28882..eb675f3f97 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -16,7 +16,7 @@ SOURCE[../../libcrypto]=$COMMON\ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ - mac_lib.c c_allm.c pkey_mac.c exchange.c + mac_lib.c mac_meth.c c_allm.c pkey_mac.c exchange.c SOURCE[../../providers/fips]=$COMMON INCLUDE[e_aes.o]=.. ../modes diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 59072e368b..3fd73212a4 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -56,7 +56,7 @@ struct evp_cipher_ctx_st { } /* EVP_CIPHER_CTX */ ; struct evp_mac_ctx_st { - const EVP_MAC *meth; /* Method structure */ + EVP_MAC *meth; /* Method structure */ void *data; /* Individual method data */ } /* EVP_MAC_CTX */; diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index ee4a68f459..7b07b55e3d 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -11,26 +11,24 @@ #include #include #include +#include +#include #include #include "internal/nelem.h" #include "internal/evp_int.h" +#include "internal/provider.h" #include "evp_locl.h" -EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id) -{ - const EVP_MAC *mac = EVP_get_macbynid(id); - - if (mac == NULL) - return NULL; - return EVP_MAC_CTX_new(mac); -} - -EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac) +EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) { EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX)); - if (ctx == NULL || (ctx->data = mac->new()) == NULL) { + if (ctx == NULL + || (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL + || !EVP_MAC_up_ref(mac)) { EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + mac->freectx(ctx->data); OPENSSL_free(ctx); ctx = NULL; } else { @@ -41,9 +39,11 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac) void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx) { - if (ctx != NULL && ctx->data != NULL) { - ctx->meth->free(ctx->data); + if (ctx != NULL) { + ctx->meth->freectx(ctx->data); ctx->data = NULL; + /* refcnt-- */ + EVP_MAC_free(ctx->meth); } OPENSSL_free(ctx); } @@ -62,8 +62,13 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) } *dst = *src; + if (!EVP_MAC_up_ref(dst->meth)) { + EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } - dst->data = src->meth->dup(src->data); + dst->data = src->meth->dupctx(src->data); if (dst->data == NULL) { EVP_MAC_CTX_free(dst); return NULL; @@ -72,16 +77,31 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) return dst; } -const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx) +EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx) { return ctx->meth; } size_t EVP_MAC_size(EVP_MAC_CTX *ctx) { - if (ctx->data != NULL) - return ctx->meth->size(ctx->data); - /* If the MAC hasn't been initialized yet, we return zero */ + size_t sz = 0; + + if (ctx->data != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN, &sz); + if (ctx->meth->ctx_get_params != NULL) { + if (ctx->meth->ctx_get_params(ctx->data, params)) + return sz; + } else if (ctx->meth->get_params != NULL) { + if (ctx->meth->get_params(params)) + return sz; + } + } + /* + * If the MAC hasn't been initialized yet, or there is no size to get, + * we return zero + */ return 0; } @@ -97,101 +117,43 @@ int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen) return ctx->meth->update(ctx->data, data, datalen); } -int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen) +int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize) { - int l = ctx->meth->size(ctx->data); + int l = EVP_MAC_size(ctx); if (l < 0) return 0; - if (poutlen != NULL) - *poutlen = l; + if (outl != NULL) + *outl = l; if (out == NULL) return 1; - return ctx->meth->final(ctx->data, out); -} - -int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...) -{ - int ok = -1; - va_list args; - - va_start(args, cmd); - ok = EVP_MAC_vctrl(ctx, cmd, args); - va_end(args); - - if (ok == -2) - EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ok; -} - -int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args) -{ - int ok = 1; - - if (ctx == NULL || ctx->meth == NULL) - return -2; - - switch (cmd) { -#if 0 - case ...: - /* code */ - ok = 1; - break; -#endif - default: - if (ctx->meth->ctrl != NULL) - ok = ctx->meth->ctrl(ctx->data, cmd, args); - else - ok = -2; - break; - } - - return ok; -} - -int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value) -{ - int ok = 1; - - if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) { - EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - - ok = ctx->meth->ctrl_str(ctx->data, type, value); - - if (ok == -2) - EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return ok; + return ctx->meth->final(ctx->data, out, outl, outsize); } -int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value) +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]) { - size_t len; - - len = strlen(value); - if (len > INT_MAX) - return -1; - return EVP_MAC_ctrl(ctx, cmd, value, len); + if (mac->get_params != NULL) + return mac->get_params(params); + return 1; } -int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex) +int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]) { - unsigned char *bin; - long binlen; - int rv = -1; - - bin = OPENSSL_hexstr2buf(hex, &binlen); - if (bin == NULL) - return 0; - if (binlen <= INT_MAX) - rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen); - OPENSSL_free(bin); - return rv; + if (ctx->meth->ctx_get_params != NULL) + return ctx->meth->ctx_get_params(ctx->data, params); + return 1; } -int EVP_MAC_nid(const EVP_MAC *mac) +int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]) { - return mac->type; + if (ctx->meth->ctx_set_params != NULL) + return ctx->meth->ctx_set_params(ctx->data, params); + return 1; } diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c new file mode 100644 index 0000000000..983b2dbd2e --- /dev/null +++ b/crypto/evp/mac_meth.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include "internal/evp_int.h" +#include "internal/provider.h" +#include "evp_locl.h" + +static int evp_mac_up_ref(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock); + return 1; +} + +static void evp_mac_free(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + if (mac == NULL) + return; + + CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock); + if (ref > 0) + return; + ossl_provider_free(mac->prov); + OPENSSL_free(mac->name); + CRYPTO_THREAD_lock_free(mac->lock); + OPENSSL_free(mac); +} + +static void *evp_mac_new(void) +{ + EVP_MAC *mac = NULL; + + if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL + || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) { + evp_mac_free(mac); + return NULL; + } + + mac->refcnt = 1; + + return mac; +} + +static void *evp_mac_from_dispatch(const char *name, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) +{ + EVP_MAC *mac = NULL; + int fnmaccnt = 0, fnctxcnt = 0; + + if ((mac = evp_mac_new()) == NULL + || (mac->name = OPENSSL_strdup(name)) == NULL) { + EVP_MAC_free(mac); + EVPerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_MAC_NEWCTX: + if (mac->newctx != NULL) + break; + mac->newctx = OSSL_get_OP_mac_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_DUPCTX: + if (mac->dupctx != NULL) + break; + mac->dupctx = OSSL_get_OP_mac_dupctx(fns); + break; + case OSSL_FUNC_MAC_FREECTX: + if (mac->freectx != NULL) + break; + mac->freectx = OSSL_get_OP_mac_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_INIT: + if (mac->init != NULL) + break; + mac->init = OSSL_get_OP_mac_init(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_UPDATE: + if (mac->update != NULL) + break; + mac->update = OSSL_get_OP_mac_update(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_FINAL: + if (mac->final != NULL) + break; + mac->final = OSSL_get_OP_mac_final(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_GETTABLE_PARAMS: + if (mac->gettable_params != NULL) + break; + mac->gettable_params = + OSSL_get_OP_mac_gettable_params(fns); + break; + case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS: + if (mac->gettable_ctx_params != NULL) + break; + mac->gettable_ctx_params = + OSSL_get_OP_mac_gettable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS: + if (mac->settable_ctx_params != NULL) + break; + mac->settable_ctx_params = + OSSL_get_OP_mac_settable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_GET_PARAMS: + if (mac->get_params != NULL) + break; + mac->get_params = OSSL_get_OP_mac_get_params(fns); + break; + case OSSL_FUNC_MAC_CTX_GET_PARAMS: + if (mac->ctx_get_params != NULL) + break; + mac->ctx_get_params = OSSL_get_OP_mac_ctx_get_params(fns); + break; + case OSSL_FUNC_MAC_CTX_SET_PARAMS: + if (mac->ctx_set_params != NULL) + break; + mac->ctx_set_params = OSSL_get_OP_mac_ctx_set_params(fns); + break; + } + } + if (fnmaccnt != 3 + || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "mac" functions, and a complete set of context + * management functions, as well as the size function. + */ + evp_mac_free(mac); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + mac->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return mac; +} + +EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties, + evp_mac_from_dispatch, evp_mac_up_ref, + evp_mac_free); +} + +int EVP_MAC_up_ref(EVP_MAC *mac) +{ + return evp_mac_up_ref(mac); +} + +void EVP_MAC_free(EVP_MAC *mac) +{ + evp_mac_free(mac); +} + +const char *EVP_MAC_name(const EVP_MAC *mac) +{ + return mac->name; +} + +const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac) +{ + if (mac->gettable_params == NULL) + return NULL; + return mac->gettable_params(); +} + +const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac) +{ + if (mac->gettable_ctx_params == NULL) + return NULL; + return mac->gettable_ctx_params(); +} + +const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac) +{ + if (mac->settable_ctx_params == NULL) + return NULL; + return mac->settable_ctx_params(); +} diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 653693e1dc..90e13f4854 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -20,9 +20,12 @@ #include #include #include +#include +#include #include "internal/asn1_int.h" #include "internal/evp_int.h" +#include "internal/provider.h" static void EVP_PKEY_free_it(EVP_PKEY *x); @@ -318,8 +321,16 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher) { #ifndef OPENSSL_NO_CMAC + const char *engine_name = e != NULL ? ENGINE_get_name(e) : NULL; + const char *cipher_name = EVP_CIPHER_name(cipher); + const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher); + OPENSSL_CTX *libctx = + prov == NULL ? NULL : ossl_provider_library_context(prov); EVP_PKEY *ret = EVP_PKEY_new(); - EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC); + EVP_MAC *cmac = EVP_MAC_fetch(libctx, "CMAC", NULL); + EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL; + OSSL_PARAM params[4]; + size_t paramsn = 0; if (ret == NULL || cmctx == NULL @@ -328,9 +339,21 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, goto err; } - if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0 - || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0 - || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) { + if (engine_name != NULL) + params[paramsn++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + (char *)engine_name, + strlen(engine_name) + 1); + params[paramsn++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM, + (char *)cipher_name, + strlen(cipher_name) + 1); + params[paramsn++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (char *)priv, len); + params[paramsn] = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_CTX_set_params(cmctx, params)) { EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); goto err; } @@ -341,6 +364,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, err: EVP_PKEY_free(ret); EVP_MAC_CTX_free(cmctx); + EVP_MAC_free(cmac); return NULL; #else EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c index fafe3c96f2..07421183ea 100644 --- a/crypto/evp/pkey_mac.c +++ b/crypto/evp/pkey_mac.c @@ -7,8 +7,12 @@ * https://www.openssl.org/source/license.html */ +#include #include #include +#include +#include +#include #include "internal/evp_int.h" #include "evp_locl.h" @@ -40,18 +44,21 @@ typedef struct { } raw_data; } MAC_PKEY_CTX; +static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); + static int pkey_mac_init(EVP_PKEY_CTX *ctx) { MAC_PKEY_CTX *hctx; + /* We're being smart and using the same base NIDs for PKEY and for MAC */ int nid = ctx->pmeth->pkey_id; + EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL); if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE); return 0; } - /* We're being smart and using the same base NIDs for PKEY and for MAC */ - hctx->ctx = EVP_MAC_CTX_new_id(nid); + hctx->ctx = EVP_MAC_CTX_new(mac); if (hctx->ctx == NULL) { OPENSSL_free(hctx); return 0; @@ -64,14 +71,13 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx) hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING; } + pkey_mac_cleanup(ctx); EVP_PKEY_CTX_set_data(ctx, hctx); ctx->keygen_info_count = 0; return 1; } -static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); - static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { MAC_PKEY_CTX *sctx, *dctx; @@ -93,6 +99,17 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) if (dctx->ctx == NULL) goto err; + /* + * Normally, nothing special would be done with the MAC method. In + * this particular case, though, the MAC method was fetched internally + * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed + * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX + * fetches the MAC method anew in this case. Therefore, its reference + * count must be adjusted here. + */ + if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx))) + goto err; + dctx->type = sctx->type; switch (dctx->type) { @@ -117,9 +134,16 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) { - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); + /* + * For the exact same reasons the MAC reference count is incremented + * in pkey_mac_copy() above, it must be explicitly freed here. + */ + + MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx); if (hctx != NULL) { + EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx); + switch (hctx->type) { case MAC_TYPE_RAW: OPENSSL_clear_free(hctx->raw_data.ktmp.data, @@ -127,6 +151,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) break; } EVP_MAC_CTX_free(hctx->ctx); + EVP_MAC_free(mac); OPENSSL_free(hctx); EVP_PKEY_CTX_set_data(ctx, NULL); } @@ -156,6 +181,8 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) if (cmkey == NULL) return 0; + if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx))) + return 0; EVP_PKEY_assign(pkey, nid, cmkey); } break; @@ -194,25 +221,34 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0; if (set_key) { - if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)) - != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx))) + if (strcmp(OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))), + EVP_MAC_name(EVP_MAC_CTX_mac(hctx->ctx))) != 0) return 0; key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); if (key == NULL) return 0; } - /* Some MACs don't support this control... that's fine */ - EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS, - EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); EVP_MD_CTX_set_update_fn(mctx, int_update); - if (set_key) - rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data, - key->length); - return rv > 0; + /* Some MACs don't support this control... that's fine */ + { + OSSL_PARAM params[3]; + size_t params_n = 0; + int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT); + + /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */ + params[params_n++] = + OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags); + if (set_key) + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + key->data, key->length); + params[params_n++] = OSSL_PARAM_construct_end(); + rv = EVP_MAC_CTX_set_params(hctx->ctx, params); + } + return rv; } static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, @@ -220,7 +256,7 @@ static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - return EVP_MAC_final(hctx->ctx, sig, siglen); + return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx)); } static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -235,14 +271,24 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return -2; /* The raw types don't support ciphers */ case MAC_TYPE_MAC: { - int rv; - - if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE, - ctx->engine)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER, - p2)) <= 0 - || !(rv = EVP_MAC_init(hctx->ctx))) - return rv; + OSSL_PARAM params[3]; + size_t params_n = 0; + char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2)); + char *engineid = (char *)ENGINE_get_id(ctx->engine); + + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + engineid, + strlen(engineid) + 1); + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM, + ciphname, + strlen(ciphname) + 1); + params[params_n] = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_CTX_set_params(hctx->ctx, params) + || !EVP_MAC_init(hctx->ctx)) + return 0; } break; default: @@ -276,8 +322,40 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) break; case EVP_PKEY_CTRL_SET_DIGEST_SIZE: - return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1); + { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t size = (size_t)p1; + size_t verify = 0; + + /* + * We verify that the length is actually set by getting back + * the same parameter and checking that it matches what we + * tried to set. + * TODO(3.0) when we have a more direct mechanism to check if + * a parameter was used, we must refactor this to use that. + */ + + params[0] = + OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN, &size); + + if (!EVP_MAC_CTX_set_params(hctx->ctx, params)) + return 0; + params[0] = + OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN, &verify); + + if (!EVP_MAC_CTX_get_params(hctx->ctx, params)) + return 0; + + /* + * Since EVP_MAC_CTX_{get,set}_params() returned successfully, + * we can only assume that the size was ignored, i.e. this + * control is unsupported. + */ + if (verify != size) + return -2; + } + break; case EVP_PKEY_CTRL_SET_MAC_KEY: switch (hctx->type) { case MAC_TYPE_RAW: @@ -287,8 +365,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 0; break; case MAC_TYPE_MAC: - if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0) - return 0; + { + OSSL_PARAM params[2]; + size_t params_n = 0; + + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + p2, p1); + params[params_n] = OSSL_PARAM_construct_end(); + + return EVP_MAC_CTX_set_params(hctx->ctx, params); + } break; default: /* This should be dead code */ @@ -303,17 +390,32 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (!EVP_MAC_init(hctx->ctx)) return 0; { - int rv; ASN1_OCTET_STRING *key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - - if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE, - ctx->engine)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD, - hctx->raw_data.md)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, - key->data, key->length)) <= 0) - return rv; + OSSL_PARAM params[4]; + size_t params_n = 0; + char *mdname = + (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md)); + char *engineid = ctx->engine == NULL + ? NULL : (char *)ENGINE_get_id(ctx->engine); + + if (engineid != NULL) { + size_t engineid_l = strlen(engineid) + 1; + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + engineid, + engineid_l); + } + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM, + mdname, + strlen(mdname) + 1); + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + key->data, key->length); + params[params_n] = OSSL_PARAM_construct_end(); + + return EVP_MAC_CTX_set_params(hctx->ctx, params); } break; case MAC_TYPE_MAC: @@ -335,8 +437,18 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); + const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx); + OSSL_PARAM params[2]; + int ok = 0; - return EVP_MAC_ctrl_str(hctx->ctx, type, value); + if (!OSSL_PARAM_allocate_from_text(¶ms[0], + EVP_MAC_CTX_settable_params(mac), + type, value, strlen(value) + 1)) + return 0; + params[1] = OSSL_PARAM_construct_end(); + ok = EVP_MAC_CTX_set_params(hctx->ctx, params); + OPENSSL_free(params[0].data); + return ok; } const EVP_PKEY_METHOD cmac_pkey_meth = { diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index ce9b9b8f51..fb443b1484 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -121,28 +121,26 @@ extern const EVP_PKEY_METHOD siphash_pkey_meth; /* struct evp_mac_impl_st is defined by the implementation */ typedef struct evp_mac_impl_st EVP_MAC_IMPL; struct evp_mac_st { - int type; - EVP_MAC_IMPL *(*new) (void); - EVP_MAC_IMPL *(*dup) (const EVP_MAC_IMPL *macsrc); - void (*free) (EVP_MAC_IMPL *macctx); - size_t (*size) (EVP_MAC_IMPL *macctx); - int (*init) (EVP_MAC_IMPL *macctx); - int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data, - size_t datalen); - int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out); - int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args); - int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value); -}; + OSSL_PROVIDER *prov; + char *name; -extern const EVP_MAC blake2b_mac_meth; -extern const EVP_MAC blake2s_mac_meth; -extern const EVP_MAC cmac_meth; -extern const EVP_MAC gmac_meth; -extern const EVP_MAC hmac_meth; -extern const EVP_MAC kmac128_meth; -extern const EVP_MAC kmac256_meth; -extern const EVP_MAC siphash_meth; -extern const EVP_MAC poly1305_meth; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_mac_newctx_fn *newctx; + OSSL_OP_mac_dupctx_fn *dupctx; + OSSL_OP_mac_freectx_fn *freectx; + OSSL_OP_mac_size_fn *size; + OSSL_OP_mac_init_fn *init; + OSSL_OP_mac_update_fn *update; + OSSL_OP_mac_final_fn *final; + OSSL_OP_mac_gettable_params_fn *gettable_params; + OSSL_OP_mac_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_mac_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_mac_get_params_fn *get_params; + OSSL_OP_mac_ctx_get_params_fn *ctx_get_params; + OSSL_OP_mac_ctx_set_params_fn *ctx_set_params; +}; /* Internal keccak algorithms used for KMAC */ const EVP_MD *evp_keccak_kmac128(void); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 637ecab1b6..6abada3c4b 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -706,6 +706,11 @@ const char *ossl_provider_module_path(const OSSL_PROVIDER *prov) #endif } +OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov) +{ + return prov->libctx; +} + /* Wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov) { @@ -801,7 +806,7 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov) { - return prov->libctx; + return ossl_provider_library_context(prov); } static int core_thread_start(const OSSL_PROVIDER *prov, diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index dd9f1cbec5..7154d5f36a 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -11,6 +11,7 @@ ossl_provider_ctx, ossl_provider_forall_loaded, ossl_provider_name, ossl_provider_dso, ossl_provider_module_name, ossl_provider_module_path, +ossl_provider_library_context, ossl_provider_teardown, ossl_provider_gettable_params, ossl_provider_get_params, ossl_provider_query_operation - internal provider routines @@ -52,6 +53,7 @@ ossl_provider_get_params, ossl_provider_query_operation const DSO *ossl_provider_dso(OSSL_PROVIDER *prov); const char *ossl_provider_module_name(OSSL_PROVIDER *prov); const char *ossl_provider_module_path(OSSL_PROVIDER *prov); + OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov); @@ -132,6 +134,9 @@ This will be used in preference to automatically trying to figure out the path from the provider name and the default module directory (more on this in L). +ossl_provider_library_context() returns the library context the given +provider I is registered in. + ossl_provider_add_parameter() adds a global parameter for the provider to retrieve as it sees fit. The parameters are a combination of I and I, and the @@ -252,6 +257,10 @@ ossl_provider_module_name(), and ossl_provider_module_path() return a pointer to their respective data if it's available, otherwise NULL is returned. +ossl_provider_library_context() return a pointer to the library context. +This may be NULL, and is perfectly valid, as it denotes the default +global library context. + ossl_provider_teardown() doesnt't return any value. ossl_provider_gettable_params() returns a pointer to a constant diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index a696c43cc5..6723c9707b 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -2,11 +2,13 @@ =head1 NAME -EVP_MAC, EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_new_id, EVP_MAC_CTX_free, -EVP_MAC_CTX_dup, EVP_MAC_CTX_mac, EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, -EVP_MAC_final, EVP_MAC_ctrl, EVP_MAC_vctrl, EVP_MAC_ctrl_str, -EVP_MAC_str2ctrl, EVP_MAC_hex2ctrl, EVP_MAC_nid, EVP_MAC_name, -EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines +EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free, EVP_MAC_name, +EVP_MAC_get_params, EVP_MAC_gettable_params, +EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup, +EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params, +EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final, +EVP_MAC_CTX_gettable_params, EVP_MAC_CTX_settable_params +- EVP MAC routines =head1 SYNOPSIS @@ -15,25 +17,29 @@ EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines typedef struct evp_mac_st EVP_MAC; typedef struct evp_mac_ctx_st EVP_MAC_CTX; - EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac); - EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid); + EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); + int EVP_MAC_up_ref(EVP_MAC *mac); + void EVP_MAC_free(EVP_MAC *mac); + const char *EVP_MAC_name(const EVP_MAC *mac); + int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); + + EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src); - const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); + EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); + int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); + int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + size_t EVP_MAC_size(EVP_MAC_CTX *ctx); int EVP_MAC_init(EVP_MAC_CTX *ctx); int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); - int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen); - int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...); - int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args); - int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value); - int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); - int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); - int EVP_MAC_nid(const EVP_MAC *mac); - const char *EVP_MAC_name(const EVP_MAC *mac); - const EVP_MAC *EVP_get_macbyname(const char *name); - const EVP_MAC *EVP_get_macbynid(int nid); - const EVP_MAC *EVP_get_macbyobj(const ASN1_OBJECT *o); + int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize); + + const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); + const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac); + const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac); =head1 DESCRIPTION @@ -60,23 +66,36 @@ B is a context type that holds internal MAC information as well as a reference to a computation context, for those MACs that rely on an underlying computation algorithm. +=head2 Algorithm implementation fetching + +EVP_MAC_fetch() fetches an implementation of a MAC I, given +a library context I and a set of I. +See L for further information. + +The returned value must eventually be freed with +L. + +EVP_MAC_up_ref() increments the reference count of an already fetched +MAC. + +EVP_MAC_free() frees a fetched algorithm. +NULL is a valid parameter, for which this function is a no-op. + =head2 Context manipulation functions -EVP_MAC_CTX_new() creates a new context for the MAC type C. -EVP_MAC_CTX_new_id() creates a new context for the numerical MAC -identity . +EVP_MAC_CTX_new() creates a new context for the MAC type I. The created context can then be used with most other functions described here. EVP_MAC_CTX_free() frees the contents of the context, including an underlying context if there is one, as well as the context itself. -B is a valid parameter, for which this function is a no-op. +NULL is a valid parameter, for which this function is a no-op. -EVP_MAC_CTX_dup() duplicates the C context and returns a newly allocated +EVP_MAC_CTX_dup() duplicates the I context and returns a newly allocated context. EVP_MAC_CTX_mac() returns the B associated with the context -C. +I. =head2 Computing functions @@ -85,131 +104,117 @@ through diverse controls. This should be called before calling EVP_MAC_update() and EVP_MAC_final(). -EVP_MAC_update() adds C bytes from C to the MAC input. +EVP_MAC_update() adds I bytes from I to the MAC input. EVP_MAC_final() does the final computation and stores the result in -the memory pointed at by C, and sets its size in the B -the C points at. -If C is B, then no computation is made. +the memory pointed at by I of size I, and sets the number +of bytes written in I<*outl> at. +If I is B or I is too small, then no computation +is made. To figure out what the output length will be and allocate space for it -dynamically, simply call with C being B and C +dynamically, simply call with I being B and I pointing at a valid location, then allocate space and make a second -call with C pointing at the allocated space. - -EVP_MAC_ctrl() is used to manipulate or get information on aspects of -the MAC which may vary depending on the MAC algorithm or its -implementation. -This includes the MAC key, and for MACs that use other algorithms to -do their computation, this is also the way to tell it which one to -use. -This functions takes variable arguments, the exact expected arguments -depend on C. -EVP_MAC_ctrl() can be called both before and after EVP_MAC_init(), but -the effect will depend on what control is being use. -See L below for a description of standard controls. - -EVP_MAC_vctrl() is the variant of EVP_MAC_ctrl() that takes a -C argument instead of variadic arguments. - -EVP_MAC_ctrl_str() is an alternative to EVP_MAC_ctrl() to control the -MAC implementation as E C, C E pairs. -The MAC implementation documentation should specify what control type -strings are accepted. - -EVP_MAC_str2ctrl() and EVP_MAC_hex2ctrl() are helper functions to -control the MAC implementation with raw strings or with strings -containing hexadecimal numbers. -The latter are decoded into bitstrings that are sent on to -EVP_MAC_ctrl(). +call with I pointing at the allocated space. + +EVP_MAC_get_params() retrieves details about the implementation +I. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. + +EVP_MAC_CTX_get_params() retrieves chosen parameters, given the +context I and its underlying context. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. + +EVP_MAC_CTX_set_params() passes chosen parameters to the underlying +context, given a context I. +The set of parameters given with I determine exactly what +parameters are passed down. +Note that a parameter that is unknown in the underlying context is +simply ignored. +Also, what happens when a needed parameter isn't passed down is +defined by the implementation. + +EVP_MAC_gettable_params(), EVP_MAC_CTX_gettable_params() and +EVP_MAC_CTX_settable_params() get a constant B array that +decribes the retrievable and settable parameters, i.e. parameters that +can be used with EVP_MAC_CTX_get_params(), EVP_MAC_CTX_get_params() +and EVP_MAC_CTX_set_params(), respectively. +See L for the use of B as parameter descriptor. =head2 Information functions EVP_MAC_size() returns the MAC output size for the given context. -EVP_MAC_nid() returns the numeric identity of the given MAC implementation. - EVP_MAC_name() returns the name of the given MAC implementation. -=head2 Object database functions - -EVP_get_macbyname() fetches a MAC implementation from the object -database by name. - -EVP_get_macbynid() fetches a MAC implementation from the object -database by numeric identity. - -EVP_get_macbyobj() fetches a MAC implementation from the object -database by ASN.1 OBJECT (i.e. an encoded OID). +=head1 PARAMETER NAMES -=head1 CONTROLS - -The standard controls are: +The standard parameter names are: =over 4 -=item B - -This control expects two arguments: C, C +=item OSSL_MAC_PARAM_KEY ("key") -These will set the MAC key from the given string of the given length. -The string may be any bitstring, and can contain NUL bytes. +Its value is the MAC key as an array of bytes. For MACs that use an underlying computation algorithm, the algorithm -I be set first, see B, -B and B below. - -=item B - -This control expects two arguments: C, C +must be set first, see parameter names "algorithm" below. -Some MAC implementations require an IV, this control sets the IV. +=item OSSL_MAC_PARAM_IV ("iv") -=item B +Some MAC implementations require an IV, this parameter sets the IV. -This control expects two arguments: C, C +=item OSSL_MAC_PARAM_CUSTOM ("custom") Some MAC implementations (KMAC, BLAKE2) accept a Customization String, -this control sets the Customization String. The default value is "". +this parameter sets the Customization String. The default value is the +empty string. -=item B - -This control expects two arguments: C, C +=item OSSL_MAC_PARAM_SALT ("salt") This option is used by BLAKE2 MAC. -=item B +=item OSSL_MAC_PARAM_XOF ("xof") -This control expects one argument: C +It's a simple flag, the value 0 or 1 are expected. This option is used by KMAC. -=item B - -This control expects one argument: C +=item OSSL_MAC_PARAM_FLAGS ("flags") These will set the MAC flags to the given numbers. Some MACs do not support this option. -=item B +=item OSSL_MAC_PARAM_ENGINE ("engine") + +=item OSSL_MAC_PARAM_MD ("md") -=item B +=item OSSL_MAC_PARAM_DIGEST ("digest") -=item B +=item OSSL_MAC_PARAM_CIPHER ("cipher") + +=item OSSL_MAC_PARAM_ALGORITHM ("algorithm") For MAC implementations that use an underlying computation algorithm, -these controls set what the algorithm should be, and the engine that +these parameters set what the algorithm should be, and the engine that implements the algorithm if needed. -Note that not all algorithms may support all digests. HMAC does not support -variable output length digests such as SHAKE128 or SHAKE256. - -B takes one argument: C +The value is always the name of the intended engine or algorithm. -B takes one argument: C +Note that not all algorithms may support all digests. +HMAC does not support variable output length digests such as SHAKE128 +or SHAKE256. -B takes one argument: C +Also note that OSSL_MAC_PARAM_ALGORITHM can be use generically instead +of OSSL_MAC_PARAM_MD, OSSL_MAC_PARAM_DIGEST or OSSL_MAC_PARAM_CIPHER, +and that OSSL_MAC_PARAM_MD and OSSL_MAC_PARAM_DIGEST are also interchangable. -=item B +=item OSSL_MAC_PARAM_SIZE For MAC implementations that support it, set the output size that EVP_MAC_final() should produce. @@ -217,46 +222,38 @@ The allowed sizes vary between MAC implementations. =back -All these control should be used before the calls to any of +All these parameters should be used before the calls to any of EVP_MAC_init(), EVP_MAC_update() and EVP_MAC_final() for a full computation. Anything else may give undefined results. -=head1 NOTES +=head1 RETURN VALUES -EVP_get_macbynid(), EVP_get_macbyobj() and EVP_MAC_name() are -implemented as a macro. +EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or +NULL if allocation failed. -=head1 RETURN VALUES +EVP_MAC_up_ref() returns 1 on success, 0 on error. + +EVP_MAC_free() returns nothing at all. + +EVP_MAC_name() returns the name of the MAC, or NULL if NULL was +passed. -EVP_MAC_CTX_new(), EVP_MAC_CTX_new_id() and EVP_MAC_CTX_dup() return a pointer -to a newly created EVP_MAC_CTX, or NULL if allocation failed. +EVP_MAC_CTX_new() and EVP_MAC_CTX_dup() return a pointer to a newly +created EVP_MAC_CTX, or NULL if allocation failed. EVP_MAC_CTX_free() returns nothing at all. -EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 on error. +EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on +success, 0 on error. -EVP_MAC_ctrl(), EVP_MAC_ctrl_str(), EVP_MAC_str2ctrl() and -EVP_MAC_hex2ctrl() return 1 on success and 0 or a negative value on -error. -In particular, the value -2 indicates that the given control type -isn't supported by the MAC implementation. +EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 +on error. EVP_MAC_size() returns the expected output size, or 0 if it isn't set. If it isn't set, a call to EVP_MAC_init() should get it set. -EVP_MAC_nid() returns the numeric identity for the given C. - -EVP_MAC_name() returns the name for the given C, if it has been -added to the object database. - -EVP_add_mac() returns 1 if the given C was successfully added to -the object database, otherwise 0. - -EVP_get_macbyname(), EVP_get_macbynid() and EVP_get_macbyobj() return -the request MAC implementation, if it exists in the object database, -otherwise B. =head1 EXAMPLE @@ -268,29 +265,12 @@ otherwise B. #include #include - - int ctrl_ign_unsupported(EVP_MAC_CTX *ctx, int cmd, ...) - { - va_list args; - int rv; - - va_start(args, cmd); - rv = EVP_MAC_vctrl(ctx, cmd, args); - va_end(args); - - if (rv == -2) - rv = 1; /* Ignore unsupported, pretend it worked fine */ - - return rv; - } + #include int main() { - const EVP_MAC *mac = - EVP_get_macbyname(getenv("MY_MAC")); - const EVP_CIPHER *cipher = - EVP_get_cipherbyname(getenv("MY_MAC_CIPHER")); - const EVP_MD *digest = - EVP_get_digestbyname(getenv("MY_MAC_DIGEST")); + EVP_MAC *mac = EVP_MAC_fetch(NULL, getenv("MY_MAC"), NULL); + const char *cipher = getenv("MY_MAC_CIPHER"); + const char *digest = getenv("MY_MAC_DIGEST"); const char *key = getenv("MY_KEY"); EVP_MAC_CTX *ctx = NULL; @@ -300,14 +280,25 @@ otherwise B. size_t i; + OSSL_PARAM params[4]; + size_t params_n = 0; + + if (cipher != NULL) + params[params_n++] = + OSSL_PARAM_construct_utf8_string("cipher", cipher, + strlen(cipher) + 1, NULL); + if (digest != NULL) + params[params_n++] = + OSSL_PARAM_construct_utf8_string("digest", digest, + strlen(digest) + 1, NULL); + params[params_n++] = + OSSL_PARAM_construct_octet_string("key", key, strlen(key), NULL); + params[params_n] = OSSL_PARAM_construct_end(); + if (mac == NULL || key == NULL || (ctx = EVP_MAC_CTX_new(mac)) == NULL - || (cipher != NULL - && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_CIPHER, cipher)) - || (digest != NULL - && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_MD, digest)) - || EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY, key, strlen(key)) <= 0) + || EVP_MAC_CTX_set_params(ctx, params) <= 0) goto err; if (!EVP_MAC_init(ctx)) @@ -327,10 +318,12 @@ otherwise B. printf("\n"); EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); exit(0); err: EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); fprintf(stderr, "Something went wrong\n"); ERR_print_errors_fp(stderr); exit (1); @@ -348,6 +341,8 @@ F<./foo>) =head1 SEE ALSO +L +L, L, L, L, @@ -362,7 +357,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2018-2019 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 diff --git a/doc/man7/provider-mac.pod b/doc/man7/provider-mac.pod new file mode 100644 index 0000000000..65aa0124e5 --- /dev/null +++ b/doc/man7/provider-mac.pod @@ -0,0 +1,255 @@ +=pod + +=head1 NAME + +provider-mac - The mac library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Context management */ + void *OP_mac_newctx(void *provctx); + void OP_mac_freectx(void *mctx); + void *OP_mac_dupctx(void *src); + + /* Encryption/decryption */ + int OP_mac_init(void *mctx); + int OP_mac_update(void *mctx, const unsigned char *in, size_t inl); + int OP_mac_final(void *mctx, unsigned char *out, size_t *outl, size_t outsize); + + /* MAC parameter descriptors */ + const OSSL_PARAM *OP_mac_get_params(void); + const OSSL_PARAM *OP_mac_ctx_get_params(void); + const OSSL_PARAM *OP_mac_ctx_set_params(void); + + /* MAC parameters */ + int OP_mac_get_params(OSSL_PARAM params[]); + int OP_mac_ctx_get_params(void *mctx, OSSL_PARAM params[]); + int OP_mac_ctx_set_params(void *mctx, const OSSL_PARAM params[]); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The MAC operation enables providers to implement mac algorithms and make +them available to applications via the API functions L, +L and L. + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_mac_newctx() has these: + + typedef void *(OSSL_OP_mac_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_mac_newctx_fn + OSSL_get_OP_mac_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_mac_newctx OSSL_FUNC_MAC_NEWCTX + OP_mac_freectx OSSL_FUNC_MAC_FREECTX + OP_mac_dupctx OSSL_FUNC_MAC_DUPCTX + + OP_mac_init OSSL_FUNC_MAC_INIT + OP_mac_update OSSL_FUNC_MAC_UPDATE + OP_mac_final OSSL_FUNC_MAC_FINAL + + OP_mac_get_params OSSL_FUNC_MAC_GET_PARAMS + OP_mac_ctx_get_params OSSL_FUNC_MAC_CTX_GET_PARAMS + OP_mac_ctx_set_params OSSL_FUNC_MAC_CTX_SET_PARAMS + + OP_mac_gettable_params OSSL_FUNC_MAC_GETTABLE_PARAMS + OP_mac_gettable_ctx_params OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS + OP_mac_settable_ctx_params OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS + +A mac algorithm implementation may not implement all of these functions. +In order to be a consistent set of functions, at least the following functions +must be implemented: OP_mac_newctx(), OP_mac_freectx(), OP_mac_init(), +OP_mac_update(), OP_mac_final(). +All other functions are optional. + +=head2 Context Management Functions + +OP_mac_newctx() should create and return a pointer to a provider side +structure for holding context information during a mac operation. +A pointer to this context will be passed back in a number of the other mac +operation function calls. +The paramater I is the provider context generated during provider +initialisation (see L). + +OP_mac_freectx() is passed a pointer to the provider side mac context in +the I parameter. +If it receives NULL as I value, it should not do anything other than +return. +This function should free any resources associated with that context. + +OP_mac_dupctx() should duplicate the provider side mac context in the +I parameter and return the duplicate copy. + +=head2 Encryption/Decryption Functions + +OP_mac_init() initialises a mac operation given a newly created provider +side mac context in the I paramter. + +OP_mac_update() is called to supply data for MAC computation of a previously +initialised mac operation. +The I parameter contains a pointer to a previously initialised provider +side context. +OP_mac_update() may be called multiple times for a single mac operation. + +OP_mac_final() completes the MAC computation started through previous +OP_mac_init() and OP_mac_update() calls. +The I parameter contains a pointer to the provider side context. +The resulting MAC should be written to I and the amount of data written +to I<*outl>, which should not exceed I bytes. +The same expectations apply to I as documented for +L. + +=head2 Mac Parameters + +See L for further details on the parameters structure used by +these functions. + +OP_mac_get_params() gets details of parameter values associated with the +provider algorithm and stores them in I. + +OP_mac_ctx_set_params() sets mac parameters associated with the given +provider side mac context I to I. +Any parameter settings are additional to any that were previously set. + +OP_mac_ctx_get_params() gets details of currently set parameter values +associated with the given provider side mac context I and stores them +in I. + +OP_mac_gettable_params(), OP_mac_gettable_ctx_params(), and +OP_mac_settable_ctx_params() all return constant B arrays +as descriptors of the parameters that OP_mac_get_params(), +OP_mac_ctx_get_params(), and OP_mac_ctx_set_params() can handle, +respectively. + +Parameters currently recognised by built-in macs are as follows. Not all +parameters are relevant to, or are understood by all macs: + +=over 4 + +=item B (octet string) + +Sets the key in the associated MAC ctx. + +=item B (octet string) + +Sets the IV of the underlying cipher, when applicable. + +=item B (utf8 string) + +Sets the custom string in the associated MAC ctx. + +=item B (octet string) + +Sets the salt of the underlying cipher, when applicable. + +=item B (int) + +Sets XOF mode in the associated MAC ctx. +0 means no XOF mode, 1 means XOF mode. + +=item B (int) + +Gets flags associated with the MAC. + +=for comment We need to investigate if this is the right approach + +=item B (utf8 string) + +Sets the name of the underlying algorithm to be used. +It must name a suitable algorithm for the MAC that's being used. + +=item B (utf8 string) + +=item B (utf8 string) + +=item B (utf8 string) + +These have the same meaning as B, but specify +the expected operation for the underlying algorithm. +These are regarded as antiquated, but are kept for easier transition from +legacy MAC implementations. + +=item B (utf8 string) + +Sets the name of an engine that implements the underlying algorithm. +This must be given together with the algorithm naming parameter to be +considered valid. + +=item B (utf8 string) + +Sets the properties to be queried when trying to fetch the underlying algorithm. +This must be given together with the algorithm naming parameter to be +considered valid. + +Note that both this and B can be given at the same time. +If the underlying algorithm ends up being fetched from a provider, offered by +and engine, or a built in legacy function depends on what is available. + +=item B (int) + +=item B (int) + +=item B (int) + +All three names are considered the same. +B and B are considered +antiquated, but are kept for easier transition from legacy MAC implementations. + +=back + +=head1 RETURN VALUES + +OP_mac_newctx() and OP_mac_dupctx() should return the newly created +provider side mac context, or NULL on failure. + +OP_mac_init(), OP_mac_update(), OP_mac_final(), OP_mac_get_params(), +OP_mac_ctx_get_params() and OP_mac_ctx_set_params() should return 1 for +success or 0 on error. + +OP_mac_gettable_params(), OP_mac_gettable_ctx_params() and +OP_mac_settable_ctx_params() should return a constant B +array, or NULL if none is offered. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider MAC interface was introduced in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/internal/provider.h b/include/internal/provider.h index f88beca8c0..a037233a30 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -63,6 +63,7 @@ const char *ossl_provider_name(const OSSL_PROVIDER *prov); const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov); const char *ossl_provider_module_name(const OSSL_PROVIDER *prov); const char *ossl_provider_module_path(const OSSL_PROVIDER *prov); +OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov); diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index bf57d15d38..e2d16be964 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -59,6 +59,26 @@ extern "C" { #define OSSL_DIGEST_PARAM_SIZE "size" /* OSSL_PARAM_INTEGER */ #define OSSL_DIGEST_PARAM_FLAGS "flags" /* OSSL_PARAM_UNSIGNED_INTEGER */ +/* MAC parameters */ +#define OSSL_MAC_PARAM_KEY "key" /* octet string */ +#define OSSL_MAC_PARAM_IV "iv" /* octet string */ +#define OSSL_MAC_PARAM_CUSTOM "custom" /* utf8 string */ +#define OSSL_MAC_PARAM_SALT "salt" /* octet string */ +#define OSSL_MAC_PARAM_XOF "xof" /* int, 0 or 1 */ +#define OSSL_MAC_PARAM_FLAGS "flags" /* int */ +/* Note that "md" and "digest" are equivalent */ +#define OSSL_MAC_PARAM_MD "md" /* utf8 string */ +#define OSSL_MAC_PARAM_DIGEST "digest" /* utf8 string */ +#define OSSL_MAC_PARAM_CIPHER "cipher" /* utf8 string */ +/* Note that "algorithm" can be used instead of "md", "digest" or "cipher" */ +#define OSSL_MAC_PARAM_ALGORITHM "algorithm" /* utf8 string */ +#define OSSL_MAC_PARAM_ENGINE "engine" /* utf8 string */ +#define OSSL_MAC_PARAM_PROPERTIES "properties" /* utf8 string */ +/* Note that "size", "digestsize" and "outlen" are equivalent */ +#define OSSL_MAC_PARAM_SIZE "size" /* size_t */ +#define OSSL_MAC_PARAM_DIGESTSIZE "digestsize" /* size_t */ +#define OSSL_MAC_PARAM_OUTLEN "outlen" /* size_t */ + /* PKEY parameters */ /* Diffie-Hellman Parameters */ #define OSSL_PKEY_PARAM_DH_P "dh-p" diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 2503119f6e..36eeaf67a8 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -230,6 +230,42 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_settable_ctx_params, OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_ctx_params, (void)) +/* MACs */ + +# define OSSL_OP_MAC 3 + +# define OSSL_FUNC_MAC_NEWCTX 1 +# define OSSL_FUNC_MAC_DUPCTX 2 +# define OSSL_FUNC_MAC_FREECTX 3 +# define OSSL_FUNC_MAC_INIT 4 +# define OSSL_FUNC_MAC_UPDATE 5 +# define OSSL_FUNC_MAC_FINAL 6 +# define OSSL_FUNC_MAC_GETTABLE_PARAMS 7 +# define OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS 8 +# define OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS 9 +# define OSSL_FUNC_MAC_GET_PARAMS 10 +# define OSSL_FUNC_MAC_CTX_GET_PARAMS 11 +# define OSSL_FUNC_MAC_CTX_SET_PARAMS 12 + +OSSL_CORE_MAKE_FUNC(void *, OP_mac_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(void *, OP_mac_dupctx, (void *src)) +OSSL_CORE_MAKE_FUNC(void, OP_mac_freectx, (void *mctx)) +OSSL_CORE_MAKE_FUNC(size_t, OP_mac_size, (void *mctx)) +OSSL_CORE_MAKE_FUNC(int, OP_mac_init, (void *mctx)) +OSSL_CORE_MAKE_FUNC(int, OP_mac_update, + (void *mctx, const unsigned char *in, size_t inl)) +OSSL_CORE_MAKE_FUNC(int, OP_mac_final, + (void *mctx, + unsigned char *out, size_t *outl, size_t outsize)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_gettable_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_gettable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_settable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(int, OP_mac_get_params, (OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, OP_mac_ctx_get_params, + (void *mctx, OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, OP_mac_ctx_set_params, + (void *mctx, const OSSL_PARAM params[])) + /*- * Key management * diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index accb22f3b1..f8789176d5 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -403,8 +403,8 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len); /* OPENSSL_INIT_BASE_ONLY 0x00040000L */ # define OPENSSL_INIT_NO_ATEXIT 0x00080000L /* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */ -# define OPENSSL_INIT_NO_ADD_ALL_MACS 0x04000000L -# define OPENSSL_INIT_ADD_ALL_MACS 0x08000000L +/* FREE: 0x04000000L */ +/* FREE: 0x08000000L */ # define OPENSSL_INIT_NO_ADD_ALL_KDFS 0x10000000L # define OPENSSL_INIT_ADD_ALL_KDFS 0x20000000L /* FREE: 0x40000000L */ diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 7fcc4505f5..c9b665dbbc 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -14,6 +14,7 @@ # include # include +# include # include # include # include @@ -1025,53 +1026,28 @@ void EVP_MD_do_all_ex(OPENSSL_CTX *libctx, /* MAC stuff */ -# define EVP_MAC_BLAKE2B NID_blake2bmac -# define EVP_MAC_BLAKE2S NID_blake2smac -# define EVP_MAC_CMAC NID_cmac -# define EVP_MAC_GMAC NID_gmac -# define EVP_MAC_HMAC NID_hmac -# define EVP_MAC_KMAC128 NID_kmac128 -# define EVP_MAC_KMAC256 NID_kmac256 -# define EVP_MAC_SIPHASH NID_siphash -# define EVP_MAC_POLY1305 NID_poly1305 - -EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac); -EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid); +EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); +int EVP_MAC_up_ref(EVP_MAC *mac); +void EVP_MAC_free(EVP_MAC *mac); +const char *EVP_MAC_name(const EVP_MAC *mac); +int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); + +EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src); -const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); +EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); +int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); +int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + size_t EVP_MAC_size(EVP_MAC_CTX *ctx); int EVP_MAC_init(EVP_MAC_CTX *ctx); int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); -int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen); -int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...); -int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args); -int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value); -int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); -int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); -int EVP_MAC_nid(const EVP_MAC *mac); - -# define EVP_get_macbynid(a) EVP_get_macbyname(OBJ_nid2sn(a)) -# define EVP_get_macbyobj(a) EVP_get_macbynid(OBJ_obj2nid(a)) -# define EVP_MAC_name(o) OBJ_nid2sn(EVP_MAC_nid(o)) -const EVP_MAC *EVP_get_macbyname(const char *name); -void EVP_MAC_do_all(void (*fn) - (const EVP_MAC *ciph, const char *from, const char *to, - void *x), void *arg); -void EVP_MAC_do_all_sorted(void (*fn) - (const EVP_MAC *ciph, const char *from, - const char *to, void *x), void *arg); - -# define EVP_MAC_CTRL_SET_KEY 0x01 /* unsigned char *, size_t */ -# define EVP_MAC_CTRL_SET_FLAGS 0x02 /* unsigned long */ -# define EVP_MAC_CTRL_SET_ENGINE 0x03 /* ENGINE * */ -# define EVP_MAC_CTRL_SET_MD 0x04 /* EVP_MD * */ -# define EVP_MAC_CTRL_SET_CIPHER 0x05 /* EVP_CIPHER * */ -# define EVP_MAC_CTRL_SET_SIZE 0x06 /* size_t */ -# define EVP_MAC_CTRL_SET_IV 0x07 /* unsigned char *, size_t */ -# define EVP_MAC_CTRL_SET_CUSTOM 0x08 /* unsigned char *, size_t */ -# define EVP_MAC_CTRL_SET_XOF 0x09 /* int */ -# define EVP_MAC_CTRL_SET_SALT 0x0a /* unsigned char *, size_t */ +int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize); +const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); +const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac); +const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac); /* PKEY stuff */ int EVP_PKEY_decrypt_old(unsigned char *dec_key, diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 0451d19046..86296136d6 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -181,8 +181,7 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings) } opts |= OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS - | OPENSSL_INIT_ADD_ALL_MACS; + | OPENSSL_INIT_ADD_ALL_DIGESTS; #ifndef OPENSSL_NO_AUTOLOAD_CONFIG if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) == 0) opts |= OPENSSL_INIT_LOAD_CONFIG; diff --git a/util/libcrypto.num b/util/libcrypto.num index 7d550ce016..58ac4fd55f 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4426,7 +4426,7 @@ EVP_MD_CTX_set_pkey_ctx 4531 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_set_digest_custom 4532 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_get_digest_custom 4533 3_0_0 EXIST::FUNCTION: EVP_MAC_CTX_new 4534 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_new_id 4535 3_0_0 EXIST::FUNCTION: +EVP_MAC_CTX_new_id 4535 3_0_0 NOEXIST::FUNCTION: EVP_MAC_CTX_free 4536 3_0_0 EXIST::FUNCTION: EVP_MAC_CTX_dup 4537 3_0_0 EXIST::FUNCTION: EVP_MAC_CTX_mac 4538 3_0_0 EXIST::FUNCTION: @@ -4434,15 +4434,15 @@ EVP_MAC_size 4539 3_0_0 EXIST::FUNCTION: EVP_MAC_init 4540 3_0_0 EXIST::FUNCTION: EVP_MAC_update 4541 3_0_0 EXIST::FUNCTION: EVP_MAC_final 4542 3_0_0 EXIST::FUNCTION: -EVP_MAC_ctrl 4543 3_0_0 EXIST::FUNCTION: -EVP_MAC_vctrl 4544 3_0_0 EXIST::FUNCTION: -EVP_MAC_ctrl_str 4545 3_0_0 EXIST::FUNCTION: -EVP_MAC_str2ctrl 4546 3_0_0 EXIST::FUNCTION: -EVP_MAC_hex2ctrl 4547 3_0_0 EXIST::FUNCTION: -EVP_MAC_nid 4548 3_0_0 EXIST::FUNCTION: -EVP_get_macbyname 4549 3_0_0 EXIST::FUNCTION: -EVP_MAC_do_all 4550 3_0_0 EXIST::FUNCTION: -EVP_MAC_do_all_sorted 4551 3_0_0 EXIST::FUNCTION: +EVP_MAC_ctrl 4543 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_vctrl 4544 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_ctrl_str 4545 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_str2ctrl 4546 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_hex2ctrl 4547 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_nid 4548 3_0_0 NOEXIST::FUNCTION: +EVP_get_macbyname 4549 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_do_all 4550 3_0_0 NOEXIST::FUNCTION: +EVP_MAC_do_all_sorted 4551 3_0_0 NOEXIST::FUNCTION: EVP_str2ctrl 4552 3_0_0 EXIST::FUNCTION: EVP_hex2ctrl 4553 3_0_0 EXIST::FUNCTION: EVP_PKEY_supports_digest_nid 4554 3_0_0 EXIST::FUNCTION: @@ -4720,3 +4720,13 @@ EVP_CIPHER_gettable_params 4829 3_0_0 EXIST::FUNCTION: EVP_CIPHER_CTX_settable_params 4830 3_0_0 EXIST::FUNCTION: EVP_CIPHER_CTX_gettable_params 4831 3_0_0 EXIST::FUNCTION: EVP_MD_get_params 4832 3_0_0 EXIST::FUNCTION: +EVP_MAC_fetch 4833 3_0_0 EXIST::FUNCTION: +EVP_MAC_CTX_settable_params 4834 3_0_0 EXIST::FUNCTION: +EVP_MAC_CTX_set_params 4835 3_0_0 EXIST::FUNCTION: +EVP_MAC_CTX_get_params 4836 3_0_0 EXIST::FUNCTION: +EVP_MAC_CTX_gettable_params 4837 3_0_0 EXIST::FUNCTION: +EVP_MAC_free 4838 3_0_0 EXIST::FUNCTION: +EVP_MAC_up_ref 4839 3_0_0 EXIST::FUNCTION: +EVP_MAC_name 4840 3_0_0 EXIST::FUNCTION: +EVP_MAC_get_params 4841 3_0_0 EXIST::FUNCTION: +EVP_MAC_gettable_params 4842 3_0_0 EXIST::FUNCTION: -- 2.34.1