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