added some support for session resuming (in client)
[gnutls:gnutls.git] / lib / gnutls_cipher.c
1 /*
2  * Copyright (C) 2000 Nikos Mavroyanopoulos
3  *
4  * This file is part of GNUTLS.
5  *
6  * GNUTLS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUTLS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <defines.h>
22 #include "gnutls_int.h"
23 #include "gnutls_errors.h"
24 #include "gnutls_compress.h"
25 #include "gnutls_cipher.h"
26 #include "gnutls_algorithms.h"
27 #include "gnutls_hash_int.h"
28 #include "gnutls_cipher_int.h"
29
30 int _gnutls_encrypt(GNUTLS_STATE state, char *data, size_t data_size,
31                     uint8 ** ciphertext, ContentType type)
32 {
33         GNUTLSPlaintext *gtxt;
34         GNUTLSCompressed *gcomp;
35         GNUTLSCiphertext *gcipher;
36         int total_length = 0, err, i;
37
38         if (data_size == 0)
39                 return 0;
40
41         err =
42             _gnutls_text2TLSPlaintext(state, type, &gtxt, data, data_size);
43         if (err < 0) {
44                 gnutls_assert();
45                 return err;
46         }
47
48         err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
49         if (err < 0) {
50                 gnutls_assert();
51                 return err;
52         }
53
54         _gnutls_freeTLSPlaintext(gtxt);
55
56         err = _gnutls_TLSCompressed2TLSCiphertext(state, &gcipher, gcomp);
57         if (err < 0) {
58                 gnutls_assert();
59                 return err;
60         }
61
62         _gnutls_freeTLSCompressed(gcomp);
63
64         *ciphertext = gnutls_malloc(gcipher->length);
65         if (*ciphertext == NULL) {
66                 gnutls_assert();
67                 return GNUTLS_E_MEMORY_ERROR;
68         }
69         memmove((*ciphertext), gcipher->fragment, gcipher->length);
70
71         total_length += gcipher->length;
72         _gnutls_freeTLSCiphertext(gcipher);
73
74         return total_length;
75 }
76
77 int _gnutls_decrypt(GNUTLS_STATE state, char *ciphertext,
78                     size_t ciphertext_size, uint8 ** data,
79                     ContentType type)
80 {
81         GNUTLSPlaintext *gtxt;
82         GNUTLSCompressed *gcomp;
83         GNUTLSCiphertext gcipher;
84         int iterations, i;
85         int err, ret;
86         int total_length = 0;
87
88         if (ciphertext_size == 0)
89                 return 0;
90
91         gcipher.type = type;
92         gcipher.length = ciphertext_size;
93         gcipher.version.major = state->connection_state.version.major;
94         gcipher.version.minor = state->connection_state.version.minor;
95         gcipher.fragment = gnutls_malloc(ciphertext_size);
96         memmove(gcipher.fragment, ciphertext, ciphertext_size);
97
98         ret = _gnutls_TLSCiphertext2TLSCompressed(state, &gcomp, &gcipher);
99         if (ret < 0) {
100                 gnutls_free(gcipher.fragment);
101                 return ret;
102         }
103         gnutls_free(gcipher.fragment);
104
105         ret = _gnutls_TLSCompressed2TLSPlaintext(state, &gtxt, gcomp);
106         if (ret < 0) {
107                 return ret;
108         }
109
110         _gnutls_freeTLSCompressed(gcomp);
111
112         ret = _gnutls_TLSPlaintext2text((void *) data, gtxt);
113         if (ret < 0) {
114                 return ret;
115         }
116         ret = gtxt->length;
117
118         _gnutls_freeTLSPlaintext(gtxt);
119
120         return ret;
121 }
122
123
124 /* Sets the specified cipher into the pending state */
125 int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo)
126 {
127
128         if (_gnutls_cipher_is_ok(algo) == 0) {
129                 if (_gnutls_cipher_priority(state, algo) < 0) {
130                         gnutls_assert();
131                         return GNUTLS_E_UNWANTED_ALGORITHM;
132                 }
133
134                 state->security_parameters.bulk_cipher_algorithm = algo;
135                 if (_gnutls_cipher_is_block(algo) == 1) {
136                         state->security_parameters.cipher_type =
137                             CIPHER_BLOCK;
138                 } else {
139                         state->security_parameters.cipher_type =
140                             CIPHER_STREAM;
141                 }
142
143                 state->security_parameters.key_material_length =
144                     state->security_parameters.key_size =
145                     _gnutls_cipher_get_key_size(algo);
146                 state->security_parameters.IV_size =
147                     _gnutls_cipher_get_iv_size(algo);
148         } else {
149                 gnutls_assert();
150                 return GNUTLS_E_UNKNOWN_CIPHER;
151         }
152
153         return 0;
154
155 }
156
157 /* Sets the specified algorithm into pending compression state */
158 int _gnutls_set_compression(GNUTLS_STATE state, CompressionMethod algo)
159 {
160
161         if (_gnutls_compression_is_ok(algo)==0) {
162                 state->security_parameters.compression_algorithm = algo;
163         } else {
164                 gnutls_assert();
165                 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
166         }
167         return 0;
168
169 }
170
171 /* Sets the specified mac algorithm into pending state */
172 int _gnutls_set_mac(GNUTLS_STATE state, MACAlgorithm algo)
173 {
174
175         if (_gnutls_mac_is_ok(algo) == 0) {
176                 state->security_parameters.mac_algorithm = algo;
177                 state->security_parameters.hash_size =
178                     _gnutls_mac_get_digest_size(algo);
179         } else {
180                 gnutls_assert();
181                 return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
182         }
183         if (_gnutls_mac_priority(state, algo) < 0) {
184                 gnutls_assert();
185                 return GNUTLS_E_UNWANTED_ALGORITHM;
186         }
187
188
189         return 0;
190
191 }
192
193 /* Sets the current connection state to conform with the
194  * Security parameters(pending state), and initializes encryption.
195  * Actually it initializes and starts encryption ( so it needs
196  * secrets and random numbers to have been negotiated)
197  * This is to be called after sending the Change Cipher Spec packet.
198  */
199 int _gnutls_connection_state_init(GNUTLS_STATE state)
200 {
201         int rc, mac_size;
202
203         state->connection_state.write_sequence_number = 0;
204         state->connection_state.read_sequence_number = 0;
205
206 /* Update internals from CipherSuite selected.
207  * If we are resuming just copy the connection state
208  */
209         if (state->gnutls_internals.resumed==RESUME_FALSE) {
210                 rc =
211                     _gnutls_set_cipher(state,
212                                _gnutls_cipher_suite_get_cipher_algo
213                                (state->gnutls_internals.current_cipher_suite));
214                 if (rc < 0)
215                         return rc;
216                 rc =
217                     _gnutls_set_mac(state,
218                             _gnutls_cipher_suite_get_mac_algo
219                             (state->gnutls_internals.current_cipher_suite));
220                 if (rc < 0)
221                         return rc;
222
223                 rc =
224                     _gnutls_set_compression(state,
225                                     state->gnutls_internals.compression_method);
226                 if (rc < 0)
227                         return rc;
228         } else {
229                  memcpy( &state->security_parameters, &state->gnutls_internals.resumed_security_parameters, sizeof(SecurityParameters));
230 #ifdef HARD_DEBUG
231                  fprintf(stderr, "Master Secret: %s\n", _gnutls_bin2hex(state->security_parameters.master_secret, 48));
232 #endif
233         }
234 /* Setup the keys since we have the master secret 
235  */
236         _gnutls_set_keys(state);
237
238
239 #ifdef DEBUG
240         fprintf(stderr, "Cipher Suite: %s\n",
241                 _gnutls_cipher_suite_get_name(state->
242                                               gnutls_internals.current_cipher_suite));
243         fprintf(stderr, "Cipher: %s\n",
244                 _gnutls_cipher_get_name(state->security_parameters.
245                                         bulk_cipher_algorithm));
246         fprintf(stderr, "MAC: %s\n",
247                 _gnutls_mac_get_name(state->security_parameters.
248                                      mac_algorithm));
249         fprintf(stderr, "Compression: %s\n", _gnutls_compression_get_name(state->security_parameters.compression_algorithm));
250 #endif
251
252         if (state->connection_state.write_mac_secret!=NULL)
253                 gnutls_free(state->connection_state.write_mac_secret);
254         if (state->connection_state.read_mac_secret!=NULL)
255                 gnutls_free(state->connection_state.read_mac_secret);
256
257         if (state->connection_state.read_cipher_state != NULL)
258                 gnutls_cipher_deinit(state->connection_state.
259                                      read_cipher_state);
260
261         if (state->connection_state.write_cipher_state != NULL)
262                 gnutls_cipher_deinit(state->connection_state.
263                                      write_cipher_state);
264
265         if (state->connection_state.read_compression_state!=NULL)
266                 gnutls_free(state->connection_state.read_compression_state);
267         if (state->connection_state.write_compression_state!=NULL)
268                 gnutls_free(state->connection_state.write_compression_state);
269
270         if (_gnutls_compression_is_ok(state->security_parameters.compression_algorithm) == 0) {
271                 state->connection_state.read_compression_state = NULL;
272                 state->connection_state.write_compression_state = NULL;
273         } else {
274                 gnutls_assert();
275                 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
276         }
277
278         if (_gnutls_mac_is_ok(state->security_parameters.mac_algorithm) == 0) {
279
280                 mac_size =
281                     _gnutls_mac_get_digest_size(state->security_parameters.
282                                                 mac_algorithm);
283                 state->connection_state.read_mac_secret = NULL;
284                 state->connection_state.write_mac_secret = NULL;
285                 state->connection_state.mac_secret_size =
286                     state->security_parameters.hash_size;
287
288                 if (mac_size > 0) {
289                         state->connection_state.read_mac_secret =
290                             gnutls_malloc(mac_size);
291                         state->connection_state.write_mac_secret =
292                             gnutls_malloc(mac_size);
293                 }
294         } else {
295                 gnutls_assert();
296                 return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
297         }
298
299         switch (state->security_parameters.entity) {
300         case GNUTLS_SERVER:
301                 state->connection_state.write_cipher_state =
302                     gnutls_cipher_init(state->security_parameters.
303                                        bulk_cipher_algorithm,
304                                        state->cipher_specs.
305                                        server_write_key,
306                                        state->security_parameters.key_size,
307                                        state->cipher_specs.server_write_IV,
308                                        state->security_parameters.IV_size);
309                 if (state->connection_state.write_cipher_state ==
310                     GNUTLS_CIPHER_FAILED
311                     && state->security_parameters.bulk_cipher_algorithm !=
312                     GNUTLS_NULL) {
313                         gnutls_assert();
314                         return GNUTLS_E_UNKNOWN_CIPHER;
315                 }
316
317                 if (state->connection_state.mac_secret_size > 0) {
318                         memmove(state->connection_state.read_mac_secret,
319                                 state->
320                                 cipher_specs.client_write_mac_secret,
321                                 state->connection_state.mac_secret_size);
322                         memmove(state->connection_state.write_mac_secret,
323                                 state->cipher_specs.
324                                 server_write_mac_secret,
325                                 state->connection_state.mac_secret_size);
326                 }
327
328                 state->connection_state.read_cipher_state =
329                     gnutls_cipher_init(state->security_parameters.
330                                        bulk_cipher_algorithm,
331                                        state->cipher_specs.
332                                        client_write_key,
333                                        state->security_parameters.key_size,
334                                        state->cipher_specs.client_write_IV,
335                                        state->security_parameters.IV_size);
336                 if (state->connection_state.read_cipher_state ==
337                     GNUTLS_CIPHER_FAILED
338                     && state->security_parameters.bulk_cipher_algorithm !=
339                     GNUTLS_NULL) {
340                         gnutls_assert();
341                         return GNUTLS_E_UNKNOWN_CIPHER;
342                 }
343
344                 break;
345
346         case GNUTLS_CLIENT:
347                 state->connection_state.read_cipher_state =
348                     gnutls_cipher_init(state->security_parameters.
349                                        bulk_cipher_algorithm,
350                                        state->cipher_specs.
351                                        server_write_key,
352                                        state->security_parameters.key_size,
353                                        state->cipher_specs.server_write_IV,
354                                        state->security_parameters.IV_size);
355                 if (state->connection_state.read_cipher_state ==
356                     GNUTLS_CIPHER_FAILED
357                     && state->security_parameters.bulk_cipher_algorithm !=
358                     GNUTLS_NULL) {
359                         gnutls_assert();
360                         return GNUTLS_E_UNKNOWN_CIPHER;
361                 }
362
363                 if (state->connection_state.mac_secret_size > 0) {
364                         memmove(state->connection_state.read_mac_secret,
365                                 state->
366                                 cipher_specs.server_write_mac_secret,
367                                 state->connection_state.mac_secret_size);
368                         memmove(state->connection_state.write_mac_secret,
369                                 state->
370                                 cipher_specs.client_write_mac_secret,
371                                 state->connection_state.mac_secret_size);
372                 }
373
374                 state->connection_state.write_cipher_state =
375                     gnutls_cipher_init(state->security_parameters.
376                                        bulk_cipher_algorithm,
377                                        state->cipher_specs.
378                                        client_write_key,
379                                        state->security_parameters.key_size,
380                                        state->cipher_specs.client_write_IV,
381                                        state->security_parameters.IV_size);
382                 if (state->connection_state.write_cipher_state ==
383                     GNUTLS_CIPHER_FAILED
384                     && state->security_parameters.bulk_cipher_algorithm !=
385                     GNUTLS_NULL) {
386                         gnutls_assert();
387                         return GNUTLS_E_UNKNOWN_CIPHER;
388                 }
389                 break;
390
391         default:
392                 gnutls_assert();
393                 return GNUTLS_E_UNKNOWN_ERROR;
394         }
395
396         return 0;
397 }
398
399 /* This is the actual encryption */
400 int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
401                                         GNUTLSCiphertext **
402                                         cipher,
403                                         GNUTLSCompressed * compressed)
404 {
405         GNUTLSCiphertext *ciphertext;
406         uint8 *content, *MAC = NULL;
407         uint16 c_length;
408         uint8 *data;
409         uint8 pad;
410         uint8 *rand;
411         uint64 seq_num;
412         int length;
413         GNUTLS_MAC_HANDLE td;
414         int blocksize =
415             _gnutls_cipher_get_block_size(state->security_parameters.
416                                           bulk_cipher_algorithm);
417
418         content = gnutls_malloc(compressed->length);
419         memmove(content, compressed->fragment, compressed->length);
420
421         *cipher = gnutls_malloc(sizeof(GNUTLSCiphertext));
422         ciphertext = *cipher;
423
424         if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */
425                 td =
426                     gnutls_mac_init_ssl3(state->security_parameters.
427                                           mac_algorithm,
428                                           state->connection_state.
429                                           write_mac_secret,
430                                           state->connection_state.
431                                           mac_secret_size);
432         } else {
433                 td =
434                     gnutls_hmac_init(state->security_parameters.
435                                      mac_algorithm,
436                                      state->connection_state.
437                                      write_mac_secret,
438                                      state->connection_state.
439                                      mac_secret_size);
440         }
441         if (td == GNUTLS_MAC_FAILED
442             && state->security_parameters.mac_algorithm != GNUTLS_MAC_NULL) {
443                 gnutls_free(*cipher);
444                 gnutls_free(content);
445                 gnutls_assert();
446                 return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
447         }
448 #ifdef WORDS_BIGENDIAN
449         seq_num = state->connection_state.write_sequence_number;
450         c_length = compressed->length;
451 #else
452         c_length = byteswap16(compressed->length);
453         seq_num =
454             byteswap64(state->connection_state.write_sequence_number);
455 #endif
456         if (td != GNUTLS_MAC_FAILED) {  /* actually when the algorithm in not the NULL one */
457                 gnutls_hmac(td, &seq_num, 8);
458                 gnutls_hmac(td, &compressed->type, 1);
459                 if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */
460                         gnutls_hmac(td, &compressed->version.major, 1);
461                         gnutls_hmac(td, &compressed->version.minor, 1);
462                 }
463                 gnutls_hmac(td, &c_length, 2);
464                 gnutls_hmac(td, compressed->fragment, compressed->length);
465                 if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */
466                         MAC = gnutls_mac_deinit_ssl3(td);
467                 } else {
468                         MAC = gnutls_hmac_deinit(td);
469                 }
470         }
471         switch (state->security_parameters.cipher_type) {
472         case CIPHER_STREAM:
473                 length =
474                     compressed->length +
475                     state->security_parameters.hash_size;
476
477                 data = gnutls_malloc(length);
478                 memmove(data, content, compressed->length);
479                 memmove(&data[compressed->length], MAC,
480                         state->security_parameters.hash_size);
481
482                 gnutls_cipher_encrypt(state->connection_state.
483                                       write_cipher_state, data, length);
484                 ciphertext->fragment = data;
485                 ciphertext->length = length;
486                 ciphertext->type = compressed->type;
487                 ciphertext->version.major = compressed->version.major;
488                 ciphertext->version.minor = compressed->version.minor;
489
490                 break;
491         case CIPHER_BLOCK:
492                 rand = gcry_random_bytes(1, GCRY_WEAK_RANDOM);
493
494                 /* make rand a multiple of blocksize */
495                 if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
496                         rand[0] = 0;
497                 } else {
498                         rand[0] =
499                             (rand[0] % (255 / blocksize)) * blocksize;
500                 }
501
502                 length =
503                     compressed->length +
504                     state->security_parameters.hash_size;
505                 pad = (uint8) (blocksize - (length % blocksize)) + rand[0];
506
507                 length += pad;
508                 data = gnutls_malloc(length);
509
510                 memset(&data[length - pad], pad - 1, pad);
511                 memmove(data, content, compressed->length);
512
513                 memmove(&data[compressed->length], MAC,
514                         state->security_parameters.hash_size);
515                 gnutls_cipher_encrypt(state->connection_state.
516                                       write_cipher_state, data, length);
517
518                 ciphertext->fragment = data;
519                 ciphertext->length = length;
520                 ciphertext->type = compressed->type;
521                 ciphertext->version.major = compressed->version.major;
522                 ciphertext->version.minor = compressed->version.minor;
523
524                 gcry_free(rand);
525                 break;
526         default:
527                 gnutls_free(*cipher);
528                 gnutls_free(content);
529                 gnutls_assert();
530                 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
531         }
532
533         if (td != GNUTLS_MAC_FAILED)
534                 gnutls_free(MAC);
535         gnutls_free(content);
536
537         return 0;
538 }
539
540 int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state,
541                                         GNUTLSCompressed **
542                                         compress,
543                                         GNUTLSCiphertext * ciphertext)
544 {
545         GNUTLSCompressed *compressed;
546         uint8 *content, *MAC = NULL;
547         uint16 c_length;
548         uint8 *data;
549         uint8 pad;
550         uint64 seq_num;
551         uint16 length;
552         GNUTLS_MAC_HANDLE td;
553         int blocksize =
554             _gnutls_cipher_get_block_size(state->security_parameters.
555                                           bulk_cipher_algorithm);
556
557         content = gnutls_malloc(ciphertext->length);
558         memmove(content, ciphertext->fragment, ciphertext->length);
559
560         *compress = gnutls_malloc(sizeof(GNUTLSCompressed));
561         compressed = *compress;
562
563
564         if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
565                 td =
566                     gnutls_mac_init_ssl3(state->security_parameters.
567                                           mac_algorithm,
568                                           state->connection_state.
569                                           read_mac_secret,
570                                           state->connection_state.
571                                           mac_secret_size);
572         } else {
573                 td =
574                     gnutls_hmac_init(state->security_parameters.
575                                      mac_algorithm,
576                                      state->connection_state.
577                                      read_mac_secret,
578                                      state->connection_state.
579                                      mac_secret_size);
580         }
581         if (td == GNUTLS_MAC_FAILED
582             && state->security_parameters.mac_algorithm != GNUTLS_MAC_NULL) {
583                 gnutls_free(*compress);
584                 gnutls_free(content);
585                 gnutls_assert();
586                 return GNUTLS_E_UNKNOWN_MAC_ALGORITHM;
587         }
588
589
590         switch (state->security_parameters.cipher_type) {
591         case CIPHER_STREAM:
592                 length =
593                     ciphertext->length -
594                     state->security_parameters.hash_size;
595                 data = gnutls_malloc(length);
596                 memmove(data, content, length);
597
598                 compressed->fragment = data;
599                 compressed->length = length;
600                 compressed->type = ciphertext->type;
601                 compressed->version.major = ciphertext->version.major;
602                 compressed->version.minor = ciphertext->version.minor;
603                 break;
604         case CIPHER_BLOCK:
605                 if ((ciphertext->length < blocksize)
606                     || (ciphertext->length % blocksize != 0)) {
607                         gnutls_assert();
608                         return GNUTLS_E_DECRYPTION_FAILED;
609                 }
610                 gnutls_cipher_decrypt(state->connection_state.
611                                       read_cipher_state, content,
612                                       ciphertext->length);
613
614                 pad = content[ciphertext->length - 1] + 1;      /* pad */
615                 length =
616                     ciphertext->length -
617                     state->security_parameters.hash_size - pad;
618
619                 if (pad >
620                     ciphertext->length -
621                     state->security_parameters.hash_size) {
622                         gnutls_assert();
623                         return GNUTLS_E_RECEIVED_BAD_MESSAGE;
624                 }
625                 data = gnutls_malloc(length);
626                 memmove(data, content, length);
627
628                 compressed->fragment = data;
629                 compressed->length = length;
630                 compressed->type = ciphertext->type;
631                 compressed->version.major = ciphertext->version.major;
632                 compressed->version.minor = ciphertext->version.minor;
633                 break;
634         default:
635                 gnutls_free(*compress);
636                 gnutls_free(content);
637                 gnutls_assert();
638                 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
639         }
640
641 #ifdef WORDS_BIGENDIAN
642         seq_num = state->connection_state.read_sequence_number;
643         c_length = compressed->length;
644 #else
645         seq_num = byteswap64(state->connection_state.read_sequence_number);
646         c_length = byteswap16((uint16) compressed->length);
647 #endif
648
649
650         if (td != GNUTLS_MAC_FAILED) {
651                 gnutls_hmac(td, &seq_num, 8);
652                 gnutls_hmac(td, &compressed->type, 1);
653                 if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */
654                         gnutls_hmac(td, &compressed->version.major, 1);
655                         gnutls_hmac(td, &compressed->version.minor, 1);
656                 }
657                 gnutls_hmac(td, &c_length, 2);
658                 gnutls_hmac(td, data, compressed->length);
659                 if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */
660                         MAC = gnutls_mac_deinit_ssl3(td);
661                 } else {
662                         MAC = gnutls_hmac_deinit(td);
663                 }
664         }
665         /* HMAC was not the same. */
666         if (memcmp
667             (MAC, &content[compressed->length],
668              state->security_parameters.hash_size) != 0) {
669                 gnutls_assert();
670                 return GNUTLS_E_MAC_FAILED;
671         }
672
673
674         if (td != GNUTLS_MAC_FAILED)
675                 gnutls_free(MAC);
676         gnutls_free(content);
677
678         return 0;
679 }
680
681 int _gnutls_freeTLSCiphertext(GNUTLSCiphertext * ciphertext)
682 {
683         if (ciphertext == NULL)
684                 return 0;
685
686         gnutls_free(ciphertext->fragment);
687         gnutls_free(ciphertext);
688
689         return 0;
690 }