Module Name: src Committed By: drochner Date: Tue May 24 18:52:52 UTC 2011
Modified Files: src/sys/opencrypto: cryptosoft.c cryptosoft_xform.c Log Message: Change the way the IV is generated for AES-CTR: use a simple counter instead of arc4random(). AES-CTR is sensitive against IV recurrence (with the same key / nonce), and a random number doesn't give that guarantee. This needs a little API change in cryptosoft -- I've suggested it to Open/FreeBSD, might change it depending on feedback. Thanks to Steven Bellovin for hints. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/sys/opencrypto/cryptosoft.c cvs rdiff -u -r1.19 -r1.20 src/sys/opencrypto/cryptosoft_xform.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/opencrypto/cryptosoft.c diff -u src/sys/opencrypto/cryptosoft.c:1.33 src/sys/opencrypto/cryptosoft.c:1.34 --- src/sys/opencrypto/cryptosoft.c:1.33 Mon May 23 13:51:10 2011 +++ src/sys/opencrypto/cryptosoft.c Tue May 24 18:52:51 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cryptosoft.c,v 1.33 2011/05/23 13:51:10 drochner Exp $ */ +/* $NetBSD: cryptosoft.c,v 1.34 2011/05/24 18:52:51 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.33 2011/05/23 13:51:10 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.34 2011/05/24 18:52:51 drochner Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -92,9 +92,13 @@ /* Initialize the IV */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ - if (crd->crd_flags & CRD_F_IV_EXPLICIT) + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crd->crd_iv, ivlen); - else { + if (exf->reinit) + exf->reinit(sw->sw_kschedule, iv, 0); + } else if (exf->reinit) { + exf->reinit(sw->sw_kschedule, 0, iv); + } else { /* Get random IV */ for (i = 0; i + sizeof (u_int32_t) <= EALG_MAX_BLOCK_LEN; @@ -129,13 +133,12 @@ /* Get IV off buf */ COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); } + if (exf->reinit) + exf->reinit(sw->sw_kschedule, iv, 0); } ivp = iv; - if (exf->reinit) - exf->reinit(sw->sw_kschedule, iv); - if (outtype == CRYPTO_BUF_CONTIG) { if (exf->reinit) { for (i = crd->crd_skip; Index: src/sys/opencrypto/cryptosoft_xform.c diff -u src/sys/opencrypto/cryptosoft_xform.c:1.19 src/sys/opencrypto/cryptosoft_xform.c:1.20 --- src/sys/opencrypto/cryptosoft_xform.c:1.19 Mon May 23 15:37:36 2011 +++ src/sys/opencrypto/cryptosoft_xform.c Tue May 24 18:52:51 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cryptosoft_xform.c,v 1.19 2011/05/23 15:37:36 drochner Exp $ */ +/* $NetBSD: cryptosoft_xform.c,v 1.20 2011/05/24 18:52:51 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $ */ @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: cryptosoft_xform.c,v 1.19 2011/05/23 15:37:36 drochner Exp $"); +__KERNEL_RCSID(1, "$NetBSD: cryptosoft_xform.c,v 1.20 2011/05/24 18:52:51 drochner Exp $"); #include <crypto/blowfish/blowfish.h> #include <crypto/cast128/cast128.h> @@ -68,7 +68,7 @@ void (*decrypt)(void *, uint8_t *); int (*setkey)(uint8_t **, const uint8_t *, int); void (*zerokey)(uint8_t **); - void (*reinit)(void *, const uint8_t *); + void (*reinit)(void *, const uint8_t *, uint8_t *); }; struct swcr_comp_algo { @@ -113,7 +113,7 @@ static void rijndael128_zerokey(u_int8_t **); static void cml_zerokey(u_int8_t **); static void aes_ctr_zerokey(u_int8_t **); -static void aes_ctr_reinit(void *, const u_int8_t *); +static void aes_ctr_reinit(void *, const u_int8_t *, u_int8_t *); static void null_init(void *); static int null_update(void *, const u_int8_t *, u_int16_t); @@ -638,6 +638,9 @@ u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)]; u_int8_t ac_block[AESCTR_BLOCKSIZE]; int ac_nr; + struct { + u_int64_t lastiv; + } ivgenctx; }; static void @@ -678,6 +681,8 @@ return EINVAL; } memcpy(ctx->ac_block, key + len - AESCTR_NONCESIZE, AESCTR_NONCESIZE); + /* random start value for simple counter */ + arc4randbytes(&ctx->ivgenctx.lastiv, sizeof(ctx->ivgenctx.lastiv)); *sched = (void *)ctx; return 0; } @@ -692,10 +697,16 @@ } void -aes_ctr_reinit(void *key, const u_int8_t *iv) +aes_ctr_reinit(void *key, const u_int8_t *iv, u_int8_t *ivout) { struct aes_ctr_ctx *ctx = key; + if (!iv) { + ctx->ivgenctx.lastiv++; + iv = (const u_int8_t *)&ctx->ivgenctx.lastiv; + } + if (ivout) + memcpy(ivout, iv, AESCTR_IVSIZE); memcpy(ctx->ac_block + AESCTR_NONCESIZE, iv, AESCTR_IVSIZE); /* reset counter */ memset(ctx->ac_block + AESCTR_NONCESIZE + AESCTR_IVSIZE, 0, 4);