More API documentation in Doxygen format (block ciphers, PEM).
authorThomas Pornin <pornin@bolet.org>
Mon, 21 Nov 2016 15:29:51 +0000 (16:29 +0100)
committerThomas Pornin <pornin@bolet.org>
Mon, 21 Nov 2016 15:29:51 +0000 (16:29 +0100)
Doxyfile
inc/bearssl_block.h
inc/bearssl_pem.h

index a7451f8..0f0a416 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -771,7 +771,7 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = inc/bearssl.h inc/bearssl_hash.h inc/bearssl_hmac.h inc/bearssl_prf.h inc/bearssl_rand.h inc/bearssl_rsa.h
+INPUT                  = inc/bearssl.h inc/bearssl_block.h inc/bearssl_hash.h inc/bearssl_hmac.h inc/bearssl_pem.h inc/bearssl_prf.h inc/bearssl_rand.h inc/bearssl_rsa.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
index 6dc0e5b..38108b7 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
 #include <stddef.h>
 #include <stdint.h>
 
-/*
- * Block Ciphers
- * -------------
+/** \file bearssl_block.h
+ *
+ * # Block Ciphers
+ *
+ * This file documents the API for block 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,
  *
  * 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,
- * initialized with the encryption key. Each set of functions is
- * provided both as named functions, and through an OOP interface.
+ * 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
  *
  * For CBC encryption and decryption, the data to encrypt or decrypt is
  * referenced as a sequence of blocks. The implementations assume that
  *
  * Each implemented block cipher is identified by an "internal name"
  * from which are derived the names of structures and functions that
  *
  * 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",
+ * implement the cipher. For the block cipher of internal name "`xxx`",
  * the following are defined:
  *
  * 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.
- *
- *
- * It shall be noted that the key expansion functions return 'void'. If
+ *   - `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.
+ *
+ *
+ * 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
  * 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
  * discarded without any explicit deallocation.
  *
  *
  * 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:
+ * ## 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).
  *
  *
- *   context_size     size (in bytes) of the context structure for subkeys
- *   block_size       cipher block size (in bytes)
- *   log_block_size   base-2 logarithm of cipher block size
- *   init             pointer to the key expansion function
- *   run              pointer to the encryption/decryption function
+ *   - `init`
  *
  *
- * Static, constant instances of these structures are defined, under
- * the names:
+ *     Pointer to the key expansion function.
  *
  *
- *   br_xxx_cbcenc_vtable
- *   br_xxx_cbcdec_vtable
- *   br_xxx_ctr_vtable
+ *   - `run`
  *
  *
+ *     Pointer to the encryption/decryption function.
  *
  *
- * Implemented Block Ciphers
- * -------------------------
+ *
+ * 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`
+ *
+ *
+ * ## Implemented Block Ciphers
  * 
  * 
- *   Function   Name         Allowed key lengths (bytes)
+ * 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       |
+ * | des_ct    | DES/3DES |         8          | 8, 16 and 24        |
+ * | des_tab   | DES/3DES |         8          | 8, 16 and 24        |
  *
  *
- *   AES        aes_ct       16, 24 and 32
- *   AES        aes_ct64     16, 24 and 32
- *   AES        aes_big      16, 24 and 32
- *   AES        aes_small    16, 24 and 32
- *   DES        des_ct       8, 16 and 24
- *   DES        des_tab      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
+ * `aes_big` is a "classical" AES implementation, using tables. It
  * is fast but not constant-time, since it makes data-dependent array
  * accesses.
  *
  * 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
+ * `aes_small` is an AES implementation optimized for code size. It
+ * is substantially slower than `aes_big`; it is not constant-time
  * either.
  *
  * 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
+ * `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).
  *
  * 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, for faster processing
- * on 64-bit machines.
+ * `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).
  *
  *
- * 'des_tab' is a classic, table-based implementation of DES/3DES. It
+ * `des_tab` is a classic, table-based implementation of DES/3DES. It
  * is not constant-time.
  *
  * is not constant-time.
  *
- * 'des_ct' is an constant-time implementation of DES/3DES. It is
- * substantially slower than 'des_tab'.
+ * `des_ct` is an constant-time implementation of DES/3DES. It is
+ * substantially slower than `des_tab`.
  */
 
  */
 
