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