summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-03-29 19:42:33 +0200
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-05-08 14:35:03 +0200
commit0a8a6afdfb71e42962921980b51942cea8632697 (patch)
tree745f3e64cca2a9993fc2548f0a80a20dca231bcb
parentbea31afef013aaf5638e96e9bed1b633c510d50d (diff)
Add quick one-shot EVP_Q_mac() and deprecation compensation decls for MAC functions
This helps compensating for deprecated functions such as HMAC() and reduces clutter in the crypto lib, apps, and tests. Also fixes memory leaks in generate_cookie_callback() of apps/lib/s_cb.c. and replaces 'B<...>' by 'I<...>' where appropriate in HMAC.pod Partially fixes #14628. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14664)
-rw-r--r--CHANGES.md8
-rw-r--r--apps/lib/s_cb.c35
-rw-r--r--crypto/crmf/crmf_pbm.c24
-rw-r--r--crypto/evp/mac_lib.c62
-rw-r--r--crypto/hmac/hmac.c42
-rw-r--r--doc/man3/EVP_MAC.pod30
-rw-r--r--doc/man3/HMAC.pod59
-rw-r--r--include/openssl/evp.h5
-rw-r--r--include/openssl/hmac.h9
-rw-r--r--providers/fips-sources.checksums6
-rw-r--r--providers/fips.checksum2
-rw-r--r--providers/implementations/kdfs/hkdf.c30
-rw-r--r--ssl/tls13_enc.c26
-rw-r--r--test/hmactest.c23
-rw-r--r--util/libcrypto.num3
15 files changed, 198 insertions, 166 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 29d28f91ab..a2ef2f6b3f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1033,18 +1033,18 @@ OpenSSL 3.0
*Paul Dale*
- * All of the low level HMAC functions have been deprecated including:
+ * All low level HMAC functions except for HMAC have been deprecated including:
- HMAC, HMAC_size, HMAC_CTX_new, HMAC_CTX_reset, HMAC_CTX_free,
+ HMAC_size, HMAC_CTX_new, HMAC_CTX_reset, HMAC_CTX_free,
HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_copy, HMAC_CTX_set_flags
and HMAC_CTX_get_md.
Use of these low level functions has been informally discouraged for a long
time. Instead applications should use L<EVP_MAC_CTX_new(3)>,
L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
- and L<EVP_MAC_final(3)>.
+ and L<EVP_MAC_final(3)> or the single-shot MAC function L<EVP_Q_mac(3)>.
- *Paul Dale*
+ *Paul Dale and David von Oheimb*
* Over two thousand fixes were made to the documentation, including:
- Common options (such as -rand/-writerand, TLS version control, etc)
diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c
index 0bb4b6c436..bdd5051ee6 100644
--- a/apps/lib/s_cb.c
+++ b/apps/lib/s_cb.c
@@ -739,10 +739,6 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
unsigned short port;
BIO_ADDR *lpeer = NULL, *peer = NULL;
int res = 0;
- EVP_MAC *hmac = NULL;
- EVP_MAC_CTX *ctx = NULL;
- OSSL_PARAM params[2], *p = params;
- size_t mac_len;
/* Initialize a random secret */
if (!cookie_initialized) {
@@ -780,32 +776,13 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
memcpy(buffer, &port, sizeof(port));
BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL);
- /* Calculate HMAC of buffer using the secret */
- hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
- if (hmac == NULL) {
- BIO_printf(bio_err, "HMAC not found\n");
- goto end;
- }
- ctx = EVP_MAC_CTX_new(hmac);
- if (ctx == NULL) {
- BIO_printf(bio_err, "HMAC context allocation failed\n");
- goto end;
- }
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA1", 0);
- *p = OSSL_PARAM_construct_end();
- if (!EVP_MAC_init(ctx, cookie_secret, COOKIE_SECRET_LENGTH, params)) {
- BIO_printf(bio_err, "HMAC context initialisation failed\n");
- goto end;
- }
- if (!EVP_MAC_update(ctx, buffer, length)) {
- BIO_printf(bio_err, "HMAC context update failed\n");
- goto end;
- }
- if (!EVP_MAC_final(ctx, cookie, &mac_len, DTLS1_COOKIE_LENGTH)) {
- BIO_printf(bio_err, "HMAC context final failed\n");
- goto end;
+ if (EVP_Q_mac(NULL, "HMAC", NULL, "SHA1", NULL,
+ cookie_secret, COOKIE_SECRET_LENGTH, buffer, length,
+ cookie, DTLS1_COOKIE_LENGTH, cookie_len) == NULL) {
+ BIO_printf(bio_err,
+ "Error calculating HMAC-SHA1 of buffer with secret\n");
+ goto end;
}
- *cookie_len = (int)mac_len;
res = 1;
end:
OPENSSL_free(buffer);
diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c
index 40a41c28b2..cf483dcb9a 100644
--- a/crypto/crmf/crmf_pbm.c
+++ b/crypto/crmf/crmf_pbm.c
@@ -16,6 +16,7 @@
#include <openssl/rand.h>
#include <openssl/evp.h>
+#include <openssl/hmac.h>
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
@@ -120,8 +121,8 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen,
* |msglen| length of the message
* |sec| key to use
* |seclen| length of the key
- * |mac| pointer to the computed mac, will be set on success
- * |maclen| if not NULL, will set variable to the length of the mac on success
+ * |out| pointer to the computed mac, will be set on success
+ * |outlen| if not NULL, will set variable to the length of the mac on success
* returns 1 on success, 0 on error
*/
/* TODO try to combine with other MAC calculations in the libray */
@@ -140,10 +141,8 @@ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq,
unsigned int bklen = EVP_MAX_MD_SIZE;
int64_t iterations;
unsigned char *mac_res = 0;
+ unsigned int maclen;
int ok = 0;
- EVP_MAC *mac = NULL;
- EVP_MAC_CTX *mctx = NULL;
- OSSL_PARAM macparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
if (out == NULL || pbmp == NULL || pbmp->mac == NULL
|| pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
@@ -208,23 +207,16 @@ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq,
ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM);
goto err;
}
-
- macparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
- (char *)hmac_mdname, 0);
- if ((mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL
- || (mctx = EVP_MAC_CTX_new(mac)) == NULL
- || !EVP_MAC_CTX_set_params(mctx, macparams)
- || !EVP_MAC_init(mctx, basekey, bklen, macparams)
- || !EVP_MAC_update(mctx, msg, msglen)
- || !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
+ /* TODO generalize to non-HMAC: */
+ if (EVP_Q_mac(libctx, "HMAC", propq, hmac_mdname, NULL, basekey, bklen,
+ msg, msglen, mac_res, EVP_MAX_MD_SIZE, &maclen) == NULL)
goto err;
+ *outlen = (size_t)maclen;
ok = 1;
err:
OPENSSL_cleanse(basekey, bklen);
- EVP_MAC_CTX_free(mctx);
- EVP_MAC_free(mac);
EVP_MD_free(owf);
EVP_MD_CTX_free(ctx);
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index 6f97de94de..8a34df3757 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -222,3 +222,65 @@ int EVP_MAC_names_do_all(const EVP_MAC *mac,
return 1;
}
+
+unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+ const char *subalg, const OSSL_PARAM *params,
+ const void *key, size_t keylen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *out, size_t outsize, unsigned int *outlen)
+{
+ EVP_MAC *mac = EVP_MAC_fetch(libctx, name, propq);
+ OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ EVP_MAC_CTX *ctx = NULL;
+ size_t len;
+ unsigned char *res = NULL;
+
+ if (outlen != NULL)
+ *outlen = 0;
+ if (mac == NULL)
+ return NULL;
+ if (subalg != NULL) {
+ const OSSL_PARAM *defined_params = EVP_MAC_settable_ctx_params(mac);
+ const char *param_name = OSSL_MAC_PARAM_DIGEST;
+
+ /*
+ * The underlying algorithm may be a cipher or a digest.
+ * We don't know which it is, but we can ask the MAC what it
+ * should be and bet on that.
+ */
+ if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) {
+ param_name = OSSL_MAC_PARAM_CIPHER;
+ if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+ subalg_param[0] =
+ OSSL_PARAM_construct_utf8_string(param_name, (char *)subalg, 0);
+ }
+ /* Single-shot - on NULL key input, set dummy key value for EVP_MAC_Init. */
+ if (key == NULL && keylen == 0)
+ key = data;
+ if ((ctx = EVP_MAC_CTX_new(mac)) != NULL
+ && EVP_MAC_CTX_set_params(ctx, subalg_param)
+ && EVP_MAC_CTX_set_params(ctx, params)
+ && EVP_MAC_init(ctx, key, keylen, params)
+ && EVP_MAC_update(ctx, data, datalen)
+ && EVP_MAC_final(ctx, out, &len, outsize)) {
+ if (out == NULL) {
+ out = OPENSSL_malloc(len);
+ if (out != NULL && !EVP_MAC_final(ctx, out, NULL, len)) {
+ OPENSSL_free(out);
+ out = NULL;
+ }
+ }
+ res = out;
+ if (res != NULL && outlen != NULL)
+ *outlen = (unsigned int)len;
+ }
+
+ err:
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(mac);
+ return res;
+}
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index 6c1a70e4bd..6d142f2cbb 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -17,8 +17,9 @@
#include <stdlib.h>
#include <string.h>
#include "internal/cryptlib.h"
-#include <openssl/hmac.h>
#include <openssl/opensslconf.h>
+#include <openssl/hmac.h>
+#include <openssl/core_names.h>
#include "hmac_local.h"
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
@@ -34,13 +35,12 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
if (md != NULL && md != ctx->md && (key == NULL || len < 0))
return 0;
- if (md != NULL) {
+ if (md != NULL)
ctx->md = md;
- } else if (ctx->md) {
+ else if (ctx->md != NULL)
md = ctx->md;
- } else {
+ else
return 0;
- }
/*
* The HMAC construction is not allowed to be used with the
@@ -217,34 +217,14 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
}
unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
- const unsigned char *d, size_t n, unsigned char *md,
- unsigned int *md_len)
+ const unsigned char *data, size_t data_len,
+ unsigned char *md, unsigned int *md_len)
{
- HMAC_CTX *c = NULL;
- static unsigned char m[EVP_MAX_MD_SIZE];
- static const unsigned char dummy_key[1] = {'\0'};
+ static unsigned char static_md[EVP_MAX_MD_SIZE];
- if (md == NULL)
- md = m;
- if ((c = HMAC_CTX_new()) == NULL)
- goto err;
-
- /* For HMAC_Init_ex, NULL key signals reuse. */
- if (key == NULL && key_len == 0) {
- key = dummy_key;
- }
-
- if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
- goto err;
- if (!HMAC_Update(c, d, n))
- goto err;
- if (!HMAC_Final(c, md, md_len))
- goto err;
- HMAC_CTX_free(c);
- return md;
- err:
- HMAC_CTX_free(c);
- return NULL;
+ return EVP_Q_mac(NULL, "HMAC", NULL, EVP_MD_name(evp_md), NULL,
+ key, key_len, data, data_len,
+ md == NULL ? static_md : md, EVP_MD_size(evp_md), md_len);
}
void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod
index 27930eb89a..f4386f9daf 100644
--- a/doc/man3/EVP_MAC.pod
+++ b/doc/man3/EVP_MAC.pod
@@ -7,8 +7,9 @@ EVP_MAC_number, EVP_MAC_name, EVP_MAC_names_do_all, EVP_MAC_description,
EVP_MAC_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_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
-EVP_MAC_CTX_get_mac_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final,
-EVP_MAC_finalXOF, EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params,
+EVP_MAC_CTX_get_mac_size, EVP_Q_mac,
+EVP_MAC_init, 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
@@ -41,6 +42,11 @@ EVP_MAC_do_all_provided - EVP MAC routines
int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx);
+ unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+ const char *subalg, const OSSL_PARAM *params,
+ const void *key, size_t keylen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *out, size_t outsize, unsigned int *outlen);
int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
const OSSL_PARAM params[]);
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
@@ -119,6 +125,19 @@ I<ctx>.
=head2 Computing functions
+EVP_Q_mac() computes the message authentication code
+of I<data> with length I<datalen>
+using the MAC algorithm I<name> and the key I<key> with length I<keylen>.
+The MAC algorithm is fetched using any given I<libctx> and property query
+string I<propq>. It takes parameters I<subalg> and further I<params>,
+both of which may be NULL if not needed.
+If I<out> is not NULL, it places the result in the memory pointed at by I<out>,
+but only if I<outsize> is sufficient (otherwise no computation is made).
+If I<out> is NULL, it allocates and uses a buffer of suitable length,
+which will be returned on success and must be freed by the caller.
+In either case, also on error,
+it assigns the number of bytes written to I<*outlen> unless I<outlen> is NULL.
+
EVP_MAC_init() sets up the underlying context I<ctx> with information given
via the I<key> and I<params> arguments. The MAC I<key> has a length of
I<keylen> and the parameters in I<params> are processed before setting
@@ -162,6 +181,7 @@ EVP_MAC_CTX_set_params() passes chosen parameters to the underlying
context, given a context I<ctx>.
The set of parameters given with I<params> determine exactly what
parameters are passed down.
+If I<params> are NULL, the unterlying context should do nothing and return 1.
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
@@ -325,7 +345,7 @@ not be considered a breaking change to the API.
=head1 RETURN VALUES
-EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or
+EVP_MAC_fetch() returns a pointer to a newly fetched B<EVP_MAC>, or
NULL if allocation failed.
EVP_MAC_up_ref() returns 1 on success, 0 on error.
@@ -351,7 +371,9 @@ EVP_MAC_CTX_free() returns nothing at all.
EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on
success, 0 on error.
-EVP_MAC_init(), EVP_MAC_update(), EVP_MAC_final() and EVP_MAC_finalXOF()
+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_CTX_get_mac_size() returns the expected output size, or 0 if it isn't set.
diff --git a/doc/man3/HMAC.pod b/doc/man3/HMAC.pod
index 816d6e325d..5057360253 100644
--- a/doc/man3/HMAC.pod
+++ b/doc/man3/HMAC.pod
@@ -20,14 +20,14 @@ HMAC_size
#include <openssl/hmac.h>
+ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+ const unsigned char *data, size_t data_len,
+ unsigned char *md, unsigned int *md_len);
+
Deprecated since OpenSSL 3.0, can be hidden entirely by defining
B<OPENSSL_API_COMPAT> with a suitable version value, see
L<openssl_user_macros(7)>:
- unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
- int key_len, const unsigned char *d, size_t n,
- unsigned char *md, unsigned int *md_len);
-
HMAC_CTX *HMAC_CTX_new(void);
int HMAC_CTX_reset(HMAC_CTX *ctx);
@@ -53,28 +53,29 @@ L<openssl_user_macros(7)>:
=head1 DESCRIPTION
-All of the functions described on this page are deprecated. Applications should
-instead use L<EVP_MAC_CTX_new(3)>, L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>,
-L<EVP_MAC_update(3)> and L<EVP_MAC_final(3)>.
-
HMAC is a MAC (message authentication code), i.e. a keyed hash
function used for message authentication, which is based on a hash
function.
-HMAC() computes the message authentication code of the B<n> bytes at
-B<d> using the hash function B<evp_md> and the key B<key> which is
-B<key_len> bytes long.
+HMAC() computes the message authentication code of the I<data_len> bytes at
+I<data> using the hash function I<evp_md> and the key I<key> which is
+I<key_len> bytes long. The I<key> may also be NULL with I<key_len> being 0.
-It places the result in B<md> (which must have space for the output of
+It places the result in I<md> (which must have space for the output of
the hash function, which is no more than B<EVP_MAX_MD_SIZE> bytes).
-If B<md> is NULL, the digest is placed in a static array. The size of
-the output is placed in B<md_len>, unless it is B<NULL>. Note: passing a NULL
-value for B<md> to use the static array is not thread safe.
+If I<md> is NULL, the digest is placed in a static array. The size of
+the output is placed in I<md_len>, unless it is NULL. Note: passing a NULL
+value for I<md> to use the static array is not thread safe.
-B<evp_md> is a message digest such as EVP_sha1(), EVP_ripemd160() etc. HMAC does
-not support variable output length digests such as EVP_shake128() and
+I<evp_md> is a message digest such as EVP_sha1(), EVP_ripemd160() etc.
+HMAC does not support variable output length digests such as EVP_shake128() and
EVP_shake256().
+All of the functions described below are deprecated.
+Applications should instead use L<EVP_MAC_CTX_new(3)>, L<EVP_MAC_CTX_free(3)>,
+L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)> and L<EVP_MAC_final(3)>
+or the 'quick' single-shot MAC function L<EVP_Q_mac(3)>.
+
HMAC_CTX_new() creates a new HMAC_CTX in heap memory.
HMAC_CTX_reset() clears an existing B<HMAC_CTX> and associated
@@ -89,27 +90,27 @@ The following functions may be used if the message is not completely
stored in memory:
HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use the hash
-function B<evp_md> and key B<key>. If both are NULL, or if B<key> is NULL
-and B<evp_md> is the same as the previous call, then the
+function I<evp_md> and key I<key>. If both are NULL, or if I<key> is NULL
+and I<evp_md> is the same as the previous call, then the
existing key is
-reused. B<ctx> must have been created with HMAC_CTX_new() before the first use
+reused. I<ctx> must have been created with HMAC_CTX_new() before the first use
of an B<HMAC_CTX> in this function.
-If HMAC_Init_ex() is called with B<key> NULL and B<evp_md> is not the
-same as the previous digest used by B<ctx> then an error is returned
+If HMAC_Init_ex() is called with I<key> NULL and I<evp_md> is not the
+same as the previous digest used by I<ctx> then an error is returned
because reuse of an existing key with a different digest is not supported.
HMAC_Init() initializes a B<HMAC_CTX> structure to use the hash
-function B<evp_md> and the key B<key> which is B<key_len> bytes
+function I<evp_md> and the key I<key> which is I<key_len> bytes
long.
HMAC_Update() can be called repeatedly with chunks of the message to
-be authenticated (B<len> bytes at B<data>).
+be authenticated (I<len> bytes at I<data>).
-HMAC_Final() places the message authentication code in B<md>, which
+HMAC_Final() places the message authentication code in I<md>, which
must have space for the hash function output.
-HMAC_CTX_copy() copies all of the internal state from B<sctx> into B<dctx>.
+HMAC_CTX_copy() copies all of the internal state from I<sctx> into I<dctx>.
HMAC_CTX_set_flags() applies the specified flags to the internal EVP_MD_CTXs.
These flags have the same meaning as for L<EVP_MD_CTX_set_flags(3)>.
@@ -125,7 +126,7 @@ HMAC() returns a pointer to the message authentication code or NULL if
an error occurred.
HMAC_CTX_new() returns a pointer to a new B<HMAC_CTX> on success or
-B<NULL> if an error occurred.
+NULL if an error occurred.
HMAC_CTX_reset(), HMAC_Init_ex(), HMAC_Update(), HMAC_Final() and
HMAC_CTX_copy() return 1 for success or 0 if an error occurred.
@@ -142,11 +143,11 @@ RFC 2104
=head1 SEE ALSO
-L<SHA1(3)>, L<evp(7)>
+L<SHA1(3)>, EVP_Q_mac(3), L<evp(7)>
=head1 HISTORY
-All of these functions were deprecated in OpenSSL 3.0.
+All functions except for HMAC() were deprecated in OpenSSL 3.0.
HMAC_CTX_init() was replaced with HMAC_CTX_reset() in OpenSSL 1.1.0.
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 91b84ebf6f..9374e86e66 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1176,6 +1176,11 @@ 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_CTX_get_mac_size(EVP_MAC_CTX *ctx);
+unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+ const char *subalg, const OSSL_PARAM *params,
+ const void *key, size_t keylen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *out, size_t outsize, unsigned int *outlen);
int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
const OSSL_PARAM params[]);
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h
index f2f502ea5c..f9e1bff3f7 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/hmac.h
@@ -27,6 +27,7 @@
# ifdef __cplusplus
extern "C" {
# endif
+
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
@@ -45,15 +46,15 @@ OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
size_t len);
OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
unsigned int *len);
-OSSL_DEPRECATEDIN_3_0 unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
- int key_len, const unsigned char *d,
- size_t n, unsigned char *md,
- unsigned int *md_len);
OSSL_DEPRECATEDIN_3_0 __owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
OSSL_DEPRECATEDIN_3_0 const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx);
# endif
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+ const unsigned char *data, size_t data_len,
+ unsigned char *md, unsigned int *md_len);
+
# ifdef __cplusplus
}
# endif
diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums
index e6d798648a..6175384c2d 100644
--- a/providers/fips-sources.checksums
+++ b/providers/fips-sources.checksums
@@ -180,7 +180,7 @@ c0f87865be8dab6ea909fd976e5a46e4e8343b18403090c4a59b2af90f9a1329 crypto/evp/evp
2d657d8de8c2441693d54ef3730d83ca4b5d76c3b3405ece89bff9e46149d670 crypto/evp/keymgmt_lib.c
56d3ed4313cb811a3c2d062ff8b2a0fd67c4b0d28fe0562a57555b3a95907535 crypto/evp/keymgmt_meth.c
9fd78bfd59378fc4a9f56ce474310d8d2851aa42862c694ee0e47b175e836c51 crypto/evp/m_sigver.c
-0f5e0cd5c66712803a19774610f6bdfe572f5dda08c58cdf1b19d38a0693911c crypto/evp/mac_lib.c
+ec959b00487bfc51f4cf33c21a60fd8a73087a622504f459ba4cfe48bb0a738c crypto/evp/mac_lib.c
5f4b933a479d7cd589c47388aebfd8d6ffa3943ec2883049fc929e6ca37e26b5 crypto/evp/mac_meth.c
f5a18107256e00e2eed6a9b54eaf44ef1b99c0f29134e9f363a09daa2d35f1b5 crypto/evp/p_lib.c
b7e9ce6e8a35e0fc5b4eb4c047cda1e811b757669dbfafa71e743d85e07817a4 crypto/evp/pmeth_check.c
@@ -195,7 +195,7 @@ ead786b4f5689ab69d6cca5d49e513e0f90cb558b67e6c5898255f2671f1393d crypto/ffc/ffc
a87945698684673832fbedb4d01e2f11df58f43f79605a9e6d7136bb15b02e52 crypto/ffc/ffc_params.c
887357f0422954f2ecb855d468ad2456a76372dc401301ba284c0fd8c6b5092e crypto/ffc/ffc_params_generate.c
73dac805abab36cd9df53a421221c71d06a366a4ce479fa788be777f11b47159 crypto/ffc/ffc_params_validate.c
-84d8ae0141a79548ad65b31fe4673e8603930f942f21f3a7623e23f539799764 crypto/hmac/hmac.c
+c193773792bec29c791e84d150ffe5ef25f53cb02e23f0e12e9000234b4322e5 crypto/hmac/hmac.c
7000ba81f54c1d516a536bc6e96ad3729e3b5b15740006c2e22f0b76606042d6 crypto/initthread.c
c6c83f826eb6465f2a1b186ea692ff6fe32dbfb821d18d254625b69083d68fb0 crypto/lhash/lhash.c
f866aafae928db1b439ac950dc90744a2397dfe222672fe68b3798396190c8b0 crypto/mem_clr.c
@@ -362,7 +362,7 @@ de342d04be6af69037922d5c97bdc40c0c27f6740636e72786a765d0d8ad9173 providers/impl
427b9abee979f94371aa4aa99b48f08f1772965c93f9bce6f4531cc4cec136b6 providers/implementations/exchange/ecdh_exch.c
9bf87b8429398a6465c7e9f749a33b84974303a458736b56f3359b30726d3969 providers/implementations/exchange/ecx_exch.c
06ba83a8a8235bcdbda56f82b017cb19361469fe47c23cc6218a7e9b88ae6513 providers/implementations/exchange/kdf_exch.c
-4f8049771ff0cb57944e1ffc9599a96023e36b424138e51b1466f9a133f03943 providers/implementations/kdfs/hkdf.c
+9b9e7937be361de8e3c3fa9a2ef17edde8a0a4391bf55c72ff9785c1e4ee7dfc providers/implementations/kdfs/hkdf.c
115e13e152cfb7d729659cb26056414f719c5e7cb2a9b3df8b6ad0f232ce109a providers/implementations/kdfs/kbkdf.c
f93d3b32e7e3bc6bd4100559b15d392613797e1048010fdc70058ae9297a1125 providers/implementations/kdfs/pbkdf2.c
abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc providers/implementations/kdfs/pbkdf2_fips.c
diff --git a/providers/fips.checksum b/providers/fips.checksum
index 4ee2135be1..50a9c51b5c 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-a1ce185646a78b5eb88229b77aec1455e6e361f7428bb884aebe45cb8fdc3703 providers/fips-sources.checksums
+4d501c5fb8a5646c618eb02511a7a1ffab71823f6adee558ee30df8bb4bd6f40 providers/fips-sources.checksums
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index 2d3c72f501..ce0c81c1d2 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -41,12 +41,12 @@ static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
-static int HKDF(const EVP_MD *evp_md,
+static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
const unsigned char *key, size_t key_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len);
-static int HKDF_Extract(const EVP_MD *evp_md,
+static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk, size_t prk_len);
@@ -127,6 +127,7 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
const EVP_MD *md;
if (!ossl_prov_is_running() || !kdf_hkdf_set_ctx_params(ctx, params))
@@ -148,13 +149,12 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
switch (ctx->mode) {
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
- return HKDF(md, ctx->salt, ctx->salt_len, ctx->key,
- ctx->key_len, ctx->info, ctx->info_len, key,
- keylen);
+ return HKDF(libctx, md, ctx->salt, ctx->salt_len,
+ ctx->key, ctx->key_len, ctx->info, ctx->info_len, key, keylen);
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
- return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key,
- ctx->key_len, key, keylen);
+ return HKDF_Extract(libctx, md, ctx->salt, ctx->salt_len,
+ ctx->key, ctx->key_len, key, keylen);
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,
@@ -169,13 +169,13 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
KDF_HKDF *ctx = vctx;
- OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
int n;
if (params == NULL)
return 1;
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
return 0;
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
@@ -316,7 +316,7 @@ const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {
* 2.3. Step 2: Expand
* HKDF-Expand(PRK, info, L) -> OKM
*/
-static int HKDF(const EVP_MD *evp_md,
+static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
@@ -332,7 +332,8 @@ static int HKDF(const EVP_MD *evp_md,
prk_len = (size_t)sz;
/* Step 1: HKDF-Extract(salt, IKM) -> PRK */
- if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len))
+ if (!HKDF_Extract(libctx, evp_md,
+ salt, salt_len, ikm, ikm_len, prk, prk_len))
return 0;
/* Step 2: HKDF-Expand(PRK, info, L) -> OKM */
@@ -366,7 +367,7 @@ static int HKDF(const EVP_MD *evp_md,
*
* PRK = HMAC-Hash(salt, IKM)
*/
-static int HKDF_Extract(const EVP_MD *evp_md,
+static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk, size_t prk_len)
@@ -380,7 +381,10 @@ static int HKDF_Extract(const EVP_MD *evp_md,
return 0;
}
/* calc: PRK = HMAC-Hash(salt, IKM) */
- return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL;
+ return
+ EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_name(evp_md), NULL, salt,
+ salt_len, ikm, ikm_len, prk, EVP_MD_size(evp_md), NULL)
+ != NULL;
}
/*
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index f88d59948d..dba1e5fb8c 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -306,22 +306,14 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
unsigned char *out)
{
const char *mdname = EVP_MD_name(ssl_handshake_md(s));
- EVP_MAC *hmac = EVP_MAC_fetch(s->ctx->libctx, "HMAC", s->ctx->propq);
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned char finsecret[EVP_MAX_MD_SIZE];
unsigned char *key = NULL;
+ unsigned int len = 0;
size_t hashlen, ret = 0;
- EVP_MAC_CTX *ctx = NULL;
- OSSL_PARAM params[3], *p = params;
-
- if (hmac == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ OSSL_PARAM params[2], *p = params;
/* Safe to cast away const here since we're not "getting" any data */
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
- (char *)mdname, 0);
if (s->ctx->propq != NULL)
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
(char *)s->ctx->propq,
@@ -345,21 +337,17 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
key = finsecret;
}
- ctx = EVP_MAC_CTX_new(hmac);
- if (ctx == NULL
- || !EVP_MAC_init(ctx, key, hashlen, params)
- || !EVP_MAC_update(ctx, hash, hashlen)
- /* outsize as per sizeof(peer_finish_md) */
- || !EVP_MAC_final(ctx, out, &hashlen, EVP_MAX_MD_SIZE * 2)) {
+ if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname,
+ params, key, hashlen, hash, hashlen,
+ /* outsize as per sizeof(peer_finish_md) */
+ out, EVP_MAX_MD_SIZE * 2, &len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
- ret = hashlen;
+ ret = len;
err: