9#include <botan/internal/gcm.h>
10#include <botan/internal/ghash.h>
11#include <botan/block_cipher.h>
12#include <botan/internal/ctr.h>
13#include <botan/internal/fmt.h>
24 if(cipher->block_size() !=
GCM_BS)
29 if(
m_tag_size != 8 && (m_tag_size < 12 || m_tag_size > 16))
34 m_ctr = std::make_unique<CTR_BE>(std::move(cipher), 4);
35 m_ghash = std::make_unique<GHASH>();
80 return m_ctr->key_spec();
85 return m_ctr->has_keying_material();
88void GCM_Mode::key_schedule(
const uint8_t key[],
size_t keylen)
90 m_ctr->set_key(key, keylen);
92 const std::vector<uint8_t> zeros(
GCM_BS);
93 m_ctr->set_iv(zeros.data(), zeros.size());
102 BOTAN_ARG_CHECK(idx == 0,
"GCM: cannot handle non-zero index in set_associated_data_n");
103 m_ghash->set_associated_data(ad.data(), ad.size());
106void GCM_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
118 copy_mem(m_y0.data(), nonce, nonce_len);
123 m_ghash->nonce_hash(m_y0, nonce, nonce_len);
126 m_ctr->set_iv(m_y0.data(), m_y0.size());
129 m_ctr->encipher(m_y0);
131 m_ghash->start(m_y0.data(), m_y0.size());
135size_t GCM_Encryption::process_msg(uint8_t buf[],
size_t sz)
138 m_ctr->cipher(buf, buf, sz);
143void GCM_Encryption::finish_msg(secure_vector<uint8_t>& buffer,
size_t offset)
146 const size_t sz = buffer.size() - offset;
147 uint8_t* buf = buffer.data() + offset;
149 m_ctr->cipher(buf, buf, sz);
152 uint8_t mac[16] = { 0 };
154 buffer += std::make_pair(mac,
tag_size());
157size_t GCM_Decryption::process_msg(uint8_t buf[],
size_t sz)
161 m_ctr->cipher(buf, buf, sz);
165void GCM_Decryption::finish_msg(secure_vector<uint8_t>& buffer,
size_t offset)
168 const size_t sz = buffer.size() - offset;
169 uint8_t* buf = buffer.data() + offset;
173 const size_t remaining = sz -
tag_size();
178 m_ghash->update(buf, remaining);
179 m_ctr->cipher(buf, buf, remaining);
182 uint8_t mac[16] = { 0 };
185 const uint8_t* included_tag = &buffer[remaining+offset];
188 throw Invalid_Authentication_Tag(
"GCM tag check failed");
190 buffer.resize(offset + remaining);
#define BOTAN_ARG_CHECK(expr, msg)
static const size_t GCM_BS
std::unique_ptr< GHASH > m_ghash
size_t tag_size() const override final
std::string provider() const override final
size_t update_granularity() const override final
Key_Length_Specification key_spec() const override final
GCM_Mode(std::unique_ptr< BlockCipher > cipher, size_t tag_size)
const std::string m_cipher_name
bool has_keying_material() const override final
void clear() override final
void reset() override final
size_t ideal_granularity() const override final
std::unique_ptr< StreamCipher > m_ctr
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) override final
std::string name() const override final
bool valid_nonce_length(size_t len) const override final
std::string m_cipher_name
#define BOTAN_BLOCK_CIPHER_PAR_MULT
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void clear_mem(T *ptr, size_t n)