mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
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)
This commit is contained in:
parent
bea31afef0
commit
0a8a6afdfb
@ -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)
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
*cookie_len = (int)mac_len;
|
||||
res = 1;
|
||||
end:
|
||||
OPENSSL_free(buffer);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
a1ce185646a78b5eb88229b77aec1455e6e361f7428bb884aebe45cb8fdc3703 providers/fips-sources.checksums
|
||||
4d501c5fb8a5646c618eb02511a7a1ffab71823f6adee558ee30df8bb4bd6f40 providers/fips-sources.checksums
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user