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>