Botan  2.12.1
Crypto and TLS for C++11
tls_cbc.cpp
Go to the documentation of this file.
1 /*
2 * TLS CBC Record Handling
3 * (C) 2012,2013,2014,2015,2016 Jack Lloyd
4 * (C) 2016 Juraj Somorovsky
5 * (C) 2016 Matthias Gierlings
6 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 */
10 
11 #include <botan/internal/tls_cbc.h>
12 #include <botan/cbc.h>
13 
14 #include <botan/internal/rounding.h>
15 #include <botan/internal/ct_utils.h>
16 #include <botan/loadstor.h>
17 #include <botan/tls_alert.h>
18 #include <botan/tls_exceptn.h>
19 
20 namespace Botan {
21 
22 namespace TLS {
23 
24 /*
25 * TLS_CBC_HMAC_AEAD_Mode Constructor
26 */
28  std::unique_ptr<BlockCipher> cipher,
29  std::unique_ptr<MessageAuthenticationCode> mac,
30  size_t cipher_keylen,
31  size_t mac_keylen,
32  Protocol_Version version,
33  bool use_encrypt_then_mac) :
34  m_cipher_name(cipher->name()),
35  m_mac_name(mac->name()),
36  m_cipher_keylen(cipher_keylen),
37  m_mac_keylen(mac_keylen),
38  m_use_encrypt_then_mac(use_encrypt_then_mac)
39  {
40  m_tag_size = mac->output_length();
41  m_block_size = cipher->block_size();
42 
43  m_iv_size = version.supports_explicit_cbc_ivs() ? m_block_size : 0;
44 
45  m_is_datagram = version.is_datagram_protocol();
46 
47  m_mac = std::move(mac);
48 
49  if(dir == ENCRYPTION)
50  m_cbc.reset(new CBC_Encryption(cipher.release(), new Null_Padding));
51  else
52  m_cbc.reset(new CBC_Decryption(cipher.release(), new Null_Padding));
53  }
54 
56  {
57  cbc().clear();
58  mac().clear();
59  reset();
60  }
61 
63  {
64  cbc_state().clear();
65  m_ad.clear();
66  m_msg.clear();
67  }
68 
69 std::string TLS_CBC_HMAC_AEAD_Mode::name() const
70  {
71  return "TLS_CBC(" + m_cipher_name + "," + m_mac_name + ")";
72  }
73 
75  {
76  return 1; // just buffers anyway
77  }
78 
80  {
81  if(m_cbc_state.empty())
82  return nl == block_size();
83  return nl == iv_size();
84  }
85 
87  {
88  return Key_Length_Specification(m_cipher_keylen + m_mac_keylen);
89  }
90 
91 void TLS_CBC_HMAC_AEAD_Mode::key_schedule(const uint8_t key[], size_t keylen)
92  {
93  // Both keys are of fixed length specified by the ciphersuite
94 
95  if(keylen != m_cipher_keylen + m_mac_keylen)
96  throw Invalid_Key_Length(name(), keylen);
97 
98  mac().set_key(&key[0], m_mac_keylen);
99  cbc().set_key(&key[m_mac_keylen], m_cipher_keylen);
100  }
101 
102 void TLS_CBC_HMAC_AEAD_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
103  {
104  if(!valid_nonce_length(nonce_len))
105  {
106  throw Invalid_IV_Length(name(), nonce_len);
107  }
108 
109  m_msg.clear();
110 
111  if(nonce_len > 0)
112  {
113  m_cbc_state.assign(nonce, nonce + nonce_len);
114  }
115  }
116 
117 size_t TLS_CBC_HMAC_AEAD_Mode::process(uint8_t buf[], size_t sz)
118  {
119  m_msg.insert(m_msg.end(), buf, buf + sz);
120  return 0;
121  }
122 
123 std::vector<uint8_t> TLS_CBC_HMAC_AEAD_Mode::assoc_data_with_len(uint16_t len)
124  {
125  std::vector<uint8_t> ad = m_ad;
126  BOTAN_ASSERT(ad.size() == 13, "Expected AAD size");
127  ad[11] = get_byte(0, len);
128  ad[12] = get_byte(1, len);
129  return ad;
130  }
131 
132 void TLS_CBC_HMAC_AEAD_Mode::set_associated_data(const uint8_t ad[], size_t ad_len)
133  {
134  if(ad_len != 13)
135  throw Invalid_Argument("Invalid TLS AEAD associated data length");
136  m_ad.assign(ad, ad + ad_len);
137  }
138 
139 void TLS_CBC_HMAC_AEAD_Encryption::set_associated_data(const uint8_t ad[], size_t ad_len)
140  {
142 
144  {
145  // AAD hack for EtM
146  const uint16_t pt_size = make_uint16(assoc_data()[11], assoc_data()[12]);
147  const uint16_t enc_size = static_cast<uint16_t>(round_up(iv_size() + pt_size + 1, block_size()));
148  assoc_data()[11] = get_byte<uint16_t>(0, enc_size);
149  assoc_data()[12] = get_byte<uint16_t>(1, enc_size);
150  }
151  }
152 
153 void TLS_CBC_HMAC_AEAD_Encryption::cbc_encrypt_record(uint8_t buf[], size_t buf_size)
154  {
155  cbc().start(cbc_state());
156  cbc().process(buf, buf_size);
157 
158  cbc_state().assign(buf + buf_size - block_size(), buf + buf_size);
159  }
160 
161 size_t TLS_CBC_HMAC_AEAD_Encryption::output_length(size_t input_length) const
162  {
163  return round_up(input_length + 1 + (use_encrypt_then_mac() ? 0 : tag_size()), block_size()) +
164  (use_encrypt_then_mac() ? tag_size() : 0);
165  }
166 
168  {
169  update(buffer, offset);
170  buffer.resize(offset); // truncate, leaving just header
171  const size_t header_size = offset;
172 
173  buffer.insert(buffer.end(), msg().begin(), msg().end());
174 
175  const size_t input_size = msg().size() + 1 + (use_encrypt_then_mac() ? 0 : tag_size());
176  const size_t enc_size = round_up(input_size, block_size());
177  const size_t pad_val = enc_size - input_size;
178  const size_t buf_size = enc_size + (use_encrypt_then_mac() ? tag_size() : 0);
179 
180  BOTAN_ASSERT(enc_size % block_size() == 0,
181  "Buffer is an even multiple of block size");
182 
183  mac().update(assoc_data());
184 
186  {
187  if(iv_size() > 0)
188  {
189  mac().update(cbc_state());
190  }
191 
192  for(size_t i = 0; i != pad_val + 1; ++i)
193  buffer.push_back(static_cast<uint8_t>(pad_val));
194  cbc_encrypt_record(&buffer[header_size], enc_size);
195  }
196 
197  // EtM also uses ciphertext size instead of plaintext size for AEAD input
198  const uint8_t* mac_input = (use_encrypt_then_mac() ? &buffer[header_size] : msg().data());
199  const size_t mac_input_len = (use_encrypt_then_mac() ? enc_size : msg().size());
200 
201  mac().update(mac_input, mac_input_len);
202 
203  buffer.resize(buffer.size() + tag_size());
204  mac().final(&buffer[buffer.size() - tag_size()]);
205 
206  if(use_encrypt_then_mac() == false)
207  {
208  for(size_t i = 0; i != pad_val + 1; ++i)
209  buffer.push_back(static_cast<uint8_t>(pad_val));
210  cbc_encrypt_record(&buffer[header_size], buf_size);
211  }
212  }
213 
214 /*
215 * Checks the TLS padding. Returns 0 if the padding is invalid (we
216 * count the padding_length field as part of the padding size so a
217 * valid padding will always be at least one byte long), or the length
218 * of the padding otherwise. This is actually padding_length + 1
219 * because both the padding and padding_length fields are padding from
220 * our perspective.
221 *
222 * Returning 0 in the error case should ensure the MAC check will fail.
223 * This approach is suggested in section 6.2.3.2 of RFC 5246.
224 */
225 uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len)
226  {
227  if(record_len == 0 || record_len > 0xFFFF)
228  return 0;
229 
230  const uint16_t rec16 = static_cast<uint16_t>(record_len);
231 
232  /*
233  * TLS v1.0 and up require all the padding bytes be the same value
234  * and allows up to 255 bytes.
235  */
236 
237  const uint16_t to_check = std::min<uint16_t>(256, static_cast<uint16_t>(record_len));
238  const uint8_t pad_byte = record[record_len-1];
239  const uint16_t pad_bytes = 1 + pad_byte;
240 
241  auto pad_invalid = CT::Mask<uint16_t>::is_lt(rec16, pad_bytes);
242 
243  for(uint16_t i = rec16 - to_check; i != rec16; ++i)
244  {
245  const uint16_t offset = rec16 - i;
246  const auto in_pad_range = CT::Mask<uint16_t>::is_lte(offset, pad_bytes);
247  const auto pad_correct = CT::Mask<uint16_t>::is_equal(record[i], pad_byte);
248  pad_invalid |= in_pad_range & ~pad_correct;
249  }
250 
251  return pad_invalid.if_not_set_return(pad_bytes);
252  }
253 
254 void TLS_CBC_HMAC_AEAD_Decryption::cbc_decrypt_record(uint8_t record_contents[], size_t record_len)
255  {
256  if(record_len == 0 || record_len % block_size() != 0)
257  throw Decoding_Error("Received TLS CBC ciphertext with invalid length");
258 
259  cbc().start(cbc_state());
260  cbc_state().assign(record_contents + record_len - block_size(),
261  record_contents + record_len);
262 
263  cbc().process(record_contents, record_len);
264  }
265 
267  {
268  /*
269  * We don't know this because the padding is arbitrary
270  */
271  return 0;
272  }
273 
274 /*
275 * This function performs additional compression calls in order
276 * to protect from the Lucky 13 attack. It adds new compression
277 * function calls over dummy data, by computing additional HMAC updates.
278 *
279 * The countermeasure was described (in a similar way) in the Lucky 13 paper.
280 *
281 * Background:
282 * - One SHA-1/SHA-256 compression is performed with 64 bytes of data.
283 * - HMAC adds 8 byte length field and padding (at least 1 byte) so that we have:
284 * - 0 - 55 bytes: 1 compression
285 * - 56 - 55+64 bytes: 2 compressions
286 * - 56+64 - 55+2*64 bytes: 3 compressions ...
287 * - For SHA-384, this works similarly, but we have 128 byte blocks and 16 byte
288 * long length field. This results in:
289 * - 0 - 111 bytes: 1 compression
290 * - 112 - 111+128 bytes: 2 compressions ...
291 *
292 * The implemented countermeasure works as follows:
293 * 1) It computes max_compressions: number of maximum compressions performed on
294 * the decrypted data
295 * 2) It computes current_compressions: number of compressions performed on the
296 * decrypted data, after padding has been removed
297 * 3) If current_compressions != max_compressions: It invokes an HMAC update
298 * over dummy data so that (max_compressions - current_compressions)
299 * compressions are performed. Otherwise, it invokes an HMAC update so that
300 * no compressions are performed.
301 *
302 * Note that the padding validation in Botan is always performed over
303 * min(plen,256) bytes, see the function check_tls_cbc_padding. This differs
304 * from the countermeasure described in the paper.
305 *
306 * Note that the padding length padlen does also count the last byte
307 * of the decrypted plaintext. This is different from the Lucky 13 paper.
308 *
309 * This countermeasure leaves a difference of about 100 clock cycles (in
310 * comparison to >1000 clock cycles observed without it).
311 *
312 * plen represents the length of the decrypted plaintext message P
313 * padlen represents the padding length
314 *
315 */
316 void TLS_CBC_HMAC_AEAD_Decryption::perform_additional_compressions(size_t plen, size_t padlen)
317  {
318  uint16_t block_size;
319  uint16_t max_bytes_in_first_block;
320  if(mac().name() == "HMAC(SHA-384)")
321  {
322  block_size = 128;
323  max_bytes_in_first_block = 111;
324  }
325  else
326  {
327  block_size = 64;
328  max_bytes_in_first_block = 55;
329  }
330  // number of maximum MACed bytes
331  const uint16_t L1 = static_cast<uint16_t>(13 + plen - tag_size());
332  // number of current MACed bytes (L1 - padlen)
333  // Here the Lucky 13 paper is different because the padlen length in the paper
334  // does not count the last message byte.
335  const uint16_t L2 = static_cast<uint16_t>(13 + plen - padlen - tag_size());
336  // From the paper, for SHA-256/SHA-1 compute: ceil((L1-55)/64) and ceil((L2-55)/64)
337  // ceil((L1-55)/64) = floor((L1+64-1-55)/64)
338  // Here we compute number of compressions for SHA-* in general
339  const uint16_t max_compresssions = ( (L1 + block_size - 1 - max_bytes_in_first_block) / block_size);
340  const uint16_t current_compressions = ((L2 + block_size - 1 - max_bytes_in_first_block) / block_size);
341  // number of additional compressions we have to perform
342  const uint16_t add_compressions = max_compresssions - current_compressions;
343  const uint16_t equal = CT::Mask<uint16_t>::is_equal(max_compresssions, current_compressions).if_set_return(1);
344  // We compute the data length we need to achieve the number of compressions.
345  // If there are no compressions, we just add 55/111 dummy bytes so that no
346  // compression is performed.
347  const uint16_t data_len = block_size * add_compressions + equal * max_bytes_in_first_block;
348  std::vector<uint8_t> data(data_len);
349  mac().update(data);
350  // we do not need to clear the MAC since the connection is broken anyway
351  }
352 
354  {
355  update(buffer, offset);
356  buffer.resize(offset);
357 
358  const size_t record_len = msg().size();
359  uint8_t* record_contents = msg().data();
360 
361  // This early exit does not leak info because all the values compared are public
362  if(record_len < tag_size() ||
363  (record_len - (use_encrypt_then_mac() ? tag_size() : 0)) % block_size() != 0)
364  {
365  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
366  }
367 
369  {
370  const size_t enc_size = record_len - tag_size();
371  const size_t enc_iv_size = enc_size + iv_size();
372 
373  BOTAN_ASSERT_NOMSG(enc_iv_size <= 0xFFFF);
374 
375  mac().update(assoc_data_with_len(static_cast<uint16_t>(enc_iv_size)));
376  if(iv_size() > 0)
377  {
378  mac().update(cbc_state());
379  }
380  mac().update(record_contents, enc_size);
381 
382  std::vector<uint8_t> mac_buf(tag_size());
383  mac().final(mac_buf.data());
384 
385  const size_t mac_offset = enc_size;
386 
387  const bool mac_ok = constant_time_compare(&record_contents[mac_offset], mac_buf.data(), tag_size());
388 
389  if(!mac_ok)
390  {
391  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
392  }
393 
394  cbc_decrypt_record(record_contents, enc_size);
395 
396  // 0 if padding was invalid, otherwise 1 + padding_bytes
397  const uint16_t pad_size = check_tls_cbc_padding(record_contents, enc_size);
398 
399  // No oracle here, whoever sent us this had the key since MAC check passed
400  if(pad_size == 0)
401  {
402  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
403  }
404 
405  const uint8_t* plaintext_block = &record_contents[0];
406  const size_t plaintext_length = enc_size - pad_size;
407 
408  buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
409  }
410  else
411  {
412  cbc_decrypt_record(record_contents, record_len);
413 
414  CT::poison(record_contents, record_len);
415 
416  // 0 if padding was invalid, otherwise 1 + padding_bytes
417  uint16_t pad_size = check_tls_cbc_padding(record_contents, record_len);
418 
419  /*
420  This mask is zero if there is not enough room in the packet to get a valid MAC.
421 
422  We have to accept empty packets, since otherwise we are not compatible
423  with how OpenSSL's countermeasure for fixing BEAST in TLS 1.0 CBC works
424  (sending empty records, instead of 1/(n-1) splitting)
425  */
426 
427  // We know the cast cannot overflow as pad_size <= 256 && tag_size <= 32
428  const auto size_ok_mask = CT::Mask<uint16_t>::is_lte(
429  static_cast<uint16_t>(tag_size() + pad_size),
430  static_cast<uint16_t>(record_len));
431 
432  pad_size = size_ok_mask.if_set_return(pad_size);
433 
434  CT::unpoison(record_contents, record_len);
435 
436  /*
437  This is unpoisoned sooner than it should. The pad_size leaks to plaintext_length and
438  then to the timing channel in the MAC computation described in the Lucky 13 paper.
439  */
440  CT::unpoison(pad_size);
441 
442  const uint8_t* plaintext_block = &record_contents[0];
443  const uint16_t plaintext_length = static_cast<uint16_t>(record_len - tag_size() - pad_size);
444 
445  mac().update(assoc_data_with_len(plaintext_length));
446  mac().update(plaintext_block, plaintext_length);
447 
448  std::vector<uint8_t> mac_buf(tag_size());
449  mac().final(mac_buf.data());
450 
451  const size_t mac_offset = record_len - (tag_size() + pad_size);
452 
453  const bool mac_ok = constant_time_compare(&record_contents[mac_offset], mac_buf.data(), tag_size());
454 
455  const auto ok_mask = size_ok_mask & CT::Mask<uint16_t>::expand(mac_ok) & CT::Mask<uint16_t>::expand(pad_size);
456 
457  CT::unpoison(ok_mask);
458 
459  if(ok_mask.is_set())
460  {
461  buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
462  }
463  else
464  {
465  perform_additional_compressions(record_len, pad_size);
466 
467  /*
468  * In DTLS case we have to finish computing the MAC since we require the
469  * MAC state be reset for future packets. This extra timing channel may
470  * be exploitable in a Lucky13 variant.
471  */
473  mac().final(mac_buf);
474  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
475  }
476  }
477  }
478 
479 }
480 
481 }
size_t process(uint8_t buf[], size_t sz) override final
Definition: tls_cbc.cpp:117
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: tls_cbc.cpp:167
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
Definition: cipher_mode.h:112
Cipher_Mode & cbc() const
Definition: tls_cbc.h:66
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
TLS_CBC_HMAC_AEAD_Mode(Cipher_Dir direction, std::unique_ptr< BlockCipher > cipher, std::unique_ptr< MessageAuthenticationCode > mac, size_t cipher_keylen, size_t mac_keylen, Protocol_Version version, bool use_encrypt_then_mac)
Definition: tls_cbc.cpp:27
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
void poison(const T *p, size_t n)
Definition: ct_utils.h:48
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: tls_cbc.cpp:353
MessageAuthenticationCode & mac() const
Definition: tls_cbc.h:68
std::string m_cipher_name
void start(const std::vector< uint8_t, Alloc > &nonce)
Definition: cipher_mode.h:69
Key_Length_Specification key_spec() const override final
Definition: tls_cbc.cpp:86
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: tls_cbc.cpp:132
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
secure_vector< uint8_t > & cbc_state()
Definition: tls_cbc.h:74
void final(uint8_t out[])
Definition: buf_comp.h:83
static Mask< T > is_lte(T x, T y)
Definition: ct_utils.h:173
static Mask< T > expand(T v)
Definition: ct_utils.h:123
std::string name
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:65
bool valid_nonce_length(size_t nl) const override final
Definition: tls_cbc.cpp:79
void clear() override final
Definition: tls_cbc.cpp:55
std::string name() const override final
Definition: tls_cbc.cpp:69
bool supports_explicit_cbc_ivs() const
Definition: tls_version.cpp:67
virtual void clear()=0
size_t tag_size() const override final
Definition: tls_cbc.h:40
std::vector< uint8_t > & assoc_data()
Definition: tls_cbc.h:75
Definition: alg_id.cpp:13
size_t update_granularity() const override final
Definition: tls_cbc.cpp:74
virtual size_t process(uint8_t msg[], size_t msg_len)=0
std::vector< uint8_t > assoc_data_with_len(uint16_t len)
Definition: tls_cbc.cpp:123
Cipher_Dir
Definition: cipher_mode.h:23
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:33
uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len)
Definition: tls_cbc.cpp:225
void reset() override final
Definition: tls_cbc.cpp:62
size_t output_length(size_t input_length) const override
Definition: tls_cbc.cpp:161
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:59
secure_vector< uint8_t > & msg()
Definition: tls_cbc.h:76
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:54
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:21
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149
virtual size_t output_length() const =0
size_t output_length(size_t input_length) const override
Definition: tls_cbc.cpp:266
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: tls_cbc.cpp:139
static Mask< T > is_lt(T x, T y)
Definition: ct_utils.h:157