Add quick one-shot EVP_Q_mac() and deprecation compensation decls for MAC functions
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Mon, 29 Mar 2021 17:42:33 +0000 (19:42 +0200)
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>
Sat, 8 May 2021 12:35:03 +0000 (14:35 +0200)
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)

15 files changed:
CHANGES.md
apps/lib/s_cb.c
crypto/crmf/crmf_pbm.c
crypto/evp/mac_lib.c
crypto/hmac/hmac.c
doc/man3/EVP_MAC.pod
doc/man3/HMAC.pod
include/openssl/evp.h
include/openssl/hmac.h
providers/fips-sources.checksums
providers/fips.checksum
providers/implementations/kdfs/hkdf.c
ssl/tls13_enc.c
test/hmactest.c
util/libcrypto.num

index 29d28f91ab6cfad1d321fec685f60c335369370c..a2ef2f6b3fc3566f13b1891e3731207a14546cf3 100644 (file)
@@ -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)
index 0bb4b6c436bb615c9fc9a68c31fe6da8c76c22b8..bdd5051ee6fc1fe26a3c4b0d329a74bea5ad04ae 100644 (file)
@@ -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);
index 40a41c28b21c7bcaa35193930bf82a694e847cd5..cf483dcb9a90eeede9ee54619a9cd785fb4f07b6 100644 (file)
@@ -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);
 
index 6f97de94ded9a6e560971aaa3350537e562e640d..8a34df3757262c04bfdd90108a446e684341efd4 100644 (file)
@@ -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;
+}
index 6c1a70e4bdad16c65b694828327ba087f9ae6c32..6d142f2cbb51df4037996a8cb551ebe8492f9261 100644 (file)
@@ -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)
index 27930eb89aa7a470c75e07ce7abfd413138218e5..f4386f9dafff712417b7ac035aee41d53d64418a 100644 (file)
@@ -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.
index 816d6e325d839d23f044a56d3ded8b7bfb623a24..50573602535d99229369781d8a76c8b3551400a7 100644 (file)
@@ -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.
 
index 91b84ebf6fb28d115587cf74a1ebfa29e970a27f..9374e86e6634ef24749e977a25851d27a54f9b26 100644 (file)
@@ -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);
index f2f502ea5cef900bcf519d576dee1c497c0d0c31..f9e1bff3f7478fbea673068836bc5877a1f01f17 100644 (file)
@@ -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
index e6d798648a18f4fa536418d1620cc5f5e9ea6443..6175384c2d6722310e32c737ce0b1eef30028635 100644 (file)
@@ -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
index 4ee2135be1ad3e807e9d10e0ead49ff250a7c89b..50a9c51b5c03dac27bccf81daad9ce7a9148f13e 100644 (file)
@@ -1 +1 @@
-a1ce185646a78b5eb88229b77aec1455e6e361f7428bb884aebe45cb8fdc3703  providers/fips-sources.checksums
+4d501c5fb8a5646c618eb02511a7a1ffab71823f6adee558ee30df8bb4bd6f40  providers/fips-sources.checksums
index 2d3c72f501df6c338af047fc63e186e80a5b9b69..ce0c81c1d2d27eac454090f46790d672b34766a7 100644 (file)
@@ -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;
 }
 
 /*
index f88d59948db2c825dd3300d57269e3d0e5951942..dba1e5fb8c03cd0b2ffa8754c16e2ce8eadd43b3 100644 (file)
@@ -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:
     OPENSSL_cleanse(finsecret, sizeof(finsecret));
-    EVP_MAC_CTX_free(ctx);
-    EVP_MAC_free(hmac);
     return ret;
 }
 
index babfb0e1a7ef049297c94ce3360d34b9734d3b64..918ae0b005c9eb7df69d7e06e62f769c85d555af 100644 (file)
@@ -100,10 +100,7 @@ static int test_hmac_md5(int idx)
                 test[idx].data, test[idx].data_len, NULL, NULL),
                 MD5_DIGEST_LENGTH);
 
-    if (!TEST_str_eq(p, test[idx].digest))
-      return 0;
-
-    return 1;
+    return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest);
 }
 # endif
 
@@ -151,7 +148,7 @@ static int test_hmac_run(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[4].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
         goto err;
 
     if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)))
@@ -164,7 +161,7 @@ static int test_hmac_run(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[5].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest))
         goto err;
 
     if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL))
@@ -172,7 +169,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     /* Test reusing a key */
@@ -181,7 +178,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     /*
@@ -193,7 +190,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     ret = 1;
@@ -207,10 +204,10 @@ static int test_hmac_single_shot(void)
 {
     char *p;
 
-    /* Test single-shot with an empty key. */
+    /* Test single-shot with NULL key. */
     p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len,
                 NULL, NULL), SHA_DIGEST_LENGTH);
-    if (!TEST_str_eq(p, test[4].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
         return 0;
 
     return 1;
@@ -237,7 +234,7 @@ static int test_hmac_copy(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[7].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest))
         goto err;
 
     ret = 1;
@@ -253,6 +250,8 @@ static char *pt(unsigned char *md, unsigned int len)
     unsigned int i;
     static char buf[80];
 
+    if (md == NULL)
+        return NULL;
     for (i = 0; i < len; i++)
         sprintf(&(buf[i * 2]), "%02x", md[i]);
     return buf;
index 13ec6e26f70a52eae18d8eaa29f98582a51a30fe..2e89c5dd26b8a5609b27326a9b8b3a580af6ee4c 100644 (file)
@@ -2028,7 +2028,7 @@ MDC2_Init                               2075      3_0_0   EXIST::FUNCTION:DEPRECATEDIN_
 i2o_SCT                                 2076   3_0_0   EXIST::FUNCTION:CT
 d2i_TS_STATUS_INFO                      2077   3_0_0   EXIST::FUNCTION:TS
 ERR_error_string_n                      2078   3_0_0   EXIST::FUNCTION:
-HMAC                                    2079   3_0_0   EXIST::FUNCTION:DEPRECATEDIN_3_0
+HMAC                                    2079   3_0_0   EXIST::FUNCTION:
 BN_mul                                  2080   3_0_0   EXIST::FUNCTION:
 BN_get0_nist_prime_384                  2081   3_0_0   EXIST::FUNCTION:
 X509_VERIFY_PARAM_set1_ip_asc           2082   3_0_0   EXIST::FUNCTION:
@@ -4408,6 +4408,7 @@ EVP_MAC_CTX_free                        ? 3_0_0   EXIST::FUNCTION:
 EVP_MAC_CTX_dup                         ?      3_0_0   EXIST::FUNCTION:
 EVP_MAC_CTX_mac                         ?      3_0_0   EXIST::FUNCTION:
 EVP_MAC_CTX_get_mac_size                ?      3_0_0   EXIST::FUNCTION:
+EVP_Q_mac                               ?      3_0_0   EXIST::FUNCTION:
 EVP_MAC_init                            ?      3_0_0   EXIST::FUNCTION:
 EVP_MAC_update                          ?      3_0_0   EXIST::FUNCTION:
 EVP_MAC_final                           ?      3_0_0   EXIST::FUNCTION: