From ccd43452e6bb870f7cc5a15d93c5aaff985d95b1 Mon Sep 17 00:00:00 2001 From: Thomas Pornin Date: Mon, 21 Nov 2016 16:29:51 +0100 Subject: [PATCH] More API documentation in Doxygen format (block ciphers, PEM). --- Doxyfile | 2 +- inc/bearssl_block.h | 974 ++++++++++++++++++++++++++++++++++++++------ inc/bearssl_pem.h | 170 ++++++-- 3 files changed, 1000 insertions(+), 146 deletions(-) diff --git a/Doxyfile b/Doxyfile index a7451f8..0f0a416 100644 --- 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. -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 diff --git a/inc/bearssl_block.h b/inc/bearssl_block.h index 6dc0e5b..38108b7 100644 --- a/inc/bearssl_block.h +++ b/inc/bearssl_block.h @@ -28,15 +28,19 @@ #include #include -/* - * 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, - * 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 @@ -48,80 +52,87 @@ * * 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: * - * 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 @@ -132,94 +143,267 @@ * 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. * - * '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. * - * '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). * - * '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. * - * '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_ { + /** + * \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); }; @@ -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. */ + +/** \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 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 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 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 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); @@ -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. */ + +/** \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 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 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 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); @@ -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. */ + +/** \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 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 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 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); @@ -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.) */ + +/** \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 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 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 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); -/* - * 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; @@ -391,6 +983,11 @@ typedef union { 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; @@ -398,6 +995,11 @@ typedef union { 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; @@ -410,25 +1012,91 @@ typedef union { * 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); @@ -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. */ + +/** \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); @@ -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. */ + +/** + * \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 tab; diff --git a/inc/bearssl_pem.h b/inc/bearssl_pem.h index a3872de..42b2305 100644 --- a/inc/bearssl_pem.h +++ b/inc/bearssl_pem.h @@ -28,10 +28,85 @@ #include #include -/* - * 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 { +#ifndef BR_DOXYGEN_IGNORE /* 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; - +#endif } 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); -/* - * 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); -/* - * 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, @@ -83,38 +176,55 @@ br_pem_decoder_setdest(br_pem_decoder_context *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); -/* - * 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 - * 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 -/* - * 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 -/* - * 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 -/* - * 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) -- 2.17.1