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