Botan 2.19.5 Crypto and TLS for C&

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