Annotation of embedaddon/ipsec-tools/src/racoon/algorithm.c, revision 1.1.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>