author | Olivier Brunel
<jjk@jjacky.com> 2023-04-06 18:14:03 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:35 UTC |
parent | 0bdbefac680bfd9e25b9e824d41c5958a76ce52a |
src/doc/hasher.h.0.md | +1 | -1 |
src/doc/hasher.h/hasher_hash.3.md | +1 | -1 |
src/doc/hmac.h.0.md | +1 | -1 |
src/doc/hmac.h/hmac.3.md | +8 | -1 |
src/doc/pbkdf2.h.0.md | +27 | -0 |
src/doc/pbkdf2.h/pbkdf2.3.md | +35 | -0 |
src/liblimb/include/limb/pbkdf2.h | +13 | -0 |
src/liblimb/pbkdf2.h/pbkdf2.c | +48 | -0 |
diff --git a/src/doc/hasher.h.0.md b/src/doc/hasher.h.0.md index 1b2fae4..f5482c0 100644 --- a/src/doc/hasher.h.0.md +++ b/src/doc/hasher.h.0.md @@ -53,4 +53,4 @@ The following functions/macros are defined : # SEE ALSO -[hmac.h](0) +[hmac.h](0), [pbkdf2.h](0) diff --git a/src/doc/hasher.h/hasher_hash.3.md b/src/doc/hasher.h/hasher_hash.3.md index 01b60f2..598c7e6 100644 --- a/src/doc/hasher.h/hasher_hash.3.md +++ b/src/doc/hasher.h/hasher_hash.3.md @@ -130,4 +130,4 @@ out("The SHA1 of ", ESC, msg, ESC, " is ", HEX(digest, sizeof(digest))); # SEE ALSO -[hmac](3), [blake3_init](3), [sha3_224_init](3) +[hmac](3), [pbkdf2](3), [blake3_init](3), [sha3_224_init](3) diff --git a/src/doc/hmac.h.0.md b/src/doc/hmac.h.0.md index bdc21ad..4c48283 100644 --- a/src/doc/hmac.h.0.md +++ b/src/doc/hmac.h.0.md @@ -22,4 +22,4 @@ The following functions are defined : # SEE ALSO -[hasher.h](0) +[hasher.h](0), [pbkdf2.h](0) diff --git a/src/doc/hmac.h/hmac.3.md b/src/doc/hmac.h/hmac.3.md index b9d1c0b..c794238 100644 --- a/src/doc/hmac.h/hmac.3.md +++ b/src/doc/hmac.h/hmac.3.md @@ -16,7 +16,8 @@ void hmac(char *<em>out</em>, hasher *<em>hr</em>, const void *<em>key</em>, siz # 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`. +using the secret key `key` of length `klen` and the cryptographic hasher `hr`, +as described in [RFC 2104][rfc2104]. 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, @@ -24,6 +25,8 @@ i.e. `hr->hlen` bytes. For a list of available hashers, refer to [hasher_hash](3). +[rfc2104]: https://datatracker.ietf.org/doc/html/rfc2104 + # EXAMPLE ```c @@ -43,3 +46,7 @@ int main(void) return 0; } ``` + +# SEE ALSO + +[pbkdf2](3) diff --git a/src/doc/pbkdf2.h.0.md b/src/doc/pbkdf2.h.0.md new file mode 100644 index 0000000..3b7fd5f --- /dev/null +++ b/src/doc/pbkdf2.h.0.md @@ -0,0 +1,27 @@ +% limb manual +% pbkdf2.h(0) + +# NAME + +pbkdf2.h - compute PBKDF2 + +# SYNOPSIS + + #include <limb/pbkdf2.h> + +# DESCRIPTION + +This header defines the required functions to derive a key from a password via +PBKDF2. + +## Functions + +The following functions are defined : + +: [pbkdf2](3) +:: Derive a key from given password & salt using PBKDF2 based on the given +:: hasher. + +# SEE ALSO + +[hasher.h](0), [hmac.h](0) diff --git a/src/doc/pbkdf2.h/pbkdf2.3.md b/src/doc/pbkdf2.h/pbkdf2.3.md new file mode 100644 index 0000000..f2fc38b --- /dev/null +++ b/src/doc/pbkdf2.h/pbkdf2.3.md @@ -0,0 +1,35 @@ +% limb manual +% pbkdf2(3) + +# NAME + +pbkdf2 - derive a key from given password & salt using PBKDF2 + +# SYNOPSIS + + #include <limb/pbkdf2.h> + +```pre hl +int pbkdf2(char *<em>dst</em>, size_t dlen, hasher *<em>hr</em>, const char *<em>pwd</em>, size_t <em>plen</em>, + const char *<em>salt</em>, size_t <em>slen</em>, size_t <em>iter</em) +``` + +# DESCRIPTION + +The `pbkdf2`() function derives a key of `dlen` bytes from the given `password` +of length `plen` bytes and `salt` of length `slen` bytes, through `iter` +iterations, using the HMAC based on the cryptographioc hasher `hr`, and writing +it into `dst`, as described in [RFC 8018][rfc8018]. + +For a list of available hashers, refer to [hasher_hash](3). + +[rfc8018]: https://datatracker.ietf.org/doc/html/rfc8018 + +# RETURN VALUE + +The `pbkdf2`() function returns 1 on success. Otherwise it returns 0, which can +only happen if `dlen` is too large, i.e. greater than 2^32 - 1. + +# SEE ALSO + +[hmac](3), [hasher_hash](3) diff --git a/src/liblimb/include/limb/pbkdf2.h b/src/liblimb/include/limb/pbkdf2.h new file mode 100644 index 0000000..49e7929 --- /dev/null +++ b/src/liblimb/include/limb/pbkdf2.h @@ -0,0 +1,13 @@ +/* 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_PBKDF2_H +#define LIMB_PBKDF2_H + +#include <stddef.h> /* size_t */ +#include <limb/hasher.h> + +extern int pbkdf2(char *dst, size_t dlen, hasher *hr, const char *pwd, size_t plen, + const char *salt, size_t slen, size_t iter); + +#endif /* LIMB_PBKDF2_H */ diff --git a/src/liblimb/pbkdf2.h/pbkdf2.c b/src/liblimb/pbkdf2.h/pbkdf2.c new file mode 100644 index 0000000..2d76e14 --- /dev/null +++ b/src/liblimb/pbkdf2.h/pbkdf2.c @@ -0,0 +1,48 @@ +/* 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 <limb/hasher.h> +#include <limb/hmac.h> +#include <limb/memxor.h> +#include <limb/u32.h> + +static void +block(void *dst, hasher *hr, const char *pwd, size_t plen, const char *salt, size_t slen, + size_t iter, size_t num, size_t r) +{ + size_t blen, mlen = slen + sizeof(u32); + if (hr->hlen > mlen) + blen = hr->hlen; + else + blen = mlen; + + char buf[blen]; + memcpy(buf, salt, slen); + u32_pack_big(buf + slen, num); + hmac(buf, hr, pwd, plen, buf, mlen); + + memcpy(dst, buf, r); + for (size_t i = 1; i < iter; ++i) { + hmac(buf, hr, pwd, plen, buf, hr->hlen); + memxor(dst, buf, r); + } +} + +int +pbkdf2(char *dst, size_t dlen, hasher *hr, const char *pwd, size_t plen, + const char *salt, size_t slen, size_t iter) +{ + if (dlen > (1ULL << 32) - 1) + return 0; + + size_t l = dlen / hr->hlen; + if (dlen % hr->hlen) ++l; + + size_t r = dlen - (l - 1) * hr->hlen; + for (size_t i = 1; i <= l; ++i) + block(dst + (i - 1) * hr->hlen, hr, pwd, plen, salt, slen, iter, i, + (i < l) ? hr->hlen : r); + + return 1; +}