9#include <botan/internal/chacha20poly1305.h>
11#include <botan/exceptn.h>
12#include <botan/mem_ops.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/int_utils.h>
15#include <botan/internal/loadstor.h>
27 return (n == 8 || n == 12 || n == 24);
51 return m_chacha->has_keying_material();
54void ChaCha20Poly1305_Mode::key_schedule(std::span<const uint8_t> key) {
62 BOTAN_ARG_CHECK(idx == 0,
"ChaCha20Poly1305: cannot handle non-zero index in set_associated_data_n");
64 throw Invalid_State(
"Cannot set AD for ChaCha20Poly1305 while processing a message");
66 m_ad.assign(ad.begin(), ad.end());
70 uint8_t len8[8] = {0};
75void ChaCha20Poly1305_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len) {
87 uint8_t first_block[64];
88 m_chacha->write_keystream(first_block,
sizeof(first_block));
97 if(
m_ad.size() % 16 != 0) {
98 const uint8_t zeros[16] = {0};
110size_t ChaCha20Poly1305_Encryption::process_msg(uint8_t buf[],
size_t sz) {
117 constexpr uint64_t MAX_CHACHA20POLY1305_INPUT = (
static_cast<uint64_t
>(1) << 38) - 64;
119 throw Invalid_State(
"ChaCha20Poly1305 message length limit exceeded");
131 const uint8_t zeros[16] = {0};
132 const size_t padding =
static_cast<size_t>(16 -
m_ctext_len % 16);
140 if(!new_size.has_value()) {
141 throw Invalid_State(
"ChaCha20Poly1305 message length limit exceeded");
143 buffer.resize(new_size.value());
154size_t ChaCha20Poly1305_Decryption::process_msg(uint8_t buf[],
size_t sz) {
160 constexpr uint64_t MAX_CHACHA20POLY1305_INPUT = (
static_cast<uint64_t
>(1) << 38) - 64;
162 throw Invalid_State(
"ChaCha20Poly1305 message length limit exceeded");
171 const size_t sz = buffer.size() - offset;
172 uint8_t* buf = buffer.data() + offset;
176 const size_t remaining = sz -
tag_size();
181 process_msg(buf, remaining);
186 const uint8_t zeros[16] = {0};
187 const size_t padding =
static_cast<size_t>(16 -
m_ctext_len % 16);
198 const uint8_t* included_tag = &buf[remaining];
204 clear_mem(std::span{buffer}.subspan(offset, remaining));
205 throw Invalid_Authentication_Tag(
"ChaCha20Poly1305 tag check failed");
207 buffer.resize(offset + remaining);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
static std::unique_ptr< AEAD_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
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 update_len(uint64_t len)
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) final
bool valid_nonce_length(size_t n) const override
secure_vector< uint8_t > m_ad
size_t ideal_granularity() const override
std::string name() const override
std::unique_ptr< StreamCipher > m_chacha
size_t update_granularity() const override
bool cfrg_version() const
size_t tag_size() const override
std::unique_ptr< MessageAuthenticationCode > m_poly1305
void update(T &buffer, size_t offset=0)
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
constexpr T add_or_throw(T a, T b, std::string_view msg)
constexpr std::optional< T > checked_add(T a, T b)
void secure_scrub_memory(void *ptr, size_t n)
constexpr auto store_le(ParamTs &&... params)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void clear_mem(T *ptr, size_t n)