Corrected SRP-RSA ciphersuites when used under TLS 1.2.
[gnutls.git] / lib / gnutls_cipher.c
blob6b832083648d83d585a195edbc19c6d12f52791f
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* Some high level functions to be used in the record encryption are
27 * included here.
30 #include "gnutls_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_compress.h"
33 #include "gnutls_cipher.h"
34 #include "gnutls_algorithms.h"
35 #include "gnutls_hash_int.h"
36 #include "gnutls_cipher_int.h"
37 #include "debug.h"
38 #include "gnutls_num.h"
39 #include "gnutls_datum.h"
40 #include "gnutls_kx.h"
41 #include "gnutls_record.h"
42 #include "gnutls_constate.h"
43 #include <random.h>
45 inline static int
46 is_write_comp_null (gnutls_session_t session)
48 record_parameters_st *record_params;
50 _gnutls_epoch_get (session, EPOCH_WRITE_CURRENT, &record_params);
51 if (record_params->compression_algorithm == GNUTLS_COMP_NULL)
52 return 0;
54 return 1;
57 inline static int
58 is_read_comp_null (gnutls_session_t session)
60 record_parameters_st *record_params;
62 _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
63 if (record_params->compression_algorithm == GNUTLS_COMP_NULL)
64 return 0;
66 return 1;
70 /* returns ciphertext which contains the headers too. This also
71 * calculates the size in the header field.
73 * If random pad != 0 then the random pad data will be appended.
75 int
76 _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
77 size_t headers_size, const opaque * data,
78 size_t data_size, opaque * ciphertext,
79 size_t ciphertext_size, content_type_t type, int random_pad,
80 record_parameters_st * params)
82 gnutls_datum_t plain;
83 gnutls_datum_t comp;
84 int ret;
85 int free_comp = 1;
87 plain.data = (opaque *) data;
88 plain.size = data_size;
90 if (plain.size == 0 || is_write_comp_null (session) == 0)
92 comp = plain;
93 free_comp = 0;
95 else
97 /* Here comp is allocated and must be
98 * freed.
100 ret = _gnutls_m_plaintext2compressed (session, &comp, &plain, params);
101 if (ret < 0)
103 gnutls_assert ();
104 return ret;
108 ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
109 ciphertext_size - headers_size,
110 comp, type, random_pad, params);
112 if (free_comp)
113 _gnutls_free_datum (&comp);
115 if (ret < 0)
117 gnutls_assert ();
118 return ret;
122 /* copy the headers */
123 memcpy (ciphertext, headers, headers_size);
124 _gnutls_write_uint16 (ret, &ciphertext[3]);
126 return ret + headers_size;
129 /* Decrypts the given data.
130 * Returns the decrypted data length.
133 _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
134 size_t ciphertext_size, uint8_t * data,
135 size_t max_data_size, content_type_t type,
136 record_parameters_st * params)
138 gnutls_datum_t gtxt;
139 gnutls_datum_t gcipher;
140 int ret;
142 if (ciphertext_size == 0)
143 return 0;
145 gcipher.size = ciphertext_size;
146 gcipher.data = ciphertext;
148 ret =
149 _gnutls_ciphertext2compressed (session, data, max_data_size,
150 gcipher, type, params);
151 if (ret < 0)
153 return ret;
156 if (ret == 0 || is_read_comp_null (session) == 0)
158 /* ret == ret */
161 else
163 gnutls_datum_t gcomp;
165 /* compression has this malloc overhead.
168 gcomp.data = data;
169 gcomp.size = ret;
170 ret = _gnutls_m_compressed2plaintext (session, &gtxt, &gcomp, params);
171 if (ret < 0)
173 return ret;
176 if (gtxt.size > MAX_RECORD_RECV_SIZE)
178 gnutls_assert ();
179 _gnutls_free_datum (&gtxt);
180 /* This shouldn't have happen and
181 * is a TLS fatal error.
183 return GNUTLS_E_DECOMPRESSION_FAILED;
186 /* This check is not really needed */
187 if (max_data_size < MAX_RECORD_RECV_SIZE)
189 gnutls_assert ();
190 _gnutls_free_datum (&gtxt);
191 return GNUTLS_E_INTERNAL_ERROR;
194 memcpy (data, gtxt.data, gtxt.size);
195 ret = gtxt.size;
197 _gnutls_free_datum (&gtxt);
200 return ret;
203 static inline int
204 mac_init (digest_hd_st * td, gnutls_mac_algorithm_t mac, opaque * secret,
205 int secret_size, int ver)
207 int ret = 0;
209 if (mac == GNUTLS_MAC_NULL)
211 return GNUTLS_E_HASH_FAILED;
214 if (ver == GNUTLS_SSL3)
215 { /* SSL 3.0 */
216 ret = _gnutls_mac_init_ssl3 (td, mac, secret, secret_size);
218 else
219 { /* TLS 1.x */
220 ret = _gnutls_hmac_init (td, mac, secret, secret_size);
223 return ret;
226 static inline void
227 mac_hash (digest_hd_st * td, void *data, int data_size, int ver)
229 if (ver == GNUTLS_SSL3)
230 { /* SSL 3.0 */
231 _gnutls_hash (td, data, data_size);
233 else
235 _gnutls_hmac (td, data, data_size);
239 static inline void
240 mac_deinit (digest_hd_st * td, opaque * res, int ver)
242 if (ver == GNUTLS_SSL3)
243 { /* SSL 3.0 */
244 _gnutls_mac_deinit_ssl3 (td, res);
246 else
248 _gnutls_hmac_deinit (td, res);
252 inline static int
253 calc_enc_length (gnutls_session_t session, int data_size,
254 int hash_size, uint8_t * pad, int random_pad,
255 cipher_type_t block_algo, uint16_t blocksize)
257 uint8_t rnd;
258 int length, ret;
260 *pad = 0;
262 switch (block_algo)
264 case CIPHER_STREAM:
265 length = data_size + hash_size;
267 break;
268 case CIPHER_BLOCK:
269 ret = _gnutls_rnd (GNUTLS_RND_NONCE, &rnd, 1);
270 if (ret < 0)
272 gnutls_assert ();
273 return ret;
276 /* make rnd a multiple of blocksize */
277 if (session->security_parameters.version == GNUTLS_SSL3 ||
278 random_pad == 0)
280 rnd = 0;
282 else
284 rnd = (rnd / blocksize) * blocksize;
285 /* added to avoid the case of pad calculated 0
286 * seen below for pad calculation.
288 if (rnd > blocksize)
289 rnd -= blocksize;
292 length = data_size + hash_size;
294 *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;
296 length += *pad;
297 if (_gnutls_version_has_explicit_iv
298 (session->security_parameters.version))
299 length += blocksize; /* for the IV */
301 break;
302 default:
303 gnutls_assert ();
304 return GNUTLS_E_INTERNAL_ERROR;
307 return length;
310 #define PREAMBLE_SIZE 16
311 static inline int
312 make_preamble (opaque * uint64_data, opaque type, uint16_t c_length,
313 opaque ver, opaque * preamble)
315 opaque minor = _gnutls_version_get_minor (ver);
316 opaque major = _gnutls_version_get_major (ver);
317 opaque *p = preamble;
319 memcpy (p, uint64_data, 8);
320 p += 8;
321 *p = type;
322 p++;
323 if (_gnutls_version_has_variable_padding (ver))
324 { /* TLS 1.0 or higher */
325 *p = major;
326 p++;
327 *p = minor;
328 p++;
330 memcpy (p, &c_length, 2);
331 p += 2;
332 return p - preamble;
335 /* This is the actual encryption
336 * Encrypts the given compressed datum, and puts the result to cipher_data,
337 * which has cipher_size size.
338 * return the actual encrypted data length.
341 _gnutls_compressed2ciphertext (gnutls_session_t session,
342 opaque * cipher_data, int cipher_size,
343 gnutls_datum_t compressed,
344 content_type_t _type, int random_pad,
345 record_parameters_st * params)
347 uint8_t MAC[MAX_HASH_SIZE];
348 uint16_t c_length;
349 uint8_t pad;
350 int length, ret;
351 uint8_t type = _type;
352 opaque preamble[PREAMBLE_SIZE];
353 int preamble_size;
354 int hash_size = _gnutls_hash_get_algo_len (params->mac_algorithm);
355 int blocksize = gnutls_cipher_get_block_size (params->cipher_algorithm);
356 cipher_type_t block_algo =
357 _gnutls_cipher_is_block (params->cipher_algorithm);
358 opaque *data_ptr;
359 int ver = gnutls_protocol_get_version (session);
362 /* Initialize MAC */
364 c_length = _gnutls_conv_uint16 (compressed.size);
366 if (params->mac_algorithm != GNUTLS_MAC_NULL)
367 { /* actually when the algorithm in not the NULL one */
368 digest_hd_st td;
370 ret = mac_init (&td, params->mac_algorithm,
371 params->write.mac_secret.data,
372 params->write.mac_secret.size, ver);
374 if (ret < 0)
376 gnutls_assert ();
377 return ret;
379 preamble_size =
380 make_preamble (UINT64DATA
381 (params->write.sequence_number),
382 type, c_length, ver, preamble);
383 mac_hash (&td, preamble, preamble_size, ver);
384 mac_hash (&td, compressed.data, compressed.size, ver);
385 mac_deinit (&td, MAC, ver);
389 /* Calculate the encrypted length (padding etc.)
391 length =
392 calc_enc_length (session, compressed.size, hash_size, &pad,
393 random_pad, block_algo, blocksize);
394 if (length < 0)
396 gnutls_assert ();
397 return length;
400 /* copy the encrypted data to cipher_data.
402 if (cipher_size < length)
404 gnutls_assert ();
405 return GNUTLS_E_MEMORY_ERROR;
408 data_ptr = cipher_data;
409 if (block_algo == CIPHER_BLOCK &&
410 _gnutls_version_has_explicit_iv (session->security_parameters.version))
412 /* copy the random IV.
414 ret = _gnutls_rnd (GNUTLS_RND_NONCE, data_ptr, blocksize);
415 if (ret < 0)
417 gnutls_assert ();
418 return ret;
421 data_ptr += blocksize;
424 memcpy (data_ptr, compressed.data, compressed.size);
425 data_ptr += compressed.size;
427 if (hash_size > 0)
429 memcpy (data_ptr, MAC, hash_size);
430 data_ptr += hash_size;
432 if (block_algo == CIPHER_BLOCK && pad > 0)
434 memset (data_ptr, pad - 1, pad);
438 /* Actual encryption (inplace).
440 ret =
441 _gnutls_cipher_encrypt (&params->write.cipher_state, cipher_data, length);
442 if (ret < 0)
444 gnutls_assert ();
445 return ret;
448 return length;
452 /* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
453 * Returns the actual compressed packet size.
456 _gnutls_ciphertext2compressed (gnutls_session_t session,
457 opaque * compress_data,
458 int compress_size,
459 gnutls_datum_t ciphertext, uint8_t type,
460 record_parameters_st * params)
462 uint8_t MAC[MAX_HASH_SIZE];
463 uint16_t c_length;
464 uint8_t pad;
465 int length;
466 uint16_t blocksize;
467 int ret, i, pad_failed = 0;
468 opaque preamble[PREAMBLE_SIZE];
469 int preamble_size;
470 int ver = gnutls_protocol_get_version (session);
471 int hash_size = _gnutls_hash_get_algo_len (params->mac_algorithm);
473 blocksize = gnutls_cipher_get_block_size (params->cipher_algorithm);
476 /* actual decryption (inplace)
478 switch (_gnutls_cipher_is_block (params->cipher_algorithm))
480 case CIPHER_STREAM:
481 if ((ret =
482 _gnutls_cipher_decrypt (&params->read.cipher_state,
483 ciphertext.data, ciphertext.size)) < 0)
485 gnutls_assert ();
486 return ret;
489 length = ciphertext.size - hash_size;
491 break;
492 case CIPHER_BLOCK:
493 if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
495 gnutls_assert ();
496 return GNUTLS_E_DECRYPTION_FAILED;
499 if ((ret =
500 _gnutls_cipher_decrypt (&params->read.cipher_state,
501 ciphertext.data, ciphertext.size)) < 0)
503 gnutls_assert ();
504 return ret;
507 /* ignore the IV in TLS 1.1.
509 if (_gnutls_version_has_explicit_iv
510 (session->security_parameters.version))
512 ciphertext.size -= blocksize;
513 ciphertext.data += blocksize;
516 if (ciphertext.size < hash_size)
518 gnutls_assert ();
519 return GNUTLS_E_DECRYPTION_FAILED;
521 pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
523 if ((int) pad > (int) ciphertext.size - hash_size)
525 gnutls_assert ();
526 _gnutls_record_log
527 ("REC[%p]: Short record length %d > %d - %d (under attack?)\n",
528 session, pad, ciphertext.size, hash_size);
529 /* We do not fail here. We check below for the
530 * the pad_failed. If zero means success.
532 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
535 length = ciphertext.size - hash_size - pad;
537 /* Check the pading bytes (TLS 1.x)
539 if (_gnutls_version_has_variable_padding (ver) && pad_failed == 0)
540 for (i = 2; i < pad; i++)
542 if (ciphertext.data[ciphertext.size - i] !=
543 ciphertext.data[ciphertext.size - 1])
544 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
546 break;
547 default:
548 gnutls_assert ();
549 return GNUTLS_E_INTERNAL_ERROR;
552 if (length < 0)
553 length = 0;
554 c_length = _gnutls_conv_uint16 ((uint16_t) length);
556 /* Pass the type, version, length and compressed through
557 * MAC.
559 if (params->mac_algorithm != GNUTLS_MAC_NULL)
561 digest_hd_st td;
563 ret = mac_init (&td, params->mac_algorithm,
564 params->read.mac_secret.data,
565 params->read.mac_secret.size, ver);
567 if (ret < 0)
569 gnutls_assert ();
570 return GNUTLS_E_INTERNAL_ERROR;
573 preamble_size =
574 make_preamble (UINT64DATA
575 (params->read.sequence_number), type,
576 c_length, ver, preamble);
577 mac_hash (&td, preamble, preamble_size, ver);
578 if (length > 0)
579 mac_hash (&td, ciphertext.data, length, ver);
581 mac_deinit (&td, MAC, ver);
584 /* This one was introduced to avoid a timing attack against the TLS
585 * 1.0 protocol.
587 if (pad_failed != 0)
589 gnutls_assert ();
590 return pad_failed;
593 /* HMAC was not the same.
595 if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
597 gnutls_assert ();
598 return GNUTLS_E_DECRYPTION_FAILED;
601 /* copy the decrypted stuff to compress_data.
603 if (compress_size < length)
605 gnutls_assert ();
606 return GNUTLS_E_DECOMPRESSION_FAILED;
608 memcpy (compress_data, ciphertext.data, length);
610 return length;