#include "hashing.h"
#include <stdlib.h>
WS_SHA1_CTX* ws_sha1_create(
void) {
WS_SHA1_CTX *ctx = malloc(
sizeof(
WS_SHA1_CTX));
if(!ctx) {
return NULL;
}
if(ws_sha1_init(ctx)) {
free(ctx);
return NULL;
}
return ctx;
}
WS_SHA256_CTX* ws_sha256_create(
void) {
WS_SHA256_CTX *ctx = malloc(
sizeof(
WS_SHA256_CTX));
if(!ctx) {
return NULL;
}
if(ws_sha256_init(ctx)) {
free(ctx);
return NULL;
}
return ctx;
}
WS_SHA512_CTX* ws_sha512_create(
void) {
WS_SHA512_CTX *ctx = malloc(
sizeof(
WS_SHA512_CTX));
if(!ctx) {
return NULL;
}
if(ws_sha512_init(ctx)) {
free(ctx);
return NULL;
}
return ctx;
}
#ifdef WS_USE_OPENSSL
#if OPENSSL_VERSION_NUMBER <
0x30000000L
int ws_sha1_init(
WS_SHA1_CTX *ctx) {
SHA1_Init(ctx);
return 0;
}
void ws_sha1_update(
WS_SHA1_CTX *ctx,
const char *data,
size_t len) {
SHA1_Update(ctx, data, len);
}
void ws_sha1_final(
WS_SHA1_CTX *ctx,
unsigned char *buf) {
SHA1_Final(buf, ctx);
}
int ws_sha256_init(
WS_SHA256_CTX *ctx) {
SHA256_Init(ctx);
return 0;
}
void ws_sha256_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t len) {
SHA256_Update(ctx, data, len);
}
void ws_sha256_final(
WS_SHA256_CTX *ctx,
unsigned char *buf) {
SHA256_Final(buf, ctx);
}
int ws_sha512_init(
WS_SHA512_CTX *ctx) {
SHA512_Init(ctx);
return 0;
}
void ws_sha512_update(
WS_SHA512_CTX *ctx,
const char *data,
size_t len) {
SHA512_Update(ctx, data, len);
}
void ws_sha512_final(
WS_SHA512_CTX *ctx,
unsigned char *buf) {
SHA512_Final(buf, ctx);
}
#else
int ws_sha1_init(
WS_SHA256_CTX *ctx) {
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
if(!mdctx) {
return 1;
}
EVP_DigestInit_ex(mdctx, EVP_sha1(),
NULL);
*ctx = mdctx;
return 0;
}
void ws_sha1_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t length) {
EVP_DigestUpdate(*ctx, data, length);
}
void ws_sha1_final(
WS_SHA256_CTX *ctx,
unsigned char *md) {
EVP_DigestFinal(*ctx, md,
NULL);
}
int ws_sha256_init(
WS_SHA256_CTX *ctx) {
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
if(!mdctx) {
return 1;
}
EVP_DigestInit_ex(mdctx, EVP_sha256(),
NULL);
*ctx = mdctx;
return 0;
}
void ws_sha256_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t length) {
EVP_DigestUpdate(*ctx, data, length);
}
void ws_sha256_final(
WS_SHA256_CTX *ctx,
unsigned char *md) {
EVP_DigestFinal(*ctx, md,
NULL);
}
int ws_sha512_init(
WS_SHA512_CTX *ctx) {
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
if(!mdctx) {
return 1;
}
EVP_DigestInit_ex(mdctx, EVP_sha512(),
NULL);
*ctx = mdctx;
return 0;
}
void ws_sha512_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t length) {
EVP_DigestUpdate(*ctx, data, length);
}
void ws_sha512_final(
WS_SHA256_CTX *ctx,
unsigned char *md) {
EVP_DigestFinal(*ctx, md,
NULL);
}
#endif
#endif
#ifdef WS_USE_CRYPTO_COMMON
int ws_sha1_init(
WS_SHA1_CTX *ctx) {
CC_SHA1_Init(ctx);
return 0;
}
void ws_sha1_update(
WS_SHA1_CTX *ctx,
const char *data,
size_t len) {
CC_SHA1_Update(ctx, data, len);
}
void ws_sha1_final(
WS_SHA1_CTX *ctx,
unsigned char *buf) {
CC_SHA1_Final(buf, ctx);
}
int ws_sha256_init(
WS_SHA256_CTX *ctx) {
CC_SHA256_Init(ctx);
return 0;
}
void ws_sha256_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t len) {
CC_SHA256_Update(ctx, data, len);
}
void ws_sha256_final(
WS_SHA256_CTX *ctx,
unsigned char *buf) {
CC_SHA256_Final(buf, ctx);
}
int ws_sha512_init(
WS_SHA512_CTX *ctx) {
CC_SHA512_Init(ctx);
return 0;
}
void ws_sha512_update(
WS_SHA512_CTX *ctx,
const char *data,
size_t len) {
CC_SHA512_Update(ctx, data, len);
}
void ws_sha512_final(
WS_SHA512_CTX *ctx,
unsigned char *buf) {
CC_SHA512_Final(buf, ctx);
}
#endif
#ifdef WS_USE_CRYPTO_CNG
static int cng_hash_init(WinBCryptSHACTX *ctx,
LPCWSTR algId) {
if(BCryptOpenAlgorithmProvider(&ctx->hAlg, algId,
NULL,
0)) {
return 1;
}
ULONG hashObjectLen;
ULONG result;
if(BCryptGetProperty(ctx->hAlg,
BCRYPT_OBJECT_LENGTH, (
PBYTE)&hashObjectLen,
sizeof(
DWORD), &result,
0)) {
cng_cleanup(ctx->hAlg,
NULL,
NULL,
NULL);
return 1;
}
ctx->pbHashObject = calloc(
1, hashObjectLen);
if(!ctx->pbHashObject) {
cng_cleanup(ctx->hAlg,
NULL,
NULL,
NULL);
return 1;
}
if(BCryptCreateHash(ctx->hAlg, &ctx->hHash, ctx->pbHashObject, hashObjectLen,
NULL,
0,
0)) {
cng_cleanup(ctx->hAlg,
NULL, ctx->hHash, ctx->pbHashObject);
return 1;
}
return 0;
}
static void cng_cleanup(
BCRYPT_ALG_HANDLE hAesAlg,
BCRYPT_KEY_HANDLE hKey,
BCRYPT_HASH_HANDLE hHash,
void *pbObject) {
if(hAesAlg) {
BCryptCloseAlgorithmProvider(hAesAlg,
0);
}
if(hKey) {
BCryptDestroyKey(hKey);
}
if(hHash) {
BCryptDestroyHash(hHash);
}
if(pbObject) {
free(pbObject);
}
}
int ws_sha1_init(
WS_SHA1_CTX *ctx) {
return cng_hash_init(ctx,
BCRYPT_SHA1_ALGORITHM);
}
void ws_sha1_update(
WS_SHA1_CTX *ctx,
const char *data,
size_t len) {
BCryptHashData(ctx->hHash, (
PUCHAR)data, len,
0);
}
void ws_sha1_final(
WS_SHA1_CTX *ctx,
unsigned char *buf) {
BCryptFinishHash(ctx->hHash, (
PUCHAR)buf,
DAV_SHA256_DIGEST_LENGTH,
0);
cng_cleanup(ctx->hAlg,
NULL, ctx->hHash, ctx->pbHashObject);
}
int ws_sha256_init(
WS_SHA256_CTX *ctx) {
return cng_hash_init(ctx,
BCRYPT_SHA256_ALGORITHM);
}
void ws_sha256_update(
WS_SHA256_CTX *ctx,
const char *data,
size_t len) {
BCryptHashData(ctx->hHash, (
PUCHAR)data, len,
0);
}
void ws_sha256_final(
WS_SHA256_CTX *ctx,
unsigned char *buf) {
BCryptFinishHash(ctx->hHash, (
PUCHAR)buf,
DAV_SHA256_DIGEST_LENGTH,
0);
cng_cleanup(ctx->hAlg,
NULL, ctx->hHash, ctx->pbHashObject);
}
int ws_sha512_init(
WS_SHA512_CTX *ctx) {
return cng_hash_init(ctx,
BCRYPT_SHA512_ALGORITHM);
}
void ws_sha512_update(
WS_SHA512_CTX *ctx,
const char *data,
size_t len) {
BCryptHashData(ctx->hHash, (
PUCHAR)data, len,
0);
}
void ws_sha512_final(
WS_SHA512_CTX *ctx,
unsigned char *buf) {
BCryptFinishHash(ctx->hHash, (
PUCHAR)buf,
DAV_SHA256_DIGEST_LENGTH,
0);
cng_cleanup(ctx->hAlg,
NULL, ctx->hHash, ctx->pbHashObject);
}
#endif