Guile: Fix `x509-certificate-dn-oid' and related functions.
[gnutls.git] / lib / gnutls_cipher.c
blobb2420f74d32d220583e540c1a789dcb6c33c964e
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 /* Some high level functions to be used in the record encryption are
26 * included here.
29 #include "gnutls_int.h"
30 #include "gnutls_errors.h"
31 #include "gnutls_compress.h"
32 #include "gnutls_cipher.h"
33 #include "gnutls_algorithms.h"
34 #include "gnutls_hash_int.h"
35 #include "gnutls_cipher_int.h"
36 #include "debug.h"
37 #include "gnutls_num.h"
38 #include "gnutls_datum.h"
39 #include "gnutls_kx.h"
40 #include "gnutls_record.h"
41 #include "gnutls_constate.h"
42 #include <gc.h>
44 inline static int
45 is_write_comp_null (gnutls_session_t session)
47 if (session->security_parameters.write_compression_algorithm ==
48 GNUTLS_COMP_NULL)
49 return 0;
51 return 1;
54 inline static int
55 is_read_comp_null (gnutls_session_t session)
57 if (session->security_parameters.read_compression_algorithm ==
58 GNUTLS_COMP_NULL)
59 return 0;
61 return 1;
65 /* returns ciphertext which contains the headers too. This also
66 * calculates the size in the header field.
68 * If random pad != 0 then the random pad data will be appended.
70 int
71 _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
72 size_t headers_size, const opaque * data,
73 size_t data_size, opaque * ciphertext,
74 size_t ciphertext_size, content_type_t type, int random_pad)
76 gnutls_datum_t plain;
77 gnutls_datum_t comp;
78 int ret;
79 int free_comp = 1;
81 plain.data = (opaque *) data;
82 plain.size = data_size;
84 if (plain.size == 0 || is_write_comp_null (session) == 0)
86 comp = plain;
87 free_comp = 0;
89 else
91 /* Here comp is allocated and must be
92 * freed.
94 ret = _gnutls_m_plaintext2compressed (session, &comp, plain);
95 if (ret < 0)
97 gnutls_assert ();
98 return ret;
102 ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
103 ciphertext_size - headers_size,
104 comp, type, random_pad);
106 if (free_comp)
107 _gnutls_free_datum (&comp);
109 if (ret < 0)
111 gnutls_assert ();
112 return ret;
116 /* copy the headers */
117 memcpy (ciphertext, headers, headers_size);
118 _gnutls_write_uint16 (ret, &ciphertext[3]);
120 return ret + headers_size;
123 /* Decrypts the given data.
124 * Returns the decrypted data length.
127 _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
128 size_t ciphertext_size, uint8_t * data,
129 size_t max_data_size, content_type_t type)
131 gnutls_datum_t gtxt;
132 gnutls_datum_t gcipher;
133 int ret;
135 if (ciphertext_size == 0)
136 return 0;
138 gcipher.size = ciphertext_size;
139 gcipher.data = ciphertext;
141 ret =
142 _gnutls_ciphertext2compressed (session, data, max_data_size,
143 gcipher, type);
144 if (ret < 0)
146 return ret;
149 if (ret == 0 || is_read_comp_null (session) == 0)
151 /* ret == ret */
154 else
156 gnutls_datum_t gcomp;
158 /* compression has this malloc overhead.
161 gcomp.data = data;
162 gcomp.size = ret;
163 ret = _gnutls_m_compressed2plaintext (session, &gtxt, gcomp);
164 if (ret < 0)
166 return ret;
169 if (gtxt.size > max_data_size)
171 gnutls_assert ();
172 _gnutls_free_datum (&gtxt);
173 /* This shouldn't have happen and
174 * is a TLS fatal error.
176 return GNUTLS_E_INTERNAL_ERROR;
179 memcpy (data, gtxt.data, gtxt.size);
180 ret = gtxt.size;
182 _gnutls_free_datum (&gtxt);
185 return ret;
188 inline static mac_hd_t
189 mac_init (gnutls_mac_algorithm_t mac, opaque * secret, int secret_size,
190 int ver)
192 mac_hd_t td;
194 if (mac == GNUTLS_MAC_NULL)
195 return GNUTLS_MAC_FAILED;
197 if (ver == GNUTLS_SSL3)
198 { /* SSL 3.0 */
199 td = _gnutls_mac_init_ssl3 (mac, secret, secret_size);
201 else
202 { /* TLS 1.x */
203 td = _gnutls_hmac_init (mac, secret, secret_size);
206 return td;
209 inline static void
210 mac_deinit (mac_hd_t td, opaque * res, int ver)
212 if (ver == GNUTLS_SSL3)
213 { /* SSL 3.0 */
214 _gnutls_mac_deinit_ssl3 (td, res);
216 else
218 _gnutls_hmac_deinit (td, res);
222 inline static int
223 calc_enc_length (gnutls_session_t session, int data_size,
224 int hash_size, uint8_t * pad, int random_pad,
225 cipher_type_t block_algo, uint16_t blocksize)
227 uint8_t rnd;
228 int length;
230 *pad = 0;
232 switch (block_algo)
234 case CIPHER_STREAM:
235 length = data_size + hash_size;
237 break;
238 case CIPHER_BLOCK:
239 if (gc_nonce (&rnd, 1) != GC_OK)
241 gnutls_assert ();
242 return GNUTLS_E_RANDOM_FAILED;
245 /* make rnd a multiple of blocksize */
246 if (session->security_parameters.version == GNUTLS_SSL3 ||
247 random_pad == 0)
249 rnd = 0;
251 else
253 rnd = (rnd / blocksize) * blocksize;
254 /* added to avoid the case of pad calculated 0
255 * seen below for pad calculation.
257 if (rnd > blocksize)
258 rnd -= blocksize;
261 length = data_size + hash_size;
263 *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;
265 length += *pad;
266 if (session->security_parameters.version >= GNUTLS_TLS1_1)
267 length += blocksize; /* for the IV */
269 break;
270 default:
271 gnutls_assert ();
272 return GNUTLS_E_INTERNAL_ERROR;
275 return length;
278 /* This is the actual encryption
279 * Encrypts the given compressed datum, and puts the result to cipher_data,
280 * which has cipher_size size.
281 * return the actual encrypted data length.
284 _gnutls_compressed2ciphertext (gnutls_session_t session,
285 opaque * cipher_data, int cipher_size,
286 gnutls_datum_t compressed,
287 content_type_t _type, int random_pad)
289 uint8_t MAC[MAX_HASH_SIZE];
290 uint16_t c_length;
291 uint8_t pad;
292 int length, ret;
293 mac_hd_t td;
294 uint8_t type = _type;
295 uint8_t major, minor;
296 int hash_size =
297 _gnutls_hash_get_algo_len (session->security_parameters.
298 write_mac_algorithm);
299 gnutls_protocol_t ver;
300 int blocksize =
301 _gnutls_cipher_get_block_size (session->security_parameters.
302 write_bulk_cipher_algorithm);
303 cipher_type_t block_algo =
304 _gnutls_cipher_is_block (session->security_parameters.
305 write_bulk_cipher_algorithm);
306 opaque *data_ptr;
309 ver = gnutls_protocol_get_version (session);
310 minor = _gnutls_version_get_minor (ver);
311 major = _gnutls_version_get_major (ver);
314 /* Initialize MAC */
315 td = mac_init (session->security_parameters.write_mac_algorithm,
316 session->connection_state.write_mac_secret.data,
317 session->connection_state.write_mac_secret.size, ver);
319 if (td == GNUTLS_MAC_FAILED
320 && session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
322 gnutls_assert ();
323 return GNUTLS_E_INTERNAL_ERROR;
326 c_length = _gnutls_conv_uint16 (compressed.size);
328 if (td != GNUTLS_MAC_FAILED)
329 { /* actually when the algorithm in not the NULL one */
330 _gnutls_hmac (td,
331 UINT64DATA (session->connection_state.
332 write_sequence_number), 8);
334 _gnutls_hmac (td, &type, 1);
335 if (ver >= GNUTLS_TLS1)
336 { /* TLS 1.0 or higher */
337 _gnutls_hmac (td, &major, 1);
338 _gnutls_hmac (td, &minor, 1);
340 _gnutls_hmac (td, &c_length, 2);
341 _gnutls_hmac (td, compressed.data, compressed.size);
342 mac_deinit (td, MAC, ver);
346 /* Calculate the encrypted length (padding etc.)
348 length =
349 calc_enc_length (session, compressed.size, hash_size, &pad,
350 random_pad, block_algo, blocksize);
351 if (length < 0)
353 gnutls_assert ();
354 return length;
357 /* copy the encrypted data to cipher_data.
359 if (cipher_size < length)
361 gnutls_assert ();
362 return GNUTLS_E_MEMORY_ERROR;
365 data_ptr = cipher_data;
366 if (block_algo == CIPHER_BLOCK &&
367 session->security_parameters.version >= GNUTLS_TLS1_1)
369 /* copy the random IV.
371 if (gc_nonce (data_ptr, blocksize) != GC_OK)
373 gnutls_assert ();
374 return GNUTLS_E_RANDOM_FAILED;
376 data_ptr += blocksize;
379 memcpy (data_ptr, compressed.data, compressed.size);
380 data_ptr += compressed.size;
382 if (hash_size > 0)
384 memcpy (data_ptr, MAC, hash_size);
385 data_ptr += hash_size;
387 if (block_algo == CIPHER_BLOCK && pad > 0)
389 memset (data_ptr, pad - 1, pad);
393 /* Actual encryption (inplace).
395 ret = _gnutls_cipher_encrypt (session->connection_state.
396 write_cipher_state, cipher_data, length);
397 if (ret < 0)
399 gnutls_assert ();
400 return ret;
403 return length;
406 /* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
407 * Returns the actual compressed packet size.
410 _gnutls_ciphertext2compressed (gnutls_session_t session,
411 opaque * compress_data,
412 int compress_size,
413 gnutls_datum_t ciphertext, uint8_t type)
415 uint8_t MAC[MAX_HASH_SIZE];
416 uint16_t c_length;
417 uint8_t pad;
418 int length;
419 mac_hd_t td;
420 uint16_t blocksize;
421 int ret, i, pad_failed = 0;
422 uint8_t major, minor;
423 gnutls_protocol_t ver;
424 int hash_size =
425 _gnutls_hash_get_algo_len (session->security_parameters.
426 read_mac_algorithm);
428 ver = gnutls_protocol_get_version (session);
429 minor = _gnutls_version_get_minor (ver);
430 major = _gnutls_version_get_major (ver);
432 blocksize = _gnutls_cipher_get_block_size (session->security_parameters.
433 read_bulk_cipher_algorithm);
435 /* initialize MAC
437 td = mac_init (session->security_parameters.read_mac_algorithm,
438 session->connection_state.read_mac_secret.data,
439 session->connection_state.read_mac_secret.size, ver);
441 if (td == GNUTLS_MAC_FAILED
442 && session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL)
444 gnutls_assert ();
445 return GNUTLS_E_INTERNAL_ERROR;
449 /* actual decryption (inplace)
451 switch (_gnutls_cipher_is_block
452 (session->security_parameters.read_bulk_cipher_algorithm))
454 case CIPHER_STREAM:
455 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
456 read_cipher_state,
457 ciphertext.data,
458 ciphertext.size)) < 0)
460 gnutls_assert ();
461 return ret;
464 length = ciphertext.size - hash_size;
466 break;
467 case CIPHER_BLOCK:
468 if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
470 gnutls_assert ();
471 return GNUTLS_E_DECRYPTION_FAILED;
474 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
475 read_cipher_state,
476 ciphertext.data,
477 ciphertext.size)) < 0)
479 gnutls_assert ();
480 return ret;
483 /* ignore the IV in TLS 1.1.
485 if (session->security_parameters.version >= GNUTLS_TLS1_1)
487 ciphertext.size -= blocksize;
488 ciphertext.data += blocksize;
490 if (ciphertext.size == 0)
492 gnutls_assert ();
493 return GNUTLS_E_DECRYPTION_FAILED;
497 pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
499 length = ciphertext.size - hash_size - pad;
501 if (pad > ciphertext.size - hash_size)
503 gnutls_assert ();
504 /* We do not fail here. We check below for the
505 * the pad_failed. If zero means success.
507 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
510 /* Check the pading bytes (TLS 1.x)
512 if (ver >= GNUTLS_TLS1 && pad_failed == 0)
513 for (i = 2; i < pad; i++)
515 if (ciphertext.data[ciphertext.size - i] !=
516 ciphertext.data[ciphertext.size - 1])
517 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
519 break;
520 default:
521 gnutls_assert ();
522 return GNUTLS_E_INTERNAL_ERROR;
525 if (length < 0)
526 length = 0;
527 c_length = _gnutls_conv_uint16 ((uint16_t) length);
529 /* Pass the type, version, length and compressed through
530 * MAC.
532 if (td != GNUTLS_MAC_FAILED)
534 _gnutls_hmac (td,
535 UINT64DATA (session->connection_state.
536 read_sequence_number), 8);
538 _gnutls_hmac (td, &type, 1);
539 if (ver >= GNUTLS_TLS1)
540 { /* TLS 1.x */
541 _gnutls_hmac (td, &major, 1);
542 _gnutls_hmac (td, &minor, 1);
544 _gnutls_hmac (td, &c_length, 2);
546 if (length > 0)
547 _gnutls_hmac (td, ciphertext.data, length);
549 mac_deinit (td, MAC, ver);
552 /* This one was introduced to avoid a timing attack against the TLS
553 * 1.0 protocol.
555 if (pad_failed != 0)
556 return pad_failed;
558 /* HMAC was not the same.
560 if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
562 gnutls_assert ();
563 return GNUTLS_E_DECRYPTION_FAILED;
566 /* copy the decrypted stuff to compress_data.
568 if (compress_size < length)
570 gnutls_assert ();
571 return GNUTLS_E_INTERNAL_ERROR;
573 memcpy (compress_data, ciphertext.data, length);
575 return length;