# HMAC-SHA-2

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

The [`crypto_auth`](https://libsodium.gitbook.io/doc/secret-key_cryptography/secret-key_authentication) 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

```c
#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

```c
#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

```c
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).

```c
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()`:

```c
int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
                                const unsigned char *key,
                                size_t keylen);
```

```c
int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
```

```c
int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
                                 unsigned char *out);
```

This alternative API supports a key of arbitrary length `keylen`.

If `keylen` is `0`, `key` can be `NULL`.

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

```c
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:

```c
int crypto_auth_hmacsha512(unsigned char *out,
                           const unsigned char *in,
                           unsigned long long inlen,
                           const unsigned char *k);
```

```c
int crypto_auth_hmacsha512_verify(const unsigned char *h,
                                  const unsigned char *in,
                                  unsigned long long inlen,
                                  const unsigned char *k);
```

```c
int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
                                const unsigned char *key,
                                size_t keylen);
```

If `keylen` is `0`, `key` can be `NULL`.

```c
int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
```

```c
int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
                                 unsigned char *out);
```

```c
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.

```c
int crypto_auth_hmacsha512256(unsigned char *out,
                              const unsigned char *in,
                              unsigned long long inlen,
                              const unsigned char *k);
```

```c
int crypto_auth_hmacsha512256_verify(const unsigned char *h,
                                     const unsigned char *in,
                                     unsigned long long inlen,
                                     const unsigned char *k);
```

```c
int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
                                   const unsigned char *key,
                                   size_t keylen);
```

```c
int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
                                     const unsigned char *in,
                                     unsigned long long inlen);
```

```c
int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
                                    unsigned char *out);
```

```c
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

* [When Messages are Keys: Is HMAC a dual-PRF?](https://eprint.iacr.org/2023/861.pdf) - M. Backendal, M. Bellare, Fl. Günther, M. Scarlata.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://libsodium.gitbook.io/doc/advanced/hmac-sha2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
