]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/algorithm.c
9ed1ef9e0bd9563e0a3a4b18ecf1bab549ec15f3
[apple/ipsec.git] / ipsec-tools / racoon / algorithm.c
1 /* $Id: algorithm.c,v 1.11.4.1 2005/06/28 22:38:02 manubsd Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "config.h"
33
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <stdlib.h>
37
38 #include "var.h"
39 #include "misc.h"
40 #include "vmbuf.h"
41 #include "plog.h"
42 #include "debug.h"
43
44 #include "crypto_openssl.h"
45 #include "dhgroup.h"
46 #include "algorithm.h"
47 #include "oakley.h"
48 #include "isakmp_var.h"
49 #include "isakmp.h"
50 #include "ipsec_doi.h"
51 #include "gcmalloc.h"
52
53 static struct hash_algorithm oakley_hashdef[] = {
54 { "md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5,
55 eay_md5_init, eay_md5_update,
56 eay_md5_final, eay_md5_hashlen,
57 eay_md5_one, },
58 { "sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA,
59 eay_sha1_init, eay_sha1_update,
60 eay_sha1_final, eay_sha1_hashlen,
61 eay_sha1_one, },
62 #ifdef WITH_SHA2
63 { "sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256,
64 eay_sha2_256_init, eay_sha2_256_update,
65 eay_sha2_256_final, eay_sha2_256_hashlen,
66 eay_sha2_256_one, },
67 { "sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384,
68 eay_sha2_384_init, eay_sha2_384_update,
69 eay_sha2_384_final, eay_sha2_384_hashlen,
70 eay_sha2_384_one, },
71 { "sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512,
72 eay_sha2_512_init, eay_sha2_512_update,
73 eay_sha2_512_final, eay_sha2_512_hashlen,
74 eay_sha2_512_one, },
75 #endif
76 };
77
78 static struct hmac_algorithm oakley_hmacdef[] = {
79 { "hmac_md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5,
80 eay_hmacmd5_init, eay_hmacmd5_update,
81 eay_hmacmd5_final, NULL,
82 eay_hmacmd5_one, },
83 { "hmac_sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA,
84 eay_hmacsha1_init, eay_hmacsha1_update,
85 eay_hmacsha1_final, NULL,
86 eay_hmacsha1_one, },
87 #ifdef WITH_SHA2
88 { "hmac_sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256,
89 eay_hmacsha2_256_init, eay_hmacsha2_256_update,
90 eay_hmacsha2_256_final, NULL,
91 eay_hmacsha2_256_one, },
92 { "hmac_sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384,
93 eay_hmacsha2_384_init, eay_hmacsha2_384_update,
94 eay_hmacsha2_384_final, NULL,
95 eay_hmacsha2_384_one, },
96 { "hmac_sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512,
97 eay_hmacsha2_512_init, eay_hmacsha2_512_update,
98 eay_hmacsha2_512_final, NULL,
99 eay_hmacsha2_512_one, },
100 #endif
101 };
102
103 static struct enc_algorithm oakley_encdef[] = {
104 { "des", algtype_des, OAKLEY_ATTR_ENC_ALG_DES, 8,
105 eay_des_encrypt, eay_des_decrypt,
106 eay_des_weakkey, eay_des_keylen, },
107 { "3des", algtype_3des, OAKLEY_ATTR_ENC_ALG_3DES, 8,
108 eay_3des_encrypt, eay_3des_decrypt,
109 eay_3des_weakkey, eay_3des_keylen, },
110 { "aes", algtype_aes, OAKLEY_ATTR_ENC_ALG_AES, 16,
111 eay_aes_encrypt, eay_aes_decrypt,
112 eay_aes_weakkey, eay_aes_keylen, },
113 };
114
115 static struct enc_algorithm ipsec_encdef[] = {
116 { "des-iv64", algtype_des_iv64, IPSECDOI_ESP_DES_IV64, 8,
117 NULL, NULL,
118 NULL, eay_des_keylen, },
119 { "des", algtype_des, IPSECDOI_ESP_DES, 8,
120 NULL, NULL,
121 NULL, eay_des_keylen, },
122 { "3des", algtype_3des, IPSECDOI_ESP_3DES, 8,
123 NULL, NULL,
124 NULL, eay_3des_keylen, },
125 { "des-iv32", algtype_des_iv32, IPSECDOI_ESP_DES_IV32, 8,
126 NULL, NULL,
127 NULL, eay_des_keylen, },
128 { "null", algtype_null_enc, IPSECDOI_ESP_NULL, 8,
129 NULL, NULL,
130 NULL, eay_null_keylen, },
131 { "aes", algtype_aes, IPSECDOI_ESP_AES, 16,
132 NULL, NULL,
133 NULL, eay_aes_keylen, },
134 };
135
136 static struct hmac_algorithm ipsec_hmacdef[] = {
137 { "md5", algtype_hmac_md5, IPSECDOI_ATTR_AUTH_HMAC_MD5,
138 NULL, NULL,
139 NULL, eay_md5_hashlen,
140 NULL, },
141 { "sha1", algtype_hmac_sha1, IPSECDOI_ATTR_AUTH_HMAC_SHA1,
142 NULL, NULL,
143 NULL, eay_sha1_hashlen,
144 NULL, },
145 { "null", algtype_non_auth, IPSECDOI_ATTR_AUTH_NONE,
146 NULL, NULL,
147 NULL, eay_null_hashlen,
148 NULL, },
149 #ifdef WITH_SHA2
150 { "hmac_sha2_256", algtype_hmac_sha2_256,IPSECDOI_ATTR_AUTH_HMAC_SHA2_256,
151 NULL, NULL,
152 NULL, eay_sha2_256_hashlen,
153 NULL, },
154 { "hmac_sha2_384", algtype_hmac_sha2_384,IPSECDOI_ATTR_AUTH_HMAC_SHA2_384,
155 NULL, NULL,
156 NULL, eay_sha2_384_hashlen,
157 NULL, },
158 { "hmac_sha2_512", algtype_hmac_sha2_512,IPSECDOI_ATTR_AUTH_HMAC_SHA2_512,
159 NULL, NULL,
160 NULL, eay_sha2_512_hashlen,
161 NULL, },
162 #endif
163 };
164
165 static struct misc_algorithm ipsec_compdef[] = {
166 { "oui", algtype_oui, IPSECDOI_IPCOMP_OUI, },
167 { "deflate", algtype_deflate, IPSECDOI_IPCOMP_DEFLATE, },
168 { "lzs", algtype_lzs, IPSECDOI_IPCOMP_LZS, },
169 };
170
171 /*
172 * In case of asymetric modes (hybrid xauth), what's racoon mode of
173 * operations ; it seems that the proposal should always use the
174 * initiator half (unless a server initiates a connection, which is
175 * not handled, and probably not useful).
176 */
177 static struct misc_algorithm oakley_authdef[] = {
178 { "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, },
179 { "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, },
180 { "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, },
181 { "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, },
182 { "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, },
183
184 { "gssapi_krb", algtype_gssapikrb,
185 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, },
186
187 #ifdef ENABLE_HYBRID
188 { "hybrid_rsa_server", algtype_hybrid_rsa_s,
189 OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, },
190
191 { "hybrid_dss_server", algtype_hybrid_dss_s,
192 OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, },
193
194 { "xauth_psk_server", algtype_xauth_psk_s,
195 OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, },
196
197 { "xauth_rsa_server", algtype_xauth_rsa_s,
198 OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, },
199
200 { "hybrid_rsa_client", algtype_hybrid_rsa_c,
201 OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, },
202
203 { "hybrid_dss_client", algtype_hybrid_dss_c,
204 OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, },
205
206 { "xauth_psk_client", algtype_xauth_psk_c,
207 OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, },
208
209 { "xauth_rsa_client", algtype_xauth_rsa_c,
210 OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, },
211 #endif
212 };
213
214 static struct dh_algorithm oakley_dhdef[] = {
215 { "modp768", algtype_modp768, OAKLEY_ATTR_GRP_DESC_MODP768,
216 &dh_modp768, },
217 { "modp1024", algtype_modp1024, OAKLEY_ATTR_GRP_DESC_MODP1024,
218 &dh_modp1024, },
219 { "modp1536", algtype_modp1536, OAKLEY_ATTR_GRP_DESC_MODP1536,
220 &dh_modp1536, },
221 { "modp2048", algtype_modp2048, OAKLEY_ATTR_GRP_DESC_MODP2048,
222 &dh_modp2048, },
223 { "modp3072", algtype_modp3072, OAKLEY_ATTR_GRP_DESC_MODP3072,
224 &dh_modp3072, },
225 { "modp4096", algtype_modp4096, OAKLEY_ATTR_GRP_DESC_MODP4096,
226 &dh_modp4096, },
227 { "modp6144", algtype_modp6144, OAKLEY_ATTR_GRP_DESC_MODP6144,
228 &dh_modp6144, },
229 { "modp8192", algtype_modp8192, OAKLEY_ATTR_GRP_DESC_MODP8192,
230 &dh_modp8192, },
231 };
232
233 static struct hash_algorithm *alg_oakley_hashdef __P((int));
234 static struct hmac_algorithm *alg_oakley_hmacdef __P((int));
235 static struct enc_algorithm *alg_oakley_encdef __P((int));
236 static struct enc_algorithm *alg_ipsec_encdef __P((int));
237 static struct hmac_algorithm *alg_ipsec_hmacdef __P((int));
238 static struct dh_algorithm *alg_oakley_dhdef __P((int));
239
240 /* oakley hash algorithm */
241 static struct hash_algorithm *
242 alg_oakley_hashdef(doi)
243 int doi;
244 {
245 int i;
246
247 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
248 if (doi == oakley_hashdef[i].doi) {
249 plog(LLV_DEBUG, LOCATION, NULL, "hash(%s)\n",
250 oakley_hashdef[i].name);
251 return &oakley_hashdef[i];
252 }
253 return NULL;
254 }
255
256 int
257 alg_oakley_hashdef_ok(doi)
258 int doi;
259 {
260 struct hash_algorithm *f;
261
262 f = alg_oakley_hashdef(doi);
263 if (f == NULL)
264 return 0;
265
266 return 1;
267 }
268
269 int
270 alg_oakley_hashdef_doi(type)
271 int type;
272 {
273 int i, res = -1;
274
275 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
276 if (type == oakley_hashdef[i].type) {
277 res = oakley_hashdef[i].doi;
278 break;
279 }
280 return res;
281 }
282
283 int
284 alg_oakley_hashdef_hashlen(doi)
285 int doi;
286 {
287 struct hash_algorithm *f;
288
289 f = alg_oakley_hashdef(doi);
290 if (f == NULL || f->hashlen == NULL)
291 return 0;
292
293 return (f->hashlen)();
294 }
295
296 const char *
297 alg_oakley_hashdef_name (doi)
298 int doi;
299 {
300 struct hash_algorithm *f;
301
302 f = alg_oakley_hashdef(doi);
303 if (f == NULL)
304 return "*UNKNOWN*";
305
306 return f->name;
307 }
308
309 vchar_t *
310 alg_oakley_hashdef_one(doi, buf)
311 int doi;
312 vchar_t *buf;
313 {
314 struct hash_algorithm *f;
315
316 f = alg_oakley_hashdef(doi);
317 if (f == NULL || f->hashlen == NULL)
318 return NULL;
319
320 return (f->one)(buf);
321 }
322
323 /* oakley hmac algorithm */
324 static struct hmac_algorithm *
325 alg_oakley_hmacdef(doi)
326 int doi;
327 {
328 int i;
329
330 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
331 if (doi == oakley_hmacdef[i].doi) {
332 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
333 oakley_hmacdef[i].name);
334 return &oakley_hmacdef[i];
335 }
336 return NULL;
337 }
338
339 int
340 alg_oakley_hmacdef_doi(type)
341 int type;
342 {
343 int i, res = -1;
344
345 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
346 if (type == oakley_hmacdef[i].type) {
347 res = oakley_hmacdef[i].doi;
348 break;
349 }
350 return res;
351 }
352
353 vchar_t *
354 alg_oakley_hmacdef_one(doi, key, buf)
355 int doi;
356 vchar_t *key, *buf;
357 {
358 struct hmac_algorithm *f;
359 vchar_t *res;
360 #ifdef ENABLE_STATS
361 struct timeval start, end;
362 #endif
363
364 f = alg_oakley_hmacdef(doi);
365 if (f == NULL || f->one == NULL)
366 return NULL;
367
368 #ifdef ENABLE_STATS
369 gettimeofday(&start, NULL);
370 #endif
371
372 res = (f->one)(key, buf);
373
374 #ifdef ENABLE_STATS
375 gettimeofday(&end, NULL);
376 syslog(LOG_NOTICE, "%s(%s size=%zu): %8.6f", __func__,
377 f->name, buf->l, timedelta(&start, &end));
378 #endif
379
380 return res;
381 }
382
383 /* oakley encryption algorithm */
384 static struct enc_algorithm *
385 alg_oakley_encdef(doi)
386 int doi;
387 {
388 int i;
389
390 for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
391 if (doi == oakley_encdef[i].doi) {
392 plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
393 oakley_encdef[i].name);
394 return &oakley_encdef[i];
395 }
396 return NULL;
397 }
398
399 int
400 alg_oakley_encdef_ok(doi)
401 int doi;
402 {
403 struct enc_algorithm *f;
404
405 f = alg_oakley_encdef(doi);
406 if (f == NULL)
407 return 0;
408
409 return 1;
410 }
411
412 int
413 alg_oakley_encdef_doi(type)
414 int type;
415 {
416 int i, res = -1;
417
418 for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
419 if (type == oakley_encdef[i].type) {
420 res = oakley_encdef[i].doi;
421 break;
422 }
423 return res;
424 }
425
426 int
427 alg_oakley_encdef_keylen(doi, len)
428 int doi, len;
429 {
430 struct enc_algorithm *f;
431
432 f = alg_oakley_encdef(doi);
433 if (f == NULL || f->keylen == NULL)
434 return -1;
435
436 return (f->keylen)(len);
437 }
438
439 int
440 alg_oakley_encdef_blocklen(doi)
441 int doi;
442 {
443 struct enc_algorithm *f;
444
445 f = alg_oakley_encdef(doi);
446 if (f == NULL)
447 return -1;
448
449 return f->blocklen;
450 }
451
452 const char *
453 alg_oakley_encdef_name (doi)
454 int doi;
455 {
456 struct enc_algorithm *f;
457
458 f = alg_oakley_encdef(doi);
459 if (f == NULL)
460 return "*UNKNOWN*";
461
462 return f->name;
463 }
464
465 vchar_t *
466 alg_oakley_encdef_decrypt(doi, buf, key, iv)
467 int doi;
468 vchar_t *buf, *key, *iv;
469 {
470 vchar_t *res;
471 struct enc_algorithm *f;
472 #ifdef ENABLE_STATS
473 struct timeval start, end;
474 #endif
475
476 f = alg_oakley_encdef(doi);
477 if (f == NULL || f->decrypt == NULL)
478 return NULL;
479
480 #ifdef ENABLE_STATS
481 gettimeofday(&start, NULL);
482 #endif
483
484 res = (f->decrypt)(buf, key, iv);
485
486 #ifdef ENABLE_STATS
487 gettimeofday(&end, NULL);
488 syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__,
489 f->name, key->l << 3, buf->l, timedelta(&start, &end));
490 #endif
491 return res;
492 }
493
494 vchar_t *
495 alg_oakley_encdef_encrypt(doi, buf, key, iv)
496 int doi;
497 vchar_t *buf, *key, *iv;
498 {
499 vchar_t *res;
500 struct enc_algorithm *f;
501 #ifdef ENABLE_STATS
502 struct timeval start, end;
503 #endif
504
505 f = alg_oakley_encdef(doi);
506 if (f == NULL || f->encrypt == NULL)
507 return NULL;
508
509 #ifdef ENABLE_STATS
510 gettimeofday(&start, NULL);
511 #endif
512
513 res = (f->encrypt)(buf, key, iv);
514
515 #ifdef ENABLE_STATS
516 gettimeofday(&end, NULL);
517 syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__,
518 f->name, key->l << 3, buf->l, timedelta(&start, &end));
519 #endif
520 return res;
521 }
522
523 /* ipsec encryption algorithm */
524 static struct enc_algorithm *
525 alg_ipsec_encdef(doi)
526 int doi;
527 {
528 int i;
529
530 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
531 if (doi == ipsec_encdef[i].doi) {
532 plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
533 ipsec_encdef[i].name);
534 return &ipsec_encdef[i];
535 }
536 return NULL;
537 }
538
539 int
540 alg_ipsec_encdef_doi(type)
541 int type;
542 {
543 int i, res = -1;
544
545 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
546 if (type == ipsec_encdef[i].type) {
547 res = ipsec_encdef[i].doi;
548 break;
549 }
550 return res;
551 }
552
553 int
554 alg_ipsec_encdef_keylen(doi, len)
555 int doi, len;
556 {
557 struct enc_algorithm *f;
558
559 f = alg_ipsec_encdef(doi);
560 if (f == NULL || f->keylen == NULL)
561 return -1;
562
563 return (f->keylen)(len);
564 }
565
566 /* ipsec hmac algorithm */
567 static struct hmac_algorithm *
568 alg_ipsec_hmacdef(doi)
569 int doi;
570 {
571 int i;
572
573 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
574 if (doi == ipsec_hmacdef[i].doi) {
575 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
576 ipsec_hmacdef[i].name);
577 return &ipsec_hmacdef[i];
578 }
579 return NULL;
580 }
581
582 int
583 alg_ipsec_hmacdef_doi(type)
584 int type;
585 {
586 int i, res = -1;
587
588 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
589 if (type == ipsec_hmacdef[i].type) {
590 res = ipsec_hmacdef[i].doi;
591 break;
592 }
593 return res;
594 }
595
596 int
597 alg_ipsec_hmacdef_hashlen(doi)
598 int doi;
599 {
600 struct hmac_algorithm *f;
601
602 f = alg_ipsec_hmacdef(doi);
603 if (f == NULL || f->hashlen == NULL)
604 return -1;
605
606 return (f->hashlen)();
607 }
608
609 /* ip compression */
610 int
611 alg_ipsec_compdef_doi(type)
612 int type;
613 {
614 int i, res = -1;
615
616 for (i = 0; i < ARRAYLEN(ipsec_compdef); i++)
617 if (type == ipsec_compdef[i].type) {
618 res = ipsec_compdef[i].doi;
619 break;
620 }
621 return res;
622 }
623
624 /* dh algorithm */
625 static struct dh_algorithm *
626 alg_oakley_dhdef(doi)
627 int doi;
628 {
629 int i;
630
631 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
632 if (doi == oakley_dhdef[i].doi) {
633 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
634 oakley_dhdef[i].name);
635 return &oakley_dhdef[i];
636 }
637 return NULL;
638 }
639
640 int
641 alg_oakley_dhdef_ok(doi)
642 int doi;
643 {
644 struct dh_algorithm *f;
645
646 f = alg_oakley_dhdef(doi);
647 if (f == NULL)
648 return 0;
649
650 return 1;
651 }
652
653 int
654 alg_oakley_dhdef_doi(type)
655 int type;
656 {
657 int i, res = -1;
658
659 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
660 if (type == oakley_dhdef[i].type) {
661 res = oakley_dhdef[i].doi;
662 break;
663 }
664 return res;
665 }
666
667 struct dhgroup *
668 alg_oakley_dhdef_group(doi)
669 int doi;
670 {
671 struct dh_algorithm *f;
672
673 f = alg_oakley_dhdef(doi);
674 if (f == NULL || f->dhgroup == NULL)
675 return NULL;
676
677 return f->dhgroup;
678 }
679
680 const char *
681 alg_oakley_dhdef_name (doi)
682 int doi;
683 {
684 struct dh_algorithm *f;
685
686 f = alg_oakley_dhdef(doi);
687 if (f == NULL)
688 return "*UNKNOWN*";
689 return f->name;
690 }
691
692 /* authentication method */
693 int
694 alg_oakley_authdef_doi(type)
695 int type;
696 {
697 int i, res = -1;
698
699 for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
700 if (type == oakley_authdef[i].type) {
701 res = oakley_authdef[i].doi;
702 break;
703 }
704 return res;
705 }
706
707 const char *
708 alg_oakley_authdef_name (doi)
709 int doi;
710 {
711 int i;
712
713 for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
714 if (doi == oakley_authdef[i].doi) {
715 return oakley_authdef[i].name;
716 }
717 return "*UNKNOWN*";
718 }
719
720 /*
721 * give the default key length
722 * OUT: -1: NG
723 * 0: fixed key cipher, key length not allowed
724 * positive: default key length
725 */
726 int
727 default_keylen(class, type)
728 int class, type;
729 {
730
731 switch (class) {
732 case algclass_isakmp_enc:
733 case algclass_ipsec_enc:
734 break;
735 default:
736 return 0;
737 }
738
739 switch (type) {
740 case algtype_blowfish:
741 case algtype_rc5:
742 case algtype_cast128:
743 case algtype_aes:
744 case algtype_twofish:
745 return 128;
746 default:
747 return 0;
748 }
749 }
750
751 /*
752 * check key length
753 * OUT: -1: NG
754 * 0: OK
755 */
756 int
757 check_keylen(class, type, len)
758 int class, type, len;
759 {
760 int badrange;
761
762 switch (class) {
763 case algclass_isakmp_enc:
764 case algclass_ipsec_enc:
765 break;
766 default:
767 /* unknown class, punt */
768 plog(LLV_ERROR, LOCATION, NULL,
769 "unknown algclass %d\n", class);
770 return -1;
771 }
772
773 /* key length must be multiple of 8 bytes - RFC2451 2.2 */
774 switch (type) {
775 case algtype_blowfish:
776 case algtype_rc5:
777 case algtype_cast128:
778 case algtype_aes:
779 case algtype_twofish:
780 if (len % 8 != 0) {
781 plog(LLV_ERROR, LOCATION, NULL,
782 "key length %d is not multiple of 8\n", len);
783 return -1;
784 }
785 break;
786 }
787
788 /* key length range */
789 badrange = 0;
790 switch (type) {
791 case algtype_blowfish:
792 if (len < 40 || 448 < len)
793 badrange++;
794 break;
795 case algtype_rc5:
796 if (len < 40 || 2040 < len)
797 badrange++;
798 break;
799 case algtype_cast128:
800 if (len < 40 || 128 < len)
801 badrange++;
802 break;
803 case algtype_aes:
804 if (!(len == 128 || len == 192 || len == 256))
805 badrange++;
806 break;
807 case algtype_twofish:
808 if (len < 40 || 256 < len)
809 badrange++;
810 break;
811 default:
812 if (len) {
813 plog(LLV_ERROR, LOCATION, NULL,
814 "key length is not allowed");
815 return -1;
816 }
817 break;
818 }
819 if (badrange) {
820 plog(LLV_ERROR, LOCATION, NULL,
821 "key length out of range\n");
822 return -1;
823 }
824
825 return 0;
826 }
827
828 /*
829 * convert algorithm type to DOI value.
830 * OUT -1 : NG
831 * other: converted.
832 */
833 int
834 algtype2doi(class, type)
835 int class, type;
836 {
837 int res = -1;
838
839 switch (class) {
840 case algclass_ipsec_enc:
841 res = alg_ipsec_encdef_doi(type);
842 break;
843 case algclass_ipsec_auth:
844 res = alg_ipsec_hmacdef_doi(type);
845 break;
846 case algclass_ipsec_comp:
847 res = alg_ipsec_compdef_doi(type);
848 break;
849 case algclass_isakmp_enc:
850 res = alg_oakley_encdef_doi(type);
851 break;
852 case algclass_isakmp_hash:
853 res = alg_oakley_hashdef_doi(type);
854 break;
855 case algclass_isakmp_dh:
856 res = alg_oakley_dhdef_doi(type);
857 break;
858 case algclass_isakmp_ameth:
859 res = alg_oakley_authdef_doi(type);
860 break;
861 }
862 return res;
863 }
864
865 /*
866 * convert algorithm class to DOI value.
867 * OUT -1 : NG
868 * other: converted.
869 */
870 int
871 algclass2doi(class)
872 int class;
873 {
874 switch (class) {
875 case algclass_ipsec_enc:
876 return IPSECDOI_PROTO_IPSEC_ESP;
877 case algclass_ipsec_auth:
878 return IPSECDOI_ATTR_AUTH;
879 case algclass_ipsec_comp:
880 return IPSECDOI_PROTO_IPCOMP;
881 case algclass_isakmp_enc:
882 return OAKLEY_ATTR_ENC_ALG;
883 case algclass_isakmp_hash:
884 return OAKLEY_ATTR_HASH_ALG;
885 case algclass_isakmp_dh:
886 return OAKLEY_ATTR_GRP_DESC;
887 case algclass_isakmp_ameth:
888 return OAKLEY_ATTR_AUTH_METHOD;
889 default:
890 return -1;
891 }
892 /*NOTREACHED*/
893 return -1;
894 }