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 * 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 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 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 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 * 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 * 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 * 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 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 * 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 * 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 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 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 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 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 * 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 * 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 * 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 * 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 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 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 * 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 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 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 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 * 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 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 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 * 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 * 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 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 * 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 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 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 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 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