10#include <botan/ghash.h>
11#include <botan/block_cipher.h>
22 m_ctr(new
CTR_BE(cipher, 4)),
30 if(
m_tag_size != 8 && (m_tag_size < 12 || m_tag_size > 16))
60 return GCM_BS * std::max<size_t>(2, BOTAN_BLOCK_CIPHER_PAR_MULT);
71 return m_ctr->key_spec();
74void GCM_Mode::key_schedule(
const uint8_t key[],
size_t keylen)
76 m_ctr->set_key(key, keylen);
78 const std::vector<uint8_t> zeros(
GCM_BS);
79 m_ctr->set_iv(zeros.data(), zeros.size());
88 m_ghash->set_associated_data(ad, ad_len);
91void GCM_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
103 copy_mem(m_y0.data(), nonce, nonce_len);
108 m_ghash->nonce_hash(m_y0, nonce, nonce_len);
111 m_ctr->set_iv(m_y0.data(), m_y0.size());
114 m_ctr->encipher(m_y0);
116 m_ghash->start(m_y0.data(), m_y0.size());
123 m_ctr->cipher(buf, buf, sz);
131 const size_t sz = buffer.size() - offset;
132 uint8_t* buf = buffer.data() + offset;
134 m_ctr->cipher(buf, buf, sz);
137 uint8_t mac[16] = { 0 };
139 buffer += std::make_pair(mac,
tag_size());
146 m_ctr->cipher(buf, buf, sz);
153 const size_t sz = buffer.size() - offset;
154 uint8_t* buf = buffer.data() + offset;
157 throw Decoding_Error(
"Insufficient input for GCM decryption, tag missing");
159 const size_t remaining = sz -
tag_size();
164 m_ghash->update(buf, remaining);
165 m_ctr->cipher(buf, buf, remaining);
168 uint8_t mac[16] = { 0 };
171 const uint8_t* included_tag = &buffer[remaining+offset];
176 buffer.resize(offset + remaining);
#define BOTAN_ARG_CHECK(expr, msg)
virtual size_t block_size() const =0
size_t process(uint8_t buf[], size_t size) override
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
size_t process(uint8_t buf[], size_t size) override
static const size_t GCM_BS
std::string name() const override
std::unique_ptr< GHASH > m_ghash
GCM_Mode(BlockCipher *cipher, size_t tag_size)
std::string provider() const override
const std::string m_cipher_name
Key_Length_Specification key_spec() const override
size_t update_granularity() const override
void set_associated_data(const uint8_t ad[], size_t ad_len) override
std::unique_ptr< StreamCipher > m_ctr
size_t tag_size() const override
bool valid_nonce_length(size_t len) const override
std::string m_cipher_name
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
void clear_mem(T *ptr, size_t n)