 |
|
| |
CRYPTO_SHA512(3MONOCYPHER) |
3MONOCYPHER |
CRYPTO_SHA512(3MONOCYPHER) |
crypto_sha512 ,
crypto_sha512_init ,
crypto_sha512_update ,
crypto_sha512_final
crypto_sha512_hmac ,
crypto_sha512_hmac_init ,
crypto_sha512_hmac_update ,
crypto_sha512_hmac_final ,
crypto_sha512_hkdf ,
crypto_sha512_hkdf_expand —
hashing, message authentication, and key derivation with
SHA-512
#include
<monocypher-ed25519.h>
void
crypto_sha512 (uint8_t hash[64],
const uint8_t *message, size_t
message_size);
void
crypto_sha512_init (crypto_sha512_ctx
*ctx);
void
crypto_sha512_update (crypto_sha512_ctx
*ctx, const uint8_t *message,
size_t message_size);
void
crypto_sha512_final (crypto_sha512_ctx
*ctx, uint8_t hash[64]);
void
crypto_sha512_hmac (uint8_t
hmac[64], const uint8_t *key,
size_t key_size, const uint8_t
*message, size_t message_size);
void
crypto_sha512_hmac_init (crypto_sha512_hmac_ctx
*ctx, const uint8_t *key, size_t
key_size);
void
crypto_sha512_hmac_update (crypto_sha512_hmac_ctx
*ctx, const uint8_t *message,
size_t message_size);
void
crypto_sha512_hmac_final (crypto_sha512_hmac_ctx
*ctx, uint8_t hmac[64]);
crypto_sha512_hkdf (uint8_t
*okm, size_t okm_size, const
uint8_t *ikm, size_t ikm_size,
const uint8_t *salt, size_t
salt_size, const uint8_t *info,
size_t info_size);
void
crypto_sha512_hkdf_expand (uint8_t
*okm, size_t okm_size, const
uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t
info_size);
void
crypto_sha512 (),
crypto_sha512_init (),
crypto_sha512_update (),
and
crypto_sha512_final ()
implement SHA-512, a cryptographically secure hash. They are provided to
enable compatibility with other cryptographic systems. It is generally
recommended to use
crypto_blake2b(3monocypher)
instead, as it both performs faster on x86_64 CPUs and lacks many of the
pitfalls of SHA-512.
Note that SHA-512 itself is not suitable for hashing passwords and
deriving keys from them; use the
crypto_argon2(3monocypher)
family of functions for that purpose instead.
SHA-512 is
vulnerable to length
extension attacks, and thus cannot directly be used for message
authentication codes (MAC), nor as a random oracle. For those, use the
crypto_sha512_hmac ()
family of functions instead.
The arguments are:
- hash
- The output SHA-512 hash, which is always 64-bytes long.
- message
- The message to hash. May be
NULL if
message_size is 0.
- message_size
- Length of message, in bytes.
crypto_sha512_hmac (),
crypto_sha512_hmac_init (),
crypto_sha512_hmac_update (),
and
crypto_sha512_hmac_final ()
implement HMAC with SHA-512, and can be used for message authentication
codes or as a random oracle. They are provided to enable compatibility with
other cryptographic systems. It is generally recommended to use keyed
crypto_blake2b(3monocypher)
instead, as it performs faster on x86_64 CPUs.
The arguments are:
- hmac
- The output MAC, which is always 64-bytes long. When used as a message
authentication code, it can safely be truncated down to 16 bytes. To avoid
timing attacks, use
crypto_verify16(3monocypher),
crypto_verify32(3monocypher),
or
crypto_verify64(3monocypher)
to compare (possibly truncated) MACs.
- key
- Some secret key. When uniformly random, one cannot predict the final HMAC
without it. Users may want to wipe the key with
crypto_wipe(3monocypher)
once they are done with it. Also stands for the salt
argument when using
crypto_sha512_hmac ()
for HKDF extraction.
- key_size
- Length of key, in bytes. 32 is a good default. Keys
longer than 128 bytes will be reduced to 64 bytes by hashing the key with
SHA-512.
- message
- The message to compute the HMAC for. May be
NULL
if message_size is 0. Also stands for the
ikm argument when using
crypto_sha512_hmac () for HKDF extraction.
- message_size
- Length of message, in bytes.
crypto_sha512_hkdf () and
crypto_sha512_hkdf_expand () implement HKDF key
derivation on top of SHA-512. HKDF is divided in two phases: first we
entropy from some input key material to produce a
pseudo-random key (PRK) which is indistinguishable from
uniform random bytes. Then we
expand
that pseudo-random key into a longer stream of independent random bytes
called output
key material (OKM).
HKDF extraction is already implemented
in
crypto_sha512_hmac (),
so there is no dedicated function. HKDF expansion is implemented by
crypto_sha512_hkdf_expand ().
Note that expansion works with any uniformly random key, the PRK does not
have to come from crypto_sha512_hmac () specifically.
Likewise, if compatibility or standard compliance is not an issue, expansion
could in principle use any pseudo-random function, such as
crypto_chacha20_djb(3monocypher).
crypto_sha512_hkdf ()
is a convenience function that performs
crypto_sha512_hmac () and
crypto_sha512_hkdf_expand ().
Contrary to most functions in
Monocypher, the inputs of
crypto_sha512_hkdf ()
and
crypto_sha512_hkdf_expand ()
cannot
overlap with their output. The unlimited size of both inputs and
output prevents us from from caching one of them in a local variable.
The arguments are:
- okm
- The output key material of HKDF or HKDF expansion, usable as a symmetric
encryption key, or set thereof.
- okm_size
- Length of okm, in bytes.
- ikm
- Input key material containing enough secret entropy to derive uniformly
random keys from, such as the shared secret of a key exchange performed
with
crypto_x25519(3monocypher).
Passwords do not contain enough entropy to be used as
input key material. Hash them with
crypto_argon2(3monocypher)
instead.
- ikm_size
- Length of ikm, in bytes.
- prk
- Pseudo-random key. Typically comes from an HKDF extraction with
crypto_sha512_hmac (),
but can come from any source as long as it is uniformly random. Should be
at least 32 bytes long.
- prk_size
- Length of prk, in bytes.
- salt
- An optional random salt, used to increase the security of the output key
material okm in some settings. Can be NULL if
salt_size is zero. Otherwise it should contain at
least 16 bytes.
- salt_size
- Length of salt, in bytes.
- info
- Optional domain separation string for key derivation. Can be NULL if
info_size is zero.
- info_size
- Length of info, in bytes.
An incremental interface is provided. It is useful for handling
streams of data or large files without using too much memory. This interface
uses three steps:
- initialisation with
crypto_sha512_init ()
or crypto_sha512_hmac_init (), which sets up a
context with the hashing parameters;
- update with
crypto_sha512_update () or
crypto_sha512_hmac_update (), which hashes the
message chunk by chunk and keeps the intermediary result in the
context;
- and finalisation with
crypto_sha512_final () or
crypto_sha512_hmac_final (), which produces the
final hash. The crypto_sha512_ctx or
crypto_sha512_hmac_ctx is automatically wiped upon
finalisation.
crypto_sha512 ()
is a convenience function that performs
crypto_sha512_init (),
crypto_sha512_update (),
and
crypto_sha512_final ().
crypto_sha512_hmac ()
is a convenience function that performs
crypto_sha512_hmac_init (),
crypto_sha512_hmac_update (),
and
crypto_sha512_hmac_final ().
These functions return nothing.
Hashing a message all at once:
uint8_t hash [64]; /* Output hash (64 bytes) */
uint8_t message[12] = "Lorem ipsum"; /* Message to hash */
crypto_sha512(hash, message, 12);
Hashing a message incrementally:
uint8_t hash [ 64]; /* Output hash (64 bytes) */
uint8_t message[500] = {1}; /* Message to hash */
crypto_sha512_ctx ctx;
crypto_sha512_init(&ctx);
for (size_t i = 0; i < 500; i += 100) {
crypto_sha512_update(&ctx, message + i, 100);
}
crypto_sha512_final(&ctx, hash);
Computing a message authentication code all at once:
uint8_t hash [64]; /* Output hash */
uint8_t key [32]; /* Key */
uint8_t message[10] = "Lorem ipsu"; /* Message to authenticate */
arc4random_buf(key, 32);
crypto_sha512_hmac(hash, key, 32, message, 10);
/* Wipe secrets if they are no longer needed */
crypto_wipe(message, 10);
crypto_wipe(key, 32);
Computing a message authentication code incrementally:
uint8_t hash [64]; /* Output hash */
uint8_t key [32]; /* Key */
uint8_t message[500] = {1}; /* Message to authenticate */
crypto_sha512_hmac_ctx ctx;
arc4random_buf(key, 32);
crypto_sha512_hmac_init(&ctx, key, 32);
/* Wipe the key */
crypto_wipe(key, 32);
for (size_t i = 0; i < 500; i += 100) {
crypto_sha512_hmac_update(&ctx, message + i, 100);
/* Wipe secrets if they are no longer needed */
crypto_wipe(message + i, 100);
}
crypto_sha512_hmac_final(&ctx, hash);
Deriving keys from input key material:
uint8_t okm[128]; /* Output random keys */
uint8_t ikm [96]; /* Input key material */
uint8_t salt[16]; /* Random salt */
uint8_t info[11] = "Lorem ipsum"; /* Domain separation */
arc4random_buf(salt, sizeof(salt));
crypto_sha512_hkdf(okm, sizeof(okm),
ikm, sizeof(ikm),
salt, sizeof(salt),
info, sizeof(info));
uint8_t *key1 = okm + 0;
uint8_t *key2 = okm + 32;
uint8_t *key3 = okm + 64;
uint8_t *key4 = okm + 96;
/* Wipe okm when it is no longer needed */
Deriving keys from several bits of input key material:
uint8_t okm [96]; /* Output secret keys */
uint8_t pk_a[32]; /* Alice public X25519 key */
uint8_t pk_b[32]; /* Bob public X25519 key */
uint8_t skab[32]; /* Alice & bob shared secret */
uint8_t ikm [96]; /* Input key material */
uint8_t salt[16]; /* Random salt */
uint8_t info[ 6] = "X25519"; /* Domain separation */
arc4random_buf(salt, sizeof(salt));
/* Extract */
uint8_t prk[64]; /* pseudo-random key */
crypto_sha512_hmac_ctx ctx;
crypto_sha512_hmac_init (&ctx, salt, sizeof(salt));
crypto_sha512_hmac_update(&ctx, pk_a, sizeof(pk_a));
crypto_sha512_hmac_update(&ctx, pk_b, sizeof(pk_b));
crypto_sha512_hmac_update(&ctx, skab, sizeof(skab));
crypto_sha512_hmac_final (&ctx, prk);
/* Expand */
crypto_sha512_hkdf_expand(okm, sizeof(okm),
prk, sizeof(prk),
info, sizeof(info));
uint8_t *key1 = okm + 0;
uint8_t *key2 = okm + 32;
uint8_t *key3 = okm + 64;
/* Wipe okm when it is no longer needed */
These functions implement SHA-512, HMAC with SHA-512, and HKDF
with SHA-512. HMAC and SHA-512 are described in RFC 6234; SHA-512 is also
described in the Federal Information Processing Standard (FIPS) 180-4; HMAC
is also described in FIPS 198-1. HKDF is described in RFC 5869.
The crypto_sha512 (),
crypto_sha512_init (),
crypto_sha512_update (), and
crypto_sha512_final () functions first appeared in
Monocypher 0.3, but were not intended for use outside Monocypher itself and
thus undocumented. They became part of the official API in Monocypher
3.0.0.
The crypto_hmac_sha512 (),
crypto_hmac_sha512_init (),
crypto_hmac_sha512_update (), and
crypto_hmac_sha512_final () functions first appeared
in Monocypher 3.0.0, then renamed
crypto_sha512_hmac (),
crypto_sha512_hmac_init (),
crypto_sha512_hmac_update (), and
crypto_sha512_hmac_final () in Monocypher 4.0.0.
crypto_sha512_hkdf () and
crypto_sha512_hkdf_expand () were added in Monocypher
4.0.0.
Monocypher does not perform any input validation. Any deviation
from the specified input and output length ranges results in
undefined
behaviour. Make sure your inputs are correct.
SHA-512 is a general-purpose cryptographic hash function; this
means that it is not suited for hashing passwords and deriving cryptographic
keys from passwords. While cryptographic keys usually have hundreds of bits
of entropy, passwords are often much less complex. When storing passwords as
hashes or when deriving keys from them, the goal is normally to prevent
attackers from quickly iterating all possible passwords. Because passwords
tend to be simple, it is important to artificially slow down attackers by
using especially computationally difficult hashing algorithms. Monocypher
therefore provides
crypto_argon2(3monocypher)
for password hashing and deriving keys from passwords.
While HKDF and HMAC are proper key derivation
functions (KDF), the HKDF expand step alone is not. It is
a pseudo-random function (PRF), that only works with a
uniformly
random key. We cannot simply input regular (non uniform) input key material
without making unusually strong assumptions about the security of HMAC.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc.
|