9#include <botan/internal/ascon_aead128.h>
11#include <botan/exceptn.h>
12#include <botan/mem_ops.h>
13#include <botan/internal/concat_util.h>
14#include <botan/internal/int_utils.h>
15#include <botan/internal/loadstor.h>
21constexpr void xor2x64(std::span<uint64_t, 2> lhs, std::span<const uint64_t, 2> rhs) {
27constexpr auto as_array_of_uint64(std::span<const uint8_t> in) {
33constexpr Ascon_p initial_state_of_ascon_aead_permutation({
34 .init_and_final_rounds = 12,
35 .processing_rounds = 8,
41constexpr uint64_t ascon_aead_128_iv = 0x00001000808c0001;
44constexpr uint64_t ascon_aead_128_domain_sep = 0x8000000000000000;
51 if(
m_key.has_value()) {
57 if(
m_key.has_value()) {
66 m_ascon_p = initial_state_of_ascon_aead_permutation;
73 m_key = as_array_of_uint64<2>(key);
77 BOTAN_ARG_CHECK(idx == 0,
"Ascon-AEAD128: cannot handle non-zero index in set_associated_data_n");
79 m_ad.assign(ad.begin(), ad.end());
88 m_ascon_p.state() =
concat(std::array{ascon_aead_128_iv}, *
m_key, as_array_of_uint64<2>({nonce, nonce_len}));
104 m_ascon_p.state()[4] ^= ascon_aead_128_domain_sep;
127size_t Ascon_AEAD128_Encryption::process_msg(uint8_t buf[],
size_t size) {
138 BOTAN_ARG_CHECK(final_block.size() >= offset,
"Offset is out of range");
140 const auto final_block_at_offset = std::span{final_block}.subspan(offset);
141 process_msg(final_block_at_offset.data(), final_block_at_offset.size());
143 final_block.insert(final_block.end(), tag.begin(), tag.end());
151size_t Ascon_AEAD128_Decryption::process_msg(uint8_t buf[],
size_t size) {
162 BOTAN_ARG_CHECK(final_block.size() >= offset,
"Offset is out of range");
164 const auto final_block_at_offset = std::span{final_block}.subspan(offset);
166 const auto final_ciphertext_block = final_block_at_offset.first(final_block_at_offset.size() -
tag_size());
167 const auto expected_tag = final_block_at_offset.last(
tag_size());
169 process_msg(final_ciphertext_block.data(), final_ciphertext_block.size());
171 clear_mem(std::span{final_block}.subspan(offset, final_ciphertext_block.size()));
172 throw Invalid_Authentication_Tag(
"Ascon-AEAD128 tag check failed");
175 final_block.resize(offset + final_ciphertext_block.size());
#define BOTAN_DEBUG_ASSERT(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
size_t output_length(size_t input_length) const override
size_t output_length(size_t input_length) const override
bool has_keying_material() const final
void key_schedule(std::span< const uint8_t > key) final
std::optional< std::array< uint64_t, 2 > > m_key
~Ascon_AEAD128_Mode() override
void maybe_absorb_associated_data()
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) final
size_t tag_size() const final
bool valid_nonce_length(size_t n) const final
std::array< uint8_t, 16 > calculate_tag_and_finish()
void start_msg(const uint8_t nonce[], size_t nonce_len) final
void percolate_in(std::span< uint8_t > data)
void percolate_out(std::span< uint8_t > data)
constexpr T add_or_throw(T a, T b, std::string_view msg)
void secure_scrub_memory(void *ptr, size_t n)
constexpr auto store_le(ParamTs &&... params)
constexpr auto concat(Rs &&... ranges)
constexpr auto load_le(ParamTs &&... params)
std::vector< T, secure_allocator< T > > secure_vector
bool constant_time_compare(std::span< const uint8_t > x, std::span< const uint8_t > y)
constexpr void clear_mem(T *ptr, size_t n)