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