author | Olivier Brunel
<jjk@jjacky.com> 2023-03-26 17:17:18 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:05:20 UTC |
parent | 5c9b41ae08bc7474aca50db29d2e1786414ac388 |
doc/hasher.h.0.md | +4 | -0 |
doc/hasher_hash.3.md | +1 | -1 |
doc/hmac.3.md | +45 | -0 |
doc/hmac.h.0.md | +25 | -0 |
include/limb/hmac.h | +11 | -0 |
meta/libs/limb | +2 | -0 |
src/hmac.c | +43 | -0 |
diff --git a/doc/hasher.h.0.md b/doc/hasher.h.0.md index a6b2369..1b2fae4 100644 --- a/doc/hasher.h.0.md +++ b/doc/hasher.h.0.md @@ -50,3 +50,7 @@ The following functions/macros are defined : : [hfinal](3) :: To obtain the hash from a hasher. + +# SEE ALSO + +[hmac.h](0) diff --git a/doc/hasher_hash.3.md b/doc/hasher_hash.3.md index a6d5f74..01b60f2 100644 --- a/doc/hasher_hash.3.md +++ b/doc/hasher_hash.3.md @@ -130,4 +130,4 @@ out("The SHA1 of ", ESC, msg, ESC, " is ", HEX(digest, sizeof(digest))); # SEE ALSO -[blake3_init](3), [sha3_224_init](3) +[hmac](3), [blake3_init](3), [sha3_224_init](3) diff --git a/doc/hmac.3.md b/doc/hmac.3.md new file mode 100644 index 0000000..b9d1c0b --- /dev/null +++ b/doc/hmac.3.md @@ -0,0 +1,45 @@ +% limb manual +% hmac(3) + +# NAME + +hmac - compute the HMAC of a given message using given hasher and key + +# SYNOPSIS + + #include <limb/hmac.h> + +```pre hl +void hmac(char *<em>out</em>, hasher *<em>hr</em>, const void *<em>key</em>, size_t <em>klen</em>, const void *<em>msg</em>, size_t <em>mlen</em>) +``` + +# DESCRIPTION + +The `hmac`() function calculates the HMAC of message `msg` of length `mlen`, +using the secret key `key` of length `klen` and the cryptographic hasher `hr`. + +The results if then copied into the buffer pointed by `out` which must be able +to hold at least the length of a message digest from the hash function used, +i.e. `hr->hlen` bytes. + +For a list of available hashers, refer to [hasher_hash](3). + +# EXAMPLE + +```c +#include <limb/hmac.h> +#include <limb/hasher_sha1.h> +#include <limb/output.h> + +int main(void) +{ + const char *msg = "The quick brown fox jumps over the lazy dog"; + const char *key = "key"; + char out[sha1->hlen]; + + hmac(out, sha1, key, 3, msg, strlen(msg)); + out("HMAC-SHA1(\"key\", \"", msg, "\") = ", HEX(out, sizeof(out))); + + return 0; +} +``` diff --git a/doc/hmac.h.0.md b/doc/hmac.h.0.md new file mode 100644 index 0000000..bdc21ad --- /dev/null +++ b/doc/hmac.h.0.md @@ -0,0 +1,25 @@ +% limb manual +% hmac.h(0) + +# NAME + +hmac.h - computing HMACs + +# SYNOPSIS + + #include <limb/hmac.h> + +# DESCRIPTION + +This header defines the required functions to compute HMACs of messages. + +## Functions + +The following functions are defined : + +: [hmac](3) +:: Compute the HMAC of a given message using given hasher and key + +# SEE ALSO + +[hasher.h](0) diff --git a/include/limb/hmac.h b/include/limb/hmac.h new file mode 100644 index 0000000..7f02ac1 --- /dev/null +++ b/include/limb/hmac.h @@ -0,0 +1,11 @@ +/* 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_HMAC_H +#define LIMB_HMAC_H + +#include "limb/hasher.h" + +extern void hmac(char *out, hasher *h, const void *key, size_t klen, const void *msg, size_t mlen); + +#endif /* LIMB_HMAC_H */ diff --git a/meta/libs/limb b/meta/libs/limb index d57a6eb..5910f3c 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -111,5 +111,7 @@ obj/hasher_sha3_224.o obj/hasher_sha3_256.o obj/hasher_sha3_384.o obj/hasher_sha3_512.o +# hmac.h +obj/hmac.o # skalibs dependency skalibs diff --git a/src/hmac.c b/src/hmac.c new file mode 100644 index 0000000..5c2b926 --- /dev/null +++ b/src/hmac.c @@ -0,0 +1,43 @@ +/* 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 <string.h> +#include <skalibs/bytestr.h> +#include "limb/hmac.h" + +void +hmac(char *out, hasher *h, const void *key, size_t klen, const void *msg, size_t mlen) +{ + unsigned char secret[h->blen]; + size_t l; + + if (klen > h->blen) { + hinit(h); + hupdate(key, klen, h); + hfinal(secret, h); + l = h->hlen; + } else { + memcpy(secret, key, klen); + l = klen; + } + memset(secret + l, 0, h->blen - l); + + unsigned char buf[h->blen]; + + for (int i = 0; i < h->blen; ++i) { + buf[i] = secret[i] ^ 0x36; + secret[i] ^= 0x5c; + } + + hinit(h); + hupdate(buf, h->blen, h); + hupdate(msg, mlen, h); + hfinal(buf, h); + + hinit(h); + hupdate(secret, h->blen, h); + hupdate(buf, h->hlen, h); + hfinal(out, h); + + byte_zero(secret, h->blen); +}