diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2005-05-25 05:47:54 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2005-05-25 05:47:54 +0000 |
commit | 2e172c5c337953c5b261a718c224233f55f766fa (patch) | |
tree | 04020363676641299cc1fc4c174c92903fc2557d | |
parent | da59a2318f0f71de02a778d5bfa0e8c13ea567d4 (diff) |
AESCTR support for ESP (RFC 3686); ok hshoexer
-rw-r--r-- | regress/sys/crypto/Makefile | 4 | ||||
-rw-r--r-- | regress/sys/crypto/aesctr/Makefile | 10 | ||||
-rw-r--r-- | regress/sys/crypto/aesctr/aesctr.c | 300 | ||||
-rw-r--r-- | sys/crypto/cryptodev.c | 5 | ||||
-rw-r--r-- | sys/crypto/cryptodev.h | 5 | ||||
-rw-r--r-- | sys/crypto/cryptosoft.c | 47 | ||||
-rw-r--r-- | sys/crypto/rijndael.c | 4 | ||||
-rw-r--r-- | sys/crypto/rijndael.h | 4 | ||||
-rw-r--r-- | sys/crypto/xform.c | 119 | ||||
-rw-r--r-- | sys/crypto/xform.h | 6 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 12 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 3 | ||||
-rw-r--r-- | sys/net/pfkeyv2_convert.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 11 |
14 files changed, 487 insertions, 49 deletions
diff --git a/regress/sys/crypto/Makefile b/regress/sys/crypto/Makefile index 7edc911464d..e2a2269aa53 100644 --- a/regress/sys/crypto/Makefile +++ b/regress/sys/crypto/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.3 2004/03/14 18:37:52 markus Exp $ +# $OpenBSD: Makefile,v 1.4 2005/05/25 05:47:53 markus Exp $ SUBDIR=enc -#SUBDIR+=auth +SUBDIR+=aesctr install: diff --git a/regress/sys/crypto/aesctr/Makefile b/regress/sys/crypto/aesctr/Makefile new file mode 100644 index 00000000000..31ae500f188 --- /dev/null +++ b/regress/sys/crypto/aesctr/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2005/05/25 05:47:53 markus Exp $ + +PROG= aesctr + +REGRESS_ROOT_TARGETS= run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + ${SUDO} ./${PROG} + +.include <bsd.regress.mk> diff --git a/regress/sys/crypto/aesctr/aesctr.c b/regress/sys/crypto/aesctr/aesctr.c new file mode 100644 index 00000000000..4cc1a6e39ce --- /dev/null +++ b/regress/sys/crypto/aesctr/aesctr.c @@ -0,0 +1,300 @@ +/* $OpenBSD: aesctr.c,v 1.1 2005/05/25 05:47:53 markus Exp $ */ + +/* + * Copyright (c) 2005 Markus Friedl <markus@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/sysctl.h> +#include <crypto/cryptodev.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> + +int debug = 0; + +enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM }; + +/* Test vectors from RFC 3686 */ +struct { + char *data[TST_NUM]; +} tests[] = { + /* 128 bit key */ + { + "AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E " + "00 00 00 30", + "00 00 00 00 00 00 00 00", + "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", + "E4 09 5D 4F B7 A7 B3 79 2D 61 75 A3 26 13 11 B8" + }, + { + "7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 " + "00 6C B6 DB", + "C0 54 3B 59 DA 48 D9 0B", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", + "51 04 A1 06 16 8A 72 D9 79 0D 41 EE 8E DA D3 88 " + "EB 2E 1E FC 46 DA 57 C8 FC E6 30 DF 91 41 BE 28" + }, + { + "76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC " + "00 E0 01 7B", + "27 77 7F 3F 4A 17 86 F0", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" + /*"20 21 22 23"*/, + "C1 CF 48 A8 9F 2F FD D9 CF 46 52 E9 EF DB 72 D7 " + "45 40 A4 2B DE 6D 78 36 D5 9A 5C EA AE F3 10 53" + /*"25 B2 07 2F"*/ + }, + /* 192 bit key */ + { + "16 AF 5B 14 5F C9 F5 79 C1 75 F9 3E 3B FB 0E ED " + "86 3D 06 CC FD B7 85 15 " + "00 00 00 48", + "36 73 3C 14 7D 6D 93 CB", + "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", + "4B 55 38 4F E2 59 C9 C8 4E 79 35 A0 03 CB E9 28", + }, + { + "7C 5C B2 40 1B 3D C3 3C 19 E7 34 08 19 E0 F6 9C " + "67 8C 3D B8 E6 F6 A9 1A " + "00 96 B0 3B", + "02 0C 6E AD C2 CB 50 0D", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", + "45 32 43 FC 60 9B 23 32 7E DF AA FA 71 31 CD 9F " + "84 90 70 1C 5A D4 A7 9C FC 1F E0 FF 42 F4 FB 00", + }, + { + "02 BF 39 1E E8 EC B1 59 B9 59 61 7B 09 65 27 9B " + "F5 9B 60 A7 86 D3 E0 FE " + "00 07 BD FD", + "5C BD 60 27 8D CC 09 12", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" + /*"20 21 22 23"*/, + "96 89 3F C5 5E 5C 72 2F 54 0B 7D D1 DD F7 E7 58 " + "D2 88 BC 95 C6 91 65 88 45 36 C8 11 66 2F 21 88" + /*"AB EE 09 35"*/, + }, + /* 256 bit key */ + { + "77 6B EF F2 85 1D B0 6F 4C 8A 05 42 C8 69 6F 6C " + "6A 81 AF 1E EC 96 B4 D3 7F C1 D6 89 E6 C1 C1 04 " + "00 00 00 60", + "DB 56 72 C9 7A A8 F0 B2", + "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", + "14 5A D0 1D BF 82 4E C7 56 08 63 DC 71 E3 E0 C0" + }, + { + "F6 D6 6D 6B D5 2D 59 BB 07 96 36 58 79 EF F8 86 " + "C6 6D D5 1A 5B 6A 99 74 4B 50 59 0C 87 A2 38 84 " + "00 FA AC 24", + "C1 58 5E F1 5A 43 D8 75", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", + "F0 5E 23 1B 38 94 61 2C 49 EE 00 0B 80 4E B2 A9 " + "B8 30 6B 50 8F 83 9D 6A 55 30 83 1D 93 44 AF 1C", + }, + { + "FF 7A 61 7C E6 91 48 E4 F1 72 6E 2F 43 58 1D E2 " + "AA 62 D9 F8 05 53 2E DF F1 EE D6 87 FB 54 15 3D " + "00 1C C5 B7", + "51 A5 1D 70 A1 C1 11 48", + "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " + "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" + /*"20 21 22 23"*/, + "EB 6C 52 82 1D 0B BB F7 CE 75 94 46 2A CA 4F AA " + "B4 07 DF 86 65 69 FD 07 F4 8C C0 B5 83 D6 07 1F" + /*"1E C0 E6 B8"*/, + }, +}; + +static int +syscrypt(const unsigned char *key, size_t klen, const unsigned char *iv, + const unsigned char *in, unsigned char *out, size_t len, int encrypt) +{ + struct session_op session; + struct crypt_op cryp; + int cryptodev_fd = -1, fd = -1; + + if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + warn("/dev/crypto"); + goto err; + } + if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { + warn("CRIOGET failed"); + goto err; + } + memset(&session, 0, sizeof(session)); + session.cipher = CRYPTO_AES_CTR; + session.key = (caddr_t) key; + session.keylen = klen; + if (ioctl(fd, CIOCGSESSION, &session) == -1) { + warn("CIOCGSESSION"); + goto err; + } + memset(&cryp, 0, sizeof(cryp)); + cryp.ses = session.ses; + cryp.op = encrypt ? COP_ENCRYPT : COP_DECRYPT; + cryp.flags = 0; + cryp.len = len; + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.iv = (caddr_t) iv; + cryp.mac = 0; + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + warn("CIOCCRYPT"); + goto err; + } + if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) { + warn("CIOCFSESSION"); + goto err; + } + close(fd); + close(cryptodev_fd); + return (0); + +err: + if (fd != -1) + close(fd); + if (cryptodev_fd != -1) + close(cryptodev_fd); + return (-1); +} + +static int +getallowsoft(void) +{ + int mib[2], old; + size_t olen; + + olen = sizeof(old); + + mib[0] = CTL_KERN; + mib[1] = KERN_CRYPTODEVALLOWSOFT; + if (sysctl(mib, 2, &old, &olen, NULL, 0) < 0) + err(1, "sysctl failed"); + + return old; +} + +static void +setallowsoft(int new) +{ + int mib[2], old; + size_t olen, nlen; + + olen = nlen = sizeof(new); + + mib[0] = CTL_KERN; + mib[1] = KERN_CRYPTODEVALLOWSOFT; + + if (sysctl(mib, 2, &old, &olen, &new, nlen) < 0) + err(1, "sysctl failed"); +} + +static int +match(unsigned char *a, unsigned char *b, size_t len) +{ + int i; + + if (memcmp(a, b, len) == 0) + return (1); + + warnx("ciphertext mismatch"); + + for (i = 0; i < len; i++) + printf("%2.2x", a[i]); + printf("\n"); + for (i = 0; i < len; i++) + printf("%2.2x", b[i]); + printf("\n"); + + return (0); +} + +static int +run(int num) +{ + int i, fail = 1, len, j, length[TST_NUM]; + u_long val; + char *ep, *from; + u_char *p, *data[TST_NUM]; + + for (i = 0; i < TST_NUM; i++) + data[i] = NULL; + for (i = 0; i < TST_NUM; i++) { + from = tests[num].data[i]; + if (debug) + printf("%s\n", from); + len = strlen(from); + if ((p = malloc(len)) == 0) { + warn("malloc"); + goto done; + } + errno = 0; + for (j = 0; j < len; j++) { + val = strtoul(&from[j*3], &ep, 16); + p[j] = (u_char)val; + if (*ep == '\0' || errno) + break; + } + length[i] = j+1; + data[i] = p; + } + len = length[TST_PLAIN]; + if ((p = malloc(len)) == 0) { + warn("malloc"); + return (1); + } + if (syscrypt(data[TST_KEY], length[TST_KEY], + data[TST_IV], data[TST_PLAIN], p, + length[TST_PLAIN], 0) < 0) { + warnx("crypt with /dev/crypto failed"); + goto done; + } + fail = !match(data[TST_CIPHER], p, len); + printf("%s test vector %d\n", fail ? "FAILED" : "OK", num); +done: + for (i = 0; i < TST_NUM; i++) + free(data[i]); + return (fail); +} + +int +main(int argc, char **argv) +{ + int allowed = 0, fail = 0, i; + + if (geteuid() == 0) { + allowed = getallowsoft(); + if (allowed == 0) + setallowsoft(1); + } + for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) + fail += run(i); + if (geteuid() == 0 && allowed == 0) + setallowsoft(0); + exit((fail > 0) ? 1 : 0); +} diff --git a/sys/crypto/cryptodev.c b/sys/crypto/cryptodev.c index 7325da55281..bd1e888d368 100644 --- a/sys/crypto/cryptodev.c +++ b/sys/crypto/cryptodev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptodev.c,v 1.62 2004/05/07 14:42:26 millert Exp $ */ +/* $OpenBSD: cryptodev.c,v 1.63 2005/05/25 05:47:53 markus Exp $ */ /* * Copyright (c) 2001 Theo de Raadt @@ -173,6 +173,9 @@ cryptof_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p) case CRYPTO_AES_CBC: txform = &enc_xform_rijndael128; break; + case CRYPTO_AES_CTR: + txform = &enc_xform_aes_ctr; + break; case CRYPTO_ARC4: txform = &enc_xform_arc4; break; diff --git a/sys/crypto/cryptodev.h b/sys/crypto/cryptodev.h index eac54325840..e14b18b56e0 100644 --- a/sys/crypto/cryptodev.h +++ b/sys/crypto/cryptodev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptodev.h,v 1.42 2003/08/14 15:18:05 jason Exp $ */ +/* $OpenBSD: cryptodev.h,v 1.43 2005/05/25 05:47:53 markus Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -96,7 +96,8 @@ #define CRYPTO_SHA2_256_HMAC 18 #define CRYPTO_SHA2_384_HMAC 19 #define CRYPTO_SHA2_512_HMAC 20 -#define CRYPTO_ALGORITHM_MAX 20 /* Keep updated - see below */ +#define CRYPTO_AES_CTR 21 +#define CRYPTO_ALGORITHM_MAX 21 /* Keep updated - see below */ #define CRYPTO_ALGORITHM_ALL (CRYPTO_ALGORITHM_MAX + 1) diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c index e1fdd00cae4..a96a317dd71 100644 --- a/sys/crypto/cryptosoft.c +++ b/sys/crypto/cryptosoft.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptosoft.c,v 1.44 2005/05/10 13:42:11 markus Exp $ */ +/* $OpenBSD: cryptosoft.c,v 1.45 2005/05/25 05:47:53 markus Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -82,21 +82,18 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; struct enc_xform *exf; - int i, k, j, blks, ind, count; + int i, k, j, blks, ind, count, ivlen; struct mbuf *m = NULL; struct uio *uio = NULL; - exf = sw->sw_exf; blks = exf->blocksize; + ivlen = exf->ivsize; /* Check for non-padded data */ if (crd->crd_len % blks) return EINVAL; - if (exf == &enc_xform_null) - return (0); - if (outtype == CRYPTO_BUF_MBUF) m = (struct mbuf *) buf; else @@ -106,27 +103,30 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, iv, blks); + bcopy(crd->crd_iv, iv, ivlen); else - arc4random_bytes(iv, blks); + arc4random_bytes(iv, ivlen); /* Do we need to write the IV */ if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { - COPYBACK(outtype, buf, crd->crd_inject, blks, iv); + COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv); } } else { /* Decryption */ /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, iv, blks); + bcopy(crd->crd_iv, iv, ivlen); else { /* Get IV off buf */ - COPYDATA(outtype, buf, crd->crd_inject, blks, iv); + COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); } } ivp = iv; + if (exf->reinit) + exf->reinit(sw->sw_kschedule, iv); + if (outtype == CRYPTO_BUF_MBUF) { /* Find beginning of data */ m = m_getptr(m, crd->crd_skip, &k); @@ -144,7 +144,9 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, m_copydata(m, k, blks, blk); /* Actual encryption/decryption */ - if (crd->crd_flags & CRD_F_ENCRYPT) { + if (exf->reinit) { + exf->encrypt(sw->sw_kschedule, blk); + } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; @@ -214,7 +216,9 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, idat = mtod(m, unsigned char *) + k; while (m->m_len >= k + blks && i > 0) { - if (crd->crd_flags & CRD_F_ENCRYPT) { + if (exf->reinit) { + exf->encrypt(sw->sw_kschedule, idat); + } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; @@ -267,7 +271,9 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ - if (crd->crd_flags & CRD_F_ENCRYPT) { + if (exf->reinit) { + exf->encrypt(sw->sw_kschedule, blk); + } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; @@ -328,7 +334,9 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, while (uio->uio_iov[ind].iov_len >= k + blks && i > 0) { - if (crd->crd_flags & CRD_F_ENCRYPT) { + if (exf->reinit) { + exf->encrypt(sw->sw_kschedule, idat); + } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; @@ -599,6 +607,9 @@ swcr_newsession(u_int32_t *sid, struct cryptoini *cri) case CRYPTO_RIJNDAEL128_CBC: txf = &enc_xform_rijndael128; goto enccommon; + case CRYPTO_AES_CTR: + txf = &enc_xform_aes_ctr; + goto enccommon; case CRYPTO_NULL: txf = &enc_xform_null; goto enccommon; @@ -760,6 +771,7 @@ swcr_freesession(u_int64_t tid) case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: + case CRYPTO_AES_CTR: case CRYPTO_NULL: txf = swd->sw_exf; @@ -868,13 +880,15 @@ swcr_process(struct cryptop *crp) } switch (sw->sw_alg) { + case CRYPTO_NULL: + break; case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: - case CRYPTO_NULL: + case CRYPTO_AES_CTR: if ((crp->crp_etype = swcr_encdec(crd, sw, crp->crp_buf, type)) != 0) goto done; @@ -945,6 +959,7 @@ swcr_init(void) algs[CRYPTO_MD5] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_RIJNDAEL128_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_DEFLATE_COMP] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_NULL] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; diff --git a/sys/crypto/rijndael.c b/sys/crypto/rijndael.c index e1dcb0dae64..1edca913680 100644 --- a/sys/crypto/rijndael.c +++ b/sys/crypto/rijndael.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rijndael.c,v 1.17 2004/12/20 20:31:18 hshoexer Exp $ */ +/* $OpenBSD: rijndael.c,v 1.18 2005/05/25 05:47:53 markus Exp $ */ /** * rijndael-alg-fst.c @@ -851,7 +851,7 @@ rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) return Nr; } -static void +void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { diff --git a/sys/crypto/rijndael.h b/sys/crypto/rijndael.h index 6b509576c6a..190b4c5f555 100644 --- a/sys/crypto/rijndael.h +++ b/sys/crypto/rijndael.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rijndael.h,v 1.10 2004/12/20 20:31:18 hshoexer Exp $ */ +/* $OpenBSD: rijndael.h,v 1.11 2005/05/25 05:47:53 markus Exp $ */ /** * rijndael-alg-fst.h @@ -51,5 +51,7 @@ void rijndael_encrypt(rijndael_ctx *, u_char *, u_char *); int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int); int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int); +void rijndaelEncrypt(const unsigned int [], int, const unsigned char [], + unsigned char []); #endif /* __RIJNDAEL_H */ diff --git a/sys/crypto/xform.c b/sys/crypto/xform.c index c9f42a648e4..b0b9b513092 100644 --- a/sys/crypto/xform.c +++ b/sys/crypto/xform.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xform.c,v 1.28 2004/12/20 20:31:18 hshoexer Exp $ */ +/* $OpenBSD: xform.c,v 1.29 2005/05/25 05:47:53 markus Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -67,6 +67,7 @@ int blf_setkey(u_int8_t **, u_int8_t *, int); int cast5_setkey(u_int8_t **, u_int8_t *, int); int skipjack_setkey(u_int8_t **, u_int8_t *, int); int rijndael128_setkey(u_int8_t **, u_int8_t *, int); +int aes_ctr_setkey(u_int8_t **, u_int8_t *, int); void des1_encrypt(caddr_t, u_int8_t *); void des3_encrypt(caddr_t, u_int8_t *); void blf_encrypt(caddr_t, u_int8_t *); @@ -85,11 +86,15 @@ void blf_zerokey(u_int8_t **); void cast5_zerokey(u_int8_t **); void skipjack_zerokey(u_int8_t **); void rijndael128_zerokey(u_int8_t **); +void aes_ctr_zerokey(u_int8_t **); void null_encrypt(caddr_t, u_int8_t *); void null_zerokey(u_int8_t **); int null_setkey(u_int8_t **, u_int8_t *, int); void null_decrypt(caddr_t, u_int8_t *); +void aes_ctr_reinit(caddr_t, u_int8_t *); +void aes_ctr_crypt(caddr_t, u_int8_t *); + int MD5Update_int(void *, u_int8_t *, u_int16_t); int SHA1Update_int(void *, u_int8_t *, u_int16_t); int RMD160Update_int(void *, u_int8_t *, u_int16_t); @@ -104,74 +109,92 @@ u_int32_t lzs_dummy(u_int8_t *, u_int32_t, u_int8_t **); /* Encryption instances */ struct enc_xform enc_xform_des = { CRYPTO_DES_CBC, "DES", - 8, 8, 8, + 8, 8, 8, 8, des1_encrypt, des1_decrypt, des1_setkey, des1_zerokey, + NULL }; struct enc_xform enc_xform_3des = { CRYPTO_3DES_CBC, "3DES", - 8, 24, 24, + 8, 8, 24, 24, des3_encrypt, des3_decrypt, des3_setkey, - des3_zerokey + des3_zerokey, + NULL }; struct enc_xform enc_xform_blf = { CRYPTO_BLF_CBC, "Blowfish", - 8, 5, 56 /* 448 bits, max key */, + 8, 8, 5, 56 /* 448 bits, max key */, blf_encrypt, blf_decrypt, blf_setkey, - blf_zerokey + blf_zerokey, + NULL }; struct enc_xform enc_xform_cast5 = { CRYPTO_CAST_CBC, "CAST-128", - 8, 5, 16, + 8, 8, 5, 16, cast5_encrypt, cast5_decrypt, cast5_setkey, - cast5_zerokey + cast5_zerokey, + NULL }; struct enc_xform enc_xform_skipjack = { CRYPTO_SKIPJACK_CBC, "Skipjack", - 8, 10, 10, + 8, 8, 10, 10, skipjack_encrypt, skipjack_decrypt, skipjack_setkey, - skipjack_zerokey + skipjack_zerokey, + NULL }; struct enc_xform enc_xform_rijndael128 = { CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES", - 16, 16, 32, + 16, 16, 16, 32, rijndael128_encrypt, rijndael128_decrypt, rijndael128_setkey, rijndael128_zerokey, + NULL +}; + +struct enc_xform enc_xform_aes_ctr = { + CRYPTO_AES_CTR, "AES-CTR", + 16, 8, 16+4, 32+4, + aes_ctr_crypt, + NULL, + aes_ctr_setkey, + aes_ctr_zerokey, + aes_ctr_reinit }; struct enc_xform enc_xform_arc4 = { CRYPTO_ARC4, "ARC4", - 1, 1, 32, + 1, 1, 1, 32, NULL, NULL, NULL, NULL, + NULL }; struct enc_xform enc_xform_null = { CRYPTO_NULL, "NULL", - 8, 24, 24, + 1, 0, 0, 256, null_encrypt, null_decrypt, null_setkey, null_zerokey, + NULL }; /* Authentication instances */ @@ -486,6 +509,76 @@ rijndael128_zerokey(u_int8_t **sched) *sched = NULL; } +#define AESCTR_NONCESIZE 4 +#define AESCTR_IVSIZE 8 +#define AESCTR_BLOCKSIZE 16 + +struct aes_ctr_ctx { + u_int32_t ac_ek[4*(MAXNR + 1)]; + u_int8_t ac_block[AESCTR_BLOCKSIZE]; + int ac_nr; +}; + +void +aes_ctr_reinit(caddr_t key, u_int8_t *iv) +{ + struct aes_ctr_ctx *ctx; + + ctx = (struct aes_ctr_ctx *)key; + bcopy(iv, ctx->ac_block + AESCTR_NONCESIZE, AESCTR_IVSIZE); + + /* reset counter */ + bzero(ctx->ac_block + AESCTR_NONCESIZE + AESCTR_IVSIZE, 4); +} + +void +aes_ctr_crypt(caddr_t key, u_int8_t *data) +{ + struct aes_ctr_ctx *ctx; + u_int8_t keystream[AESCTR_BLOCKSIZE]; + int i; + + ctx = (struct aes_ctr_ctx *)key; + /* increment counter */ + for (i = AESCTR_BLOCKSIZE - 1; + i >= AESCTR_NONCESIZE + AESCTR_IVSIZE; i--) + if (++ctx->ac_block[i]) /* continue on overflow */ + break; + rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream); + for (i = 0; i < AESCTR_BLOCKSIZE; i++) + data[i] ^= keystream[i]; +} + +int +aes_ctr_setkey(u_int8_t **sched, u_int8_t *key, int len) +{ + struct aes_ctr_ctx *ctx; + + if (len < AESCTR_NONCESIZE) + return -1; + + MALLOC(*sched, u_int8_t *, sizeof(struct aes_ctr_ctx), M_CRYPTO_DATA, + M_WAITOK); + bzero(*sched, sizeof(struct aes_ctr_ctx)); + ctx = (struct aes_ctr_ctx *)*sched; + ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, + (len - AESCTR_NONCESIZE) * 8); + if (ctx->ac_nr == 0) { + aes_ctr_zerokey(sched); + return -1; + } + bcopy(key + len - AESCTR_NONCESIZE, ctx->ac_block, AESCTR_NONCESIZE); + return 0; +} + +void +aes_ctr_zerokey(u_int8_t **sched) +{ + bzero(*sched, sizeof(struct aes_ctr_ctx)); + FREE(*sched, M_CRYPTO_DATA); + *sched = NULL; +} + /* * And now for auth. */ diff --git a/sys/crypto/xform.h b/sys/crypto/xform.h index fa7838665c2..b2e19c99ed2 100644 --- a/sys/crypto/xform.h +++ b/sys/crypto/xform.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xform.h,v 1.15 2004/12/20 20:31:18 hshoexer Exp $ */ +/* $OpenBSD: xform.h,v 1.16 2005/05/25 05:47:53 markus Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -45,12 +45,13 @@ struct auth_hash { struct enc_xform { int type; char *name; - u_int16_t blocksize; + u_int16_t blocksize, ivsize; u_int16_t minkey, maxkey; void (*encrypt) (caddr_t, u_int8_t *); void (*decrypt) (caddr_t, u_int8_t *); int (*setkey) (u_int8_t **, u_int8_t *, int len); void (*zerokey) (u_int8_t **); + void (*reinit) (caddr_t, u_int8_t *); }; struct comp_algo { @@ -76,6 +77,7 @@ extern struct enc_xform enc_xform_blf; extern struct enc_xform enc_xform_cast5; extern struct enc_xform enc_xform_skipjack; extern struct enc_xform enc_xform_rijndael128; +extern struct enc_xform enc_xform_aes_ctr; extern struct enc_xform enc_xform_arc4; extern struct enc_xform enc_xform_null; diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 770c301048a..8abc1dca9ee 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.103 2005/05/24 03:13:53 ho Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.104 2005/05/25 05:47:53 markus Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -100,7 +100,8 @@ static const struct sadb_alg ealgs[] = { { SADB_X_EALG_BLF, 64, 40, BLF_MAXKEYLEN * 8}, { SADB_X_EALG_CAST, 64, 40, 128}, { SADB_X_EALG_SKIPJACK, 64, 80, 80}, - { SADB_X_EALG_AES, 128, 64, 256} + { SADB_X_EALG_AES, 128, 128, 256}, + { SADB_X_EALG_AESCTR, 128, 128 + 32, 256 + 32} }; static const struct sadb_alg aalgs[] = { @@ -1958,8 +1959,13 @@ pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw, if (!strncasecmp(ipsec_def_enc, "aes", sizeof("aes"))) { sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES; - sadb_comb->sadb_comb_encrypt_minbits = 64; + sadb_comb->sadb_comb_encrypt_minbits = 128; sadb_comb->sadb_comb_encrypt_maxbits = 256; + } else if (!strncasecmp(ipsec_def_enc, "aesctr", + sizeof("aesctr"))) { + sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR; + sadb_comb->sadb_comb_encrypt_minbits = 128+32; + sadb_comb->sadb_comb_encrypt_maxbits = 256+32; } else if (!strncasecmp(ipsec_def_enc, "3des", sizeof("3des"))) { sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 1ad5702a79a..4738ffd66ce 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.h,v 1.53 2005/04/04 22:18:47 hshoexer Exp $ */ +/* $OpenBSD: pfkeyv2.h,v 1.54 2005/05/25 05:47:53 markus Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) January 1998 * @@ -299,6 +299,7 @@ struct sadb_x_udpencap { #define SADB_X_EALG_RC4 10 #define SADB_EALG_NULL 11 #define SADB_X_EALG_AES 12 +#define SADB_X_EALG_AESCTR 13 #define SADB_X_EALG_SKIPJACK 249 #define SADB_EALG_MAX 249 diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c index 0c7f1963414..43b24904338 100644 --- a/sys/net/pfkeyv2_convert.c +++ b/sys/net/pfkeyv2_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2_convert.c,v 1.23 2005/05/24 02:30:03 ho Exp $ */ +/* $OpenBSD: pfkeyv2_convert.c,v 1.24 2005/05/25 05:47:53 markus Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@keromytis.org) * @@ -232,6 +232,10 @@ export_sa(void **p, struct tdb *tdb) sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES; break; + case CRYPTO_AES_CTR: + sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR; + break; + case CRYPTO_CAST_CBC: sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST; break; diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index 47cff502423..26f2a1eff29 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.89 2005/05/10 13:42:11 markus Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.90 2005/05/25 05:47:53 markus Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -113,6 +113,10 @@ esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) txform = &enc_xform_rijndael128; break; + case SADB_X_EALG_AESCTR: + txform = &enc_xform_aes_ctr; + break; + case SADB_X_EALG_BLF: txform = &enc_xform_blf; break; @@ -145,10 +149,7 @@ esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n", txform->name)); - if (ii->ii_encalg == SADB_EALG_NULL) - tdbp->tdb_ivlen = 0; - else - tdbp->tdb_ivlen = txform->blocksize; + tdbp->tdb_ivlen = txform->ivsize; if (tdbp->tdb_flags & TDBF_HALFIV) tdbp->tdb_ivlen /= 2; } |