#ifndef HASHING_H
#define HASHING_H
#define WS_SHA1_DIGEST_LENGTH 20
#define WS_SHA256_DIGEST_LENGTH 32
#define WS_SHA512_DIGEST_LENGTH 32
#ifdef __APPLE__
#define WS_USE_CRYPTO_COMMON
#define WS_CRYPTO_COMMON_CRYPTO
#define WS_AES_CTX CCCryptorRef
#define WS_SHA1_CTX CC_SHA1_CTX
#define WS_SHA256_CTX CC_SHA256_CTX
#define WS_SHA512_CTX CC_SHA512_CTX
#include <CommonCrypto/CommonCrypto.h>
#include <CommonCrypto/CommonDigest.h>
#elif defined(_WIN32)
#define WS_USE_CRYPTO_CNG
#include <windows.h>
#include <bcrypt.h>
typedef struct WinBCryptCTX {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_KEY_HANDLE hKey;
void *pbKeyObject;
unsigned char pbIV[16];
unsigned char buf[16];
ULONG buflen;
} WinBCryptCTX;
typedef struct WinBCryptSHACTX {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
void *pbHashObject;
} WinBCryptSHACTX;
#define WS_AES_CTX WinBCryptCTX
#define WS_SHA1_CTX WinBCryptSHACTX
#define WS_SHA256_CTX WinBCryptSHACTX
#define WS_SHA512_CTX WinBCryptSHACTX
#else
#include <openssl/evp.h>
#include <openssl/rand.h>
#define WS_USE_OPENSSL
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#define WS_SHA1_CTX SHA_CTX
#define WS_SHA256_CTX SHA256_CTX
#define WS_SHA512_CTX SHA512_CTX
#else
#define WS_SHA1_CTX EVP_MD_CTX*
#define WS_SHA256_CTX EVP_MD_CTX*
#define WS_SHA512_CTX EVP_MD_CTX*
#endif
#if defined(__sun) && defined(__SunOS_5_10)
#include <sha2.h>
#define SHA_Init SHAInit
#define SHA_Update SHAUpdate
#define SHA_Final SHAFinal
#define SHA256_Init SHA256Init
#define SHA256_Update SHA256Update
#define SHA256_Final SHA256Final
#define SHA512_Init SHA512Init
#define SHA512_Update SHA512Update
#define SHA512_Final SHA512Final
#else
#include <openssl/sha.h>
#endif
#endif
int ws_sha1_init(WS_SHA1_CTX *ctx);
WS_SHA1_CTX* ws_sha1_create(void);
void ws_sha1_update(WS_SHA1_CTX *ctx, const char *data, size_t len);
void ws_sha1_final(WS_SHA1_CTX *ctx, unsigned char *buf);
int ws_sha256_init(WS_SHA256_CTX *ctx);
WS_SHA256_CTX* ws_sha256_create(void);
void ws_sha256_update(WS_SHA256_CTX *ctx, const char *data, size_t len);
void ws_sha256_final(WS_SHA256_CTX *ctx, unsigned char *buf);
int ws_sha512_init(WS_SHA512_CTX *ctx);
WS_SHA512_CTX* ws_sha512_create(void);
void ws_sha512_update(WS_SHA512_CTX *ctx, const char *data, size_t len);
void ws_sha512_final(WS_SHA512_CTX *ctx, unsigned char *buf);
#ifdef __cplusplus
}
#endif
#endif