#ifndef _HMAC_SHA_256_H_
#define _HMAC_SHA_256_H_
 
#define SHA256_BLOCKLEN  64ul //size of message block buffer
#define SHA256_DIGESTLEN 32ul //size of digest in uint8_t
#define SHA256_DIGESTINT 8ul  //size of digest in uint32_t
 
// #ifndef PBKDF2_SHA256_STATIC
// #define PBKDF2_SHA256_DEF extern
// #else
// #define PBKDF2_SHA256_DEF static
// #endif
 
#include <stdint.h>
 
 
typedef struct sha256_ctx
{
	uint64_t len;                 // processed message length
	uint32_t h[SHA256_DIGESTINT]; // hash state
	uint8_t buf[SHA256_BLOCKLEN]; // message block buffer
} sha256_ctx_t;
 
void sha256_init(sha256_ctx_t *ctx);
void sha256_update(sha256_ctx_t *ctx, const uint8_t *m, uint32_t mlen);
// resets state: calls sha256_init
void sha256_final(sha256_ctx_t *ctx, uint8_t *md);
 
typedef struct hmac_sha256_ctx
{
	uint8_t buf[SHA256_BLOCKLEN]; // key block buffer, not needed after init
	uint32_t h_inner[SHA256_DIGESTINT];
	uint32_t h_outer[SHA256_DIGESTINT];
	sha256_ctx_t sha;
} hmac_sha256_ctx_t;
 
void hmac_sha256_init(hmac_sha256_ctx_t *hmac, const uint8_t *key, uint32_t keylen);
void hmac_sha256_update(hmac_sha256_ctx_t *hmac, const uint8_t *m, uint32_t mlen);
void hmac_sha256_final(hmac_sha256_ctx_t *hmac, uint8_t *md);
 
void pbkdf2_sha256(hmac_sha256_ctx_t *ctx,const uint8_t *key, uint32_t keylen, const uint8_t *salt, uint32_t saltlen, uint32_t rounds,uint8_t *dk, uint32_t dklen);

void HMAC_SHA256(const uint8_t* key, int keyLen, const uint8_t* value, int valueLen, unsigned char* out);

void HASH_SHA256(const uint8_t *key, int keyLen, uint8_t *out);

void TC_SHA256(const uint8_t *data, size_t len, uint8_t *out);
 
#endif // _HMAC_SHA_256_H_


