Coverage Report

Created: 2021-02-21 07:20

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