Added generic EAX and CCM implementations.
[BearSSL] / inc / bearssl_aead.h
index 09cb9e8..b1e52a3 100644 (file)
@@ -127,7 +127,7 @@ extern "C" {
  *
  *   - Nonce, plaintext and additional authenticated data all consist
  *     in an integral number of bytes. There is no provision to use
- *     elements whose lengh in bits is not a multiple of 8.
+ *     elements whose length in bits is not a multiple of 8.
  *
  * Each AEAD algorithm has its own requirements and limits on the sizes
  * of additional data and plaintext. This API does not provide any
@@ -169,6 +169,9 @@ extern "C" {
  * Note that there is no OOP method for context initialisation: the
  * various AEAD algorithms have different requirements that would not
  * map well to a single initialisation API.
+ *
+ * The OOP API is not provided for CCM, due to its specific requirements
+ * (length of plaintext must be known in advance).
  */
 
 /**
@@ -213,7 +216,7 @@ struct br_aead_class_ {
         *
         * \param cc     AEAD context structure.
         * \param data   pointer to additional authenticated data.
-        * \param len    length of additiona authenticated data (in bytes).
+        * \param len    length of additional authenticated data (in bytes).
         */
        void (*aad_inject)(const br_aead_class **cc,
                const void *data, size_t len);
@@ -266,6 +269,8 @@ struct br_aead_class_ {
         * `check_tag()` function may be used to compute and check the
         * tag value.
         *
+        * Tag length depends on the AEAD algorithm.
+        *
         * \param cc    AEAD context structure.
         * \param tag   destination buffer for the tag.
         */
@@ -282,11 +287,44 @@ struct br_aead_class_ {
         * data or the tag was altered in transit, normally leading to
         * wholesale rejection of the complete message.
         *
+        * Tag length depends on the AEAD algorithm.
+        *
         * \param cc    AEAD context structure.
-        * \param tag   tag value to compare with (16 bytes).
+        * \param tag   tag value to compare with.
         * \return  1 on success (exact match of tag value), 0 otherwise.
         */
        uint32_t (*check_tag)(const br_aead_class **cc, const void *tag);
+
+       /**
+        * \brief Compute authentication tag (with truncation).
+        *
+        * This function is similar to `get_tag()`, except that the tag
+        * length is provided. Some AEAD algorithms allow several tag
+        * lengths, usually by truncating the normal tag. Shorter tags
+        * mechanically increase success probability of forgeries.
+        * The range of allowed tag lengths depends on the algorithm.
+        *
+        * \param cc    AEAD context structure.
+        * \param tag   destination buffer for the tag.
+        * \param len   tag length (in bytes).
+        */
+       void (*get_tag_trunc)(const br_aead_class **cc, void *tag, size_t len);
+
+       /**
+        * \brief Compute and check authentication tag (with truncation).
+        *
+        * This function is similar to `check_tag()` except that it
+        * works over an explicit tag length. See `get_tag()` for a
+        * discussion of explicit tag lengths; the range of allowed tag
+        * lengths depends on the algorithm.
+        *
+        * \param cc    AEAD context structure.
+        * \param tag   tag value to compare with.
+        * \param len   tag length (in bytes).
+        * \return  1 on success (exact match of tag value), 0 otherwise.
+        */
+       uint32_t (*check_tag_trunc)(const br_aead_class **cc,
+               const void *tag, size_t len);
 };
 
 /**
@@ -379,7 +417,7 @@ void br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len);
  *
  * \param ctx    GCM context structure.
  * \param data   pointer to additional authenticated data.
- * \param len    length of additiona authenticated data (in bytes).
+ * \param len    length of additional authenticated data (in bytes).
  */
 void br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len);
 
@@ -449,11 +487,478 @@ void br_gcm_get_tag(br_gcm_context *ctx, void *tag);
  */
 uint32_t br_gcm_check_tag(br_gcm_context *ctx, const void *tag);
 
+/**
+ * \brief Compute GCM authentication tag (with truncation).
+ *
+ * This function is similar to `br_gcm_get_tag()`, except that it allows
+ * the tag to be truncated to a smaller length. The intended tag length
+ * is provided as `len` (in bytes); it MUST be no more than 16, but
+ * it may be smaller. Note that decreasing tag length mechanically makes
+ * forgeries easier; NIST SP 800-38D specifies that the tag length shall
+ * lie between 12 and 16 bytes (inclusive), but may be truncated down to
+ * 4 or 8 bytes, for specific applications that can tolerate it. It must
+ * also be noted that successful forgeries leak information on the
+ * authentication key, making subsequent forgeries easier. Therefore,
+ * tag truncation, and in particular truncation to sizes lower than 12
+ * bytes, shall be envisioned only with great care.
+ *
+ * The tag is written in the provided `tag` buffer. This call terminates
+ * the GCM run: no data may be processed with that GCM context
+ * afterwards, until `br_gcm_reset()` is called to initiate a new GCM
+ * run.
+ *
+ * The tag value must normally be sent along with the encrypted data.
+ * When decrypting, the tag value must be recomputed and compared with
+ * the received tag: if the two tag values differ, then either the tag
+ * or the encrypted data was altered in transit. As an alternative to
+ * this function, the `br_gcm_check_tag_trunc()` function can be used to
+ * compute and check the tag value.
+ *
+ * \param ctx   GCM context structure.
+ * \param tag   destination buffer for the tag.
+ * \param len   tag length (16 bytes or less).
+ */
+void br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len);
+
+/**
+ * \brief Compute and check GCM authentication tag (with truncation).
+ *
+ * This function is an alternative to `br_gcm_get_tag_trunc()`, normally used
+ * on the receiving end (i.e. when decrypting value). The tag value is
+ * recomputed and compared with the provided tag value. If they match, 1
+ * is returned; on mismatch, 0 is returned. A returned value of 0 means
+ * that the data or the tag was altered in transit, normally leading to
+ * wholesale rejection of the complete message.
+ *
+ * Tag length MUST be 16 bytes or less. The normal GCM tag length is 16
+ * bytes. See `br_check_tag_trunc()` for some discussion on the potential
+ * perils of truncating authentication tags.
+ *
+ * \param ctx   GCM context structure.
+ * \param tag   tag value to compare with.
+ * \param len   tag length (in bytes).
+ * \return  1 on success (exact match of tag value), 0 otherwise.
+ */
+uint32_t br_gcm_check_tag_trunc(br_gcm_context *ctx,
+       const void *tag, size_t len);
+
 /**
  * \brief Class instance for GCM.
  */
 extern const br_aead_class br_gcm_vtable;
 
+/**
+ * \brief Context structure for EAX.
+ *
+ * EAX is an AEAD mode that combines a block cipher in CTR mode with
+ * CBC-MAC using the same block cipher and the same key, to provide
+ * authenticated encryption:
+ *
+ *   - Any block cipher with 16-byte blocks can be used with EAX
+ *     (technically, other block sizes are defined as well, but this
+ *     is not implemented by these functions; shorter blocks also
+ *     imply numerous security issues).
+ *
+ *   - The nonce can have any length, as long as nonce values are
+ *     not reused (thus, if nonces are randomly selected, the nonce
+ *     size should be such that reuse probability is negligible).
+ *
+ *   - Additional authenticated data length is unlimited.
+ *
+ *   - Message length is unlimited.
+ *
+ *   - The authentication tag has length 16 bytes.
+ *
+ * The EAX initialisation function receives as parameter an
+ * _initialised_ block cipher implementation context, with the secret
+ * key already set. A pointer to that context will be kept within the
+ * EAX context structure. It is up to the caller to allocate and
+ * initialise that block cipher context.
+ */
+typedef struct {
+       /** \brief Pointer to vtable for this context. */
+       const br_aead_class *vtable;
+
+#ifndef BR_DOXYGEN_IGNORE
+       const br_block_ctrcbc_class **bctx;
+       unsigned char L2[16];
+       unsigned char L4[16];
+       unsigned char nonce[16];
+       unsigned char head[16];
+       unsigned char ctr[16];
+       unsigned char cbcmac[16];
+       unsigned char buf[16];
+       size_t ptr;
+#endif
+} br_eax_context;
+
+/**
+ * \brief Initialize an EAX context.
+ *
+ * A block cipher implementation, with its initialised context
+ * structure, is provided. The block cipher MUST use 16-byte blocks in
+ * CTR + CBC-MAC mode, and its secret key MUST have been already set in
+ * the provided context. The parameters are linked in the EAX context.
+ *
+ * After this function has been called, the `br_eax_reset()` function must
+ * be called, to provide the nonce for EAX computation.
+ *
+ * \param ctx    EAX context structure.
+ * \param bctx   block cipher context (already initialised with secret key).
+ */
+void br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx);
+
+/**
+ * \brief Reset an EAX context.
+ *
+ * This function resets an already initialised EAX context for a new
+ * computation run. Implementations and keys are conserved. This function
+ * can be called at any time; it cancels any ongoing EAX computation that
+ * uses the provided context structure.
+ *
+ * It is critical to EAX security that nonce values are not repeated for
+ * the same encryption key. Nonces can have arbitrary length. If nonces
+ * are randomly generated, then a nonce length of at least 128 bits (16
+ * bytes) is recommended, to make nonce reuse probability sufficiently
+ * low.
+ *
+ * \param ctx     EAX context structure.
+ * \param nonce   EAX nonce to use.
+ * \param len     EAX nonce length (in bytes).
+ */
+void br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len);
+
+/**
+ * \brief Inject additional authenticated data into EAX.
+ *
+ * The provided data is injected into a running EAX computation. Additional
+ * data must be injected _before_ the call to `br_eax_flip()`.
+ * Additional data can be injected in several chunks of arbitrary length;
+ * the total amount of additional authenticated data is unlimited.
+ *
+ * \param ctx    EAX context structure.
+ * \param data   pointer to additional authenticated data.
+ * \param len    length of additional authenticated data (in bytes).
+ */
+void br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len);
+
+/**
+ * \brief Finish injection of additional authenticated data into EAX.
+ *
+ * This function MUST be called before beginning the actual encryption
+ * or decryption (with `br_eax_run()`), even if no additional authenticated
+ * data was injected. No additional authenticated data may be injected
+ * after this function call.
+ *
+ * \param ctx   EAX context structure.
+ */
+void br_eax_flip(br_eax_context *ctx);
+
+/**
+ * \brief Encrypt or decrypt some data with EAX.
+ *
+ * Data encryption or decryption can be done after `br_eax_flip()`
+ * has been called on the context. If `encrypt` is non-zero, then the
+ * provided data shall be plaintext, and it is encrypted in place.
+ * Otherwise, the data shall be ciphertext, and it is decrypted in place.
+ *
+ * Data may be provided in several chunks of arbitrary length.
+ *
+ * \param ctx       EAX context structure.
+ * \param encrypt   non-zero for encryption, zero for decryption.
+ * \param data      data to encrypt or decrypt.
+ * \param len       data length (in bytes).
+ */
+void br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len);
+
+/**
+ * \brief Compute EAX authentication tag.
+ *
+ * Compute the EAX authentication tag. The tag is a 16-byte value which
+ * is written in the provided `tag` buffer. This call terminates the
+ * EAX run: no data may be processed with that EAX context afterwards,
+ * until `br_eax_reset()` is called to initiate a new EAX run.
+ *
+ * The tag value must normally be sent along with the encrypted data.
+ * When decrypting, the tag value must be recomputed and compared with
+ * the received tag: if the two tag values differ, then either the tag
+ * or the encrypted data was altered in transit. As an alternative to
+ * this function, the `br_eax_check_tag()` function can be used to
+ * compute and check the tag value.
+ *
+ * \param ctx   EAX context structure.
+ * \param tag   destination buffer for the tag (16 bytes).
+ */
+void br_eax_get_tag(br_eax_context *ctx, void *tag);
+
+/**
+ * \brief Compute and check EAX authentication tag.
+ *
+ * This function is an alternative to `br_eax_get_tag()`, normally used
+ * on the receiving end (i.e. when decrypting value). The tag value is
+ * recomputed and compared with the provided tag value. If they match, 1
+ * is returned; on mismatch, 0 is returned. A returned value of 0 means
+ * that the data or the tag was altered in transit, normally leading to
+ * wholesale rejection of the complete message.
+ *
+ * \param ctx   EAX context structure.
+ * \param tag   tag value to compare with (16 bytes).
+ * \return  1 on success (exact match of tag value), 0 otherwise.
+ */
+uint32_t br_eax_check_tag(br_eax_context *ctx, const void *tag);
+
+/**
+ * \brief Compute EAX authentication tag (with truncation).
+ *
+ * This function is similar to `br_eax_get_tag()`, except that it allows
+ * the tag to be truncated to a smaller length. The intended tag length
+ * is provided as `len` (in bytes); it MUST be no more than 16, but
+ * it may be smaller. Note that decreasing tag length mechanically makes
+ * forgeries easier; NIST SP 800-38D specifies that the tag length shall
+ * lie between 12 and 16 bytes (inclusive), but may be truncated down to
+ * 4 or 8 bytes, for specific applications that can tolerate it. It must
+ * also be noted that successful forgeries leak information on the
+ * authentication key, making subsequent forgeries easier. Therefore,
+ * tag truncation, and in particular truncation to sizes lower than 12
+ * bytes, shall be envisioned only with great care.
+ *
+ * The tag is written in the provided `tag` buffer. This call terminates
+ * the EAX run: no data may be processed with that EAX context
+ * afterwards, until `br_eax_reset()` is called to initiate a new EAX
+ * run.
+ *
+ * The tag value must normally be sent along with the encrypted data.
+ * When decrypting, the tag value must be recomputed and compared with
+ * the received tag: if the two tag values differ, then either the tag
+ * or the encrypted data was altered in transit. As an alternative to
+ * this function, the `br_eax_check_tag_trunc()` function can be used to
+ * compute and check the tag value.
+ *
+ * \param ctx   EAX context structure.
+ * \param tag   destination buffer for the tag.
+ * \param len   tag length (16 bytes or less).
+ */
+void br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len);
+
+/**
+ * \brief Compute and check EAX authentication tag (with truncation).
+ *
+ * This function is an alternative to `br_eax_get_tag_trunc()`, normally used
+ * on the receiving end (i.e. when decrypting value). The tag value is
+ * recomputed and compared with the provided tag value. If they match, 1
+ * is returned; on mismatch, 0 is returned. A returned value of 0 means
+ * that the data or the tag was altered in transit, normally leading to
+ * wholesale rejection of the complete message.
+ *
+ * Tag length MUST be 16 bytes or less. The normal EAX tag length is 16
+ * bytes. See `br_check_tag_trunc()` for some discussion on the potential
+ * perils of truncating authentication tags.
+ *
+ * \param ctx   EAX context structure.
+ * \param tag   tag value to compare with.
+ * \param len   tag length (in bytes).
+ * \return  1 on success (exact match of tag value), 0 otherwise.
+ */
+uint32_t br_eax_check_tag_trunc(br_eax_context *ctx,
+       const void *tag, size_t len);
+
+/**
+ * \brief Class instance for EAX.
+ */
+extern const br_aead_class br_eax_vtable;
+
+/**
+ * \brief Context structure for CCM.
+ *
+ * CCM is an AEAD mode that combines a block cipher in CTR mode with
+ * CBC-MAC using the same block cipher and the same key, to provide
+ * authenticated encryption:
+ *
+ *   - Any block cipher with 16-byte blocks can be used with CCM
+ *     (technically, other block sizes are defined as well, but this
+ *     is not implemented by these functions; shorter blocks also
+ *     imply numerous security issues).
+ *
+ *   - The authentication tag length, and plaintext length, MUST be
+ *     known when starting processing data. Plaintext and ciphertext
+ *     can still be provided by chunks, but the total size must match
+ *     the value provided upon initialisation.
+ *
+ *   - The nonce length is constrained betwen 7 and 13 bytes (inclusive).
+ *     Furthermore, the plaintext length, when encoded, must fit over
+ *     15-nonceLen bytes; thus, if the nonce has length 13 bytes, then
+ *     the plaintext length cannot exceed 65535 bytes.
+ *
+ *   - Additional authenticated data length is practically unlimited
+ *     (formal limit is at 2^64 bytes).
+ *
+ *   - The authentication tag has length 4 to 16 bytes (even values only).
+ *
+ * The CCM initialisation function receives as parameter an
+ * _initialised_ block cipher implementation context, with the secret
+ * key already set. A pointer to that context will be kept within the
+ * CCM context structure. It is up to the caller to allocate and
+ * initialise that block cipher context.
+ */
+typedef struct {
+#ifndef BR_DOXYGEN_IGNORE
+       const br_block_ctrcbc_class **bctx;
+       unsigned char ctr[16];
+       unsigned char cbcmac[16];
+       unsigned char tagmask[16];
+       unsigned char buf[16];
+       size_t ptr;
+       size_t tag_len;
+#endif
+} br_ccm_context;
+
+/**
+ * \brief Initialize a CCM context.
+ *
+ * A block cipher implementation, with its initialised context
+ * structure, is provided. The block cipher MUST use 16-byte blocks in
+ * CTR + CBC-MAC mode, and its secret key MUST have been already set in
+ * the provided context. The parameters are linked in the CCM context.
+ *
+ * After this function has been called, the `br_ccm_reset()` function must
+ * be called, to provide the nonce for CCM computation.
+ *
+ * \param ctx    CCM context structure.
+ * \param bctx   block cipher context (already initialised with secret key).
+ */
+void br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx);
+
+/**
+ * \brief Reset a CCM context.
+ *
+ * This function resets an already initialised CCM context for a new
+ * computation run. Implementations and keys are conserved. This function
+ * can be called at any time; it cancels any ongoing CCM computation that
+ * uses the provided context structure.
+ *
+ * The `aad_len` parameter contains the total length, in bytes, of the
+ * additional authenticated data. It may be zero. That length MUST be
+ * exact.
+ *
+ * The `data_len` parameter contains the total length, in bytes, of the
+ * data that will be injected (plaintext or ciphertext). That length MUST
+ * be exact. Moreover, that length MUST be less than 2^(8*(15-nonce_len)).
+ *
+ * The nonce length (`nonce_len`), in bytes, must be in the 7..13 range
+ * (inclusive).
+ *
+ * The tag length (`tag_len`), in bytes, must be in the 4..16 range, and
+ * be an even integer. Short tags mechanically allow for higher forgery
+ * probabilities; hence, tag sizes smaller than 12 bytes shall be used only
+ * with care.
+ *
+ * It is critical to CCM security that nonce values are not repeated for
+ * the same encryption key. Random generation of nonces is not generally
+ * recommended, due to the relatively small maximum nonce value.
+ *
+ * Returned value is 1 on success, 0 on error. An error is reported if
+ * the tag or nonce length is out of range, or if the
+ * plaintext/ciphertext length cannot be encoded with the specified
+ * nonce length.
+ *
+ * \param ctx         CCM context structure.
+ * \param nonce       CCM nonce to use.
+ * \param nonce_len   CCM nonce length (in bytes, 7 to 13).
+ * \param aad_len     additional authenticated data length (in bytes).
+ * \param data_len    plaintext/ciphertext length (in bytes).
+ * \param tag_len     tag length (in bytes).
+ * \return  1 on success, 0 on error.
+ */
+int br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len,
+       uint64_t aad_len, uint64_t data_len, size_t tag_len);
+
+/**
+ * \brief Inject additional authenticated data into CCM.
+ *
+ * The provided data is injected into a running CCM computation. Additional
+ * data must be injected _before_ the call to `br_ccm_flip()`.
+ * Additional data can be injected in several chunks of arbitrary length,
+ * but the total amount MUST exactly match the value which was provided
+ * to `br_ccm_reset()`.
+ *
+ * \param ctx    CCM context structure.
+ * \param data   pointer to additional authenticated data.
+ * \param len    length of additional authenticated data (in bytes).
+ */
+void br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len);
+
+/**
+ * \brief Finish injection of additional authenticated data into CCM.
+ *
+ * This function MUST be called before beginning the actual encryption
+ * or decryption (with `br_ccm_run()`), even if no additional authenticated
+ * data was injected. No additional authenticated data may be injected
+ * after this function call.
+ *
+ * \param ctx   CCM context structure.
+ */
+void br_ccm_flip(br_ccm_context *ctx);
+
+/**
+ * \brief Encrypt or decrypt some data with CCM.
+ *
+ * Data encryption or decryption can be done after `br_ccm_flip()`
+ * has been called on the context. If `encrypt` is non-zero, then the
+ * provided data shall be plaintext, and it is encrypted in place.
+ * Otherwise, the data shall be ciphertext, and it is decrypted in place.
+ *
+ * Data may be provided in several chunks of arbitrary length, provided
+ * that the total length exactly matches the length provided to the
+ * `br_ccm_reset()` call.
+ *
+ * \param ctx       CCM context structure.
+ * \param encrypt   non-zero for encryption, zero for decryption.
+ * \param data      data to encrypt or decrypt.
+ * \param len       data length (in bytes).
+ */
+void br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len);
+
+/**
+ * \brief Compute CCM authentication tag.
+ *
+ * Compute the CCM authentication tag. This call terminates the CCM
+ * run: all data must have been injected with `br_ccm_run()` (in zero,
+ * one or more successive calls). After this function has been called,
+ * no more data can br processed; a `br_ccm_reset()` call is required
+ * to start a new message.
+ *
+ * The tag length was provided upon context initialisation (last call
+ * to `br_ccm_reset()`); it is returned by this function.
+ *
+ * The tag value must normally be sent along with the encrypted data.
+ * When decrypting, the tag value must be recomputed and compared with
+ * the received tag: if the two tag values differ, then either the tag
+ * or the encrypted data was altered in transit. As an alternative to
+ * this function, the `br_ccm_check_tag()` function can be used to
+ * compute and check the tag value.
+ *
+ * \param ctx   CCM context structure.
+ * \param tag   destination buffer for the tag (up to 16 bytes).
+ * \return  the tag length (in bytes).
+ */
+size_t br_ccm_get_tag(br_ccm_context *ctx, void *tag);
+
+/**
+ * \brief Compute and check CCM authentication tag.
+ *
+ * This function is an alternative to `br_ccm_get_tag()`, normally used
+ * on the receiving end (i.e. when decrypting value). The tag value is
+ * recomputed and compared with the provided tag value. If they match, 1
+ * is returned; on mismatch, 0 is returned. A returned value of 0 means
+ * that the data or the tag was altered in transit, normally leading to
+ * wholesale rejection of the complete message.
+ *
+ * \param ctx   CCM context structure.
+ * \param tag   tag value to compare with (up to 16 bytes).
+ * \return  1 on success (exact match of tag value), 0 otherwise.
+ */
+uint32_t br_ccm_check_tag(br_ccm_context *ctx, const void *tag);
+
 #ifdef __cplusplus
 }
 #endif