2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 Free
3 * 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,
26 /* Functions that are supposed to run after the handshake procedure is
27 * finished. These functions activate the established security parameters.
30 #include <gnutls_int.h>
31 #include <gnutls_constate.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_kx.h>
34 #include <gnutls_algorithms.h>
35 #include <gnutls_num.h>
36 #include <gnutls_datum.h>
37 #include <gnutls_state.h>
39 static const char keyexp
[] = "key expansion";
40 static const int keyexp_length
= sizeof (keyexp
) - 1;
42 static const char ivblock
[] = "IV block";
43 static const int ivblock_length
= sizeof (ivblock
) - 1;
45 static const char cliwrite
[] = "client write key";
46 static const int cliwrite_length
= sizeof (cliwrite
) - 1;
48 static const char servwrite
[] = "server write key";
49 static const int servwrite_length
= sizeof (servwrite
) - 1;
51 #define EXPORT_FINAL_KEY_SIZE 16
53 /* This function is to be called after handshake, when master_secret,
54 * client_random and server_random have been initialized.
55 * This function creates the keys and stores them into pending session.
56 * (session->cipher_specs)
59 _gnutls_set_keys (gnutls_session_t session
, int hash_size
, int IV_size
,
60 int key_size
, int export_flag
)
62 /* FIXME: This function is too long
64 opaque rnd
[2 * GNUTLS_RANDOM_SIZE
];
65 opaque rrnd
[2 * GNUTLS_RANDOM_SIZE
];
69 /* avoid using malloc */
70 opaque key_block
[2 * MAX_HASH_SIZE
+ 2 * MAX_CIPHER_KEY_SIZE
+
71 2 * MAX_CIPHER_BLOCK_SIZE
];
73 if (session
->cipher_specs
.generated_keys
!= 0)
75 /* keys have already been generated.
76 * reset generated_keys and exit normally.
78 session
->cipher_specs
.generated_keys
= 0;
82 block_size
= 2 * hash_size
+ 2 * key_size
;
84 block_size
+= 2 * IV_size
;
86 memcpy (rnd
, session
->security_parameters
.server_random
,
88 memcpy (&rnd
[GNUTLS_RANDOM_SIZE
],
89 session
->security_parameters
.client_random
, GNUTLS_RANDOM_SIZE
);
91 memcpy (rrnd
, session
->security_parameters
.client_random
,
93 memcpy (&rrnd
[GNUTLS_RANDOM_SIZE
],
94 session
->security_parameters
.server_random
, GNUTLS_RANDOM_SIZE
);
96 if (session
->security_parameters
.version
== GNUTLS_SSL3
)
99 _gnutls_ssl3_generate_random
100 (session
->security_parameters
.master_secret
, GNUTLS_MASTER_SIZE
, rnd
,
101 2 * GNUTLS_RANDOM_SIZE
, block_size
, key_block
);
106 _gnutls_PRF (session
, session
->security_parameters
.master_secret
,
107 GNUTLS_MASTER_SIZE
, keyexp
, keyexp_length
,
108 rnd
, 2 * GNUTLS_RANDOM_SIZE
, block_size
, key_block
);
117 _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size
,
118 _gnutls_bin2hex (key_block
, block_size
, buf
,
121 _gnutls_free_datum (&session
->cipher_specs
.server_write_mac_secret
);
122 _gnutls_free_datum (&session
->cipher_specs
.client_write_mac_secret
);
123 _gnutls_free_datum (&session
->cipher_specs
.server_write_IV
);
124 _gnutls_free_datum (&session
->cipher_specs
.client_write_IV
);
125 _gnutls_free_datum (&session
->cipher_specs
.server_write_key
);
126 _gnutls_free_datum (&session
->cipher_specs
.client_write_key
);
132 if (_gnutls_sset_datum
133 (&session
->cipher_specs
.client_write_mac_secret
,
134 &key_block
[pos
], hash_size
) < 0)
137 return GNUTLS_E_MEMORY_ERROR
;
141 if (_gnutls_sset_datum
142 (&session
->cipher_specs
.server_write_mac_secret
,
143 &key_block
[pos
], hash_size
) < 0)
146 return GNUTLS_E_MEMORY_ERROR
;
153 opaque key1
[EXPORT_FINAL_KEY_SIZE
];
154 opaque key2
[EXPORT_FINAL_KEY_SIZE
];
155 opaque
*client_write_key
, *server_write_key
;
156 int client_write_key_size
, server_write_key_size
;
158 if (export_flag
== 0)
160 client_write_key
= &key_block
[pos
];
161 client_write_key_size
= key_size
;
165 server_write_key
= &key_block
[pos
];
166 server_write_key_size
= key_size
;
173 client_write_key
= key1
;
174 server_write_key
= key2
;
176 /* generate the final keys */
178 if (session
->security_parameters
.version
== GNUTLS_SSL3
)
181 _gnutls_ssl3_hash_md5 (&key_block
[pos
],
183 2 * GNUTLS_RANDOM_SIZE
,
184 EXPORT_FINAL_KEY_SIZE
,
191 _gnutls_PRF (session
, &key_block
[pos
], key_size
,
192 cliwrite
, cliwrite_length
,
194 2 * GNUTLS_RANDOM_SIZE
,
195 EXPORT_FINAL_KEY_SIZE
, client_write_key
);
204 client_write_key_size
= EXPORT_FINAL_KEY_SIZE
;
207 if (session
->security_parameters
.version
== GNUTLS_SSL3
)
210 _gnutls_ssl3_hash_md5 (&key_block
[pos
], key_size
,
211 rnd
, 2 * GNUTLS_RANDOM_SIZE
,
212 EXPORT_FINAL_KEY_SIZE
,
218 _gnutls_PRF (session
, &key_block
[pos
], key_size
,
219 servwrite
, servwrite_length
,
220 rrnd
, 2 * GNUTLS_RANDOM_SIZE
,
221 EXPORT_FINAL_KEY_SIZE
, server_write_key
);
230 server_write_key_size
= EXPORT_FINAL_KEY_SIZE
;
234 if (_gnutls_sset_datum
235 (&session
->cipher_specs
.client_write_key
,
236 client_write_key
, client_write_key_size
) < 0)
239 return GNUTLS_E_MEMORY_ERROR
;
241 _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
242 client_write_key_size
,
243 _gnutls_bin2hex (client_write_key
,
244 client_write_key_size
, buf
,
247 if (_gnutls_sset_datum
248 (&session
->cipher_specs
.server_write_key
,
249 server_write_key
, server_write_key_size
) < 0)
252 return GNUTLS_E_MEMORY_ERROR
;
255 _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
256 server_write_key_size
,
257 _gnutls_bin2hex (server_write_key
,
258 server_write_key_size
, buf
,
264 /* IV generation in export and non export ciphers.
266 if (IV_size
> 0 && export_flag
== 0)
268 if (_gnutls_sset_datum
269 (&session
->cipher_specs
.client_write_IV
, &key_block
[pos
],
273 return GNUTLS_E_MEMORY_ERROR
;
277 if (_gnutls_sset_datum
278 (&session
->cipher_specs
.server_write_IV
, &key_block
[pos
],
282 return GNUTLS_E_MEMORY_ERROR
;
287 else if (IV_size
> 0 && export_flag
!= 0)
289 opaque iv_block
[MAX_CIPHER_BLOCK_SIZE
* 2];
291 if (session
->security_parameters
.version
== GNUTLS_SSL3
)
293 ret
= _gnutls_ssl3_hash_md5 ("", 0,
294 rrnd
, GNUTLS_RANDOM_SIZE
* 2,
303 ret
= _gnutls_ssl3_hash_md5 ("", 0, rnd
,
304 GNUTLS_RANDOM_SIZE
* 2,
305 IV_size
, &iv_block
[IV_size
]);
310 ret
= _gnutls_PRF (session
, "", 0,
311 ivblock
, ivblock_length
, rrnd
,
312 2 * GNUTLS_RANDOM_SIZE
, IV_size
* 2, iv_block
);
321 if (_gnutls_sset_datum
322 (&session
->cipher_specs
.client_write_IV
, iv_block
, IV_size
) < 0)
325 return GNUTLS_E_MEMORY_ERROR
;
328 if (_gnutls_sset_datum
329 (&session
->cipher_specs
.server_write_IV
,
330 &iv_block
[IV_size
], IV_size
) < 0)
333 return GNUTLS_E_MEMORY_ERROR
;
337 session
->cipher_specs
.generated_keys
= 1;
343 _gnutls_set_read_keys (gnutls_session_t session
)
347 int key_size
, export_flag
;
348 gnutls_cipher_algorithm_t algo
;
349 gnutls_mac_algorithm_t mac_algo
;
351 mac_algo
= session
->security_parameters
.read_mac_algorithm
;
352 algo
= session
->security_parameters
.read_bulk_cipher_algorithm
;
354 hash_size
= _gnutls_hash_get_algo_len (mac_algo
);
355 IV_size
= _gnutls_cipher_get_iv_size (algo
);
356 key_size
= gnutls_cipher_get_key_size (algo
);
357 export_flag
= _gnutls_cipher_get_export_flag (algo
);
359 return _gnutls_set_keys (session
, hash_size
, IV_size
, key_size
,
364 _gnutls_set_write_keys (gnutls_session_t session
)
368 int key_size
, export_flag
;
369 gnutls_cipher_algorithm_t algo
;
370 gnutls_mac_algorithm_t mac_algo
;
372 mac_algo
= session
->security_parameters
.write_mac_algorithm
;
373 algo
= session
->security_parameters
.write_bulk_cipher_algorithm
;
375 hash_size
= _gnutls_hash_get_algo_len (mac_algo
);
376 IV_size
= _gnutls_cipher_get_iv_size (algo
);
377 key_size
= gnutls_cipher_get_key_size (algo
);
378 export_flag
= _gnutls_cipher_get_export_flag (algo
);
380 return _gnutls_set_keys (session
, hash_size
, IV_size
, key_size
,
384 #define CPY_EXTENSIONS \
385 gnutls_free(dst->extensions.session_ticket); \
386 gnutls_free(dst->extensions.oprfi_client); \
387 gnutls_free(dst->extensions.oprfi_server); \
388 memcpy(&dst->extensions.server_names, &src->extensions, sizeof(src->extensions)); \
389 memset(&src->extensions, 0, sizeof(src->extensions)) /* avoid duplicate free's */
391 #define CPY_COMMON dst->entity = src->entity; \
392 dst->kx_algorithm = src->kx_algorithm; \
393 memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(cipher_suite_st)); \
394 memcpy( dst->master_secret, src->master_secret, GNUTLS_MASTER_SIZE); \
395 memcpy( dst->client_random, src->client_random, GNUTLS_RANDOM_SIZE); \
396 memcpy( dst->server_random, src->server_random, GNUTLS_RANDOM_SIZE); \
397 memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
398 dst->session_id_size = src->session_id_size; \
399 dst->cert_type = src->cert_type; \
400 dst->timestamp = src->timestamp; \
401 dst->max_record_recv_size = src->max_record_recv_size; \
402 dst->max_record_send_size = src->max_record_send_size; \
403 dst->version = src->version; \
404 memcpy( &dst->inner_secret, &src->inner_secret, GNUTLS_MASTER_SIZE)
407 _gnutls_cpy_read_security_parameters (security_parameters_st
*
408 dst
, security_parameters_st
* src
)
412 dst
->read_bulk_cipher_algorithm
= src
->read_bulk_cipher_algorithm
;
413 dst
->read_mac_algorithm
= src
->read_mac_algorithm
;
414 dst
->read_compression_algorithm
= src
->read_compression_algorithm
;
418 _gnutls_cpy_write_security_parameters (security_parameters_st
*
419 dst
, security_parameters_st
* src
)
422 CPY_EXTENSIONS
; /* only do once */
424 dst
->write_bulk_cipher_algorithm
= src
->write_bulk_cipher_algorithm
;
425 dst
->write_mac_algorithm
= src
->write_mac_algorithm
;
426 dst
->write_compression_algorithm
= src
->write_compression_algorithm
;
429 /* Sets the current connection session to conform with the
430 * Security parameters(pending session), and initializes encryption.
431 * Actually it initializes and starts encryption ( so it needs
432 * secrets and random numbers to have been negotiated)
433 * This is to be called after sending the Change Cipher Spec packet.
436 _gnutls_connection_state_init (gnutls_session_t session
)
440 /* Setup the master secret
442 if ((ret
= _gnutls_generate_master (session
, 0)) < 0)
453 /* Initializes the read connection session
454 * (read encrypted data)
457 _gnutls_read_connection_state_init (gnutls_session_t session
)
462 _gnutls_uint64zero (session
->connection_state
.read_sequence_number
);
464 /* Update internals from CipherSuite selected.
465 * If we are resuming just copy the connection session
467 if (session
->internals
.resumed
== RESUME_FALSE
)
469 rc
= _gnutls_set_read_cipher (session
,
470 _gnutls_cipher_suite_get_cipher_algo
471 (&session
->security_parameters
.
472 current_cipher_suite
));
475 rc
= _gnutls_set_read_mac (session
,
476 _gnutls_cipher_suite_get_mac_algo
477 (&session
->security_parameters
.
478 current_cipher_suite
));
482 rc
= _gnutls_set_kx (session
,
483 _gnutls_cipher_suite_get_kx_algo
484 (&session
->security_parameters
.
485 current_cipher_suite
));
489 rc
= _gnutls_set_read_compression (session
,
497 _gnutls_cpy_read_security_parameters (&session
->security_parameters
,
499 resumed_security_parameters
);
503 rc
= _gnutls_set_read_keys (session
);
507 _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n",
509 _gnutls_cipher_suite_get_name
510 (&session
->security_parameters
.
511 current_cipher_suite
));
513 if (_gnutls_compression_is_ok
514 (session
->security_parameters
.read_compression_algorithm
) != 0)
517 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
520 if (_gnutls_mac_is_ok
521 (session
->security_parameters
.read_mac_algorithm
) != 0)
524 return GNUTLS_E_INTERNAL_ERROR
;
527 /* Free all the previous keys/ sessions etc.
529 if (session
->connection_state
.read_mac_secret
.data
!= NULL
)
530 _gnutls_free_datum (&session
->connection_state
.read_mac_secret
);
532 _gnutls_cipher_deinit (&session
->connection_state
.read_cipher_state
);
534 if (session
->connection_state
.read_compression_state
!= NULL
)
535 _gnutls_comp_deinit (session
->connection_state
.read_compression_state
, 1);
539 _gnutls_hash_get_algo_len (session
->security_parameters
.
542 _gnutls_handshake_log
543 ("HSK[%p]: Initializing internal [read] cipher sessions\n", session
);
545 switch (session
->security_parameters
.entity
)
548 /* initialize cipher session
550 rc
= _gnutls_cipher_init (&session
->connection_state
.read_cipher_state
,
552 security_parameters
.read_bulk_cipher_algorithm
,
553 &session
->cipher_specs
.client_write_key
,
554 &session
->cipher_specs
.client_write_IV
);
556 && session
->security_parameters
.read_bulk_cipher_algorithm
!=
563 /* copy mac secrets from cipherspecs, to connection
568 if (_gnutls_sset_datum (&session
->connection_state
.read_mac_secret
,
569 session
->cipher_specs
.
570 client_write_mac_secret
.data
,
571 session
->cipher_specs
.
572 client_write_mac_secret
.size
) < 0)
575 return GNUTLS_E_MEMORY_ERROR
;
583 rc
= _gnutls_cipher_init (&session
->connection_state
.read_cipher_state
,
585 security_parameters
.read_bulk_cipher_algorithm
,
586 &session
->cipher_specs
.server_write_key
,
587 &session
->cipher_specs
.server_write_IV
);
590 && session
->security_parameters
.read_bulk_cipher_algorithm
!=
594 return GNUTLS_E_INTERNAL_ERROR
;
598 /* copy mac secret to connection session
602 if (_gnutls_sset_datum (&session
->connection_state
.read_mac_secret
,
603 session
->cipher_specs
.
604 server_write_mac_secret
.data
,
605 session
->cipher_specs
.
606 server_write_mac_secret
.size
) < 0)
609 return GNUTLS_E_MEMORY_ERROR
;
615 default: /* this check is useless */
617 return GNUTLS_E_INTERNAL_ERROR
;
620 session
->connection_state
.read_compression_state
=
621 _gnutls_comp_init (session
->security_parameters
.
622 read_compression_algorithm
, 1);
624 if (session
->connection_state
.read_compression_state
== GNUTLS_COMP_FAILED
)
627 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
635 /* Initializes the write connection session
636 * (write encrypted data)
639 _gnutls_write_connection_state_init (gnutls_session_t session
)
644 _gnutls_uint64zero (session
->connection_state
.write_sequence_number
);
646 /* Update internals from CipherSuite selected.
647 * If we are resuming just copy the connection session
649 if (session
->internals
.resumed
== RESUME_FALSE
)
651 rc
= _gnutls_set_write_cipher (session
,
652 _gnutls_cipher_suite_get_cipher_algo
653 (&session
->security_parameters
.
654 current_cipher_suite
));
657 rc
= _gnutls_set_write_mac (session
,
658 _gnutls_cipher_suite_get_mac_algo
659 (&session
->security_parameters
.
660 current_cipher_suite
));
664 rc
= _gnutls_set_kx (session
,
665 _gnutls_cipher_suite_get_kx_algo
666 (&session
->security_parameters
.
667 current_cipher_suite
));
671 rc
= _gnutls_set_write_compression (session
,
679 _gnutls_cpy_write_security_parameters (&session
->security_parameters
,
681 resumed_security_parameters
);
684 rc
= _gnutls_set_write_keys (session
);
688 _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n", session
,
689 _gnutls_cipher_suite_get_name
690 (&session
->security_parameters
.
691 current_cipher_suite
));
693 if (_gnutls_compression_is_ok
694 (session
->security_parameters
.write_compression_algorithm
) != 0)
697 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
700 if (_gnutls_mac_is_ok
701 (session
->security_parameters
.write_mac_algorithm
) != 0)
704 return GNUTLS_E_INTERNAL_ERROR
;
709 /* Free all the previous keys/ sessions etc.
711 if (session
->connection_state
.write_mac_secret
.data
!= NULL
)
712 _gnutls_free_datum (&session
->connection_state
.write_mac_secret
);
714 _gnutls_cipher_deinit (&session
->connection_state
.write_cipher_state
);
716 if (session
->connection_state
.write_compression_state
!= NULL
)
717 _gnutls_comp_deinit (session
->connection_state
.write_compression_state
,
721 _gnutls_hash_get_algo_len (session
->security_parameters
.
722 write_mac_algorithm
);
724 _gnutls_handshake_log
725 ("HSK[%p]: Initializing internal [write] cipher sessions\n", session
);
727 switch (session
->security_parameters
.entity
)
730 /* initialize cipher session
732 rc
= _gnutls_cipher_init (&session
->connection_state
.write_cipher_state
,
733 session
->security_parameters
.
734 write_bulk_cipher_algorithm
,
735 &session
->cipher_specs
.server_write_key
,
736 &session
->cipher_specs
.server_write_IV
);
739 && session
->security_parameters
.write_bulk_cipher_algorithm
!=
743 return GNUTLS_E_INTERNAL_ERROR
;
747 /* copy mac secrets from cipherspecs, to connection
752 if (_gnutls_sset_datum (&session
->connection_state
.write_mac_secret
,
753 session
->cipher_specs
.
754 server_write_mac_secret
.data
,
755 session
->cipher_specs
.
756 server_write_mac_secret
.size
) < 0)
759 return GNUTLS_E_MEMORY_ERROR
;
768 rc
= _gnutls_cipher_init (&session
->connection_state
.write_cipher_state
,
769 session
->security_parameters
.
770 write_bulk_cipher_algorithm
,
771 &session
->cipher_specs
.client_write_key
,
772 &session
->cipher_specs
.client_write_IV
);
775 && session
->security_parameters
.write_bulk_cipher_algorithm
!=
779 return GNUTLS_E_INTERNAL_ERROR
;
782 /* copy mac secret to connection session
786 if (_gnutls_sset_datum (&session
->connection_state
.write_mac_secret
,
787 session
->cipher_specs
.
788 client_write_mac_secret
.data
,
789 session
->cipher_specs
.
790 client_write_mac_secret
.size
) < 0)
793 return GNUTLS_E_MEMORY_ERROR
;
801 return GNUTLS_E_INTERNAL_ERROR
;
805 session
->connection_state
.write_compression_state
=
806 _gnutls_comp_init (session
->security_parameters
.
807 write_compression_algorithm
, 0);
809 if (session
->connection_state
.write_compression_state
== GNUTLS_COMP_FAILED
)
812 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
818 /* Sets the specified cipher into the pending session
821 _gnutls_set_read_cipher (gnutls_session_t session
,
822 gnutls_cipher_algorithm_t algo
)
825 if (_gnutls_cipher_is_ok (algo
) == 0)
827 if (_gnutls_cipher_priority (session
, algo
) < 0)
830 return GNUTLS_E_UNWANTED_ALGORITHM
;
833 session
->security_parameters
.read_bulk_cipher_algorithm
= algo
;
839 return GNUTLS_E_INTERNAL_ERROR
;
847 _gnutls_set_write_cipher (gnutls_session_t session
,
848 gnutls_cipher_algorithm_t algo
)
851 if (_gnutls_cipher_is_ok (algo
) == 0)
853 if (_gnutls_cipher_priority (session
, algo
) < 0)
856 return GNUTLS_E_UNWANTED_ALGORITHM
;
859 session
->security_parameters
.write_bulk_cipher_algorithm
= algo
;
865 return GNUTLS_E_INTERNAL_ERROR
;
873 /* Sets the specified algorithm into pending compression session
876 _gnutls_set_read_compression (gnutls_session_t session
,
877 gnutls_compression_method_t algo
)
880 if (_gnutls_compression_is_ok (algo
) == 0)
882 session
->security_parameters
.read_compression_algorithm
= algo
;
887 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
894 _gnutls_set_write_compression (gnutls_session_t session
,
895 gnutls_compression_method_t algo
)
898 if (_gnutls_compression_is_ok (algo
) == 0)
900 session
->security_parameters
.write_compression_algorithm
= algo
;
905 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
;
911 /* Sets the specified kx algorithm into pending session
914 _gnutls_set_kx (gnutls_session_t session
, gnutls_kx_algorithm_t algo
)
917 if (_gnutls_kx_is_ok (algo
) == 0)
919 session
->security_parameters
.kx_algorithm
= algo
;
924 return GNUTLS_E_INTERNAL_ERROR
;
926 if (_gnutls_kx_priority (session
, algo
) < 0)
929 /* we shouldn't get here */
930 return GNUTLS_E_UNWANTED_ALGORITHM
;
937 /* Sets the specified mac algorithm into pending session */
939 _gnutls_set_read_mac (gnutls_session_t session
, gnutls_mac_algorithm_t algo
)
942 if (_gnutls_mac_is_ok (algo
) == 0)
944 session
->security_parameters
.read_mac_algorithm
= algo
;
949 return GNUTLS_E_INTERNAL_ERROR
;
951 if (_gnutls_mac_priority (session
, algo
) < 0)
954 return GNUTLS_E_UNWANTED_ALGORITHM
;
963 _gnutls_set_write_mac (gnutls_session_t session
, gnutls_mac_algorithm_t algo
)
966 if (_gnutls_mac_is_ok (algo
) == 0)
968 session
->security_parameters
.write_mac_algorithm
= algo
;
973 return GNUTLS_E_INTERNAL_ERROR
;
975 if (_gnutls_mac_priority (session
, algo
) < 0)
978 return GNUTLS_E_UNWANTED_ALGORITHM
;