1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00

- 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
This commit is contained in:
Hajimu UMEMOTO 2003-10-13 14:57:41 +00:00
parent 3a2e2a0ec8
commit b42ac57f4f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121071
14 changed files with 550 additions and 22 deletions

View File

@ -196,6 +196,9 @@ static struct val2str str_alg_enc[] = {
#endif
#ifdef SADB_X_EALG_TWOFISHCBC
{ SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
#endif
#ifdef SADB_X_EALG_AESCTR
{ SADB_X_EALG_AESCTR, "aes-ctr", },
#endif
{ -1, NULL, },
};

View File

@ -573,8 +573,13 @@ cast128-cbc 40 to 128 rfc2451
des-deriv 64 ipsec-ciph-des-derived-01 (expired)
3des-deriv 192 no document
rijndael-cbc 128/192/256 draft-ietf-ipsec-ciph-aes-cbc-00
aes-ctr 160/224/288 draft-ietf-ipsec-ciph-aes-ctr-03
.Ed
.Pp
Note that the first 128 bits of a key for
.Li aes-ctr
will be used as AES key, and remaining 32 bits will be used as nonce.
.Pp
Followings are the list of compression algorithms that can be used as
.Ar calgo
in

View File

@ -184,6 +184,7 @@ cast128-cbc { PREPROC; yylval.num = SADB_X_EALG_CAST128CBC; return(ALG_ENC); }
des-deriv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DESDERIV); }
des-32iv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DES32IV); }
rijndael-cbc { PREPROC; yylval.num = SADB_X_EALG_RIJNDAELCBC; return(ALG_ENC); }
aes-ctr { PREPROC; yylval.num = SADB_X_EALG_AESCTR; return(ALG_ENC); }
/* compression algorithms */
{hyphen}C { PREPROC; return(F_COMP); }

View File

@ -1731,6 +1731,7 @@ Currently supported algorithms are:
HMAC SHA2-384 with 96bit crypto checksum (no document)
HMAC SHA2-512 with 96bit crypto checksum (no document)
HMAC RIPEMD160 with 96bit crypto checksum (RFC2857)
AES XCBC MAC with 96bit crypto checksum (RFC3566)
new IPsec ESP
null encryption (rfc2410.txt)
DES-CBC with derived IV
@ -1739,9 +1740,9 @@ Currently supported algorithms are:
3DES-CBC with explicit IV (rfc2451.txt)
BLOWFISH CBC (rfc2451.txt)
CAST128 CBC (rfc2451.txt)
RIJNDAEL/AES CBC (draft-ietf-ipsec-ciph-aes-cbc-00.txt,
uses IANA-assigned protocol number)
TWOFISH CBC (draft-ietf-ipsec-ciph-aes-cbc-00.txt)
RIJNDAEL/AES CBC (rfc3602.txt)
AES counter mode (draft-ietf-ipsec-ciph-aes-ctr-03.txt)
each of the above can be combined with:
ESP authentication with HMAC-MD5(96bit)
ESP authentication with HMAC-SHA1(96bit)

View File

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

View File

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

View File

@ -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,

463
sys/netinet6/esp_aesctr.c Normal file
View File

@ -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;
}

42
sys/netinet6/esp_aesctr.h Normal file
View File

@ -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));

View File

@ -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;
{

View File

@ -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;
{

View File

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

View File

@ -573,8 +573,13 @@ cast128-cbc 40 to 128 rfc2451
des-deriv 64 ipsec-ciph-des-derived-01 (expired)
3des-deriv 192 no document
rijndael-cbc 128/192/256 draft-ietf-ipsec-ciph-aes-cbc-00
aes-ctr 160/224/288 draft-ietf-ipsec-ciph-aes-ctr-03
.Ed
.Pp
Note that the first 128 bits of a key for
.Li aes-ctr
will be used as AES key, and remaining 32 bits will be used as nonce.
.Pp
Followings are the list of compression algorithms that can be used as
.Ar calgo
in

View File

@ -184,6 +184,7 @@ cast128-cbc { PREPROC; yylval.num = SADB_X_EALG_CAST128CBC; return(ALG_ENC); }
des-deriv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DESDERIV); }
des-32iv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DES32IV); }
rijndael-cbc { PREPROC; yylval.num = SADB_X_EALG_RIJNDAELCBC; return(ALG_ENC); }
aes-ctr { PREPROC; yylval.num = SADB_X_EALG_AESCTR; return(ALG_ENC); }
/* compression algorithms */
{hyphen}C { PREPROC; return(F_COMP); }