/* * Copyright (c) 2016 Thomas Pornin * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef BR_BEARSSL_BLOCK_H__ #define BR_BEARSSL_BLOCK_H__ #include #include #ifdef __cplusplus extern "C" { #endif /** \file bearssl_block.h * * # Block Ciphers and Symmetric Ciphers * * This file documents the API for block ciphers and other symmetric * ciphers. * * * ## Procedural API * * For a block cipher implementation, up to three separate sets of * functions are provided, for CBC encryption, CBC decryption, and CTR * encryption/decryption. Each set has its own context structure, * initialised with the encryption key. * * For CBC encryption and decryption, the data to encrypt or decrypt is * referenced as a sequence of blocks. The implementations assume that * there is no partial block; no padding is applied or removed. The * caller is responsible for handling any kind of padding. * * Function for CTR encryption are defined only for block ciphers with * blocks of 16 bytes or more (i.e. AES, but not DES/3DES). * * Each implemented block cipher is identified by an "internal name" * from which are derived the names of structures and functions that * implement the cipher. For the block cipher of internal name "`xxx`", * the following are defined: * * - `br_xxx_BLOCK_SIZE` * * A macro that evaluates to the block size (in bytes) of the * cipher. For all implemented block ciphers, this value is a * power of two. * * - `br_xxx_cbcenc_keys` * * Context structure that contains the subkeys resulting from the key * expansion. These subkeys are appropriate for CBC encryption. The * structure first field is called `vtable` and points to the * appropriate OOP structure. * * - `br_xxx_cbcenc_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` * * Perform key expansion: subkeys for CBC encryption are computed and * written in the provided context structure. The key length MUST be * adequate for the implemented block cipher. This function also sets * the `vtable` field. * * - `br_xxx_cbcenc_run(const br_xxx_cbcenc_keys *ctx, void *iv, void *data, size_t len)` * * Perform CBC encryption of `len` bytes, in place. The encrypted data * replaces the cleartext. `len` MUST be a multiple of the block length * (if it is not, the function may loop forever or overflow a buffer). * The IV is provided with the `iv` pointer; it is also updated with * a copy of the last encrypted block. * * - `br_xxx_cbcdec_keys` * * Context structure that contains the subkeys resulting from the key * expansion. These subkeys are appropriate for CBC decryption. The * structure first field is called `vtable` and points to the * appropriate OOP structure. * * - `br_xxx_cbcdec_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` * * Perform key expansion: subkeys for CBC decryption are computed and * written in the provided context structure. The key length MUST be * adequate for the implemented block cipher. This function also sets * the `vtable` field. * * - `br_xxx_cbcdec_run(const br_xxx_cbcdec_keys *ctx, void *iv, void *data, size_t num_blocks)` * * Perform CBC decryption of `len` bytes, in place. The decrypted data * replaces the ciphertext. `len` MUST be a multiple of the block length * (if it is not, the function may loop forever or overflow a buffer). * The IV is provided with the `iv` pointer; it is also updated with * a copy of the last _encrypted_ block. * * - `br_xxx_ctr_keys` * * Context structure that contains the subkeys resulting from the key * expansion. These subkeys are appropriate for CTR encryption and * decryption. The structure first field is called `vtable` and * points to the appropriate OOP structure. * * - `br_xxx_ctr_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` * * Perform key expansion: subkeys for CTR encryption and decryption * are computed and written in the provided context structure. The * key length MUST be adequate for the implemented block cipher. This * function also sets the `vtable` field. * * - `br_xxx_ctr_run(const br_xxx_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len)` (returns `uint32_t`) * * Perform CTR encryption/decryption of some data. Processing is done * "in place" (the output data replaces the input data). This function * implements the "standard incrementing function" from NIST SP800-38A, * annex B: the IV length shall be 4 bytes less than the block size * (i.e. 12 bytes for AES) and the counter is the 32-bit value starting * with `cc`. The data length (`len`) is not necessarily a multiple of * the block size. The new counter value is returned, which supports * chunked processing, provided that each chunk length (except possibly * the last one) is a multiple of the block size. * * - `br_xxx_ctrcbc_keys` * * Context structure that contains the subkeys resulting from the * key expansion. These subkeys are appropriate for doing combined * CTR encryption/decryption and CBC-MAC, as used in the CCM and EAX * authenticated encryption modes. The structure first field is * called `vtable` and points to the appropriate OOP structure. * * - `br_xxx_ctrcbc_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` * * Perform key expansion: subkeys for combined CTR * encryption/decryption and CBC-MAC are computed and written in the * provided context structure. The key length MUST be adequate for * the implemented block cipher. This function also sets the * `vtable` field. * * - `br_xxx_ctrcbc_encrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` * * Perform CTR encryption of some data, and CBC-MAC. Processing is * done "in place" (the output data replaces the input data). This * function applies CTR encryption on the data, using a full * block-size counter (i.e. for 128-bit blocks, the counter is * incremented as a 128-bit value). The 'ctr' array contains the * initial value for the counter (used in the first block) and it is * updated with the new value after data processing. The 'cbcmac' * value shall point to a block-sized value which is used as IV for * CBC-MAC, computed over the encrypted data (output of CTR * encryption); the resulting CBC-MAC is written over 'cbcmac' on * output. * * The data length MUST be a multiple of the block size. * * - `br_xxx_ctrcbc_decrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` * * Perform CTR decryption of some data, and CBC-MAC. Processing is * done "in place" (the output data replaces the input data). This * function applies CTR decryption on the data, using a full * block-size counter (i.e. for 128-bit blocks, the counter is * incremented as a 128-bit value). The 'ctr' array contains the * initial value for the counter (used in the first block) and it is * updated with the new value after data processing. The 'cbcmac' * value shall point to a block-sized value which is used as IV for * CBC-MAC, computed over the encrypted data (input of CTR * encryption); the resulting CBC-MAC is written over 'cbcmac' on * output. * * The data length MUST be a multiple of the block size. * * - `br_xxx_ctrcbc_ctr(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *data, size_t len)` * * Perform CTR encryption or decryption of the provided data. The * data is processed "in place" (the output data replaces the input * data). A full block-sized counter is applied (i.e. for 128-bit * blocks, the counter is incremented as a 128-bit value). The 'ctr' * array contains the initial value for the counter (used in the * first block), and it is updated with the new value after data * processing. * * The data length MUST be a multiple of the block size. * * - `br_xxx_ctrcbc_mac(const br_xxx_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len)` * * Compute CBC-MAC over the provided data. The IV for CBC-MAC is * provided as 'cbcmac'; the output is written over the same array. * The data itself is untouched. The data length MUST be a multiple * of the block size. * * * It shall be noted that the key expansion functions return `void`. If * the provided key length is not allowed, then there will be no error * reporting; implementations need not validate the key length, thus an * invalid key length may result in undefined behaviour (e.g. buffer * overflow). * * Subkey structures contain no interior pointer, and no external * resources are allocated upon key expansion. They can thus be * discarded without any explicit deallocation. * * * ## Object-Oriented API * * Each context structure begins with a field (called `vtable`) that * points to an instance of a structure that references the relevant * functions through pointers. Each such structure contains the * following: * * - `context_size` * * The size (in bytes) of the context structure for subkeys. * * - `block_size` * * The cipher block size (in bytes). * * - `log_block_size` * * The base-2 logarithm of cipher block size (e.g. 4 for blocks * of 16 bytes). * * - `init` * * Pointer to the key expansion function. * * - `run` * * Pointer to the encryption/decryption function. * * For combined CTR/CBC-MAC encryption, the `vtable` has a slightly * different structure: * * - `context_size` * * The size (in bytes) of the context structure for subkeys. * * - `block_size` * * The cipher block size (in bytes). * * - `log_block_size` * * The base-2 logarithm of cipher block size (e.g. 4 for blocks * of 16 bytes). * * - `init` * * Pointer to the key expansion function. * * - `encrypt` * * Pointer to the CTR encryption + CBC-MAC function. * * - `decrypt` * * Pointer to the CTR decryption + CBC-MAC function. * * - `ctr` * * Pointer to the CTR encryption/decryption function. * * - `mac` * * Pointer to the CBC-MAC function. * * For block cipher "`xxx`", static, constant instances of these * structures are defined, under the names: * * - `br_xxx_cbcenc_vtable` * - `br_xxx_cbcdec_vtable` * - `br_xxx_ctr_vtable` * - `br_xxx_ctrcbc_vtable` * * * ## Implemented Block Ciphers * * Provided implementations are: * * | Name | Function | Block Size (bytes) | Key lengths (bytes) | * | :-------- | :------- | :----------------: | :-----------------: | * | aes_big | AES | 16 | 16, 24 and 32 | * | aes_small | AES | 16 | 16, 24 and 32 | * | aes_ct | AES | 16 | 16, 24 and 32 | * | aes_ct64 | AES | 16 | 16, 24 and 32 | * | aes_x86ni | AES | 16 | 16, 24 and 32 | * | des_ct | DES/3DES | 8 | 8, 16 and 24 | * | des_tab | DES/3DES | 8 | 8, 16 and 24 | * * **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8, * 16 and 24 bytes), but some of the bits are ignored by the algorithm, so * the _effective_ key lengths, from a security point of view, are 56, * 112 and 168 bits, respectively. * * `aes_big` is a "classical" AES implementation, using tables. It * is fast but not constant-time, since it makes data-dependent array * accesses. * * `aes_small` is an AES implementation optimized for code size. It * is substantially slower than `aes_big`; it is not constant-time * either. * * `aes_ct` is a constant-time implementation of AES; its code is about * as big as that of `aes_big`, while its performance is comparable to * that of `aes_small`. However, it is constant-time. This * implementation should thus be considered to be the "default" AES in * BearSSL, to be used unless the operational context guarantees that a * non-constant-time implementation is safe, or an architecture-specific * constant-time implementation can be used (e.g. using dedicated * hardware opcodes). * * `aes_ct64` is another constant-time implementation of AES. It is * similar to `aes_ct` but uses 64-bit values. On 32-bit machines, * `aes_ct64` is not faster than `aes_ct`, often a bit slower, and has * a larger footprint; however, on 64-bit architectures, `aes_ct64` * is typically twice faster than `aes_ct` for modes that allow parallel * operations (i.e. CTR, and CBC decryption, but not CBC encryption). * * `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It * uses the AES-NI opcodes when available. * * `des_tab` is a classic, table-based implementation of DES/3DES. It * is not constant-time. * * `des_ct` is an constant-time implementation of DES/3DES. It is * substantially slower than `des_tab`. * * ## ChaCha20 and Poly1305 * * ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They * are described in [RFC 7539](https://tools.ietf.org/html/rfc7539). * * Two function pointer types are defined: * * - `br_chacha20_run` describes a function that implements ChaCha20 * only. * * - `br_poly1305_run` describes an implementation of Poly1305, * in the AEAD combination with ChaCha20 specified in RFC 7539 * (the ChaCha20 implementation is provided as a function pointer). * * `chacha20_ct` is a straightforward implementation of ChaCha20 in * plain C; it is constant-time, small, and reasonably fast. * * `chacha20_sse2` leverages SSE2 opcodes (on x86 architectures that * support these opcodes). It is faster than `chacha20_ct`. * * `poly1305_ctmul` is an implementation of the ChaCha20+Poly1305 AEAD * construction, where the Poly1305 part is performed with mixed 32-bit * multiplications (operands are 32-bit, result is 64-bit). * * `poly1305_ctmul32` implements ChaCha20+Poly1305 using pure 32-bit * multiplications (32-bit operands, 32-bit result). It is slower than * `poly1305_ctmul`, except on some specific architectures such as * the ARM Cortex M0+. * * `poly1305_ctmulq` implements ChaCha20+Poly1305 with mixed 64-bit * multiplications (operands are 64-bit, result is 128-bit) on 64-bit * platforms that support such operations. * * `poly1305_i15` implements ChaCha20+Poly1305 with the generic "i15" * big integer implementation. It is meant mostly for testing purposes, * although it can help with saving a few hundred bytes of code footprint * on systems where code size is scarce. */ /** * \brief Class type for CBC encryption implementations. * * A `br_block_cbcenc_class` instance points to the functions implementing * a specific block cipher, when used in CBC mode for encrypting data. */ typedef struct br_block_cbcenc_class_ br_block_cbcenc_class; struct br_block_cbcenc_class_ { /** * \brief Size (in bytes) of the context structure appropriate * for containing subkeys. */ size_t context_size; /** * \brief Size of individual blocks (in bytes). */ unsigned block_size; /** * \brief Base-2 logarithm of the size of individual blocks, * expressed in bytes. */ unsigned log_block_size; /** * \brief Initialisation function. * * This function sets the `vtable` field in the context structure. * The key length MUST be one of the key lengths supported by * the implementation. * * \param ctx context structure to initialise. * \param key secret key. * \param key_len key length (in bytes). */ void (*init)(const br_block_cbcenc_class **ctx, const void *key, size_t key_len); /** * \brief Run the CBC encryption. * * The `iv` parameter points to the IV for this run; it is * updated with a copy of the last encrypted block. The data * is encrypted "in place"; its length (`len`) MUST be a * multiple of the block size. * * \param ctx context structure (already initialised). * \param iv IV for CBC encryption (updated). * \param data data to encrypt. * \param len data length (in bytes, multiple of block size). */ void (*run)(const br_block_cbcenc_class *const *ctx, void *iv, void *data, size_t len); }; /** * \brief Class type for CBC decryption implementations. * * A `br_block_cbcdec_class` instance points to the functions implementing * a specific block cipher, when used in CBC mode for decrypting data. */ typedef struct br_block_cbcdec_class_ br_block_cbcdec_class; struct br_block_cbcdec_class_ { /** * \brief Size (in bytes) of the context structure appropriate * for containing subkeys. */ size_t context_size; /** * \brief Size of individual blocks (in bytes). */ unsigned block_size; /** * \brief Base-2 logarithm of the size of individual blocks, * expressed in bytes. */ unsigned log_block_size; /** * \brief Initialisation function. * * This function sets the `vtable` field in the context structure. * The key length MUST be one of the key lengths supported by * the implementation. * * \param ctx context structure to initialise. * \param key secret key. * \param key_len key length (in bytes). */ void (*init)(const br_block_cbcdec_class **ctx, const void *key, size_t key_len); /** * \brief Run the CBC decryption. * * The `iv` parameter points to the IV for this run; it is * updated with a copy of the last encrypted block. The data * is decrypted "in place"; its length (`len`) MUST be a * multiple of the block size. * * \param ctx context structure (already initialised). * \param iv IV for CBC decryption (updated). * \param data data to decrypt. * \param len data length (in bytes, multiple of block size). */ void (*run)(const br_block_cbcdec_class *const *ctx, void *iv, void *data, size_t len); }; /** * \brief Class type for CTR encryption/decryption implementations. * * A `br_block_ctr_class` instance points to the functions implementing * a specific block cipher, when used in CTR mode for encrypting or * decrypting data. */ typedef struct br_block_ctr_class_ br_block_ctr_class; struct br_block_ctr_class_ { /** * \brief Size (in bytes) of the context structure appropriate * for containing subkeys. */ size_t context_size; /** * \brief Size of individual blocks (in bytes). */ unsigned block_size; /** * \brief Base-2 logarithm of the size of individual blocks, * expressed in bytes. */ unsigned log_block_size; /** * \brief Initialisation function. * * This function sets the `vtable` field in the context structure. * The key length MUST be one of the key lengths supported by * the implementation. * * \param ctx context structure to initialise. * \param key secret key. * \param key_len key length (in bytes). */ void (*init)(const br_block_ctr_class **ctx, const void *key, size_t key_len); /** * \brief Run the CTR encryption or decryption. * * The `iv` parameter points to the IV for this run; its * length is exactly 4 bytes less than the block size (e.g. * 12 bytes for AES/CTR). The IV is combined with a 32-bit * block counter to produce the block value which is processed * with the block cipher. * * The data to encrypt or decrypt is updated "in place". Its * length (`len` bytes) is not required to be a multiple of * the block size; if the final block is partial, then the * corresponding key stream bits are dropped. * * The resulting counter value is returned. * * \param ctx context structure (already initialised). * \param iv IV for CTR encryption/decryption. * \param cc initial value for the block counter. * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \return the new block counter value. */ uint32_t (*run)(const br_block_ctr_class *const *ctx, const void *iv, uint32_t cc, void *data, size_t len); }; /** * \brief Class type for combined CTR and CBC-MAC implementations. * * A `br_block_ctrcbc_class` instance points to the functions implementing * a specific block cipher, when used in CTR mode for encrypting or * decrypting data, along with CBC-MAC. */ typedef struct br_block_ctrcbc_class_ br_block_ctrcbc_class; struct br_block_ctrcbc_class_ { /** * \brief Size (in bytes) of the context structure appropriate * for containing subkeys. */ size_t context_size; /** * \brief Size of individual blocks (in bytes). */ unsigned block_size; /** * \brief Base-2 logarithm of the size of individual blocks, * expressed in bytes. */ unsigned log_block_size; /** * \brief Initialisation function. * * This function sets the `vtable` field in the context structure. * The key length MUST be one of the key lengths supported by * the implementation. * * \param ctx context structure to initialise. * \param key secret key. * \param key_len key length (in bytes). */ void (*init)(const br_block_ctrcbc_class **ctx, const void *key, size_t key_len); /** * \brief Run the CTR encryption + CBC-MAC. * * The `ctr` parameter points to the counter; its length shall * be equal to the block size. It is updated by this function * as encryption proceeds. * * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC * is computed over the encrypted data (output of CTR * encryption). Its length shall be equal to the block size. The * computed CBC-MAC value is written over the `cbcmac` array. * * The data to encrypt is updated "in place". Its length (`len` * bytes) MUST be a multiple of the block size. * * \param ctx context structure (already initialised). * \param ctr counter for CTR encryption (initial and final). * \param cbcmac IV and output buffer for CBC-MAC. * \param data data to encrypt. * \param len data length (in bytes). */ void (*encrypt)(const br_block_ctrcbc_class *const *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief Run the CTR decryption + CBC-MAC. * * The `ctr` parameter points to the counter; its length shall * be equal to the block size. It is updated by this function * as decryption proceeds. * * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC * is computed over the encrypted data (i.e. before CTR * decryption). Its length shall be equal to the block size. The * computed CBC-MAC value is written over the `cbcmac` array. * * The data to decrypt is updated "in place". Its length (`len` * bytes) MUST be a multiple of the block size. * * \param ctx context structure (already initialised). * \param ctr counter for CTR encryption (initial and final). * \param cbcmac IV and output buffer for CBC-MAC. * \param data data to decrypt. * \param len data length (in bytes). */ void (*decrypt)(const br_block_ctrcbc_class *const *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief Run the CTR encryption/decryption only. * * The `ctr` parameter points to the counter; its length shall * be equal to the block size. It is updated by this function * as decryption proceeds. * * The data to decrypt is updated "in place". Its length (`len` * bytes) MUST be a multiple of the block size. * * \param ctx context structure (already initialised). * \param ctr counter for CTR encryption (initial and final). * \param data data to decrypt. * \param len data length (in bytes). */ void (*ctr)(const br_block_ctrcbc_class *const *ctx, void *ctr, void *data, size_t len); /** * \brief Run the CBC-MAC only. * * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC * is computed over the encrypted data (i.e. before CTR * decryption). Its length shall be equal to the block size. The * computed CBC-MAC value is written over the `cbcmac` array. * * The data is unmodified. Its length (`len` bytes) MUST be a * multiple of the block size. * * \param ctx context structure (already initialised). * \param cbcmac IV and output buffer for CBC-MAC. * \param data data to decrypt. * \param len data length (in bytes). */ void (*mac)(const br_block_ctrcbc_class *const *ctx, void *cbcmac, const void *data, size_t len); }; /* * Traditional, table-based AES implementation. It is fast, but uses * internal tables (in particular a 1 kB table for encryption, another * 1 kB table for decryption, and a 256-byte table for key schedule), * and it is not constant-time. In contexts where cache-timing attacks * apply, this implementation may leak the secret key. */ /** \brief AES block size (16 bytes). */ #define br_aes_big_BLOCK_SIZE 16 /** * \brief Context for AES subkeys (`aes_big` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_big_cbcenc_keys; /** * \brief Context for AES subkeys (`aes_big` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_big_cbcdec_keys; /** * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption * and decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctr_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_big_ctr_keys; /** * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption * and decryption + CBC-MAC). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctrcbc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_big_ctrcbc_keys; /** * \brief Class instance for AES CBC encryption (`aes_big` implementation). */ extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable; /** * \brief Class instance for AES CBC decryption (`aes_big` implementation). */ extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable; /** * \brief Class instance for AES CTR encryption and decryption * (`aes_big` implementation). */ extern const br_block_ctr_class br_aes_big_ctr_vtable; /** * \brief Class instance for AES CTR encryption/decryption + CBC-MAC * (`aes_big` implementation). */ extern const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable; /** * \brief Context initialisation (key schedule) for AES CBC encryption * (`aes_big` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CBC decryption * (`aes_big` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR encryption * and decryption (`aes_big` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC * (`aes_big` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv, void *data, size_t len); /** * \brief CTR encryption and decryption with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param iv IV (constant, 12 bytes). * \param cc initial block counter value. * \param data data to encrypt or decrypt (updated). * \param len data length (in bytes). * \return new block counter value. */ uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief CTR encryption + CBC-MAC with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR decryption + CBC-MAC with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR encryption/decryption with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param data data to MAC (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, void *ctr, void *data, size_t len); /** * \brief CBC-MAC with AES (`aes_big` implementation). * * \param ctx context (already initialised). * \param cbcmac IV for CBC-MAC (updated). * \param data data to MAC (unmodified). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len); /* * AES implementation optimized for size. It is slower than the * traditional table-based AES implementation, but requires much less * code. It still uses data-dependent table accesses (albeit within a * much smaller 256-byte table), which makes it conceptually vulnerable * to cache-timing attacks. */ /** \brief AES block size (16 bytes). */ #define br_aes_small_BLOCK_SIZE 16 /** * \brief Context for AES subkeys (`aes_small` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_small_cbcenc_keys; /** * \brief Context for AES subkeys (`aes_small` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_small_cbcdec_keys; /** * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption * and decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctr_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_small_ctr_keys; /** * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption * and decryption + CBC-MAC). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctrcbc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_small_ctrcbc_keys; /** * \brief Class instance for AES CBC encryption (`aes_small` implementation). */ extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable; /** * \brief Class instance for AES CBC decryption (`aes_small` implementation). */ extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable; /** * \brief Class instance for AES CTR encryption and decryption * (`aes_small` implementation). */ extern const br_block_ctr_class br_aes_small_ctr_vtable; /** * \brief Class instance for AES CTR encryption/decryption + CBC-MAC * (`aes_small` implementation). */ extern const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable; /** * \brief Context initialisation (key schedule) for AES CBC encryption * (`aes_small` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CBC decryption * (`aes_small` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR encryption * and decryption (`aes_small` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC * (`aes_small` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv, void *data, size_t len); /** * \brief CTR encryption and decryption with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param iv IV (constant, 12 bytes). * \param cc initial block counter value. * \param data data to decrypt (updated). * \param len data length (in bytes). * \return new block counter value. */ uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief CTR encryption + CBC-MAC with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR decryption + CBC-MAC with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR encryption/decryption with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param data data to MAC (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, void *ctr, void *data, size_t len); /** * \brief CBC-MAC with AES (`aes_small` implementation). * * \param ctx context (already initialised). * \param cbcmac IV for CBC-MAC (updated). * \param data data to MAC (unmodified). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len); /* * Constant-time AES implementation. Its size is similar to that of * 'aes_big', and its performance is similar to that of 'aes_small' (faster * decryption, slower encryption). However, it is constant-time, i.e. * immune to cache-timing and similar attacks. */ /** \brief AES block size (16 bytes). */ #define br_aes_ct_BLOCK_SIZE 16 /** * \brief Context for AES subkeys (`aes_ct` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_ct_cbcenc_keys; /** * \brief Context for AES subkeys (`aes_ct` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_ct_cbcdec_keys; /** * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption * and decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctr_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_ct_ctr_keys; /** * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption * and decryption + CBC-MAC). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctrcbc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[60]; unsigned num_rounds; #endif } br_aes_ct_ctrcbc_keys; /** * \brief Class instance for AES CBC encryption (`aes_ct` implementation). */ extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable; /** * \brief Class instance for AES CBC decryption (`aes_ct` implementation). */ extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable; /** * \brief Class instance for AES CTR encryption and decryption * (`aes_ct` implementation). */ extern const br_block_ctr_class br_aes_ct_ctr_vtable; /** * \brief Class instance for AES CTR encryption/decryption + CBC-MAC * (`aes_ct` implementation). */ extern const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable; /** * \brief Context initialisation (key schedule) for AES CBC encryption * (`aes_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CBC decryption * (`aes_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR encryption * and decryption (`aes_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC * (`aes_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv, void *data, size_t len); /** * \brief CTR encryption and decryption with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param iv IV (constant, 12 bytes). * \param cc initial block counter value. * \param data data to decrypt (updated). * \param len data length (in bytes). * \return new block counter value. */ uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief CTR encryption + CBC-MAC with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR decryption + CBC-MAC with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR encryption/decryption with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param data data to MAC (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, void *ctr, void *data, size_t len); /** * \brief CBC-MAC with AES (`aes_ct` implementation). * * \param ctx context (already initialised). * \param cbcmac IV for CBC-MAC (updated). * \param data data to MAC (unmodified). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len); /* * 64-bit constant-time AES implementation. It is similar to 'aes_ct' * but uses 64-bit registers, making it about twice faster than 'aes_ct' * on 64-bit platforms, while remaining constant-time and with a similar * code size. (The doubling in performance is only for CBC decryption * and CTR mode; CBC encryption is non-parallel and cannot benefit from * the larger registers.) */ /** \brief AES block size (16 bytes). */ #define br_aes_ct64_BLOCK_SIZE 16 /** * \brief Context for AES subkeys (`aes_ct64` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint64_t skey[30]; unsigned num_rounds; #endif } br_aes_ct64_cbcenc_keys; /** * \brief Context for AES subkeys (`aes_ct64` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint64_t skey[30]; unsigned num_rounds; #endif } br_aes_ct64_cbcdec_keys; /** * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption * and decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctr_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint64_t skey[30]; unsigned num_rounds; #endif } br_aes_ct64_ctr_keys; /** * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption * and decryption + CBC-MAC). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctrcbc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint64_t skey[30]; unsigned num_rounds; #endif } br_aes_ct64_ctrcbc_keys; /** * \brief Class instance for AES CBC encryption (`aes_ct64` implementation). */ extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable; /** * \brief Class instance for AES CBC decryption (`aes_ct64` implementation). */ extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable; /** * \brief Class instance for AES CTR encryption and decryption * (`aes_ct64` implementation). */ extern const br_block_ctr_class br_aes_ct64_ctr_vtable; /** * \brief Class instance for AES CTR encryption/decryption + CBC-MAC * (`aes_ct64` implementation). */ extern const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable; /** * \brief Context initialisation (key schedule) for AES CBC encryption * (`aes_ct64` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CBC decryption * (`aes_ct64` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR encryption * and decryption (`aes_ct64` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC * (`aes_ct64` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv, void *data, size_t len); /** * \brief CTR encryption and decryption with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param iv IV (constant, 12 bytes). * \param cc initial block counter value. * \param data data to decrypt (updated). * \param len data length (in bytes). * \return new block counter value. */ uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief CTR encryption + CBC-MAC with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR decryption + CBC-MAC with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR encryption/decryption with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param data data to MAC (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, void *ctr, void *data, size_t len); /** * \brief CBC-MAC with AES (`aes_ct64` implementation). * * \param ctx context (already initialised). * \param cbcmac IV for CBC-MAC (updated). * \param data data to MAC (unmodified). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len); /* * AES implementation using AES-NI opcodes (x86 platform). */ /** \brief AES block size (16 bytes). */ #define br_aes_x86ni_BLOCK_SIZE 16 /** * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE union { unsigned char skni[16 * 15]; } skey; unsigned num_rounds; #endif } br_aes_x86ni_cbcenc_keys; /** * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE union { unsigned char skni[16 * 15]; } skey; unsigned num_rounds; #endif } br_aes_x86ni_cbcdec_keys; /** * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption * and decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctr_class *vtable; #ifndef BR_DOXYGEN_IGNORE union { unsigned char skni[16 * 15]; } skey; unsigned num_rounds; #endif } br_aes_x86ni_ctr_keys; /** * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption * and decryption + CBC-MAC). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_ctrcbc_class *vtable; #ifndef BR_DOXYGEN_IGNORE union { unsigned char skni[16 * 15]; } skey; unsigned num_rounds; #endif } br_aes_x86ni_ctrcbc_keys; /** * \brief Class instance for AES CBC encryption (`aes_x86ni` implementation). * * Since this implementation might be omitted from the library, or the * AES opcode unavailable on the current CPU, a pointer to this class * instance should be obtained through `br_aes_x86ni_cbcenc_get_vtable()`. */ extern const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable; /** * \brief Class instance for AES CBC decryption (`aes_x86ni` implementation). * * Since this implementation might be omitted from the library, or the * AES opcode unavailable on the current CPU, a pointer to this class * instance should be obtained through `br_aes_x86ni_cbcdec_get_vtable()`. */ extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable; /** * \brief Class instance for AES CTR encryption and decryption * (`aes_x86ni` implementation). * * Since this implementation might be omitted from the library, or the * AES opcode unavailable on the current CPU, a pointer to this class * instance should be obtained through `br_aes_x86ni_ctr_get_vtable()`. */ extern const br_block_ctr_class br_aes_x86ni_ctr_vtable; /** * \brief Class instance for AES CTR encryption/decryption + CBC-MAC * (`aes_x86ni` implementation). * * Since this implementation might be omitted from the library, or the * AES opcode unavailable on the current CPU, a pointer to this class * instance should be obtained through `br_aes_x86ni_ctrcbc_get_vtable()`. */ extern const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable; /** * \brief Context initialisation (key schedule) for AES CBC encryption * (`aes_x86ni` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CBC decryption * (`aes_x86ni` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR encryption * and decryption (`aes_x86ni` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC * (`aes_x86ni` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 16). */ void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv, void *data, size_t len); /** * \brief CTR encryption and decryption with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param iv IV (constant, 12 bytes). * \param cc initial block counter value. * \param data data to decrypt (updated). * \param len data length (in bytes). * \return new block counter value. */ uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief CTR encryption + CBC-MAC with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR decryption + CBC-MAC with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param cbcmac IV for CBC-MAC (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len); /** * \brief CTR encryption/decryption with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param ctr counter for CTR (16 bytes, updated). * \param data data to MAC (updated). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx, void *ctr, void *data, size_t len); /** * \brief CBC-MAC with AES (`aes_x86ni` implementation). * * \param ctx context (already initialised). * \param cbcmac IV for CBC-MAC (updated). * \param data data to MAC (unmodified). * \param len data length (in bytes, MUST be a multiple of 16). */ void br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len); /** * \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if * available. * * This function returns a pointer to `br_aes_x86ni_cbcenc_vtable`, if * that implementation was compiled in the library _and_ the x86 AES * opcodes are available on the currently running CPU. If either of * these conditions is not met, then this function returns `NULL`. * * \return the `aes_x86ni` AES-CBC (encryption) implementation, or `NULL`. */ const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void); /** * \brief Obtain the `aes_x86ni` AES-CBC (decryption) implementation, if * available. * * This function returns a pointer to `br_aes_x86ni_cbcdec_vtable`, if * that implementation was compiled in the library _and_ the x86 AES * opcodes are available on the currently running CPU. If either of * these conditions is not met, then this function returns `NULL`. * * \return the `aes_x86ni` AES-CBC (decryption) implementation, or `NULL`. */ const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void); /** * \brief Obtain the `aes_x86ni` AES-CTR implementation, if available. * * This function returns a pointer to `br_aes_x86ni_ctr_vtable`, if * that implementation was compiled in the library _and_ the x86 AES * opcodes are available on the currently running CPU. If either of * these conditions is not met, then this function returns `NULL`. * * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. */ const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void); /** * \brief Obtain the `aes_x86ni` AES-CTR + CBC-MAC implementation, if * available. * * This function returns a pointer to `br_aes_x86ni_ctrcbc_vtable`, if * that implementation was compiled in the library _and_ the x86 AES * opcodes are available on the currently running CPU. If either of * these conditions is not met, then this function returns `NULL`. * * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. */ const br_block_ctrcbc_class *br_aes_x86ni_ctrcbc_get_vtable(void); /** * \brief Aggregate structure large enough to be used as context for * subkeys (CBC encryption) for all AES implementations. */ typedef union { const br_block_cbcenc_class *vtable; br_aes_big_cbcenc_keys c_big; br_aes_small_cbcenc_keys c_small; br_aes_ct_cbcenc_keys c_ct; br_aes_ct64_cbcenc_keys c_ct64; br_aes_x86ni_cbcenc_keys c_x86ni; } br_aes_gen_cbcenc_keys; /** * \brief Aggregate structure large enough to be used as context for * subkeys (CBC decryption) for all AES implementations. */ typedef union { const br_block_cbcdec_class *vtable; br_aes_big_cbcdec_keys c_big; br_aes_small_cbcdec_keys c_small; br_aes_ct_cbcdec_keys c_ct; br_aes_ct64_cbcdec_keys c_ct64; br_aes_x86ni_cbcdec_keys c_x86ni; } br_aes_gen_cbcdec_keys; /** * \brief Aggregate structure large enough to be used as context for * subkeys (CTR encryption and decryption) for all AES implementations. */ typedef union { const br_block_ctr_class *vtable; br_aes_big_ctr_keys c_big; br_aes_small_ctr_keys c_small; br_aes_ct_ctr_keys c_ct; br_aes_ct64_ctr_keys c_ct64; br_aes_x86ni_ctr_keys c_x86ni; } br_aes_gen_ctr_keys; /** * \brief Aggregate structure large enough to be used as context for * subkeys (CTR encryption/decryption + CBC-MAC) for all AES implementations. */ typedef union { const br_block_ctrcbc_class *vtable; br_aes_big_ctrcbc_keys c_big; br_aes_small_ctrcbc_keys c_small; br_aes_ct_ctrcbc_keys c_ct; br_aes_ct64_ctrcbc_keys c_ct64; br_aes_x86ni_ctrcbc_keys c_x86ni; } br_aes_gen_ctrcbc_keys; /* * Traditional, table-based implementation for DES/3DES. Since tables are * used, cache-timing attacks are conceptually possible. */ /** \brief DES/3DES block size (8 bytes). */ #define br_des_tab_BLOCK_SIZE 8 /** * \brief Context for DES subkeys (`des_tab` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[96]; unsigned num_rounds; #endif } br_des_tab_cbcenc_keys; /** * \brief Context for DES subkeys (`des_tab` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[96]; unsigned num_rounds; #endif } br_des_tab_cbcdec_keys; /** * \brief Class instance for DES CBC encryption (`des_tab` implementation). */ extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable; /** * \brief Class instance for DES CBC decryption (`des_tab` implementation). */ extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable; /** * \brief Context initialisation (key schedule) for DES CBC encryption * (`des_tab` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for DES CBC decryption * (`des_tab` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with DES (`des_tab` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 8). */ void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with DES (`des_tab` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 8). */ void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv, void *data, size_t len); /* * Constant-time implementation for DES/3DES. It is substantially slower * (by a factor of about 4x), but also immune to cache-timing attacks. */ /** \brief DES/3DES block size (8 bytes). */ #define br_des_ct_BLOCK_SIZE 8 /** * \brief Context for DES subkeys (`des_ct` implementation, CBC encryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcenc_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[96]; unsigned num_rounds; #endif } br_des_ct_cbcenc_keys; /** * \brief Context for DES subkeys (`des_ct` implementation, CBC decryption). * * First field is a pointer to the vtable; it is set by the initialisation * function. Other fields are not supposed to be accessed by user code. */ typedef struct { /** \brief Pointer to vtable for this context. */ const br_block_cbcdec_class *vtable; #ifndef BR_DOXYGEN_IGNORE uint32_t skey[96]; unsigned num_rounds; #endif } br_des_ct_cbcdec_keys; /** * \brief Class instance for DES CBC encryption (`des_ct` implementation). */ extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable; /** * \brief Class instance for DES CBC decryption (`des_ct` implementation). */ extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable; /** * \brief Context initialisation (key schedule) for DES CBC encryption * (`des_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, const void *key, size_t len); /** * \brief Context initialisation (key schedule) for DES CBC decryption * (`des_ct` implementation). * * \param ctx context to initialise. * \param key secret key. * \param len secret key length (in bytes). */ void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, const void *key, size_t len); /** * \brief CBC encryption with DES (`des_ct` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to encrypt (updated). * \param len data length (in bytes, MUST be multiple of 8). */ void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv, void *data, size_t len); /** * \brief CBC decryption with DES (`des_ct` implementation). * * \param ctx context (already initialised). * \param iv IV (updated). * \param data data to decrypt (updated). * \param len data length (in bytes, MUST be multiple of 8). */ void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv, void *data, size_t len); /* * These structures are large enough to accommodate subkeys for all * DES/3DES implementations. */ /** * \brief Aggregate structure large enough to be used as context for * subkeys (CBC encryption) for all DES implementations. */ typedef union { const br_block_cbcenc_class *vtable; br_des_tab_cbcenc_keys tab; br_des_ct_cbcenc_keys ct; } br_des_gen_cbcenc_keys; /** * \brief Aggregate structure large enough to be used as context for * subkeys (CBC decryption) for all DES implementations. */ typedef union { const br_block_cbcdec_class *vtable; br_des_tab_cbcdec_keys c_tab; br_des_ct_cbcdec_keys c_ct; } br_des_gen_cbcdec_keys; /** * \brief Type for a ChaCha20 implementation. * * An implementation follows the description in RFC 7539: * * - Key is 256 bits (`key` points to exactly 32 bytes). * * - IV is 96 bits (`iv` points to exactly 12 bytes). * * - Block counter is over 32 bits and starts at value `cc`; the * resulting value is returned. * * Data (pointed to by `data`, of length `len`) is encrypted/decrypted * in place. If `len` is not a multiple of 64, then the excess bytes from * the last block processing are dropped (therefore, "chunked" processing * works only as long as each non-final chunk has a length multiple of 64). * * \param key secret key (32 bytes). * \param iv IV (12 bytes). * \param cc initial counter value. * \param data data to encrypt or decrypt. * \param len data length (in bytes). */ typedef uint32_t (*br_chacha20_run)(const void *key, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief ChaCha20 implementation (straightforward C code, constant-time). * * \see br_chacha20_run * * \param key secret key (32 bytes). * \param iv IV (12 bytes). * \param cc initial counter value. * \param data data to encrypt or decrypt. * \param len data length (in bytes). */ uint32_t br_chacha20_ct_run(const void *key, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief ChaCha20 implementation (SSE2 code, constant-time). * * This implementation is available only on x86 platforms, depending on * compiler support. Moreover, in 32-bit mode, it might not actually run, * if the underlying hardware does not implement the SSE2 opcode (in * 64-bit mode, SSE2 is part of the ABI, so if the code could be compiled * at all, then it can run). Use `br_chacha20_sse2_get()` to safely obtain * a pointer to that function. * * \see br_chacha20_run * * \param key secret key (32 bytes). * \param iv IV (12 bytes). * \param cc initial counter value. * \param data data to encrypt or decrypt. * \param len data length (in bytes). */ uint32_t br_chacha20_sse2_run(const void *key, const void *iv, uint32_t cc, void *data, size_t len); /** * \brief Obtain the `sse2` ChaCha20 implementation, if available. * * This function returns a pointer to `br_chacha20_sse2_run`, if * that implementation was compiled in the library _and_ the SSE2 * opcodes are available on the currently running CPU. If either of * these conditions is not met, then this function returns `0`. * * \return the `sse2` ChaCha20 implementation, or `0`. */ br_chacha20_run br_chacha20_sse2_get(void); /** * \brief Type for a ChaCha20+Poly1305 AEAD implementation. * * The provided data is encrypted or decrypted with ChaCha20. The * authentication tag is computed on the concatenation of the * additional data and the ciphertext, with the padding and lengths * as described in RFC 7539 (section 2.8). * * After decryption, the caller is responsible for checking that the * computed tag matches the expected value. * * \param key secret key (32 bytes). * \param iv nonce (12 bytes). * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \param aad additional authenticated data. * \param aad_len length of additional authenticated data (in bytes). * \param tag output buffer for the authentication tag. * \param ichacha implementation of ChaCha20. * \param encrypt non-zero for encryption, zero for decryption. */ typedef void (*br_poly1305_run)(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); /** * \brief ChaCha20+Poly1305 AEAD implementation (mixed 32-bit multiplications). * * \see br_poly1305_run * * \param key secret key (32 bytes). * \param iv nonce (12 bytes). * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \param aad additional authenticated data. * \param aad_len length of additional authenticated data (in bytes). * \param tag output buffer for the authentication tag. * \param ichacha implementation of ChaCha20. * \param encrypt non-zero for encryption, zero for decryption. */ void br_poly1305_ctmul_run(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); /** * \brief ChaCha20+Poly1305 AEAD implementation (pure 32-bit multiplications). * * \see br_poly1305_run * * \param key secret key (32 bytes). * \param iv nonce (12 bytes). * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \param aad additional authenticated data. * \param aad_len length of additional authenticated data (in bytes). * \param tag output buffer for the authentication tag. * \param ichacha implementation of ChaCha20. * \param encrypt non-zero for encryption, zero for decryption. */ void br_poly1305_ctmul32_run(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); /** * \brief ChaCha20+Poly1305 AEAD implementation (i15). * * This implementation relies on the generic big integer code "i15" * (which uses pure 32-bit multiplications). As such, it may save a * little code footprint in a context where "i15" is already included * (e.g. for elliptic curves or for RSA); however, it is also * substantially slower than the ctmul and ctmul32 implementations. * * \see br_poly1305_run * * \param key secret key (32 bytes). * \param iv nonce (12 bytes). * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \param aad additional authenticated data. * \param aad_len length of additional authenticated data (in bytes). * \param tag output buffer for the authentication tag. * \param ichacha implementation of ChaCha20. * \param encrypt non-zero for encryption, zero for decryption. */ void br_poly1305_i15_run(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); /** * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq). * * This implementation uses 64-bit multiplications (result over 128 bits). * It is available only on platforms that offer such a primitive (in * practice, 64-bit architectures). Use `br_poly1305_ctmulq_get()` to * dynamically obtain a pointer to that function, or 0 if not supported. * * \see br_poly1305_run * * \param key secret key (32 bytes). * \param iv nonce (12 bytes). * \param data data to encrypt or decrypt. * \param len data length (in bytes). * \param aad additional authenticated data. * \param aad_len length of additional authenticated data (in bytes). * \param tag output buffer for the authentication tag. * \param ichacha implementation of ChaCha20. * \param encrypt non-zero for encryption, zero for decryption. */ void br_poly1305_ctmulq_run(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); /** * \brief Get the ChaCha20+Poly1305 "ctmulq" implementation, if available. * * This function returns a pointer to the `br_poly1305_ctmulq_run()` * function if supported on the current platform; otherwise, it returns 0. * * \return the ctmulq ChaCha20+Poly1305 implementation, or 0. */ br_poly1305_run br_poly1305_ctmulq_get(void); #ifdef __cplusplus } #endif #endif