2 * Copyright (C) 2008-2020 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
76 * Transform number (IKEv1 only)
78 uint8_t transform_number
;
82 * This is a hack to not change the previous order when printing proposals
84 static transform_type_t
type_for_sort(const void *type
)
86 const transform_type_t
*t
= type
;
90 case PSEUDO_RANDOM_FUNCTION
:
91 return INTEGRITY_ALGORITHM
;
92 case INTEGRITY_ALGORITHM
:
93 return PSEUDO_RANDOM_FUNCTION
;
100 * Sort transform types
102 static int type_sort(const void *a
, const void *b
, void *user
)
104 transform_type_t ta
= type_for_sort(a
), tb
= type_for_sort(b
);
109 * Find a transform type
111 static int type_find(const void *a
, const void *b
)
113 return type_sort(a
, b
, NULL
);
117 * Check if the given transform type is already in the set
119 static bool contains_type(array_t
*types
, transform_type_t type
)
121 return array_bsearch(types
, &type
, type_find
, NULL
) != -1;
125 * Add the given transform type to the set
127 static void add_type(array_t
*types
, transform_type_t type
)
129 if (!contains_type(types
, type
))
131 array_insert(types
, ARRAY_TAIL
, &type
);
132 array_sort(types
, type_sort
, NULL
);
137 * Merge two sets of transform types into a new array
139 static array_t
*merge_types(private_proposal_t
*this, private_proposal_t
*other
)
142 transform_type_t type
;
145 count
= max(array_count(this->types
), array_count(other
->types
));
146 types
= array_create(sizeof(transform_type_t
), count
);
148 for (i
= 0; i
< count
; i
++)
150 if (array_get(this->types
, i
, &type
))
152 add_type(types
, type
);
154 if (array_get(other
->types
, i
, &type
))
156 add_type(types
, type
);
163 * Remove the given transform type from the set
165 static void remove_type(private_proposal_t
*this, transform_type_t type
)
169 i
= array_bsearch(this->types
, &type
, type_find
, NULL
);
172 array_remove(this->types
, i
, NULL
);
177 * Struct used to store different kinds of algorithms.
180 /** Type of the transform */
181 transform_type_t type
;
182 /** algorithm identifier */
184 /** key size in bits, or zero if not needed */
188 METHOD(proposal_t
, add_algorithm
, void,
189 private_proposal_t
*this, transform_type_t type
,
190 uint16_t alg
, uint16_t key_size
)
195 .key_size
= key_size
,
198 array_insert(this->transforms
, ARRAY_TAIL
, &entry
);
199 add_type(this->types
, type
);
202 CALLBACK(alg_filter
, bool,
203 uintptr_t type
, enumerator_t
*orig
, va_list args
)
206 uint16_t *alg
, *key_size
;
208 VA_ARGS_VGET(args
, alg
, key_size
);
210 while (orig
->enumerate(orig
, &entry
))
212 if (entry
->type
!= type
)
222 *key_size
= entry
->key_size
;
229 METHOD(proposal_t
, create_enumerator
, enumerator_t
*,
230 private_proposal_t
*this, transform_type_t type
)
232 return enumerator_create_filter(
233 array_create_enumerator(this->transforms
),
234 alg_filter
, (void*)(uintptr_t)type
, NULL
);
237 METHOD(proposal_t
, get_algorithm
, bool,
238 private_proposal_t
*this, transform_type_t type
,
239 uint16_t *alg
, uint16_t *key_size
)
241 enumerator_t
*enumerator
;
244 enumerator
= create_enumerator(this, type
);
245 if (enumerator
->enumerate(enumerator
, alg
, key_size
))
249 enumerator
->destroy(enumerator
);
254 METHOD(proposal_t
, has_dh_group
, bool,
255 private_proposal_t
*this, diffie_hellman_group_t group
)
257 bool found
= FALSE
, any
= FALSE
;
258 enumerator_t
*enumerator
;
261 enumerator
= create_enumerator(this, DIFFIE_HELLMAN_GROUP
);
262 while (enumerator
->enumerate(enumerator
, ¤t
, NULL
))
265 if (current
== group
)
271 enumerator
->destroy(enumerator
);
273 if (!any
&& group
== MODP_NONE
)
280 METHOD(proposal_t
, promote_dh_group
, bool,
281 private_proposal_t
*this, diffie_hellman_group_t group
)
283 enumerator_t
*enumerator
;
287 enumerator
= array_create_enumerator(this->transforms
);
288 while (enumerator
->enumerate(enumerator
, &entry
))
290 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&&
293 array_remove_at(this->transforms
, enumerator
);
297 enumerator
->destroy(enumerator
);
302 .type
= DIFFIE_HELLMAN_GROUP
,
305 array_insert(this->transforms
, ARRAY_HEAD
, &entry
);
311 * Select a matching proposal from this and other.
313 static bool select_algo(private_proposal_t
*this, proposal_t
*other
,
314 transform_type_t type
, proposal_selection_flag_t flags
,
315 bool log
, uint16_t *alg
, uint16_t *ks
)
317 enumerator_t
*e1
, *e2
;
318 uint16_t alg1
, alg2
, ks1
, ks2
;
319 bool found
= FALSE
, optional
= FALSE
;
321 if (type
== DIFFIE_HELLMAN_GROUP
)
323 optional
= this->protocol
== PROTO_ESP
|| this->protocol
== PROTO_AH
;
326 e1
= create_enumerator(this, type
);
327 e2
= other
->create_enumerator(other
, type
);
328 if (!e1
->enumerate(e1
, &alg1
, NULL
))
330 if (!e2
->enumerate(e2
, &alg2
, NULL
))
337 { /* if NONE is proposed, we accept the proposal */
340 while (!found
&& e2
->enumerate(e2
, &alg2
, NULL
));
343 else if (!e2
->enumerate(e2
, NULL
, NULL
))
348 { /* if NONE is proposed, we accept the proposal */
351 while (!found
&& e1
->enumerate(e1
, &alg1
, NULL
));
356 e1
= create_enumerator(this, type
);
357 /* compare algs, order of algs in "first" is preferred */
358 while (!found
&& e1
->enumerate(e1
, &alg1
, &ks1
))
361 e2
= other
->create_enumerator(other
, type
);
362 while (e2
->enumerate(e2
, &alg2
, &ks2
))
364 if (alg1
== alg2
&& ks1
== ks2
)
366 if ((flags
& PROPOSAL_SKIP_PRIVATE
) && alg1
>= 1024)
370 DBG1(DBG_CFG
, "an algorithm from private space would "
371 "match, but peer implementation is unknown, "
389 * Select algorithms from the given proposals, if selected is given, the result
390 * is stored there and errors are logged.
392 static bool select_algos(private_proposal_t
*this, proposal_t
*other
,
393 proposal_t
*selected
, proposal_selection_flag_t flags
)
395 transform_type_t type
;
397 bool skip_integrity
= FALSE
;
400 types
= merge_types(this, (private_proposal_t
*)other
);
401 for (i
= 0; i
< array_count(types
); i
++)
403 uint16_t alg
= 0, ks
= 0;
405 array_get(types
, i
, &type
);
406 if (type
== INTEGRITY_ALGORITHM
&& skip_integrity
)
410 if (type
== DIFFIE_HELLMAN_GROUP
&& (flags
& PROPOSAL_SKIP_DH
))
414 if (select_algo(this, other
, type
, flags
, selected
!= NULL
, &alg
, &ks
))
416 if (alg
== 0 && type
!= EXTENDED_SEQUENCE_NUMBERS
)
417 { /* 0 is "valid" for extended sequence numbers, for other
418 * transforms it either means NONE or is reserved */
423 selected
->add_algorithm(selected
, type
, alg
, ks
);
425 if (type
== ENCRYPTION_ALGORITHM
&&
426 encryption_algorithm_is_aead(alg
))
428 /* no integrity algorithm required, we have an AEAD */
429 skip_integrity
= TRUE
;
436 DBG2(DBG_CFG
, " no acceptable %N found", transform_type_names
,
439 array_destroy(types
);
443 array_destroy(types
);
447 METHOD(proposal_t
, select_proposal
, proposal_t
*,
448 private_proposal_t
*this, proposal_t
*other
,
449 proposal_selection_flag_t flags
)
451 proposal_t
*selected
;
453 DBG2(DBG_CFG
, "selecting proposal:");
455 if (this->protocol
!= other
->get_protocol(other
))
457 DBG2(DBG_CFG
, " protocol mismatch, skipping");
461 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
463 selected
= proposal_create_v1(this->protocol
, this->number
,
464 this->transform_number
);
465 selected
->set_spi(selected
, this->spi
);
469 selected
= proposal_create_v1(this->protocol
, other
->get_number(other
),
470 other
->get_transform_number(other
));
471 selected
->set_spi(selected
, other
->get_spi(other
));
474 if (!select_algos(this, other
, selected
, flags
))
476 selected
->destroy(selected
);
479 DBG2(DBG_CFG
, " proposal matches");
483 METHOD(proposal_t
, matches
, bool,
484 private_proposal_t
*this, proposal_t
*other
,
485 proposal_selection_flag_t flags
)
487 if (this->protocol
!= other
->get_protocol(other
))
491 return select_algos(this, other
, NULL
, flags
);
494 METHOD(proposal_t
, get_protocol
, protocol_id_t
,
495 private_proposal_t
*this)
497 return this->protocol
;
500 METHOD(proposal_t
, set_spi
, void,
501 private_proposal_t
*this, uint64_t spi
)
506 METHOD(proposal_t
, get_spi
, uint64_t,
507 private_proposal_t
*this)
513 * Check if two proposals have the same algorithms for a given transform type
515 static bool algo_list_equals(private_proposal_t
*this, proposal_t
*other
,
516 transform_type_t type
)
518 enumerator_t
*e1
, *e2
;
519 uint16_t alg1
, alg2
, ks1
, ks2
;
522 e1
= create_enumerator(this, type
);
523 e2
= other
->create_enumerator(other
, type
);
524 while (e1
->enumerate(e1
, &alg1
, &ks1
))
526 if (!e2
->enumerate(e2
, &alg2
, &ks2
))
528 /* this has more algs */
532 if (alg1
!= alg2
|| ks1
!= ks2
)
538 if (e2
->enumerate(e2
, &alg2
, &ks2
))
540 /* other has more algs */
549 METHOD(proposal_t
, get_number
, uint8_t,
550 private_proposal_t
*this)
555 METHOD(proposal_t
, get_transform_number
, uint8_t,
556 private_proposal_t
*this)
558 return this->transform_number
;
561 METHOD(proposal_t
, equals
, bool,
562 private_proposal_t
*this, proposal_t
*other
)
564 transform_type_t type
;
568 if (&this->public == other
)
573 types
= merge_types(this, (private_proposal_t
*)other
);
574 for (i
= 0; i
< array_count(types
); i
++)
576 array_get(types
, i
, &type
);
577 if (!algo_list_equals(this, other
, type
))
579 array_destroy(types
);
583 array_destroy(types
);
587 METHOD(proposal_t
, clone_
, proposal_t
*,
588 private_proposal_t
*this, proposal_selection_flag_t flags
)
590 private_proposal_t
*clone
;
591 enumerator_t
*enumerator
;
594 clone
= (private_proposal_t
*)proposal_create(this->protocol
, 0);
596 enumerator
= array_create_enumerator(this->transforms
);
597 while (enumerator
->enumerate(enumerator
, &entry
))
599 if (entry
->alg
>= 1024 && (flags
& PROPOSAL_SKIP_PRIVATE
))
603 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&& (flags
& PROPOSAL_SKIP_DH
))
607 array_insert(clone
->transforms
, ARRAY_TAIL
, entry
);
608 add_type(clone
->types
, entry
->type
);
610 enumerator
->destroy(enumerator
);
612 clone
->spi
= this->spi
;
613 clone
->number
= this->number
;
614 clone
->transform_number
= this->transform_number
;
616 return &clone
->public;
620 * Map integrity algorithms to the PRF functions using the same algorithm.
622 static const struct {
623 integrity_algorithm_t integ
;
624 pseudo_random_function_t prf
;
625 } integ_prf_map
[] = {
626 {AUTH_HMAC_SHA1_96
, PRF_HMAC_SHA1
},
627 {AUTH_HMAC_SHA1_160
, PRF_HMAC_SHA1
},
628 {AUTH_HMAC_SHA2_256_128
, PRF_HMAC_SHA2_256
},
629 {AUTH_HMAC_SHA2_384_192
, PRF_HMAC_SHA2_384
},
630 {AUTH_HMAC_SHA2_512_256
, PRF_HMAC_SHA2_512
},
631 {AUTH_HMAC_MD5_96
, PRF_HMAC_MD5
},
632 {AUTH_HMAC_MD5_128
, PRF_HMAC_MD5
},
633 {AUTH_AES_XCBC_96
, PRF_AES128_XCBC
},
634 {AUTH_CAMELLIA_XCBC_96
, PRF_CAMELLIA128_XCBC
},
635 {AUTH_AES_CMAC_96
, PRF_AES128_CMAC
},
639 * Remove all entries of the given transform type
641 static void remove_transform(private_proposal_t
*this, transform_type_t type
)
646 e
= array_create_enumerator(this->transforms
);
647 while (e
->enumerate(e
, &entry
))
649 if (entry
->type
== type
)
651 array_remove_at(this->transforms
, e
);
655 remove_type(this, type
);
659 * Checks the proposal read from a string.
661 static bool check_proposal(private_proposal_t
*this)
666 bool all_aead
= TRUE
, any_aead
= FALSE
, any_enc
= FALSE
;
669 if (this->protocol
== PROTO_IKE
)
671 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
672 { /* No explicit PRF found. We assume the same algorithm as used
673 * for integrity checking. */
674 e
= create_enumerator(this, INTEGRITY_ALGORITHM
);
675 while (e
->enumerate(e
, &alg
, &ks
))
677 for (i
= 0; i
< countof(integ_prf_map
); i
++)
679 if (alg
== integ_prf_map
[i
].integ
)
681 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
,
682 integ_prf_map
[i
].prf
, 0);
689 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION
, NULL
, NULL
))
691 DBG1(DBG_CFG
, "a PRF algorithm is mandatory in IKE proposals");
694 /* remove MODP_NONE from IKE proposal */
695 e
= array_create_enumerator(this->transforms
);
696 while (e
->enumerate(e
, &entry
))
698 if (entry
->type
== DIFFIE_HELLMAN_GROUP
&& !entry
->alg
)
700 array_remove_at(this->transforms
, e
);
704 if (!get_algorithm(this, DIFFIE_HELLMAN_GROUP
, NULL
, NULL
))
706 DBG1(DBG_CFG
, "a DH group is mandatory in IKE proposals");
711 { /* remove PRFs from ESP/AH proposals */
712 remove_transform(this, PSEUDO_RANDOM_FUNCTION
);
715 if (this->protocol
== PROTO_IKE
|| this->protocol
== PROTO_ESP
)
717 e
= create_enumerator(this, ENCRYPTION_ALGORITHM
);
718 while (e
->enumerate(e
, &alg
, &ks
))
721 if (encryption_algorithm_is_aead(alg
))
732 DBG1(DBG_CFG
, "an encryption algorithm is mandatory in %N proposals",
733 protocol_id_names
, this->protocol
);
736 else if (any_aead
&& !all_aead
)
738 DBG1(DBG_CFG
, "classic and combined-mode (AEAD) encryption "
739 "algorithms can't be contained in the same %N proposal",
740 protocol_id_names
, this->protocol
);
744 { /* if all encryption algorithms in the proposal are AEADs,
745 * we MUST NOT propose any integrity algorithms */
746 remove_transform(this, INTEGRITY_ALGORITHM
);
748 else if (this->protocol
== PROTO_IKE
&&
749 !get_algorithm(this, INTEGRITY_ALGORITHM
, NULL
, NULL
))
751 DBG1(DBG_CFG
, "an integrity algorithm is mandatory in %N proposals "
752 "with classic (non-AEAD) encryption algorithms",
753 protocol_id_names
, this->protocol
);
758 { /* AES-GMAC is parsed as encryption algorithm, so we map that to the
759 * proper integrity algorithm */
760 e
= array_create_enumerator(this->transforms
);
761 while (e
->enumerate(e
, &entry
))
763 if (entry
->type
== ENCRYPTION_ALGORITHM
)
765 if (entry
->alg
== ENCR_NULL_AUTH_AES_GMAC
)
767 entry
->type
= INTEGRITY_ALGORITHM
;
768 ks
= entry
->key_size
;
773 entry
->alg
= AUTH_AES_128_GMAC
;
776 entry
->alg
= AUTH_AES_192_GMAC
;
779 entry
->alg
= AUTH_AES_256_GMAC
;
785 /* remove all other encryption algorithms */
786 array_remove_at(this->transforms
, e
);
790 remove_type(this, ENCRYPTION_ALGORITHM
);
792 if (!get_algorithm(this, INTEGRITY_ALGORITHM
, NULL
, NULL
))
794 DBG1(DBG_CFG
, "an integrity algorithm is mandatory in AH "
800 if (this->protocol
== PROTO_AH
|| this->protocol
== PROTO_ESP
)
802 if (!get_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NULL
, NULL
))
803 { /* ESN not specified, assume not supported */
804 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
808 array_compress(this->transforms
);
809 array_compress(this->types
);
814 * add a algorithm identified by a string to the proposal.
816 static bool add_string_algo(private_proposal_t
*this, const char *alg
)
818 const proposal_token_t
*token
;
820 token
= lib
->proposal
->get_token(lib
->proposal
, alg
);
823 DBG1(DBG_CFG
, "algorithm '%s' not recognized", alg
);
827 add_algorithm(this, token
->type
, token
->algorithm
, token
->keysize
);
833 * Print all algorithms of the given type
835 static int print_alg(private_proposal_t
*this, printf_hook_data_t
*data
,
836 transform_type_t type
, bool *first
)
838 enumerator_t
*enumerator
;
843 names
= transform_get_enum_names(type
);
845 enumerator
= array_create_enumerator(this->transforms
);
846 while (enumerator
->enumerate(enumerator
, &entry
))
850 if (type
!= entry
->type
)
861 written
+= print_in_hook(data
, "%s%N", prefix
, names
, entry
->alg
);
865 written
+= print_in_hook(data
, "%sUNKNOWN_%u_%u", prefix
,
866 entry
->type
, entry
->alg
);
870 written
+= print_in_hook(data
, "_%u", entry
->key_size
);
873 enumerator
->destroy(enumerator
);
878 * Described in header.
880 int proposal_printf_hook(printf_hook_data_t
*data
, printf_hook_spec_t
*spec
,
881 const void *const *args
)
883 private_proposal_t
*this = *((private_proposal_t
**)(args
[0]));
884 linked_list_t
*list
= *((linked_list_t
**)(args
[0]));
885 enumerator_t
*enumerator
;
886 transform_type_t
*type
;
892 return print_in_hook(data
, "(null)");
897 enumerator
= list
->create_enumerator(list
);
898 while (enumerator
->enumerate(enumerator
, &this))
899 { /* call recursively */
902 written
+= print_in_hook(data
, "%P", this);
907 written
+= print_in_hook(data
, ", %P", this);
910 enumerator
->destroy(enumerator
);
914 written
= print_in_hook(data
, "%N:", protocol_id_names
, this->protocol
);
915 enumerator
= array_create_enumerator(this->types
);
916 while (enumerator
->enumerate(enumerator
, &type
))
918 written
+= print_alg(this, data
, *type
, &first
);
920 enumerator
->destroy(enumerator
);
924 METHOD(proposal_t
, destroy
, void,
925 private_proposal_t
*this)
927 array_destroy(this->transforms
);
928 array_destroy(this->types
);
933 * Described in header
935 proposal_t
*proposal_create_v1(protocol_id_t protocol
, uint8_t number
,
938 private_proposal_t
*this;
942 .add_algorithm
= _add_algorithm
,
943 .create_enumerator
= _create_enumerator
,
944 .get_algorithm
= _get_algorithm
,
945 .has_dh_group
= _has_dh_group
,
946 .promote_dh_group
= _promote_dh_group
,
947 .select
= _select_proposal
,
949 .get_protocol
= _get_protocol
,
952 .get_number
= _get_number
,
953 .get_transform_number
= _get_transform_number
,
958 .protocol
= protocol
,
960 .transform_number
= transform
,
961 .transforms
= array_create(sizeof(entry_t
), 0),
962 .types
= array_create(sizeof(transform_type_t
), 0),
965 return &this->public;
969 * Described in header
971 proposal_t
*proposal_create(protocol_id_t protocol
, uint8_t number
)
973 return proposal_create_v1(protocol
, number
, 0);
977 * Add supported IKE algorithms to proposal
979 static bool proposal_add_supported_ike(private_proposal_t
*this, bool aead
)
981 enumerator_t
*enumerator
;
982 encryption_algorithm_t encryption
;
983 integrity_algorithm_t integrity
;
984 pseudo_random_function_t prf
;
985 diffie_hellman_group_t group
;
986 const char *plugin_name
;
990 /* Round 1 adds algorithms with at least 128 bit security strength */
991 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
992 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
996 case ENCR_AES_GCM_ICV16
:
997 case ENCR_AES_CCM_ICV16
:
998 case ENCR_CAMELLIA_CCM_ICV16
:
999 /* we assume that we support all AES/Camellia sizes */
1000 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1001 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1002 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1004 case ENCR_CHACHA20_POLY1305
:
1005 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 0);
1011 enumerator
->destroy(enumerator
);
1013 /* Round 2 adds algorithms with less than 128 bit security strength */
1014 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
1015 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1019 case ENCR_AES_GCM_ICV12
:
1020 case ENCR_AES_GCM_ICV8
:
1021 case ENCR_AES_CCM_ICV12
:
1022 case ENCR_AES_CCM_ICV8
:
1023 case ENCR_CAMELLIA_CCM_ICV12
:
1024 case ENCR_CAMELLIA_CCM_ICV8
:
1025 /* we assume that we support all AES/Camellia sizes */
1026 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1027 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1028 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1034 enumerator
->destroy(enumerator
);
1036 if (!array_count(this->transforms
))
1043 /* Round 1 adds algorithms with at least 128 bit security strength */
1044 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1045 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1051 case ENCR_CAMELLIA_CBC
:
1052 case ENCR_CAMELLIA_CTR
:
1053 /* we assume that we support all AES/Camellia sizes */
1054 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 128);
1055 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 192);
1056 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 256);
1062 enumerator
->destroy(enumerator
);
1064 /* Round 2 adds algorithms with less than 128 bit security strength */
1065 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1066 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1071 add_algorithm(this, ENCRYPTION_ALGORITHM
, encryption
, 0);
1080 enumerator
->destroy(enumerator
);
1082 if (!array_count(this->transforms
))
1087 /* Round 1 adds algorithms with at least 128 bit security strength */
1088 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1089 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1093 case AUTH_HMAC_SHA2_256_128
:
1094 case AUTH_HMAC_SHA2_384_192
:
1095 case AUTH_HMAC_SHA2_512_256
:
1096 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
1102 enumerator
->destroy(enumerator
);
1104 /* Round 2 adds algorithms with less than 128 bit security strength */
1105 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1106 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1110 case AUTH_AES_XCBC_96
:
1111 case AUTH_AES_CMAC_96
:
1112 case AUTH_HMAC_SHA1_96
:
1113 add_algorithm(this, INTEGRITY_ALGORITHM
, integrity
, 0);
1115 case AUTH_HMAC_MD5_96
:
1121 enumerator
->destroy(enumerator
);
1124 /* Round 1 adds algorithms with at least 128 bit security strength */
1125 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1126 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1130 case PRF_HMAC_SHA2_256
:
1131 case PRF_HMAC_SHA2_384
:
1132 case PRF_HMAC_SHA2_512
:
1133 case PRF_AES128_XCBC
:
1134 case PRF_AES128_CMAC
:
1135 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
1141 enumerator
->destroy(enumerator
);
1143 /* Round 2 adds algorithms with less than 128 bit security strength */
1144 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1145 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1150 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, prf
, 0);
1159 enumerator
->destroy(enumerator
);
1161 /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */
1162 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1163 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1179 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1185 enumerator
->destroy(enumerator
);
1187 /* Round 2 adds other algorithms with at least 128 bit security strength */
1188 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1189 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1197 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1203 enumerator
->destroy(enumerator
);
1205 /* Round 3 adds algorithms with less than 128 bit security strength */
1206 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1207 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1212 /* only for testing purposes */
1222 /* RFC 5114 primes are of questionable source */
1231 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, group
, 0);
1237 enumerator
->destroy(enumerator
);
1243 * Described in header
1245 proposal_t
*proposal_create_default(protocol_id_t protocol
)
1247 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
, 0);
1252 if (!proposal_add_supported_ike(this, FALSE
))
1259 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
1260 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
1261 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
1262 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
1263 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
1264 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
1265 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
1266 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
1267 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
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);
1280 return &this->public;
1284 * Described in header
1286 proposal_t
*proposal_create_default_aead(protocol_id_t protocol
)
1288 private_proposal_t
*this;
1293 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1294 if (!proposal_add_supported_ike(this, TRUE
))
1299 return &this->public;
1301 /* AES-GCM should be supported by pretty much all current kernels,
1302 * RFC 8221 even made it mandatory */
1303 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1304 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV16
, 128);
1305 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV16
, 192);
1306 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV16
, 256);
1307 return &this->public;
1315 * Described in header
1317 proposal_t
*proposal_create_from_string(protocol_id_t protocol
, const char *algs
)
1319 private_proposal_t
*this;
1320 enumerator_t
*enumerator
;
1324 this = (private_proposal_t
*)proposal_create(protocol
, 0);
1326 /* get all tokens, separated by '-' */
1327 enumerator
= enumerator_create_token(algs
, "-", " ");
1328 while (enumerator
->enumerate(enumerator
, &alg
))
1330 if (!add_string_algo(this, alg
))
1337 enumerator
->destroy(enumerator
);
1339 if (failed
|| !check_proposal(this))
1345 return &this->public;
1349 * Described in header
1351 proposal_t
*proposal_select(linked_list_t
*configured
, linked_list_t
*supplied
,
1352 proposal_selection_flag_t flags
)
1354 enumerator_t
*prefer_enum
, *match_enum
;
1355 proposal_t
*proposal
, *match
, *selected
= NULL
;
1357 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
1359 prefer_enum
= supplied
->create_enumerator(supplied
);
1360 match_enum
= configured
->create_enumerator(configured
);
1364 prefer_enum
= configured
->create_enumerator(configured
);
1365 match_enum
= supplied
->create_enumerator(supplied
);
1368 while (prefer_enum
->enumerate(prefer_enum
, &proposal
))
1370 if (flags
& PROPOSAL_PREFER_SUPPLIED
)
1372 configured
->reset_enumerator(configured
, match_enum
);
1376 supplied
->reset_enumerator(supplied
, match_enum
);
1378 while (match_enum
->enumerate(match_enum
, &match
))
1380 selected
= proposal
->select(proposal
, match
, flags
);
1383 DBG2(DBG_CFG
, "received proposals: %#P", supplied
);
1384 DBG2(DBG_CFG
, "configured proposals: %#P", configured
);
1385 DBG1(DBG_CFG
, "selected proposal: %P", selected
);
1394 prefer_enum
->destroy(prefer_enum
);
1395 match_enum
->destroy(match_enum
);
1398 DBG1(DBG_CFG
, "received proposals: %#P", supplied
);
1399 DBG1(DBG_CFG
, "configured proposals: %#P", configured
);