Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tls_cbc.cpp
Go to the documentation of this file.
1 /*
2 * TLS CBC Record Handling
3 * (C) 2012,2013,2014,2015,2016 Jack Lloyd
4 * (C) 2016 Juraj Somorovsky
5 * (C) 2016 Matthias Gierlings
6 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 */
10
11 #include <botan/internal/tls_cbc.h>
12 #include <botan/internal/rounding.h>
13 #include <botan/internal/ct_utils.h>
14 #include <botan/tls_alert.h>
15 #include <botan/tls_magic.h>
16 #include <botan/tls_exceptn.h>
17
18 namespace Botan {
19
20 namespace TLS {
21
22 /*
23 * TLS_CBC_HMAC_AEAD_Mode Constructor
24 */
25 TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode(const std::string& cipher_name,
26 size_t cipher_keylen,
27 const std::string& mac_name,
28 size_t mac_keylen,
29 bool use_explicit_iv,
30 bool use_encrypt_then_mac) :
31 m_cipher_name(cipher_name),
32 m_mac_name(mac_name),
33 m_cipher_keylen(cipher_keylen),
34 m_mac_keylen(mac_keylen),
35 m_use_encrypt_then_mac(use_encrypt_then_mac)
36 {
37 m_cipher = BlockCipher::create_or_throw(m_cipher_name);
38 m_mac = MessageAuthenticationCode::create_or_throw("HMAC(" + m_mac_name + ")");
39
40 m_tag_size = m_mac->output_length();
41 m_block_size = m_cipher->block_size();
42
43 m_iv_size = use_explicit_iv ? m_block_size : 0;
44 }
45
46 void TLS_CBC_HMAC_AEAD_Mode::clear()
47 {
48 cipher().clear();
49 mac().clear();
50 reset();
51 }
52
53 void TLS_CBC_HMAC_AEAD_Mode::reset()
54 {
55 cbc_state().clear();
56 m_ad.clear();
57 m_msg.clear();
58 }
59
60 std::string TLS_CBC_HMAC_AEAD_Mode::name() const
61 {
62 return "TLS_CBC(" + m_cipher_name + "," + m_mac_name + ")";
63 }
64
65 size_t TLS_CBC_HMAC_AEAD_Mode::update_granularity() const
66 {
67 return 1; // just buffers anyway
68 }
69
70 bool TLS_CBC_HMAC_AEAD_Mode::valid_nonce_length(size_t nl) const
71 {
72 if(m_cbc_state.empty())
73 return nl == block_size();
74 return nl == iv_size();
75 }
76
77 Key_Length_Specification TLS_CBC_HMAC_AEAD_Mode::key_spec() const
78 {
79 return Key_Length_Specification(m_cipher_keylen + m_mac_keylen);
80 }
81
82 void TLS_CBC_HMAC_AEAD_Mode::key_schedule(const uint8_t key[], size_t keylen)
83 {
84 // Both keys are of fixed length specified by the ciphersuite
85
86 if(keylen != m_cipher_keylen + m_mac_keylen)
87 throw Invalid_Key_Length(name(), keylen);
88
89 cipher().set_key(&key[0], m_cipher_keylen);
90 mac().set_key(&key[m_cipher_keylen], m_mac_keylen);
91 }
92
93 void TLS_CBC_HMAC_AEAD_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
94 {
95 if(!valid_nonce_length(nonce_len))
96 {
97 throw Invalid_IV_Length(name(), nonce_len);
98 }
99
100 m_msg.clear();
101
102 if(nonce_len > 0)
103 {
104 m_cbc_state.assign(nonce, nonce + nonce_len);
105 }
106 }
107
108 size_t TLS_CBC_HMAC_AEAD_Mode::process(uint8_t buf[], size_t sz)
109 {
110 m_msg.insert(m_msg.end(), buf, buf + sz);
111 return 0;
112 }
113
114 std::vector<uint8_t> TLS_CBC_HMAC_AEAD_Mode::assoc_data_with_len(uint16_t len)
115 {
116 std::vector<uint8_t> ad = m_ad;
117 BOTAN_ASSERT(ad.size() == 13, "Expected AAD size");
118 ad[11] = get_byte(0, len);
119 ad[12] = get_byte(1, len);
120 return ad;
121 }
122
123 void TLS_CBC_HMAC_AEAD_Mode::set_associated_data(const uint8_t ad[], size_t ad_len)
124 {
125 if(ad_len != 13)
126 throw Exception("Invalid TLS AEAD associated data length");
127 m_ad.assign(ad, ad + ad_len);
128 }
129
130 void TLS_CBC_HMAC_AEAD_Encryption::set_associated_data(const uint8_t ad[], size_t ad_len)
131 {
132 TLS_CBC_HMAC_AEAD_Mode::set_associated_data(ad, ad_len);
133
134 if(use_encrypt_then_mac())
135 {
136 // AAD hack for EtM
137 size_t pt_size = make_uint16(assoc_data()[11], assoc_data()[12]);
138 size_t enc_size = round_up(iv_size() + pt_size + 1, block_size());
139 assoc_data()[11] = get_byte<uint16_t>(0, enc_size);
140 assoc_data()[12] = get_byte<uint16_t>(1, enc_size);
141 }
142 }
143
144 void TLS_CBC_HMAC_AEAD_Encryption::cbc_encrypt_record(uint8_t buf[], size_t buf_size)
145 {
146 const size_t blocks = buf_size / block_size();
147 BOTAN_ASSERT(buf_size % block_size() == 0, "Valid CBC input");
148
149 xor_buf(buf, cbc_state().data(), block_size());
150 cipher().encrypt(buf);
151
152 for(size_t i = 1; i < blocks; ++i)
153 {
154 xor_buf(&buf[block_size()*i], &buf[block_size()*(i-1)], block_size());
155 cipher().encrypt(&buf[block_size()*i]);
156 }
157
158 cbc_state().assign(&buf[block_size()*(blocks-1)],
159 &buf[block_size()*blocks]);
160 }
161
162 size_t TLS_CBC_HMAC_AEAD_Encryption::output_length(size_t input_length) const
163 {
164 return round_up(input_length + 1 + (use_encrypt_then_mac() ? 0 : tag_size()), block_size()) +
165 (use_encrypt_then_mac() ? tag_size() : 0);
166 }
167
168 void TLS_CBC_HMAC_AEAD_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
169 {
170 update(buffer, offset);
171 buffer.resize(offset); // truncate, leaving just header
172 const size_t header_size = offset;
173
174 buffer.insert(buffer.end(), msg().begin(), msg().end());
175
176 const size_t input_size = msg().size() + 1 + (use_encrypt_then_mac() ? 0 : tag_size());
177 const size_t enc_size = round_up(input_size, block_size());
178 const size_t pad_val = enc_size - input_size;
179 const size_t buf_size = enc_size + (use_encrypt_then_mac() ? tag_size() : 0);
180
181 BOTAN_ASSERT(enc_size % block_size() == 0,
182 "Buffer is an even multiple of block size");
183
184 mac().update(assoc_data());
185
186 if(use_encrypt_then_mac())
187 {
188 if(iv_size() > 0)
189 {
190 mac().update(cbc_state());
191 }
192
193 for(size_t i = 0; i != pad_val + 1; ++i)
194 buffer.push_back(static_cast<uint8_t>(pad_val));
195 cbc_encrypt_record(&buffer[header_size], enc_size);
196 }
197
198 // EtM also uses ciphertext size instead of plaintext size for AEAD input
199 const uint8_t* mac_input = (use_encrypt_then_mac() ? &buffer[header_size] : msg().data());
200 const size_t mac_input_len = (use_encrypt_then_mac() ? enc_size : msg().size());
201
202 mac().update(mac_input, mac_input_len);
203
204 buffer.resize(buffer.size() + tag_size());
205 mac().final(&buffer[buffer.size() - tag_size()]);
206
207 if(use_encrypt_then_mac() == false)
208 {
209 for(size_t i = 0; i != pad_val + 1; ++i)
210 buffer.push_back(static_cast<uint8_t>(pad_val));
211 cbc_encrypt_record(&buffer[header_size], buf_size);
212 }
213 }
214
215 namespace {
216
217
218 /*
219 * Checks the TLS padding. Returns 0 if the padding is invalid (we
220 * count the padding_length field as part of the padding size so a
221 * valid padding will always be at least one byte long), or the length
222 * of the padding otherwise. This is actually padding_length + 1
223 * because both the padding and padding_length fields are padding from
224 * our perspective.
225 *
226 * Returning 0 in the error case should ensure the MAC check will fail.
227 * This approach is suggested in section 6.2.3.2 of RFC 5246.
228 */
229 uint16_t check_tls_padding(const uint8_t record[], size_t record_len)
230 {
231 /*
232 * TLS v1.0 and up require all the padding bytes be the same value
233 * and allows up to 255 bytes.
234 */
235
236 const uint8_t pad_byte = record[(record_len-1)];
237
238 uint8_t pad_invalid = 0;
239 for(size_t i = 0; i != record_len; ++i)
240 {
241 const size_t left = record_len - i - 2;
242 const uint8_t delim_mask = CT::is_less<uint16_t>(static_cast<uint16_t>(left), pad_byte) & 0xFF;
243 pad_invalid |= (delim_mask & (record[i] ^ pad_byte));
244 }
245
246 uint16_t pad_invalid_mask = CT::expand_mask<uint16_t>(pad_invalid);
247 return CT::select<uint16_t>(pad_invalid_mask, 0, pad_byte + 1);
248 }
249
250 }
251
252 void TLS_CBC_HMAC_AEAD_Decryption::cbc_decrypt_record(uint8_t record_contents[], size_t record_len)
253 {
254 BOTAN_ASSERT(record_len % block_size() == 0,
255 "Buffer is an even multiple of block size");
256
257 const size_t blocks = record_len / block_size();
258
259 BOTAN_ASSERT(blocks >= 1, "At least one ciphertext block");
260
261 uint8_t* buf = record_contents;
262
263 secure_vector<uint8_t> last_ciphertext(block_size());
264 copy_mem(last_ciphertext.data(), buf, block_size());
265
266 cipher().decrypt(buf);
267 xor_buf(buf, cbc_state().data(), block_size());
268
269 secure_vector<uint8_t> last_ciphertext2;
270
271 for(size_t i = 1; i < blocks; ++i)
272 {
273 last_ciphertext2.assign(&buf[block_size()*i], &buf[block_size()*(i+1)]);
274 cipher().decrypt(&buf[block_size()*i]);
275 xor_buf(&buf[block_size()*i], last_ciphertext.data(), block_size());
276 std::swap(last_ciphertext, last_ciphertext2);
277 }
278
279 cbc_state().assign(last_ciphertext.begin(), last_ciphertext.end());
280 }
281
282 size_t TLS_CBC_HMAC_AEAD_Decryption::output_length(size_t) const
283 {
284 /*
285 * We don't know this because the padding is arbitrary
286 */
287 return 0;
288 }
289
290 /*
291 * This function performs additional compression calls in order
292 * to protect from the Lucky 13 attack. It adds new compression
293 * function calls over dummy data, by computing additional HMAC updates.
294 *
295 * The countermeasure was described (in a similar way) in the Lucky 13 paper.
296 *
297 * Background:
298 * - One SHA-1/SHA-256 compression is performed with 64 bytes of data.
299 * - HMAC adds 8 byte length field and padding (at least 1 byte) so that we have:
300 * - 0 - 55 bytes: 1 compression
301 * - 56 - 55+64 bytes: 2 compressions
302 * - 56+64 - 55+2*64 bytes: 3 compressions ...
303 * - For SHA-384, this works similarly, but we have 128 byte blocks and 16 byte
304 * long length field. This results in:
305 * - 0 - 111 bytes: 1 compression
306 * - 112 - 111+128 bytes: 2 compressions ...
307 *
308 * The implemented countermeasure works as follows:
309 * 1) It computes max_compressions: number of maximum compressions performed on
310 * the decrypted data
311 * 2) It computes current_compressions: number of compressions performed on the
312 * decrypted data, after padding has been removed
313 * 3) If current_compressions != max_compressions: It invokes an HMAC update
314 * over dummy data so that (max_compressions - current_compressions)
315 * compressions are performed. Otherwise, it invokes an HMAC update so that
316 * no compressions are performed.
317 *
318 * Note that the padding validation in Botan is always performed over
319 * min(plen,256) bytes, see the function check_tls_padding. This differs
320 * from the countermeasure described in the paper.
321 *
322 * Note that the padding length padlen does also count the last byte
323 * of the decrypted plaintext. This is different from the Lucky 13 paper.
324 *
325 * This countermeasure leaves a difference of about 100 clock cycles (in
326 * comparison to >1000 clock cycles observed without it).
327 *
328 * plen represents the length of the decrypted plaintext message P
329 * padlen represents the padding length
330 *
331 */
332 void TLS_CBC_HMAC_AEAD_Decryption::perform_additional_compressions(size_t plen, size_t padlen)
333 {
334 uint16_t block_size;
335 uint16_t max_bytes_in_first_block;
336 if(mac().name() == "HMAC(SHA-384)")
337 {
338 block_size = 128;
339 max_bytes_in_first_block = 111;
340 }
341 else
342 {
343 block_size = 64;
344 max_bytes_in_first_block = 55;
345 }
346 // number of maximum MACed bytes
347 const uint16_t L1 = 13 + plen - tag_size();
348 // number of current MACed bytes (L1 - padlen)
349 // Here the Lucky 13 paper is different because the padlen length in the paper
350 // does not count the last message byte.
351 const uint16_t L2 = 13 + plen - padlen - tag_size();
352 // From the paper, for SHA-256/SHA-1 compute: ceil((L1-55)/64) and ceil((L2-55)/64)
353 // ceil((L1-55)/64) = floor((L1+64-1-55)/64)
354 // Here we compute number of compressions for SHA-* in general
355 const uint16_t max_compresssions = ( (L1 + block_size - 1 - max_bytes_in_first_block) / block_size);
356 const uint16_t current_compressions = ((L2 + block_size - 1 - max_bytes_in_first_block) / block_size);
357 // number of additional compressions we have to perform
358 const uint16_t add_compressions = max_compresssions - current_compressions;
359 const uint8_t equal = CT::is_equal(max_compresssions, current_compressions) & 0x01;
360 // We compute the data length we need to achieve the number of compressions.
361 // If there are no compressions, we just add 55/111 dummy bytes so that no
362 // compression is performed.
363 const uint16_t data_len = block_size * add_compressions + equal * max_bytes_in_first_block;
364 secure_vector<uint8_t> data(data_len);
365 mac().update(unlock(data));
366 // we do not need to clear the MAC since the connection is broken anyway
367 }
368
369 void TLS_CBC_HMAC_AEAD_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
370 {
371 update(buffer, offset);
372 buffer.resize(offset);
373
374 const size_t record_len = msg().size();
375 uint8_t* record_contents = msg().data();
376
377 // This early exit does not leak info because all the values compared are public
378 if(record_len < tag_size() ||
379 (record_len - (use_encrypt_then_mac() ? tag_size() : 0)) % block_size() != 0)
380 {
381 throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
382 }
383
384 if(use_encrypt_then_mac())
385 {
386 const size_t enc_size = record_len - tag_size();
387
388 mac().update(assoc_data_with_len(iv_size() + enc_size));
389 if(iv_size() > 0)
390 {
391 mac().update(cbc_state());
392 }
393 mac().update(record_contents, enc_size);
394
395 std::vector<uint8_t> mac_buf(tag_size());
396 mac().final(mac_buf.data());
397
398 const size_t mac_offset = enc_size;
399
400 const bool mac_ok = same_mem(&record_contents[mac_offset], mac_buf.data(), tag_size());
401
402 if(!mac_ok)
403 {
404 throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
405 }
406
407 cbc_decrypt_record(record_contents, enc_size);
408
409 // 0 if padding was invalid, otherwise 1 + padding_bytes
410 uint16_t pad_size = check_tls_padding(record_contents, enc_size);
411
412 // No oracle here, whoever sent us this had the key since MAC check passed
413 if(pad_size == 0)
414 {
415 throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
416 }
417
418 const uint8_t* plaintext_block = &record_contents[0];
419 const uint16_t plaintext_length = enc_size - pad_size;
420
421 buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
422 }
423 else
424 {
425 CT::poison(record_contents, record_len);
426
427 cbc_decrypt_record(record_contents, record_len);
428
429 // 0 if padding was invalid, otherwise 1 + padding_bytes
430 uint16_t pad_size = check_tls_padding(record_contents, record_len);
431
432 /*
433 This mask is zero if there is not enough room in the packet to get a valid MAC.
434
435 We have to accept empty packets, since otherwise we are not compatible
436 with how OpenSSL's countermeasure for fixing BEAST in TLS 1.0 CBC works
437 (sending empty records, instead of 1/(n-1) splitting)
438 */
439
440 const uint16_t size_ok_mask = CT::is_lte<uint16_t>(static_cast<uint16_t>(tag_size() + pad_size), static_cast<uint16_t>(record_len + 1));
441 pad_size &= size_ok_mask;
442
443 CT::unpoison(record_contents, record_len);
444
445 /*
446 This is unpoisoned sooner than it should. The pad_size leaks to plaintext_length and
447 then to the timing channel in the MAC computation described in the Lucky 13 paper.
448 */
449 CT::unpoison(pad_size);
450
451 const uint8_t* plaintext_block = &record_contents[0];
452 const uint16_t plaintext_length = static_cast<uint16_t>(record_len - tag_size() - pad_size);
453
454 mac().update(assoc_data_with_len(plaintext_length));
455 mac().update(plaintext_block, plaintext_length);
456
457 std::vector<uint8_t> mac_buf(tag_size());
458 mac().final(mac_buf.data());
459
460 const size_t mac_offset = record_len - (tag_size() + pad_size);
461
462 const bool mac_ok = same_mem(&record_contents[mac_offset], mac_buf.data(), tag_size());
463
464 const uint16_t ok_mask = size_ok_mask & CT::expand_mask<uint16_t>(mac_ok) & CT::expand_mask<uint16_t>(pad_size);
465
466 CT::unpoison(ok_mask);
467
468 if(ok_mask)
469 {
470 buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
471 }
472 else
473 {
474 perform_additional_compressions(record_len, pad_size);
475 throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
476 }
477 }
478 }
479
480 }
481
482 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::BlockCipher::encrypt
void encrypt(const uint8_t in[], uint8_t out[]) const
Definition: block_cipher.h:80
Botan::BlockCipher::decrypt
void decrypt(const uint8_t in[], uint8_t out[]) const
Definition: block_cipher.h:90
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cipher
BlockCipher & cipher() const
Definition: tls_cbc.h:62
Botan::Invalid_Key_Length
Definition: exceptn.h:98
Botan::Exception
Definition: exceptn.h:21
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode
TLS_CBC_HMAC_AEAD_Mode(const std::string &cipher_name, size_t cipher_keylen, const std::string &mac_name, size_t mac_keylen, bool use_explicit_iv, bool use_encrypt_then_mac)
Definition: tls_cbc.cpp:25
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
m_cipher_name
std::string m_cipher_name
Definition: openssl_block.cpp:53
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::block_size
size_t block_size() const
Definition: tls_cbc.h:58
Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: tls_cbc.cpp:168
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::clear
void clear() overridefinal
Definition: tls_cbc.cpp:46
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::TLS::TLS_CBC_HMAC_AEAD_Mode::tag_size
size_t tag_size() const overridefinal
Definition: tls_cbc.h:39
Botan::CT::poison
void poison(const T *p, size_t n)
Definition: ct_utils.h:46
Botan::Invalid_IV_Length
Definition: exceptn.h:109
Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: tls_cbc.cpp:369
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::mac
MessageAuthenticationCode & mac() const
Definition: tls_cbc.h:68
Botan::CT::is_equal
T is_equal(T x, T y)
Definition: ct_utils.h:116
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::set_associated_data
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: tls_cbc.cpp:123
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc_state
secure_vector< uint8_t > & cbc_state()
Definition: tls_cbc.h:74
Botan::Buffered_Computation::final
void final(uint8_t out[])
Definition: buf_comp.h:89
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::SymmetricAlgorithm::set_key
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:66
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::key_spec
Key_Length_Specification key_spec() const overridefinal
Definition: tls_cbc.cpp:77
Botan::SymmetricAlgorithm::clear
virtual void clear()=0
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::iv_size
size_t iv_size() const
Definition: tls_cbc.h:57
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::assoc_data
std::vector< uint8_t > & assoc_data()
Definition: tls_cbc.h:75
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::use_encrypt_then_mac
bool use_encrypt_then_mac() const
Definition: tls_cbc.h:60
Botan::BlockCipher::create_or_throw
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: block_cipher.cpp:285
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::update_granularity
size_t update_granularity() const overridefinal
Definition: tls_cbc.cpp:65
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::process
size_t process(uint8_t buf[], size_t sz) overridefinal
Definition: tls_cbc.cpp:108
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::assoc_data_with_len
std::vector< uint8_t > assoc_data_with_len(uint16_t len)
Definition: tls_cbc.cpp:114
Botan::Buffered_Computation::update
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:34
Botan::make_uint16
uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:60
Botan::MessageAuthenticationCode::create_or_throw
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:138
Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::output_length
size_t output_length(size_t input_length) const override
Definition: tls_cbc.cpp:162
Botan::get_byte
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:47
Botan::CT::unpoison
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:57
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::msg
secure_vector< uint8_t > & msg()
Definition: tls_cbc.h:76
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::name
std::string name() const overridefinal
Definition: tls_cbc.cpp:60
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::valid_nonce_length
bool valid_nonce_length(size_t nl) const overridefinal
Definition: tls_cbc.cpp:70
Botan::round_up
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:22
Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::output_length
size_t output_length(size_t input_length) const override
Definition: tls_cbc.cpp:282
Botan::TLS::TLS_Exception
Definition: tls_exceptn.h:21
Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::set_associated_data
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: tls_cbc.cpp:130
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::reset
void reset() overridefinal
Definition: tls_cbc.cpp:53
Botan::TLS::Alert::BAD_RECORD_MAC
Definition: tls_alert.h:30