2 * Copyright (C) 2008-2018 Tobias Brunner
3 * Copyright (C) 2006-2010 Martin Willi
4 * Copyright (C) 2013-2015 Andreas Steffen
5 * HSR Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <collections/array.h>
23 #include <utils/identification.h>
25 #include <crypto/transform.h>
26 #include <crypto/prfs/prf.h>
27 #include <crypto/crypters/crypter.h>
28 #include <crypto/signers/signer.h>
30 ENUM(protocol_id_names
, PROTO_NONE
, PROTO_IPCOMP
,
38 typedef struct private_proposal_t private_proposal_t
;
41 * Private data of an proposal_t object
43 struct private_proposal_t
{
51 * protocol (ESP or AH)
53 protocol_id_t protocol
;
56 * Priority ordered list of transforms, as entry_t
72 * Struct used to store different kinds of algorithms.
75 /** Type of the transform */
76 transform_type_t type
;
77 /** algorithm identifier */
79 /** key size in bits, or zero if not needed */
83 METHOD(proposal_t
, add_algorithm
, void,
84 private_proposal_t
*this, transform_type_t type
,
85 uint16_t alg
, uint16_t key_size
)
93 array_insert(this->transforms
, ARRAY_TAIL
, &entry
);
96 CALLBACK(alg_filter
, bool,
97 uintptr_t type
, enumerator_t
*orig
, va_list args
)
100 uint16_t *alg
, *key_size
;
102 VA_ARGS_VGET(args
, alg
, key_size
);
104 while (orig
->enumerate(orig
, &entry
))
106 if (entry
->type
!= type
)
116 *key_size
= entry
->key_size
;
123 METHOD(proposal_t
, create_enumerator
, enumerator_t
*,
124 private_proposal_t
*this, transform_type_t type
)
126 return enumerator_create_filter(
127 array_create_enumerator(this->transforms
),
128 alg_filter
, (void*)(uintptr_t)type
, NULL
);
131 METHOD(proposal_t
, get_algorithm
, bool,
132 private_proposal_t
*this, transform_type_t type
,
133 uint16_t *alg
, uint16_t *key_size
)
135 enumerator_t
*enumerator
;
138 enumerator
= create_enumerator(this, type
);
139 if (enumerator
->enumerate(enumerator
, alg
, key_size
))
143 enumerator
->destroy(enumerator
);
148 METHOD(proposal_t
, has_dh_group
, bool,
149 private_proposal_t
*this, diffie_hellman_group_t group
)
151 bool found
= FALSE
, any
= FALSE
;
152 enumerator_t
*enumerator
;
155 enumerator
= create_enumerator(this, DIFFIE_HELLMAN_GROUP
);
156 while (enumerator
->enumerate(enumerator
, ¤t
, NULL
))
159 if (current
== group
)
165 enumerator
->destroy(enumerator
);
167 if (!any
&& group
== MODP_NONE
)
174 METHOD(proposal_t
, promote_dh_group
, bool,
175 private_proposal_t
*this, diffie_hellman_group_t group
)
177 enumerator_t
*enumerator
;
181 enumerator
= array_create_enumerator(this->transforms
);
182 while (enumerator
->enumerate(enumerator
, &entry
))
184 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&&
187 array_remove_at(this->transforms
, enumerator
);
191 enumerator
->destroy(enumerator
);
196 .type
= DIFFIE_HELLMAN_GROUP
,
199 array_insert(this->transforms
, ARRAY_HEAD
, &entry
);
204 METHOD(proposal_t
, strip_dh
, void,
205 private_proposal_t
*this, diffie_hellman_group_t keep
)
207 enumerator_t
*enumerator
;
210 enumerator
= array_create_enumerator(this->transforms
);
211 while (enumerator
->enumerate(enumerator
, &entry
))
213 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&&
216 array_remove_at(this->transforms
, enumerator
);
219 enumerator
->destroy(enumerator
);
223 * Select a matching proposal from this and other, insert into selected.
225 static bool select_algo(private_proposal_t
*this, proposal_t
*other
,
226 proposal_t
*selected
, transform_type_t type
, bool priv
)
228 enumerator_t
*e1
, *e2
;
229 uint16_t alg1
, alg2
, ks1
, ks2
;
230 bool found
= FALSE
, optional
= FALSE
;
232 if (type
== INTEGRITY_ALGORITHM
&&
233 selected
->get_algorithm(selected
, ENCRYPTION_ALGORITHM
, &alg1
, NULL
) &&
234 encryption_algorithm_is_aead(alg1
))
236 /* no integrity algorithm required, we have an AEAD */
239 if (type
== DIFFIE_HELLMAN_GROUP
)
241 optional
= this->protocol
== PROTO_ESP
|| this->protocol
== PROTO_AH
;
244 e1
= create_enumerator(this, type
);
245 e2
= other
->create_enumerator(other
, type
);
246 if (!e1
->enumerate(e1
, &alg1
, NULL
))
248 if (!e2
->enumerate(e2
, &alg2
, NULL
))
255 { /* if NONE is proposed, we accept the proposal */
258 while (!found
&& e2
->enumerate(e2
, &alg2
, NULL
));
261 else if (!e2
->enumerate(e2
, NULL
, NULL
))
266 { /* if NONE is proposed, we accept the proposal */
269 while (!found
&& e1
->enumerate(e1
, &alg1
, NULL
));
274 e1
= create_enumerator(this, type
);
275 /* compare algs, order of algs in "first" is preferred */
276 while (!found
&& e1
->enumerate(e1
, &alg1
, &ks1
))
279 e2
= other
->create_enumerator(other
, type
);
280 while (e2
->enumerate(e2
, &alg2
, &ks2
))
282 if (alg1
== alg2
&& ks1
== ks2
)
284 if (!priv
&& alg1
>= 1024)
286 /* accept private use algorithms only if requested */
287 DBG1(DBG_CFG
, "an algorithm from private space would match, "
288 "but peer implementation is unknown, skipped");
291 selected
->add_algorithm(selected
, type
, alg1
, ks1
);
297 /* no match in all comparisons */
303 DBG2(DBG_CFG
, " no acceptable %N found", transform_type_names
, type
);
308 METHOD(proposal_t
, select_proposal
, proposal_t
*,
309 private_proposal_t
*this, proposal_t
*other
, bool other_remote
,
312 proposal_t
*selected
;
314 DBG2(DBG_CFG
, "selecting proposal:");
316 if (this->protocol
!= other
->get_protocol(other
))
318 DBG2(DBG_CFG
, " protocol mismatch, skipping");
324 selected
= proposal_create(this->protocol
, other
->get_number(other
));
325 selected
->set_spi(selected
, other
->get_spi(other
));
329 selected
= proposal_create(this->protocol
, this->number
);
330 selected
->set_spi(selected
, this->spi
);
334 if (!select_algo(this, other
, selected
, ENCRYPTION_ALGORITHM
, private) ||
335 !select_algo(this, other
, selected
, PSEUDO_RANDOM_FUNCTION
, private) ||
336 !select_algo(this, other
, selected
, INTEGRITY_ALGORITHM
, private) ||
337 !select_algo(this, other
, selected
, DIFFIE_HELLMAN_GROUP
, private) ||
338 !select_algo(this, other
, selected
, EXTENDED_SEQUENCE_NUMBERS
, private))
340 selected
->destroy(selected
);
344 DBG2(DBG_CFG
, " proposal matches");
348 METHOD(proposal_t
, get_protocol
, protocol_id_t
,
349 private_proposal_t
*this)
351 return this->protocol
;
354 METHOD(proposal_t
, set_spi
, void,
355 private_proposal_t
*this, uint64_t spi
)
360 METHOD(proposal_t
, get_spi
, uint64_t,
361 private_proposal_t
*this)
367 * Check if two proposals have the same algorithms for a given transform type
369 static bool algo_list_equals(private_proposal_t
*this, proposal_t
*other
,
370 transform_type_t type
)
372 enumerator_t
*e1
, *e2
;
373 uint16_t alg1
, alg2
, ks1
, ks2
;
376 e1
= create_enumerator(this, type
);
377 e2
= other
->create_enumerator(other
, type
);
378 while (e1
->enumerate(e1
, &alg1
, &ks1
))
380 if (!e2
->enumerate(e2
, &alg2
, &ks2
))
382 /* this has more algs */
386 if (alg1
!= alg2
|| ks1
!= ks2
)
392 if (e2
->enumerate(e2
, &alg2
, &ks2
))
394 /* other has more algs */
403 METHOD(proposal_t
, get_number
, u_int
,
404 private_proposal_t
*this)
409 METHOD(proposal_t
, equals
, bool,
410 private_proposal_t
*this, proposal_t
*other
)
412 if (&this->public == other
)
417 algo_list_equals(this, other
, ENCRYPTION_ALGORITHM
) &&
418 algo_list_equals(this, other
, INTEGRITY_ALGORITHM
) &&
419 algo_list_equals(this, other
, PSEUDO_RANDOM_FUNCTION
) &&
420 algo_list_equals(this, other
, DIFFIE_HELLMAN_GROUP
) &&
421 algo_list_equals(this, other
, EXTENDED_SEQUENCE_NUMBERS
));
424 METHOD(proposal_t
, clone_
, proposal_t
*,
425 private_proposal_t
*this)
427 private_proposal_t
*clone
;
428 enumerator_t
*enumerator
;
431 clone
= (private_proposal_t
*)proposal_create(this->protocol
, 0);
433 enumerator
= array_create_enumerator(this->transforms
);
434 while (enumerator
->enumerate(enumerator
, &entry
))
436 array_insert(clone
->transforms
, ARRAY_TAIL
, entry
);
438 enumerator
->destroy(enumerator
);
440 clone
->spi
= this->spi
;
441 clone
->number
= this->number
;
443 return &clone
->public;
447 * Map integrity algorithms to the PRF functions using the same algorithm.
449 static const struct {
450 integrity_algorithm_t integ
;
451 pseudo_random_function_t prf
;
452 } integ_prf_map
[] = {
453 {AUTH_HMAC_SHA1_96
, PRF_HMAC_SHA1
},
454 {AUTH_HMAC_SHA1_160
, PRF_HMAC_SHA1
},
455 {AUTH_HMAC_SHA2_256_128
, PRF_HMAC_SHA2_256
},
456 {AUTH_HMAC_SHA2_384_192
, PRF_HMAC_SHA2_384
},
457 {AUTH_HMAC_SHA2_512_256
, PRF_HMAC_SHA2_512
},
458 {AUTH_HMAC_MD5_96
, PRF_HMAC_MD5
},
459 {AUTH_HMAC_MD5_128
, PRF_HMAC_MD5
},
460 {AUTH_AES_XCBC_96
, PRF_AES128_XCBC
},
461 {AUTH_CAMELLIA_XCBC_96
, PRF_CAMELLIA128_XCBC
},
462 {AUTH_AES_CMAC_96
, PRF_AES128_CMAC
},
466 * Remove all entries of the given transform type
468 static void remove_transform(private_proposal_t
*this, transform_type_t type
)
473 e
= array_create_enumerator(this->transforms
);
474 while (e
->enumerate(e
, &entry
))
476 if (entry
->type
== type
)
478 array_remove_at(this->transforms
, e
);
485 * Checks the proposal read from a string.
487 static bool check_proposal(private_proposal_t
*this)
492 bool all_aead
= TRUE
, any_aead
= FALSE
, any_enc
= FALSE
;
495 if (this->protocol
== PROTO_IKE
)
497 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
498 { /* No explicit PRF found. We assume the same algorithm as used
499 * for integrity checking. */
500 e
= create_enumerator(this, INTEGRITY_ALGORITHM
);
501 while (e
->enumerate(e
, &alg
, &ks
))
503 for (i
= 0; i
< countof(integ_prf_map
); i
++)
505 if (alg
== integ_prf_map
[i
].integ
)
507 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
,
508 integ_prf_map
[i
].prf
, 0);
515 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
517 DBG1(DBG_CFG
, "a PRF algorithm is mandatory in IKE proposals");
520 /* remove MODP_NONE from IKE proposal */
521 e
= array_create_enumerator(this->transforms
);
522 while (e
->enumerate(e
, &entry
))
524 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&& !entry
->alg
)
526 array_remove_at(this->transforms
, e
);
530 if (!get_algorithm(this, DIFFIE_HELLMAN_GROUP
, NULL
, NULL
))
532 DBG1(DBG_CFG
, "a DH group is mandatory in IKE proposals");
537 { /* remove PRFs from ESP/AH proposals */
538 remove_transform(this, PSEUDO_RANDOM_FUNCTION
);
541 if (this->protocol
== PROTO_IKE
|| this->protocol
== PROTO_ESP
)
543 e
= create_enumerator(this, ENCRYPTION_ALGORITHM
);
544 while (e
->enumerate(e
, &alg
, &ks
))
547 if (encryption_algorithm_is_aead(alg
))
558 DBG1(DBG_CFG
, "an encryption algorithm is mandatory in %N proposals",
559 protocol_id_names
, this->protocol
);
562 else if (any_aead
&& !all_aead
)
564 DBG1(DBG_CFG
, "classic and combined-mode (AEAD) encryption "
565 "algorithms can't be contained in the same %N proposal",
566 protocol_id_names
, this->protocol
);
570 { /* if all encryption algorithms in the proposal are AEADs,
571 * we MUST NOT propose any integrity algorithms */
572 remove_transform(this, INTEGRITY_ALGORITHM
);
576 { /* AES-GMAC is parsed as encryption algorithm, so we map that to the
577 * proper integrity algorithm */
578 e
= array_create_enumerator(this->transforms
);
579 while (e
->enumerate(e
, &entry
))
581 if (entry
->type
== ENCRYPTION_ALGORITHM
)
583 if (entry
->alg
== ENCR_NULL_AUTH_AES_GMAC
)
585 entry
->type
= INTEGRITY_ALGORITHM
;
586 ks
= entry
->key_size
;
591 entry
->alg
= AUTH_AES_128_GMAC
;
594 entry
->alg
= AUTH_AES_192_GMAC
;
597 entry
->alg
= AUTH_AES_256_GMAC
;
603 /* remove all other encryption algorithms */
604 array_remove_at(this->transforms
, e
);
609 if (!get_algorithm(this, INTEGRITY_ALGORITHM
, NULL
, NULL
))
611 DBG1(DBG_CFG
, "an integrity algorithm is mandatory in AH "
617 if (this->protocol
== PROTO_AH
|| this->protocol
== PROTO_ESP
)
619 if (!get_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NULL
, NULL
))
620 { /* ESN not specified, assume not supported */
621 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
625 array_compress(this->transforms
);
630 * add a algorithm identified by a string to the proposal.
632 static bool add_string_algo(private_proposal_t
*this, const char *alg
)
634 const proposal_token_t
*token
;
636 token
= lib
->proposal
->get_token(lib
->proposal
, alg
);
639 DBG1(DBG_CFG
, "algorithm '%s' not recognized", alg
);
643 add_algorithm(this, token
->type
, token
->algorithm
, token
->keysize
);
649 * print all algorithms of a kind to buffer
651 static int print_alg(private_proposal_t
*this, printf_hook_data_t
*data
,
652 u_int kind
, void *names
, bool *first
)
654 enumerator_t
*enumerator
;
658 enumerator
= create_enumerator(this, kind
);
659 while (enumerator
->enumerate(enumerator
, &alg
, &size
))
663 written
+= print_in_hook(data
, "%N", names
, alg
);
668 written
+= print_in_hook(data
, "/%N", names
, alg
);
672 written
+= print_in_hook(data
, "_%u", size
);
675 enumerator
->destroy(enumerator
);
680 * Described in header.
682 int proposal_printf_hook(printf_hook_data_t
*data
, printf_hook_spec_t
*spec
,
683 const void *const *args
)
685 private_proposal_t
*this = *((private_proposal_t
**)(args
[0]));
686 linked_list_t
*list
= *((linked_list_t
**)(args
[0]));
687 enumerator_t
*enumerator
;
693 return print_in_hook(data
, "(null)");
698 enumerator
= list
->create_enumerator(list
);
699 while (enumerator
->enumerate(enumerator
, &this))
700 { /* call recursively */
703 written
+= print_in_hook(data
, "%P", this);
708 written
+= print_in_hook(data
, ", %P", this);
711 enumerator
->destroy(enumerator
);
715 written
= print_in_hook(data
, "%N:", protocol_id_names
, this->protocol
);
716 written
+= print_alg(this, data
, ENCRYPTION_ALGORITHM
,
717 encryption_algorithm_names
, &first
);
718 written
+= print_alg(this, data
, INTEGRITY_ALGORITHM
,
719 integrity_algorithm_names
, &first
);
720 written
+= print_alg(this, data
, PSEUDO_RANDOM_FUNCTION
,
721 pseudo_random_function_names
, &first
);
722 written
+= print_alg(this, data
, DIFFIE_HELLMAN_GROUP
,
723 diffie_hellman_group_names
, &first
);
724 written
+= print_alg(this, data
, EXTENDED_SEQUENCE_NUMBERS
,
725 extended_sequence_numbers_names
, &first
);
729 METHOD(proposal_t
, destroy
, void,
730 private_proposal_t
*this)
732 array_destroy(this->transforms
);
737 * Described in header
739 proposal_t
*proposal_create(protocol_id_t protocol
, u_int number
)
741 private_proposal_t
*this;
745 .add_algorithm
= _add_algorithm
,
746 .create_enumerator
= _create_enumerator
,
747 .get_algorithm
= _get_algorithm
,
748 .has_dh_group
= _has_dh_group
,
749 .promote_dh_group
= _promote_dh_group
,
750 .strip_dh
= _strip_dh
,
751 .select
= _select_proposal
,
752 .get_protocol
= _get_protocol
,
755 .get_number
= _get_number
,
760 .protocol
= protocol
,
762 .transforms
= array_create(sizeof(entry_t
), 0),
765 return &this->public;
769 * Add supported IKE algorithms to proposal
771 static bool proposal_add_supported_ike(private_proposal_t
*this, bool aead
)
773 enumerator_t
*enumerator
;
774 encryption_algorithm_t encryption
;
775 integrity_algorithm_t integrity
;
776 pseudo_random_function_t prf
;
777 diffie_hellman_group_t group
;
778 const char *plugin_name
;
782 /* Round 1 adds algorithms with at least 128 bit security strength */
783 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
784 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
788 case ENCR_AES_GCM_ICV16
:
789 case ENCR_AES_CCM_ICV16
:
790 case ENCR_CAMELLIA_CCM_ICV16
:
791 /* we assume that we support all AES/Camellia sizes */
792 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
793 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
794 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
796 case ENCR_CHACHA20_POLY1305
:
797 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
803 enumerator
->destroy(enumerator
);
805 /* Round 2 adds algorithms with less than 128 bit security strength */
806 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
807 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
811 case ENCR_AES_GCM_ICV12
:
812 case ENCR_AES_GCM_ICV8
:
813 case ENCR_AES_CCM_ICV12
:
814 case ENCR_AES_CCM_ICV8
:
815 case ENCR_CAMELLIA_CCM_ICV12
:
816 case ENCR_CAMELLIA_CCM_ICV8
:
817 /* we assume that we support all AES/Camellia sizes */
818 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
819 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
820 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
826 enumerator
->destroy(enumerator
);
828 if (!array_count(this->transforms
))
835 /* Round 1 adds algorithms with at least 128 bit security strength */
836 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
837 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
843 case ENCR_CAMELLIA_CBC
:
844 case ENCR_CAMELLIA_CTR
:
845 /* we assume that we support all AES/Camellia sizes */
846 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
847 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
848 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
854 enumerator
->destroy(enumerator
);
856 /* Round 2 adds algorithms with less than 128 bit security strength */
857 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
858 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
863 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 0);
872 enumerator
->destroy(enumerator
);
874 if (!array_count(this->transforms
))
879 /* Round 1 adds algorithms with at least 128 bit security strength */
880 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
881 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
885 case AUTH_HMAC_SHA2_256_128
:
886 case AUTH_HMAC_SHA2_384_192
:
887 case AUTH_HMAC_SHA2_512_256
:
888 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
894 enumerator
->destroy(enumerator
);
896 /* Round 2 adds algorithms with less than 128 bit security strength */
897 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
898 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
902 case AUTH_AES_XCBC_96
:
903 case AUTH_AES_CMAC_96
:
904 case AUTH_HMAC_SHA1_96
:
905 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
907 case AUTH_HMAC_MD5_96
:
913 enumerator
->destroy(enumerator
);
916 /* Round 1 adds algorithms with at least 128 bit security strength */
917 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
918 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
922 case PRF_HMAC_SHA2_256
:
923 case PRF_HMAC_SHA2_384
:
924 case PRF_HMAC_SHA2_512
:
925 case PRF_AES128_XCBC
:
926 case PRF_AES128_CMAC
:
927 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
933 enumerator
->destroy(enumerator
);
935 /* Round 2 adds algorithms with less than 128 bit security strength */
936 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
937 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
942 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
951 enumerator
->destroy(enumerator
);
953 /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */
954 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
955 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
971 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
977 enumerator
->destroy(enumerator
);
979 /* Round 2 adds other algorithms with at least 128 bit security strength */
980 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
981 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
988 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
994 enumerator
->destroy(enumerator
);
996 /* Round 3 adds algorithms with less than 128 bit security strength */
997 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
998 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1003 /* only for testing purposes */
1013 /* RFC 5114 primes are of questionable source */
1022 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1028 enumerator
->destroy(enumerator
);
1034 * Described in header
1036 proposal_t
*proposal_create_default(protocol_id_t protocol
)
1038 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
, 0);
1043 if (!proposal_add_supported_ike(this, FALSE
))
1050 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
1051 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
1052 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
1053 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
1054 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
1055 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
1056 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
1057 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
1058 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
1061 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
1062 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
1063 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
1064 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
1065 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
1066 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
1071 return &this->public;
1075 * Described in header
1077 proposal_t
*proposal_create_default_aead(protocol_id_t protocol
)
1079 private_proposal_t
*this;
1084 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1085 if (!proposal_add_supported_ike(this, TRUE
))
1090 return &this->public;
1092 /* we currently don't include any AEAD proposal for ESP, as we
1093 * don't know if our kernel backend actually supports it. */
1102 * Described in header
1104 proposal_t
*proposal_create_from_string(protocol_id_t protocol
, const char *algs
)
1106 private_proposal_t
*this;
1107 enumerator_t
*enumerator
;
1111 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1113 /* get all tokens, separated by '-' */
1114 enumerator
= enumerator_create_token(algs
, "-", " ");
1115 while (enumerator
->enumerate(enumerator
, &alg
))
1117 if (!add_string_algo(this, alg
))
1124 enumerator
->destroy(enumerator
);
1126 if (failed
|| !check_proposal(this))
1132 return &this->public;