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