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()),
35 m_nonce_bytes_from_handshake(suite.nonce_bytes_from_handshake()),
36 m_nonce_bytes_from_record(suite.nonce_bytes_from_record())
63 m_aead->set_key(cipher_key + mac_key);
66 "Ciphersuite uses implemented IV length");
69 if(m_nonce.size() != 12)
71 m_nonce.resize(m_nonce.size() + 8);
76 #if defined(BOTAN_HAS_TLS_CBC)
86 uses_encrypt_then_mac));
96 uses_encrypt_then_mac));
99 m_aead->set_key(cipher_key + mac_key);
103 m_nonce_bytes_from_record = m_nonce_bytes_from_handshake;
104 else if(our_side ==
false)
107 throw Exception(
"Negotiated disabled TLS CBC+HMAC ciphersuite");
118 std::vector<uint8_t> nonce;
123 rng.
randomize(nonce.data(), nonce.size());
128 std::vector<uint8_t> nonce(12);
130 xor_buf(nonce, m_nonce.data(), m_nonce.size());
135 std::vector<uint8_t> nonce = m_nonce;
158 std::vector<uint8_t> nonce(12);
160 xor_buf(nonce, m_nonce.data(), m_nonce.size());
166 throw Decoding_Error(
"Invalid AEAD packet too short to be valid");
167 std::vector<uint8_t> nonce = m_nonce;
177 std::vector<uint8_t> nonce = m_nonce;
189 std::vector<uint8_t> ad(13);
205 const uint16_t len16 = len_field;
207 output.push_back(
get_byte(0, len16));
208 output.push_back(
get_byte(1, len16));
228 for(
size_t i = 0; i != 8; ++i)
234 append_u16_len(output, msg.
get_size());
248 const std::vector<uint8_t> nonce = cs->
aead_nonce(seq, rng);
250 append_u16_len(output, rec_size);
260 const size_t header_size = output.size();
264 aead->
finish(output, header_size);
267 "Produced ciphertext larger than protocol allows");
273 const uint8_t*& input,
275 size_t& input_consumed,
278 if(readbuf.size() >= desired)
281 const size_t taken =
std::min(input_size, desired - readbuf.size());
283 readbuf.insert(readbuf.end(), input, input + taken);
284 input_consumed += taken;
288 return (desired - readbuf.size());
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,
296 Connection_Cipher_State& cs)
298 AEAD_Mode* aead = cs.aead();
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();
305 const size_t ptext_size = aead->output_length(msg_length);
307 aead->set_associated_data_vec(
308 cs.format_ad(record_sequence, record_type, record_version, static_cast<uint16_t>(ptext_size))
313 const size_t offset = output.size();
314 output += std::make_pair(msg, msg_length);
315 aead->finish(output, offset);
318 size_t read_tls_record(secure_vector<uint8_t>& readbuf,
319 Record_Raw_Input& raw_input,
321 Connection_Sequence_Numbers* sequence_numbers,
326 if(
size_t needed = fill_buffer_to(readbuf,
327 raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
334 *rec.get_protocol_version() = Protocol_Version(readbuf[1], readbuf[2]);
336 BOTAN_ASSERT(!rec.get_protocol_version()->is_datagram_protocol(),
"Expected TLS");
343 "Received a record that exceeds maximum size");
347 "Received a completely empty record");
349 if(
size_t needed = fill_buffer_to(readbuf,
350 raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
356 "Have the full record");
358 *rec.get_type() =
static_cast<Record_Type>(readbuf[0]);
364 *rec.get_sequence() = sequence_numbers->next_read_sequence();
365 epoch = sequence_numbers->current_read_epoch();
370 *rec.get_sequence() = 0;
384 auto cs = get_cipherstate(epoch);
388 decrypt_record(rec.get_data(),
392 *rec.get_protocol_version(),
397 sequence_numbers->read_accept(*rec.get_sequence());
403 size_t read_dtls_record(secure_vector<uint8_t>& readbuf,
404 Record_Raw_Input& raw_input,
406 Connection_Sequence_Numbers* sequence_numbers,
411 if(fill_buffer_to(readbuf, raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
DTLS_HEADER_SIZE))
420 *rec.get_protocol_version() = Protocol_Version(readbuf[1], readbuf[2]);
422 BOTAN_ASSERT(rec.get_protocol_version()->is_datagram_protocol(),
"Expected DTLS");
429 "Got message that exceeds maximum size");
431 if(fill_buffer_to(readbuf, raw_input.get_data(), raw_input.get_size(), raw_input.get_consumed(),
DTLS_HEADER_SIZE + record_size))
439 "Have the full record");
441 *rec.get_type() =
static_cast<Record_Type>(readbuf[0]);
446 epoch = (*rec.get_sequence() >> 48);
448 if(sequence_numbers && sequence_numbers->already_seen(*rec.get_sequence()))
466 auto cs = get_cipherstate(epoch);
470 decrypt_record(rec.get_data(),
474 *rec.get_protocol_version(),
478 catch(std::exception)
486 sequence_numbers->read_accept(*rec.get_sequence());
501 return read_dtls_record(readbuf, raw_input, rec,
502 sequence_numbers, get_cipherstate);
504 return read_tls_record(readbuf, raw_input, rec,
505 sequence_numbers, get_cipherstate);
void xor_buf(T out[], const T in[], size_t length)
const InitializationVector & client_iv() const
secure_vector< uint8_t > bits_of() const
uint8_t minor_version() 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
const uint8_t * get_data()
size_t nonce_bytes_from_record() const
std::function< std::shared_ptr< Connection_Cipher_State >uint16_t)> get_cipherstate_fn
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)
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)
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
size_t mac_keylen() const
std::vector< T, secure_allocator< T >> secure_vector
const SymmetricKey & client_mac_key() const
bool supports_explicit_cbc_ivs() const
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
const SymmetricKey & server_mac_key() const
AEAD_Mode * get_aead(const std::string &algo, Cipher_Dir dir)
void copy_mem(T *out, const T *in, size_t n)
std::vector< T > unlock(const secure_vector< T > &in)
size_t nonce_bytes_from_handshake() const
size_t cipher_keylen() const
std::string mac_algo() const
std::string cipher_algo() const
uint16_t make_uint16(uint8_t i0, uint8_t i1)
const InitializationVector & server_iv() const
void write_record(secure_vector< uint8_t > &output, Record_Message msg, Protocol_Version version, uint64_t seq, Connection_Cipher_State *cs, RandomNumberGenerator &rng)
uint8_t get_byte(size_t byte_num, T input)
const SymmetricKey & client_cipher_key() const
bool is_datagram_protocol() const
virtual void finish(secure_vector< uint8_t > &final_block, size_t offset=0)=0
const SymmetricKey & server_cipher_key() const