core: add support for lots of different hash algorithms
This commit is contained in:
139
core/hash/hash.c
Normal file
139
core/hash/hash.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user