#ifndef WOLF_CRYPT_HMAC_H
#define WOLF_CRYPT_HMAC_H
#include <wolfssl/wolfcrypt/hash.h>
#ifndef NO_HMAC
#if FIPS_VERSION3_GE(2,0,0)
#include <wolfssl/wolfcrypt/fips.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if FIPS_VERSION3_GE(6,0,0)
extern const unsigned int wolfCrypt_FIPS_hmac_ro_sanity[2];
WOLFSSL_LOCAL int wolfCrypt_FIPS_HMAC_sanity(void);
#endif
#if FIPS_VERSION3_GE(6,0,0)
#define FIPS_ALLOW_SHORT 1
#endif
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(2,0,0)
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#endif
#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_HMAC)
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#endif
#ifndef NO_OLD_WC_NAMES
#define HMAC_BLOCK_SIZE WC_HMAC_BLOCK_SIZE
#endif
#define WC_HMAC_INNER_HASH_KEYED_SW 1
#define WC_HMAC_INNER_HASH_KEYED_DEV 2
enum {
HMAC_FIPS_MIN_KEY = 14,
IPAD = 0x36,
OPAD = 0x5C,
#ifdef NO_MD5
WC_MD5 = WC_HASH_TYPE_MD5,
#endif
#ifdef NO_SHA
WC_SHA = WC_HASH_TYPE_SHA,
#endif
#ifdef NO_SHA256
WC_SHA256 = WC_HASH_TYPE_SHA256,
#endif
#ifndef WOLFSSL_SHA512
WC_SHA512 = WC_HASH_TYPE_SHA512,
#ifndef WOLFSSL_NOSHA512_224
WC_SHA512_224 = WC_HASH_TYPE_SHA512_224,
#endif
#ifndef WOLFSSL_NOSHA512_256
WC_SHA512_256 = WC_HASH_TYPE_SHA512_256,
#endif
#endif
#ifndef WOLFSSL_SHA384
WC_SHA384 = WC_HASH_TYPE_SHA384,
#endif
#ifndef WOLFSSL_SHA224
WC_SHA224 = WC_HASH_TYPE_SHA224,
#endif
#ifndef WOLFSSL_SHA3
WC_SHA3_224 = WC_HASH_TYPE_SHA3_224,
WC_SHA3_256 = WC_HASH_TYPE_SHA3_256,
WC_SHA3_384 = WC_HASH_TYPE_SHA3_384,
WC_SHA3_512 = WC_HASH_TYPE_SHA3_512,
#endif
#ifdef WOLF_PRIVATE_KEY_ID
HMAC_MAX_ID_LEN = 32,
HMAC_MAX_LABEL_LEN = 32,
#endif
WOLF_ENUM_DUMMY_LAST_ELEMENT(HMAC)
};
#define WC_HMAC_BLOCK_SIZE WC_MAX_BLOCK_SIZE
#if !defined(WOLFSSL_SHA3) && !defined(WOLFSSL_SHA512) && \
!defined(WOLFSSL_SHA384) && defined(NO_SHA256) && \
defined(WOLFSSL_SHA224) && defined(NO_SHA) && defined(NO_MD5)
#error "You have to have some kind of hash if you want to use HMAC."
#endif
typedef wc_Hashes wc_HmacHash;
struct Hmac {
wc_HmacHash hash;
#ifdef WOLFSSL_HMAC_COPY_HASH
wc_HmacHash i_hash;
wc_HmacHash o_hash;
#endif
word32 ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)];
word32 opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)];
word32 innerHash[WC_MAX_DIGEST_SIZE / sizeof(word32)];
void* heap;
byte macType;
byte innerHashKeyed;
#ifdef WOLFSSL_KCAPI_HMAC
struct kcapi_handle* handle;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev;
#endif
#if defined(WOLFSSL_DEVCRYPTO) && defined(WOLFSSL_DEVCRYPTO_HMAC)
WC_CRYPTODEV ctx;
#endif
#ifdef WOLF_CRYPTO_CB
int devId;
void* devCtx;
const byte* keyRaw;
#endif
#ifdef WOLF_PRIVATE_KEY_ID
byte id[HMAC_MAX_ID_LEN];
int idLen;
char label[HMAC_MAX_LABEL_LEN];
int labelLen;
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
word16 keyLen;
#endif
#if defined(STM32_HASH) && defined(STM32_HMAC)
STM32_HASH_Context stmCtx;
word32 stmAlgo;
word32 stmBlockSize;
word32 stmDigestSize;
word32 stmKeyLen;
#endif
};
#ifndef WC_HMAC_TYPE_DEFINED
typedef struct Hmac Hmac;
#define WC_HMAC_TYPE_DEFINED
#endif
#endif
WOLFSSL_API int wc_HmacSetKey(Hmac* hmac, int type, const byte* key,
word32 length);
WOLFSSL_API int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key,
word32 length, int allowFlag);
WOLFSSL_API int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length);
WOLFSSL_API int wc_HmacFinal(Hmac* hmac, byte* hash);
#ifdef WOLFSSL_KCAPI_HMAC
WOLFSSL_API int wc_HmacSetKey_Software(Hmac* hmac, int type, const byte* key,
word32 keySz);
WOLFSSL_API int wc_HmacUpdate_Software(Hmac* hmac, const byte* in, word32 sz);
WOLFSSL_API int wc_HmacFinal_Software(Hmac* hmac, byte* out);
#endif
WOLFSSL_API int wc_HmacSizeByType(int type);
WOLFSSL_API int wc_HmacInit(Hmac* hmac, void* heap, int devId);
#ifdef WOLF_PRIVATE_KEY_ID
WOLFSSL_API int wc_HmacInit_Id(Hmac* hmac, byte* id, int len, void* heap,
int devId);
WOLFSSL_API int wc_HmacInit_Label(Hmac* hmac, const char* label, void* heap,
int devId);
#endif
WOLFSSL_API int wc_HmacCopy(Hmac* src, Hmac* dst);
WOLFSSL_API void wc_HmacFree(Hmac* hmac);
WOLFSSL_API int wolfSSL_GetHmacMaxSize(void);
WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap);
WOLFSSL_LOCAL int _HmacInitIOHashes(Hmac* hmac);
#ifdef HAVE_HKDF
WOLFSSL_API int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz,
const byte* inKey, word32 inKeySz, byte* out,
void* heap, int devId);
WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
const byte* inKey, word32 inKeySz, byte* out);
WOLFSSL_API int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz,
const byte* info, word32 infoSz,
byte* out, word32 outSz, void* heap, int devId);
WOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
const byte* info, word32 infoSz,
byte* out, word32 outSz);
WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
const byte* salt, word32 saltSz,
const byte* info, word32 infoSz,
byte* out, word32 outSz);
WOLFSSL_API int wc_HKDF_ex(int type, const byte* inKey, word32 inKeySz,
const byte* salt, word32 saltSz,
const byte* info, word32 infoSz,
byte* out, word32 outSz, void* heap, int devId);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif