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
61 * Types of transforms contained, as transform_type_t
77 * This is a hack to not change the previous order when printing proposals
79 static transform_type_t
type_for_sort(const void *type
)
81 const transform_type_t
*t
= type
;
85 case PSEUDO_RANDOM_FUNCTION
:
86 return INTEGRITY_ALGORITHM
;
87 case INTEGRITY_ALGORITHM
:
88 return PSEUDO_RANDOM_FUNCTION
;
95 * Sort transform types
97 static int type_sort(const void *a
, const void *b
, void *user
)
99 transform_type_t ta
= type_for_sort(a
), tb
= type_for_sort(b
);
104 * Find a transform type
106 static int type_find(const void *a
, const void *b
)
108 return type_sort(a
, b
, NULL
);
112 * Check if the given transform type is already in the set
114 static bool contains_type(array_t
*types
, transform_type_t type
)
116 return array_bsearch(types
, &type
, type_find
, NULL
) != -1;
120 * Add the given transform type to the set
122 static void add_type(array_t
*types
, transform_type_t type
)
124 if (!contains_type(types
, type
))
126 array_insert(types
, ARRAY_TAIL
, &type
);
127 array_sort(types
, type_sort
, NULL
);
132 * Merge two sets of transform types into a new array
134 static array_t
*merge_types(private_proposal_t
*this, private_proposal_t
*other
)
137 transform_type_t type
;
140 count
= max(array_count(this->types
), array_count(other
->types
));
141 types
= array_create(sizeof(transform_type_t
), count
);
143 for (i
= 0; i
< count
; i
++)
145 if (array_get(this->types
, i
, &type
))
147 add_type(types
, type
);
149 if (array_get(other
->types
, i
, &type
))
151 add_type(types
, type
);
158 * Remove the given transform type from the set
160 static void remove_type(private_proposal_t
*this, transform_type_t type
)
164 i
= array_bsearch(this->types
, &type
, type_find
, NULL
);
167 array_remove(this->types
, i
, NULL
);
172 * Struct used to store different kinds of algorithms.
175 /** Type of the transform */
176 transform_type_t type
;
177 /** algorithm identifier */
179 /** key size in bits, or zero if not needed */
183 METHOD(proposal_t
, add_algorithm
, void,
184 private_proposal_t
*this, transform_type_t type
,
185 uint16_t alg
, uint16_t key_size
)
190 .key_size
= key_size
,
193 array_insert(this->transforms
, ARRAY_TAIL
, &entry
);
194 add_type(this->types
, type
);
197 CALLBACK(alg_filter
, bool,
198 uintptr_t type
, enumerator_t
*orig
, va_list args
)
201 uint16_t *alg
, *key_size
;
203 VA_ARGS_VGET(args
, alg
, key_size
);
205 while (orig
->enumerate(orig
, &entry
))
207 if (entry
->type
!= type
)
217 *key_size
= entry
->key_size
;
224 METHOD(proposal_t
, create_enumerator
, enumerator_t
*,
225 private_proposal_t
*this, transform_type_t type
)
227 return enumerator_create_filter(
228 array_create_enumerator(this->transforms
),
229 alg_filter
, (void*)(uintptr_t)type
, NULL
);
232 METHOD(proposal_t
, get_algorithm
, bool,
233 private_proposal_t
*this, transform_type_t type
,
234 uint16_t *alg
, uint16_t *key_size
)
236 enumerator_t
*enumerator
;
239 enumerator
= create_enumerator(this, type
);
240 if (enumerator
->enumerate(enumerator
, alg
, key_size
))
244 enumerator
->destroy(enumerator
);
249 METHOD(proposal_t
, has_dh_group
, bool,
250 private_proposal_t
*this, diffie_hellman_group_t group
)
252 bool found
= FALSE
, any
= FALSE
;
253 enumerator_t
*enumerator
;
256 enumerator
= create_enumerator(this, DIFFIE_HELLMAN_GROUP
);
257 while (enumerator
->enumerate(enumerator
, ¤t
, NULL
))
260 if (current
== group
)
266 enumerator
->destroy(enumerator
);
268 if (!any
&& group
== MODP_NONE
)
275 METHOD(proposal_t
, promote_dh_group
, bool,
276 private_proposal_t
*this, diffie_hellman_group_t group
)
278 enumerator_t
*enumerator
;
282 enumerator
= array_create_enumerator(this->transforms
);
283 while (enumerator
->enumerate(enumerator
, &entry
))
285 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&&
288 array_remove_at(this->transforms
, enumerator
);
292 enumerator
->destroy(enumerator
);
297 .type
= DIFFIE_HELLMAN_GROUP
,
300 array_insert(this->transforms
, ARRAY_HEAD
, &entry
);
305 METHOD(proposal_t
, strip_dh
, void,
306 private_proposal_t
*this, diffie_hellman_group_t keep
)
308 enumerator_t
*enumerator
;
312 enumerator
= array_create_enumerator(this->transforms
);
313 while (enumerator
->enumerate(enumerator
, &entry
))
315 if (entry
->type
== DIFFIE_HELLMAN_GROUP
)
317 if (entry
->alg
!= keep
)
319 array_remove_at(this->transforms
, enumerator
);
327 enumerator
->destroy(enumerator
);
328 array_compress(this->transforms
);
330 if (keep
== MODP_NONE
|| !found
)
332 remove_type(this, DIFFIE_HELLMAN_GROUP
);
333 array_compress(this->types
);
338 * Select a matching proposal from this and other.
340 static bool select_algo(private_proposal_t
*this, proposal_t
*other
,
341 transform_type_t type
, proposal_selection_flag_t flags
,
342 bool log
, uint16_t *alg
, uint16_t *ks
)
344 enumerator_t
*e1
, *e2
;
345 uint16_t alg1
, alg2
, ks1
, ks2
;
346 bool found
= FALSE
, optional
= FALSE
;
348 if (type
== DIFFIE_HELLMAN_GROUP
)
350 optional
= this->protocol
== PROTO_ESP
|| this->protocol
== PROTO_AH
;
353 e1
= create_enumerator(this, type
);
354 e2
= other
->create_enumerator(other
, type
);
355 if (!e1
->enumerate(e1
, &alg1
, NULL
))
357 if (!e2
->enumerate(e2
, &alg2
, NULL
))
364 { /* if NONE is proposed, we accept the proposal */
367 while (!found
&& e2
->enumerate(e2
, &alg2
, NULL
));
370 else if (!e2
->enumerate(e2
, NULL
, NULL
))
375 { /* if NONE is proposed, we accept the proposal */
378 while (!found
&& e1
->enumerate(e1
, &alg1
, NULL
));
383 e1
= create_enumerator(this, type
);
384 /* compare algs, order of algs in "first" is preferred */
385 while (!found
&& e1
->enumerate(e1
, &alg1
, &ks1
))
388 e2
= other
->create_enumerator(other
, type
);
389 while (e2
->enumerate(e2
, &alg2
, &ks2
))
391 if (alg1
== alg2
&& ks1
== ks2
)
393 if ((flags
& PROPOSAL_SKIP_PRIVATE
) && alg1
>= 1024)
397 DBG1(DBG_CFG
, "an algorithm from private space would "
398 "match, but peer implementation is unknown, "
416 * Select algorithms from the given proposals, if selected is given, the result
417 * is stored there and errors are logged.
419 static bool select_algos(private_proposal_t
*this, proposal_t
*other
,
420 proposal_t
*selected
, proposal_selection_flag_t flags
)
422 transform_type_t type
;
424 bool skip_integrity
= FALSE
;
427 types
= merge_types(this, (private_proposal_t
*)other
);
428 for (i
= 0; i
< array_count(types
); i
++)
430 uint16_t alg
= 0, ks
= 0;
432 array_get(types
, i
, &type
);
433 if (type
== INTEGRITY_ALGORITHM
&& skip_integrity
)
437 if (type
== DIFFIE_HELLMAN_GROUP
&& (flags
& PROPOSAL_SKIP_DH
))
441 if (select_algo(this, other
, type
, flags
, selected
!= NULL
, &alg
, &ks
))
443 if (alg
== 0 && type
!= EXTENDED_SEQUENCE_NUMBERS
)
444 { /* 0 is "valid" for extended sequence numbers, for other
445 * transforms it either means NONE or is reserved */
450 selected
->add_algorithm(selected
, type
, alg
, ks
);
452 if (type
== ENCRYPTION_ALGORITHM
&&
453 encryption_algorithm_is_aead(alg
))
455 /* no integrity algorithm required, we have an AEAD */
456 skip_integrity
= TRUE
;
463 DBG2(DBG_CFG
, " no acceptable %N found", transform_type_names
,
466 array_destroy(types
);
470 array_destroy(types
);
474 METHOD(proposal_t
, select_proposal
, proposal_t
*,
475 private_proposal_t
*this, proposal_t
*other
,
476 proposal_selection_flag_t flags
)
478 proposal_t
*selected
;
480 DBG2(DBG_CFG
, "selecting proposal:");
482 if (this->protocol
!= other
->get_protocol(other
))
484 DBG2(DBG_CFG
, " protocol mismatch, skipping");
488 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
490 selected
= proposal_create(this->protocol
, this->number
);
491 selected
->set_spi(selected
, this->spi
);
495 selected
= proposal_create(this->protocol
, other
->get_number(other
));
496 selected
->set_spi(selected
, other
->get_spi(other
));
499 if (!select_algos(this, other
, selected
, flags
))
501 selected
->destroy(selected
);
504 DBG2(DBG_CFG
, " proposal matches");
508 METHOD(proposal_t
, matches
, bool,
509 private_proposal_t
*this, proposal_t
*other
,
510 proposal_selection_flag_t flags
)
512 if (this->protocol
!= other
->get_protocol(other
))
516 return select_algos(this, other
, NULL
, flags
);
519 METHOD(proposal_t
, get_protocol
, protocol_id_t
,
520 private_proposal_t
*this)
522 return this->protocol
;
525 METHOD(proposal_t
, set_spi
, void,
526 private_proposal_t
*this, uint64_t spi
)
531 METHOD(proposal_t
, get_spi
, uint64_t,
532 private_proposal_t
*this)
538 * Check if two proposals have the same algorithms for a given transform type
540 static bool algo_list_equals(private_proposal_t
*this, proposal_t
*other
,
541 transform_type_t type
)
543 enumerator_t
*e1
, *e2
;
544 uint16_t alg1
, alg2
, ks1
, ks2
;
547 e1
= create_enumerator(this, type
);
548 e2
= other
->create_enumerator(other
, type
);
549 while (e1
->enumerate(e1
, &alg1
, &ks1
))
551 if (!e2
->enumerate(e2
, &alg2
, &ks2
))
553 /* this has more algs */
557 if (alg1
!= alg2
|| ks1
!= ks2
)
563 if (e2
->enumerate(e2
, &alg2
, &ks2
))
565 /* other has more algs */
574 METHOD(proposal_t
, get_number
, u_int
,
575 private_proposal_t
*this)
580 METHOD(proposal_t
, equals
, bool,
581 private_proposal_t
*this, proposal_t
*other
)
583 transform_type_t type
;
587 if (&this->public == other
)
592 types
= merge_types(this, (private_proposal_t
*)other
);
593 for (i
= 0; i
< array_count(types
); i
++)
595 array_get(types
, i
, &type
);
596 if (!algo_list_equals(this, other
, type
))
598 array_destroy(types
);
602 array_destroy(types
);
606 METHOD(proposal_t
, clone_
, proposal_t
*,
607 private_proposal_t
*this, proposal_selection_flag_t flags
)
609 private_proposal_t
*clone
;
610 enumerator_t
*enumerator
;
613 clone
= (private_proposal_t
*)proposal_create(this->protocol
, 0);
615 enumerator
= array_create_enumerator(this->transforms
);
616 while (enumerator
->enumerate(enumerator
, &entry
))
618 if (entry
->alg
>= 1024 && (flags
& PROPOSAL_SKIP_PRIVATE
))
622 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&& (flags
& PROPOSAL_SKIP_DH
))
626 array_insert(clone
->transforms
, ARRAY_TAIL
, entry
);
627 add_type(clone
->types
, entry
->type
);
629 enumerator
->destroy(enumerator
);
631 clone
->spi
= this->spi
;
632 clone
->number
= this->number
;
634 return &clone
->public;
638 * Map integrity algorithms to the PRF functions using the same algorithm.
640 static const struct {
641 integrity_algorithm_t integ
;
642 pseudo_random_function_t prf
;
643 } integ_prf_map
[] = {
644 {AUTH_HMAC_SHA1_96
, PRF_HMAC_SHA1
},
645 {AUTH_HMAC_SHA1_160
, PRF_HMAC_SHA1
},
646 {AUTH_HMAC_SHA2_256_128
, PRF_HMAC_SHA2_256
},
647 {AUTH_HMAC_SHA2_384_192
, PRF_HMAC_SHA2_384
},
648 {AUTH_HMAC_SHA2_512_256
, PRF_HMAC_SHA2_512
},
649 {AUTH_HMAC_MD5_96
, PRF_HMAC_MD5
},
650 {AUTH_HMAC_MD5_128
, PRF_HMAC_MD5
},
651 {AUTH_AES_XCBC_96
, PRF_AES128_XCBC
},
652 {AUTH_CAMELLIA_XCBC_96
, PRF_CAMELLIA128_XCBC
},
653 {AUTH_AES_CMAC_96
, PRF_AES128_CMAC
},
657 * Remove all entries of the given transform type
659 static void remove_transform(private_proposal_t
*this, transform_type_t type
)
664 e
= array_create_enumerator(this->transforms
);
665 while (e
->enumerate(e
, &entry
))
667 if (entry
->type
== type
)
669 array_remove_at(this->transforms
, e
);
673 remove_type(this, type
);
677 * Checks the proposal read from a string.
679 static bool check_proposal(private_proposal_t
*this)
684 bool all_aead
= TRUE
, any_aead
= FALSE
, any_enc
= FALSE
;
687 if (this->protocol
== PROTO_IKE
)
689 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
690 { /* No explicit PRF found. We assume the same algorithm as used
691 * for integrity checking. */
692 e
= create_enumerator(this, INTEGRITY_ALGORITHM
);
693 while (e
->enumerate(e
, &alg
, &ks
))
695 for (i
= 0; i
< countof(integ_prf_map
); i
++)
697 if (alg
== integ_prf_map
[i
].integ
)
699 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
,
700 integ_prf_map
[i
].prf
, 0);
707 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
709 DBG1(DBG_CFG
, "a PRF algorithm is mandatory in IKE proposals");
712 /* remove MODP_NONE from IKE proposal */
713 e
= array_create_enumerator(this->transforms
);
714 while (e
->enumerate(e
, &entry
))
716 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&& !entry
->alg
)
718 array_remove_at(this->transforms
, e
);
722 if (!get_algorithm(this, DIFFIE_HELLMAN_GROUP
, NULL
, NULL
))
724 DBG1(DBG_CFG
, "a DH group is mandatory in IKE proposals");
729 { /* remove PRFs from ESP/AH proposals */
730 remove_transform(this, PSEUDO_RANDOM_FUNCTION
);
733 if (this->protocol
== PROTO_IKE
|| this->protocol
== PROTO_ESP
)
735 e
= create_enumerator(this, ENCRYPTION_ALGORITHM
);
736 while (e
->enumerate(e
, &alg
, &ks
))
739 if (encryption_algorithm_is_aead(alg
))
750 DBG1(DBG_CFG
, "an encryption algorithm is mandatory in %N proposals",
751 protocol_id_names
, this->protocol
);
754 else if (any_aead
&& !all_aead
)
756 DBG1(DBG_CFG
, "classic and combined-mode (AEAD) encryption "
757 "algorithms can't be contained in the same %N proposal",
758 protocol_id_names
, this->protocol
);
762 { /* if all encryption algorithms in the proposal are AEADs,
763 * we MUST NOT propose any integrity algorithms */
764 remove_transform(this, INTEGRITY_ALGORITHM
);
766 else if (this->protocol
== PROTO_IKE
&&
767 !get_algorithm(this, INTEGRITY_ALGORITHM
, NULL
, NULL
))
769 DBG1(DBG_CFG
, "an integrity algorithm is mandatory in %N proposals "
770 "with classic (non-AEAD) encryption algorithms",
771 protocol_id_names
, this->protocol
);
776 { /* AES-GMAC is parsed as encryption algorithm, so we map that to the
777 * proper integrity algorithm */
778 e
= array_create_enumerator(this->transforms
);
779 while (e
->enumerate(e
, &entry
))
781 if (entry
->type
== ENCRYPTION_ALGORITHM
)
783 if (entry
->alg
== ENCR_NULL_AUTH_AES_GMAC
)
785 entry
->type
= INTEGRITY_ALGORITHM
;
786 ks
= entry
->key_size
;
791 entry
->alg
= AUTH_AES_128_GMAC
;
794 entry
->alg
= AUTH_AES_192_GMAC
;
797 entry
->alg
= AUTH_AES_256_GMAC
;
803 /* remove all other encryption algorithms */
804 array_remove_at(this->transforms
, e
);
808 remove_type(this, ENCRYPTION_ALGORITHM
);
810 if (!get_algorithm(this, INTEGRITY_ALGORITHM
, NULL
, NULL
))
812 DBG1(DBG_CFG
, "an integrity algorithm is mandatory in AH "
818 if (this->protocol
== PROTO_AH
|| this->protocol
== PROTO_ESP
)
820 if (!get_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NULL
, NULL
))
821 { /* ESN not specified, assume not supported */
822 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
826 array_compress(this->transforms
);
827 array_compress(this->types
);
832 * add a algorithm identified by a string to the proposal.
834 static bool add_string_algo(private_proposal_t
*this, const char *alg
)
836 const proposal_token_t
*token
;
838 token
= lib
->proposal
->get_token(lib
->proposal
, alg
);
841 DBG1(DBG_CFG
, "algorithm '%s' not recognized", alg
);
845 add_algorithm(this, token
->type
, token
->algorithm
, token
->keysize
);
851 * Print all algorithms of the given type
853 static int print_alg(private_proposal_t
*this, printf_hook_data_t
*data
,
854 transform_type_t type
, bool *first
)
856 enumerator_t
*enumerator
;
861 names
= transform_get_enum_names(type
);
863 enumerator
= array_create_enumerator(this->transforms
);
864 while (enumerator
->enumerate(enumerator
, &entry
))
868 if (type
!= entry
->type
)
879 written
+= print_in_hook(data
, "%s%N", prefix
, names
, entry
->alg
);
883 written
+= print_in_hook(data
, "%sUNKNOWN_%u_%u", prefix
,
884 entry
->type
, entry
->alg
);
888 written
+= print_in_hook(data
, "_%u", entry
->key_size
);
891 enumerator
->destroy(enumerator
);
896 * Described in header.
898 int proposal_printf_hook(printf_hook_data_t
*data
, printf_hook_spec_t
*spec
,
899 const void *const *args
)
901 private_proposal_t
*this = *((private_proposal_t
**)(args
[0]));
902 linked_list_t
*list
= *((linked_list_t
**)(args
[0]));
903 enumerator_t
*enumerator
;
904 transform_type_t
*type
;
910 return print_in_hook(data
, "(null)");
915 enumerator
= list
->create_enumerator(list
);
916 while (enumerator
->enumerate(enumerator
, &this))
917 { /* call recursively */
920 written
+= print_in_hook(data
, "%P", this);
925 written
+= print_in_hook(data
, ", %P", this);
928 enumerator
->destroy(enumerator
);
932 written
= print_in_hook(data
, "%N:", protocol_id_names
, this->protocol
);
933 enumerator
= array_create_enumerator(this->types
);
934 while (enumerator
->enumerate(enumerator
, &type
))
936 written
+= print_alg(this, data
, *type
, &first
);
938 enumerator
->destroy(enumerator
);
942 METHOD(proposal_t
, destroy
, void,
943 private_proposal_t
*this)
945 array_destroy(this->transforms
);
946 array_destroy(this->types
);
951 * Described in header
953 proposal_t
*proposal_create(protocol_id_t protocol
, u_int number
)
955 private_proposal_t
*this;
959 .add_algorithm
= _add_algorithm
,
960 .create_enumerator
= _create_enumerator
,
961 .get_algorithm
= _get_algorithm
,
962 .has_dh_group
= _has_dh_group
,
963 .promote_dh_group
= _promote_dh_group
,
964 .strip_dh
= _strip_dh
,
965 .select
= _select_proposal
,
967 .get_protocol
= _get_protocol
,
970 .get_number
= _get_number
,
975 .protocol
= protocol
,
977 .transforms
= array_create(sizeof(entry_t
), 0),
978 .types
= array_create(sizeof(transform_type_t
), 0),
981 return &this->public;
985 * Add supported IKE algorithms to proposal
987 static bool proposal_add_supported_ike(private_proposal_t
*this, bool aead
)
989 enumerator_t
*enumerator
;
990 encryption_algorithm_t encryption
;
991 integrity_algorithm_t integrity
;
992 pseudo_random_function_t prf
;
993 diffie_hellman_group_t group
;
994 const char *plugin_name
;
998 /* Round 1 adds algorithms with at least 128 bit security strength */
999 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
1000 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1004 case ENCR_AES_GCM_ICV16
:
1005 case ENCR_AES_CCM_ICV16
:
1006 case ENCR_CAMELLIA_CCM_ICV16
:
1007 /* we assume that we support all AES/Camellia sizes */
1008 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1009 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1010 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1012 case ENCR_CHACHA20_POLY1305
:
1013 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 0);
1019 enumerator
->destroy(enumerator
);
1021 /* Round 2 adds algorithms with less than 128 bit security strength */
1022 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
1023 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1027 case ENCR_AES_GCM_ICV12
:
1028 case ENCR_AES_GCM_ICV8
:
1029 case ENCR_AES_CCM_ICV12
:
1030 case ENCR_AES_CCM_ICV8
:
1031 case ENCR_CAMELLIA_CCM_ICV12
:
1032 case ENCR_CAMELLIA_CCM_ICV8
:
1033 /* we assume that we support all AES/Camellia sizes */
1034 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1035 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1036 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1042 enumerator
->destroy(enumerator
);
1044 if (!array_count(this->transforms
))
1051 /* Round 1 adds algorithms with at least 128 bit security strength */
1052 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1053 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1059 case ENCR_CAMELLIA_CBC
:
1060 case ENCR_CAMELLIA_CTR
:
1061 /* we assume that we support all AES/Camellia sizes */
1062 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1063 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1064 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1070 enumerator
->destroy(enumerator
);
1072 /* Round 2 adds algorithms with less than 128 bit security strength */
1073 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1074 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1079 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 0);
1088 enumerator
->destroy(enumerator
);
1090 if (!array_count(this->transforms
))
1095 /* Round 1 adds algorithms with at least 128 bit security strength */
1096 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1097 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1101 case AUTH_HMAC_SHA2_256_128
:
1102 case AUTH_HMAC_SHA2_384_192
:
1103 case AUTH_HMAC_SHA2_512_256
:
1104 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
1110 enumerator
->destroy(enumerator
);
1112 /* Round 2 adds algorithms with less than 128 bit security strength */
1113 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1114 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1118 case AUTH_AES_XCBC_96
:
1119 case AUTH_AES_CMAC_96
:
1120 case AUTH_HMAC_SHA1_96
:
1121 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
1123 case AUTH_HMAC_MD5_96
:
1129 enumerator
->destroy(enumerator
);
1132 /* Round 1 adds algorithms with at least 128 bit security strength */
1133 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1134 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1138 case PRF_HMAC_SHA2_256
:
1139 case PRF_HMAC_SHA2_384
:
1140 case PRF_HMAC_SHA2_512
:
1141 case PRF_AES128_XCBC
:
1142 case PRF_AES128_CMAC
:
1143 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
1149 enumerator
->destroy(enumerator
);
1151 /* Round 2 adds algorithms with less than 128 bit security strength */
1152 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1153 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1158 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
1167 enumerator
->destroy(enumerator
);
1169 /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */
1170 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1171 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1187 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1193 enumerator
->destroy(enumerator
);
1195 /* Round 2 adds other algorithms with at least 128 bit security strength */
1196 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1197 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1205 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1211 enumerator
->destroy(enumerator
);
1213 /* Round 3 adds algorithms with less than 128 bit security strength */
1214 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1215 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1220 /* only for testing purposes */
1230 /* RFC 5114 primes are of questionable source */
1239 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1245 enumerator
->destroy(enumerator
);
1251 * Described in header
1253 proposal_t
*proposal_create_default(protocol_id_t protocol
)
1255 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
, 0);
1260 if (!proposal_add_supported_ike(this, FALSE
))
1267 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
1268 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
1269 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
1270 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
1271 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
1272 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
1273 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
1274 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
1275 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
1278 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
1279 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
1280 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
1281 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
1282 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
1283 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
1288 return &this->public;
1292 * Described in header
1294 proposal_t
*proposal_create_default_aead(protocol_id_t protocol
)
1296 private_proposal_t
*this;
1301 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1302 if (!proposal_add_supported_ike(this, TRUE
))
1307 return &this->public;
1309 /* we currently don't include any AEAD proposal for ESP, as we
1310 * don't know if our kernel backend actually supports it. */
1319 * Described in header
1321 proposal_t
*proposal_create_from_string(protocol_id_t protocol
, const char *algs
)
1323 private_proposal_t
*this;
1324 enumerator_t
*enumerator
;
1328 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1330 /* get all tokens, separated by '-' */
1331 enumerator
= enumerator_create_token(algs
, "-", " ");
1332 while (enumerator
->enumerate(enumerator
, &alg
))
1334 if (!add_string_algo(this, alg
))
1341 enumerator
->destroy(enumerator
);
1343 if (failed
|| !check_proposal(this))
1349 return &this->public;
1353 * Described in header
1355 proposal_t
*proposal_select(linked_list_t
*configured
, linked_list_t
*supplied
,
1356 proposal_selection_flag_t flags
)
1358 enumerator_t
*prefer_enum
, *match_enum
;
1359 proposal_t
*proposal
, *match
, *selected
= NULL
;
1361 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
1363 prefer_enum
= supplied
->create_enumerator(supplied
);
1364 match_enum
= configured
->create_enumerator(configured
);
1368 prefer_enum
= configured
->create_enumerator(configured
);
1369 match_enum
= supplied
->create_enumerator(supplied
);
1372 while (prefer_enum
->enumerate(prefer_enum
, &proposal
))
1374 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
1376 configured
->reset_enumerator(configured
, match_enum
);
1380 supplied
->reset_enumerator(supplied
, match_enum
);
1382 while (match_enum
->enumerate(match_enum
, &match
))
1384 selected
= proposal
->select(proposal
, match
, flags
);
1387 DBG2(DBG_CFG
, "received proposals: %#P", supplied
);
1388 DBG2(DBG_CFG
, "configured proposals: %#P", configured
);
1389 DBG1(DBG_CFG
, "selected proposal: %P", selected
);
1398 prefer_enum
->destroy(prefer_enum
);
1399 match_enum
->destroy(match_enum
);
1402 DBG1(DBG_CFG
, "received proposals: %#P", supplied
);
1403 DBG1(DBG_CFG
, "configured proposals: %#P", configured
);