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