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 *
alg_oakley_hashdef(doi)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
alg_oakley_hashdef_ok(doi)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
alg_oakley_hashdef_doi(type)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
alg_oakley_hashdef_hashlen(doi)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 *
alg_oakley_hashdef_name(doi)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 *
alg_oakley_hashdef_one(doi,buf)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 *
alg_oakley_hmacdef(doi)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
alg_oakley_hmacdef_doi(type)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 *
alg_oakley_hmacdef_one(doi,key,buf)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 *
alg_oakley_encdef(doi)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
alg_oakley_encdef_ok(doi)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
alg_oakley_encdef_doi(type)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
alg_oakley_encdef_keylen(doi,len)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
alg_oakley_encdef_blocklen(doi)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 *
alg_oakley_encdef_name(doi)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 *
alg_oakley_encdef_decrypt(doi,buf,key,iv)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 *
alg_oakley_encdef_encrypt(doi,buf,key,iv)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 *
alg_ipsec_encdef(doi)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
alg_ipsec_encdef_doi(type)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
alg_ipsec_encdef_keylen(doi,len)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 *
alg_ipsec_hmacdef(doi)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
alg_ipsec_hmacdef_doi(type)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
alg_ipsec_hmacdef_hashlen(doi)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
alg_ipsec_compdef_doi(type)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 *
alg_oakley_dhdef(doi)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
alg_oakley_dhdef_ok(doi)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
alg_oakley_dhdef_doi(type)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 *
alg_oakley_dhdef_group(doi)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 *
alg_oakley_dhdef_name(doi)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
alg_oakley_authdef_doi(type)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 *
alg_oakley_authdef_name(doi)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
default_keylen(class,type)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
check_keylen(class,type,len)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
algtype2doi(class,type)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
algclass2doi(class)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 }
958