Libsodium documentation
  • Introduction
  • Installation
  • Quickstart and FAQ
  • Projects using libsodium
  • Commercial support
  • Bindings for other languages
  • Usage
  • Helpers
  • Padding
  • Secure memory
  • Generating random data
  • Secret-key cryptography
    • Authenticated encryption
    • Encrypted streams and file encryption
    • Encrypting a set of related messages
    • Authentication
    • AEAD constructions
      • ChaCha20-Poly1305
        • Original ChaCha20-Poly1305 construction
        • IETF ChaCha20-Poly1305 construction
        • XChaCha20-Poly1305 construction
      • AEGIS-256
      • AEGIS-128L
      • AES256-GCM
        • AES256-GCM with precomputation
  • Public-key cryptography
    • Authenticated encryption
    • Public-key signatures
    • Sealed boxes
  • Hashing
    • Generic hashing
    • Short-input hashing
  • Password hashing
    • The pwhash* API
  • Key derivation
    • HKDF
  • Key exchange
  • Advanced
    • SHA-2
    • HMAC-SHA-2
    • The Scrypt function
    • Point*scalar multiplication
    • One-time authentication
    • Stream ciphers
      • ChaCha20
      • XChaCha20
      • Salsa20
      • XSalsa20
    • Ed25519 to Curve25519
    • Finite field arithmetic
      • Ristretto
    • Custom RNG
  • Internals
  • Roadmap
Powered by GitBook
On this page
  • Single-part example
  • Multi-part example
  • Usage
  • HMAC-SHA-256
  • HMAC-SHA-512
  • HMAC-SHA-512-256
  • Constants
  • Data types
  • Notes
  • References
  1. Advanced

HMAC-SHA-2

PreviousSHA-2NextThe Scrypt function

Last updated 10 months ago

The keyed message authentication codes HMAC-SHA-256, HMAC-SHA-512 and HMAC-SHA512-256 (truncated HMAC-SHA-512) are provided.

The API provides a simplified interface for message authentication.

If required, a streaming API is available to process a message as a sequence of multiple chunks.

Single-part example

#define MESSAGE ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_LEN 22

unsigned char hash[crypto_auth_hmacsha512_BYTES];
unsigned char key[crypto_auth_hmacsha512_KEYBYTES];

crypto_auth_hmacsha512_keygen(key);
crypto_auth_hmacsha512(hash, MESSAGE, MESSAGE_LEN, key);

Multi-part example

#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char hash[crypto_auth_hmacsha512_BYTES];
unsigned char key[crypto_auth_hmacsha512_KEYBYTES];
crypto_auth_hmacsha512_state state;

crypto_auth_hmacsha512_keygen(key);

crypto_auth_hmacsha512_init(&state, key, sizeof key);

crypto_auth_hmacsha512_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_auth_hmacsha512_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_auth_hmacsha512_final(&state, hash);

Usage

HMAC-SHA-256

int crypto_auth_hmacsha256(unsigned char *out,
                           const unsigned char *in,
                           unsigned long long inlen,
                           const unsigned char *k);

The crypto_auth_hmacsha256() function authenticates a message in whose length is inlen using the secret key k whose length is crypto_auth_hmacsha256_KEYBYTES, and puts the authenticator into out (crypto_auth_hmacsha256_BYTES bytes).

int crypto_auth_hmacsha256_verify(const unsigned char *h,
                                  const unsigned char *in,
                                  unsigned long long inlen,
                                  const unsigned char *k);

The crypto_auth_hmacsha256_verify() function verifies in constant time that h is a correct authenticator for the message in whose length is inlen under a secret key k (crypto_auth_hmacsha256_KEYBYTES bytes).

It returns -1 if the verification fails, and 0 on success.

A multi-part (streaming) API can be used instead of crypto_auth_hmacsha256():

int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
                                const unsigned char *key,
                                size_t keylen);
int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
                                 unsigned char *out);

This alternative API supports a key of arbitrary length keylen.

However, please note that in the HMAC construction, a key larger than the block size gets reduced to h(key).

void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]);

This helper function introduced in libsodium 1.0.12 creates a random key k.

It is equivalent to calling randombytes_buf() but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

HMAC-SHA-512

Similarly to the crypto_auth_hmacsha256_*() set of functions, the crypto_auth_hmacsha512_*() set of functions implements HMAC-SHA512:

int crypto_auth_hmacsha512(unsigned char *out,
                           const unsigned char *in,
                           unsigned long long inlen,
                           const unsigned char *k);
int crypto_auth_hmacsha512_verify(const unsigned char *h,
                                  const unsigned char *in,
                                  unsigned long long inlen,
                                  const unsigned char *k);
int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
                                const unsigned char *key,
                                size_t keylen);
int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
                                 unsigned char *out);
void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]);

HMAC-SHA-512-256

HMAC-SHA-512-256 is implemented as HMAC-SHA-512 with the output truncated to 256 bits. This is slightly faster than HMAC-SHA-256. Note that this construction is not the same as HMAC-SHA-512/256, which is HMAC using the SHA-512/256 function.

int crypto_auth_hmacsha512256(unsigned char *out,
                              const unsigned char *in,
                              unsigned long long inlen,
                              const unsigned char *k);
int crypto_auth_hmacsha512256_verify(const unsigned char *h,
                                     const unsigned char *in,
                                     unsigned long long inlen,
                                     const unsigned char *k);
int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
                                   const unsigned char *key,
                                   size_t keylen);
int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
                                     const unsigned char *in,
                                     unsigned long long inlen);
int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
                                    unsigned char *out);
void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]);

Constants

  • crypto_auth_hmacsha256_BYTES

  • crypto_auth_hmacsha256_KEYBYTES

  • crypto_auth_hmacsha512_BYTES

  • crypto_auth_hmacsha512_KEYBYTES

  • crypto_auth_hmacsha512256_BYTES

  • crypto_auth_hmacsha512256_KEYBYTES

Data types

  • crypto_auth_hmacsha256_state

  • crypto_auth_hmacsha512_state

  • crypto_auth_hmacsha512256_state

Notes

  • The state must be initialized with crypto_auth_hmacsha*_init() before updating or finalizing it. After crypto_auth_hmacsha*_final() returns, the state should not be used any more, unless it is reinitialized using crypto_auth_hmacsha*_init().

  • Arbitrary key lengths are supported using the multi-part interface. However, keys larger than 32 bytes are generally useless, even with SHA-512. It has been proven that HMAC offers PRF security with any sufficiently large key length.

  • crypto_auth_hmacsha256_*() can be used to create AWS HMAC-SHA256 request signatures.

  • crypto_auth_hmacsha512_*() is only provided for compatibility with legacy protocols specifically requiring that construction. The 32-byte authenticator offered by other functions is more than enough to guarantee that collisions will never occur.

  • Only use these functions for interoperability with 3rd party services. For everything else, you should probably use crypto_auth()/crypto_auth_verify() or crypto_generichash_*() instead.

References

- M. Backendal, M. Bellare, Fl. Günther, M. Scarlata.

crypto_auth
When Messages are Keys: Is HMAC a dual-PRF?