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,
25 /* Some high level functions to be used in the record encryption are
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"
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"
45 is_write_comp_null (gnutls_session_t session
)
47 if (session
->security_parameters
.write_compression_algorithm
==
55 is_read_comp_null (gnutls_session_t session
)
57 if (session
->security_parameters
.read_compression_algorithm
==
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.
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
)
81 plain
.data
= (opaque
*) data
;
82 plain
.size
= data_size
;
84 if (plain
.size
== 0 || is_write_comp_null (session
) == 0)
91 /* Here comp is allocated and must be
94 ret
= _gnutls_m_plaintext2compressed (session
, &comp
, plain
);
102 ret
= _gnutls_compressed2ciphertext (session
, &ciphertext
[headers_size
],
103 ciphertext_size
- headers_size
,
104 comp
, type
, random_pad
);
107 _gnutls_free_datum (&comp
);
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
)
132 gnutls_datum_t gcipher
;
135 if (ciphertext_size
== 0)
138 gcipher
.size
= ciphertext_size
;
139 gcipher
.data
= ciphertext
;
142 _gnutls_ciphertext2compressed (session
, data
, max_data_size
,
149 if (ret
== 0 || is_read_comp_null (session
) == 0)
156 gnutls_datum_t gcomp
;
158 /* compression has this malloc overhead.
163 ret
= _gnutls_m_compressed2plaintext (session
, >xt
, gcomp
);
169 if (gtxt
.size
> max_data_size
)
172 _gnutls_free_datum (>xt
);
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
);
182 _gnutls_free_datum (>xt
);
188 inline static mac_hd_t
189 mac_init (gnutls_mac_algorithm_t mac
, opaque
* secret
, int secret_size
,
194 if (mac
== GNUTLS_MAC_NULL
)
195 return GNUTLS_MAC_FAILED
;
197 if (ver
== GNUTLS_SSL3
)
199 td
= _gnutls_mac_init_ssl3 (mac
, secret
, secret_size
);
203 td
= _gnutls_hmac_init (mac
, secret
, secret_size
);
210 mac_deinit (mac_hd_t td
, opaque
* res
, int ver
)
212 if (ver
== GNUTLS_SSL3
)
214 _gnutls_mac_deinit_ssl3 (td
, res
);
218 _gnutls_hmac_deinit (td
, res
);
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
)
235 length
= data_size
+ hash_size
;
239 if (gc_nonce (&rnd
, 1) != GC_OK
)
242 return GNUTLS_E_RANDOM_FAILED
;
245 /* make rnd a multiple of blocksize */
246 if (session
->security_parameters
.version
== GNUTLS_SSL3
||
253 rnd
= (rnd
/ blocksize
) * blocksize
;
254 /* added to avoid the case of pad calculated 0
255 * seen below for pad calculation.
261 length
= data_size
+ hash_size
;
263 *pad
= (uint8_t) (blocksize
- (length
% blocksize
)) + rnd
;
266 if (session
->security_parameters
.version
>= GNUTLS_TLS1_1
)
267 length
+= blocksize
; /* for the IV */
272 return GNUTLS_E_INTERNAL_ERROR
;
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
];
294 uint8_t type
= _type
;
295 uint8_t major
, minor
;
297 _gnutls_hash_get_algo_len (session
->security_parameters
.
298 write_mac_algorithm
);
299 gnutls_protocol_t ver
;
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
);
309 ver
= gnutls_protocol_get_version (session
);
310 minor
= _gnutls_version_get_minor (ver
);
311 major
= _gnutls_version_get_major (ver
);
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
)
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 */
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.)
349 calc_enc_length (session
, compressed
.size
, hash_size
, &pad
,
350 random_pad
, block_algo
, blocksize
);
357 /* copy the encrypted data to cipher_data.
359 if (cipher_size
< length
)
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
)
374 return GNUTLS_E_RANDOM_FAILED
;
376 data_ptr
+= blocksize
;
379 memcpy (data_ptr
, compressed
.data
, compressed
.size
);
380 data_ptr
+= compressed
.size
;
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
);
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
,
413 gnutls_datum_t ciphertext
, uint8_t type
)
415 uint8_t MAC
[MAX_HASH_SIZE
];
421 int ret
, i
, pad_failed
= 0;
422 uint8_t major
, minor
;
423 gnutls_protocol_t ver
;
425 _gnutls_hash_get_algo_len (session
->security_parameters
.
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
);
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
)
445 return GNUTLS_E_INTERNAL_ERROR
;
449 /* actual decryption (inplace)
451 switch (_gnutls_cipher_is_block
452 (session
->security_parameters
.read_bulk_cipher_algorithm
))
455 if ((ret
= _gnutls_cipher_decrypt (session
->connection_state
.
458 ciphertext
.size
)) < 0)
464 length
= ciphertext
.size
- hash_size
;
468 if ((ciphertext
.size
< blocksize
) || (ciphertext
.size
% blocksize
!= 0))
471 return GNUTLS_E_DECRYPTION_FAILED
;
474 if ((ret
= _gnutls_cipher_decrypt (session
->connection_state
.
477 ciphertext
.size
)) < 0)
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)
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
)
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
;
522 return GNUTLS_E_INTERNAL_ERROR
;
527 c_length
= _gnutls_conv_uint16 ((uint16_t) length
);
529 /* Pass the type, version, length and compressed through
532 if (td
!= GNUTLS_MAC_FAILED
)
535 UINT64DATA (session
->connection_state
.
536 read_sequence_number
), 8);
538 _gnutls_hmac (td
, &type
, 1);
539 if (ver
>= GNUTLS_TLS1
)
541 _gnutls_hmac (td
, &major
, 1);
542 _gnutls_hmac (td
, &minor
, 1);
544 _gnutls_hmac (td
, &c_length
, 2);
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
558 /* HMAC was not the same.
560 if (memcmp (MAC
, &ciphertext
.data
[length
], hash_size
) != 0)
563 return GNUTLS_E_DECRYPTION_FAILED
;
566 /* copy the decrypted stuff to compress_data.
568 if (compress_size
< length
)
571 return GNUTLS_E_INTERNAL_ERROR
;
573 memcpy (compress_data
, ciphertext
.data
, length
);