Botan 2.1.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 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 m_nonce_bytes_from_handshake(suite.nonce_bytes_from_handshake()),
36 m_nonce_bytes_from_record(suite.nonce_bytes_from_record())
37 {
38 SymmetricKey mac_key, cipher_key;
39 InitializationVector iv;
40
41 if(side == CLIENT)
42 {
43 cipher_key = keys.client_cipher_key();
44 iv = keys.client_iv();
45 mac_key = keys.client_mac_key();
46 }
47 else
48 {
49 cipher_key = keys.server_cipher_key();
50 iv = keys.server_iv();
51 mac_key = keys.server_mac_key();
52 }
53
54 BOTAN_ASSERT_EQUAL(iv.length(), nonce_bytes_from_handshake(), "Matching nonce sizes");
55
56 m_nonce = unlock(iv.bits_of());
57
58 if(suite.mac_algo() == "AEAD")
59 {
60 m_aead.reset(get_aead(suite.cipher_algo(), our_side ? ENCRYPTION : DECRYPTION));
61 BOTAN_ASSERT(m_aead, "Have AEAD");
62
63 m_aead->set_key(cipher_key + mac_key);
64
65 BOTAN_ASSERT(nonce_bytes_from_record() == 0 || nonce_bytes_from_record() == 8,
66 "Ciphersuite uses implemented IV length");
67
68 m_cbc_nonce = false;
69 if(m_nonce.size() != 12)
70 {
71 m_nonce.resize(m_nonce.size() + 8);
72 }
73 }
74 else
75 {
76 #if defined(BOTAN_HAS_TLS_CBC)
77 // legacy CBC+HMAC mode
78 if(our_side)
79 {
80 m_aead.reset(new TLS_CBC_HMAC_AEAD_Encryption(
81 suite.cipher_algo(),
82 suite.cipher_keylen(),
83 suite.mac_algo(),
84 suite.mac_keylen(),
85 version.supports_explicit_cbc_ivs(),
86 uses_encrypt_then_mac));
87 }
88 else
89 {
90 m_aead.reset(new TLS_CBC_HMAC_AEAD_Decryption(
91 suite.cipher_algo(),
92 suite.cipher_keylen(),
93 suite.mac_algo(),
94 suite.mac_keylen(),
95 version.supports_explicit_cbc_ivs(),
96 uses_encrypt_then_mac));
97 }
98
99 m_aead->set_key(cipher_key + mac_key);
100
101 m_cbc_nonce = true;
102 if(version.supports_explicit_cbc_ivs())
103 m_nonce_bytes_from_record = m_nonce_bytes_from_handshake;
104 else if(our_side == false)
105 m_aead->start(iv.bits_of());
106 #else
107 throw Exception("Negotiated disabled TLS CBC+HMAC ciphersuite");
108 #endif
109 }
110 }
111
112 std::vector<uint8_t> Connection_Cipher_State::aead_nonce(uint64_t seq, RandomNumberGenerator& rng)
113 {
114 if(m_cbc_nonce)
115 {
116 if(m_nonce.size())
117 {
118 std::vector<uint8_t> nonce;
119 nonce.swap(m_nonce);
120 return nonce;
121 }
122 std::vector<uint8_t> nonce(nonce_bytes_from_record());
123 rng.randomize(nonce.data(), nonce.size());
124 return nonce;
125 }
126 else if(nonce_bytes_from_handshake() == 12)
127 {
128 std::vector<uint8_t> nonce(12);
129 store_be(seq, nonce.data() + 4);
130 xor_buf(nonce, m_nonce.data(), m_nonce.size());
131 return nonce;
132 }
133 else
134 {
135 std::vector<uint8_t> nonce = m_nonce;
136 store_be(seq, &nonce[nonce_bytes_from_handshake()]);
137 return nonce;
138 }
139 }
140
141 std::vector<uint8_t>
142 Connection_Cipher_State::aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq)
143 {
144 if(m_cbc_nonce)
145 {
146 if(record_len < nonce_bytes_from_record())
147 throw Decoding_Error("Invalid CBC packet too short to be valid");
148 std::vector<uint8_t> nonce(record, record + nonce_bytes_from_record());
149 return nonce;
150 }
151 else if(nonce_bytes_from_handshake() == 12)
152 {
153 /*
154 Assumes if the suite specifies 12 bytes come from the handshake then
155 use the XOR nonce construction from draft-ietf-tls-chacha20-poly1305
156 */
157
158 std::vector<uint8_t> nonce(12);
159 store_be(seq, nonce.data() + 4);
160 xor_buf(nonce, m_nonce.data(), m_nonce.size());
161 return nonce;
162 }
163 else if(nonce_bytes_from_record() > 0)
164 {
165 if(record_len < nonce_bytes_from_record())
166 throw Decoding_Error("Invalid AEAD packet too short to be valid");
167 std::vector<uint8_t> nonce = m_nonce;
168 copy_mem(&nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record());
169 return nonce;
170 }
171 else
172 {
173 /*
174 nonce_len == 0 is assumed to mean no nonce in the message but
175 instead the AEAD uses the seq number in network order.
176 */
177 std::vector<uint8_t> nonce = m_nonce;
178 store_be(seq, &nonce[nonce_bytes_from_handshake()]);
179 return nonce;
180 }
181 }
182
183 std::vector<uint8_t>
184 Connection_Cipher_State::format_ad(uint64_t msg_sequence,
185 uint8_t msg_type,
186 Protocol_Version version,
187 uint16_t msg_length)
188 {
189 std::vector<uint8_t> ad(13);
190
191 store_be(msg_sequence, &ad[0]);
192 ad[8] = msg_type;
193 ad[9] = version.major_version();
194 ad[10] = version.minor_version();
195 ad[11] = get_byte(0, msg_length);
196 ad[12] = get_byte(1, msg_length);
197
198 return ad;
199 }
200
201 namespace {
202
203 inline void append_u16_len(secure_vector<uint8_t>& output, size_t len_field)
204 {
205 const uint16_t len16 = len_field;
206 BOTAN_ASSERT_EQUAL(len_field, len16, "No truncation");
207 output.push_back(get_byte(0, len16));
208 output.push_back(get_byte(1, len16));
209 }
210
211 }
212
213 void write_record(secure_vector<uint8_t>& output,
214 Record_Message msg,
215 Protocol_Version version,
216 uint64_t seq,
217 Connection_Cipher_State* cs,
218 RandomNumberGenerator& rng)
219 {
220 output.clear();
221
222 output.push_back(msg.get_type());
223 output.push_back(version.major_version());
224 output.push_back(version.minor_version());
225
226 if(version.is_datagram_protocol())
227 {
228 for(size_t i = 0; i != 8; ++i)
229 output.push_back(get_byte(i, seq));
230 }
231
232 if(!cs) // initial unencrypted handshake records
233 {
234 append_u16_len(output, msg.get_size());
235 output.insert(output.end(), msg.get_data(), msg.get_data() + msg.get_size());
236 return;
237 }
238
239 AEAD_Mode* aead = cs->aead();
240 std::vector<uint8_t> aad = cs->format_ad(seq, msg.get_type(), version, static_cast<uint16_t>(msg.get_size()));
241
242 const size_t ctext_size = aead->output_length(msg.get_size());
243
244 const size_t rec_size = ctext_size + cs->nonce_bytes_from_record();
245
246 aead->set_ad(aad);
247
248 const std::vector<uint8_t> nonce = cs->aead_nonce(seq, rng);
249
250 append_u16_len(output, rec_size);
251
252 if(cs->nonce_bytes_from_record() > 0)
253 {
254 if(cs->cbc_nonce())
255 output += nonce;
256 else
257 output += std::make_pair(&nonce[cs->nonce_bytes_from_handshake()], cs->nonce_bytes_from_record());
258 }
259
260 const size_t header_size = output.size();
261 output += std::make_pair(msg.get_data(), msg.get_size());
262
263 aead->start(nonce);
264 aead->finish(output, header_size);
265
266 BOTAN_ASSERT(output.size() < MAX_CIPHERTEXT_SIZE,
267 "Produced ciphertext larger than protocol allows");
268 }
269
270 namespace {
271
272 size_t fill_buffer_to(secure_vector<uint8_t>& readbuf,
273 const uint8_t*& input,
274 size_t& input_size,
275 size_t& input_consumed,
276 size_t desired)
277 {
278 if(readbuf.size() >= desired)
279 return 0; // already have it
280
281 const size_t taken = std::min(input_size, desired - readbuf.size());
282
283 readbuf.insert(readbuf.end(), input, input + taken);
284 input_consumed += taken;
285 input_size -= taken;
286 input += taken;
287
288 return (desired - readbuf.size()); // how many bytes do we still need?
289 }
290
291 void decrypt_record(secure_vector<uint8_t>& output,
292 uint8_t record_contents[], size_t record_len,
293 uint64_t record_sequence,
294 Protocol_Version record_version,
295 Record_Type record_type,
296 Connection_Cipher_State& cs)
297 {
298 AEAD_Mode* aead = cs.aead();
299 BOTAN_ASSERT(aead, "Cannot decrypt without cipher");
300
301 const std::vector<uint8_t> nonce = cs.aead_nonce(record_contents, record_len, record_sequence);
302 const uint8_t* msg = &record_contents[cs.nonce_bytes_from_record()];
303 const size_t msg_length = record_len - cs.nonce_bytes_from_record();
304
305 const size_t ptext_size = aead->output_length(msg_length);
306
307 aead->set_associated_data_vec(
308 cs.format_ad(record_sequence, record_type, record_version, static_cast<uint16_t>(ptext_size))
309 );
310
311 aead->start(nonce);
312
313 const size_t offset = output.size();
314 output += std::make_pair(msg, msg_length);
315 aead->finish(output, offset);
316 }
317
318 size_t read_tls_record(secure_vector<uint8_t>& readbuf,
319 Record_Raw_Input& raw_input,
320 Record& rec,
321 Connection_Sequence_Numbers* sequence_numbers,
322 get_cipherstate_fn get_cipherstate)
323 {
324 if(readbuf.size() < TLS_HEADER_SIZE) // header incomplete?
325 {
326 if(size_t needed = fill_buffer_to(readbuf,
327 raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
328 TLS_HEADER_SIZE))
329 return needed;
330
331 BOTAN_ASSERT_EQUAL(readbuf.size(), TLS_HEADER_SIZE, "Have an entire header");
332 }
333
334 *rec.get_protocol_version() = Protocol_Version(readbuf[1], readbuf[2]);
335
336 BOTAN_ASSERT(!rec.get_protocol_version()->is_datagram_protocol(), "Expected TLS");
337
338 const size_t record_size = make_uint16(readbuf[TLS_HEADER_SIZE-2],
339 readbuf[TLS_HEADER_SIZE-1]);
340
341 if(record_size > MAX_CIPHERTEXT_SIZE)
342 throw TLS_Exception(Alert::RECORD_OVERFLOW,
343 "Received a record that exceeds maximum size");
344
345 if(record_size == 0)
346 throw TLS_Exception(Alert::DECODE_ERROR,
347 "Received a completely empty record");
348
349 if(size_t needed = fill_buffer_to(readbuf,
350 raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
351 TLS_HEADER_SIZE + record_size))
352 return needed;
353
354 BOTAN_ASSERT_EQUAL(static_cast<size_t>(TLS_HEADER_SIZE) + record_size,
355 readbuf.size(),
356 "Have the full record");
357
358 *rec.get_type() = static_cast<Record_Type>(readbuf[0]);
359
360 uint16_t epoch = 0;
361
362 if(sequence_numbers)
363 {
364 *rec.get_sequence() = sequence_numbers->next_read_sequence();
365 epoch = sequence_numbers->current_read_epoch();
366 }
367 else
368 {
369 // server initial handshake case
370 *rec.get_sequence() = 0;
371 epoch = 0;
372 }
373
374 uint8_t* record_contents = &readbuf[TLS_HEADER_SIZE];
375
376 if(epoch == 0) // Unencrypted initial handshake
377 {
378 rec.get_data().assign(readbuf.begin() + TLS_HEADER_SIZE, readbuf.begin() + TLS_HEADER_SIZE + record_size);
379 readbuf.clear();
380 return 0; // got a full record
381 }
382
383 // Otherwise, decrypt, check MAC, return plaintext
384 auto cs = get_cipherstate(epoch);
385
386 BOTAN_ASSERT(cs, "Have cipherstate for this epoch");
387
388 decrypt_record(rec.get_data(),
389 record_contents,
390 record_size,
391 *rec.get_sequence(),
392 *rec.get_protocol_version(),
393 *rec.get_type(),
394 *cs);
395
396 if(sequence_numbers)
397 sequence_numbers->read_accept(*rec.get_sequence());
398
399 readbuf.clear();
400 return 0;
401 }
402
403 size_t read_dtls_record(secure_vector<uint8_t>& readbuf,
404 Record_Raw_Input& raw_input,
405 Record& rec,
406 Connection_Sequence_Numbers* sequence_numbers,
407 get_cipherstate_fn get_cipherstate)
408 {
409 if(readbuf.size() < DTLS_HEADER_SIZE) // header incomplete?
410 {
411 if(fill_buffer_to(readbuf, raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(), DTLS_HEADER_SIZE))
412 {
413 readbuf.clear();
414 return 0;
415 }
416
417 BOTAN_ASSERT_EQUAL(readbuf.size(), DTLS_HEADER_SIZE, "Have an entire header");
418 }
419
420 *rec.get_protocol_version() = Protocol_Version(readbuf[1], readbuf[2]);
421
422 BOTAN_ASSERT(rec.get_protocol_version()->is_datagram_protocol(), "Expected DTLS");
423
424 const size_t record_size = make_uint16(readbuf[DTLS_HEADER_SIZE-2],
425 readbuf[DTLS_HEADER_SIZE-1]);
426
427 if(record_size > MAX_CIPHERTEXT_SIZE)
428 throw TLS_Exception(Alert::RECORD_OVERFLOW,
429 "Got message that exceeds maximum size");
430
431 if(fill_buffer_to(readbuf, raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(), DTLS_HEADER_SIZE + record_size))
432 {
433 // Truncated packet?
434 readbuf.clear();
435 return 0;
436 }
437
438 BOTAN_ASSERT_EQUAL(static_cast<size_t>(DTLS_HEADER_SIZE) + record_size, readbuf.size(),
439 "Have the full record");
440
441 *rec.get_type() = static_cast<Record_Type>(readbuf[0]);
442
443 uint16_t epoch = 0;
444
445 *rec.get_sequence() = load_be<uint64_t>(&readbuf[3], 0);
446 epoch = (*rec.get_sequence() >> 48);
447
448 if(sequence_numbers && sequence_numbers->already_seen(*rec.get_sequence()))
449 {
450 readbuf.clear();
451 return 0;
452 }
453
454 uint8_t* record_contents = &readbuf[DTLS_HEADER_SIZE];
455
456 if(epoch == 0) // Unencrypted initial handshake
457 {
458 rec.get_data().assign(readbuf.begin() + DTLS_HEADER_SIZE, readbuf.begin() + DTLS_HEADER_SIZE + record_size);
459 readbuf.clear();
460 return 0; // got a full record
461 }
462
463 try
464 {
465 // Otherwise, decrypt, check MAC, return plaintext
466 auto cs = get_cipherstate(epoch);
467
468 BOTAN_ASSERT(cs, "Have cipherstate for this epoch");
469
470 decrypt_record(rec.get_data(),
471 record_contents,
472 record_size,
473 *rec.get_sequence(),
474 *rec.get_protocol_version(),
475 *rec.get_type(),
476 *cs);
477 }
478 catch(std::exception)
479 {
480 readbuf.clear();
481 *rec.get_type() = NO_RECORD;
482 return 0;
483 }
484
485 if(sequence_numbers)
486 sequence_numbers->read_accept(*rec.get_sequence());
487
488 readbuf.clear();
489 return 0;
490 }
491
492 }
493
494 size_t read_record(secure_vector<uint8_t>& readbuf,
495 Record_Raw_Input& raw_input,
496 Record& rec,
497 Connection_Sequence_Numbers* sequence_numbers,
498 get_cipherstate_fn get_cipherstate)
499 {
500 if(raw_input.is_datagram())
501 return read_dtls_record(readbuf, raw_input, rec,
502 sequence_numbers, get_cipherstate);
503 else
504 return read_tls_record(readbuf, raw_input, rec,
505 sequence_numbers, get_cipherstate);
506 }
507
508 }
509
510 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::TLS::Session_Keys::client_iv
const InitializationVector & client_iv() const
Definition: tls_session_key.h:48
Botan::OctetString::bits_of
secure_vector< uint8_t > bits_of() const
Definition: symkey.h:31
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:82
Botan::Exception
Definition: exceptn.h:21
Botan::OctetString
Definition: symkey.h:19
Botan::TLS::Record_Raw_Input
Definition: tls_record.h:124
Botan::TLS::Connection_Cipher_State::aead_nonce
std::vector< uint8_t > aead_nonce(uint64_t seq, RandomNumberGenerator &rng)
Definition: tls_record.cpp:112
Botan::TLS::Connection_Cipher_State::aead
AEAD_Mode * aead()
Definition: tls_record.h:45
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::store_be
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:441
Botan::RandomNumberGenerator::randomize
virtual void randomize(uint8_t output[], size_t length)=0
Botan::ENCRYPTION
Definition: cipher_mode.h:212
Botan::TLS::Record_Message::get_data
const uint8_t * get_data()
Definition: tls_record.h:114
Botan::TLS::Connection_Cipher_State::nonce_bytes_from_record
size_t nonce_bytes_from_record() const
Definition: tls_record.h:56
Botan::TLS::get_cipherstate_fn
std::function< std::shared_ptr< Connection_Cipher_State >uint16_t)> get_cipherstate_fn
Definition: tls_record.h:166
Botan::TLS::read_record
size_t read_record(secure_vector< uint8_t > &readbuf, Record_Raw_Input &raw_input, Record &rec, Connection_Sequence_Numbers *sequence_numbers, get_cipherstate_fn get_cipherstate)
Definition: tls_record.cpp:494
Botan::TLS::Record_Raw_Input::is_datagram
bool is_datagram()
Definition: tls_record.h:139
std
Definition: bigint.h:619
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:66
Botan::TLS::Protocol_Version
Definition: tls_version.h:21
Botan::TLS::Session_Keys
Definition: tls_session_key.h:22
Botan::TLS::Record_Message
Definition: tls_record.h:103
Botan::OctetString::length
size_t length() const
Definition: symkey.h:25
Botan::TLS::Ciphersuite
Definition: tls_ciphersuite.h:22
Botan::TLS::Record_Message::get_type
uint8_t & get_type()
Definition: tls_record.h:112
Botan::TLS::Connection_Side
Connection_Side
Definition: tls_magic.h:27
Botan::Cipher_Mode::start
void start(const std::vector< uint8_t, Alloc > &nonce)
Definition: cipher_mode.h:38
Botan::DECRYPTION
Definition: cipher_mode.h:212
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::load_be< uint64_t >
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:223
Botan::Cipher_Mode::output_length
virtual size_t output_length(size_t input_length) const =0
Botan::TLS::Ciphersuite::mac_keylen
size_t mac_keylen() const
Definition: tls_ciphersuite.h:106
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::TLS::Session_Keys::client_mac_key
const SymmetricKey & client_mac_key() const
Definition: tls_session_key.h:38
Botan::TLS::Protocol_Version::supports_explicit_cbc_ivs
bool supports_explicit_cbc_ivs() const
Definition: tls_version.cpp:67
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:184
Botan::TLS::Record_Message::get_size
size_t & get_size()
Definition: tls_record.h:115
Botan::TLS::MAX_CIPHERTEXT_SIZE
Definition: tls_magic.h:24
Botan::TLS::CLIENT
Definition: tls_magic.h:27
BOTAN_ASSERT_EQUAL
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:53
Botan::TLS::Protocol_Version::major_version
uint8_t major_version() const
Definition: tls_version.h:77
Botan::TLS::Alert::DECODE_ERROR
Definition: tls_alert.h:44
Botan::TLS::Session_Keys::server_mac_key
const SymmetricKey & server_mac_key() const
Definition: tls_session_key.h:43
Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption
Definition: tls_cbc.h:138
Botan::TLS::DTLS_HEADER_SIZE
Definition: tls_magic.h:20
Botan::Decoding_Error
Definition: exceptn.h:189
Botan::get_aead
AEAD_Mode * get_aead(const std::string &algo, Cipher_Dir dir)
Definition: aead.cpp:41
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_Encryption
Definition: tls_cbc.h:105
Botan::TLS::Connection_Sequence_Numbers
Definition: tls_seq_numbers.h:17
Botan::TLS::Record_Type
Record_Type
Definition: tls_magic.h:29
Botan::AEAD_Mode
Definition: aead.h:22
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::TLS::Connection_Cipher_State::nonce_bytes_from_handshake
size_t nonce_bytes_from_handshake() const
Definition: tls_record.h:55
Botan::TLS::Ciphersuite::cipher_keylen
size_t cipher_keylen() const
Definition: tls_ciphersuite.h:100
Botan::TLS::Ciphersuite::mac_algo
std::string mac_algo() const
Definition: tls_ciphersuite.h:88
Botan::TLS::NO_RECORD
Definition: tls_magic.h:35
Botan::TLS::Ciphersuite::cipher_algo
std::string cipher_algo() const
Definition: tls_ciphersuite.h:83
Botan::make_uint16
uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:60
Botan::TLS::Alert::RECORD_OVERFLOW
Definition: tls_alert.h:32
Botan::CT::min
T min(T a, T b)
Definition: ct_utils.h:180
Botan::TLS::Session_Keys::server_iv
const InitializationVector & server_iv() const
Definition: tls_session_key.h:53
Botan::TLS::write_record
void write_record(secure_vector< uint8_t > &output, Record_Message msg, Protocol_Version version, uint64_t seq, Connection_Cipher_State *cs, RandomNumberGenerator &rng)
Definition: tls_record.cpp:213
Botan::get_byte
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:47
Botan::TLS::Record
Definition: tls_record.h:75
Botan::TLS::Session_Keys::client_cipher_key
const SymmetricKey & client_cipher_key() const
Definition: tls_session_key.h:28
Botan::TLS::TLS_HEADER_SIZE
Definition: tls_magic.h:19
Botan::TLS::Protocol_Version::is_datagram_protocol
bool is_datagram_protocol() const
Definition: tls_version.cpp:34
Botan::Cipher_Mode::finish
virtual void finish(secure_vector< uint8_t > &final_block, size_t offset=0)=0
Botan::TLS::Session_Keys::server_cipher_key
const SymmetricKey & server_cipher_key() const
Definition: tls_session_key.h:33
Botan::TLS::Connection_Cipher_State::cbc_nonce
bool cbc_nonce() const
Definition: tls_record.h:57