Files
bluelib/core/hash/hash.c

140 lines
3.2 KiB
C
Raw Normal View History

#include "hash.h"
#include <blue/core/hash.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define FNV1_OFFSET_BASIS 0xcbf29ce484222325
#define FNV1_PRIME 0x100000001b3
extern struct b_hash_function_ops z__b_md4_ops;
extern struct b_hash_function_ops z__b_md5_ops;
extern struct b_hash_function_ops z__b_sha1_ops;
extern struct b_hash_function_ops z__b_sha2_224_ops;
extern struct b_hash_function_ops z__b_sha2_256_ops;
extern struct b_hash_function_ops z__b_sha2_384_ops;
extern struct b_hash_function_ops z__b_sha2_512_ops;
extern struct b_hash_function_ops z__b_sha3_224_ops;
extern struct b_hash_function_ops z__b_sha3_256_ops;
extern struct b_hash_function_ops z__b_sha3_384_ops;
extern struct b_hash_function_ops z__b_sha3_512_ops;
extern struct b_hash_function_ops z__b_shake128_ops;
extern struct b_hash_function_ops z__b_shake256_ops;
static const struct b_hash_function_ops *hash_functions[] = {
[B_HASH_NONE] = NULL,
[B_HASH_MD4] = &z__b_md4_ops,
[B_HASH_MD5] = &z__b_md5_ops,
[B_HASH_SHA1] = &z__b_sha1_ops,
[B_HASH_SHA2_224] = &z__b_sha2_224_ops,
[B_HASH_SHA2_256] = &z__b_sha2_256_ops,
[B_HASH_SHA2_384] = &z__b_sha2_384_ops,
[B_HASH_SHA2_512] = &z__b_sha2_512_ops,
[B_HASH_SHA3_224] = &z__b_sha3_224_ops,
[B_HASH_SHA3_256] = &z__b_sha3_256_ops,
[B_HASH_SHA3_384] = &z__b_sha3_384_ops,
[B_HASH_SHA3_512] = &z__b_sha3_512_ops,
[B_HASH_SHAKE128] = &z__b_shake128_ops,
[B_HASH_SHAKE256] = &z__b_shake256_ops,
};
static const size_t nr_hash_functions
= sizeof hash_functions / sizeof hash_functions[0];
uint64_t b_hash_string(const char *s)
{
size_t x = 0;
return b_hash_string_ex(s, &x);
}
uint64_t b_hash_string_ex(const char *s, size_t *len)
{
uint64_t hash = FNV1_OFFSET_BASIS;
size_t i = 0;
for (i = 0; s[i]; i++) {
hash ^= s[i];
hash *= FNV1_PRIME;
}
if (len) {
*len = i;
}
return hash;
}
enum b_status b_hash_ctx_init(struct b_hash_ctx *ctx, enum b_hash_function func)
{
if (func < 0 || func >= nr_hash_functions) {
return B_ERR_NOT_SUPPORTED;
}
const struct b_hash_function_ops *hash_function = hash_functions[func];
if (!hash_function) {
return B_ERR_NOT_SUPPORTED;
}
memset(ctx, 0x0, sizeof *ctx);
ctx->ctx_func = func;
ctx->ctx_ops = hash_function;
if (hash_function->hash_init) {
hash_function->hash_init(ctx);
}
return B_SUCCESS;
}
enum b_status b_hash_ctx_reset(struct b_hash_ctx *ctx)
{
if (ctx->ctx_func == B_HASH_NONE || !ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state);
if (ctx->ctx_ops->hash_init) {
ctx->ctx_ops->hash_init(ctx);
}
return B_SUCCESS;
}
enum b_status b_hash_ctx_update(struct b_hash_ctx *ctx, const void *p, size_t len)
{
if (!ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
if (!ctx->ctx_ops->hash_update) {
return B_ERR_NOT_SUPPORTED;
}
ctx->ctx_ops->hash_update(ctx, p, len);
return B_SUCCESS;
}
enum b_status b_hash_ctx_finish(
struct b_hash_ctx *ctx, void *out_digest, size_t out_max)
{
if (!ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
if (!ctx->ctx_ops->hash_finish) {
return B_ERR_NOT_SUPPORTED;
}
ctx->ctx_ops->hash_finish(ctx, out_digest, out_max);
memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state);
if (ctx->ctx_ops->hash_init) {
ctx->ctx_ops->hash_init(ctx);
}
return B_SUCCESS;
}