author | Olivier Brunel
<jjk@jjacky.com> 2023-03-26 13:07:56 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-03-26 14:03:03 UTC |
parent | 2e3d09c11ae56fd1f65f9c061a1bfedd1cd9c913 |
doc/hasher.h.0.md | +52 | -0 |
doc/hasher_hash.3.md | +87 | -0 |
include/limb/hasher.h | +31 | -0 |
meta/libs/limb | +2 | -0 |
src/hasher_hash.c | +12 | -0 |
diff --git a/doc/hasher.h.0.md b/doc/hasher.h.0.md new file mode 100644 index 0000000..a6b2369 --- /dev/null +++ b/doc/hasher.h.0.md @@ -0,0 +1,52 @@ +% limb manual +% hasher.h(0) + +# NAME + +hasher.h - generic message digest interface + +# SYNOPSIS + + #include <limb/hasher.h> + +# DESCRIPTION + +This header defines the required functions to compute message digests through a +generic interface. + +## Types + +The following types are defined : + +: *hasher_init* +:: Generic pointer function for context initialization + +: *hasher_upate* +:: Generic pointer function for feeding data into a hashing context + +: *hasher_final* +:: Generic pointer function for computing/obtaining the message digest + +## Structures + +The following structures are defined : + +: *struct hasher*, *hasher* +:: A structure representing a hasher, allowing to compute a message digest +:: through the algorithm of said hasher. + +## Functions + +The following functions/macros are defined : + +: [hasher_hash](3) +:: To compute the message digest through a given hasher + +: [hinit](3) +:: To initialize a hasher. + +: [hupdate](3) +:: To feed data into a hasher. + +: [hfinal](3) +:: To obtain the hash from a hasher. diff --git a/doc/hasher_hash.3.md b/doc/hasher_hash.3.md new file mode 100644 index 0000000..457c1fd --- /dev/null +++ b/doc/hasher_hash.3.md @@ -0,0 +1,87 @@ +% limb manual +% hasher_hash(3) + +# NAME + +hasher\_hash, hinit, hupdate, hfinal - compute a message digest using a given hasher + +# SYNOPSIS + + #include <limb/hasher.h> + +```pre hl +void hinit (hasher *<em>hasher</em>) +void hupdate (const void *<em>msg</em>, size_t <em>mlen</em>, hasher *<em>hasher</em>) +void hfinal (void *<em>digest</em>, hasher *<em>hasher</em>) + +void hasher_hash(void *<em>digest</em>, const void *<em>msg</em>, size_t <em>mlen</em>, hasher *<em>hasher</em>) +``` + +# DESCRIPTION + +A hasher is a structure containing all required information to compute a message +digest for a given algorithm. It is defined as such : + + typedef void (*hasher_init) (void *ctx); + typedef void (*hasher_update) (const void *msg, size_t mlen, void *ctx); + typedef void (*hasher_final) (void *digest, void *ctx); + + struct hasher { + size_t hlen; + size_t blen; + hasher_init init; + hasher_update update; + hasher_final final; + void *ctx; + }; + +The members are the following : + +: `hlen` +:: Length (in bytes) of the generated hash/message digest. + +: `blen` +:: Length (in bytes) of the internal block size for the algorithm. + +: `init` +:: Function to call to initialize the hasher's context. + +: `update` +:: Function to call to feed data into the hasher. + +: `final` +:: Function to call to obtain the hash/message digest from the hasher. + +: `ctx` +:: The hasher's (opaque) context. + +Though it is possible to call the previously mentioned functions directly, some +macros are available to make things easier. + +The `hinit`() macro initializes the hasher `hasher` to calculate a new message +digest. + +The `hupdate`() macro feeds the specified chunk of data pointed by `msg` of +length `mlen` to be hashed into the given `hasher`. You can call this function +repeatedly as many times as needed. + +The `hfinal`() macro stores the calculated hash from `hasher` in binary form +into `digest`, which must be able to store as many bytes as needed, available +through `hasher->hlen`. + +Finally, the `hasher_hash`() function is there for convenience, allowing to +compute into `digest` the message digest for message `msg` of length `mlen` +using `hasher` all in a single call, when the entire message is available in +a single continuous memory area. + +# EXAMPLE + +To compute the SHA1 of a given message, and show it on *stdout*, one could do : + +```c +const char *msg = "The quick brown fox jumps over the lazy dog"; +char digest[sha1->hlen]; + +hasher_hash(digest, msg, strlen(msg), sha1); +out("The SHA1 of ", ESC, msg, ESC, " is ", HEX(digest, sizeof(digest))); +``` diff --git a/include/limb/hasher.h b/include/limb/hasher.h new file mode 100644 index 0000000..af7aa1a --- /dev/null +++ b/include/limb/hasher.h @@ -0,0 +1,31 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LIMB_HASHER_H +#define LIMB_HASHER_H + +#include <stddef.h> /* size_t */ +#include "limb/int.h" + +typedef void (*hasher_init) (void *ctx); +typedef void (*hasher_update) (const void *msg, size_t mlen, void *ctx); +typedef void (*hasher_final) (void *digest, void *ctx); + +typedef struct hasher hasher; + +struct hasher { + size_t hlen; + size_t blen; + hasher_init init; + hasher_update update; + hasher_final final; + u8 ctx[]; +}; + +#define hinit(h) h->init(h->ctx) +#define hupdate(d,l,h) h->update(d, l, h->ctx) +#define hfinal(o,h) h->final(o, h->ctx) + +extern void hasher_hash(void *digest, const void *msg, size_t mlen, hasher *hasher); + +#endif /* LIMB_HASHER_H */ diff --git a/meta/libs/limb b/meta/libs/limb index b26bf93..a0508a9 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -85,6 +85,8 @@ obj/hmap/hmap_init.o obj/hmap/hmap_set.o obj/hmap/hmap_get.o obj/hmap/hmap_free.o +# hasher.h +obj/hasher_hash.o # SHA3 obj/sha3/byte_order.o obj/sha3/rhash_sha3_process_block.o diff --git a/src/hasher_hash.c b/src/hasher_hash.c new file mode 100644 index 0000000..2259a84 --- /dev/null +++ b/src/hasher_hash.c @@ -0,0 +1,12 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/hasher.h" + +void +hasher_hash(void *md, const void *msg, size_t mlen, hasher *h) +{ + hinit(h); + hupdate(msg, mlen, h); + hfinal(md, h); +}