Annotation of embedaddon/ipsec-tools/src/racoon/algorithm.c, revision 1.1
1.1 ! misho 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>