Botan  2.1.0
Crypto and TLS for C++11
gmac.cpp
Go to the documentation of this file.
1 /*
2  * GMAC
3  * (C) 2016 Matthias Gierlings, RenĂ© Korthaus
4  *
5  * Botan is released under the Simplified BSD License (see license.txt)
6  */
7 
8 #include <botan/gmac.h>
9 
10 namespace Botan {
11 
13  : GHASH(),
14  m_aad_buf(),
15  m_cipher(cipher),
16  m_initialized(false)
17  {}
18 
20  {
21  GHASH::clear();
22  m_H.resize(GCM_BS);
23  m_H_ad.resize(GCM_BS);
24  m_ghash.resize(GCM_BS);
25  m_cipher->clear();
26  m_aad_buf.clear();
27  m_initialized = false;
28  }
29 
30 std::string GMAC::name() const
31  {
32  return "GMAC(" + m_cipher->name() + ")";
33  }
34 
35 size_t GMAC::output_length() const
36  {
37  return GCM_BS;
38  }
39 
40 void GMAC::add_data(const uint8_t input[], size_t size)
41  {
42  m_ad_len += size;
43 
44  // buffer partial blocks till we received a full input block
45  // or final is called.
46  m_aad_buf.insert(m_aad_buf.end(), input, input + size);
47  if(m_aad_buf.size() >= GCM_BS)
48  {
49  // process all complete input blocks.
51  m_aad_buf.data(),
52  m_aad_buf.size() - (m_aad_buf.size() % GCM_BS));
53 
54  // remove all processed blocks from buffer.
55  m_aad_buf.erase(m_aad_buf.begin(),
56  m_aad_buf.end() - (m_aad_buf.size() % GCM_BS));
57  }
58  }
59 
60 void GMAC::key_schedule(const uint8_t key[], size_t size)
61  {
62  clear();
63  m_cipher->set_key(key, size);
64  m_cipher->encrypt(m_H_ad.data(), m_H.data());
65  }
66 
67 void GMAC::start_msg(const uint8_t nonce[], size_t nonce_len)
68  {
69  secure_vector<uint8_t> y0(GCM_BS);
70 
71  if(nonce_len == 12)
72  {
73  copy_mem(y0.data(), nonce, nonce_len);
74  y0[GCM_BS - 1] = 1;
75  }
76  else
77  {
78  ghash_update(y0, nonce, nonce_len);
79  add_final_block(y0, 0, nonce_len);
80  }
81 
82  secure_vector<uint8_t> m_enc_y0(GCM_BS);
83  m_cipher->encrypt(y0.data(), m_enc_y0.data());
84  GHASH::start(m_enc_y0.data(), m_enc_y0.size());
85  m_initialized = true;
86  }
87 
88 void GMAC::final_result(uint8_t mac[])
89  {
90  // This ensures the GMAC computation has been initialized with a fresh
91  // nonce. The aim of this check is to prevent developers from re-using
92  // nonces (and potential nonce-reuse attacks).
93  BOTAN_ASSERT(m_initialized,
94  "The GMAC computation has not been initialized with a fresh "
95  "nonce.");
96  // process the rest of the aad buffer. Even if it is a partial block only
97  // ghash_update will process it properly.
98  if(m_aad_buf.size() > 0)
99  {
101  m_aad_buf.data(),
102  m_aad_buf.size());
103  }
104  secure_vector<uint8_t> result = GHASH::final();
105  std::copy(result.begin(), result.end(), mac);
106  clear();
107  }
108 
110  {
111  return new GMAC(m_cipher->clone());
112  }
113 }
secure_vector< uint8_t > m_H
Definition: gcm.h:144
secure_vector< uint8_t > m_ghash
Definition: gcm.h:146
void start(const uint8_t nonce[], size_t len)
Definition: gcm.cpp:97
void add_final_block(secure_vector< uint8_t > &x, size_t ad_len, size_t pt_len)
Definition: gcm.cpp:120
void ghash_update(secure_vector< uint8_t > &x, const uint8_t input[], size_t input_len)
Definition: gcm.cpp:69
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
void clear() override
Definition: gmac.cpp:19
secure_vector< uint8_t > m_H_ad
Definition: gcm.h:145
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Definition: alg_id.cpp:13
void clear() override
Definition: gcm.cpp:151
size_t m_ad_len
Definition: gcm.h:147
GMAC(BlockCipher *cipher)
Definition: gmac.cpp:12
MessageAuthenticationCode * clone() const override
Definition: gmac.cpp:109
secure_vector< uint8_t > final()
Definition: gcm.cpp:128
std::string name() const override
Definition: gmac.cpp:30
size_t output_length() const override
Definition: gmac.cpp:35