diff --git a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs index df1973c3294506..b70cc5c913fae8 100644 --- a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs @@ -517,6 +517,24 @@ public static void VerifyEmptyHMAC_Span(HMAC referenceAlgorithm, HashAlgorithmNa } } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotAndroid))] + [MemberData(nameof(GetHMACs))] + public static void VerifyEmptyHMACKey_Cloned(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) + { + using (referenceAlgorithm) + using (IncrementalHash incrementalHash = IncrementalHash.CreateHMAC(hashAlgorithm, Array.Empty())) + using (IncrementalHash cloned = incrementalHash.Clone()) + { + referenceAlgorithm.Key = Array.Empty(); + cloned.AppendData([1, 2, 3]); + byte[] referenceHash = referenceAlgorithm.ComputeHash([1, 2, 3]); + byte[] clonedResult = new byte[referenceHash.Length]; + Assert.True(cloned.TryGetHashAndReset(clonedResult, out int bytesWritten)); + Assert.Equal(referenceHash.Length, bytesWritten); + Assert.Equal(referenceHash, clonedResult); + } + } + [Theory] [MemberData(nameof(GetHashAlgorithms))] public static void VerifyTrivialHash_Span(HashAlgorithm referenceAlgorithm, HashAlgorithmName hashAlgorithm) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index db613a21d546bf..4d85a1380ca262 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -38,6 +38,7 @@ #include "pal_crypto_config.h" #include "pal_compiler.h" +#define OPENSSL_VERSION_3_0_2_RTM 0x3000002FL #define OPENSSL_VERSION_3_0_RTM 0x30000000L #define OPENSSL_VERSION_1_1_1_RTM 0x10101000L #define OPENSSL_VERSION_1_1_0_RTM 0x10100000L @@ -313,10 +314,12 @@ extern bool g_libSslUses32BitTime; REQUIRED_FUNCTION(BN_value_one) \ REQUIRED_FUNCTION(BN_CTX_new) \ REQUIRED_FUNCTION(BN_CTX_free) \ + REQUIRED_FUNCTION(CRYPTO_clear_free) \ REQUIRED_FUNCTION(CRYPTO_free) \ REQUIRED_FUNCTION(CRYPTO_get_ex_new_index) \ REQUIRED_FUNCTION(CRYPTO_malloc) \ REQUIRED_FUNCTION(CRYPTO_set_mem_functions) \ + REQUIRED_FUNCTION(CRYPTO_zalloc) \ REQUIRED_FUNCTION(d2i_OCSP_RESPONSE) \ REQUIRED_FUNCTION(d2i_PKCS12_fp) \ REQUIRED_FUNCTION(d2i_PKCS7) \ @@ -467,7 +470,9 @@ extern bool g_libSslUses32BitTime; REQUIRED_FUNCTION(EVP_MD_CTX_new) \ REQUIRED_FUNCTION(EVP_MD_CTX_set_flags) \ LIGHTUP_FUNCTION(EVP_MD_fetch) \ + LIGHTUP_FUNCTION(EVP_MD_get0_name) \ RENAMED_FUNCTION(EVP_MD_get_size, EVP_MD_size) \ + LIGHTUP_FUNCTION(EVP_MD_is_a) \ REQUIRED_FUNCTION(EVP_PKCS82PKEY) \ REQUIRED_FUNCTION(EVP_PKEY2PKCS8) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \ @@ -868,10 +873,12 @@ extern TYPEOF(OPENSSL_gmtime)* OPENSSL_gmtime_ptr; #define BN_value_one BN_value_one_ptr #define BN_CTX_free BN_CTX_free_ptr #define BN_CTX_new BN_CTX_new_ptr +#define CRYPTO_clear_free CRYPTO_clear_free_ptr #define CRYPTO_free CRYPTO_free_ptr #define CRYPTO_get_ex_new_index CRYPTO_get_ex_new_index_ptr #define CRYPTO_malloc CRYPTO_malloc_ptr #define CRYPTO_set_mem_functions CRYPTO_set_mem_functions_ptr +#define CRYPTO_zalloc CRYPTO_zalloc_ptr #define d2i_OCSP_RESPONSE d2i_OCSP_RESPONSE_ptr #define d2i_PKCS12_fp d2i_PKCS12_fp_ptr #define d2i_PKCS7 d2i_PKCS7_ptr @@ -1022,7 +1029,9 @@ extern TYPEOF(OPENSSL_gmtime)* OPENSSL_gmtime_ptr; #define EVP_MD_CTX_new EVP_MD_CTX_new_ptr #define EVP_MD_CTX_set_flags EVP_MD_CTX_set_flags_ptr #define EVP_MD_fetch EVP_MD_fetch_ptr +#define EVP_MD_get0_name EVP_MD_get0_name_ptr #define EVP_MD_get_size EVP_MD_get_size_ptr +#define EVP_MD_is_a EVP_MD_is_a_ptr #define EVP_PKCS82PKEY EVP_PKCS82PKEY_ptr #define EVP_PKEY2PKCS8 EVP_PKEY2PKCS8_ptr #define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h index 84ac0bb726579d..5836727ba60ead 100644 --- a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h +++ b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h @@ -21,6 +21,7 @@ #define OSSL_MAC_PARAM_KEY "key" #define OSSL_MAC_PARAM_CUSTOM "custom" +#define OSSL_MAC_PARAM_DIGEST "digest" #define OSSL_MAC_PARAM_XOF "xof" #define OSSL_MAC_PARAM_SIZE "size" @@ -81,6 +82,8 @@ void EVP_MAC_free(EVP_MAC *mac); EVP_MD* EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_MD_get_size(const EVP_MD* md); +const char *EVP_MD_get0_name(const EVP_MD *md); +int EVP_MD_is_a(const EVP_MD *md, const char *name); EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const char *name, const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, const char *propquery); int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_hmac.c b/src/native/libs/System.Security.Cryptography.Native/pal_hmac.c index ce15fe62302ccc..e0b17404dab223 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_hmac.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_hmac.c @@ -7,14 +7,139 @@ #include -HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen, const EVP_MD* md) +static EVP_MAC* g_evpMacHmac = NULL; +static pthread_once_t g_evpMacHmacInit = PTHREAD_ONCE_INIT; + +static void EnsureMacHmac(void) +{ +#ifdef NEED_OPENSSL_3_0 + if (API_EXISTS(EVP_MAC_fetch)) + { + g_evpMacHmac = EVP_MAC_fetch(NULL, "HMAC", NULL); + return; + } +#endif + + g_evpMacHmac = NULL; +} + +#define HAVE_EVP_MAC (g_evpMacHmac != NULL) +#define ENSURE_DN_MAC_CONSISTENCY(ctx) \ + do \ + { \ + assert((ctx->legacy == NULL) != (ctx->mac == NULL)); \ + } \ + while (0) + +DN_MAC_CTX* CryptoNative_HmacCreate(uint8_t* key, int32_t keyLen, const EVP_MD* md) { assert(key != NULL || keyLen == 0); assert(keyLen >= 0); assert(md != NULL); + pthread_once(&g_evpMacHmacInit, EnsureMacHmac); ERR_clear_error(); + // NOTE: We can't pass NULL as empty key since HMAC_Init_ex will interpret + // that as request to reuse the "existing" key. + uint8_t _ = 0; + if (keyLen == 0) + { + key = &_; + } + +#ifdef NEED_OPENSSL_3_0 + if (HAVE_EVP_MAC) + { + assert(API_EXISTS(EVP_MAC_CTX_new)); + assert(API_EXISTS(EVP_MAC_init)); + assert(API_EXISTS(EVP_MD_get0_name)); + assert(API_EXISTS(EVP_MD_is_a)); + assert(API_EXISTS(OSSL_PARAM_construct_octet_string)); + assert(API_EXISTS(OSSL_PARAM_construct_utf8_string)); + assert(API_EXISTS(OSSL_PARAM_construct_end)); + + // HMAC-MD5 does not exist some Linux distros. + // Since MD5 can never be FIPS, fall back to the old implementation. + if (!EVP_MD_is_a(md, "MD5")) + { + EVP_MAC_CTX* evpMac = EVP_MAC_CTX_new(g_evpMacHmac); + + if (evpMac == NULL) + { + return NULL; + } + + const char* algorithm = EVP_MD_get0_name(md); + + // OSSL_PARAM_construct_utf8_string wants a non-const qualified value. Rather than suppress compiler warnings + // which differ from compiler to compiler, we copy the string in to a temporary value. + char* algorithmDup = strdup(algorithm); + + if (algorithmDup == NULL) + { + EVP_MAC_CTX_free(evpMac); + return NULL; + } + + size_t keyLenT = Int32ToSizeT(keyLen); + + OSSL_PARAM params[] = + { + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (void*) key, keyLenT), + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, algorithmDup, 0), + OSSL_PARAM_construct_end(), + }; + + if (!EVP_MAC_init(evpMac, NULL, 0, params)) + { + EVP_MAC_CTX_free(evpMac); + free(algorithmDup); + return NULL; + } + + free(algorithmDup); + + DN_MAC_CTX* dnCtx = (DN_MAC_CTX*)OPENSSL_zalloc(sizeof(DN_MAC_CTX)); + + if (dnCtx == NULL) + { + EVP_MAC_CTX_free(evpMac); + return NULL; + } + + unsigned long version = OpenSSL_version_num(); + + // OpenSSL [3.0.0, 3.0.2] have an issue where EVP_MAC_init cannot reset the HMAC instance + // with its existing key. The key must always be supplied. In order to work around this, + // we keep a copy of the key for these OpenSSL versions. + // If this is on a fixed or non-applicable version of OpenSSL, the key in the context struct will be + // NULL. A NULL key tells the init to re-use the existing key properly. So for affected versions of + // OpenSSL, the key will be present. For unaffected, it will be NULL and let OpenSSL do the correct reset + // behavior. + if (version >= OPENSSL_VERSION_3_0_RTM && version <= OPENSSL_VERSION_3_0_2_RTM) + { + // OpenSSL's allocator will not allocate a zero-sized buffer. So always allocate at least one + // byte. keyLenT will still be zero and contains the actual length of the key. + uint8_t* keyCopy = (uint8_t*)OPENSSL_malloc(keyLenT == 0 ? 1 : keyLenT); + + if (keyCopy == NULL) + { + EVP_MAC_CTX_free(evpMac); + OPENSSL_free(dnCtx); + return NULL; + } + + memcpy(keyCopy, key, keyLenT); + dnCtx->key = keyCopy; + dnCtx->keyLen = keyLenT; + } + + dnCtx->mac = evpMac; + return dnCtx; + } + } +#endif HMAC_CTX* ctx = HMAC_CTX_new(); if (ctx == NULL) @@ -26,12 +151,6 @@ HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen, const EVP_ return NULL; } - // NOTE: We can't pass NULL as empty key since HMAC_Init_ex will interpret - // that as request to reuse the "existing" key. - uint8_t _; - if (keyLen == 0) - key = &_; - int ret = HMAC_Init_ex(ctx, key, keyLen, md, NULL); if (!ret) @@ -40,32 +159,80 @@ HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen, const EVP_ return NULL; } - return ctx; + DN_MAC_CTX* dnCtx = (DN_MAC_CTX*)OPENSSL_zalloc(sizeof(DN_MAC_CTX)); + + if (dnCtx == NULL) + { + HMAC_CTX_free(ctx); + return NULL; + } + + dnCtx->legacy = ctx; + return dnCtx; } -void CryptoNative_HmacDestroy(HMAC_CTX* ctx) +void CryptoNative_HmacDestroy(DN_MAC_CTX* ctx) { if (ctx != NULL) { - HMAC_CTX_free(ctx); + ENSURE_DN_MAC_CONSISTENCY(ctx); + +#ifdef NEED_OPENSSL_3_0 + if (ctx->mac) + { + EVP_MAC_CTX_free(ctx->mac); + ctx->mac = NULL; + } + + if (ctx->key) + { + OPENSSL_clear_free(ctx->key, ctx->keyLen); + ctx->key = NULL; + ctx->keyLen = 0; + } +#endif + if (ctx->legacy) + { + HMAC_CTX_free(ctx->legacy); + ctx->legacy = NULL; + } + + OPENSSL_free(ctx); } } -int32_t CryptoNative_HmacReset(HMAC_CTX* ctx) +int32_t CryptoNative_HmacReset(DN_MAC_CTX* ctx) { assert(ctx != NULL); + ENSURE_DN_MAC_CONSISTENCY(ctx); ERR_clear_error(); - return HMAC_Init_ex(ctx, NULL, 0, NULL, NULL); +#ifdef NEED_OPENSSL_3_0 + if (HAVE_EVP_MAC && ctx->mac) + { + // See the Create method for the key and keyLen. These may be NULL and zero. Certain versions of OpenSSL + // require the key to re-initialize. In versions that are not affected, key is NULL and is to mean "reuse the + // existing key." + return EVP_MAC_init(ctx->mac, ctx->key, ctx->keyLen, NULL); + } +#endif + + if (ctx->legacy) + { + return HMAC_Init_ex(ctx->legacy, NULL, 0, NULL, NULL); + } + + return -1; } -int32_t CryptoNative_HmacUpdate(HMAC_CTX* ctx, const uint8_t* data, int32_t len) +int32_t CryptoNative_HmacUpdate(DN_MAC_CTX* ctx, const uint8_t* data, int32_t len) { assert(ctx != NULL); assert(data != NULL || len == 0); assert(len >= 0); + ENSURE_DN_MAC_CONSISTENCY(ctx); ERR_clear_error(); if (len < 0) @@ -73,16 +240,29 @@ int32_t CryptoNative_HmacUpdate(HMAC_CTX* ctx, const uint8_t* data, int32_t len) return 0; } - return HMAC_Update(ctx, data, Int32ToSizeT(len)); +#ifdef NEED_OPENSSL_3_0 + if (HAVE_EVP_MAC && ctx->mac) + { + return EVP_MAC_update(ctx->mac, data, Int32ToSizeT(len)); + } +#endif + + if (ctx->legacy) + { + return HMAC_Update(ctx->legacy, data, Int32ToSizeT(len)); + } + + return -1; } -int32_t CryptoNative_HmacFinal(HMAC_CTX* ctx, uint8_t* md, int32_t* len) +int32_t CryptoNative_HmacFinal(DN_MAC_CTX* ctx, uint8_t* md, int32_t* len) { assert(ctx != NULL); assert(len != NULL); assert(md != NULL || *len == 0); assert(*len >= 0); + ENSURE_DN_MAC_CONSISTENCY(ctx); ERR_clear_error(); if (len == NULL || *len < 0) @@ -90,18 +270,83 @@ int32_t CryptoNative_HmacFinal(HMAC_CTX* ctx, uint8_t* md, int32_t* len) return 0; } - unsigned int unsignedLen = Int32ToUint32(*len); - int ret = HMAC_Final(ctx, md, &unsignedLen); - *len = Uint32ToInt32(unsignedLen); + int ret = -1; + +#ifdef NEED_OPENSSL_3_0 + if (HAVE_EVP_MAC && ctx->mac) + { + size_t outl = 0; + size_t lenT = Int32ToSizeT(*len); + ret = EVP_MAC_final(ctx->mac, md, &outl, lenT); + *len = SizeTToInt32(outl); + return ret; + } +#endif + + if (ctx->legacy) + { + unsigned int unsignedLen = Int32ToUint32(*len); + ret = HMAC_Final(ctx->legacy, md, &unsignedLen); + *len = Uint32ToInt32(unsignedLen); + return ret; + } + return ret; } -HMAC_CTX* CryptoNative_HmacCopy(const HMAC_CTX* ctx) +DN_MAC_CTX* CryptoNative_HmacCopy(const DN_MAC_CTX* ctx) { assert(ctx != NULL); + ENSURE_DN_MAC_CONSISTENCY(ctx); ERR_clear_error(); +#ifdef NEED_OPENSSL_3_0 + if (HAVE_EVP_MAC && ctx->mac) + { + EVP_MAC_CTX* macDup = EVP_MAC_CTX_dup(ctx->mac); + + if (macDup == NULL) + { + return NULL; + } + + DN_MAC_CTX* copyCtx = (DN_MAC_CTX*)OPENSSL_zalloc(sizeof(DN_MAC_CTX)); + + if (copyCtx == NULL) + { + EVP_MAC_CTX_free(macDup); + return NULL; + } + + // See Create for the existence of key. This gets copied, even if the key length is zero. + if (ctx->key) + { + size_t keyLen = ctx->keyLen; + uint8_t* keyCopy = (uint8_t*)OPENSSL_malloc(keyLen == 0 ? 1 : keyLen); + + if (keyCopy == NULL) + { + EVP_MAC_CTX_free(macDup); + OPENSSL_free(copyCtx); + return NULL; + } + + memcpy(keyCopy, ctx->key, keyLen); + copyCtx->key = keyCopy; + copyCtx->keyLen = ctx->keyLen; + } + + copyCtx->mac = macDup; + return copyCtx; + } +#endif + + if (ctx->legacy == NULL) + { + return NULL; + } + HMAC_CTX* dup = HMAC_CTX_new(); if (dup == NULL) @@ -114,23 +359,33 @@ HMAC_CTX* CryptoNative_HmacCopy(const HMAC_CTX* ctx) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcast-qual" - if (!HMAC_CTX_copy(dup, (HMAC_CTX*)ctx)) + if (!HMAC_CTX_copy(dup, (HMAC_CTX*)(ctx->legacy))) #pragma clang diagnostic pop { HMAC_CTX_free(dup); return NULL; } - return dup; + DN_MAC_CTX* copyCtx = (DN_MAC_CTX*)OPENSSL_zalloc(sizeof(DN_MAC_CTX)); + + if (copyCtx == NULL) + { + HMAC_CTX_free(dup); + return NULL; + } + + copyCtx->legacy = dup; + return copyCtx; } -int32_t CryptoNative_HmacCurrent(const HMAC_CTX* ctx, uint8_t* md, int32_t* len) +int32_t CryptoNative_HmacCurrent(const DN_MAC_CTX* ctx, uint8_t* md, int32_t* len) { assert(ctx != NULL); assert(len != NULL); assert(md != NULL || *len == 0); assert(*len >= 0); + ENSURE_DN_MAC_CONSISTENCY(ctx); ERR_clear_error(); if (len == NULL || *len < 0) @@ -138,12 +393,12 @@ int32_t CryptoNative_HmacCurrent(const HMAC_CTX* ctx, uint8_t* md, int32_t* len) return 0; } - HMAC_CTX* dup = CryptoNative_HmacCopy(ctx); + DN_MAC_CTX* dup = CryptoNative_HmacCopy(ctx); if (dup != NULL) { int ret = CryptoNative_HmacFinal(dup, md, len); - HMAC_CTX_free(dup); + CryptoNative_HmacDestroy(dup); return ret; } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_hmac.h b/src/native/libs/System.Security.Cryptography.Native/pal_hmac.h index eb8f9f08a598be..5ceadf0817a279 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_hmac.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_hmac.h @@ -13,59 +13,56 @@ // Forward declarations - shim API must not depend on knowing layout of these types. typedef struct hmac_ctx_st HMAC_CTX; +struct _DN_MAC_CTX { + HMAC_CTX* legacy; + EVP_MAC_CTX* mac; + uint8_t* key; + size_t keyLen; +}; + +typedef struct _DN_MAC_CTX DN_MAC_CTX; + /** - * Creates and initializes an HMAC_CTX with the given key and EVP_MD. - * - * Implemented by: - * 1) allocating a new HMAC_CTX - * 2) calling HMAC_Init_ex with the new HMAC_CTX and the given args. + * Creates and initializes a context with the given key and EVP_MD. The context is not guaranteed to be a particular + * OpenSSL construct. It should be treated as an opaque pointer that is passed to the appropriate CryptoNative functions. * - * Returns new HMAC_CTX on success, nullptr on failure. + * Returns new context on success, nullptr on failure. */ -PALEXPORT HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen, const EVP_MD* md); +PALEXPORT DN_MAC_CTX* CryptoNative_HmacCreate(uint8_t* key, int32_t keyLen, const EVP_MD* md); /** - * Cleans up and deletes an HMAC_CTX instance created by HmacCreate. - * - * Implemented by calling HMAC_CTX_free + * Cleans up and deletes a context instance created by HmacCreate. * * No-op if ctx is null. - * The given HMAC_CTX pointer is invalid after this call. * Always succeeds. */ -PALEXPORT void CryptoNative_HmacDestroy(HMAC_CTX* ctx); +PALEXPORT void CryptoNative_HmacDestroy(DN_MAC_CTX* ctx); /** - * Resets an HMAC_CTX instance for a new computation, preserving the key and EVP_MD. - * - * Implemented by passing all null/0 values but ctx to HMAC_Init_ex. + * Resets an instance for a new computation, preserving the key and EVP_MD. */ -PALEXPORT int32_t CryptoNative_HmacReset(HMAC_CTX* ctx); +PALEXPORT int32_t CryptoNative_HmacReset(DN_MAC_CTX* ctx); /** * Appends data to the computation. * - * Direct shim to HMAC_Update. - * - * Returns 1 for success or 0 for failure. (Always succeeds on platforms where HMAC_Update returns void.) + * Returns 1 for success or 0 for failure. */ -PALEXPORT int32_t CryptoNative_HmacUpdate(HMAC_CTX* ctx, const uint8_t* data, int32_t len); +PALEXPORT int32_t CryptoNative_HmacUpdate(DN_MAC_CTX* ctx, const uint8_t* data, int32_t len); /** * Finalizes the computation and obtains the result. * - * Direct shim to HMAC_Final. - * - * Returns 1 for success or 0 for failure. (Always succeeds on platforms where HMAC_Update returns void.) + * Returns 1 for success or 0 for failure. */ -PALEXPORT int32_t CryptoNative_HmacFinal(HMAC_CTX* ctx, uint8_t* md, int32_t* len); +PALEXPORT int32_t CryptoNative_HmacFinal(DN_MAC_CTX* ctx, uint8_t* md, int32_t* len); /** * Retrieves the HMAC for the data already accumulated in ctx without finalizing the state. * * Returns 1 for success or 0 for failure. */ -PALEXPORT int32_t CryptoNative_HmacCurrent(const HMAC_CTX* ctx, uint8_t* md, int32_t* len); +PALEXPORT int32_t CryptoNative_HmacCurrent(const DN_MAC_CTX* ctx, uint8_t* md, int32_t* len); /** * Computes the HMAC of data using a key in a single operation. @@ -83,4 +80,4 @@ PALEXPORT int32_t CryptoNative_HmacOneShot(const EVP_MD* type, * Clones the context of the HMAC. * Returns NULL on failure. */ -PALEXPORT HMAC_CTX* CryptoNative_HmacCopy(const HMAC_CTX* ctx); +PALEXPORT DN_MAC_CTX* CryptoNative_HmacCopy(const DN_MAC_CTX* ctx);