/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 | | } |