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