Botan 2.19.5 Crypto and TLS for C&

gmac.cpp
Go to the documentation of this file.
1/*
2 * GMAC
3 * (C) 2016 Matthias Gierlings, René Korthaus
4 * (C) 2017 Jack Lloyd
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9#include <botan/gmac.h>
10#include <botan/ghash.h>
11#include <botan/exceptn.h>
12#include <botan/block_cipher.h>
13
14 namespace Botan {
15
16 GMAC::GMAC(BlockCipher* cipher) :
17 m_cipher(cipher),
18 m_ghash(new GHASH),
19 m_aad_buf(GCM_BS),
20 m_aad_buf_pos(0),
21 m_initialized(false)
22 {
23 }
24
25 void GMAC::clear()
26 {
27 m_cipher->clear();
28 m_ghash->clear();
29 zeroise(m_aad_buf);
30 m_aad_buf_pos = 0;
31 m_initialized = false;
32 }
33
34 GMAC::~GMAC() { /* for unique_ptr */ }
35
36 Key_Length_Specification GMAC::key_spec() const
37 {
38 return m_cipher->key_spec();
39 }
40
41std::string GMAC::name() const
42 {
43 return "GMAC(" + m_cipher->name() + ")";
44 }
45
46 size_t GMAC::output_length() const
47 {
48 return GCM_BS;
49 }
50
51 void GMAC::add_data(const uint8_t input[], size_t size)
52 {
53 if(m_aad_buf_pos > 0)
54 {
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;
58 input += taking;
59 size -= taking;
60
61 if(m_aad_buf_pos == GCM_BS)
62 {
63 m_ghash->update_associated_data(m_aad_buf.data(), GCM_BS);
64 m_aad_buf_pos = 0;
65 }
66 }
67
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);
71 input += full_blocks;
72
73 if(left_over > 0)
74 {
75 copy_mem(&m_aad_buf[m_aad_buf_pos], input, left_over);
76 m_aad_buf_pos += left_over;
77 }
78 }
79
80 void GMAC::key_schedule(const uint8_t key[], size_t size)
81 {
82 clear();
83 m_cipher->set_key(key, size);
84
85 secure_vector<uint8_t> H(GCM_BS);
86 m_cipher->encrypt(H);
87 m_ghash->set_key(H);
88 }
89
90 void GMAC::start_msg(const uint8_t nonce[], size_t nonce_len)
91 {
92 secure_vector<uint8_t> y0(GCM_BS);
93
94 if(nonce_len == 12)
95 {
96 copy_mem(y0.data(), nonce, nonce_len);
97 y0[GCM_BS - 1] = 1;
98 }
99 else
100 {
101 m_ghash->ghash_update(y0, nonce, nonce_len);
102 m_ghash->add_final_block(y0, 0, nonce_len);
103 }
104
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;
109 }
110
111 void GMAC::final_result(uint8_t mac[])
112 {
113 // This ensures the GMAC computation has been initialized with a fresh
114 // nonce. The aim of this check is to prevent developers from re-using
115 // nonces (and potential nonce-reuse attacks).
116 if(m_initialized == false)
117 throw Invalid_State("GMAC was not used with a fresh nonce");
118
119 // process the rest of the aad buffer. Even if it is a partial block only
120 // ghash_update will process it properly.
121 if(m_aad_buf_pos > 0)
122 {
123 m_ghash->update_associated_data(m_aad_buf.data(), m_aad_buf_pos);
124 }
125
126 m_ghash->final(mac, output_length());
127 clear();
128 }
129
130 MessageAuthenticationCode* GMAC::clone() const
131 {
132 return new GMAC(m_cipher->clone());
133 }
134}
Botan::BlockCipher
Definition: block_cipher.h:22
Botan::GHASH
Definition: ghash.h:23
Botan::GMAC::clone
MessageAuthenticationCode * clone() const override
Definition: gmac.cpp:130
Botan::GMAC::name
std::string name() const override
Definition: gmac.cpp:41
Botan::GMAC::key_spec
Key_Length_Specification key_spec() const override
Definition: gmac.cpp:36
Botan::GMAC::GMAC
GMAC(BlockCipher *cipher)
Definition: gmac.cpp:16
Botan::GMAC::clear
void clear() override
Definition: gmac.cpp:25
Botan::GMAC::output_length
size_t output_length() const override
Definition: gmac.cpp:46
Botan::GMAC::~GMAC
~GMAC()
Definition: gmac.cpp:34
Botan::Key_Length_Specification
Definition: sym_algo.h:20
Botan::MessageAuthenticationCode
Definition: mac.h:23
Botan
Definition: alg_id.cpp:13
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:114
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133