c880020de80267df1dd17b64d62cf79fc174c678
[strongswan.git] / src / libstrongswan / crypto / proposal / proposal.c
1 /*
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
6 *
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>.
11 *
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
15 * for more details.
16 */
17
18 #include <string.h>
19
20 #include "proposal.h"
21
22 #include <collections/array.h>
23 #include <utils/identification.h>
24
25 #include <crypto/transform.h>
26 #include <crypto/prfs/prf.h>
27 #include <crypto/crypters/crypter.h>
28 #include <crypto/signers/signer.h>
29
30 ENUM(protocol_id_names, PROTO_NONE, PROTO_IPCOMP,
31 "PROTO_NONE",
32 "IKE",
33 "AH",
34 "ESP",
35 "IPCOMP",
36 );
37
38 typedef struct private_proposal_t private_proposal_t;
39
40 /**
41 * Private data of an proposal_t object
42 */
43 struct private_proposal_t {
44
45 /**
46 * Public part
47 */
48 proposal_t public;
49
50 /**
51 * protocol (ESP or AH)
52 */
53 protocol_id_t protocol;
54
55 /**
56 * Priority ordered list of transforms, as entry_t
57 */
58 array_t *transforms;
59
60 /**
61 * Types of transforms contained, as transform_type_t
62 */
63 array_t *types;
64
65 /**
66 * senders SPI
67 */
68 uint64_t spi;
69
70 /**
71 * Proposal number
72 */
73 u_int number;
74 };
75
76 /**
77 * This is a hack to not change the previous order when printing proposals
78 */
79 static transform_type_t type_for_sort(const void *type)
80 {
81 const transform_type_t *t = type;
82
83 switch (*t)
84 {
85 case PSEUDO_RANDOM_FUNCTION:
86 return INTEGRITY_ALGORITHM;
87 case INTEGRITY_ALGORITHM:
88 return PSEUDO_RANDOM_FUNCTION;
89 default:
90 return *t;
91 }
92 }
93
94 /**
95 * Sort transform types
96 */
97 static int type_sort(const void *a, const void *b, void *user)
98 {
99 transform_type_t ta = type_for_sort(a), tb = type_for_sort(b);
100 return ta - tb;
101 }
102
103 /**
104 * Find a transform type
105 */
106 static int type_find(const void *a, const void *b)
107 {
108 return type_sort(a, b, NULL);
109 }
110
111 /**
112 * Check if the given transform type is already in the set
113 */
114 static bool contains_type(array_t *types, transform_type_t type)
115 {
116 return array_bsearch(types, &type, type_find, NULL) != -1;
117 }
118
119 /**
120 * Add the given transform type to the set
121 */
122 static void add_type(array_t *types, transform_type_t type)
123 {
124 if (!contains_type(types, type))
125 {
126 array_insert(types, ARRAY_TAIL, &type);
127 array_sort(types, type_sort, NULL);
128 }
129 }
130
131 /**
132 * Merge two sets of transform types into a new array
133 */
134 static array_t *merge_types(private_proposal_t *this, private_proposal_t *other)
135 {
136 array_t *types;
137 transform_type_t type;
138 int i, count;
139
140 count = max(array_count(this->types), array_count(other->types));
141 types = array_create(sizeof(transform_type_t), count);
142
143 for (i = 0; i < count; i++)
144 {
145 if (array_get(this->types, i, &type))
146 {
147 add_type(types, type);
148 }
149 if (array_get(other->types, i, &type))
150 {
151 add_type(types, type);
152 }
153 }
154 return types;
155 }
156
157 /**
158 * Remove the given transform type from the set
159 */
160 static void remove_type(private_proposal_t *this, transform_type_t type)
161 {
162 int i;
163
164 i = array_bsearch(this->types, &type, type_find, NULL);
165 if (i >= 0)
166 {
167 array_remove(this->types, i, NULL);
168 }
169 }
170
171 /**
172 * Struct used to store different kinds of algorithms.
173 */
174 typedef struct {
175 /** Type of the transform */
176 transform_type_t type;
177 /** algorithm identifier */
178 uint16_t alg;
179 /** key size in bits, or zero if not needed */
180 uint16_t key_size;
181 } entry_t;
182
183 METHOD(proposal_t, add_algorithm, void,
184 private_proposal_t *this, transform_type_t type,
185 uint16_t alg, uint16_t key_size)
186 {
187 entry_t entry = {
188 .type = type,
189 .alg = alg,
190 .key_size = key_size,
191 };
192
193 array_insert(this->transforms, ARRAY_TAIL, &entry);
194 add_type(this->types, type);
195 }
196
197 CALLBACK(alg_filter, bool,
198 uintptr_t type, enumerator_t *orig, va_list args)
199 {
200 entry_t *entry;
201 uint16_t *alg, *key_size;
202
203 VA_ARGS_VGET(args, alg, key_size);
204
205 while (orig->enumerate(orig, &entry))
206 {
207 if (entry->type != type)
208 {
209 continue;
210 }
211 if (alg)
212 {
213 *alg = entry->alg;
214 }
215 if (key_size)
216 {
217 *key_size = entry->key_size;
218 }
219 return TRUE;
220 }
221 return FALSE;
222 }
223
224 METHOD(proposal_t, create_enumerator, enumerator_t*,
225 private_proposal_t *this, transform_type_t type)
226 {
227 return enumerator_create_filter(
228 array_create_enumerator(this->transforms),
229 alg_filter, (void*)(uintptr_t)type, NULL);
230 }
231
232 METHOD(proposal_t, get_algorithm, bool,
233 private_proposal_t *this, transform_type_t type,
234 uint16_t *alg, uint16_t *key_size)
235 {
236 enumerator_t *enumerator;
237 bool found = FALSE;
238
239 enumerator = create_enumerator(this, type);
240 if (enumerator->enumerate(enumerator, alg, key_size))
241 {
242 found = TRUE;
243 }
244 enumerator->destroy(enumerator);
245
246 return found;
247 }
248
249 METHOD(proposal_t, has_dh_group, bool,
250 private_proposal_t *this, diffie_hellman_group_t group)
251 {
252 bool found = FALSE, any = FALSE;
253 enumerator_t *enumerator;
254 uint16_t current;
255
256 enumerator = create_enumerator(this, DIFFIE_HELLMAN_GROUP);
257 while (enumerator->enumerate(enumerator, &current, NULL))
258 {
259 any = TRUE;
260 if (current == group)
261 {
262 found = TRUE;
263 break;
264 }
265 }
266 enumerator->destroy(enumerator);
267
268 if (!any && group == MODP_NONE)
269 {
270 found = TRUE;
271 }
272 return found;
273 }
274
275 METHOD(proposal_t, promote_dh_group, bool,
276 private_proposal_t *this, diffie_hellman_group_t group)
277 {
278 enumerator_t *enumerator;
279 entry_t *entry;
280 bool found = FALSE;
281
282 enumerator = array_create_enumerator(this->transforms);
283 while (enumerator->enumerate(enumerator, &entry))
284 {
285 if (entry->type == DIFFIE_HELLMAN_GROUP &&
286 entry->alg == group)
287 {
288 array_remove_at(this->transforms, enumerator);
289 found = TRUE;
290 }
291 }
292 enumerator->destroy(enumerator);
293
294 if (found)
295 {
296 entry_t entry = {
297 .type = DIFFIE_HELLMAN_GROUP,
298 .alg = group,
299 };
300 array_insert(this->transforms, ARRAY_HEAD, &entry);
301 }
302 return found;
303 }
304
305 METHOD(proposal_t, strip_dh, void,
306 private_proposal_t *this, diffie_hellman_group_t keep)
307 {
308 enumerator_t *enumerator;
309 entry_t *entry;
310 bool found = FALSE;
311
312 enumerator = array_create_enumerator(this->transforms);
313 while (enumerator->enumerate(enumerator, &entry))
314 {
315 if (entry->type == DIFFIE_HELLMAN_GROUP)
316 {
317 if (entry->alg != keep)
318 {
319 array_remove_at(this->transforms, enumerator);
320 }
321 else
322 {
323 found = TRUE;
324 }
325 }
326 }
327 enumerator->destroy(enumerator);
328 array_compress(this->transforms);
329
330 if (keep == MODP_NONE || !found)
331 {
332 remove_type(this, DIFFIE_HELLMAN_GROUP);
333 array_compress(this->types);
334 }
335 }
336
337 /**
338 * Select a matching proposal from this and other.
339 */
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)
343 {
344 enumerator_t *e1, *e2;
345 uint16_t alg1, alg2, ks1, ks2;
346 bool found = FALSE, optional = FALSE;
347
348 if (type == DIFFIE_HELLMAN_GROUP)
349 {
350 optional = this->protocol == PROTO_ESP || this->protocol == PROTO_AH;
351 }
352
353 e1 = create_enumerator(this, type);
354 e2 = other->create_enumerator(other, type);
355 if (!e1->enumerate(e1, &alg1, NULL))
356 {
357 if (!e2->enumerate(e2, &alg2, NULL))
358 {
359 found = TRUE;
360 }
361 else if (optional)
362 {
363 do
364 { /* if NONE is proposed, we accept the proposal */
365 found = !alg2;
366 }
367 while (!found && e2->enumerate(e2, &alg2, NULL));
368 }
369 }
370 else if (!e2->enumerate(e2, NULL, NULL))
371 {
372 if (optional)
373 {
374 do
375 { /* if NONE is proposed, we accept the proposal */
376 found = !alg1;
377 }
378 while (!found && e1->enumerate(e1, &alg1, NULL));
379 }
380 }
381
382 e1->destroy(e1);
383 e1 = create_enumerator(this, type);
384 /* compare algs, order of algs in "first" is preferred */
385 while (!found && e1->enumerate(e1, &alg1, &ks1))
386 {
387 e2->destroy(e2);
388 e2 = other->create_enumerator(other, type);
389 while (e2->enumerate(e2, &alg2, &ks2))
390 {
391 if (alg1 == alg2 && ks1 == ks2)
392 {
393 if (!(flags & PROPOSAL_ALLOW_PRIVATE) && alg1 >= 1024)
394 {
395 if (log)
396 {
397 DBG1(DBG_CFG, "an algorithm from private space would "
398 "match, but peer implementation is unknown, "
399 "skipped");
400 }
401 continue;
402 }
403 *alg = alg1;
404 *ks = ks1;
405 found = TRUE;
406 break;
407 }
408 }
409 }
410 e1->destroy(e1);
411 e2->destroy(e2);
412 return found;
413 }
414
415 /**
416 * Select algorithms from the given proposals, if selected is given, the result
417 * is stored there and errors are logged.
418 */
419 static bool select_algos(private_proposal_t *this, proposal_t *other,
420 proposal_t *selected, proposal_selection_flag_t flags)
421 {
422 transform_type_t type;
423 array_t *types;
424 bool skip_integrity = FALSE;
425 int i;
426
427 types = merge_types(this, (private_proposal_t*)other);
428 for (i = 0; i < array_count(types); i++)
429 {
430 uint16_t alg = 0, ks = 0;
431
432 array_get(types, i, &type);
433 if (type == INTEGRITY_ALGORITHM && skip_integrity)
434 {
435 continue;
436 }
437 if (type == DIFFIE_HELLMAN_GROUP && (flags & PROPOSAL_SKIP_DH))
438 {
439 continue;
440 }
441 if (select_algo(this, other, type, flags, selected != NULL, &alg, &ks))
442 {
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 */
446 continue;
447 }
448 if (selected)
449 {
450 selected->add_algorithm(selected, type, alg, ks);
451 }
452 if (type == ENCRYPTION_ALGORITHM &&
453 encryption_algorithm_is_aead(alg))
454 {
455 /* no integrity algorithm required, we have an AEAD */
456 skip_integrity = TRUE;
457 }
458 }
459 else
460 {
461 if (selected)
462 {
463 DBG2(DBG_CFG, " no acceptable %N found", transform_type_names,
464 type);
465 }
466 array_destroy(types);
467 return FALSE;
468 }
469 }
470 array_destroy(types);
471 return TRUE;
472 }
473
474 METHOD(proposal_t, select_proposal, proposal_t*,
475 private_proposal_t *this, proposal_t *other,
476 proposal_selection_flag_t flags)
477 {
478 proposal_t *selected;
479
480 DBG2(DBG_CFG, "selecting proposal:");
481
482 if (this->protocol != other->get_protocol(other))
483 {
484 DBG2(DBG_CFG, " protocol mismatch, skipping");
485 return NULL;
486 }
487
488 if (flags & PROPOSAL_PREFER_SUPPLIED)
489 {
490 selected = proposal_create(this->protocol, this->number);
491 selected->set_spi(selected, this->spi);
492 }
493 else
494 {
495 selected = proposal_create(this->protocol, other->get_number(other));
496 selected->set_spi(selected, other->get_spi(other));
497 }
498
499 if (!select_algos(this, other, selected, flags))
500 {
501 selected->destroy(selected);
502 return NULL;
503 }
504 DBG2(DBG_CFG, " proposal matches");
505 return selected;
506 }
507
508 METHOD(proposal_t, matches, bool,
509 private_proposal_t *this, proposal_t *other,
510 proposal_selection_flag_t flags)
511 {
512 if (this->protocol != other->get_protocol(other))
513 {
514 return FALSE;
515 }
516 return select_algos(this, other, NULL, flags);
517 }
518
519 METHOD(proposal_t, get_protocol, protocol_id_t,
520 private_proposal_t *this)
521 {
522 return this->protocol;
523 }
524
525 METHOD(proposal_t, set_spi, void,
526 private_proposal_t *this, uint64_t spi)
527 {
528 this->spi = spi;
529 }
530
531 METHOD(proposal_t, get_spi, uint64_t,
532 private_proposal_t *this)
533 {
534 return this->spi;
535 }
536
537 /**
538 * Check if two proposals have the same algorithms for a given transform type
539 */
540 static bool algo_list_equals(private_proposal_t *this, proposal_t *other,
541 transform_type_t type)
542 {
543 enumerator_t *e1, *e2;
544 uint16_t alg1, alg2, ks1, ks2;
545 bool equals = TRUE;
546
547 e1 = create_enumerator(this, type);
548 e2 = other->create_enumerator(other, type);
549 while (e1->enumerate(e1, &alg1, &ks1))
550 {
551 if (!e2->enumerate(e2, &alg2, &ks2))
552 {
553 /* this has more algs */
554 equals = FALSE;
555 break;
556 }
557 if (alg1 != alg2 || ks1 != ks2)
558 {
559 equals = FALSE;
560 break;
561 }
562 }
563 if (e2->enumerate(e2, &alg2, &ks2))
564 {
565 /* other has more algs */
566 equals = FALSE;
567 }
568 e1->destroy(e1);
569 e2->destroy(e2);
570
571 return equals;
572 }
573
574 METHOD(proposal_t, get_number, u_int,
575 private_proposal_t *this)
576 {
577 return this->number;
578 }
579
580 METHOD(proposal_t, equals, bool,
581 private_proposal_t *this, proposal_t *other)
582 {
583 transform_type_t type;
584 array_t *types;
585 int i;
586
587 if (&this->public == other)
588 {
589 return TRUE;
590 }
591
592 types = merge_types(this, (private_proposal_t*)other);
593 for (i = 0; i < array_count(types); i++)
594 {
595 array_get(types, i, &type);
596 if (!algo_list_equals(this, other, type))
597 {
598 array_destroy(types);
599 return FALSE;
600 }
601 }
602 array_destroy(types);
603 return TRUE;
604 }
605
606 METHOD(proposal_t, clone_, proposal_t*,
607 private_proposal_t *this)
608 {
609 private_proposal_t *clone;
610 enumerator_t *enumerator;
611 entry_t *entry;
612 transform_type_t *type;
613
614 clone = (private_proposal_t*)proposal_create(this->protocol, 0);
615
616 enumerator = array_create_enumerator(this->transforms);
617 while (enumerator->enumerate(enumerator, &entry))
618 {
619 array_insert(clone->transforms, ARRAY_TAIL, entry);
620 }
621 enumerator->destroy(enumerator);
622 enumerator = array_create_enumerator(this->types);
623 while (enumerator->enumerate(enumerator, &type))
624 {
625 array_insert(clone->types, ARRAY_TAIL, type);
626 }
627 enumerator->destroy(enumerator);
628
629 clone->spi = this->spi;
630 clone->number = this->number;
631
632 return &clone->public;
633 }
634
635 /**
636 * Map integrity algorithms to the PRF functions using the same algorithm.
637 */
638 static const struct {
639 integrity_algorithm_t integ;
640 pseudo_random_function_t prf;
641 } integ_prf_map[] = {
642 {AUTH_HMAC_SHA1_96, PRF_HMAC_SHA1 },
643 {AUTH_HMAC_SHA1_160, PRF_HMAC_SHA1 },
644 {AUTH_HMAC_SHA2_256_128, PRF_HMAC_SHA2_256 },
645 {AUTH_HMAC_SHA2_384_192, PRF_HMAC_SHA2_384 },
646 {AUTH_HMAC_SHA2_512_256, PRF_HMAC_SHA2_512 },
647 {AUTH_HMAC_MD5_96, PRF_HMAC_MD5 },
648 {AUTH_HMAC_MD5_128, PRF_HMAC_MD5 },
649 {AUTH_AES_XCBC_96, PRF_AES128_XCBC },
650 {AUTH_CAMELLIA_XCBC_96, PRF_CAMELLIA128_XCBC },
651 {AUTH_AES_CMAC_96, PRF_AES128_CMAC },
652 };
653
654 /**
655 * Remove all entries of the given transform type
656 */
657 static void remove_transform(private_proposal_t *this, transform_type_t type)
658 {
659 enumerator_t *e;
660 entry_t *entry;
661
662 e = array_create_enumerator(this->transforms);
663 while (e->enumerate(e, &entry))
664 {
665 if (entry->type == type)
666 {
667 array_remove_at(this->transforms, e);
668 }
669 }
670 e->destroy(e);
671 remove_type(this, type);
672 }
673
674 /**
675 * Checks the proposal read from a string.
676 */
677 static bool check_proposal(private_proposal_t *this)
678 {
679 enumerator_t *e;
680 entry_t *entry;
681 uint16_t alg, ks;
682 bool all_aead = TRUE, any_aead = FALSE, any_enc = FALSE;
683 int i;
684
685 if (this->protocol == PROTO_IKE)
686 {
687 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION, NULL, NULL))
688 { /* No explicit PRF found. We assume the same algorithm as used
689 * for integrity checking. */
690 e = create_enumerator(this, INTEGRITY_ALGORITHM);
691 while (e->enumerate(e, &alg, &ks))
692 {
693 for (i = 0; i < countof(integ_prf_map); i++)
694 {
695 if (alg == integ_prf_map[i].integ)
696 {
697 add_algorithm(this, PSEUDO_RANDOM_FUNCTION,
698 integ_prf_map[i].prf, 0);
699 break;
700 }
701 }
702 }
703 e->destroy(e);
704 }
705 if (!get_algorithm(this, PSEUDO_RANDOM_FUNCTION, NULL, NULL))
706 {
707 DBG1(DBG_CFG, "a PRF algorithm is mandatory in IKE proposals");
708 return FALSE;
709 }
710 /* remove MODP_NONE from IKE proposal */
711 e = array_create_enumerator(this->transforms);
712 while (e->enumerate(e, &entry))
713 {
714 if (entry->type == DIFFIE_HELLMAN_GROUP && !entry->alg)
715 {
716 array_remove_at(this->transforms, e);
717 }
718 }
719 e->destroy(e);
720 if (!get_algorithm(this, DIFFIE_HELLMAN_GROUP, NULL, NULL))
721 {
722 DBG1(DBG_CFG, "a DH group is mandatory in IKE proposals");
723 return FALSE;
724 }
725 }
726 else
727 { /* remove PRFs from ESP/AH proposals */
728 remove_transform(this, PSEUDO_RANDOM_FUNCTION);
729 }
730
731 if (this->protocol == PROTO_IKE || this->protocol == PROTO_ESP)
732 {
733 e = create_enumerator(this, ENCRYPTION_ALGORITHM);
734 while (e->enumerate(e, &alg, &ks))
735 {
736 any_enc = TRUE;
737 if (encryption_algorithm_is_aead(alg))
738 {
739 any_aead = TRUE;
740 continue;
741 }
742 all_aead = FALSE;
743 }
744 e->destroy(e);
745
746 if (!any_enc)
747 {
748 DBG1(DBG_CFG, "an encryption algorithm is mandatory in %N proposals",
749 protocol_id_names, this->protocol);
750 return FALSE;
751 }
752 else if (any_aead && !all_aead)
753 {
754 DBG1(DBG_CFG, "classic and combined-mode (AEAD) encryption "
755 "algorithms can't be contained in the same %N proposal",
756 protocol_id_names, this->protocol);
757 return FALSE;
758 }
759 else if (all_aead)
760 { /* if all encryption algorithms in the proposal are AEADs,
761 * we MUST NOT propose any integrity algorithms */
762 remove_transform(this, INTEGRITY_ALGORITHM);
763 }
764 else if (this->protocol == PROTO_IKE &&
765 !get_algorithm(this, INTEGRITY_ALGORITHM, NULL, NULL))
766 {
767 DBG1(DBG_CFG, "an integrity algorithm is mandatory in %N proposals "
768 "with classic (non-AEAD) encryption algorithms",
769 protocol_id_names, this->protocol);
770 return FALSE;
771 }
772 }
773 else
774 { /* AES-GMAC is parsed as encryption algorithm, so we map that to the
775 * proper integrity algorithm */
776 e = array_create_enumerator(this->transforms);
777 while (e->enumerate(e, &entry))
778 {
779 if (entry->type == ENCRYPTION_ALGORITHM)
780 {
781 if (entry->alg == ENCR_NULL_AUTH_AES_GMAC)
782 {
783 entry->type = INTEGRITY_ALGORITHM;
784 ks = entry->key_size;
785 entry->key_size = 0;
786 switch (ks)
787 {
788 case 128:
789 entry->alg = AUTH_AES_128_GMAC;
790 continue;
791 case 192:
792 entry->alg = AUTH_AES_192_GMAC;
793 continue;
794 case 256:
795 entry->alg = AUTH_AES_256_GMAC;
796 continue;
797 default:
798 break;
799 }
800 }
801 /* remove all other encryption algorithms */
802 array_remove_at(this->transforms, e);
803 }
804 }
805 e->destroy(e);
806 remove_type(this, ENCRYPTION_ALGORITHM);
807
808 if (!get_algorithm(this, INTEGRITY_ALGORITHM, NULL, NULL))
809 {
810 DBG1(DBG_CFG, "an integrity algorithm is mandatory in AH "
811 "proposals");
812 return FALSE;
813 }
814 }
815
816 if (this->protocol == PROTO_AH || this->protocol == PROTO_ESP)
817 {
818 if (!get_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NULL, NULL))
819 { /* ESN not specified, assume not supported */
820 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
821 }
822 }
823
824 array_compress(this->transforms);
825 array_compress(this->types);
826 return TRUE;
827 }
828
829 /**
830 * add a algorithm identified by a string to the proposal.
831 */
832 static bool add_string_algo(private_proposal_t *this, const char *alg)
833 {
834 const proposal_token_t *token;
835
836 token = lib->proposal->get_token(lib->proposal, alg);
837 if (token == NULL)
838 {
839 DBG1(DBG_CFG, "algorithm '%s' not recognized", alg);
840 return FALSE;
841 }
842
843 add_algorithm(this, token->type, token->algorithm, token->keysize);
844
845 return TRUE;
846 }
847
848 /**
849 * Print all algorithms of the given type
850 */
851 static int print_alg(private_proposal_t *this, printf_hook_data_t *data,
852 transform_type_t type, bool *first)
853 {
854 enumerator_t *enumerator;
855 size_t written = 0;
856 entry_t *entry;
857 enum_name_t *names;
858
859 names = transform_get_enum_names(type);
860
861 enumerator = array_create_enumerator(this->transforms);
862 while (enumerator->enumerate(enumerator, &entry))
863 {
864 char *prefix = "/";
865
866 if (type != entry->type)
867 {
868 continue;
869 }
870 if (*first)
871 {
872 prefix = "";
873 *first = FALSE;
874 }
875 if (names)
876 {
877 written += print_in_hook(data, "%s%N", prefix, names, entry->alg);
878 }
879 else
880 {
881 written += print_in_hook(data, "%sUNKNOWN_%u_%u", prefix,
882 entry->type, entry->alg);
883 }
884 if (entry->key_size)
885 {
886 written += print_in_hook(data, "_%u", entry->key_size);
887 }
888 }
889 enumerator->destroy(enumerator);
890 return written;
891 }
892
893 /**
894 * Described in header.
895 */
896 int proposal_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
897 const void *const *args)
898 {
899 private_proposal_t *this = *((private_proposal_t**)(args[0]));
900 linked_list_t *list = *((linked_list_t**)(args[0]));
901 enumerator_t *enumerator;
902 transform_type_t *type;
903 size_t written = 0;
904 bool first = TRUE;
905
906 if (this == NULL)
907 {
908 return print_in_hook(data, "(null)");
909 }
910
911 if (spec->hash)
912 {
913 enumerator = list->create_enumerator(list);
914 while (enumerator->enumerate(enumerator, &this))
915 { /* call recursively */
916 if (first)
917 {
918 written += print_in_hook(data, "%P", this);
919 first = FALSE;
920 }
921 else
922 {
923 written += print_in_hook(data, ", %P", this);
924 }
925 }
926 enumerator->destroy(enumerator);
927 return written;
928 }
929
930 written = print_in_hook(data, "%N:", protocol_id_names, this->protocol);
931 enumerator = array_create_enumerator(this->types);
932 while (enumerator->enumerate(enumerator, &type))
933 {
934 written += print_alg(this, data, *type, &first);
935 }
936 enumerator->destroy(enumerator);
937 return written;
938 }
939
940 METHOD(proposal_t, destroy, void,
941 private_proposal_t *this)
942 {
943 array_destroy(this->transforms);
944 array_destroy(this->types);
945 free(this);
946 }
947
948 /*
949 * Described in header
950 */
951 proposal_t *proposal_create(protocol_id_t protocol, u_int number)
952 {
953 private_proposal_t *this;
954
955 INIT(this,
956 .public = {
957 .add_algorithm = _add_algorithm,
958 .create_enumerator = _create_enumerator,
959 .get_algorithm = _get_algorithm,
960 .has_dh_group = _has_dh_group,
961 .promote_dh_group = _promote_dh_group,
962 .strip_dh = _strip_dh,
963 .select = _select_proposal,
964 .matches = _matches,
965 .get_protocol = _get_protocol,
966 .set_spi = _set_spi,
967 .get_spi = _get_spi,
968 .get_number = _get_number,
969 .equals = _equals,
970 .clone = _clone_,
971 .destroy = _destroy,
972 },
973 .protocol = protocol,
974 .number = number,
975 .transforms = array_create(sizeof(entry_t), 0),
976 .types = array_create(sizeof(transform_type_t), 0),
977 );
978
979 return &this->public;
980 }
981
982 /**
983 * Add supported IKE algorithms to proposal
984 */
985 static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
986 {
987 enumerator_t *enumerator;
988 encryption_algorithm_t encryption;
989 integrity_algorithm_t integrity;
990 pseudo_random_function_t prf;
991 diffie_hellman_group_t group;
992 const char *plugin_name;
993
994 if (aead)
995 {
996 /* Round 1 adds algorithms with at least 128 bit security strength */
997 enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
998 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
999 {
1000 switch (encryption)
1001 {
1002 case ENCR_AES_GCM_ICV16:
1003 case ENCR_AES_CCM_ICV16:
1004 case ENCR_CAMELLIA_CCM_ICV16:
1005 /* we assume that we support all AES/Camellia sizes */
1006 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
1007 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
1008 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
1009 break;
1010 case ENCR_CHACHA20_POLY1305:
1011 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0);
1012 break;
1013 default:
1014 break;
1015 }
1016 }
1017 enumerator->destroy(enumerator);
1018
1019 /* Round 2 adds algorithms with less than 128 bit security strength */
1020 enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
1021 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
1022 {
1023 switch (encryption)
1024 {
1025 case ENCR_AES_GCM_ICV12:
1026 case ENCR_AES_GCM_ICV8:
1027 case ENCR_AES_CCM_ICV12:
1028 case ENCR_AES_CCM_ICV8:
1029 case ENCR_CAMELLIA_CCM_ICV12:
1030 case ENCR_CAMELLIA_CCM_ICV8:
1031 /* we assume that we support all AES/Camellia sizes */
1032 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
1033 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
1034 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
1035 break;
1036 default:
1037 break;
1038 }
1039 }
1040 enumerator->destroy(enumerator);
1041
1042 if (!array_count(this->transforms))
1043 {
1044 return FALSE;
1045 }
1046 }
1047 else
1048 {
1049 /* Round 1 adds algorithms with at least 128 bit security strength */
1050 enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
1051 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
1052 {
1053 switch (encryption)
1054 {
1055 case ENCR_AES_CBC:
1056 case ENCR_AES_CTR:
1057 case ENCR_CAMELLIA_CBC:
1058 case ENCR_CAMELLIA_CTR:
1059 /* we assume that we support all AES/Camellia sizes */
1060 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
1061 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
1062 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
1063 break;
1064 default:
1065 break;
1066 }
1067 }
1068 enumerator->destroy(enumerator);
1069
1070 /* Round 2 adds algorithms with less than 128 bit security strength */
1071 enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
1072 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
1073 {
1074 switch (encryption)
1075 {
1076 case ENCR_3DES:
1077 add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0);
1078 break;
1079 case ENCR_DES:
1080 /* no, thanks */
1081 break;
1082 default:
1083 break;
1084 }
1085 }
1086 enumerator->destroy(enumerator);
1087
1088 if (!array_count(this->transforms))
1089 {
1090 return FALSE;
1091 }
1092
1093 /* Round 1 adds algorithms with at least 128 bit security strength */
1094 enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
1095 while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
1096 {
1097 switch (integrity)
1098 {
1099 case AUTH_HMAC_SHA2_256_128:
1100 case AUTH_HMAC_SHA2_384_192:
1101 case AUTH_HMAC_SHA2_512_256:
1102 add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0);
1103 break;
1104 default:
1105 break;
1106 }
1107 }
1108 enumerator->destroy(enumerator);
1109
1110 /* Round 2 adds algorithms with less than 128 bit security strength */
1111 enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
1112 while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
1113 {
1114 switch (integrity)
1115 {
1116 case AUTH_AES_XCBC_96:
1117 case AUTH_AES_CMAC_96:
1118 case AUTH_HMAC_SHA1_96:
1119 add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0);
1120 break;
1121 case AUTH_HMAC_MD5_96:
1122 /* no, thanks */
1123 default:
1124 break;
1125 }
1126 }
1127 enumerator->destroy(enumerator);
1128 }
1129
1130 /* Round 1 adds algorithms with at least 128 bit security strength */
1131 enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
1132 while (enumerator->enumerate(enumerator, &prf, &plugin_name))
1133 {
1134 switch (prf)
1135 {
1136 case PRF_HMAC_SHA2_256:
1137 case PRF_HMAC_SHA2_384:
1138 case PRF_HMAC_SHA2_512:
1139 case PRF_AES128_XCBC:
1140 case PRF_AES128_CMAC:
1141 add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
1142 break;
1143 default:
1144 break;
1145 }
1146 }
1147 enumerator->destroy(enumerator);
1148
1149 /* Round 2 adds algorithms with less than 128 bit security strength */
1150 enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
1151 while (enumerator->enumerate(enumerator, &prf, &plugin_name))
1152 {
1153 switch (prf)
1154 {
1155 case PRF_HMAC_SHA1:
1156 add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
1157 break;
1158 case PRF_HMAC_MD5:
1159 /* no, thanks */
1160 break;
1161 default:
1162 break;
1163 }
1164 }
1165 enumerator->destroy(enumerator);
1166
1167 /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */
1168 enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
1169 while (enumerator->enumerate(enumerator, &group, &plugin_name))
1170 {
1171 switch (group)
1172 {
1173 case ECP_256_BIT:
1174 case ECP_384_BIT:
1175 case ECP_521_BIT:
1176 case ECP_256_BP:
1177 case ECP_384_BP:
1178 case ECP_512_BP:
1179 case CURVE_25519:
1180 case CURVE_448:
1181 case NTRU_128_BIT:
1182 case NTRU_192_BIT:
1183 case NTRU_256_BIT:
1184 case NH_128_BIT:
1185 add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0);
1186 break;
1187 default:
1188 break;
1189 }
1190 }
1191 enumerator->destroy(enumerator);
1192
1193 /* Round 2 adds other algorithms with at least 128 bit security strength */
1194 enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
1195 while (enumerator->enumerate(enumerator, &group, &plugin_name))
1196 {
1197 switch (group)
1198 {
1199 case MODP_3072_BIT:
1200 case MODP_4096_BIT:
1201 case MODP_6144_BIT:
1202 case MODP_8192_BIT:
1203 add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0);
1204 break;
1205 default:
1206 break;
1207 }
1208 }
1209 enumerator->destroy(enumerator);
1210
1211 /* Round 3 adds algorithms with less than 128 bit security strength */
1212 enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
1213 while (enumerator->enumerate(enumerator, &group, &plugin_name))
1214 {
1215 switch (group)
1216 {
1217 case MODP_NULL:
1218 /* only for testing purposes */
1219 break;
1220 case MODP_768_BIT:
1221 case MODP_1024_BIT:
1222 case MODP_1536_BIT:
1223 /* weak */
1224 break;
1225 case MODP_1024_160:
1226 case MODP_2048_224:
1227 case MODP_2048_256:
1228 /* RFC 5114 primes are of questionable source */
1229 break;
1230 case ECP_224_BIT:
1231 case ECP_224_BP:
1232 case ECP_192_BIT:
1233 case NTRU_112_BIT:
1234 /* rarely used */
1235 break;
1236 case MODP_2048_BIT:
1237 add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0);
1238 break;
1239 default:
1240 break;
1241 }
1242 }
1243 enumerator->destroy(enumerator);
1244
1245 return TRUE;
1246 }
1247
1248 /*
1249 * Described in header
1250 */
1251 proposal_t *proposal_create_default(protocol_id_t protocol)
1252 {
1253 private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
1254
1255 switch (protocol)
1256 {
1257 case PROTO_IKE:
1258 if (!proposal_add_supported_ike(this, FALSE))
1259 {
1260 destroy(this);
1261 return NULL;
1262 }
1263 break;
1264 case PROTO_ESP:
1265 add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128);
1266 add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192);
1267 add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
1268 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
1269 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
1270 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
1271 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
1272 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
1273 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
1274 break;
1275 case PROTO_AH:
1276 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
1277 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
1278 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
1279 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
1280 add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
1281 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
1282 break;
1283 default:
1284 break;
1285 }
1286 return &this->public;
1287 }
1288
1289 /*
1290 * Described in header
1291 */
1292 proposal_t *proposal_create_default_aead(protocol_id_t protocol)
1293 {
1294 private_proposal_t *this;
1295
1296 switch (protocol)
1297 {
1298 case PROTO_IKE:
1299 this = (private_proposal_t*)proposal_create(protocol, 0);
1300 if (!proposal_add_supported_ike(this, TRUE))
1301 {
1302 destroy(this);
1303 return NULL;
1304 }
1305 return &this->public;
1306 case PROTO_ESP:
1307 /* we currently don't include any AEAD proposal for ESP, as we
1308 * don't know if our kernel backend actually supports it. */
1309 return NULL;
1310 case PROTO_AH:
1311 default:
1312 return NULL;
1313 }
1314 }
1315
1316 /*
1317 * Described in header
1318 */
1319 proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs)
1320 {
1321 private_proposal_t *this;
1322 enumerator_t *enumerator;
1323 bool failed = TRUE;
1324 char *alg;
1325
1326 this = (private_proposal_t*)proposal_create(protocol, 0);
1327
1328 /* get all tokens, separated by '-' */
1329 enumerator = enumerator_create_token(algs, "-", " ");
1330 while (enumerator->enumerate(enumerator, &alg))
1331 {
1332 if (!add_string_algo(this, alg))
1333 {
1334 failed = TRUE;
1335 break;
1336 }
1337 failed = FALSE;
1338 }
1339 enumerator->destroy(enumerator);
1340
1341 if (failed || !check_proposal(this))
1342 {
1343 destroy(this);
1344 return NULL;
1345 }
1346
1347 return &this->public;
1348 }
1349
1350 /*
1351 * Described in header
1352 */
1353 proposal_t *proposal_select(linked_list_t *configured, linked_list_t *supplied,
1354 proposal_selection_flag_t flags)
1355 {
1356 enumerator_t *prefer_enum, *match_enum;
1357 proposal_t *proposal, *match, *selected = NULL;
1358
1359 if (flags & PROPOSAL_PREFER_SUPPLIED)
1360 {
1361 prefer_enum = supplied->create_enumerator(supplied);
1362 match_enum = configured->create_enumerator(configured);
1363 }
1364 else
1365 {
1366 prefer_enum = configured->create_enumerator(configured);
1367 match_enum = supplied->create_enumerator(supplied);
1368 }
1369
1370 while (prefer_enum->enumerate(prefer_enum, &proposal))
1371 {
1372 if (flags & PROPOSAL_PREFER_SUPPLIED)
1373 {
1374 configured->reset_enumerator(configured, match_enum);
1375 }
1376 else
1377 {
1378 supplied->reset_enumerator(supplied, match_enum);
1379 }
1380 while (match_enum->enumerate(match_enum, &match))
1381 {
1382 selected = proposal->select(proposal, match, flags);
1383 if (selected)
1384 {
1385 DBG2(DBG_CFG, "received proposals: %#P", supplied);
1386 DBG2(DBG_CFG, "configured proposals: %#P", configured);
1387 DBG1(DBG_CFG, "selected proposal: %P", selected);
1388 break;
1389 }
1390 }
1391 if (selected)
1392 {
1393 break;
1394 }
1395 }
1396 prefer_enum->destroy(prefer_enum);
1397 match_enum->destroy(match_enum);
1398 if (!selected)
1399 {
1400 DBG1(DBG_CFG, "received proposals: %#P", supplied);
1401 DBG1(DBG_CFG, "configured proposals: %#P", configured);
1402 }
1403 return selected;
1404 }