Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2000-2013 Free Software Foundation, Inc. |
3 | | * Copyright (C) 2013 Nikos Mavrogiannopoulos |
4 | | * Copyright (C) 2017-2018 Red Hat, Inc. |
5 | | * |
6 | | * Author: Nikos Mavrogiannopoulos |
7 | | * |
8 | | * This file is part of GnuTLS. |
9 | | * |
10 | | * The GnuTLS is free software; you can redistribute it and/or |
11 | | * modify it under the terms of the GNU Lesser General Public License |
12 | | * as published by the Free Software Foundation; either version 2.1 of |
13 | | * the License, or (at your option) any later version. |
14 | | * |
15 | | * This library is distributed in the hope that it will be useful, but |
16 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | | * Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public License |
21 | | * along with this program. If not, see <https://www.gnu.org/licenses/> |
22 | | * |
23 | | */ |
24 | | |
25 | | /* Some high level functions to be used in the record encryption are |
26 | | * included here. |
27 | | */ |
28 | | |
29 | | #include "gnutls_int.h" |
30 | | #include "errors.h" |
31 | | #include "cipher.h" |
32 | | #include "algorithms.h" |
33 | | #include "hash_int.h" |
34 | | #include "cipher_int.h" |
35 | | #include "debug.h" |
36 | | #include "num.h" |
37 | | #include "datum.h" |
38 | | #include "kx.h" |
39 | | #include "record.h" |
40 | | #include "constate.h" |
41 | | #include "mbuffers.h" |
42 | | #include <state.h> |
43 | | #include <random.h> |
44 | | |
45 | | #include <nettle/memxor.h> |
46 | | |
47 | | static int encrypt_packet(gnutls_session_t session, |
48 | | uint8_t * cipher_data, int cipher_size, |
49 | | gnutls_datum_t * plain, |
50 | | size_t min_pad, |
51 | | content_type_t _type, record_parameters_st * params); |
52 | | |
53 | | static int decrypt_packet(gnutls_session_t session, |
54 | | gnutls_datum_t * ciphertext, |
55 | | gnutls_datum_t * plain, |
56 | | content_type_t type, |
57 | | record_parameters_st * params, uint64_t sequence); |
58 | | |
59 | | static int |
60 | | decrypt_packet_tls13(gnutls_session_t session, |
61 | | gnutls_datum_t * ciphertext, |
62 | | gnutls_datum_t * plain, |
63 | | content_type_t * type, record_parameters_st * params, |
64 | | uint64_t sequence); |
65 | | |
66 | | static int |
67 | | encrypt_packet_tls13(gnutls_session_t session, |
68 | | uint8_t * cipher_data, size_t cipher_size, |
69 | | gnutls_datum_t * plain, |
70 | | size_t pad_size, |
71 | | uint8_t type, record_parameters_st * params); |
72 | | |
73 | | /* returns ciphertext which contains the headers too. This also |
74 | | * calculates the size in the header field. |
75 | | * |
76 | | */ |
77 | | int |
78 | | _gnutls_encrypt(gnutls_session_t session, |
79 | | const uint8_t * data, size_t data_size, |
80 | | size_t min_pad, |
81 | | mbuffer_st * bufel, |
82 | | content_type_t type, record_parameters_st * params) |
83 | 0 | { |
84 | 0 | gnutls_datum_t plaintext; |
85 | 0 | const version_entry_st *vers = |
86 | 0 | (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) && |
87 | 0 | !IS_SERVER(session) ? |
88 | 0 | session->internals.resumed_security_parameters.pversion : |
89 | 0 | get_version(session); |
90 | 0 | int ret; |
91 | |
|
92 | 0 | plaintext.data = (uint8_t *) data; |
93 | 0 | plaintext.size = data_size; |
94 | |
|
95 | 0 | if (vers && vers->tls13_sem) { |
96 | | /* it fills the header, as it is included in the authenticated |
97 | | * data of the AEAD cipher. */ |
98 | 0 | ret = |
99 | 0 | encrypt_packet_tls13(session, |
100 | 0 | _mbuffer_get_udata_ptr(bufel), |
101 | 0 | _mbuffer_get_udata_size(bufel), |
102 | 0 | &plaintext, min_pad, type, params); |
103 | 0 | if (ret < 0) |
104 | 0 | return gnutls_assert_val(ret); |
105 | 0 | } else { |
106 | 0 | ret = |
107 | 0 | encrypt_packet(session, |
108 | 0 | _mbuffer_get_udata_ptr(bufel), |
109 | 0 | _mbuffer_get_udata_size |
110 | 0 | (bufel), &plaintext, min_pad, type, params); |
111 | 0 | if (ret < 0) |
112 | 0 | return gnutls_assert_val(ret); |
113 | |
|
114 | 0 | } |
115 | | |
116 | 0 | if (IS_DTLS(session)) |
117 | 0 | _gnutls_write_uint16(ret, ((uint8_t *) |
118 | 0 | _mbuffer_get_uhead_ptr(bufel)) + 11); |
119 | 0 | else |
120 | 0 | _gnutls_write_uint16(ret, ((uint8_t *) |
121 | 0 | _mbuffer_get_uhead_ptr(bufel)) + 3); |
122 | |
|
123 | 0 | _mbuffer_set_udata_size(bufel, ret); |
124 | 0 | _mbuffer_set_uhead_size(bufel, 0); |
125 | |
|
126 | 0 | return _mbuffer_get_udata_size(bufel); |
127 | 0 | } |
128 | | |
129 | | /* Decrypts the given data. |
130 | | * Returns the decrypted data length. |
131 | | * |
132 | | * The output is preallocated with the maximum allowed data size. |
133 | | */ |
134 | | int |
135 | | _gnutls_decrypt(gnutls_session_t session, |
136 | | gnutls_datum_t * ciphertext, |
137 | | gnutls_datum_t * output, |
138 | | content_type_t * type, |
139 | | record_parameters_st * params, uint64_t sequence) |
140 | 0 | { |
141 | 0 | int ret; |
142 | 0 | const version_entry_st *vers = get_version(session); |
143 | |
|
144 | 0 | if (ciphertext->size == 0) |
145 | 0 | return 0; |
146 | | |
147 | 0 | if (vers && vers->tls13_sem) |
148 | 0 | ret = |
149 | 0 | decrypt_packet_tls13(session, ciphertext, |
150 | 0 | output, type, params, sequence); |
151 | 0 | else |
152 | 0 | ret = |
153 | 0 | decrypt_packet(session, ciphertext, |
154 | 0 | output, *type, params, sequence); |
155 | 0 | if (ret < 0) |
156 | 0 | return gnutls_assert_val(ret); |
157 | | |
158 | 0 | return ret; |
159 | 0 | } |
160 | | |
161 | | inline static int |
162 | | calc_enc_length_block(gnutls_session_t session, |
163 | | const version_entry_st * ver, |
164 | | int data_size, |
165 | | int hash_size, uint8_t * pad, |
166 | | unsigned auth_cipher, uint16_t blocksize, unsigned etm) |
167 | 0 | { |
168 | | /* pad is the LH pad the user wants us to add. Besides |
169 | | * this LH pad, we only add minimal padding |
170 | | */ |
171 | 0 | unsigned int pre_length = data_size + *pad; |
172 | 0 | unsigned int length, new_pad; |
173 | |
|
174 | 0 | if (etm == 0) |
175 | 0 | pre_length += hash_size; |
176 | |
|
177 | 0 | new_pad = (uint8_t) (blocksize - (pre_length % blocksize)) + *pad; |
178 | |
|
179 | 0 | if (new_pad > 255) |
180 | 0 | new_pad -= blocksize; |
181 | 0 | *pad = new_pad; |
182 | |
|
183 | 0 | length = data_size + hash_size + *pad; |
184 | |
|
185 | 0 | if (_gnutls_version_has_explicit_iv(ver)) |
186 | 0 | length += blocksize; /* for the IV */ |
187 | |
|
188 | 0 | return length; |
189 | 0 | } |
190 | | |
191 | | inline static int |
192 | | calc_enc_length_stream(gnutls_session_t session, int data_size, |
193 | | int hash_size, unsigned auth_cipher, |
194 | | unsigned exp_iv_size) |
195 | 0 | { |
196 | 0 | unsigned int length; |
197 | |
|
198 | 0 | length = data_size + hash_size; |
199 | 0 | if (auth_cipher) |
200 | 0 | length += exp_iv_size; |
201 | |
|
202 | 0 | return length; |
203 | 0 | } |
204 | | |
205 | | /* generates the authentication data (data to be hashed only |
206 | | * and are not to be sent). Returns their size. |
207 | | */ |
208 | | int |
209 | | _gnutls_make_preamble(uint64_t uint64_data, uint8_t type, unsigned int length, |
210 | | const version_entry_st * ver, |
211 | | uint8_t preamble[MAX_PREAMBLE_SIZE]) |
212 | 0 | { |
213 | 0 | uint8_t *p = preamble; |
214 | 0 | uint16_t c_length; |
215 | |
|
216 | 0 | c_length = _gnutls_conv_uint16(length); |
217 | |
|
218 | 0 | _gnutls_write_uint64(uint64_data, p); |
219 | 0 | p += 8; |
220 | 0 | *p = type; |
221 | 0 | p++; |
222 | | #ifdef ENABLE_SSL3 |
223 | | if (ver->id != GNUTLS_SSL3) |
224 | | #endif |
225 | 0 | { /* TLS protocols */ |
226 | 0 | *p = ver->major; |
227 | 0 | p++; |
228 | 0 | *p = ver->minor; |
229 | 0 | p++; |
230 | 0 | } |
231 | 0 | memcpy(p, &c_length, 2); |
232 | 0 | p += 2; |
233 | 0 | return p - preamble; |
234 | 0 | } |
235 | | |
236 | | /* This is the actual encryption |
237 | | * Encrypts the given plaintext datum, and puts the result to cipher_data, |
238 | | * which has cipher_size size. |
239 | | * return the actual encrypted data length. |
240 | | */ |
241 | | static int |
242 | | encrypt_packet(gnutls_session_t session, |
243 | | uint8_t * cipher_data, int cipher_size, |
244 | | gnutls_datum_t * plain, |
245 | | size_t min_pad, |
246 | | content_type_t type, record_parameters_st * params) |
247 | 0 | { |
248 | 0 | uint8_t pad; |
249 | 0 | int length, ret; |
250 | 0 | uint8_t preamble[MAX_PREAMBLE_SIZE]; |
251 | 0 | int preamble_size; |
252 | 0 | int tag_size = _gnutls_auth_cipher_tag_len(¶ms->write.ctx.tls12); |
253 | 0 | int blocksize = _gnutls_cipher_get_block_size(params->cipher); |
254 | 0 | unsigned algo_type = _gnutls_cipher_type(params->cipher); |
255 | 0 | uint8_t *data_ptr, *full_cipher_ptr; |
256 | 0 | const version_entry_st *ver = get_version(session); |
257 | 0 | int explicit_iv = _gnutls_version_has_explicit_iv(ver); |
258 | 0 | int auth_cipher = _gnutls_auth_cipher_is_aead(¶ms->write.ctx.tls12); |
259 | 0 | uint8_t nonce[MAX_CIPHER_IV_SIZE]; |
260 | 0 | unsigned imp_iv_size = 0, exp_iv_size = 0; |
261 | 0 | bool etm = 0; |
262 | |
|
263 | 0 | if (unlikely(ver == NULL)) |
264 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
265 | | |
266 | 0 | if (algo_type == CIPHER_BLOCK && params->etm != 0) |
267 | 0 | etm = 1; |
268 | |
|
269 | 0 | _gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n", |
270 | 0 | session, _gnutls_cipher_get_name(params->cipher), |
271 | 0 | _gnutls_mac_get_name(params->mac), |
272 | 0 | (unsigned int)params->epoch); |
273 | | |
274 | | /* Calculate the encrypted length (padding etc.) |
275 | | */ |
276 | 0 | if (algo_type == CIPHER_BLOCK) { |
277 | | /* Call gnutls_rnd() once. Get data used for the IV |
278 | | */ |
279 | 0 | ret = gnutls_rnd(GNUTLS_RND_NONCE, nonce, blocksize); |
280 | 0 | if (ret < 0) |
281 | 0 | return gnutls_assert_val(ret); |
282 | | |
283 | 0 | pad = min_pad; |
284 | |
|
285 | 0 | length = |
286 | 0 | calc_enc_length_block(session, ver, plain->size, |
287 | 0 | tag_size, &pad, auth_cipher, |
288 | 0 | blocksize, etm); |
289 | 0 | } else { /* AEAD + STREAM */ |
290 | 0 | imp_iv_size = |
291 | 0 | _gnutls_cipher_get_implicit_iv_size(params->cipher); |
292 | 0 | exp_iv_size = |
293 | 0 | _gnutls_cipher_get_explicit_iv_size(params->cipher); |
294 | |
|
295 | 0 | pad = 0; |
296 | 0 | length = |
297 | 0 | calc_enc_length_stream(session, plain->size, |
298 | 0 | tag_size, auth_cipher, exp_iv_size); |
299 | 0 | } |
300 | | |
301 | 0 | if (length < 0) |
302 | 0 | return gnutls_assert_val(length); |
303 | | |
304 | | /* copy the encrypted data to cipher_data. |
305 | | */ |
306 | 0 | if (cipher_size < length) |
307 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
308 | | |
309 | 0 | data_ptr = cipher_data; |
310 | 0 | full_cipher_ptr = data_ptr; |
311 | |
|
312 | 0 | if (algo_type == CIPHER_BLOCK || algo_type == CIPHER_STREAM) { |
313 | 0 | if (algo_type == CIPHER_BLOCK && explicit_iv != 0) { |
314 | | /* copy the random IV. |
315 | | */ |
316 | 0 | memcpy(data_ptr, nonce, blocksize); |
317 | 0 | ret = |
318 | 0 | _gnutls_auth_cipher_setiv(¶ms->write.ctx.tls12, |
319 | 0 | data_ptr, blocksize); |
320 | 0 | if (ret < 0) |
321 | 0 | return gnutls_assert_val(ret); |
322 | | |
323 | | /*data_ptr += blocksize; */ |
324 | 0 | cipher_data += blocksize; |
325 | 0 | } |
326 | 0 | } else { /* AEAD */ |
327 | 0 | if ((params->cipher->flags & GNUTLS_CIPHER_FLAG_XOR_NONCE) == 0) { |
328 | | /* Values in AEAD are pretty fixed in TLS 1.2 for 128-bit block |
329 | | */ |
330 | 0 | if (params->write.iv_size != imp_iv_size) |
331 | 0 | return |
332 | 0 | gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
333 | | |
334 | | /* Instead of generating a new nonce on every packet, we use the |
335 | | * write.sequence_number (It is a MAY on RFC 5288), and safer |
336 | | * as it will never reuse a value. |
337 | | */ |
338 | 0 | memcpy(nonce, params->write.iv, params->write.iv_size); |
339 | 0 | _gnutls_write_uint64(params->write.sequence_number, |
340 | 0 | &nonce[imp_iv_size]); |
341 | |
|
342 | 0 | memcpy(data_ptr, &nonce[imp_iv_size], exp_iv_size); |
343 | | |
344 | | /*data_ptr += exp_iv_size; */ |
345 | 0 | cipher_data += exp_iv_size; |
346 | 0 | } else { /* XOR nonce with IV */ |
347 | 0 | if (unlikely |
348 | 0 | (params->write.iv_size != 12 || imp_iv_size != 12 |
349 | 0 | || exp_iv_size != 0)) |
350 | 0 | return |
351 | 0 | gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
352 | | |
353 | 0 | memset(nonce, 0, 4); |
354 | 0 | _gnutls_write_uint64(params->write.sequence_number, |
355 | 0 | &nonce[4]); |
356 | |
|
357 | 0 | memxor(nonce, params->write.iv, 12); |
358 | 0 | } |
359 | 0 | } |
360 | | |
361 | 0 | if (etm) |
362 | 0 | ret = length - tag_size; |
363 | 0 | else |
364 | 0 | ret = plain->size; |
365 | |
|
366 | 0 | preamble_size = |
367 | 0 | _gnutls_make_preamble(params->write.sequence_number, |
368 | 0 | type, ret, ver, preamble); |
369 | |
|
370 | 0 | if (algo_type == CIPHER_BLOCK || algo_type == CIPHER_STREAM) { |
371 | | /* add the authenticated data */ |
372 | 0 | ret = |
373 | 0 | _gnutls_auth_cipher_add_auth(¶ms->write.ctx.tls12, |
374 | 0 | preamble, preamble_size); |
375 | 0 | if (ret < 0) |
376 | 0 | return gnutls_assert_val(ret); |
377 | | |
378 | 0 | if (etm && explicit_iv) { |
379 | | /* In EtM we need to hash the IV as well */ |
380 | 0 | ret = |
381 | 0 | _gnutls_auth_cipher_add_auth(¶ms->write. |
382 | 0 | ctx.tls12, |
383 | 0 | full_cipher_ptr, |
384 | 0 | blocksize); |
385 | 0 | if (ret < 0) |
386 | 0 | return gnutls_assert_val(ret); |
387 | 0 | } |
388 | | |
389 | | /* Actual encryption. |
390 | | */ |
391 | 0 | ret = |
392 | 0 | _gnutls_auth_cipher_encrypt2_tag(¶ms->write.ctx.tls12, |
393 | 0 | plain->data, |
394 | 0 | plain->size, cipher_data, |
395 | 0 | cipher_size, pad); |
396 | 0 | if (ret < 0) |
397 | 0 | return gnutls_assert_val(ret); |
398 | 0 | } else { /* AEAD */ |
399 | 0 | ret = |
400 | 0 | _gnutls_aead_cipher_encrypt(¶ms->write.ctx.tls12.cipher, |
401 | 0 | nonce, |
402 | 0 | imp_iv_size + exp_iv_size, |
403 | 0 | preamble, preamble_size, |
404 | 0 | tag_size, plain->data, |
405 | 0 | plain->size, cipher_data, |
406 | 0 | cipher_size); |
407 | 0 | if (ret < 0) |
408 | 0 | return gnutls_assert_val(ret); |
409 | 0 | } |
410 | | |
411 | 0 | return length; |
412 | 0 | } |
413 | | |
414 | | static int |
415 | | encrypt_packet_tls13(gnutls_session_t session, |
416 | | uint8_t * cipher_data, size_t cipher_size, |
417 | | gnutls_datum_t * plain, |
418 | | size_t pad_size, |
419 | | uint8_t type, record_parameters_st * params) |
420 | 0 | { |
421 | 0 | int ret; |
422 | 0 | unsigned int tag_size = params->write.aead_tag_size; |
423 | 0 | const version_entry_st *ver = get_version(session); |
424 | 0 | uint8_t nonce[MAX_CIPHER_IV_SIZE]; |
425 | 0 | unsigned iv_size = 0; |
426 | 0 | ssize_t max, total; |
427 | 0 | uint8_t aad[5]; |
428 | 0 | giovec_t auth_iov[1]; |
429 | 0 | giovec_t iov[2]; |
430 | |
|
431 | 0 | if (unlikely(ver == NULL)) |
432 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
433 | | |
434 | 0 | _gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n", |
435 | 0 | session, _gnutls_cipher_get_name(params->cipher), |
436 | 0 | _gnutls_mac_get_name(params->mac), |
437 | 0 | (unsigned int)params->epoch); |
438 | |
|
439 | 0 | iv_size = params->write.iv_size; |
440 | |
|
441 | 0 | if (params->cipher->id == GNUTLS_CIPHER_NULL) { |
442 | 0 | if (cipher_size < plain->size + 1) |
443 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
444 | 0 | memcpy(cipher_data, plain->data, plain->size); |
445 | 0 | return plain->size; |
446 | 0 | } |
447 | | |
448 | 0 | if (unlikely(iv_size < 8)) |
449 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
450 | | |
451 | 0 | memset(nonce, 0, iv_size - 8); |
452 | 0 | _gnutls_write_uint64(params->write.sequence_number, |
453 | 0 | &nonce[iv_size - 8]); |
454 | 0 | memxor(nonce, params->write.iv, iv_size); |
455 | |
|
456 | 0 | max = max_record_send_size(session) + MAX_RECORD_SEND_OVERHEAD(session); |
457 | | |
458 | | /* make TLS 1.3 form of data */ |
459 | 0 | total = plain->size + 1 + pad_size; |
460 | | |
461 | | /* check whether padding would exceed max */ |
462 | 0 | if (total > max) { |
463 | 0 | if (unlikely(max < (ssize_t) plain->size + 1)) |
464 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
465 | | |
466 | 0 | pad_size = max - plain->size - 1; |
467 | 0 | total = max; |
468 | 0 | } |
469 | | |
470 | | /* create authenticated data header */ |
471 | 0 | aad[0] = GNUTLS_APPLICATION_DATA; |
472 | 0 | aad[1] = 0x03; |
473 | 0 | aad[2] = 0x03; |
474 | 0 | _gnutls_write_uint16(total + tag_size, &aad[3]); |
475 | |
|
476 | 0 | auth_iov[0].iov_base = aad; |
477 | 0 | auth_iov[0].iov_len = sizeof(aad); |
478 | |
|
479 | 0 | iov[0].iov_base = plain->data; |
480 | 0 | iov[0].iov_len = plain->size; |
481 | |
|
482 | 0 | if (pad_size || (session->internals.flags & GNUTLS_SAFE_PADDING_CHECK)) { |
483 | 0 | uint8_t *pad = gnutls_calloc(1, 1 + pad_size); |
484 | 0 | if (pad == NULL) |
485 | 0 | return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); |
486 | | |
487 | 0 | pad[0] = type; |
488 | |
|
489 | 0 | iov[1].iov_base = pad; |
490 | 0 | iov[1].iov_len = 1 + pad_size; |
491 | |
|
492 | 0 | ret = gnutls_aead_cipher_encryptv(¶ms->write.ctx.aead, |
493 | 0 | nonce, iv_size, |
494 | 0 | auth_iov, 1, |
495 | 0 | tag_size, |
496 | 0 | iov, 2, |
497 | 0 | cipher_data, &cipher_size); |
498 | 0 | gnutls_free(pad); |
499 | 0 | } else { |
500 | 0 | iov[1].iov_base = &type; |
501 | 0 | iov[1].iov_len = 1; |
502 | |
|
503 | 0 | ret = gnutls_aead_cipher_encryptv(¶ms->write.ctx.aead, |
504 | 0 | nonce, iv_size, |
505 | 0 | auth_iov, 1, |
506 | 0 | tag_size, |
507 | 0 | iov, 2, |
508 | 0 | cipher_data, &cipher_size); |
509 | 0 | } |
510 | | |
511 | 0 | if (ret < 0) |
512 | 0 | return gnutls_assert_val(ret); |
513 | | |
514 | 0 | return cipher_size; |
515 | 0 | } |
516 | | |
517 | | /* Deciphers the ciphertext packet, and puts the result to plain. |
518 | | * Returns the actual plaintext packet size. |
519 | | */ |
520 | | static int |
521 | | decrypt_packet(gnutls_session_t session, |
522 | | gnutls_datum_t * ciphertext, |
523 | | gnutls_datum_t * plain, |
524 | | content_type_t type, record_parameters_st * params, |
525 | | uint64_t sequence) |
526 | 0 | { |
527 | 0 | uint8_t tag[MAX_HASH_SIZE]; |
528 | 0 | uint8_t nonce[MAX_CIPHER_IV_SIZE]; |
529 | 0 | const uint8_t *tag_ptr = NULL; |
530 | 0 | unsigned int pad = 0; |
531 | 0 | int length, length_to_decrypt; |
532 | 0 | uint16_t blocksize; |
533 | 0 | int ret; |
534 | 0 | uint8_t preamble[MAX_PREAMBLE_SIZE]; |
535 | 0 | unsigned int preamble_size = 0; |
536 | 0 | const version_entry_st *ver = get_version(session); |
537 | 0 | unsigned int tag_size = |
538 | 0 | _gnutls_auth_cipher_tag_len(¶ms->read.ctx.tls12); |
539 | 0 | unsigned int explicit_iv = _gnutls_version_has_explicit_iv(ver); |
540 | 0 | unsigned imp_iv_size, exp_iv_size; |
541 | 0 | unsigned cipher_type = _gnutls_cipher_type(params->cipher); |
542 | 0 | bool etm = 0; |
543 | |
|
544 | 0 | if (unlikely(ver == NULL)) |
545 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
546 | | |
547 | 0 | imp_iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher); |
548 | 0 | exp_iv_size = _gnutls_cipher_get_explicit_iv_size(params->cipher); |
549 | 0 | blocksize = _gnutls_cipher_get_block_size(params->cipher); |
550 | |
|
551 | 0 | if (params->etm != 0 && cipher_type == CIPHER_BLOCK) |
552 | 0 | etm = 1; |
553 | | |
554 | | /* if EtM mode and not AEAD */ |
555 | 0 | if (etm) { |
556 | 0 | if (unlikely(ciphertext->size < tag_size)) |
557 | 0 | return |
558 | 0 | gnutls_assert_val |
559 | 0 | (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); |
560 | | |
561 | 0 | preamble_size = _gnutls_make_preamble(sequence, |
562 | 0 | type, |
563 | 0 | ciphertext->size - |
564 | 0 | tag_size, ver, preamble); |
565 | |
|
566 | 0 | ret = |
567 | 0 | _gnutls_auth_cipher_add_auth(¶ms->read.ctx.tls12, |
568 | 0 | preamble, preamble_size); |
569 | 0 | if (unlikely(ret < 0)) |
570 | 0 | return gnutls_assert_val(ret); |
571 | | |
572 | 0 | ret = _gnutls_auth_cipher_add_auth(¶ms->read.ctx.tls12, |
573 | 0 | ciphertext->data, |
574 | 0 | ciphertext->size - tag_size); |
575 | 0 | if (unlikely(ret < 0)) |
576 | 0 | return gnutls_assert_val(ret); |
577 | | |
578 | 0 | ret = |
579 | 0 | _gnutls_auth_cipher_tag(¶ms->read.ctx.tls12, tag, |
580 | 0 | tag_size); |
581 | 0 | if (unlikely(ret < 0)) |
582 | 0 | return gnutls_assert_val(ret); |
583 | | |
584 | 0 | if (unlikely |
585 | 0 | (gnutls_memcmp |
586 | 0 | (tag, &ciphertext->data[ciphertext->size - tag_size], |
587 | 0 | tag_size) != 0)) { |
588 | | /* HMAC was not the same. */ |
589 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
590 | 0 | } |
591 | 0 | } |
592 | | |
593 | | /* actual decryption (inplace) |
594 | | */ |
595 | 0 | switch (cipher_type) { |
596 | 0 | case CIPHER_AEAD: |
597 | | /* The way AEAD ciphers are defined in RFC5246, it allows |
598 | | * only stream ciphers. |
599 | | */ |
600 | 0 | if (unlikely |
601 | 0 | (_gnutls_auth_cipher_is_aead(¶ms->read.ctx.tls12) == 0)) |
602 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
603 | | |
604 | 0 | if (unlikely(ciphertext->size < (tag_size + exp_iv_size))) |
605 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
606 | | |
607 | 0 | if ((params->cipher->flags & GNUTLS_CIPHER_FLAG_XOR_NONCE) == 0) { |
608 | | /* Values in AEAD are pretty fixed in TLS 1.2 for 128-bit block |
609 | | */ |
610 | 0 | if (unlikely(params->read.iv_size != 4)) |
611 | 0 | return |
612 | 0 | gnutls_assert_val |
613 | 0 | (GNUTLS_E_DECRYPTION_FAILED); |
614 | | |
615 | 0 | memcpy(nonce, params->read.iv, imp_iv_size); |
616 | |
|
617 | 0 | memcpy(&nonce[imp_iv_size], |
618 | 0 | ciphertext->data, exp_iv_size); |
619 | |
|
620 | 0 | ciphertext->data += exp_iv_size; |
621 | 0 | ciphertext->size -= exp_iv_size; |
622 | 0 | } else { /* XOR nonce with IV */ |
623 | 0 | if (unlikely |
624 | 0 | (params->read.iv_size != 12 || imp_iv_size != 12 |
625 | 0 | || exp_iv_size != 0)) |
626 | 0 | return |
627 | 0 | gnutls_assert_val |
628 | 0 | (GNUTLS_E_DECRYPTION_FAILED); |
629 | | |
630 | 0 | memset(nonce, 0, 4); |
631 | 0 | _gnutls_write_uint64(sequence, &nonce[4]); |
632 | |
|
633 | 0 | memxor(nonce, params->read.iv, 12); |
634 | 0 | } |
635 | | |
636 | 0 | length = ciphertext->size - tag_size; |
637 | |
|
638 | 0 | length_to_decrypt = ciphertext->size; |
639 | | |
640 | | /* Pass the type, version, length and plain through |
641 | | * MAC. |
642 | | */ |
643 | 0 | preamble_size = |
644 | 0 | _gnutls_make_preamble(sequence, type, |
645 | 0 | length, ver, preamble); |
646 | |
|
647 | 0 | if (unlikely((unsigned)length_to_decrypt > plain->size)) { |
648 | 0 | _gnutls_audit_log(session, |
649 | 0 | "Received %u bytes, while expecting less than %u\n", |
650 | 0 | (unsigned int)length_to_decrypt, |
651 | 0 | (unsigned int)plain->size); |
652 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
653 | 0 | } |
654 | | |
655 | 0 | ret = |
656 | 0 | _gnutls_aead_cipher_decrypt(¶ms->read.ctx.tls12.cipher, |
657 | 0 | nonce, |
658 | 0 | exp_iv_size + imp_iv_size, |
659 | 0 | preamble, preamble_size, |
660 | 0 | tag_size, ciphertext->data, |
661 | 0 | length_to_decrypt, plain->data, |
662 | 0 | plain->size); |
663 | 0 | if (unlikely(ret < 0)) |
664 | 0 | return gnutls_assert_val(ret); |
665 | | |
666 | 0 | return length; |
667 | | |
668 | 0 | break; |
669 | 0 | case CIPHER_STREAM: |
670 | 0 | if (unlikely(ciphertext->size < tag_size)) |
671 | 0 | return |
672 | 0 | gnutls_assert_val |
673 | 0 | (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); |
674 | | |
675 | 0 | length_to_decrypt = ciphertext->size; |
676 | 0 | length = ciphertext->size - tag_size; |
677 | 0 | tag_ptr = plain->data + length; |
678 | | |
679 | | /* Pass the type, version, length and plain through |
680 | | * MAC. |
681 | | */ |
682 | 0 | preamble_size = |
683 | 0 | _gnutls_make_preamble(sequence, type, |
684 | 0 | length, ver, preamble); |
685 | |
|
686 | 0 | ret = |
687 | 0 | _gnutls_auth_cipher_add_auth(¶ms->read.ctx.tls12, |
688 | 0 | preamble, preamble_size); |
689 | 0 | if (unlikely(ret < 0)) |
690 | 0 | return gnutls_assert_val(ret); |
691 | | |
692 | 0 | if (unlikely((unsigned)length_to_decrypt > plain->size)) { |
693 | 0 | _gnutls_audit_log(session, |
694 | 0 | "Received %u bytes, while expecting less than %u\n", |
695 | 0 | (unsigned int)length_to_decrypt, |
696 | 0 | (unsigned int)plain->size); |
697 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
698 | 0 | } |
699 | | |
700 | 0 | ret = |
701 | 0 | _gnutls_auth_cipher_decrypt2(¶ms->read.ctx.tls12, |
702 | 0 | ciphertext->data, |
703 | 0 | length_to_decrypt, |
704 | 0 | plain->data, plain->size); |
705 | |
|
706 | 0 | if (unlikely(ret < 0)) |
707 | 0 | return gnutls_assert_val(ret); |
708 | | |
709 | 0 | ret = |
710 | 0 | _gnutls_auth_cipher_tag(¶ms->read.ctx.tls12, tag, |
711 | 0 | tag_size); |
712 | 0 | if (unlikely(ret < 0)) |
713 | 0 | return gnutls_assert_val(ret); |
714 | | |
715 | 0 | if (unlikely(gnutls_memcmp(tag, tag_ptr, tag_size) != 0)) { |
716 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
717 | 0 | } |
718 | | |
719 | 0 | break; |
720 | 0 | case CIPHER_BLOCK: |
721 | 0 | if (unlikely(ciphertext->size < blocksize)) |
722 | 0 | return |
723 | 0 | gnutls_assert_val |
724 | 0 | (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); |
725 | | |
726 | 0 | if (etm == 0) { |
727 | 0 | if (unlikely(ciphertext->size % blocksize != 0)) |
728 | 0 | return |
729 | 0 | gnutls_assert_val |
730 | 0 | (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); |
731 | 0 | } else { |
732 | 0 | if (unlikely |
733 | 0 | ((ciphertext->size - tag_size) % blocksize != 0)) |
734 | 0 | return |
735 | 0 | gnutls_assert_val |
736 | 0 | (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); |
737 | 0 | } |
738 | | |
739 | | /* ignore the IV in TLS 1.1+ |
740 | | */ |
741 | 0 | if (explicit_iv) { |
742 | 0 | ret = _gnutls_auth_cipher_setiv(¶ms->read.ctx.tls12, |
743 | 0 | ciphertext->data, |
744 | 0 | blocksize); |
745 | 0 | if (ret < 0) |
746 | 0 | return gnutls_assert_val(ret); |
747 | | |
748 | 0 | memcpy(nonce, ciphertext->data, blocksize); |
749 | 0 | ciphertext->size -= blocksize; |
750 | 0 | ciphertext->data += blocksize; |
751 | 0 | } |
752 | | |
753 | 0 | if (unlikely(ciphertext->size < tag_size + 1)) |
754 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
755 | | |
756 | | /* we don't use the auth_cipher interface here, since |
757 | | * TLS with block ciphers is impossible to be used under such |
758 | | * an API. (the length of plaintext is required to calculate |
759 | | * auth_data, but it is not available before decryption). |
760 | | */ |
761 | 0 | if (unlikely(ciphertext->size > plain->size)) |
762 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
763 | | |
764 | 0 | if (etm == 0) { |
765 | 0 | ret = |
766 | 0 | _gnutls_cipher_decrypt2(¶ms->read.ctx.tls12. |
767 | 0 | cipher, ciphertext->data, |
768 | 0 | ciphertext->size, |
769 | 0 | plain->data, plain->size); |
770 | 0 | if (unlikely(ret < 0)) |
771 | 0 | return gnutls_assert_val(ret); |
772 | | |
773 | 0 | ret = cbc_mac_verify(session, params, preamble, type, |
774 | 0 | sequence, plain->data, |
775 | 0 | ciphertext->size, tag_size); |
776 | 0 | if (unlikely(ret < 0)) |
777 | 0 | return gnutls_assert_val(ret); |
778 | | |
779 | 0 | length = ret; |
780 | 0 | } else { /* EtM */ |
781 | 0 | ret = |
782 | 0 | _gnutls_cipher_decrypt2(¶ms->read.ctx.tls12. |
783 | 0 | cipher, ciphertext->data, |
784 | 0 | ciphertext->size - tag_size, |
785 | 0 | plain->data, plain->size); |
786 | 0 | if (unlikely(ret < 0)) |
787 | 0 | return gnutls_assert_val(ret); |
788 | | |
789 | 0 | pad = plain->data[ciphertext->size - tag_size - 1]; /* pad */ |
790 | 0 | length = ciphertext->size - tag_size - pad - 1; |
791 | |
|
792 | 0 | if (unlikely(length < 0)) |
793 | 0 | return |
794 | 0 | gnutls_assert_val |
795 | 0 | (GNUTLS_E_DECRYPTION_FAILED); |
796 | 0 | } |
797 | 0 | break; |
798 | 0 | default: |
799 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
800 | 0 | } |
801 | | |
802 | 0 | return length; |
803 | 0 | } |
804 | | |
805 | | static int |
806 | | decrypt_packet_tls13(gnutls_session_t session, |
807 | | gnutls_datum_t * ciphertext, |
808 | | gnutls_datum_t * plain, |
809 | | content_type_t * type, record_parameters_st * params, |
810 | | uint64_t sequence) |
811 | 0 | { |
812 | 0 | uint8_t nonce[MAX_CIPHER_IV_SIZE]; |
813 | 0 | size_t length, length_to_decrypt; |
814 | 0 | int ret; |
815 | 0 | const version_entry_st *ver = get_version(session); |
816 | 0 | unsigned int tag_size = params->read.aead_tag_size; |
817 | 0 | unsigned iv_size; |
818 | 0 | unsigned j; |
819 | 0 | volatile unsigned length_set; |
820 | 0 | uint8_t aad[5]; |
821 | |
|
822 | 0 | if (unlikely(ver == NULL)) |
823 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
824 | | |
825 | 0 | if (params->cipher->id == GNUTLS_CIPHER_NULL) { |
826 | 0 | if (plain->size < ciphertext->size) |
827 | 0 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); |
828 | | |
829 | 0 | length = ciphertext->size; |
830 | 0 | memcpy(plain->data, ciphertext->data, length); |
831 | |
|
832 | 0 | return length; |
833 | 0 | } |
834 | | |
835 | 0 | iv_size = _gnutls_cipher_get_iv_size(params->cipher); |
836 | | |
837 | | /* The way AEAD ciphers are defined in RFC5246, it allows |
838 | | * only stream ciphers. |
839 | | */ |
840 | 0 | if (unlikely(ciphertext->size < tag_size)) |
841 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
842 | | |
843 | 0 | if (unlikely(params->read.iv_size != iv_size || iv_size < 8)) |
844 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
845 | | |
846 | 0 | memset(nonce, 0, iv_size - 8); |
847 | 0 | _gnutls_write_uint64(sequence, &nonce[iv_size - 8]); |
848 | 0 | memxor(nonce, params->read.iv, params->read.iv_size); |
849 | |
|
850 | 0 | length = ciphertext->size - tag_size; |
851 | |
|
852 | 0 | length_to_decrypt = ciphertext->size; |
853 | |
|
854 | 0 | if (unlikely((unsigned)length_to_decrypt > plain->size)) { |
855 | 0 | _gnutls_audit_log(session, |
856 | 0 | "Received %u bytes, while expecting less than %u\n", |
857 | 0 | (unsigned int)length_to_decrypt, |
858 | 0 | (unsigned int)plain->size); |
859 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
860 | 0 | } |
861 | | |
862 | 0 | aad[0] = GNUTLS_APPLICATION_DATA; |
863 | 0 | aad[1] = 0x03; |
864 | 0 | aad[2] = 0x03; |
865 | 0 | _gnutls_write_uint16(ciphertext->size, &aad[3]); |
866 | |
|
867 | 0 | ret = gnutls_aead_cipher_decrypt(¶ms->read.ctx.aead, |
868 | 0 | nonce, iv_size, |
869 | 0 | aad, sizeof(aad), |
870 | 0 | tag_size, |
871 | 0 | ciphertext->data, length_to_decrypt, |
872 | 0 | plain->data, &length); |
873 | 0 | if (unlikely(ret < 0)) |
874 | 0 | return gnutls_assert_val(ret); |
875 | | |
876 | | /* 1 octet for content type */ |
877 | 0 | if (length > max_decrypted_size(session) + 1) { |
878 | 0 | _gnutls_audit_log |
879 | 0 | (session, "Received packet with illegal length: %u\n", |
880 | 0 | (unsigned int)length); |
881 | |
|
882 | 0 | return gnutls_assert_val(GNUTLS_E_RECORD_OVERFLOW); |
883 | 0 | } |
884 | | |
885 | 0 | length_set = 0; |
886 | | |
887 | | /* now figure the actual data size. We intentionally iterate through all data, |
888 | | * to avoid leaking the padding length due to timing differences in processing. |
889 | | */ |
890 | 0 | for (j = length; j > 0; j--) { |
891 | 0 | if (plain->data[j - 1] != 0 && length_set == 0) { |
892 | 0 | *type = plain->data[j - 1]; |
893 | 0 | length = j - 1; |
894 | 0 | length_set = 1; |
895 | 0 | if (! |
896 | 0 | (session-> |
897 | 0 | internals.flags & GNUTLS_SAFE_PADDING_CHECK)) |
898 | 0 | break; |
899 | 0 | } |
900 | 0 | } |
901 | |
|
902 | 0 | if (!length_set) |
903 | 0 | return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); |
904 | | |
905 | 0 | return length; |
906 | 0 | } |