Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tls_record.cpp
Go to the documentation of this file.
1 /*
2 * TLS Record Handling
3 * (C) 2012,2013,2014,2015,2016,2019 Jack Lloyd
4 * 2016 Juraj Somorovsky
5 * 2016 Matthias Gierlings
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9
10 #include <botan/internal/tls_record.h>
11 #include <botan/tls_ciphersuite.h>
12 #include <botan/tls_exceptn.h>
13 #include <botan/loadstor.h>
14 #include <botan/internal/tls_seq_numbers.h>
15 #include <botan/internal/tls_session_key.h>
16 #include <botan/internal/rounding.h>
17 #include <botan/internal/ct_utils.h>
18 #include <botan/rng.h>
19
20 #if defined(BOTAN_HAS_TLS_CBC)
21 #include <botan/internal/tls_cbc.h>
22 #endif
23
24 namespace Botan {
25
26 namespace TLS {
27
28 Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version,
29 Connection_Side side,
30 bool our_side,
31 const Ciphersuite& suite,
32 const Session_Keys& keys,
33 bool uses_encrypt_then_mac) :
34 m_start_time(std::chrono::system_clock::now())
35 {
36 m_nonce_format = suite.nonce_format();
37 m_nonce_bytes_from_record = suite.nonce_bytes_from_record(version);
38 m_nonce_bytes_from_handshake = suite.nonce_bytes_from_handshake();
39
40 const secure_vector<uint8_t>& aead_key = keys.aead_key(side);
41 m_nonce = keys.nonce(side);
42
43 BOTAN_ASSERT_NOMSG(m_nonce.size() == m_nonce_bytes_from_handshake);
44
45 if(nonce_format() == Nonce_Format::CBC_MODE)
46 {
47 #if defined(BOTAN_HAS_TLS_CBC)
48 // legacy CBC+HMAC mode
49 auto mac = MessageAuthenticationCode::create_or_throw("HMAC(" + suite.mac_algo() + ")");
50 auto cipher = BlockCipher::create_or_throw(suite.cipher_algo());
51
52 if(our_side)
53 {
54 m_aead.reset(new TLS_CBC_HMAC_AEAD_Encryption(
55 std::move(cipher),
56 std::move(mac),
57 suite.cipher_keylen(),
58 suite.mac_keylen(),
59 version,
60 uses_encrypt_then_mac));
61 }
62 else
63 {
64 m_aead.reset(new TLS_CBC_HMAC_AEAD_Decryption(
65 std::move(cipher),
66 std::move(mac),
67 suite.cipher_keylen(),
68 suite.mac_keylen(),
69 version,
70 uses_encrypt_then_mac));
71 }
72
73 #else
74 BOTAN_UNUSED(uses_encrypt_then_mac);
75 throw Internal_Error("Negotiated disabled TLS CBC+HMAC ciphersuite");
76 #endif
77 }
78 else
79 {
80 m_aead = AEAD_Mode::create_or_throw(suite.cipher_algo(), our_side ? ENCRYPTION : DECRYPTION);
81 }
82
83 m_aead->set_key(aead_key);
84 }
85
86 std::vector<uint8_t> Connection_Cipher_State::aead_nonce(uint64_t seq, RandomNumberGenerator& rng)
87 {
88 switch(m_nonce_format)
89 {
90 case Nonce_Format::CBC_MODE:
91 {
92 if(m_nonce.size())
93 {
94 std::vector<uint8_t> nonce;
95 nonce.swap(m_nonce);
96 return nonce;
97 }
98 std::vector<uint8_t> nonce(nonce_bytes_from_record());
99 rng.randomize(nonce.data(), nonce.size());
100 return nonce;
101 }
102 case Nonce_Format::AEAD_XOR_12:
103 {
104 std::vector<uint8_t> nonce(12);
105 store_be(seq, nonce.data() + 4);
106 xor_buf(nonce, m_nonce.data(), m_nonce.size());
107 return nonce;
108 }
109 case Nonce_Format::AEAD_IMPLICIT_4:
110 {
111 BOTAN_ASSERT_NOMSG(m_nonce.size() == 4);
112 std::vector<uint8_t> nonce(12);
113 copy_mem(&nonce[0], m_nonce.data(), 4);
114 store_be(seq, &nonce[nonce_bytes_from_handshake()]);
115 return nonce;
116 }
117 }
118
119 throw Invalid_State("Unknown nonce format specified");
120 }
121
122 std::vector<uint8_t>
123 Connection_Cipher_State::aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq)
124 {
125 switch(m_nonce_format)
126 {
127 case Nonce_Format::CBC_MODE:
128 {
129 if(nonce_bytes_from_record() == 0 && m_nonce.size())
130 {
131 std::vector<uint8_t> nonce;
132 nonce.swap(m_nonce);
133 return nonce;
134 }
135 if(record_len < nonce_bytes_from_record())
136 throw Decoding_Error("Invalid CBC packet too short to be valid");
137 std::vector<uint8_t> nonce(record, record + nonce_bytes_from_record());
138 return nonce;
139 }
140 case Nonce_Format::AEAD_XOR_12:
141 {
142 std::vector<uint8_t> nonce(12);
143 store_be(seq, nonce.data() + 4);
144 xor_buf(nonce, m_nonce.data(), m_nonce.size());
145 return nonce;
146 }
147 case Nonce_Format::AEAD_IMPLICIT_4:
148 {
149 BOTAN_ASSERT_NOMSG(m_nonce.size() == 4);
150 if(record_len < nonce_bytes_from_record())
151 throw Decoding_Error("Invalid AEAD packet too short to be valid");
152 std::vector<uint8_t> nonce(12);
153 copy_mem(&nonce[0], m_nonce.data(), 4);
154 copy_mem(&nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record());
155 return nonce;
156 }
157 }
158
159 throw Invalid_State("Unknown nonce format specified");
160 }
161
162 std::vector<uint8_t>
163 Connection_Cipher_State::format_ad(uint64_t msg_sequence,
164 uint8_t msg_type,
165 Protocol_Version version,
166 uint16_t msg_length)
167 {
168 std::vector<uint8_t> ad(13);
169
170 store_be(msg_sequence, &ad[0]);
171 ad[8] = msg_type;
172 ad[9] = version.major_version();
173 ad[10] = version.minor_version();
174 ad[11] = get_byte(0, msg_length);
175 ad[12] = get_byte(1, msg_length);
176
177 return ad;
178 }
179
180 namespace {
181
182 inline void append_u16_len(secure_vector<uint8_t>& output, size_t len_field)
183 {
184 const uint16_t len16 = static_cast<uint16_t>(len_field);
185 BOTAN_ASSERT_EQUAL(len_field, len16, "No truncation");
186 output.push_back(get_byte(0, len16));
187 output.push_back(get_byte(1, len16));
188 }
189
190 }
191
192 void write_record(secure_vector<uint8_t>& output,
193 uint8_t record_type,
194 Protocol_Version version,
195 uint64_t record_sequence,
196 const uint8_t* message,
197 size_t message_len,
198 Connection_Cipher_State* cs,
199 RandomNumberGenerator& rng)
200 {
201 output.clear();
202
203 output.push_back(record_type);
204 output.push_back(version.major_version());
205 output.push_back(version.minor_version());
206
207 if(version.is_datagram_protocol())
208 {
209 for(size_t i = 0; i != 8; ++i)
210 output.push_back(get_byte(i, record_sequence));
211 }
212
213 if(!cs) // initial unencrypted handshake records
214 {
215 append_u16_len(output, message_len);
216 output.insert(output.end(), message, message + message_len);
217 return;
218 }
219
220 AEAD_Mode& aead = cs->aead();
221 std::vector<uint8_t> aad = cs->format_ad(record_sequence, record_type, version, static_cast<uint16_t>(message_len));
222
223 const size_t ctext_size = aead.output_length(message_len);
224
225 const size_t rec_size = ctext_size + cs->nonce_bytes_from_record();
226
227 aead.set_ad(aad);
228
229 const std::vector<uint8_t> nonce = cs->aead_nonce(record_sequence, rng);
230
231 append_u16_len(output, rec_size);
232
233 if(cs->nonce_bytes_from_record() > 0)
234 {
235 if(cs->nonce_format() == Nonce_Format::CBC_MODE)
236 output += nonce;
237 else
238 output += std::make_pair(&nonce[cs->nonce_bytes_from_handshake()], cs->nonce_bytes_from_record());
239 }
240
241 const size_t header_size = output.size();
242 output += std::make_pair(message, message_len);
243
244 aead.start(nonce);
245 aead.finish(output, header_size);
246
247 BOTAN_ASSERT(output.size() < MAX_CIPHERTEXT_SIZE,
248 "Produced ciphertext larger than protocol allows");
249 }
250
251 namespace {
252
253 size_t fill_buffer_to(secure_vector<uint8_t>& readbuf,
254 const uint8_t*& input,
255 size_t& input_size,
256 size_t& input_consumed,
257 size_t desired)
258 {
259 if(readbuf.size() >= desired)
260 return 0; // already have it
261
262 const size_t taken = std::min(input_size, desired - readbuf.size());
263
264 readbuf.insert(readbuf.end(), input, input + taken);
265 input_consumed += taken;
266 input_size -= taken;
267 input += taken;
268
269 return (desired - readbuf.size()); // how many bytes do we still need?
270 }
271
272 void decrypt_record(secure_vector<uint8_t>& output,
273 uint8_t record_contents[], size_t record_len,
274 uint64_t record_sequence,
275 Protocol_Version record_version,
276 Record_Type record_type,
277 Connection_Cipher_State& cs)
278 {
279 AEAD_Mode& aead = cs.aead();
280
281 const std::vector<uint8_t> nonce = cs.aead_nonce(record_contents, record_len, record_sequence);
282 const uint8_t* msg = &record_contents[cs.nonce_bytes_from_record()];
283 const size_t msg_length = record_len - cs.nonce_bytes_from_record();
284
285 /*
286 * This early rejection is based just on public information (length of the
287 * encrypted packet) and so does not leak any information. We used to use
288 * decode_error here which really is more appropriate, but that confuses some
289 * tools which are attempting automated detection of padding oracles,
290 * including older versions of TLS-Attacker.
291 */
292 if(msg_length < aead.minimum_final_size())
293 throw TLS_Exception(Alert::BAD_RECORD_MAC, "AEAD packet is shorter than the tag");
294
295 const size_t ptext_size = aead.output_length(msg_length);
296
297 aead.set_associated_data_vec(
298 cs.format_ad(record_sequence,
299 static_cast<uint8_t>(record_type),
300 record_version,
301 static_cast<uint16_t>(ptext_size))
302 );
303
304 aead.start(nonce);
305
306 output.assign(msg, msg + msg_length);
307 aead.finish(output, 0);
308 }
309
310 Record_Header read_tls_record(secure_vector<uint8_t>& readbuf,
311 const uint8_t input[],
312 size_t input_len,
313 size_t& consumed,
314 secure_vector<uint8_t>& recbuf,
315 Connection_Sequence_Numbers* sequence_numbers,
316 get_cipherstate_fn get_cipherstate)
317 {
318 if(readbuf.size() < TLS_HEADER_SIZE) // header incomplete?
319 {
320 if(size_t needed = fill_buffer_to(readbuf, input, input_len, consumed, TLS_HEADER_SIZE))
321 {
322 return Record_Header(needed);
323 }
324
325 BOTAN_ASSERT_EQUAL(readbuf.size(), TLS_HEADER_SIZE, "Have an entire header");
326 }
327
328 const Protocol_Version version(readbuf[1], readbuf[2]);
329
330 if(version.is_datagram_protocol())
331 throw TLS_Exception(Alert::PROTOCOL_VERSION,
332 "Expected TLS but got a record with DTLS version");
333
334 const size_t record_size = make_uint16(readbuf[TLS_HEADER_SIZE-2],
335 readbuf[TLS_HEADER_SIZE-1]);
336
337 if(record_size > MAX_CIPHERTEXT_SIZE)
338 throw TLS_Exception(Alert::RECORD_OVERFLOW,
339 "Received a record that exceeds maximum size");
340
341 if(record_size == 0)
342 throw TLS_Exception(Alert::DECODE_ERROR,
343 "Received a completely empty record");
344
345 if(size_t needed = fill_buffer_to(readbuf, input, input_len, consumed, TLS_HEADER_SIZE + record_size))
346 {
347 return Record_Header(needed);
348 }
349
350 BOTAN_ASSERT_EQUAL(static_cast<size_t>(TLS_HEADER_SIZE) + record_size,
351 readbuf.size(),
352 "Have the full record");
353
354 const Record_Type type = static_cast<Record_Type>(readbuf[0]);
355
356 uint16_t epoch = 0;
357
358 uint64_t sequence = 0;
359 if(sequence_numbers)
360 {
361 sequence = sequence_numbers->next_read_sequence();
362 epoch = sequence_numbers->current_read_epoch();
363 }
364 else
365 {
366 // server initial handshake case
367 epoch = 0;
368 }
369
370 if(epoch == 0) // Unencrypted initial handshake
371 {
372 recbuf.assign(readbuf.begin() + TLS_HEADER_SIZE, readbuf.begin() + TLS_HEADER_SIZE + record_size);
373 readbuf.clear();
374 return Record_Header(sequence, version, type);
375 }
376
377 // Otherwise, decrypt, check MAC, return plaintext
378 auto cs = get_cipherstate(epoch);
379
380 BOTAN_ASSERT(cs, "Have cipherstate for this epoch");
381
382 decrypt_record(recbuf,
383 &readbuf[TLS_HEADER_SIZE],
384 record_size,
385 sequence,
386 version,
387 type,
388 *cs);
389
390 if(sequence_numbers)
391 sequence_numbers->read_accept(sequence);
392
393 readbuf.clear();
394 return Record_Header(sequence, version, type);
395 }
396
397 Record_Header read_dtls_record(secure_vector<uint8_t>& readbuf,
398 const uint8_t input[],
399 size_t input_len,
400 size_t& consumed,
401 secure_vector<uint8_t>& recbuf,
402 Connection_Sequence_Numbers* sequence_numbers,
403 get_cipherstate_fn get_cipherstate,
404 bool allow_epoch0_restart)
405 {
406 if(readbuf.size() < DTLS_HEADER_SIZE) // header incomplete?
407 {
408 if(fill_buffer_to(readbuf, input, input_len, consumed, DTLS_HEADER_SIZE))
409 {
410 readbuf.clear();
411 return Record_Header(0);
412 }
413
414 BOTAN_ASSERT_EQUAL(readbuf.size(), DTLS_HEADER_SIZE, "Have an entire header");
415 }
416
417 const Protocol_Version version(readbuf[1], readbuf[2]);
418
419 if(version.is_datagram_protocol() == false)
420 {
421 readbuf.clear();
422 return Record_Header(0);
423 }
424
425 const size_t record_size = make_uint16(readbuf[DTLS_HEADER_SIZE-2],
426 readbuf[DTLS_HEADER_SIZE-1]);
427
428 if(record_size > MAX_CIPHERTEXT_SIZE)
429 {
430 // Too large to be valid, ignore it
431 readbuf.clear();
432 return Record_Header(0);
433 }
434
435 if(fill_buffer_to(readbuf, input, input_len, consumed, DTLS_HEADER_SIZE + record_size))
436 {
437 // Truncated packet?
438 readbuf.clear();
439 return Record_Header(0);
440 }
441
442 BOTAN_ASSERT_EQUAL(static_cast<size_t>(DTLS_HEADER_SIZE) + record_size, readbuf.size(),
443 "Have the full record");
444
445 const Record_Type type = static_cast<Record_Type>(readbuf[0]);
446
447 const uint64_t sequence = load_be<uint64_t>(&readbuf[3], 0);
448 const uint16_t epoch = (sequence >> 48);
449
450 const bool already_seen = sequence_numbers && sequence_numbers->already_seen(sequence);
451
452 if(already_seen && !(epoch == 0 && allow_epoch0_restart))
453 {
454 readbuf.clear();
455 return Record_Header(0);
456 }
457
458 if(epoch == 0) // Unencrypted initial handshake
459 {
460 recbuf.assign(readbuf.begin() + DTLS_HEADER_SIZE, readbuf.begin() + DTLS_HEADER_SIZE + record_size);
461 readbuf.clear();
462 if(sequence_numbers)
463 sequence_numbers->read_accept(sequence);
464 return Record_Header(sequence, version, type);
465 }
466
467 try
468 {
469 // Otherwise, decrypt, check MAC, return plaintext
470 auto cs = get_cipherstate(epoch);
471
472 BOTAN_ASSERT(cs, "Have cipherstate for this epoch");
473
474 decrypt_record(recbuf,
475 &readbuf[DTLS_HEADER_SIZE],
476 record_size,
477 sequence,
478 version,
479 type,
480 *cs);
481 }
482 catch(std::exception&)
483 {
484 readbuf.clear();
485 return Record_Header(0);
486 }
487
488 if(sequence_numbers)
489 sequence_numbers->read_accept(sequence);
490
491 readbuf.clear();
492 return Record_Header(sequence, version, type);
493 }
494
495 }
496
497 Record_Header read_record(bool is_datagram,
498 secure_vector<uint8_t>& readbuf,
499 const uint8_t input[],
500 size_t input_len,
501 size_t& consumed,
502 secure_vector<uint8_t>& recbuf,
503 Connection_Sequence_Numbers* sequence_numbers,
504 get_cipherstate_fn get_cipherstate,
505 bool allow_epoch0_restart)
506 {
507 if(is_datagram)
508 return read_dtls_record(readbuf, input, input_len, consumed,
509 recbuf, sequence_numbers, get_cipherstate, allow_epoch0_restart);
510 else
511 return read_tls_record(readbuf, input, input_len, consumed,
512 recbuf, sequence_numbers, get_cipherstate);
513 }
514
515 }
516
517 }
Botan::TLS::read_record
Record_Header read_record(bool is_datagram, secure_vector< uint8_t > &readbuf, const uint8_t input[], size_t input_len, size_t &consumed, secure_vector< uint8_t > &recbuf, Connection_Sequence_Numbers *sequence_numbers, get_cipherstate_fn get_cipherstate, bool allow_epoch0_restart)
Definition: tls_record.cpp:497
Botan::TLS::Connection_Cipher_State
Definition: tls_record.h:32
Botan::TLS::Protocol_Version::minor_version
uint8_t minor_version() const
Definition: tls_version.h:84
Botan::TLS::Connection_Cipher_State::nonce_format
Nonce_Format nonce_format() const
Definition: tls_record.h:62
Botan::TLS::Connection_Cipher_State::aead_nonce
std::vector< uint8_t > aead_nonce(uint64_t seq, RandomNumberGenerator &rng)
Definition: tls_record.cpp:86
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::store_be
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
Botan::TLS::Connection_Cipher_State::aead
AEAD_Mode & aead()
Definition: tls_record.h:45
Botan::RandomNumberGenerator::randomize
virtual void randomize(uint8_t output[], size_t length)=0
Botan::TLS::Connection_Cipher_State::nonce_bytes_from_record
size_t nonce_bytes_from_record() const
Definition: tls_record.h:60
Botan::TLS::get_cipherstate_fn
std::function< std::shared_ptr< Connection_Cipher_State >uint16_t)> get_cipherstate_fn
Definition: tls_record.h:152
Botan::get_byte
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
std
Definition: bigint.h:1135
Botan::TLS::write_record
void write_record(secure_vector< uint8_t > &output, uint8_t record_type, Protocol_Version version, uint64_t record_sequence, const uint8_t *message, size_t message_len, Connection_Cipher_State *cs, RandomNumberGenerator &rng)
Definition: tls_record.cpp:192
Botan::TLS::Ciphersuite::nonce_bytes_from_record
size_t nonce_bytes_from_record(Protocol_Version version) const
Definition: tls_ciphersuite.cpp:40
Botan::Internal_Error
Definition: exceptn.h:341
BOTAN_ASSERT_NOMSG
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
Botan::TLS::Connection_Cipher_State::Connection_Cipher_State
Connection_Cipher_State(Protocol_Version version, Connection_Side which_side, bool is_our_side, const Ciphersuite &suite, const Session_Keys &keys, bool uses_encrypt_then_mac)
Definition: tls_record.cpp:28
Botan::AEAD_Mode::set_ad
void set_ad(const std::vector< uint8_t, Alloc > &ad)
Definition: aead.h:95
Botan::TLS::Protocol_Version
Definition: tls_version.h:21
type
MechanismType type
Definition: p11_mechanism.cpp:44
Botan::TLS::Session_Keys
Definition: tls_session_key.h:23
Botan::TLS::Session_Keys::nonce
const std::vector< uint8_t > & nonce(Connection_Side side) const
Definition: tls_session_key.h:56
Botan::TLS::Ciphersuite
Definition: tls_ciphersuite.h:24
Botan::TLS::Connection_Side
Connection_Side
Definition: tls_magic.h:32
Botan::Cipher_Mode::start
void start(const std::vector< uint8_t, Alloc > &nonce)
Definition: cipher_mode.h:69
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
Botan::Decoding_Error
Definition: exceptn.h:199
Botan::load_be< uint64_t >
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:217
Botan::Cipher_Mode::output_length
virtual size_t output_length(size_t input_length) const =0
Botan::TLS::Ciphersuite::nonce_format
Nonce_Format nonce_format() const
Definition: tls_ciphersuite.h:119
Botan::TLS::Ciphersuite::mac_keylen
size_t mac_keylen() const
Definition: tls_ciphersuite.h:121
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::TLS::Record_Header
Definition: tls_record.h:80
Botan::xor_buf
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:232
Botan::TLS::Connection_Cipher_State::format_ad
std::vector< uint8_t > format_ad(uint64_t seq, uint8_t type, Protocol_Version version, uint16_t ptext_length)
Definition: tls_record.cpp:163
Botan::TLS::MAX_CIPHERTEXT_SIZE
Definition: tls_magic.h:28
BOTAN_ASSERT_EQUAL
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:81
Botan::TLS::Protocol_Version::major_version
uint8_t major_version() const
Definition: tls_version.h:79
Botan::TLS::Nonce_Format::CBC_MODE
Botan::TLS::Alert::DECODE_ERROR
Definition: tls_alert.h:44
Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption
Definition: tls_cbc.h:141
Botan::TLS::DTLS_HEADER_SIZE
Definition: tls_magic.h:24
Botan::DECRYPTION
Definition: cipher_mode.h:23
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:132
Botan
Definition: alg_id.cpp:13
Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption
Definition: tls_cbc.h:106
Botan::TLS::Connection_Sequence_Numbers
Definition: tls_seq_numbers.h:18
Botan::TLS::Record_Type
Record_Type
Definition: tls_magic.h:35
BOTAN_UNUSED
#define BOTAN_UNUSED(...)
Definition: assert.h:142
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:348
Botan::AEAD_Mode
Definition: aead.h:22
Botan::TLS::Connection_Cipher_State::nonce_bytes_from_handshake
size_t nonce_bytes_from_handshake() const
Definition: tls_record.h:59
Botan::TLS::Ciphersuite::cipher_keylen
size_t cipher_keylen() const
Definition: tls_ciphersuite.h:113
Botan::Invalid_State
Definition: exceptn.h:215
Botan::TLS::Ciphersuite::mac_algo
std::string mac_algo() const
Definition: tls_ciphersuite.h:103
Botan::TLS::Ciphersuite::cipher_algo
std::string cipher_algo() const
Definition: tls_ciphersuite.h:98
Botan::TLS::Alert::RECORD_OVERFLOW
Definition: tls_alert.h:32
Botan::TLS::Session_Keys::aead_key
const secure_vector< uint8_t > & aead_key(Connection_Side side) const
Definition: tls_session_key.h:51
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:141
Botan::ENCRYPTION
Definition: cipher_mode.h:23
Botan::TLS::Nonce_Format::AEAD_XOR_12
Botan::TLS::Ciphersuite::nonce_bytes_from_handshake
size_t nonce_bytes_from_handshake() const
Definition: tls_ciphersuite.cpp:20
Botan::make_uint16
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:54
Botan::TLS::Alert::PROTOCOL_VERSION
Definition: tls_alert.h:47
Botan::TLS::TLS_HEADER_SIZE
Definition: tls_magic.h:23
Botan::TLS::Protocol_Version::is_datagram_protocol
bool is_datagram_protocol() const
Definition: tls_version.cpp:33
Botan::AEAD_Mode::create_or_throw
static std::unique_ptr< AEAD_Mode > create_or_throw(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: aead.cpp:42
Botan::TLS::Nonce_Format::AEAD_IMPLICIT_4
Botan::Cipher_Mode::finish
virtual void finish(secure_vector< uint8_t > &final_block, size_t offset=0)=0
Botan::TLS::Alert::BAD_RECORD_MAC
Definition: tls_alert.h:30