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