140 lines
3.2 KiB
C
140 lines
3.2 KiB
C
|
|
#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;
|
||
|
|
}
|