/* * Copyright (C) 2022 - 2026, Stephan Mueller * * License: see LICENSE file in root directory * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ #ifndef LC_AEAD_H #define LC_AEAD_H #include "lc_aes.h" #include "lc_memory_support.h" #include "lc_status.h" #ifdef __cplusplus extern "C" { #endif /// \cond DO_NOT_DOCUMENT struct lc_aead { int (*setkey)(void *state, const uint8_t *key, const size_t keylen, const uint8_t *iv, size_t ivlen); void (*encrypt)(void *state, const uint8_t *plaintext, uint8_t *ciphertext, size_t datalen, const uint8_t *aad, size_t aadlen, uint8_t *tag, size_t taglen); void (*enc_init)(void *state, const uint8_t *aad, size_t aadlen); void (*enc_update)(void *state, const uint8_t *plaintext, uint8_t *ciphertext, size_t datalen); void (*enc_final)(void *state, uint8_t *tag, size_t taglen); int (*decrypt)(void *state, const uint8_t *ciphertext, uint8_t *plaintext, size_t datalen, const uint8_t *aad, size_t aadlen, const uint8_t *tag, size_t taglen); void (*dec_init)(void *state, const uint8_t *aad, size_t aadlen); void (*dec_update)(void *state, const uint8_t *ciphertext, uint8_t *plaintext, size_t datalen); int (*dec_final)(void *state, const uint8_t *tag, size_t taglen); void (*zero)(void *state); uint64_t algorithm_type; }; struct lc_aead_ctx { const struct lc_aead *aead; void *aead_state; }; #define LC_AEAD_CTX(name, cb) \ name->aead = cb; \ name->aead_state = (uint8_t *)(name) + sizeof(struct lc_aead_ctx) #define LC_AEAD_HASH_ALIGN_CTX(name, cb) \ name->aead = cb; \ name->aead_state = LC_ALIGN_HASH_MASK((uint8_t *)(name) + \ sizeof(struct lc_aead_ctx)) /// \endcond /** @defgroup AEAD Authenticated Encryption with Associated Data * * Concept of AEAD algorithms in leancrypto * * All AEAD algorithms can be used with the API calls documented below. However, * the allocation part is AEAD-algorithm-specific. Thus, perform the following * steps * * 1. Allocation: Use the stack or heap allocation functions documented in * lc_chacha20_poly1305.h, lc_aes_gcm.h, * lc_ascon_lightweight.h, lc_ascon_keccak.h, lc_cshake_crypt.h, * lc_kmac_crypt.h, lc_hash_crypt.h, lc_symhmac.h, or lc_symkmac.h. * * 2. Use the returned cipher handle with the API calls below. */ /** * @ingroup AEAD * @brief Zeroize AEAD context * * @param [in] ctx AEAD context to be zeroized */ void lc_aead_zero(struct lc_aead_ctx *ctx); /** * @ingroup AEAD * @brief Zeroize and free AEAD context * * @param [in] ctx AEAD context to be zeroized and freed */ void lc_aead_zero_free(struct lc_aead_ctx *ctx); /** * @ingroup AEAD * @brief Set the key for the AEAD encyption or decryption operation * * @param [in] ctx AEAD context handle * @param [in] key Buffer with key * @param [in] keylen Length of key buffer * @param [in] iv initialization vector to be used * @param [in] ivlen length of initialization vector * * The algorithm supports a key of arbitrary size. The only requirement is that * the same key is used for decryption as for encryption. * * @return 0 upon success; < 0 on error */ int lc_aead_setkey(struct lc_aead_ctx *ctx, const uint8_t *key, const size_t keylen, const uint8_t *iv, size_t ivlen); /** * @ingroup AEAD * @brief AEAD-encrypt data in one call * * @param [in] ctx AEAD context handle with key set / IV * @param [in] plaintext Plaintext data to be encrypted * @param [out] ciphertext Ciphertext data buffer to be filled * @param [in] datalen Length of the plaintext and ciphertext data buffers * \note the encryption operation is symmetric and * generates as much output as input. * @param [in] aad Additional authenticate data to be processed - this is data * which is not encrypted, but considered as part of the * authentication. * @param [in] aadlen Length of the AAD buffer * @param [out] tag Buffer to be filled with tag * @param [in] taglen Length of tag buffer. The full tag size hc_get_tagsize(). * If the buffer is smaller, a truncated tag value is * returned. * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_encrypt(struct lc_aead_ctx *ctx, const uint8_t *plaintext, uint8_t *ciphertext, size_t datalen, const uint8_t *aad, size_t aadlen, uint8_t *tag, size_t taglen); /** * @ingroup AEAD * @brief Initialize AEAD encryption * * This call allows multiple successive _update calls to process data. * * @param [in] ctx AEAD context handle with key set / IV * @param [in] aad Additional authenticate data to be processed - this is data * which is not encrypted, but considered as part of the * authentication. * @param [in] aadlen Length of the AAD buffer * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_enc_init(struct lc_aead_ctx *ctx, const uint8_t *aad, size_t aadlen); /** * @ingroup AEAD * @brief AEAD-encrypt data - send partial data * * \note This operation can be invoked multiple times and must be completed * with a call to lc_aead_enc_final. * * @param [in] ctx AEAD context handle with key set / IV * @param [in] plaintext Plaintext data to be encrypted * @param [out] ciphertext Ciphertext data buffer to be filled * @param [in] datalen Length of the plaintext and ciphertext data buffers * \note the encryption operation is symmetric and * generates as much output as input. * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_enc_update(struct lc_aead_ctx *ctx, const uint8_t *plaintext, uint8_t *ciphertext, size_t datalen); /** * @ingroup AEAD * @brief Complete AEAD encryption - Obtain the authentication tag from the * encryption operation * * @param [in] ctx AEAD context handle with key set / IV * @param [out] tag Buffer to be filled with tag * @param [in] taglen Length of tag buffer. The full tag size hc_get_tagsize(). * If the buffer is smaller, a truncated tag value is * returned. * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_enc_final(struct lc_aead_ctx *ctx, uint8_t *tag, size_t taglen); /** * @ingroup AEAD * @brief AEAD-decrypt data in one call * * @param [in] ctx AEAD context handle with key set / IV * @param [in] ciphertext Ciphertext data to be decrypted * @param [out] plaintext Plaintext data buffer to be filled * @param [in] datalen Length of the plaintext and ciphertext data buffers * \note the encryption operation is symmetric and * generates as much output as input. * @param [in] aad Additional authenticate data to be processed - this is data * which is not decrypted, but considered as part of the * authentication. * @param [in] aadlen Length of the AAD buffer * @param [in] tag Authentication tag generated by encryption operation * @param [in] taglen Length of tag buffer. * * * @return 0 on successful authentication, < 0 on error * (-EBADMSG means authentication error) */ int lc_aead_decrypt(struct lc_aead_ctx *ctx, const uint8_t *ciphertext, uint8_t *plaintext, size_t datalen, const uint8_t *aad, size_t aadlen, const uint8_t *tag, size_t taglen); /** * @ingroup AEAD * @brief Initialize AEAD decryption * * This call allows multiple successive _update calls to process data. * * @param [in] ctx AEAD context handle with key set / IV * @param [in] aad Additional authenticate data to be processed - this is data * which is not encrypted, but considered as part of the * authentication. * @param [in] aadlen Length of the AAD buffer * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_dec_init(struct lc_aead_ctx *ctx, const uint8_t *aad, size_t aadlen); /** * @ingroup AEAD * @brief AEAD-decrypt data - send partial data * * \note This operation can be invoked multiple times and must be completed * with a call to lc_aead_dec_final. * * @param [in] ctx AEAD context handle with key set / IV * @param [in] ciphertext Ciphertext data to be decrypted * @param [out] plaintext Plaintext data buffer to be filled * @param [in] datalen Length of the plaintext and ciphertext data buffers * \note the encryption operation is symmetric and * generates as much output as input. * * @return amount of processed bytes on success, < 0 on error */ int lc_aead_dec_update(struct lc_aead_ctx *ctx, const uint8_t *ciphertext, uint8_t *plaintext, size_t datalen); /** * @ingroup AEAD * @brief AEAD-decrypt data - Perform authentication * * @param [in] ctx AEAD context handle with key set / IV * @param [in] tag Authentication tag generated by encryption operation * @param [in] taglen Length of tag buffer. * * * @return 0 on successful authentication, < 0 on error * (-EBADMSG means authentication error) */ int lc_aead_dec_final(struct lc_aead_ctx *ctx, const uint8_t *tag, size_t taglen); /** * @ingroup AEAD * @brief Obtain algorithm status * * @param [in] aead AEAD algorithm instance * * @return algorithm status */ enum lc_alg_status_val lc_aead_alg_status(const struct lc_aead *aead); /** * @ingroup AEAD * @brief Obtain algorithm status * * @param [in] ctx AEAD context handle * * @return algorithm status */ enum lc_alg_status_val lc_aead_ctx_alg_status(const struct lc_aead_ctx *ctx); #ifdef __cplusplus } #endif #endif /* LC_AEAD_H */