+/**
+ * \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_ {
 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;
        size_t context_size;
+
+       /**
+        * \brief Size of individual blocks (in bytes).
+        */
        unsigned block_size;
        unsigned block_size;
+
+       /**
+        * \brief Base-2 logarithm of the size of individual blocks,
+        * expressed in bytes.
+        */
        unsigned log_block_size;
        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);
        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);
 };
 
        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_ {
 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;
        size_t context_size;
+
+       /**
+        * \brief Size of individual blocks (in bytes).
+        */
        unsigned block_size;
        unsigned block_size;
+
+       /**
+        * \brief Base-2 logarithm of the size of individual blocks,
+        * expressed in bytes.
+        */
        unsigned log_block_size;
        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);
        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);
 };
 
        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_ {
 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;
        size_t context_size;
+
+       /**
+        * \brief Size of individual blocks (in bytes).
+        */
        unsigned block_size;
        unsigned block_size;
+
+       /**
+        * \brief Base-2 logarithm of the size of individual blocks,
+        * expressed in bytes.
+        */
        unsigned log_block_size;
        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);
        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);
 };
        uint32_t (*run)(const br_block_ctr_class *const *ctx,
                const void *iv, uint32_t cc, void *data, size_t len);
 };
@@ -231,35 +415,137 @@ struct br_block_ctr_class_ {
  * and it is not constant-time. In contexts where cache-timing attacks
  * apply, this implementation may leak the secret key.
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_big_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_big_cbcdec_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_ctr_class *vtable;
        const br_block_ctr_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_big_ctr_keys;
 } br_aes_big_ctr_keys;
+
+/**
+ * \brief Class instance for AES CBC encryption (`aes_big` implementation).
+ */
 extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable;
 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;
 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;
 extern const br_block_ctr_class br_aes_big_ctr_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);
 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);
 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);
 void br_aes_big_ctr_init(br_aes_big_ctr_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);
 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);
 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 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);
 
 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);
 
@@ -270,35 +556,137 @@ uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx,
  * much smaller 256-byte table), which makes it conceptually vulnerable
  * to cache-timing attacks.
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_small_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_small_cbcdec_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_ctr_class *vtable;
        const br_block_ctr_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_small_ctr_keys;
 } br_aes_small_ctr_keys;
+
+/**
+ * \brief Class instance for AES CBC encryption (`aes_small` implementation).
+ */
 extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable;
 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;
 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;
 extern const br_block_ctr_class br_aes_small_ctr_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);
 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);
 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);
 void br_aes_small_ctr_init(br_aes_small_ctr_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);
 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);
 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);
 
 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);
 
@@ -308,35 +696,137 @@ uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx,
  * decryption, slower encryption). However, it is constant-time, i.e.
  * immune to cache-timing and similar attacks.
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_ct_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_ct_cbcdec_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_ctr_class *vtable;
        const br_block_ctr_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[60];
        unsigned num_rounds;
        uint32_t skey[60];
        unsigned num_rounds;
+#endif
 } br_aes_ct_ctr_keys;
 } br_aes_ct_ctr_keys;
+
+/**
+ * \brief Class instance for AES CBC encryption (`aes_ct` implementation).
+ */
 extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable;
 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;
 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;
 extern const br_block_ctr_class br_aes_ct_ctr_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);
 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);
 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);
 void br_aes_ct_ctr_init(br_aes_ct_ctr_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);
 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);
 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);
 
 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);
 
@@ -348,41 +838,143 @@ uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx,
  * and CTR mode; CBC encryption is non-parallel and cannot benefit from
  * the larger registers.)
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint64_t skey[30];
        unsigned num_rounds;
        uint64_t skey[30];
        unsigned num_rounds;
+#endif
 } br_aes_ct64_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint64_t skey[30];
        unsigned num_rounds;
        uint64_t skey[30];
        unsigned num_rounds;
+#endif
 } br_aes_ct64_cbcdec_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_ctr_class *vtable;
        const br_block_ctr_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint64_t skey[30];
        unsigned num_rounds;
        uint64_t skey[30];
        unsigned num_rounds;
