2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <utils/linked_list.h>
25 #include <utils/identification.h>
26 #include <utils/lexparser.h>
27 #include <crypto/prfs/prf.h>
28 #include <crypto/crypters/crypter.h>
29 #include <crypto/signers/signer.h>
32 ENUM(protocol_id_names
, PROTO_NONE
, PROTO_ESP
,
39 ENUM_BEGIN(transform_type_names
, UNDEFINED_TRANSFORM_TYPE
, UNDEFINED_TRANSFORM_TYPE
,
40 "UNDEFINED_TRANSFORM_TYPE");
41 ENUM_NEXT(transform_type_names
, ENCRYPTION_ALGORITHM
, EXTENDED_SEQUENCE_NUMBERS
, UNDEFINED_TRANSFORM_TYPE
,
42 "ENCRYPTION_ALGORITHM",
43 "PSEUDO_RANDOM_FUNCTION",
44 "INTEGRITY_ALGORITHM",
45 "DIFFIE_HELLMAN_GROUP",
46 "EXTENDED_SEQUENCE_NUMBERS");
47 ENUM_END(transform_type_names
, EXTENDED_SEQUENCE_NUMBERS
);
49 ENUM(extended_sequence_numbers_names
, NO_EXT_SEQ_NUMBERS
, EXT_SEQ_NUMBERS
,
54 typedef struct private_proposal_t private_proposal_t
;
55 typedef struct algorithm_t algorithm_t
;
58 * Private data of an proposal_t object
60 struct private_proposal_t
{
68 * protocol (ESP or AH)
70 protocol_id_t protocol
;
73 * priority ordered list of encryption algorithms
75 linked_list_t
*encryption_algos
;
78 * priority ordered list of integrity algorithms
80 linked_list_t
*integrity_algos
;
83 * priority ordered list of pseudo random functions
85 linked_list_t
*prf_algos
;
88 * priority ordered list of dh groups
90 linked_list_t
*dh_groups
;
93 * priority ordered list of extended sequence number flags
104 * Struct used to store different kinds of algorithms.
108 * Value from an encryption_algorithm_t/integrity_algorithm_t/...
113 * the associated key size in bits, or zero if not needed
119 * Add algorithm/keysize to a algorithm list
121 static void add_algo(linked_list_t
*list
, u_int16_t algo
, u_int16_t key_size
)
123 algorithm_t
*algo_key
;
125 algo_key
= malloc_thing(algorithm_t
);
126 algo_key
->algorithm
= algo
;
127 algo_key
->key_size
= key_size
;
128 list
->insert_last(list
, (void*)algo_key
);
132 * Implements proposal_t.add_algorithm
134 static void add_algorithm(private_proposal_t
*this, transform_type_t type
,
135 u_int16_t algo
, u_int16_t key_size
)
139 case ENCRYPTION_ALGORITHM
:
140 add_algo(this->encryption_algos
, algo
, key_size
);
142 case INTEGRITY_ALGORITHM
:
143 add_algo(this->integrity_algos
, algo
, key_size
);
145 case PSEUDO_RANDOM_FUNCTION
:
146 add_algo(this->prf_algos
, algo
, key_size
);
148 case DIFFIE_HELLMAN_GROUP
:
149 add_algo(this->dh_groups
, algo
, 0);
151 case EXTENDED_SEQUENCE_NUMBERS
:
152 add_algo(this->esns
, algo
, 0);
160 * filter function for peer configs
162 static bool alg_filter(void *null
, algorithm_t
**in
, u_int16_t
*alg
,
163 void **unused
, u_int16_t
*key_size
)
165 algorithm_t
*algo
= *in
;
166 *alg
= algo
->algorithm
;
169 *key_size
= algo
->key_size
;
175 * Implements proposal_t.create_enumerator.
177 static enumerator_t
*create_enumerator(private_proposal_t
*this,
178 transform_type_t type
)
184 case ENCRYPTION_ALGORITHM
:
185 list
= this->encryption_algos
;
187 case INTEGRITY_ALGORITHM
:
188 list
= this->integrity_algos
;
190 case PSEUDO_RANDOM_FUNCTION
:
191 list
= this->prf_algos
;
193 case DIFFIE_HELLMAN_GROUP
:
194 list
= this->dh_groups
;
196 case EXTENDED_SEQUENCE_NUMBERS
:
202 return enumerator_create_filter(list
->create_enumerator(list
),
203 (void*)alg_filter
, NULL
, NULL
);
207 * Implements proposal_t.get_algorithm.
209 static bool get_algorithm(private_proposal_t
*this, transform_type_t type
,
210 u_int16_t
*alg
, u_int16_t
*key_size
)
212 enumerator_t
*enumerator
;
215 enumerator
= create_enumerator(this, type
);
216 if (enumerator
->enumerate(enumerator
, alg
, key_size
))
220 enumerator
->destroy(enumerator
);
225 * Implements proposal_t.has_dh_group
227 static bool has_dh_group(private_proposal_t
*this, diffie_hellman_group_t group
)
231 if (this->dh_groups
->get_count(this->dh_groups
))
233 algorithm_t
*current
;
234 enumerator_t
*enumerator
;
236 enumerator
= this->dh_groups
->create_enumerator(this->dh_groups
);
237 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
239 if (current
->algorithm
== group
)
245 enumerator
->destroy(enumerator
);
247 else if (group
== MODP_NONE
)
255 * Implementation of proposal_t.strip_dh.
257 static void strip_dh(private_proposal_t
*this)
261 while (this->dh_groups
->remove_last(this->dh_groups
, (void**)&alg
) == SUCCESS
)
268 * Returns true if the given alg is an authenticated encryption algorithm
270 static bool is_authenticated_encryption(u_int16_t alg
)
274 case ENCR_AES_CCM_ICV8
:
275 case ENCR_AES_CCM_ICV12
:
276 case ENCR_AES_CCM_ICV16
:
277 case ENCR_AES_GCM_ICV8
:
278 case ENCR_AES_GCM_ICV12
:
279 case ENCR_AES_GCM_ICV16
:
286 * Find a matching alg/keysize in two linked lists
288 static bool select_algo(linked_list_t
*first
, linked_list_t
*second
, bool *add
,
289 u_int16_t
*alg
, size_t *key_size
)
291 enumerator_t
*e1
, *e2
;
292 algorithm_t
*alg1
, *alg2
;
294 /* if in both are zero algorithms specified, we HAVE a match */
295 if (first
->get_count(first
) == 0 && second
->get_count(second
) == 0)
301 e1
= first
->create_enumerator(first
);
302 e2
= second
->create_enumerator(second
);
303 /* compare algs, order of algs in "first" is preferred */
304 while (e1
->enumerate(e1
, &alg1
))
307 e2
= second
->create_enumerator(second
);
308 while (e2
->enumerate(e2
, &alg2
))
310 if (alg1
->algorithm
== alg2
->algorithm
&&
311 alg1
->key_size
== alg2
->key_size
)
313 /* ok, we have an algorithm */
314 *alg
= alg1
->algorithm
;
315 *key_size
= alg1
->key_size
;
323 /* no match in all comparisons */
330 * Implements proposal_t.select.
332 static proposal_t
*select_proposal(private_proposal_t
*this, private_proposal_t
*other
)
334 proposal_t
*selected
;
339 DBG2(DBG_CFG
, "selecting proposal:");
342 if (this->protocol
!= other
->protocol
)
344 DBG2(DBG_CFG
, " protocol mismatch, skipping");
348 selected
= proposal_create(this->protocol
);
350 /* select encryption algorithm */
351 if (select_algo(this->encryption_algos
, other
->encryption_algos
, &add
, &algo
, &key_size
))
355 selected
->add_algorithm(selected
, ENCRYPTION_ALGORITHM
, algo
, key_size
);
363 selected
->destroy(selected
);
364 DBG2(DBG_CFG
, " no acceptable ENCRYPTION_ALGORITHM found");
365 DBG2(DBG_CFG
, " list of received ENCRYPTION_ALGORITHM proposals:");
366 e
= other
->encryption_algos
->create_enumerator(other
->encryption_algos
);
367 while (e
->enumerate(e
, &alg
))
369 DBG2(DBG_CFG
, " %N-%d", encryption_algorithm_names
,
370 alg
->algorithm
, alg
->key_size
);
375 /* select integrity algorithm */
376 if (!is_authenticated_encryption(algo
))
378 if (select_algo(this->integrity_algos
, other
->integrity_algos
, &add
, &algo
, &key_size
))
382 selected
->add_algorithm(selected
, INTEGRITY_ALGORITHM
, algo
, key_size
);
390 selected
->destroy(selected
);
391 DBG2(DBG_CFG
, " no acceptable INTEGRITY_ALGORITHM found");
392 DBG2(DBG_CFG
, " list of received INTEGRITY_ALGORITHM proposals:");
393 e
= other
->integrity_algos
->create_enumerator(other
->integrity_algos
);
394 while (e
->enumerate(e
, &alg
))
396 DBG2(DBG_CFG
, " %N", integrity_algorithm_names
, alg
->algorithm
);
402 /* select prf algorithm */
403 if (select_algo(this->prf_algos
, other
->prf_algos
, &add
, &algo
, &key_size
))
407 selected
->add_algorithm(selected
, PSEUDO_RANDOM_FUNCTION
, algo
, key_size
);
412 selected
->destroy(selected
);
413 DBG2(DBG_CFG
, " no acceptable PSEUDO_RANDOM_FUNCTION found, skipping");
416 /* select a DH-group */
417 if (select_algo(this->dh_groups
, other
->dh_groups
, &add
, &algo
, &key_size
))
421 selected
->add_algorithm(selected
, DIFFIE_HELLMAN_GROUP
, algo
, 0);
426 selected
->destroy(selected
);
427 DBG2(DBG_CFG
, " no acceptable DIFFIE_HELLMAN_GROUP found, skipping");
430 /* select if we use ESNs */
431 if (select_algo(this->esns
, other
->esns
, &add
, &algo
, &key_size
))
435 selected
->add_algorithm(selected
, EXTENDED_SEQUENCE_NUMBERS
, algo
, 0);
440 selected
->destroy(selected
);
441 DBG2(DBG_CFG
, " no acceptable EXTENDED_SEQUENCE_NUMBERS found, skipping");
444 DBG2(DBG_CFG
, " proposal matches");
446 /* apply SPI from "other" */
447 selected
->set_spi(selected
, other
->spi
);
449 /* everything matched, return new proposal */
454 * Implements proposal_t.get_protocols.
456 static protocol_id_t
get_protocol(private_proposal_t
*this)
458 return this->protocol
;
462 * Implements proposal_t.set_spi.
464 static void set_spi(private_proposal_t
*this, u_int64_t spi
)
470 * Implements proposal_t.get_spi.
472 static u_int64_t
get_spi(private_proposal_t
*this)
478 * Clone a algorithm list
480 static void clone_algo_list(linked_list_t
*list
, linked_list_t
*clone_list
)
482 algorithm_t
*algo
, *clone_algo
;
483 enumerator_t
*enumerator
;
485 enumerator
= list
->create_enumerator(list
);
486 while (enumerator
->enumerate(enumerator
, &algo
))
488 clone_algo
= malloc_thing(algorithm_t
);
489 memcpy(clone_algo
, algo
, sizeof(algorithm_t
));
490 clone_list
->insert_last(clone_list
, (void*)clone_algo
);
492 enumerator
->destroy(enumerator
);
496 * check if an algorithm list equals
498 static bool algo_list_equals(linked_list_t
*l1
, linked_list_t
*l2
)
500 enumerator_t
*e1
, *e2
;
501 algorithm_t
*alg1
, *alg2
;
504 if (l1
->get_count(l1
) != l2
->get_count(l2
))
509 e1
= l1
->create_enumerator(l1
);
510 e2
= l2
->create_enumerator(l2
);
511 while (e1
->enumerate(e1
, &alg1
) && e2
->enumerate(e2
, &alg2
))
513 if (alg1
->algorithm
!= alg2
->algorithm
||
514 alg1
->key_size
!= alg2
->key_size
)
526 * Implementation of proposal_t.equals.
528 static bool equals(private_proposal_t
*this, private_proposal_t
*other
)
534 if (this->public.equals
!= other
->public.equals
)
539 algo_list_equals(this->encryption_algos
, other
->encryption_algos
) &&
540 algo_list_equals(this->integrity_algos
, other
->integrity_algos
) &&
541 algo_list_equals(this->prf_algos
, other
->prf_algos
) &&
542 algo_list_equals(this->dh_groups
, other
->dh_groups
) &&
543 algo_list_equals(this->esns
, other
->esns
));
547 * Implements proposal_t.clone
549 static proposal_t
*clone_(private_proposal_t
*this)
551 private_proposal_t
*clone
= (private_proposal_t
*)proposal_create(this->protocol
);
553 clone_algo_list(this->encryption_algos
, clone
->encryption_algos
);
554 clone_algo_list(this->integrity_algos
, clone
->integrity_algos
);
555 clone_algo_list(this->prf_algos
, clone
->prf_algos
);
556 clone_algo_list(this->dh_groups
, clone
->dh_groups
);
557 clone_algo_list(this->esns
, clone
->esns
);
559 clone
->spi
= this->spi
;
561 return &clone
->public;
565 * Checks the proposal read from a string.
567 static void check_proposal(private_proposal_t
*this)
571 bool all_aead
= TRUE
;
573 e
= this->encryption_algos
->create_enumerator(this->encryption_algos
);
574 while (e
->enumerate(e
, &alg
))
576 if (!is_authenticated_encryption(alg
->algorithm
))
586 /* if all encryption algorithms in the proposal are authenticated encryption
587 * algorithms we MUST NOT propose any integrity algorithms */
588 while (this->integrity_algos
->remove_last(this->integrity_algos
, (void**)&alg
) == SUCCESS
)
596 * add a algorithm identified by a string to the proposal.
597 * TODO: we could use gperf here.
599 static status_t
add_string_algo(private_proposal_t
*this, chunk_t alg
)
601 if (strncmp(alg
.ptr
, "null", alg
.len
) == 0)
603 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_NULL
, 0);
605 else if (strncmp(alg
.ptr
, "aes128", alg
.len
) == 0)
607 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
609 else if (strncmp(alg
.ptr
, "aes192", alg
.len
) == 0)
611 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
613 else if (strncmp(alg
.ptr
, "aes256", alg
.len
) == 0)
615 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
617 else if (strstr(alg
.ptr
, "ccm"))
619 u_int16_t key_size
, icv_size
;
621 if (sscanf(alg
.ptr
, "aes%huccm%hu", &key_size
, &icv_size
) == 2)
623 if (key_size
== 128 || key_size
== 192 || key_size
== 256)
629 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV8
, key_size
);
631 case 12: /* octets */
633 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV12
, key_size
);
635 case 16: /* octets */
637 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV16
, key_size
);
640 /* invalid ICV size */
646 else if (strstr(alg
.ptr
, "gcm"))
648 u_int16_t key_size
, icv_size
;
650 if (sscanf(alg
.ptr
, "aes%hugcm%hu", &key_size
, &icv_size
) == 2)
652 if (key_size
== 128 || key_size
== 192 || key_size
== 256)
658 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV8
, key_size
);
660 case 12: /* octets */
662 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV12
, key_size
);
664 case 16: /* octets */
666 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV16
, key_size
);
669 /* invalid ICV size */
675 else if (strncmp(alg
.ptr
, "3des", alg
.len
) == 0)
677 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
679 /* blowfish only uses some predefined key sizes yet */
680 else if (strncmp(alg
.ptr
, "blowfish128", alg
.len
) == 0)
682 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 128);
684 else if (strncmp(alg
.ptr
, "blowfish192", alg
.len
) == 0)
686 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 192);
688 else if (strncmp(alg
.ptr
, "blowfish256", alg
.len
) == 0)
690 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 256);
692 else if (strncmp(alg
.ptr
, "sha", alg
.len
) == 0 ||
693 strncmp(alg
.ptr
, "sha1", alg
.len
) == 0)
695 /* sha means we use SHA for both, PRF and AUTH */
696 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
697 if (this->protocol
== PROTO_IKE
)
699 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA1
, 0);
702 else if (strncmp(alg
.ptr
, "sha256", alg
.len
) == 0 ||
703 strncmp(alg
.ptr
, "sha2_256", alg
.len
) == 0)
705 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
706 if (this->protocol
== PROTO_IKE
)
708 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_256
, 0);
711 else if (strncmp(alg
.ptr
, "sha384", alg
.len
) == 0 ||
712 strncmp(alg
.ptr
, "sha2_384", alg
.len
) == 0)
714 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
715 if (this->protocol
== PROTO_IKE
)
717 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_384
, 0);
720 else if (strncmp(alg
.ptr
, "sha512", alg
.len
) == 0 ||
721 strncmp(alg
.ptr
, "sha2_512", alg
.len
) == 0)
723 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
724 if (this->protocol
== PROTO_IKE
)
726 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_512
, 0);
729 else if (strncmp(alg
.ptr
, "md5", alg
.len
) == 0)
731 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
732 if (this->protocol
== PROTO_IKE
)
734 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_MD5
, 0);
737 else if (strncmp(alg
.ptr
, "aesxcbc", alg
.len
) == 0)
739 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
740 if (this->protocol
== PROTO_IKE
)
742 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_AES128_XCBC
, 0);
745 else if (strncmp(alg
.ptr
, "modp768", alg
.len
) == 0)
747 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_768_BIT
, 0);
749 else if (strncmp(alg
.ptr
, "modp1024", alg
.len
) == 0)
751 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1024_BIT
, 0);
753 else if (strncmp(alg
.ptr
, "modp1536", alg
.len
) == 0)
755 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1536_BIT
, 0);
757 else if (strncmp(alg
.ptr
, "modp2048", alg
.len
) == 0)
759 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_2048_BIT
, 0);
761 else if (strncmp(alg
.ptr
, "modp4096", alg
.len
) == 0)
763 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_4096_BIT
, 0);
765 else if (strncmp(alg
.ptr
, "modp8192", alg
.len
) == 0)
767 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_8192_BIT
, 0);
769 else if (strncmp(alg
.ptr
, "ecp256", alg
.len
) == 0)
771 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_256_BIT
, 0);
773 else if (strncmp(alg
.ptr
, "ecp384", alg
.len
) == 0)
775 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_384_BIT
, 0);
777 else if (strncmp(alg
.ptr
, "ecp521", alg
.len
) == 0)
779 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_521_BIT
, 0);
789 * Implements proposal_t.destroy.
791 static void destroy(private_proposal_t
*this)
793 this->encryption_algos
->destroy_function(this->encryption_algos
, free
);
794 this->integrity_algos
->destroy_function(this->integrity_algos
, free
);
795 this->prf_algos
->destroy_function(this->prf_algos
, free
);
796 this->dh_groups
->destroy_function(this->dh_groups
, free
);
797 this->esns
->destroy_function(this->esns
, free
);
802 * Describtion in header-file
804 proposal_t
*proposal_create(protocol_id_t protocol
)
806 private_proposal_t
*this = malloc_thing(private_proposal_t
);
808 this->public.add_algorithm
= (void (*)(proposal_t
*,transform_type_t
,u_int16_t
,u_int16_t
))add_algorithm
;
809 this->public.create_enumerator
= (enumerator_t
* (*)(proposal_t
*,transform_type_t
))create_enumerator
;
810 this->public.get_algorithm
= (bool (*)(proposal_t
*,transform_type_t
,u_int16_t
*,u_int16_t
*))get_algorithm
;
811 this->public.has_dh_group
= (bool (*)(proposal_t
*,diffie_hellman_group_t
))has_dh_group
;
812 this->public.strip_dh
= (void(*)(proposal_t
*))strip_dh
;
813 this->public.select
= (proposal_t
* (*)(proposal_t
*,proposal_t
*))select_proposal
;
814 this->public.get_protocol
= (protocol_id_t(*)(proposal_t
*))get_protocol
;
815 this->public.set_spi
= (void(*)(proposal_t
*,u_int64_t
))set_spi
;
816 this->public.get_spi
= (u_int64_t(*)(proposal_t
*))get_spi
;
817 this->public.equals
= (bool(*)(proposal_t
*, proposal_t
*other
))equals
;
818 this->public.clone
= (proposal_t
*(*)(proposal_t
*))clone_
;
819 this->public.destroy
= (void(*)(proposal_t
*))destroy
;
822 this->protocol
= protocol
;
824 this->encryption_algos
= linked_list_create();
825 this->integrity_algos
= linked_list_create();
826 this->prf_algos
= linked_list_create();
827 this->dh_groups
= linked_list_create();
828 this->esns
= linked_list_create();
830 return &this->public;
834 * Describtion in header-file
836 proposal_t
*proposal_create_default(protocol_id_t protocol
)
838 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
);
843 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
844 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
845 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
846 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
847 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
848 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
849 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
850 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
851 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
852 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
853 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_AES128_XCBC
, 0);
854 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_256
, 0);
855 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA1
, 0);
856 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_MD5
, 0);
857 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_384
, 0);
858 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_512
, 0);
859 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_2048_BIT
, 0);
860 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1536_BIT
, 0);
861 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1024_BIT
, 0);
862 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_4096_BIT
, 0);
863 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_8192_BIT
, 0);
866 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
867 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
868 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
869 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
870 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 256);
871 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
872 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
873 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
874 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
877 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
878 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
879 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
880 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
886 return &this->public;
890 * Describtion in header-file
892 proposal_t
*proposal_create_from_string(protocol_id_t protocol
, const char *algs
)
894 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
);
895 chunk_t string
= {(void*)algs
, strlen(algs
)};
897 status_t status
= SUCCESS
;
899 eat_whitespace(&string
);
906 /* get all tokens, separated by '-' */
907 while (extract_token(&alg
, '-', &string
))
909 status
|= add_string_algo(this, alg
);
913 status
|= add_string_algo(this, string
);
915 if (status
!= SUCCESS
)
921 check_proposal(this);
923 if (protocol
== PROTO_AH
|| protocol
== PROTO_ESP
)
925 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
927 return &this->public;