Use libtasn1 v2.4.
[gnutls.git] / lib / gnutls_cipher.c
blobf1a4efcba7559b318e3aa3c8bd5456eb3d72c920
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 library 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 if (session->security_parameters.write_compression_algorithm ==
49 GNUTLS_COMP_NULL)
50 return 0;
52 return 1;
55 inline static int
56 is_read_comp_null (gnutls_session_t session)
58 if (session->security_parameters.read_compression_algorithm ==
59 GNUTLS_COMP_NULL)
60 return 0;
62 return 1;
66 /* returns ciphertext which contains the headers too. This also
67 * calculates the size in the header field.
69 * If random pad != 0 then the random pad data will be appended.
71 int
72 _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
73 size_t headers_size, const opaque * data,
74 size_t data_size, opaque * ciphertext,
75 size_t ciphertext_size, content_type_t type, int random_pad)
77 gnutls_datum_t plain;
78 gnutls_datum_t comp;
79 int ret;
80 int free_comp = 1;
82 plain.data = (opaque *) data;
83 plain.size = data_size;
85 if (plain.size == 0 || is_write_comp_null (session) == 0)
87 comp = plain;
88 free_comp = 0;
90 else
92 /* Here comp is allocated and must be
93 * freed.
95 ret = _gnutls_m_plaintext2compressed (session, &comp, &plain);
96 if (ret < 0)
98 gnutls_assert ();
99 return ret;
103 ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
104 ciphertext_size - headers_size,
105 comp, type, random_pad);
107 if (free_comp)
108 _gnutls_free_datum (&comp);
110 if (ret < 0)
112 gnutls_assert ();
113 return ret;
117 /* copy the headers */
118 memcpy (ciphertext, headers, headers_size);
119 _gnutls_write_uint16 (ret, &ciphertext[3]);
121 return ret + headers_size;
124 /* Decrypts the given data.
125 * Returns the decrypted data length.
128 _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
129 size_t ciphertext_size, uint8_t * data,
130 size_t max_data_size, content_type_t type)
132 gnutls_datum_t gtxt;
133 gnutls_datum_t gcipher;
134 int ret;
136 if (ciphertext_size == 0)
137 return 0;
139 gcipher.size = ciphertext_size;
140 gcipher.data = ciphertext;
142 ret =
143 _gnutls_ciphertext2compressed (session, data, max_data_size,
144 gcipher, type);
145 if (ret < 0)
147 return ret;
150 if (ret == 0 || is_read_comp_null (session) == 0)
152 /* ret == ret */
155 else
157 gnutls_datum_t gcomp;
159 /* compression has this malloc overhead.
162 gcomp.data = data;
163 gcomp.size = ret;
164 ret = _gnutls_m_compressed2plaintext (session, &gtxt, &gcomp);
165 if (ret < 0)
167 return ret;
170 if (gtxt.size > MAX_RECORD_RECV_SIZE)
172 gnutls_assert ();
173 _gnutls_free_datum (&gtxt);
174 /* This shouldn't have happen and
175 * is a TLS fatal error.
177 return GNUTLS_E_DECOMPRESSION_FAILED;
180 /* This check is not really needed */
181 if (max_data_size < MAX_RECORD_RECV_SIZE)
183 gnutls_assert ();
184 _gnutls_free_datum (&gtxt);
185 return GNUTLS_E_INTERNAL_ERROR;
188 memcpy (data, gtxt.data, gtxt.size);
189 ret = gtxt.size;
191 _gnutls_free_datum (&gtxt);
194 return ret;
197 static inline int
198 mac_init (digest_hd_st * td, gnutls_mac_algorithm_t mac, opaque * secret,
199 int secret_size, int ver)
201 int ret = 0;
203 if (mac == GNUTLS_MAC_NULL)
205 return GNUTLS_E_HASH_FAILED;
208 if (ver == GNUTLS_SSL3)
209 { /* SSL 3.0 */
210 ret = _gnutls_mac_init_ssl3 (td, mac, secret, secret_size);
212 else
213 { /* TLS 1.x */
214 ret = _gnutls_hmac_init (td, mac, secret, secret_size);
217 return ret;
220 static inline void
221 mac_hash (digest_hd_st * td, void * data, int data_size, int ver)
223 if (ver == GNUTLS_SSL3)
224 { /* SSL 3.0 */
225 _gnutls_hash (td, data, data_size);
227 else
229 _gnutls_hmac (td, data, data_size);
233 static inline void
234 mac_deinit (digest_hd_st * td, opaque * res, int ver)
236 if (ver == GNUTLS_SSL3)
237 { /* SSL 3.0 */
238 _gnutls_mac_deinit_ssl3 (td, res);
240 else
242 _gnutls_hmac_deinit (td, res);
246 inline static int
247 calc_enc_length (gnutls_session_t session, int data_size,
248 int hash_size, uint8_t * pad, int random_pad,
249 cipher_type_t block_algo, uint16_t blocksize)
251 uint8_t rnd;
252 int length, ret;
254 *pad = 0;
256 switch (block_algo)
258 case CIPHER_STREAM:
259 length = data_size + hash_size;
261 break;
262 case CIPHER_BLOCK:
263 ret = _gnutls_rnd (GNUTLS_RND_NONCE, &rnd, 1);
264 if (ret < 0)
266 gnutls_assert ();
267 return ret;
270 /* make rnd a multiple of blocksize */
271 if (session->security_parameters.version == GNUTLS_SSL3 ||
272 random_pad == 0)
274 rnd = 0;
276 else
278 rnd = (rnd / blocksize) * blocksize;
279 /* added to avoid the case of pad calculated 0
280 * seen below for pad calculation.
282 if (rnd > blocksize)
283 rnd -= blocksize;
286 length = data_size + hash_size;
288 *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;
290 length += *pad;
291 if (_gnutls_version_has_explicit_iv
292 (session->security_parameters.version))
293 length += blocksize; /* for the IV */
295 break;
296 default:
297 gnutls_assert ();
298 return GNUTLS_E_INTERNAL_ERROR;
301 return length;
304 #define PREAMBLE_SIZE 16
305 static inline int make_preamble(opaque* uint64_data, opaque type, uint16_t c_length, opaque ver, opaque* preamble)
307 opaque minor = _gnutls_version_get_minor (ver);
308 opaque major = _gnutls_version_get_major (ver);
309 opaque *p = preamble;
311 memcpy(p, uint64_data, 8);
312 p+=8;
313 *p=type; p++;
314 if (_gnutls_version_has_variable_padding (ver))
315 { /* TLS 1.0 or higher */
316 *p = major; p++;
317 *p = minor; p++;
319 memcpy(p, &c_length, 2);
320 p+=2;
321 return p-preamble;
324 /* This is the actual encryption
325 * Encrypts the given compressed datum, and puts the result to cipher_data,
326 * which has cipher_size size.
327 * return the actual encrypted data length.
330 _gnutls_compressed2ciphertext (gnutls_session_t session,
331 opaque * cipher_data, int cipher_size,
332 gnutls_datum_t compressed,
333 content_type_t _type, int random_pad)
335 uint8_t MAC[MAX_HASH_SIZE];
336 uint16_t c_length;
337 uint8_t pad;
338 int length, ret;
339 uint8_t type = _type;
340 opaque preamble[PREAMBLE_SIZE];
341 int preamble_size;
342 int hash_size =
343 _gnutls_hash_get_algo_len (session->security_parameters.
344 write_mac_algorithm);
345 int blocksize =
346 gnutls_cipher_get_block_size (session->security_parameters.
347 write_bulk_cipher_algorithm);
348 cipher_type_t block_algo =
349 _gnutls_cipher_is_block (session->security_parameters.
350 write_bulk_cipher_algorithm);
351 opaque *data_ptr;
352 int ver = gnutls_protocol_get_version (session);
355 /* Initialize MAC */
357 c_length = _gnutls_conv_uint16 (compressed.size);
359 if (session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
360 { /* actually when the algorithm in not the NULL one */
361 digest_hd_st td;
363 ret = mac_init (&td, session->security_parameters.write_mac_algorithm,
364 session->connection_state.write_mac_secret.data,
365 session->connection_state.write_mac_secret.size, ver);
367 if (ret < 0)
369 gnutls_assert ();
370 return ret;
372 preamble_size = make_preamble( UINT64DATA (session->connection_state.write_sequence_number), type, c_length, ver, preamble);
373 mac_hash (&td, preamble, preamble_size, ver);
374 mac_hash (&td, compressed.data, compressed.size, ver);
375 mac_deinit (&td, MAC, ver);
379 /* Calculate the encrypted length (padding etc.)
381 length =
382 calc_enc_length (session, compressed.size, hash_size, &pad,
383 random_pad, block_algo, blocksize);
384 if (length < 0)
386 gnutls_assert ();
387 return length;
390 /* copy the encrypted data to cipher_data.
392 if (cipher_size < length)
394 gnutls_assert ();
395 return GNUTLS_E_MEMORY_ERROR;
398 data_ptr = cipher_data;
399 if (block_algo == CIPHER_BLOCK &&
400 _gnutls_version_has_explicit_iv (session->security_parameters.version))
402 /* copy the random IV.
404 ret = _gnutls_rnd (GNUTLS_RND_NONCE, data_ptr, blocksize);
405 if (ret < 0)
407 gnutls_assert ();
408 return ret;
411 data_ptr += blocksize;
414 memcpy (data_ptr, compressed.data, compressed.size);
415 data_ptr += compressed.size;
417 if (hash_size > 0)
419 memcpy (data_ptr, MAC, hash_size);
420 data_ptr += hash_size;
422 if (block_algo == CIPHER_BLOCK && pad > 0)
424 memset (data_ptr, pad - 1, pad);
428 /* Actual encryption (inplace).
430 ret =
431 _gnutls_cipher_encrypt (&session->connection_state.write_cipher_state,
432 cipher_data, length);
433 if (ret < 0)
435 gnutls_assert ();
436 return ret;
439 return length;
442 /* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
443 * Returns the actual compressed packet size.
446 _gnutls_ciphertext2compressed (gnutls_session_t session,
447 opaque * compress_data,
448 int compress_size,
449 gnutls_datum_t ciphertext, uint8_t type)
451 uint8_t MAC[MAX_HASH_SIZE];
452 uint16_t c_length;
453 uint8_t pad;
454 int length;
455 uint16_t blocksize;
456 int ret, i, pad_failed = 0;
457 opaque preamble[PREAMBLE_SIZE];
458 int preamble_size;
459 int ver = gnutls_protocol_get_version (session);
460 int hash_size =
461 _gnutls_hash_get_algo_len (session->security_parameters.
462 read_mac_algorithm);
464 blocksize =
465 gnutls_cipher_get_block_size (session->security_parameters.
466 read_bulk_cipher_algorithm);
469 /* actual decryption (inplace)
471 switch (_gnutls_cipher_is_block
472 (session->security_parameters.read_bulk_cipher_algorithm))
474 case CIPHER_STREAM:
475 if ((ret =
476 _gnutls_cipher_decrypt (&session->connection_state.
477 read_cipher_state, ciphertext.data,
478 ciphertext.size)) < 0)
480 gnutls_assert ();
481 return ret;
484 length = ciphertext.size - hash_size;
486 break;
487 case CIPHER_BLOCK:
488 if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
490 gnutls_assert ();
491 return GNUTLS_E_DECRYPTION_FAILED;
494 if ((ret =
495 _gnutls_cipher_decrypt (&session->connection_state.
496 read_cipher_state, ciphertext.data,
497 ciphertext.size)) < 0)
499 gnutls_assert ();
500 return ret;
503 /* ignore the IV in TLS 1.1.
505 if (_gnutls_version_has_explicit_iv
506 (session->security_parameters.version))
508 ciphertext.size -= blocksize;
509 ciphertext.data += blocksize;
511 if (ciphertext.size == 0)
513 gnutls_assert ();
514 return GNUTLS_E_DECRYPTION_FAILED;
518 pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
520 if ((int) pad > (int) ciphertext.size - hash_size)
522 gnutls_assert ();
523 _gnutls_record_log
524 ("REC[%p]: Short record length %d > %d - %d (under attack?)\n",
525 session, pad, ciphertext.size, hash_size);
526 /* We do not fail here. We check below for the
527 * the pad_failed. If zero means success.
529 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
532 length = ciphertext.size - hash_size - pad;
534 /* Check the pading bytes (TLS 1.x)
536 if (_gnutls_version_has_variable_padding (ver) && pad_failed == 0)
537 for (i = 2; i < pad; i++)
539 if (ciphertext.data[ciphertext.size - i] !=
540 ciphertext.data[ciphertext.size - 1])
541 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
543 break;
544 default:
545 gnutls_assert ();
546 return GNUTLS_E_INTERNAL_ERROR;
549 if (length < 0)
550 length = 0;
551 c_length = _gnutls_conv_uint16 ((uint16_t) length);
553 /* Pass the type, version, length and compressed through
554 * MAC.
556 if (session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL)
558 digest_hd_st td;
560 ret = mac_init (&td, session->security_parameters.read_mac_algorithm,
561 session->connection_state.read_mac_secret.data,
562 session->connection_state.read_mac_secret.size, ver);
564 if (ret < 0)
566 gnutls_assert ();
567 return GNUTLS_E_INTERNAL_ERROR;
570 preamble_size = make_preamble( UINT64DATA (session->connection_state.read_sequence_number), type, c_length, ver, preamble);
571 mac_hash (&td, preamble, preamble_size, ver);
572 if (length > 0)
573 mac_hash (&td, ciphertext.data, length, ver);
575 mac_deinit (&td, MAC, ver);
578 /* This one was introduced to avoid a timing attack against the TLS
579 * 1.0 protocol.
581 if (pad_failed != 0)
583 gnutls_assert ();
584 return pad_failed;
587 /* HMAC was not the same.
589 if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
591 gnutls_assert ();
592 return GNUTLS_E_DECRYPTION_FAILED;
595 /* copy the decrypted stuff to compress_data.
597 if (compress_size < length)
599 gnutls_assert ();
600 return GNUTLS_E_DECOMPRESSION_FAILED;
602 memcpy (compress_data, ciphertext.data, length);
604 return length;