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