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>
20 #if defined(BOTAN_HAS_TLS_CBC)
21 #include <botan/internal/tls_cbc.h>
33 bool uses_encrypt_then_mac) :
34 m_start_time(
std::chrono::system_clock::now())
41 m_nonce = keys.
nonce(side);
47 #if defined(BOTAN_HAS_TLS_CBC)
60 uses_encrypt_then_mac));
70 uses_encrypt_then_mac));
75 throw Internal_Error(
"Negotiated disabled TLS CBC+HMAC ciphersuite");
83 m_aead->set_key(aead_key);
88 switch(m_nonce_format)
94 std::vector<uint8_t> nonce;
99 rng.
randomize(nonce.data(), nonce.size());
104 std::vector<uint8_t> nonce(12);
106 xor_buf(nonce, m_nonce.data(), m_nonce.size());
112 std::vector<uint8_t> nonce(12);
113 copy_mem(&nonce[0], m_nonce.data(), 4);
125 switch(m_nonce_format)
131 std::vector<uint8_t> nonce;
142 std::vector<uint8_t> nonce(12);
144 xor_buf(nonce, m_nonce.data(), m_nonce.size());
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);
168 std::vector<uint8_t> ad(13);
184 const uint16_t len16 =
static_cast<uint16_t
>(len_field);
186 output.push_back(
get_byte(0, len16));
187 output.push_back(
get_byte(1, len16));
195 uint64_t record_sequence,
196 const uint8_t* message,
203 output.push_back(record_type);
209 for(
size_t i = 0; i != 8; ++i)
210 output.push_back(
get_byte(i, record_sequence));
215 append_u16_len(output, message_len);
216 output.insert(output.end(), message, message + message_len);
221 std::vector<uint8_t> aad = cs->
format_ad(record_sequence, record_type, version, static_cast<uint16_t>(message_len));
229 const std::vector<uint8_t> nonce = cs->
aead_nonce(record_sequence, rng);
231 append_u16_len(output, rec_size);
241 const size_t header_size = output.size();
242 output += std::make_pair(message, message_len);
245 aead.
finish(output, header_size);
248 "Produced ciphertext larger than protocol allows");
254 const uint8_t*& input,
256 size_t& input_consumed,
259 if(readbuf.size() >= desired)
262 const size_t taken = std::min(input_size, desired - readbuf.size());
264 readbuf.insert(readbuf.end(), input, input + taken);
265 input_consumed += taken;
269 return (desired - readbuf.size());
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,
277 Connection_Cipher_State& cs)
279 AEAD_Mode& aead = cs.aead();
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();
292 if(msg_length < aead.minimum_final_size())
295 const size_t ptext_size = aead.output_length(msg_length);
297 aead.set_associated_data_vec(
298 cs.format_ad(record_sequence,
299 static_cast<uint8_t>(record_type),
301 static_cast<uint16_t>(ptext_size))
306 output.assign(msg, msg + msg_length);
307 aead.finish(output, 0);
310 Record_Header read_tls_record(secure_vector<uint8_t>& readbuf,
311 const uint8_t input[],
314 secure_vector<uint8_t>& recbuf,
315 Connection_Sequence_Numbers* sequence_numbers,
320 if(
size_t needed = fill_buffer_to(readbuf, input, input_len, consumed,
TLS_HEADER_SIZE))
322 return Record_Header(needed);
328 const Protocol_Version version(readbuf[1], readbuf[2]);
330 if(version.is_datagram_protocol())
332 "Expected TLS but got a record with DTLS version");
339 "Received a record that exceeds maximum size");
343 "Received a completely empty record");
345 if(
size_t needed = fill_buffer_to(readbuf, input, input_len, consumed,
TLS_HEADER_SIZE + record_size))
347 return Record_Header(needed);
352 "Have the full record");
358 uint64_t sequence = 0;
361 sequence = sequence_numbers->next_read_sequence();
362 epoch = sequence_numbers->current_read_epoch();
374 return Record_Header(sequence, version, type);
378 auto cs = get_cipherstate(epoch);
382 decrypt_record(recbuf,
391 sequence_numbers->read_accept(sequence);
394 return Record_Header(sequence, version, type);
397 Record_Header read_dtls_record(secure_vector<uint8_t>& readbuf,
398 const uint8_t input[],
401 secure_vector<uint8_t>& recbuf,
402 Connection_Sequence_Numbers* sequence_numbers,
404 bool allow_epoch0_restart)
411 return Record_Header(0);
417 const Protocol_Version version(readbuf[1], readbuf[2]);
419 if(version.is_datagram_protocol() ==
false)
422 return Record_Header(0);
432 return Record_Header(0);
435 if(fill_buffer_to(readbuf, input, input_len, consumed,
DTLS_HEADER_SIZE + record_size))
439 return Record_Header(0);
443 "Have the full record");
448 const uint16_t epoch = (sequence >> 48);
450 const bool already_seen = sequence_numbers && sequence_numbers->already_seen(sequence);
452 if(already_seen && !(epoch == 0 && allow_epoch0_restart))
455 return Record_Header(0);
463 sequence_numbers->read_accept(sequence);
464 return Record_Header(sequence, version, type);
470 auto cs = get_cipherstate(epoch);
474 decrypt_record(recbuf,
482 catch(std::exception&)
485 return Record_Header(0);
489 sequence_numbers->read_accept(sequence);
492 return Record_Header(sequence, version, type);
499 const uint8_t input[],
505 bool allow_epoch0_restart)
508 return read_dtls_record(readbuf, input, input_len, consumed,
509 recbuf, sequence_numbers, get_cipherstate, allow_epoch0_restart);
511 return read_tls_record(readbuf, input, input_len, consumed,
512 recbuf, sequence_numbers, get_cipherstate);
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)
uint8_t minor_version() const
Nonce_Format nonce_format() const
std::vector< uint8_t > aead_nonce(uint64_t seq, RandomNumberGenerator &rng)
void store_be(uint16_t in, uint8_t out[2])
virtual void randomize(uint8_t output[], size_t length)=0
size_t nonce_bytes_from_record() const
std::function< std::shared_ptr< Connection_Cipher_State >uint16_t)> get_cipherstate_fn
constexpr uint8_t get_byte(size_t byte_num, T input)
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)
size_t nonce_bytes_from_record(Protocol_Version version) const
#define BOTAN_ASSERT_NOMSG(expr)
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)
void set_ad(const std::vector< uint8_t, Alloc > &ad)
const std::vector< uint8_t > & nonce(Connection_Side side) const
void start(const std::vector< uint8_t, Alloc > &nonce)
#define BOTAN_ASSERT(expr, assertion_made)
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
virtual size_t output_length(size_t input_length) const =0
Nonce_Format nonce_format() const
size_t mac_keylen() const
std::vector< T, secure_allocator< T >> secure_vector
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
std::vector< uint8_t > format_ad(uint64_t seq, uint8_t type, Protocol_Version version, uint16_t ptext_length)
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
uint8_t major_version() const
void copy_mem(T *out, const T *in, size_t n)
#define BOTAN_UNUSED(...)
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
size_t nonce_bytes_from_handshake() const
size_t cipher_keylen() const
std::string mac_algo() const
std::string cipher_algo() const
const secure_vector< uint8_t > & aead_key(Connection_Side side) const
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
size_t nonce_bytes_from_handshake() const
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
bool is_datagram_protocol() const
static std::unique_ptr< AEAD_Mode > create_or_throw(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
virtual void finish(secure_vector< uint8_t > &final_block, size_t offset=0)=0