+#endif
 } br_aes_ct64_ctr_keys;
 } br_aes_ct64_ctr_keys;
+
+/**
+ * \brief Class instance for AES CBC encryption (`aes_ct64` implementation).
+ */
 extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable;
 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;
 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;
 extern const br_block_ctr_class br_aes_ct64_ctr_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);
 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);
 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);
 void br_aes_ct64_ctr_init(br_aes_ct64_ctr_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);
 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);
 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);
 
 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);
 
-/*
- * These structures are large enough to accommodate subkeys for all
- * AES implementations.
+/**
+ * \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;
  */
 typedef union {
        const br_block_cbcenc_class *vtable;
@@ -391,6 +983,11 @@ typedef union {
        br_aes_ct_cbcenc_keys ct;
        br_aes_ct64_cbcenc_keys ct64;
 } br_aes_gen_cbcenc_keys;
        br_aes_ct_cbcenc_keys ct;
        br_aes_ct64_cbcenc_keys ct64;
 } 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 big;
 typedef union {
        const br_block_cbcdec_class *vtable;
        br_aes_big_cbcdec_keys big;
@@ -398,6 +995,11 @@ typedef union {
        br_aes_ct_cbcdec_keys ct;
        br_aes_ct64_cbcdec_keys ct64;
 } br_aes_gen_cbcdec_keys;
        br_aes_ct_cbcdec_keys ct;
        br_aes_ct64_cbcdec_keys ct64;
 } 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 big;
 typedef union {
        const br_block_ctr_class *vtable;
        br_aes_big_ctr_keys big;
@@ -410,25 +1012,91 @@ typedef union {
  * Traditional, table-based implementation for DES/3DES. Since tables are
  * used, cache-timing attacks are conceptually possible.
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[96];
        unsigned num_rounds;
        uint32_t skey[96];
        unsigned num_rounds;
+#endif
 } br_des_tab_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[96];
        unsigned num_rounds;
        uint32_t skey[96];
        unsigned num_rounds;
+#endif
 } br_des_tab_cbcdec_keys;
 } 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;
 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;
 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);
 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);
 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);
 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);
 
 void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv,
        void *data, size_t len);
 
@@ -436,25 +1104,91 @@ void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv,
  * Constant-time implementation for DES/3DES. It is substantially slower
  * (by a factor of about 4x), but also immune to cache-timing attacks.
  */
  * 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
 #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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcenc_class *vtable;
        const br_block_cbcenc_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[96];
        unsigned num_rounds;
        uint32_t skey[96];
        unsigned num_rounds;
+#endif
 } br_des_ct_cbcenc_keys;
 } 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 {
 typedef struct {
+       /** \brief Pointer to vtable for this context. */
        const br_block_cbcdec_class *vtable;
        const br_block_cbcdec_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
        uint32_t skey[96];
        unsigned num_rounds;
        uint32_t skey[96];
        unsigned num_rounds;
+#endif
 } br_des_ct_cbcdec_keys;
 } 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;
 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;
 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);
 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);
 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);
 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);
 
 void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv,
        void *data, size_t len);
 
