X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=inc%2Fbearssl_hmac.h;h=511dbbe4382b7c85adffc7456b5573c3a68b70ad;hp=d65653ac7754cc577b42c0466f6bf479069078f9;hb=127fb4a31d24e58fa8e04a154c6e87a2cb28245b;hpb=3210f38e0491b39aec1ef419cb4114e9483089fb diff --git a/inc/bearssl_hmac.h b/inc/bearssl_hmac.h index d65653a..511dbbe 100644 --- a/inc/bearssl_hmac.h +++ b/inc/bearssl_hmac.h @@ -30,9 +30,13 @@ #include "bearssl_hash.h" -/* - * HMAC - * ---- +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_hmac.h + * + * # HMAC * * HMAC is initialized with a key and an underlying hash function; it * then fills a "key context". That context contains the processed @@ -44,94 +48,143 @@ * * IMPORTANT: HMAC shall be used only with functions that have the * following properties: - * hash output size does not exceed 64 bytes - * hash internal state size does not exceed 64 bytes - * internal block length is a power of 2 between 16 and 256 bytes + * + * - hash output size does not exceed 64 bytes; + * - hash internal state size does not exceed 64 bytes; + * - internal block length is a power of 2 between 16 and 256 bytes. */ -/* - * Key context. +/** + * \brief HMAC key context. + * + * The HMAC key context is initialised with a hash function implementation + * and a secret key. Contents are opaque (callers should not access them + * directly). The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. */ typedef struct { +#ifndef BR_DOXYGEN_IGNORE const br_hash_class *dig_vtable; unsigned char ksi[64], kso[64]; +#endif } br_hmac_key_context; -/* - * Initialize the key context with the provided key, using the hash function - * identified by digest_class. +/** + * \brief HMAC key context initialisation. + * + * Initialise the key context with the provided key, using the hash function + * identified by `digest_vtable`. This supports arbitrary key lengths. + * + * \param kc HMAC key context to initialise. + * \param digest_vtable pointer to the hash function implementation vtable. + * \param key pointer to the HMAC secret key. + * \param key_len HMAC secret key length (in bytes). */ void br_hmac_key_init(br_hmac_key_context *kc, - const br_hash_class *digest_class, const void *key, size_t key_len); - -/* - * A helper structure that is big enough to accommodate all context - * structures for all hash functions for which HMAC is supported. - */ -typedef union { - const br_hash_class *vtable; - br_md5_context md5; - br_sha1_context sha1; - br_sha224_context sha224; - br_sha256_context sha256; - br_sha384_context sha384; - br_sha512_context sha512; -} br_hmac_allhash_context; + const br_hash_class *digest_vtable, const void *key, size_t key_len); -/* - * Context for an HMAC computation. +/** + * \brief HMAC computation context. + * + * The HMAC computation context maintains the state for a single HMAC + * computation. It is modified as input bytes are injected. The context + * is caller-allocated and has no release function since it does not + * dynamically allocate external resources. Its contents are opaque. */ typedef struct { - br_hmac_allhash_context dig; +#ifndef BR_DOXYGEN_IGNORE + br_hash_compat_context dig; unsigned char kso[64]; size_t out_len; +#endif } br_hmac_context; -/* - * Initialize a HMAC context with a key context. The key context is +/** + * \brief HMAC computation initialisation. + * + * Initialise a HMAC context with a key context. The key context is * unmodified. Relevant data from the key context is immediately copied; * the key context can thus be independently reused, modified or released * without impacting this HMAC computation. * * An explicit output length can be specified; the actual output length * will be the minimum of that value and the natural HMAC output length. - * If out_len is 0, then the natural HMAC output length is selected. + * If `out_len` is 0, then the natural HMAC output length is selected. The + * "natural output length" is the output length of the underlying hash + * function. + * + * \param ctx HMAC context to initialise. + * \param kc HMAC key context (already initialised with the key). + * \param out_len HMAC output length (0 to select "natural length"). */ void br_hmac_init(br_hmac_context *ctx, const br_hmac_key_context *kc, size_t out_len); -/* - * Get the MAC output size. The context must have been initialized. +/** + * \brief Get the HMAC output size. + * + * The HMAC output size is the number of bytes that will actually be + * produced with `br_hmac_out()` with the provided context. This function + * MUST NOT be called on a non-initialised HMAC computation context. + * The returned value is the minimum of the HMAC natural length (output + * size of the underlying hash function) and the `out_len` parameter which + * was used with the last `br_hmac_init()` call on that context (if the + * initialisation `out_len` parameter was 0, then this function will + * return the HMAC natural length). + * + * \param ctx the (already initialised) HMAC computation context. + * \return the HMAC actual output size. */ -#define br_hmac_size(ctx) ((ctx)->out_len) +static inline size_t +br_hmac_size(br_hmac_context *ctx) +{ + return ctx->out_len; +} -/* - * Process some more bytes. +/** + * \brief Inject some bytes in HMAC. + * + * The provided `len` bytes are injected as extra input in the HMAC + * computation incarnated by the `ctx` HMAC context. It is acceptable + * that `len` is zero, in which case `data` is ignored (and may be + * `NULL`) and this function does nothing. */ void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len); -/* - * Compute the HMAC output. The destination buffer MUST be large enough - * to accomodate the result. The context is NOT modified; further bytes - * may be processed. Thus, "partial HMAC" values can be efficiently - * obtained. +/** + * \brief Compute the HMAC output. + * + * The destination buffer MUST be large enough to accomodate the result; + * its length is at most the "natural length" of HMAC (i.e. the output + * length of the underlying hash function). The context is NOT modified; + * further bytes may be processed. Thus, "partial HMAC" values can be + * efficiently obtained. * * Returned value is the output length (in bytes). + * + * \param ctx HMAC computation context. + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). */ size_t br_hmac_out(const br_hmac_context *ctx, void *out); -/* - * Compute the HMAC output in constant time. Some extra input bytes are - * processed, then the output is computed. The extra input consists in - * the 'len' bytes pointed to by 'data'. The 'len' parameter must lie - * between 'min_len' and 'max_len' (inclusive); max_len bytes are - * actually read from 'data'. Computing time (and memory access pattern) - * will not depend upon the data bytes or the value of 'len'. - * - * The output is written in the 'out' buffer, that MUST be large enough +/** + * \brief Constant-time HMAC computation. + * + * This function compute the HMAC output in constant time. Some extra + * input bytes are processed, then the output is computed. The extra + * input consists in the `len` bytes pointed to by `data`. The `len` + * parameter must lie between `min_len` and `max_len` (inclusive); + * `max_len` bytes are actually read from `data`. Computing time (and + * memory access pattern) will not depend upon the data byte contents or + * the value of `len`. + * + * The output is written in the `out` buffer, that MUST be large enough * to receive it. * - * The difference max_len-min_len MUST be less than 2^30. + * The difference `max_len - min_len` MUST be less than 230 + * (i.e. about one gigabyte). * * This function computes the output properly only if the underlying * hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256, @@ -139,10 +192,20 @@ size_t br_hmac_out(const br_hmac_context *ctx, void *out); * * The provided context is NOT modified. * - * Returned value is the MAC length (in bytes). + * \param ctx the (already initialised) HMAC computation context. + * \param data the extra input bytes. + * \param len the extra input length (in bytes). + * \param min_len minimum extra input length (in bytes). + * \param max_len maximum extra input length (in bytes). + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). */ size_t br_hmac_outCT(const br_hmac_context *ctx, const void *data, size_t len, size_t min_len, size_t max_len, void *out); +#ifdef __cplusplus +} +#endif + #endif