diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index c6b021fcd89c39..b698469312d780 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -115,9 +115,42 @@ size_t EVP_MAC_CTX_get_block_size(EVP_MAC_CTX *ctx) int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM params[]) { + if (ctx->meth->init == NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } return ctx->meth->init(ctx->algctx, key, keylen, params); } +int EVP_MAC_init_SKEY(EVP_MAC_CTX *ctx, const EVP_SKEY *skey, const OSSL_PARAM params[]) +{ + if (ctx->meth->init_opaque == NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + /* We have raw bytes implementation inside the EVP_SKEY object */ + if (skey->skeymgmt == NULL) { + if (ctx->meth->init == NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + return ctx->meth->init(ctx->algctx, skey->keybytes, skey->keybyteslen, params); + } + + if (skey->skeymgmt->prov != ctx->meth->prov) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + if (ctx->meth->init_opaque == NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + return ctx->meth->init_opaque(ctx->algctx, skey->keydata, params); +} + int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen) { return ctx->meth->update(ctx->algctx, data, datalen); diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c index a3e7a0220850db..b24d8462c232b9 100644 --- a/crypto/evp/mac_meth.c +++ b/crypto/evp/mac_meth.c @@ -60,7 +60,7 @@ static void *evp_mac_from_algorithm(int name_id, { const OSSL_DISPATCH *fns = algodef->implementation; EVP_MAC *mac = NULL; - int fnmaccnt = 0, fnctxcnt = 0; + int fnmaccnt = 0, fnctxcnt = 0, mac_init_found = 0; if ((mac = evp_mac_new()) == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); @@ -96,7 +96,7 @@ static void *evp_mac_from_algorithm(int name_id, if (mac->init != NULL) break; mac->init = OSSL_FUNC_mac_init(fns); - fnmaccnt++; + mac_init_found = 1; break; case OSSL_FUNC_MAC_UPDATE: if (mac->update != NULL) @@ -143,8 +143,15 @@ static void *evp_mac_from_algorithm(int name_id, break; mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns); break; + case OSSL_FUNC_MAC_INIT_OPAQUE: + if (mac->init_opaque != NULL) + break; + mac->init_opaque = OSSL_FUNC_mac_init_opaque(fns); + mac_init_found = 1; + break; } } + fnmaccnt += mac_init_found; if (fnmaccnt != 3 || fnctxcnt != 2) { /* diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index defa4042689dc4..ed031644312a15 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -8,7 +8,7 @@ EVP_MAC_get0_provider, 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_get0_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params, EVP_MAC_CTX_get_mac_size, EVP_MAC_CTX_get_block_size, EVP_Q_mac, -EVP_MAC_init, EVP_MAC_update, EVP_MAC_final, EVP_MAC_finalXOF, +EVP_MAC_init, EVP_MAC_init_SKEY, EVP_MAC_update, EVP_MAC_final, EVP_MAC_finalXOF, EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params, EVP_MAC_CTX_gettable_params, EVP_MAC_CTX_settable_params, EVP_MAC_do_all_provided - EVP MAC routines @@ -49,6 +49,7 @@ EVP_MAC_do_all_provided - EVP MAC routines unsigned char *out, size_t outsize, size_t *outlen); int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM params[]); + int EVP_MAC_init_SKEY(EVP_MAC_CTX *ctx, const EVP_SKEY *skey, const OSSL_PARAM params[]); 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 *outl, size_t outsize); @@ -151,6 +152,9 @@ has been called on the same object). See the NOTES section below. EVP_MAC_init() should be called before EVP_MAC_update() and EVP_MAC_final(). +EVP_MAC_init_SKEY() is similar to EVP_MAC_init() but accepts an opaque +B object as a key. + EVP_MAC_update() adds I bytes from I to the MAC input. EVP_MAC_final() does the final computation and stores the result in @@ -384,8 +388,8 @@ success, 0 on error. EVP_Q_mac() returns a pointer to the computed MAC value, or NULL on error. -EVP_MAC_init(), EVP_MAC_update(), EVP_MAC_final(), and EVP_MAC_finalXOF() -return 1 on success, 0 on error. +EVP_MAC_init(), EVP_MAC_init_SKEY(), EVP_MAC_update(), EVP_MAC_final(), and +EVP_MAC_finalXOF() return 1 on success, 0 on error. EVP_MAC_CTX_get_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() will set it. @@ -491,6 +495,8 @@ L These functions were added in OpenSSL 3.0. +The EVP_MAC_init_SKEY() function was added in OpenSSL 3.5. + =head1 COPYRIGHT Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man7/provider-mac.pod b/doc/man7/provider-mac.pod index b5cf5c9eb72977..5208224498d640 100644 --- a/doc/man7/provider-mac.pod +++ b/doc/man7/provider-mac.pod @@ -25,6 +25,7 @@ provider-mac - The mac library E-E provider functions /* Encryption/decryption */ int OSSL_FUNC_mac_init(void *mctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]); + int OSSL_FUNC_mac_init_opaque(void *mctx, const void *key, const OSSL_PARAM params[]); int OSSL_FUNC_mac_update(void *mctx, const unsigned char *in, size_t inl); int OSSL_FUNC_mac_final(void *mctx, unsigned char *out, size_t *outl, size_t outsize); @@ -71,6 +72,7 @@ macros in L, as follows: OSSL_FUNC_mac_dupctx OSSL_FUNC_MAC_DUPCTX OSSL_FUNC_mac_init OSSL_FUNC_MAC_INIT + OSSL_FUNC_mac_init_opaque OSSL_FUNC_MAC_INIT_OPAQUE OSSL_FUNC_mac_update OSSL_FUNC_MAC_UPDATE OSSL_FUNC_mac_final OSSL_FUNC_MAC_FINAL @@ -84,7 +86,8 @@ macros in L, as follows: 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: OSSL_FUNC_mac_newctx(), OSSL_FUNC_mac_freectx(), OSSL_FUNC_mac_init(), +must be implemented: OSSL_FUNC_mac_newctx(), OSSL_FUNC_mac_freectx(), +at least one of OSSL_FUNC_mac_init() and OSSL_FUNC_mac_init_opaque(), OSSL_FUNC_mac_update(), OSSL_FUNC_mac_final(). All other functions are optional. @@ -112,6 +115,9 @@ OSSL_FUNC_mac_init() initialises a mac operation given a newly created provider side mac context in the I parameter. The I are set before setting the MAC I of I bytes. +OSSL_FUNC_mac_init_opaque() is similar but uses an opaque provider-specific object +to initialize the MAC context. + OSSL_FUNC_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 @@ -234,7 +240,8 @@ the EVP layer will begin enforcing the listed transitions. OSSL_FUNC_mac_newctx() and OSSL_FUNC_mac_dupctx() should return the newly created provider side mac context, or NULL on failure. -OSSL_FUNC_mac_init(), OSSL_FUNC_mac_update(), OSSL_FUNC_mac_final(), OSSL_FUNC_mac_get_params(), +OSSL_FUNC_mac_init(), OSSL_FUNC_mac_init_opaque(), +OSSL_FUNC_mac_update(), OSSL_FUNC_mac_final(), OSSL_FUNC_mac_get_params(), OSSL_FUNC_mac_get_ctx_params() and OSSL_FUNC_mac_set_ctx_params() should return 1 for success or 0 on error. @@ -255,6 +262,8 @@ L, L The provider MAC interface was introduced in OpenSSL 3.0. The parameters "no-short-mac" and "fips-indicator" were added in OpenSSL 3.4. +The function OSSL_FUNC_mac_init_opaque() was introduced in OpenSSL 3.5. + =head1 COPYRIGHT Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/crypto/evp.h b/include/crypto/evp.h index ea86fca7adcb54..29e84ae1a786af 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -226,6 +226,7 @@ struct evp_mac_st { OSSL_FUNC_mac_get_params_fn *get_params; OSSL_FUNC_mac_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_mac_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_mac_init_opaque_fn *init_opaque; }; struct evp_kdf_st { diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 23541dde43f87f..149403007afd9e 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -440,6 +440,7 @@ OSSL_CORE_MAKE_FUNC(int, cipher_decrypt_opaque_init, (void *cctx, # define OSSL_FUNC_MAC_GETTABLE_PARAMS 10 # define OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS 11 # define OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS 12 +# define OSSL_FUNC_MAC_INIT_OPAQUE 13 OSSL_CORE_MAKE_FUNC(void *, mac_newctx, (void *provctx)) OSSL_CORE_MAKE_FUNC(void *, mac_dupctx, (void *src)) @@ -461,6 +462,7 @@ OSSL_CORE_MAKE_FUNC(int, mac_get_ctx_params, (void *mctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, mac_set_ctx_params, (void *mctx, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, mac_init_opaque, (void *mctx, const void *key, const OSSL_PARAM params[])) /* KDFs and PRFs */ diff --git a/include/openssl/evp.h b/include/openssl/evp.h index f4dcec2d0f2aac..8ad0247fc019f1 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1261,6 +1261,7 @@ unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *pro unsigned char *out, size_t outsize, size_t *outlen); int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM params[]); +int EVP_MAC_init_SKEY(EVP_MAC_CTX *ctx, const EVP_SKEY *skey, const OSSL_PARAM params[]); 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 *outl, size_t outsize); diff --git a/util/libcrypto.num b/util/libcrypto.num index d333b4595fa4d0..726705fe54872a 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5894,3 +5894,4 @@ EVP_SKEYMGMT_do_all_provided ? 3_5_0 EXIST::FUNCTION: EVP_SKEYMGMT_names_do_all ? 3_5_0 EXIST::FUNCTION: EVP_KDF_derive_SKEY ? 3_5_0 EXIST::FUNCTION: EVP_PKEY_derive_SKEY ? 3_5_0 EXIST::FUNCTION: +EVP_MAC_init_SKEY ? 3_5_0 EXIST::FUNCTION: