10#include <botan/ghash.h>
11#include <botan/exceptn.h>
12#include <botan/block_cipher.h>
31 m_initialized =
false;
38 return m_cipher->key_spec();
43 return "GMAC(" + m_cipher->name() +
")";
51void GMAC::add_data(
const uint8_t input[],
size_t size)
55 const size_t taking = std::min(GCM_BS - m_aad_buf_pos, size);
56 copy_mem(&m_aad_buf[m_aad_buf_pos], input, taking);
57 m_aad_buf_pos += taking;
61 if(m_aad_buf_pos == GCM_BS)
63 m_ghash->update_associated_data(m_aad_buf.data(), GCM_BS);
68 const size_t left_over = size % GCM_BS;
69 const size_t full_blocks = size - left_over;
70 m_ghash->update_associated_data(input, full_blocks);
75 copy_mem(&m_aad_buf[m_aad_buf_pos], input, left_over);
76 m_aad_buf_pos += left_over;
80void GMAC::key_schedule(
const uint8_t key[],
size_t size)
83 m_cipher->set_key(key, size);
85 secure_vector<uint8_t> H(GCM_BS);
90void GMAC::start_msg(
const uint8_t nonce[],
size_t nonce_len)
92 secure_vector<uint8_t> y0(GCM_BS);
96 copy_mem(y0.data(), nonce, nonce_len);
101 m_ghash->ghash_update(y0, nonce, nonce_len);
102 m_ghash->add_final_block(y0, 0, nonce_len);
105 secure_vector<uint8_t> m_enc_y0(GCM_BS);
106 m_cipher->encrypt(y0.data(), m_enc_y0.data());
107 m_ghash->start(m_enc_y0.data(), m_enc_y0.size());
108 m_initialized =
true;
111void GMAC::final_result(uint8_t mac[])
116 if(m_initialized ==
false)
117 throw Invalid_State(
"GMAC was not used with a fresh nonce");
121 if(m_aad_buf_pos > 0)
123 m_ghash->update_associated_data(m_aad_buf.data(), m_aad_buf_pos);
132 return new GMAC(m_cipher->clone());
MessageAuthenticationCode * clone() const override
std::string name() const override
Key_Length_Specification key_spec() const override
GMAC(BlockCipher *cipher)
size_t output_length() const override
void zeroise(std::vector< T, Alloc > &vec)
void copy_mem(T *out, const T *in, size_t n)