diff options
author | ume <ume@FreeBSD.org> | 2003-10-13 14:57:41 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-10-13 14:57:41 +0000 |
commit | fd41336ef5a14e7f322b0a8af359c45ce03d4cc8 (patch) | |
tree | 2a5d44fe2e98a214421d56ae5f3dea9a73bd2413 /sys | |
parent | b24bb74b9ee088f076e89f68095367a214f7cc1d (diff) | |
download | FreeBSD-src-fd41336ef5a14e7f322b0a8af359c45ce03d4cc8.zip FreeBSD-src-fd41336ef5a14e7f322b0a8af359c45ce03d4cc8.tar.gz |
- support AES counter mode for ESP.
- use size_t as return type of schedlen(), as there's no error
check needed.
- clear key schedule buffer before freeing.
Obtained from: KAME
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 8 | ||||
-rw-r--r-- | sys/netinet6/esp.h | 2 | ||||
-rw-r--r-- | sys/netinet6/esp_aesctr.c | 463 | ||||
-rw-r--r-- | sys/netinet6/esp_aesctr.h | 42 | ||||
-rw-r--r-- | sys/netinet6/esp_core.c | 30 | ||||
-rw-r--r-- | sys/netinet6/esp_rijndael.c | 2 | ||||
-rw-r--r-- | sys/netinet6/esp_rijndael.h | 2 |
8 files changed, 531 insertions, 19 deletions
diff --git a/sys/conf/files b/sys/conf/files index 84a88f5..9ba820a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1441,6 +1441,7 @@ netinet6/ah_core.c optional ipsec netinet6/ah_input.c optional ipsec netinet6/ah_output.c optional ipsec netinet6/dest6.c optional inet6 +netinet6/esp_aesctr.c optional ipsec ipsec_esp netinet6/esp_core.c optional ipsec ipsec_esp netinet6/esp_input.c optional ipsec ipsec_esp netinet6/esp_output.c optional ipsec ipsec_esp diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 6fa8a2d..c0897e5 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -319,22 +319,22 @@ struct sadb_x_ipsecrequest { #define SADB_EALG_DESCBC 2 #define SADB_EALG_3DESCBC 3 #define SADB_EALG_NULL 11 -#define SADB_EALG_MAX 12 +#define SADB_EALG_MAX 250 /* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_EALG_CAST128CBC 6 #define SADB_X_EALG_BLOWFISHCBC 7 #define SADB_X_EALG_RIJNDAELCBC 12 #define SADB_X_EALG_AES 12 /* private allocations should use 249-255 (RFC2407) */ -#define SADB_X_EALG_SKIPJACK 249 +#define SADB_X_EALG_SKIPJACK 249 /*250*/ /* for FAST_IPSEC */ +#define SADB_X_EALG_AESCTR 250 /*249*/ /* draft-ietf-ipsec-ciph-aes-ctr-03 */ -#if 1 /*nonstandard */ +/* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_CALG_NONE 0 #define SADB_X_CALG_OUI 1 #define SADB_X_CALG_DEFLATE 2 #define SADB_X_CALG_LZS 3 #define SADB_X_CALG_MAX 4 -#endif #define SADB_IDENTTYPE_RESERVED 0 #define SADB_IDENTTYPE_PREFIX 1 diff --git a/sys/netinet6/esp.h b/sys/netinet6/esp.h index 28fe456..ba6c7ae 100644 --- a/sys/netinet6/esp.h +++ b/sys/netinet6/esp.h @@ -78,7 +78,7 @@ struct esp_algorithm { int (*mature) __P((struct secasvar *)); int keymin; /* in bits */ int keymax; /* in bits */ - int (*schedlen) __P((const struct esp_algorithm *)); + size_t (*schedlen) __P((const struct esp_algorithm *)); const char *name; int (*ivlen) __P((const struct esp_algorithm *, struct secasvar *)); int (*decrypt) __P((struct mbuf *, size_t, diff --git a/sys/netinet6/esp_aesctr.c b/sys/netinet6/esp_aesctr.c new file mode 100644 index 0000000..9fbd615 --- /dev/null +++ b/sys/netinet6/esp_aesctr.c @@ -0,0 +1,463 @@ +/* $KAME: esp_aesctr.c,v 1.2 2003/07/20 00:29:37 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <sys/syslog.h> +#include <sys/mbuf.h> + +#include <net/if.h> +#include <net/route.h> + +#include <netinet/in.h> + +#include <netinet6/ipsec.h> +#include <netinet6/esp.h> +#include <netinet6/esp_aesctr.h> + +#include <netkey/key.h> + +#include <crypto/rijndael/rijndael.h> + +#include <net/net_osdep.h> + +#define AES_BLOCKSIZE 16 + +#define NONCESIZE 4 +union cblock { + struct { + u_int8_t nonce[4]; + u_int8_t iv[16]; + u_int32_t ctr; + } v __attribute__((__packed__)); + u_int8_t cblock[16]; +}; + +typedef struct { + u_int32_t r_ek[(RIJNDAEL_MAXNR+1)*4]; + int r_nr; /* key-length-dependent number of rounds */ +} aesctr_ctx; + +int +esp_aesctr_mature(sav) + struct secasvar *sav; +{ + int keylen; + const struct esp_algorithm *algo; + + algo = esp_algorithm_lookup(sav->alg_enc); + if (!algo) { + ipseclog((LOG_ERR, + "esp_aeesctr_mature %s: unsupported algorithm.\n", + algo->name)); + return 1; + } + + keylen = sav->key_enc->sadb_key_bits; + if (keylen < algo->keymin || algo->keymax < keylen) { + ipseclog((LOG_ERR, + "esp_aesctr_mature %s: invalid key length %d.\n", + algo->name, sav->key_enc->sadb_key_bits)); + return 1; + } + + /* rijndael key + nonce */ + if (!(keylen == 128 + 32 || keylen == 192 + 32 || keylen == 256 + 32)) { + ipseclog((LOG_ERR, + "esp_aesctr_mature %s: invalid key length %d.\n", + algo->name, keylen)); + return 1; + } + + return 0; +} + +size_t +esp_aesctr_schedlen(algo) + const struct esp_algorithm *algo; +{ + + return sizeof(aesctr_ctx); +} + +int +esp_aesctr_schedule(algo, sav) + const struct esp_algorithm *algo; + struct secasvar *sav; +{ + aesctr_ctx *ctx; + int keylen; + + /* SA key = AES key + nonce */ + keylen = _KEYLEN(sav->key_enc) * 8 - NONCESIZE * 8; + + ctx = (aesctr_ctx *)sav->sched; + if ((ctx->r_nr = rijndaelKeySetupEnc(ctx->r_ek, + (char *)_KEYBUF(sav->key_enc), keylen)) == 0) + return -1; + return 0; +} + +int +esp_aesctr_decrypt(m, off, sav, algo, ivlen) + struct mbuf *m; + size_t off; + struct secasvar *sav; + const struct esp_algorithm *algo; + int ivlen; +{ + struct mbuf *s; + struct mbuf *d, *d0 = NULL, *dp; + int soff, doff; /* offset from the head of chain, to head of this mbuf */ + int sn, dn; /* offset from the head of the mbuf, to meat */ + size_t ivoff, bodyoff; + union cblock cblock; + u_int8_t keystream[AES_BLOCKSIZE], *nonce; + u_int32_t ctr; + u_int8_t *ivp; + u_int8_t sbuf[AES_BLOCKSIZE], *sp, *dst; + struct mbuf *scut; + int scutoff; + int i; + int blocklen; + aesctr_ctx *ctx; + + if (ivlen != sav->ivlen) { + ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: " + "unsupported ivlen %d\n", algo->name, ivlen)); + goto fail; + } + + /* assumes blocklen == padbound */ + blocklen = algo->padbound; + + ivoff = off + sizeof(struct newesp); + bodyoff = off + sizeof(struct newesp) + ivlen; + + /* setup counter block */ + nonce = _KEYBUF(sav->key_enc) + _KEYLEN(sav->key_enc) - NONCESIZE; + bcopy(nonce, cblock.v.nonce, NONCESIZE); + m_copydata(m, ivoff, ivlen, cblock.v.iv); + ctr = 1; + + if (m->m_pkthdr.len < bodyoff) { + ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: bad len %d/%lu\n", + algo->name, m->m_pkthdr.len, (unsigned long)bodyoff)); + goto fail; + } + if ((m->m_pkthdr.len - bodyoff) % blocklen) { + ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: " + "payload length must be multiple of %d\n", + algo->name, blocklen)); + goto fail; + } + + s = m; + d = d0 = dp = NULL; + soff = doff = sn = dn = 0; + ivp = sp = NULL; + + /* skip bodyoff */ + while (soff < bodyoff) { + if (soff + s->m_len > bodyoff) { + sn = bodyoff - soff; + break; + } + + soff += s->m_len; + s = s->m_next; + } + scut = s; + scutoff = sn; + + /* skip over empty mbuf */ + while (s && s->m_len == 0) + s = s->m_next; + + while (soff < m->m_pkthdr.len) { + /* source */ + if (sn + blocklen <= s->m_len) { + /* body is continuous */ + sp = mtod(s, u_int8_t *) + sn; + } else { + /* body is non-continuous */ + m_copydata(s, sn, blocklen, (caddr_t)sbuf); + sp = sbuf; + } + + /* destination */ + if (!d || dn + blocklen > d->m_len) { + if (d) + dp = d; + MGET(d, M_DONTWAIT, MT_DATA); + i = m->m_pkthdr.len - (soff + sn); + if (d && i > MLEN) { + MCLGET(d, M_DONTWAIT); + if ((d->m_flags & M_EXT) == 0) { + m_free(d); + d = NULL; + } + } + if (!d) { + goto nomem; + } + if (!d0) + d0 = d; + if (dp) + dp->m_next = d; + d->m_len = 0; + d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen; + if (d->m_len > i) + d->m_len = i; + dn = 0; + } + + /* put counter into counter block */ + cblock.v.ctr = htonl(ctr); + + /* setup keystream */ + ctx = (aesctr_ctx *)sav->sched; + rijndaelEncrypt(ctx->r_ek, ctx->r_nr, cblock.cblock, keystream); + + bcopy(sp, mtod(d, u_int8_t *) + dn, blocklen); + dst = mtod(d, u_int8_t *) + dn; + for (i = 0; i < blocklen; i++) + dst[i] ^= keystream[i]; + + ctr++; + + sn += blocklen; + dn += blocklen; + + /* find the next source block */ + while (s && sn >= s->m_len) { + sn -= s->m_len; + soff += s->m_len; + s = s->m_next; + } + + /* skip over empty mbuf */ + while (s && s->m_len == 0) + s = s->m_next; + } + + m_freem(scut->m_next); + scut->m_len = scutoff; + scut->m_next = d0; + + /* just in case */ + bzero(&cblock, sizeof(cblock)); + bzero(keystream, sizeof(keystream)); + + return 0; + +fail: + m_freem(m); + if (d0) + m_freem(d0); + return EINVAL; + +nomem: + m_freem(m); + if (d0) + m_freem(d0); + return ENOBUFS; +} + +int +esp_aesctr_encrypt(m, off, plen, sav, algo, ivlen) + struct mbuf *m; + size_t off; + size_t plen; + struct secasvar *sav; + const struct esp_algorithm *algo; + int ivlen; +{ + struct mbuf *s; + struct mbuf *d, *d0, *dp; + int soff, doff; /* offset from the head of chain, to head of this mbuf */ + int sn, dn; /* offset from the head of the mbuf, to meat */ + size_t ivoff, bodyoff; + union cblock cblock; + u_int8_t keystream[AES_BLOCKSIZE], *nonce; + u_int32_t ctr; + u_int8_t sbuf[AES_BLOCKSIZE], *sp, *dst; + struct mbuf *scut; + int scutoff; + int i; + int blocklen; + aesctr_ctx *ctx; + + if (ivlen != sav->ivlen) { + ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: " + "unsupported ivlen %d\n", algo->name, ivlen)); + m_freem(m); + return EINVAL; + } + + /* assumes blocklen == padbound */ + blocklen = algo->padbound; + + ivoff = off + sizeof(struct newesp); + bodyoff = off + sizeof(struct newesp) + ivlen; + + /* put iv into the packet. */ + /* maybe it is better to overwrite dest, not source */ + m_copyback(m, ivoff, ivlen, sav->iv); + + /* setup counter block */ + nonce = _KEYBUF(sav->key_enc) + _KEYLEN(sav->key_enc) - NONCESIZE; + bcopy(nonce, cblock.v.nonce, NONCESIZE); + m_copydata(m, ivoff, ivlen, cblock.v.iv); + ctr = 1; + + if (m->m_pkthdr.len < bodyoff) { + ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: bad len %d/%lu\n", + algo->name, m->m_pkthdr.len, (unsigned long)bodyoff)); + m_freem(m); + return EINVAL; + } + if ((m->m_pkthdr.len - bodyoff) % blocklen) { + ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: " + "payload length must be multiple of %lu\n", + algo->name, (unsigned long)algo->padbound)); + m_freem(m); + return EINVAL; + } + + s = m; + d = d0 = dp = NULL; + soff = doff = sn = dn = 0; + sp = NULL; + + /* skip bodyoff */ + while (soff < bodyoff) { + if (soff + s->m_len > bodyoff) { + sn = bodyoff - soff; + break; + } + + soff += s->m_len; + s = s->m_next; + } + scut = s; + scutoff = sn; + + /* skip over empty mbuf */ + while (s && s->m_len == 0) + s = s->m_next; + + while (soff < m->m_pkthdr.len) { + /* source */ + if (sn + blocklen <= s->m_len) { + /* body is continuous */ + sp = mtod(s, u_int8_t *) + sn; + } else { + /* body is non-continuous */ + m_copydata(s, sn, blocklen, (caddr_t)sbuf); + sp = sbuf; + } + + /* destination */ + if (!d || dn + blocklen > d->m_len) { + if (d) + dp = d; + MGET(d, M_DONTWAIT, MT_DATA); + i = m->m_pkthdr.len - (soff + sn); + if (d && i > MLEN) { + MCLGET(d, M_DONTWAIT); + if ((d->m_flags & M_EXT) == 0) { + m_free(d); + d = NULL; + } + } + if (!d) { + m_freem(m); + if (d0) + m_freem(d0); + return ENOBUFS; + } + if (!d0) + d0 = d; + if (dp) + dp->m_next = d; + d->m_len = 0; + d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen; + if (d->m_len > i) + d->m_len = i; + dn = 0; + } + + /* put counter into counter block */ + cblock.v.ctr = htonl(ctr); + + /* setup keystream */ + ctx = (aesctr_ctx *)sav->sched; + rijndaelEncrypt(ctx->r_ek, ctx->r_nr, cblock.cblock, keystream); + + bcopy(sp, mtod(d, u_int8_t *) + dn, blocklen); + dst = mtod(d, u_int8_t *) + dn; + for (i = 0; i < blocklen; i++) + dst[i] ^= keystream[i]; + + ctr++; + + sn += blocklen; + dn += blocklen; + + /* find the next source block */ + while (s && sn >= s->m_len) { + sn -= s->m_len; + soff += s->m_len; + s = s->m_next; + } + + /* skip over empty mbuf */ + while (s && s->m_len == 0) + s = s->m_next; + } + + m_freem(scut->m_next); + scut->m_len = scutoff; + scut->m_next = d0; + + /* just in case */ + bzero(&cblock, sizeof(cblock)); + bzero(keystream, sizeof(keystream)); + + key_sa_stir_iv(sav); + + return 0; +} diff --git a/sys/netinet6/esp_aesctr.h b/sys/netinet6/esp_aesctr.h new file mode 100644 index 0000000..bb7f7ea --- /dev/null +++ b/sys/netinet6/esp_aesctr.h @@ -0,0 +1,42 @@ +/* $KAME: esp_aesctr.h,v 1.2 2003/07/20 00:29:38 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998 and 2003 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +extern int esp_aesctr_mature __P((struct secasvar *)); +extern size_t esp_aesctr_schedlen __P((const struct esp_algorithm *)); +extern int esp_aesctr_schedule __P((const struct esp_algorithm *, + struct secasvar *)); +extern int esp_aesctr_decrypt __P((struct mbuf *, size_t, + struct secasvar *, const struct esp_algorithm *, int)); +extern int esp_aesctr_encrypt __P((struct mbuf *, size_t, size_t, + struct secasvar *, const struct esp_algorithm *, int)); + diff --git a/sys/netinet6/esp_core.c b/sys/netinet6/esp_core.c index 148d9c4..bfb0713a 100644 --- a/sys/netinet6/esp_core.c +++ b/sys/netinet6/esp_core.c @@ -68,9 +68,11 @@ #include <netinet6/esp6.h> #endif #include <netinet6/esp_rijndael.h> +#include <netinet6/esp_aesctr.h> #include <net/pfkeyv2.h> #include <netkey/keydb.h> #include <netkey/key.h> + #include <crypto/des/des.h> #include <crypto/blowfish/blowfish.h> #include <crypto/cast128/cast128.h> @@ -87,7 +89,7 @@ static int esp_descbc_ivlen __P((const struct esp_algorithm *, struct secasvar *)); static int esp_des_schedule __P((const struct esp_algorithm *, struct secasvar *)); -static int esp_des_schedlen __P((const struct esp_algorithm *)); +static size_t esp_des_schedlen __P((const struct esp_algorithm *)); static int esp_des_blockdecrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_des_blockencrypt __P((const struct esp_algorithm *, @@ -95,21 +97,21 @@ static int esp_des_blockencrypt __P((const struct esp_algorithm *, static int esp_cbc_mature __P((struct secasvar *)); static int esp_blowfish_schedule __P((const struct esp_algorithm *, struct secasvar *)); -static int esp_blowfish_schedlen __P((const struct esp_algorithm *)); +static size_t esp_blowfish_schedlen __P((const struct esp_algorithm *)); static int esp_blowfish_blockdecrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_blowfish_blockencrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_cast128_schedule __P((const struct esp_algorithm *, struct secasvar *)); -static int esp_cast128_schedlen __P((const struct esp_algorithm *)); +static size_t esp_cast128_schedlen __P((const struct esp_algorithm *)); static int esp_cast128_blockdecrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_cast128_blockencrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_3des_schedule __P((const struct esp_algorithm *, struct secasvar *)); -static int esp_3des_schedlen __P((const struct esp_algorithm *)); +static size_t esp_3des_schedlen __P((const struct esp_algorithm *)); static int esp_3des_blockdecrypt __P((const struct esp_algorithm *, struct secasvar *, u_int8_t *, u_int8_t *)); static int esp_3des_blockencrypt __P((const struct esp_algorithm *, @@ -134,7 +136,7 @@ static const struct esp_algorithm esp_algorithms[] = { esp_common_ivlen, esp_cbc_decrypt, esp_cbc_encrypt, esp_3des_schedule, esp_3des_blockdecrypt, esp_3des_blockencrypt, }, - { 1, 0, esp_null_mature, 0, 2048, 0, "null", + { 1, 0, esp_null_mature, 0, 2048, NULL, "null", esp_common_ivlen, esp_null_decrypt, esp_null_encrypt, NULL, }, { 8, 8, esp_cbc_mature, 40, 448, esp_blowfish_schedlen, "blowfish-cbc", @@ -151,6 +153,9 @@ static const struct esp_algorithm esp_algorithms[] = { esp_common_ivlen, esp_cbc_decrypt, esp_cbc_encrypt, esp_rijndael_schedule, esp_rijndael_blockdecrypt, esp_rijndael_blockencrypt }, + { 16, 8, esp_aesctr_mature, 160, 288, esp_aesctr_schedlen, "aes-ctr", + esp_common_ivlen, esp_aesctr_decrypt, + esp_aesctr_encrypt, esp_aesctr_schedule }, }; const struct esp_algorithm * @@ -171,6 +176,8 @@ esp_algorithm_lookup(idx) return &esp_algorithms[4]; case SADB_X_EALG_RIJNDAELCBC: return &esp_algorithms[5]; + case SADB_X_EALG_AESCTR: + return &esp_algorithms[6]; default: return NULL; } @@ -216,8 +223,6 @@ esp_schedule(algo, sav) return 0; sav->schedlen = (*algo->schedlen)(algo); - if (sav->schedlen < 0) - return EINVAL; sav->sched = malloc(sav->schedlen, M_SECA, M_NOWAIT); if (!sav->sched) { sav->schedlen = 0; @@ -228,6 +233,7 @@ esp_schedule(algo, sav) if (error) { ipseclog((LOG_ERR, "esp_schedule %s: error %d\n", algo->name, error)); + bzero(sav->sched, sav->schedlen); free(sav->sched, M_SECA); sav->sched = NULL; sav->schedlen = 0; @@ -326,7 +332,7 @@ esp_descbc_ivlen(algo, sav) return 8; } -static int +static size_t esp_des_schedlen(algo) const struct esp_algorithm *algo; { @@ -443,7 +449,7 @@ esp_cbc_mature(sav) return 0; } -static int +static size_t esp_blowfish_schedlen(algo) const struct esp_algorithm *algo; { @@ -502,12 +508,12 @@ esp_blowfish_blockencrypt(algo, sav, s, d) return 0; } -static int +static size_t esp_cast128_schedlen(algo) const struct esp_algorithm *algo; { - return sizeof(u_int32_t) * 32; + return sizeof(cast128_key); } static int @@ -545,7 +551,7 @@ esp_cast128_blockencrypt(algo, sav, s, d) return 0; } -static int +static size_t esp_3des_schedlen(algo) const struct esp_algorithm *algo; { diff --git a/sys/netinet6/esp_rijndael.c b/sys/netinet6/esp_rijndael.c index 950bbe8..e8c6995 100644 --- a/sys/netinet6/esp_rijndael.c +++ b/sys/netinet6/esp_rijndael.c @@ -51,7 +51,7 @@ #include <net/net_osdep.h> /* as rijndael uses assymetric scheduled keys, we need to do it twice. */ -int +size_t esp_rijndael_schedlen(algo) const struct esp_algorithm *algo; { diff --git a/sys/netinet6/esp_rijndael.h b/sys/netinet6/esp_rijndael.h index 0c40d78..5018bf1 100644 --- a/sys/netinet6/esp_rijndael.h +++ b/sys/netinet6/esp_rijndael.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -int esp_rijndael_schedlen __P((const struct esp_algorithm *)); +size_t esp_rijndael_schedlen __P((const struct esp_algorithm *)); int esp_rijndael_schedule __P((const struct esp_algorithm *, struct secasvar *)); int esp_rijndael_blockdecrypt __P((const struct esp_algorithm *, |