Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

eax.cpp
Go to the documentation of this file.
1 /*
2 * EAX Mode Encryption
3 * (C) 1999-2007 Jack Lloyd
4 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/eax.h>
10 #include <botan/cmac.h>
11 #include <botan/ctr.h>
12 #include <botan/parsing.h>
13
14 namespace Botan {
15
16 namespace {
17
18 /*
19 * EAX MAC-based PRF
20 */
21 secure_vector<uint8_t> eax_prf(uint8_t tag, size_t block_size,
22 MessageAuthenticationCode& mac,
23 const uint8_t in[], size_t length)
24 {
25 for(size_t i = 0; i != block_size - 1; ++i)
26 {
27 mac.update(0);
28 }
29 mac.update(tag);
30 mac.update(in, length);
31 return mac.final();
32 }
33
34 }
35
36 /*
37 * EAX_Mode Constructor
38 */
39 EAX_Mode::EAX_Mode(BlockCipher* cipher, size_t tag_size) :
40 m_tag_size(tag_size ? tag_size : cipher->block_size()),
41 m_cipher(cipher),
42 m_ctr(new CTR_BE(m_cipher->clone())),
43 m_cmac(new CMAC(m_cipher->clone()))
44 {
45 if(m_tag_size < 8 || m_tag_size > m_cmac->output_length())
46 throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(tag_size));
47 }
48
49 void EAX_Mode::clear()
50 {
51 m_cipher->clear();
52 m_ctr->clear();
53 m_cmac->clear();
54 reset();
55 }
56
57 void EAX_Mode::reset()
58 {
59 m_ad_mac.clear();
60 m_nonce_mac.clear();
61 }
62
63 std::string EAX_Mode::name() const
64 {
65 return (m_cipher->name() + "/EAX");
66 }
67
68 size_t EAX_Mode::update_granularity() const
69 {
70 return 1;
71 }
72
73 Key_Length_Specification EAX_Mode::key_spec() const
74 {
75 return m_cipher->key_spec();
76 }
77
78 /*
79 * Set the EAX key
80 */
81 void EAX_Mode::key_schedule(const uint8_t key[], size_t length)
82 {
83 /*
84 * These could share the key schedule, which is one nice part of EAX,
85 * but it's much easier to ignore that here...
86 */
87 m_ctr->set_key(key, length);
88 m_cmac->set_key(key, length);
89 }
90
91 /*
92 * Set the EAX associated data
93 */
94 void EAX_Mode::set_associated_data(const uint8_t ad[], size_t length)
95 {
96 m_ad_mac = eax_prf(1, block_size(), *m_cmac, ad, length);
97 }
98
99 void EAX_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
100 {
101 if(!valid_nonce_length(nonce_len))
102 throw Invalid_IV_Length(name(), nonce_len);
103
104 m_nonce_mac = eax_prf(0, block_size(), *m_cmac, nonce, nonce_len);
105
106 m_ctr->set_iv(m_nonce_mac.data(), m_nonce_mac.size());
107
108 for(size_t i = 0; i != block_size() - 1; ++i)
109 m_cmac->update(0);
110 m_cmac->update(2);
111 }
112
113 size_t EAX_Encryption::process(uint8_t buf[], size_t sz)
114 {
115 m_ctr->cipher(buf, buf, sz);
116 m_cmac->update(buf, sz);
117 return sz;
118 }
119
120 void EAX_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
121 {
122 update(buffer, offset);
123
124 secure_vector<uint8_t> data_mac = m_cmac->final();
125 xor_buf(data_mac, m_nonce_mac, data_mac.size());
126
127 if(m_ad_mac.empty())
128 {
129 m_ad_mac = eax_prf(1, block_size(), *m_cmac, nullptr, 0);
130 }
131
132 xor_buf(data_mac, m_ad_mac, data_mac.size());
133
134 buffer += std::make_pair(data_mac.data(), tag_size());
135 }
136
137 size_t EAX_Decryption::process(uint8_t buf[], size_t sz)
138 {
139 m_cmac->update(buf, sz);
140 m_ctr->cipher(buf, buf, sz);
141 return sz;
142 }
143
144 void EAX_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
145 {
146 BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
147 const size_t sz = buffer.size() - offset;
148 uint8_t* buf = buffer.data() + offset;
149
150 BOTAN_ASSERT(sz >= tag_size(), "Have the tag as part of final input");
151
152 const size_t remaining = sz - tag_size();
153
154 if(remaining)
155 {
156 m_cmac->update(buf, remaining);
157 m_ctr->cipher(buf, buf, remaining);
158 }
159
160 const uint8_t* included_tag = &buf[remaining];
161
162 secure_vector<uint8_t> mac = m_cmac->final();
163 mac ^= m_nonce_mac;
164
165 if(m_ad_mac.empty())
166 {
167 m_ad_mac = eax_prf(1, block_size(), *m_cmac, nullptr, 0);
168 }
169
170 mac ^= m_ad_mac;
171
172 if(!same_mem(mac.data(), included_tag, tag_size()))
173 throw Integrity_Failure("EAX tag check failed");
174
175 buffer.resize(offset + remaining);
176 }
177
178 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::EAX_Decryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: eax.cpp:144
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::EAX_Mode::key_spec
Key_Length_Specification key_spec() const override
Definition: eax.cpp:73
Botan::EAX_Encryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: eax.cpp:113
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
Botan::EAX_Mode::name
std::string name() const override
Definition: eax.cpp:63
Botan::EAX_Mode::clear
void clear() override
Definition: eax.cpp:49
Botan::Integrity_Failure
Definition: exceptn.h:198
Botan::Cipher_Mode::update
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
Definition: cipher_mode.h:81
Botan::Key_Length_Specification
Definition: key_spec.h:18
Botan::CTR_BE
Definition: ctr.h:19
Botan::EAX_Mode::m_ad_mac
secure_vector< uint8_t > m_ad_mac
Definition: eax.h:57
Botan::EAX_Mode::m_nonce_mac
secure_vector< uint8_t > m_nonce_mac
Definition: eax.h:59
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::Invalid_IV_Length
Definition: exceptn.h:109
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::EAX_Mode::valid_nonce_length
bool valid_nonce_length(size_t) const override
Definition: eax.h:34
Botan::EAX_Mode::EAX_Mode
EAX_Mode(BlockCipher *cipher, size_t tag_size)
Definition: eax.cpp:39
Botan::EAX_Decryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: eax.cpp:137
Botan
Definition: alg_id.cpp:13
Botan::EAX_Mode::block_size
size_t block_size() const
Definition: eax.h:49
Botan::EAX_Mode::m_cipher
std::unique_ptr< BlockCipher > m_cipher
Definition: eax.h:53
Botan::CMAC
Definition: cmac.h:19
Botan::EAX_Mode::tag_size
size_t tag_size() const override
Definition: eax.h:36
Botan::EAX_Mode::reset
void reset() override
Definition: eax.cpp:57
Botan::EAX_Mode::m_cmac
std::unique_ptr< MessageAuthenticationCode > m_cmac
Definition: eax.h:55
Botan::EAX_Mode::update_granularity
size_t update_granularity() const override
Definition: eax.cpp:68
Botan::EAX_Mode::set_associated_data
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: eax.cpp:94
Botan::EAX_Mode::m_ctr
std::unique_ptr< StreamCipher > m_ctr
Definition: eax.h:54
Botan::EAX_Encryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: eax.cpp:120
Botan::BlockCipher
Definition: block_cipher.h:19