summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libipsec/pfkey_dump.c3
-rw-r--r--sbin/setkey/setkey.85
-rw-r--r--sbin/setkey/token.l1
-rw-r--r--share/doc/IPv6/IMPLEMENTATION7
-rw-r--r--sys/conf/files1
-rw-r--r--sys/net/pfkeyv2.h8
-rw-r--r--sys/netinet6/esp.h2
-rw-r--r--sys/netinet6/esp_aesctr.c463
-rw-r--r--sys/netinet6/esp_aesctr.h42
-rw-r--r--sys/netinet6/esp_core.c30
-rw-r--r--sys/netinet6/esp_rijndael.c2
-rw-r--r--sys/netinet6/esp_rijndael.h2
-rw-r--r--usr.sbin/setkey/setkey.85
-rw-r--r--usr.sbin/setkey/token.l1
14 files changed, 550 insertions, 22 deletions
diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c
index b2cddf2..0113e14 100644
--- a/lib/libipsec/pfkey_dump.c
+++ b/lib/libipsec/pfkey_dump.c
@@ -197,6 +197,9 @@ static struct val2str str_alg_enc[] = {
#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, },
};
diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8
index 680803b..4ab8927 100644
--- a/sbin/setkey/setkey.8
+++ b/sbin/setkey/setkey.8
@@ -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
diff --git a/sbin/setkey/token.l b/sbin/setkey/token.l
index 312df4c..5f73594 100644
--- a/sbin/setkey/token.l
+++ b/sbin/setkey/token.l
@@ -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); }
diff --git a/share/doc/IPv6/IMPLEMENTATION b/share/doc/IPv6/IMPLEMENTATION
index 5bc6bd6..50ca516 100644
--- a/share/doc/IPv6/IMPLEMENTATION
+++ b/share/doc/IPv6/IMPLEMENTATION
@@ -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)
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 *,
diff --git a/usr.sbin/setkey/setkey.8 b/usr.sbin/setkey/setkey.8
index 680803b..4ab8927 100644
--- a/usr.sbin/setkey/setkey.8
+++ b/usr.sbin/setkey/setkey.8
@@ -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
diff --git a/usr.sbin/setkey/token.l b/usr.sbin/setkey/token.l
index 312df4c..5f73594 100644
--- a/usr.sbin/setkey/token.l
+++ b/usr.sbin/setkey/token.l
@@ -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); }
OpenPOWER on IntegriCloud