1/* $KAME: algorithm.c,v 1.23 2002/04/25 09:48:32 sakane 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 <sys/param.h> 33#include <sys/types.h> 34#include <stdlib.h> 35 36#include "var.h" 37#include "misc.h" 38#include "vmbuf.h" 39#include "plog.h" 40#include "debug.h" 41 42#include "crypto_openssl.h" 43#include "dhgroup.h" 44#include "algorithm.h" 45#include "oakley.h" 46#include "isakmp_var.h" 47#include "isakmp.h" 48#include "ipsec_doi.h" 49#include "gcmalloc.h" 50 51static struct hash_algorithm oakley_hashdef[] = { 52{ "md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5, 53 eay_md5_init, eay_md5_update, 54 eay_md5_final, eay_md5_hashlen, 55 eay_md5_one, }, 56{ "sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA, 57 eay_sha1_init, eay_sha1_update, 58 eay_sha1_final, eay_sha1_hashlen, 59 eay_sha1_one, }, 60{ "sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256, 61 eay_sha2_256_init, eay_sha2_256_update, 62 eay_sha2_256_final, eay_sha2_256_hashlen, 63 eay_sha1_one, }, 64{ "sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384, 65 eay_sha2_384_init, eay_sha2_384_update, 66 eay_sha2_384_final, eay_sha2_384_hashlen, 67 eay_sha1_one, }, 68{ "sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512, 69 eay_sha2_512_init, eay_sha2_512_update, 70 eay_sha2_512_final, eay_sha2_512_hashlen, 71 eay_sha1_one, }, 72}; 73 74static struct hmac_algorithm oakley_hmacdef[] = { 75{ "hmac_md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5, 76 eay_hmacmd5_init, eay_hmacmd5_update, 77 eay_hmacmd5_final, NULL, 78 eay_hmacmd5_one, }, 79{ "hmac_sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA, 80 eay_hmacsha1_init, eay_hmacsha1_update, 81 eay_hmacsha1_final, NULL, 82 eay_hmacsha1_one, }, 83{ "hmac_sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256, 84 eay_hmacsha2_256_init, eay_hmacsha2_256_update, 85 eay_hmacsha2_256_final, NULL, 86 eay_hmacsha2_256_one, }, 87{ "hmac_sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384, 88 eay_hmacsha2_384_init, eay_hmacsha2_384_update, 89 eay_hmacsha2_384_final, NULL, 90 eay_hmacsha2_384_one, }, 91{ "hmac_sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512, 92 eay_hmacsha2_512_init, eay_hmacsha2_512_update, 93 eay_hmacsha2_512_final, NULL, 94 eay_hmacsha2_512_one, }, 95}; 96 97static struct enc_algorithm oakley_encdef[] = { 98{ "des", algtype_des, OAKLEY_ATTR_ENC_ALG_DES, 8, 99 eay_des_encrypt, eay_des_decrypt, 100 eay_des_weakkey, eay_des_keylen, }, 101#ifdef HAVE_OPENSSL_IDEA_H 102{ "idea", algtype_idea, OAKLEY_ATTR_ENC_ALG_IDEA, 8, 103 eay_idea_encrypt, eay_idea_decrypt, 104 eay_idea_weakkey, eay_idea_keylen, }, 105#endif 106{ "blowfish", algtype_blowfish, OAKLEY_ATTR_ENC_ALG_BLOWFISH, 8, 107 eay_bf_encrypt, eay_bf_decrypt, 108 eay_bf_weakkey, eay_bf_keylen, }, 109#ifdef HAVE_OPENSSL_RC5_H 110{ "rc5", algtype_rc5, OAKLEY_ATTR_ENC_ALG_RC5, 8, 111 eay_rc5_encrypt, eay_rc5_decrypt, 112 eay_rc5_weakkey, eay_rc5_keylen, }, 113#endif 114{ "3des", algtype_3des, OAKLEY_ATTR_ENC_ALG_3DES, 8, 115 eay_3des_encrypt, eay_3des_decrypt, 116 eay_3des_weakkey, eay_3des_keylen, }, 117{ "cast", algtype_cast128, OAKLEY_ATTR_ENC_ALG_CAST, 8, 118 eay_cast_encrypt, eay_cast_decrypt, 119 eay_cast_weakkey, eay_cast_keylen, }, 120{ "aes", algtype_rijndael, OAKLEY_ATTR_ENC_ALG_AES, 16, 121 eay_aes_encrypt, eay_aes_decrypt, 122 eay_aes_weakkey, eay_aes_keylen, }, 123}; 124 125static struct enc_algorithm ipsec_encdef[] = { 126{ "des-iv64", algtype_des_iv64, IPSECDOI_ESP_DES_IV64, 8, 127 NULL, NULL, 128 NULL, eay_des_keylen, }, 129{ "des", algtype_des, IPSECDOI_ESP_DES, 8, 130 NULL, NULL, 131 NULL, eay_des_keylen, }, 132{ "3des", algtype_3des, IPSECDOI_ESP_3DES, 8, 133 NULL, NULL, 134 NULL, eay_3des_keylen, }, 135#ifdef HAVE_OPENSSL_RC5_H 136{ "rc5", algtype_rc5, IPSECDOI_ESP_RC5, 8, 137 NULL, NULL, 138 NULL, eay_rc5_keylen, }, 139#endif 140{ "cast", algtype_cast128, IPSECDOI_ESP_CAST, 8, 141 NULL, NULL, 142 NULL, eay_cast_keylen, }, 143{ "blowfish", algtype_blowfish, IPSECDOI_ESP_BLOWFISH, 8, 144 NULL, NULL, 145 NULL, eay_bf_keylen, }, 146{ "des-iv32", algtype_des_iv32, IPSECDOI_ESP_DES_IV32, 8, 147 NULL, NULL, 148 NULL, eay_des_keylen, }, 149{ "null", algtype_null_enc, IPSECDOI_ESP_NULL, 8, 150 NULL, NULL, 151 NULL, eay_null_keylen, }, 152{ "rijndael", algtype_rijndael, IPSECDOI_ESP_RIJNDAEL, 16, 153 NULL, NULL, 154 NULL, eay_aes_keylen, }, 155{ "twofish", algtype_twofish, IPSECDOI_ESP_TWOFISH, 16, 156 NULL, NULL, 157 NULL, eay_twofish_keylen, }, 158#ifdef HAVE_OPENSSL_IDEA_H 159{ "3idea", algtype_3idea, IPSECDOI_ESP_3IDEA, 8, 160 NULL, NULL, 161 NULL, NULL, }, 162{ "idea", algtype_idea, IPSECDOI_ESP_IDEA, 8, 163 NULL, NULL, 164 NULL, NULL, }, 165#endif 166{ "rc4", algtype_rc4, IPSECDOI_ESP_RC4, 8, 167 NULL, NULL, 168 NULL, NULL, }, 169}; 170 171static struct hmac_algorithm ipsec_hmacdef[] = { 172{ "md5", algtype_hmac_md5, IPSECDOI_ATTR_AUTH_HMAC_MD5, 173 NULL, NULL, 174 NULL, eay_md5_hashlen, 175 NULL, }, 176{ "sha1", algtype_hmac_sha1, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 177 NULL, NULL, 178 NULL, eay_sha1_hashlen, 179 NULL, }, 180{ "kpdk", algtype_kpdk, IPSECDOI_ATTR_AUTH_KPDK, 181 NULL, NULL, 182 NULL, eay_kpdk_hashlen, 183 NULL, }, 184{ "null", algtype_non_auth, IPSECDOI_ATTR_AUTH_NONE, 185 NULL, NULL, 186 NULL, eay_null_hashlen, 187 NULL, }, 188{ "hmac_sha2_256", algtype_hmac_sha2_256, IPSECDOI_ATTR_SHA2_256, 189 NULL, NULL, 190 NULL, eay_sha2_256_hashlen, 191 NULL, }, 192{ "hmac_sha2_384", algtype_hmac_sha2_384, IPSECDOI_ATTR_SHA2_384, 193 NULL, NULL, 194 NULL, eay_sha2_384_hashlen, 195 NULL, }, 196{ "hmac_sha2_512", algtype_hmac_sha2_512, IPSECDOI_ATTR_SHA2_512, 197 NULL, NULL, 198 NULL, eay_sha2_512_hashlen, 199 NULL, }, 200}; 201 202static struct misc_algorithm ipsec_compdef[] = { 203{ "oui", algtype_oui, IPSECDOI_IPCOMP_OUI, }, 204{ "deflate", algtype_deflate, IPSECDOI_IPCOMP_DEFLATE, }, 205{ "lzs", algtype_lzs, IPSECDOI_IPCOMP_LZS, }, 206}; 207 208static struct misc_algorithm oakley_authdef[] = { 209{ "psk", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, }, 210{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, }, 211{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, }, 212{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, }, 213{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, }, 214{ "gssapi_krb", algtype_gssapikrb, OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, }, 215}; 216 217static struct dh_algorithm oakley_dhdef[] = { 218{ "modp768", algtype_modp768, OAKLEY_ATTR_GRP_DESC_MODP768, 219 &dh_modp768, }, 220{ "modp1024", algtype_modp1024, OAKLEY_ATTR_GRP_DESC_MODP1024, 221 &dh_modp1024, }, 222{ "modp1536", algtype_modp1536, OAKLEY_ATTR_GRP_DESC_MODP1536, 223 &dh_modp1536, }, 224{ "modp2048", algtype_modp2048, OAKLEY_ATTR_GRP_DESC_MODP2048, 225 &dh_modp2048, }, 226{ "modp3072", algtype_modp3072, OAKLEY_ATTR_GRP_DESC_MODP3072, 227 &dh_modp3072, }, 228{ "modp4096", algtype_modp4096, OAKLEY_ATTR_GRP_DESC_MODP4096, 229 &dh_modp4096, }, 230{ "modp6144", algtype_modp6144, OAKLEY_ATTR_GRP_DESC_MODP6144, 231 &dh_modp6144, }, 232{ "modp8192", algtype_modp8192, OAKLEY_ATTR_GRP_DESC_MODP8192, 233 &dh_modp8192, }, 234}; 235 236static struct hash_algorithm *alg_oakley_hashdef __P((int)); 237static struct hmac_algorithm *alg_oakley_hmacdef __P((int)); 238static struct enc_algorithm *alg_oakley_encdef __P((int)); 239static struct enc_algorithm *alg_ipsec_encdef __P((int)); 240static struct hmac_algorithm *alg_ipsec_hmacdef __P((int)); 241static struct dh_algorithm *alg_oakley_dhdef __P((int)); 242 243/* oakley hash algorithm */ 244static struct hash_algorithm * 245alg_oakley_hashdef(doi) 246 int doi; 247{ 248 int i; 249 250 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++) 251 if (doi == oakley_hashdef[i].doi) { 252 plog(LLV_DEBUG, LOCATION, NULL, "hash(%s)\n", 253 oakley_hashdef[i].name); 254 return &oakley_hashdef[i]; 255 } 256 return NULL; 257} 258 259int 260alg_oakley_hashdef_ok(doi) 261 int doi; 262{ 263 struct hash_algorithm *f; 264 265 f = alg_oakley_hashdef(doi); 266 if (f == NULL) 267 return 0; 268 269 return 1; 270} 271 272int 273alg_oakley_hashdef_doi(type) 274 int type; 275{ 276 int i, res = -1; 277 278 for (i = 0; i < ARRAYLEN(oakley_hashdef); i++) 279 if (type == oakley_hashdef[i].type) { 280 res = oakley_hashdef[i].doi; 281 break; 282 } 283 return res; 284} 285 286int 287alg_oakley_hashdef_hashlen(doi) 288 int doi; 289{ 290 struct hash_algorithm *f; 291 292 f = alg_oakley_hashdef(doi); 293 if (f == NULL || f->hashlen == NULL) 294 return 0; 295 296 return (f->hashlen)(); 297} 298 299vchar_t * 300alg_oakley_hashdef_one(doi, buf) 301 int doi; 302 vchar_t *buf; 303{ 304 struct hash_algorithm *f; 305 306 f = alg_oakley_hashdef(doi); 307 if (f == NULL || f->hashlen == NULL) 308 return NULL; 309 310 return (f->one)(buf); 311} 312 313/* oakley hmac algorithm */ 314static struct hmac_algorithm * 315alg_oakley_hmacdef(doi) 316 int doi; 317{ 318 int i; 319 320 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++) 321 if (doi == oakley_hmacdef[i].doi) { 322 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", 323 oakley_hmacdef[i].name); 324 return &oakley_hmacdef[i]; 325 } 326 return NULL; 327} 328 329int 330alg_oakley_hmacdef_doi(type) 331 int type; 332{ 333 int i, res = -1; 334 335 for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++) 336 if (type == oakley_hmacdef[i].type) { 337 res = oakley_hmacdef[i].doi; 338 break; 339 } 340 return res; 341} 342 343vchar_t * 344alg_oakley_hmacdef_one(doi, key, buf) 345 int doi; 346 vchar_t *key, *buf; 347{ 348 struct hmac_algorithm *f; 349 vchar_t *res; 350#ifdef ENABLE_STATS 351 struct timeval start, end; 352#endif 353 354 f = alg_oakley_hmacdef(doi); 355 if (f == NULL || f->one == NULL) 356 return NULL; 357 358#ifdef ENABLE_STATS 359 gettimeofday(&start, NULL); 360#endif 361 362 res = (f->one)(key, buf); 363 364#ifdef ENABLE_STATS 365 gettimeofday(&end, NULL); 366 syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __FUNCTION__, 367 f->name, buf->l, timedelta(&start, &end)); 368#endif 369 370 return res; 371} 372 373/* oakley encryption algorithm */ 374static struct enc_algorithm * 375alg_oakley_encdef(doi) 376 int doi; 377{ 378 int i; 379 380 for (i = 0; i < ARRAYLEN(oakley_encdef); i++) 381 if (doi == oakley_encdef[i].doi) { 382 plog(LLV_DEBUG, LOCATION, NULL, "encription(%s)\n", 383 oakley_encdef[i].name); 384 return &oakley_encdef[i]; 385 } 386 return NULL; 387} 388 389int 390alg_oakley_encdef_ok(doi) 391 int doi; 392{ 393 struct enc_algorithm *f; 394 395 f = alg_oakley_encdef(doi); 396 if (f == NULL) 397 return 0; 398 399 return 1; 400} 401 402int 403alg_oakley_encdef_doi(type) 404 int type; 405{ 406 int i, res = -1; 407 408 for (i = 0; i < ARRAYLEN(oakley_encdef); i++) 409 if (type == oakley_encdef[i].type) { 410 res = oakley_encdef[i].doi; 411 break; 412 } 413 return res; 414} 415 416int 417alg_oakley_encdef_keylen(doi, len) 418 int doi, len; 419{ 420 struct enc_algorithm *f; 421 422 f = alg_oakley_encdef(doi); 423 if (f == NULL || f->keylen == NULL) 424 return -1; 425 426 return (f->keylen)(len); 427} 428 429int 430alg_oakley_encdef_blocklen(doi) 431 int doi; 432{ 433 struct enc_algorithm *f; 434 435 f = alg_oakley_encdef(doi); 436 if (f == NULL) 437 return -1; 438 439 return f->blocklen; 440} 441 442vchar_t * 443alg_oakley_encdef_decrypt(doi, buf, key, iv) 444 int doi; 445 vchar_t *buf, *key, *iv; 446{ 447 vchar_t *res; 448 struct enc_algorithm *f; 449#ifdef ENABLE_STATS 450 struct timeval start, end; 451#endif 452 453 f = alg_oakley_encdef(doi); 454 if (f == NULL || f->decrypt == NULL) 455 return NULL; 456 457#ifdef ENABLE_STATS 458 gettimeofday(&start, NULL); 459#endif 460 461 res = (f->decrypt)(buf, key, iv); 462 463#ifdef ENABLE_STATS 464 gettimeofday(&end, NULL); 465 syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __FUNCTION__, 466 f->name, key->l << 3, buf->l, timedelta(&start, &end)); 467#endif 468 return res; 469} 470 471vchar_t * 472alg_oakley_encdef_encrypt(doi, buf, key, iv) 473 int doi; 474 vchar_t *buf, *key, *iv; 475{ 476 vchar_t *res; 477 struct enc_algorithm *f; 478#ifdef ENABLE_STATS 479 struct timeval start, end; 480#endif 481 482 f = alg_oakley_encdef(doi); 483 if (f == NULL || f->encrypt == NULL) 484 return NULL; 485 486#ifdef ENABLE_STATS 487 gettimeofday(&start, NULL); 488#endif 489 490 res = (f->encrypt)(buf, key, iv); 491 492#ifdef ENABLE_STATS 493 gettimeofday(&end, NULL); 494 syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __FUNCTION__, 495 f->name, key->l << 3, buf->l, timedelta(&start, &end)); 496#endif 497 return res; 498} 499 500/* ipsec encryption algorithm */ 501static struct enc_algorithm * 502alg_ipsec_encdef(doi) 503 int doi; 504{ 505 int i; 506 507 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++) 508 if (doi == ipsec_encdef[i].doi) { 509 plog(LLV_DEBUG, LOCATION, NULL, "encription(%s)\n", 510 ipsec_encdef[i].name); 511 return &ipsec_encdef[i]; 512 } 513 return NULL; 514} 515 516int 517alg_ipsec_encdef_doi(type) 518 int type; 519{ 520 int i, res = -1; 521 522 for (i = 0; i < ARRAYLEN(ipsec_encdef); i++) 523 if (type == ipsec_encdef[i].type) { 524 res = ipsec_encdef[i].doi; 525 break; 526 } 527 return res; 528} 529 530int 531alg_ipsec_encdef_keylen(doi, len) 532 int doi, len; 533{ 534 struct enc_algorithm *f; 535 536 f = alg_ipsec_encdef(doi); 537 if (f == NULL || f->keylen == NULL) 538 return -1; 539 540 return (f->keylen)(len); 541} 542 543/* ipsec hmac algorithm */ 544static struct hmac_algorithm * 545alg_ipsec_hmacdef(doi) 546 int doi; 547{ 548 int i; 549 550 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++) 551 if (doi == ipsec_hmacdef[i].doi) { 552 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", 553 oakley_hmacdef[i].name); 554 return &ipsec_hmacdef[i]; 555 } 556 return NULL; 557} 558 559int 560alg_ipsec_hmacdef_doi(type) 561 int type; 562{ 563 int i, res = -1; 564 565 for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++) 566 if (type == ipsec_hmacdef[i].type) { 567 res = ipsec_hmacdef[i].doi; 568 break; 569 } 570 return res; 571} 572 573int 574alg_ipsec_hmacdef_hashlen(doi) 575 int doi; 576{ 577 struct hmac_algorithm *f; 578 579 f = alg_ipsec_hmacdef(doi); 580 if (f == NULL || f->hashlen == NULL) 581 return -1; 582 583 return (f->hashlen)(); 584} 585 586/* ip compression */ 587int 588alg_ipsec_compdef_doi(type) 589 int type; 590{ 591 int i, res = -1; 592 593 for (i = 0; i < ARRAYLEN(ipsec_compdef); i++) 594 if (type == ipsec_compdef[i].type) { 595 res = ipsec_compdef[i].doi; 596 break; 597 } 598 return res; 599} 600 601/* dh algorithm */ 602static struct dh_algorithm * 603alg_oakley_dhdef(doi) 604 int doi; 605{ 606 int i; 607 608 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++) 609 if (doi == oakley_dhdef[i].doi) { 610 plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", 611 oakley_dhdef[i].name); 612 return &oakley_dhdef[i]; 613 } 614 return NULL; 615} 616 617int 618alg_oakley_dhdef_ok(doi) 619 int doi; 620{ 621 struct dh_algorithm *f; 622 623 f = alg_oakley_dhdef(doi); 624 if (f == NULL) 625 return 0; 626 627 return 1; 628} 629 630int 631alg_oakley_dhdef_doi(type) 632 int type; 633{ 634 int i, res = -1; 635 636 for (i = 0; i < ARRAYLEN(oakley_dhdef); i++) 637 if (type == oakley_dhdef[i].type) { 638 res = oakley_dhdef[i].doi; 639 break; 640 } 641 return res; 642} 643 644struct dhgroup * 645alg_oakley_dhdef_group(doi) 646 int doi; 647{ 648 struct dh_algorithm *f; 649 650 f = alg_oakley_dhdef(doi); 651 if (f == NULL || f->dhgroup == NULL) 652 return NULL; 653 654 return f->dhgroup; 655} 656 657/* authentication method */ 658int 659alg_oakley_authdef_doi(type) 660 int type; 661{ 662 int i, res = -1; 663 664 for (i = 0; i < ARRAYLEN(oakley_authdef); i++) 665 if (type == oakley_authdef[i].type) { 666 res = oakley_authdef[i].doi; 667 break; 668 } 669 return res; 670} 671 672/* 673 * give the default key length 674 * OUT: -1: NG 675 * 0: fixed key cipher, key length not allowed 676 * positive: default key length 677 */ 678int 679default_keylen(class, type) 680 int class, type; 681{ 682 683 switch (class) { 684 case algclass_isakmp_enc: 685 case algclass_ipsec_enc: 686 break; 687 default: 688 return 0; 689 } 690 691 switch (type) { 692 case algtype_blowfish: 693 case algtype_rc5: 694 case algtype_cast128: 695 case algtype_rijndael: 696 case algtype_twofish: 697 return 128; 698 default: 699 return 0; 700 } 701} 702 703/* 704 * check key length 705 * OUT: -1: NG 706 * 0: OK 707 */ 708int 709check_keylen(class, type, len) 710 int class, type, len; 711{ 712 int badrange; 713 714 switch (class) { 715 case algclass_isakmp_enc: 716 case algclass_ipsec_enc: 717 break; 718 default: 719 /* unknown class, punt */ 720 plog(LLV_ERROR, LOCATION, NULL, 721 "unknown algclass %d\n", class); 722 return -1; 723 } 724 725 /* key length must be multiple of 8 bytes - RFC2451 2.2 */ 726 switch (type) { 727 case algtype_blowfish: 728 case algtype_rc5: 729 case algtype_cast128: 730 case algtype_rijndael: 731 case algtype_twofish: 732 if (len % 8 != 0) { 733 plog(LLV_ERROR, LOCATION, NULL, 734 "key length %d is not multiple of 8\n", len); 735 return -1; 736 } 737 break; 738 } 739 740 /* key length range */ 741 badrange = 0; 742 switch (type) { 743 case algtype_blowfish: 744 if (len < 40 || 448 < len) 745 badrange++; 746 break; 747 case algtype_rc5: 748 if (len < 40 || 2040 < len) 749 badrange++; 750 break; 751 case algtype_cast128: 752 if (len < 40 || 128 < len) 753 badrange++; 754 break; 755 case algtype_rijndael: 756 if (!(len == 128 || len == 192 || len == 256)) 757 badrange++; 758 break; 759 case algtype_twofish: 760 if (len < 40 || 256 < len) 761 badrange++; 762 break; 763 default: 764 if (len) { 765 plog(LLV_ERROR, LOCATION, NULL, 766 "key length is not allowed"); 767 return -1; 768 } 769 break; 770 } 771 if (badrange) { 772 plog(LLV_ERROR, LOCATION, NULL, 773 "key length out of range\n"); 774 return -1; 775 } 776 777 return 0; 778} 779 780/* 781 * convert algorithm type to DOI value. 782 * OUT -1 : NG 783 * other: converted. 784 */ 785int 786algtype2doi(class, type) 787 int class, type; 788{ 789 int res = -1; 790 791 switch (class) { 792 case algclass_ipsec_enc: 793 res = alg_ipsec_encdef_doi(type); 794 break; 795 case algclass_ipsec_auth: 796 res = alg_ipsec_hmacdef_doi(type); 797 break; 798 case algclass_ipsec_comp: 799 res = alg_ipsec_compdef_doi(type); 800 break; 801 case algclass_isakmp_enc: 802 res = alg_oakley_encdef_doi(type); 803 break; 804 case algclass_isakmp_hash: 805 res = alg_oakley_hashdef_doi(type); 806 break; 807 case algclass_isakmp_dh: 808 res = alg_oakley_dhdef_doi(type); 809 break; 810 case algclass_isakmp_ameth: 811 res = alg_oakley_authdef_doi(type); 812 break; 813 } 814 return res; 815} 816 817/* 818 * convert algorithm class to DOI value. 819 * OUT -1 : NG 820 * other: converted. 821 */ 822int 823algclass2doi(class) 824 int class; 825{ 826 switch (class) { 827 case algclass_ipsec_enc: 828 return IPSECDOI_PROTO_IPSEC_ESP; 829 case algclass_ipsec_auth: 830 return IPSECDOI_ATTR_AUTH; 831 case algclass_ipsec_comp: 832 return IPSECDOI_PROTO_IPCOMP; 833 case algclass_isakmp_enc: 834 return OAKLEY_ATTR_ENC_ALG; 835 case algclass_isakmp_hash: 836 return OAKLEY_ATTR_HASH_ALG; 837 case algclass_isakmp_dh: 838 return OAKLEY_ATTR_GRP_DESC; 839 case algclass_isakmp_ameth: 840 return OAKLEY_ATTR_AUTH_METHOD; 841 default: 842 return -1; 843 } 844 /*NOTREACHED*/ 845 return -1; 846} 847