Coverage Report

Created: 2021-05-04 09:02

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