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