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