]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/algorithm.c
ipsec-34.0.3.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
78static 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
103static 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
131static 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
177static 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
210static 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
216static struct misc_algorithm oakley_authdef[] = {
217{ "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, },
218{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, },
219{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, },
220{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, },
221{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, },
222{ "gssapi_krb", algtype_gssapikrb, OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, },
223#ifdef ENABLE_HYBRID
224{ "hybrid_rsa_server", algtype_hybrid_rsa_s,
225 OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, },
226{ "hybrid_dss_server", algtype_hybrid_dss_s,
227 OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, },
228{ "hybrid_rsa_client", algtype_hybrid_rsa_c,
229 OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, },
230{ "hybrid_dss_client", algtype_hybrid_dss_c,
231 OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, },
232#endif
233};
234
235static struct dh_algorithm oakley_dhdef[] = {
236{ "modp768", algtype_modp768, OAKLEY_ATTR_GRP_DESC_MODP768,
237 &dh_modp768, },
238{ "modp1024", algtype_modp1024, OAKLEY_ATTR_GRP_DESC_MODP1024,
239 &dh_modp1024, },
240{ "modp1536", algtype_modp1536, OAKLEY_ATTR_GRP_DESC_MODP1536,
241 &dh_modp1536, },
242{ "modp2048", algtype_modp2048, OAKLEY_ATTR_GRP_DESC_MODP2048,
243 &dh_modp2048, },
244{ "modp3072", algtype_modp3072, OAKLEY_ATTR_GRP_DESC_MODP3072,
245 &dh_modp3072, },
246{ "modp4096", algtype_modp4096, OAKLEY_ATTR_GRP_DESC_MODP4096,
247 &dh_modp4096, },
248{ "modp6144", algtype_modp6144, OAKLEY_ATTR_GRP_DESC_MODP6144,
249 &dh_modp6144, },
250{ "modp8192", algtype_modp8192, OAKLEY_ATTR_GRP_DESC_MODP8192,
251 &dh_modp8192, },
252};
253
254static struct hash_algorithm *alg_oakley_hashdef __P((int));
255static struct hmac_algorithm *alg_oakley_hmacdef __P((int));
256static struct enc_algorithm *alg_oakley_encdef __P((int));
257static struct enc_algorithm *alg_ipsec_encdef __P((int));
258static struct hmac_algorithm *alg_ipsec_hmacdef __P((int));
259static struct dh_algorithm *alg_oakley_dhdef __P((int));
260
261/* oakley hash algorithm */
262static struct hash_algorithm *
263alg_oakley_hashdef(doi)
264 int doi;
265{
266 int i;
267
268 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
269 if (doi == oakley_hashdef[i].doi) {
270 plog(LLV_DEBUG, LOCATION, NULL, "hash(%s)\n",
271 oakley_hashdef[i].name);
272 return &oakley_hashdef[i];
273 }
274 return NULL;
275}
276
277int
278alg_oakley_hashdef_ok(doi)
279 int doi;
280{
281 struct hash_algorithm *f;
282
283 f = alg_oakley_hashdef(doi);
284 if (f == NULL)
285 return 0;
286
287 return 1;
288}
289
290int
291alg_oakley_hashdef_doi(type)
292 int type;
293{
294 int i, res = -1;
295
296 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
297 if (type == oakley_hashdef[i].type) {
298 res = oakley_hashdef[i].doi;
299 break;
300 }
301 return res;
302}
303
304int
305alg_oakley_hashdef_hashlen(doi)
306 int doi;
307{
308 struct hash_algorithm *f;
309
310 f = alg_oakley_hashdef(doi);
311 if (f == NULL || f->hashlen == NULL)
312 return 0;
313
314 return (f->hashlen)();
315}
316
317const char *
318alg_oakley_hashdef_name (doi)
319 int doi;
320{
321 struct hash_algorithm *f;
322
323 f = alg_oakley_hashdef(doi);
324 if (f == NULL)
325 return "*UNKNOWN*";
326
327 return f->name;
328}
329
330vchar_t *
331alg_oakley_hashdef_one(doi, buf)
332 int doi;
333 vchar_t *buf;
334{
335 struct hash_algorithm *f;
336
337 f = alg_oakley_hashdef(doi);
338 if (f == NULL || f->hashlen == NULL)
339 return NULL;
340
341 return (f->one)(buf);
342}
343
344/* oakley hmac algorithm */
345static struct hmac_algorithm *
346alg_oakley_hmacdef(doi)
347 int doi;
348{
349 int i;
350
351 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
352 if (doi == oakley_hmacdef[i].doi) {
353 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
354 oakley_hmacdef[i].name);
355 return &oakley_hmacdef[i];
356 }
357 return NULL;
358}
359
360int
361alg_oakley_hmacdef_doi(type)
362 int type;
363{
364 int i, res = -1;
365
366 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
367 if (type == oakley_hmacdef[i].type) {
368 res = oakley_hmacdef[i].doi;
369 break;
370 }
371 return res;
372}
373
374vchar_t *
375alg_oakley_hmacdef_one(doi, key, buf)
376 int doi;
377 vchar_t *key, *buf;
378{
379 struct hmac_algorithm *f;
380 vchar_t *res;
381#ifdef ENABLE_STATS
382 struct timeval start, end;
383#endif
384
385 f = alg_oakley_hmacdef(doi);
386 if (f == NULL || f->one == NULL)
387 return NULL;
388
389#ifdef ENABLE_STATS
390 gettimeofday(&start, NULL);
391#endif
392
393 res = (f->one)(key, buf);
394
395#ifdef ENABLE_STATS
396 gettimeofday(&end, NULL);
397 syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __func__,
398 f->name, buf->l, timedelta(&start, &end));
399#endif
400
401 return res;
402}
403
404/* oakley encryption algorithm */
405static struct enc_algorithm *
406alg_oakley_encdef(doi)
407 int doi;
408{
409 int i;
410
411 for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
412 if (doi == oakley_encdef[i].doi) {
413 plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
414 oakley_encdef[i].name);
415 return &oakley_encdef[i];
416 }
417 return NULL;
418}
419
420int
421alg_oakley_encdef_ok(doi)
422 int doi;
423{
424 struct enc_algorithm *f;
425
426 f = alg_oakley_encdef(doi);
427 if (f == NULL)
428 return 0;
429
430 return 1;
431}
432
433int
434alg_oakley_encdef_doi(type)
435 int type;
436{
437 int i, res = -1;
438
439 for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
440 if (type == oakley_encdef[i].type) {
441 res = oakley_encdef[i].doi;
442 break;
443 }
444 return res;
445}
446
447int
448alg_oakley_encdef_keylen(doi, len)
449 int doi, len;
450{
451 struct enc_algorithm *f;
452
453 f = alg_oakley_encdef(doi);
454 if (f == NULL || f->keylen == NULL)
455 return -1;
456
457 return (f->keylen)(len);
458}
459
460int
461alg_oakley_encdef_blocklen(doi)
462 int doi;
463{
464 struct enc_algorithm *f;
465
466 f = alg_oakley_encdef(doi);
467 if (f == NULL)
468 return -1;
469
470 return f->blocklen;
471}
472
473const char *
474alg_oakley_encdef_name (doi)
475 int doi;
476{
477 struct enc_algorithm *f;
478
479 f = alg_oakley_encdef(doi);
480 if (f == NULL)
481 return "*UNKNOWN*";
482
483 return f->name;
484}
485
486vchar_t *
487alg_oakley_encdef_decrypt(doi, buf, key, iv)
488 int doi;
489 vchar_t *buf, *key, *iv;
490{
491 vchar_t *res;
492 struct enc_algorithm *f;
493#ifdef ENABLE_STATS
494 struct timeval start, end;
495#endif
496
497 f = alg_oakley_encdef(doi);
498 if (f == NULL || f->decrypt == NULL)
499 return NULL;
500
501#ifdef ENABLE_STATS
502 gettimeofday(&start, NULL);
503#endif
504
505 res = (f->decrypt)(buf, key, iv);
506
507#ifdef ENABLE_STATS
508 gettimeofday(&end, NULL);
509 syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
510 f->name, key->l << 3, buf->l, timedelta(&start, &end));
511#endif
512 return res;
513}
514
515vchar_t *
516alg_oakley_encdef_encrypt(doi, buf, key, iv)
517 int doi;
518 vchar_t *buf, *key, *iv;
519{
520 vchar_t *res;
521 struct enc_algorithm *f;
522#ifdef ENABLE_STATS
523 struct timeval start, end;
524#endif
525
526 f = alg_oakley_encdef(doi);
527 if (f == NULL || f->encrypt == NULL)
528 return NULL;
529
530#ifdef ENABLE_STATS
531 gettimeofday(&start, NULL);
532#endif
533
534 res = (f->encrypt)(buf, key, iv);
535
536#ifdef ENABLE_STATS
537 gettimeofday(&end, NULL);
538 syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
539 f->name, key->l << 3, buf->l, timedelta(&start, &end));
540#endif
541 return res;
542}
543
544/* ipsec encryption algorithm */
545static struct enc_algorithm *
546alg_ipsec_encdef(doi)
547 int doi;
548{
549 int i;
550
551 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
552 if (doi == ipsec_encdef[i].doi) {
553 plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
554 ipsec_encdef[i].name);
555 return &ipsec_encdef[i];
556 }
557 return NULL;
558}
559
560int
561alg_ipsec_encdef_doi(type)
562 int type;
563{
564 int i, res = -1;
565
566 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
567 if (type == ipsec_encdef[i].type) {
568 res = ipsec_encdef[i].doi;
569 break;
570 }
571 return res;
572}
573
574int
575alg_ipsec_encdef_keylen(doi, len)
576 int doi, len;
577{
578 struct enc_algorithm *f;
579
580 f = alg_ipsec_encdef(doi);
581 if (f == NULL || f->keylen == NULL)
582 return -1;
583
584 return (f->keylen)(len);
585}
586
587/* ipsec hmac algorithm */
588static struct hmac_algorithm *
589alg_ipsec_hmacdef(doi)
590 int doi;
591{
592 int i;
593
594 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
595 if (doi == ipsec_hmacdef[i].doi) {
596 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
597 oakley_hmacdef[i].name);
598 return &ipsec_hmacdef[i];
599 }
600 return NULL;
601}
602
603int
604alg_ipsec_hmacdef_doi(type)
605 int type;
606{
607 int i, res = -1;
608
609 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
610 if (type == ipsec_hmacdef[i].type) {
611 res = ipsec_hmacdef[i].doi;
612 break;
613 }
614 return res;
615}
616
617int
618alg_ipsec_hmacdef_hashlen(doi)
619 int doi;
620{
621 struct hmac_algorithm *f;
622
623 f = alg_ipsec_hmacdef(doi);
624 if (f == NULL || f->hashlen == NULL)
625 return -1;
626
627 return (f->hashlen)();
628}
629
630/* ip compression */
631int
632alg_ipsec_compdef_doi(type)
633 int type;
634{
635 int i, res = -1;
636
637 for (i = 0; i < ARRAYLEN(ipsec_compdef); i++)
638 if (type == ipsec_compdef[i].type) {
639 res = ipsec_compdef[i].doi;
640 break;
641 }
642 return res;
643}
644
645/* dh algorithm */
646static struct dh_algorithm *
647alg_oakley_dhdef(doi)
648 int doi;
649{
650 int i;
651
652 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
653 if (doi == oakley_dhdef[i].doi) {
654 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
655 oakley_dhdef[i].name);
656 return &oakley_dhdef[i];
657 }
658 return NULL;
659}
660
661int
662alg_oakley_dhdef_ok(doi)
663 int doi;
664{
665 struct dh_algorithm *f;
666
667 f = alg_oakley_dhdef(doi);
668 if (f == NULL)
669 return 0;
670
671 return 1;
672}
673
674int
675alg_oakley_dhdef_doi(type)
676 int type;
677{
678 int i, res = -1;
679
680 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
681 if (type == oakley_dhdef[i].type) {
682 res = oakley_dhdef[i].doi;
683 break;
684 }
685 return res;
686}
687
688struct dhgroup *
689alg_oakley_dhdef_group(doi)
690 int doi;
691{
692 struct dh_algorithm *f;
693
694 f = alg_oakley_dhdef(doi);
695 if (f == NULL || f->dhgroup == NULL)
696 return NULL;
697
698 return f->dhgroup;
699}
700
701const char *
702alg_oakley_dhdef_name (doi)
703 int doi;
704{
705 struct dh_algorithm *f;
706
707 f = alg_oakley_dhdef(doi);
708 if (f == NULL)
709 return "*UNKNOWN*";
710 return f->name;
711}
712
713/* authentication method */
714int
715alg_oakley_authdef_doi(type)
716 int type;
717{
718 int i, res = -1;
719
720 for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
721 if (type == oakley_authdef[i].type) {
722 res = oakley_authdef[i].doi;
723 break;
724 }
725 return res;
726}
727
728const char *
729alg_oakley_authdef_name (doi)
730 int doi;
731{
732 int i;
733
734 for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
735 if (doi == oakley_authdef[i].doi) {
736 return oakley_authdef[i].name;
737 }
738 return "*UNKNOWN*";
739}
740
741/*
742 * give the default key length
743 * OUT: -1: NG
744 * 0: fixed key cipher, key length not allowed
745 * positive: default key length
746 */
747int
748default_keylen(class, type)
749 int class, type;
750{
751
752 switch (class) {
753 case algclass_isakmp_enc:
754 case algclass_ipsec_enc:
755 break;
756 default:
757 return 0;
758 }
759
760 switch (type) {
761 case algtype_blowfish:
762 case algtype_rc5:
763 case algtype_cast128:
764 case algtype_aes:
765 case algtype_twofish:
766 return 128;
767 default:
768 return 0;
769 }
770}
771
772/*
773 * check key length
774 * OUT: -1: NG
775 * 0: OK
776 */
777int
778check_keylen(class, type, len)
779 int class, type, len;
780{
781 int badrange;
782
783 switch (class) {
784 case algclass_isakmp_enc:
785 case algclass_ipsec_enc:
786 break;
787 default:
788 /* unknown class, punt */
789 plog(LLV_ERROR, LOCATION, NULL,
790 "unknown algclass %d\n", class);
791 return -1;
792 }
793
794 /* key length must be multiple of 8 bytes - RFC2451 2.2 */
795 switch (type) {
796 case algtype_blowfish:
797 case algtype_rc5:
798 case algtype_cast128:
799 case algtype_aes:
800 case algtype_twofish:
801 if (len % 8 != 0) {
802 plog(LLV_ERROR, LOCATION, NULL,
803 "key length %d is not multiple of 8\n", len);
804 return -1;
805 }
806 break;
807 }
808
809 /* key length range */
810 badrange = 0;
811 switch (type) {
812 case algtype_blowfish:
813 if (len < 40 || 448 < len)
814 badrange++;
815 break;
816 case algtype_rc5:
817 if (len < 40 || 2040 < len)
818 badrange++;
819 break;
820 case algtype_cast128:
821 if (len < 40 || 128 < len)
822 badrange++;
823 break;
824 case algtype_aes:
825 if (!(len == 128 || len == 192 || len == 256))
826 badrange++;
827 break;
828 case algtype_twofish:
829 if (len < 40 || 256 < len)
830 badrange++;
831 break;
832 default:
833 if (len) {
834 plog(LLV_ERROR, LOCATION, NULL,
835 "key length is not allowed");
836 return -1;
837 }
838 break;
839 }
840 if (badrange) {
841 plog(LLV_ERROR, LOCATION, NULL,
842 "key length out of range\n");
843 return -1;
844 }
845
846 return 0;
847}
848
849/*
850 * convert algorithm type to DOI value.
851 * OUT -1 : NG
852 * other: converted.
853 */
854int
855algtype2doi(class, type)
856 int class, type;
857{
858 int res = -1;
859
860 switch (class) {
861 case algclass_ipsec_enc:
862 res = alg_ipsec_encdef_doi(type);
863 break;
864 case algclass_ipsec_auth:
865 res = alg_ipsec_hmacdef_doi(type);
866 break;
867 case algclass_ipsec_comp:
868 res = alg_ipsec_compdef_doi(type);
869 break;
870 case algclass_isakmp_enc:
871 res = alg_oakley_encdef_doi(type);
872 break;
873 case algclass_isakmp_hash:
874 res = alg_oakley_hashdef_doi(type);
875 break;
876 case algclass_isakmp_dh:
877 res = alg_oakley_dhdef_doi(type);
878 break;
879 case algclass_isakmp_ameth:
880 res = alg_oakley_authdef_doi(type);
881 break;
882 }
883 return res;
884}
885
886/*
887 * convert algorithm class to DOI value.
888 * OUT -1 : NG
889 * other: converted.
890 */
891int
892algclass2doi(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}