@@ -462,11 +1196,21 @@ void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv,
  * These structures are large enough to accommodate subkeys for all
  * DES/3DES implementations.
  */
  * 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;
 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 tab;
 typedef union {
        const br_block_cbcdec_class *vtable;
        br_des_tab_cbcdec_keys tab;
index a3872de..42b2305 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
 #include <stddef.h>
 #include <stdint.h>
 
-/*
- * Context for a PEM decoder.
+/** \file bearssl_pem.h
+ *
+ * # PEM Support
+ *
+ * PEM is a traditional encoding layer use to store binary objects (in
+ * particular X.509 certificates, and private keys) in text files. While
+ * the acronym comes from an old, defunct standard ("Privacy Enhanced
+ * Mail"), the format has been reused, with some variations, by many
+ * systems, and is a _de facto_ standard, even though it is not, actually,
+ * specified in all clarity anywhere.
+ *
+ * ## Format Details
+ *
+ * BearSSL contains a generic, streamed PEM decoder, which handles the
+ * following format:
+ *
+ *   - The input source (a sequence of bytes) is assumed to be the
+ *     encoding of a text file in an ASCII-compatible charset. This
+ *     includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each
+ *     line ends on a newline character (U+000A LINE FEED). The
+ *     U+000D CARRIAGE RETURN characters are ignored, so the code
+ *     accepts both Windows-style and Unix-style line endings.
+ *
+ *   - Each object begins with a banner that occurs at the start of
+ *     a line; the first banner characters are "`-----BEGIN `" (five
+ *     dashes, the word "BEGIN", and a space). The banner matching is
+ *     not case-sensitive.
+ *
+ *   - The _object name_ consists in the characters that follow the
+ *     banner start sequence, up to the end of the line, but without
+ *     trailing dashes (in "normal" PEM, there are five trailing
+ *     dashes, but this implementation is not picky about these dashes).
+ *     The BearSSL decoder normalises the name characters to uppercase
+ *     (for ASCII letters only) and accepts names up to 127 characters.
+ *
+ *   - The object ends with a banner that again occurs at the start of
+ *     a line, and starts with "`-----END `" (again case-insensitive).
+ *
+ *   - Between that start and end banner, only Base64 data shall occur.
+ *     Base64 converts each sequence of three bytes into four
+ *     characters; the four characters are ASCII letters, digits, "`+`"
+ *     or "`-`" signs, and one or two "`=`" signs may occur in the last
+ *     quartet. Whitespace is ignored (whitespace is any ASCII character
+ *     of code 32 or less, so control characters are whitespace) and
+ *     lines may have arbitrary length; the only restriction is that the
+ *     four characters of a quartet must appear on the same line (no
+ *     line break inside a quartet).
+ *
+ *   - A single file may contain more than one PEM object. Bytes that
+ *     occur between objects are ignored.
+ *
+ *
+ * ## PEM Decoder API
+ *
+ * The PEM decoder offers a state-machine API. The caller allocates a
+ * decoder context, then injects source bytes. Source bytes are pushed
+ * with `br_pem_decoder_push()`. The decoder stops accepting bytes when
+ * it reaches an "event", which is either the start of an object, the
+ * end of an object, or a decoding error within an object.
+ *
+ * The `br_pem_decoder_event()` function is used to obtain the current
+ * event; it also clears it, thus allowing the decoder to accept more
+ * bytes. When a object start event is raised, the decoder context
+ * offers the found object name (normalised to ASCII uppercase).
+ *
+ * When an object is reached, the caller must set an appropriate callback
+ * function, which will receive (by chunks) the decoded object data.
+ *
+ * Since the decoder context makes no dynamic allocation, it requires
+ * no explicit deallocation.
+ */
+
+/**
+ * \brief PEM decoder context.
+ *
+ * Contents are opaque (they should not be accessed directly).
  */
 typedef struct {
  */
 typedef struct {
+#ifndef BR_DOXYGEN_IGNORE
        /* CPU for the T0 virtual machine. */
        struct {
                uint32_t *dp;
        /* CPU for the T0 virtual machine. */
        struct {
                uint32_t *dp;
@@ -52,27 +127,45 @@ typedef struct {
        char name[128];
        unsigned char buf[255];
        size_t ptr;
        char name[128];
        unsigned char buf[255];
        size_t ptr;
-
+#endif
 } br_pem_decoder_context;
 
 } br_pem_decoder_context;
 
-/*
- * Initialise a PEM decoder structure.
+/**
+ * \brief Initialise a PEM decoder structure.
+ *
+ * \param ctx   decoder context to initialise.
  */
 void br_pem_decoder_init(br_pem_decoder_context *ctx);
 
  */
 void br_pem_decoder_init(br_pem_decoder_context *ctx);
 
-/*
- * Push some bytes into the decoder. Returned value is the number of
- * bytes actually consumed; this may be less than the number of provided
- * bytes if an event is produced. When an event is produced, it must
- * be read (with br_pem_decoder_event()); until the event is read, this
- * function will return 0.
+/**
+ * \brief Push some bytes into the decoder.
+ *
+ * Returned value is the number of bytes actually consumed; this may be
+ * less than the number of provided bytes if an event is raised. When an
+ * event is raised, it must be read (with `br_pem_decoder_event()`);
+ * until the event is read, this function will return 0.
+ *
+ * \param ctx    decoder context.
+ * \param data   new data bytes.
+ * \param len    number of new data bytes.
+ * \return  the number of bytes actually received (may be less than `len`).
  */
 size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
        const void *data, size_t len);
 
  */
 size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
        const void *data, size_t len);
 
-/*
- * Set the receiver for decoded data. The provided function (with opaque
- * context pointer) will be called with successive data chunks.
+/**
+ * \brief Set the receiver for decoded data.
+ *
+ * When an object is entered, the provided function (with opaque context
+ * pointer) will be called repeatedly with successive chunks of decoded
+ * data for that object. If `dest` is set to 0, then decoded data is
+ * simply ignored. The receiver can be set at any time, but, in practice,
+ * it should be called immediately after receiving a "start of object"
+ * event.
+ *
+ * \param ctx        decoder context.
+ * \param dest       callback for receiving decoded data.
+ * \param dest_ctx   opaque context pointer for the `dest` callback.
  */
 static inline void
 br_pem_decoder_setdest(br_pem_decoder_context *ctx,
  */
 static inline void
 br_pem_decoder_setdest(br_pem_decoder_context *ctx,
@@ -83,38 +176,55 @@ br_pem_decoder_setdest(br_pem_decoder_context *ctx,
        ctx->dest_ctx = dest_ctx;
 }
 
        ctx->dest_ctx = dest_ctx;
 }
 
-/*
- * Get the last event. This is 0 if no event has been produced. Calling
- * ths function clears the event and allows new source bytes to be
- * processed.
+/**
+ * \brief Get the last event.
+ *
+ * If an event was raised, then this function returns the event value, and
+ * also clears it, thereby allowing the decoder to proceed. If no event
+ * was raised since the last call to `br_pem_decoder_event()`, then this
+ * function returns 0.
+ *
+ * \param ctx   decoder context.
+ * \return  the raised event, or 0.
  */
 int br_pem_decoder_event(br_pem_decoder_context *ctx);
 
  */
 int br_pem_decoder_event(br_pem_decoder_context *ctx);
 
-/*
- * This event is called when the start of a new object has been detected.
+/**
+ * \brief Event: start of object.
+ *
+ * This event is raised when the start of a new object has been detected.
  * The object name (normalised to uppercase) can be accessed with
  * The object name (normalised to uppercase) can be accessed with
- * br_pem_decoder_name(). The caller MUST provide an appropriate receiver
- * (with br_pem_decoder_setdest()) before sending new data bytes.
+ * `br_pem_decoder_name()`.
  */
 #define BR_PEM_BEGIN_OBJ   1
 
  */
 #define BR_PEM_BEGIN_OBJ   1
 
-/*
- * This event is called when the end of the current object is reached
- * (normally).
+/**
+ * \brief Event: end of object.
+ *
+ * This event is raised when the end of the current object is reached
+ * (normally, i.e. with no decoding error).
  */
 #define BR_PEM_END_OBJ     2
 
  */
 #define BR_PEM_END_OBJ     2
 
-/*
- * This event is called when decoding fails while decoding an object.
+/**
+ * \brief Event: decoding error.
+ *
+ * This event is raised when decoding fails within an object.
  * This formally closes the current object and brings the decoder back
  * to the "out of any object" state. The offending line in the source
  * is consumed.
  */
 #define BR_PEM_ERROR       3
 
  * This formally closes the current object and brings the decoder back
  * to the "out of any object" state. The offending line in the source
  * is consumed.
  */
 #define BR_PEM_ERROR       3
 
-/*
- * Get the name of the encountered object. That name is normalised to
- * uppercase (for ASCII characters).
+/**
+ * \brief Get the name of the encountered object.
+ *
+ * The encountered object name is defined only when the "start of object"
+ * event is raised. That name is normalised to uppercase (for ASCII letters
+ * only) and does not include trailing dashes.
+ *
+ * \param ctx   decoder context.
+ * \return  the current object name.
  */
 static inline const char *
 br_pem_decoder_name(br_pem_decoder_context *ctx)
  */
 static inline const char *
 br_pem_decoder_name(br_pem_decoder_context *ctx)