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