summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2002-03-19 23:24:54 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2002-03-19 23:24:54 +0000
commit4616ad8a96f282e9d3408fd568f27107a672c149 (patch)
tree6c16f353e8dfcc121804359da2eef46cb5b2731f /sys
parentef3e143b94911f849e21e17b68643aa6569cbfac (diff)
Don't keep the last blocksize-bytes of ciphertext for use as the next
plaintext's IV, in CBC mode. Use arc4random() to acquire fresh IVs per message instead (particularly useful for IPsec). This avoids the CBC oracle attack. provos@ ok
Diffstat (limited to 'sys')
-rw-r--r--sys/crypto/cryptosoft.c32
-rw-r--r--sys/crypto/cryptosoft.h4
2 files changed, 18 insertions, 18 deletions
diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c
index edd3d5619c0..42774e19524 100644
--- a/sys/crypto/cryptosoft.c
+++ b/sys/crypto/cryptosoft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptosoft.c,v 1.31 2002/03/05 15:59:41 markus Exp $ */
+/* $OpenBSD: cryptosoft.c,v 1.32 2002/03/19 23:24:53 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -105,8 +105,22 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
if (crd->crd_flags & CRD_F_IV_EXPLICIT)
bcopy(crd->crd_iv, iv, blks);
else {
- /* Use IV from context */
- bcopy(sw->sw_iv, iv, blks);
+ /* Get random IV */
+ for (i = 0;
+ i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN;
+ i += sizeof (u_int32_t))
+ *((u_int32_t *) (iv + i)) = arc4random();
+ /*
+ * What if the block size is not a multiple
+ * of sizeof (u_int32_t), which is the size of
+ * what arc4random() returns ?
+ */
+ if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) {
+ u_int32_t temp = arc4random();
+
+ bcopy (&temp, iv + i,
+ EALG_MAX_BLOCK_LEN - i);
+ }
}
/* Do we need to write the IV */
@@ -364,10 +378,6 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
}
}
- /* Keep the last block */
- if (crd->crd_flags & CRD_F_ENCRYPT)
- bcopy(ivp, sw->sw_iv, blks);
-
return 0; /* Done with encryption/decryption */
}
@@ -602,13 +612,7 @@ swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
enccommon:
txf->setkey(&((*swd)->sw_kschedule), cri->cri_key,
cri->cri_klen / 8);
- (*swd)->sw_iv = malloc(txf->blocksize, M_CRYPTO_DATA, M_NOWAIT);
- if ((*swd)->sw_iv == NULL) {
- swcr_freesession(i);
- return ENOBUFS;
- }
(*swd)->sw_exf = txf;
- get_random_bytes((*swd)->sw_iv, txf->blocksize);
break;
case CRYPTO_MD5_HMAC:
@@ -756,8 +760,6 @@ swcr_freesession(u_int64_t tid)
if (swd->sw_kschedule)
txf->zerokey(&(swd->sw_kschedule));
- if (swd->sw_iv)
- free(swd->sw_iv, M_CRYPTO_DATA);
break;
case CRYPTO_MD5_HMAC:
diff --git a/sys/crypto/cryptosoft.h b/sys/crypto/cryptosoft.h
index 6b3fe4b193a..6a445672918 100644
--- a/sys/crypto/cryptosoft.h
+++ b/sys/crypto/cryptosoft.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptosoft.h,v 1.8 2002/03/05 15:59:41 markus Exp $ */
+/* $OpenBSD: cryptosoft.h,v 1.9 2002/03/19 23:24:53 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -36,7 +36,6 @@ struct swcr_data {
} SWCR_AUTH;
struct {
u_int8_t *SW_kschedule;
- u_int8_t *SW_iv;
struct enc_xform *SW_exf;
} SWCR_ENC;
struct {
@@ -50,7 +49,6 @@ struct swcr_data {
#define sw_klen SWCR_UN.SWCR_AUTH.SW_klen
#define sw_axf SWCR_UN.SWCR_AUTH.SW_axf
#define sw_kschedule SWCR_UN.SWCR_ENC.SW_kschedule
-#define sw_iv SWCR_UN.SWCR_ENC.SW_iv
#define sw_exf SWCR_UN.SWCR_ENC.SW_exf
#define sw_size SWCR_UN.SWCR_COMP.SW_size
#define sw_cxf SWCR_UN.SWCR_COMP.SW_cxf