summaryrefslogtreecommitdiff
path: root/sys/crypto
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-06-29 14:48:05 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-06-29 14:48:05 +0000
commit1b047c0a705eb03c70912339bdc1e73ea765c248 (patch)
treeea7db10e187fb60001d986e0f735e4785773941d /sys/crypto
parent66b096d9b4ad32616057742460289482a57eef0b (diff)
Add support for the Extended (64-bit) Sequence Number as defined
in RFC4302 and RFC4303. Right now only software crypto engine is capable of doing it. Replay check was rewritten to implement algorithm described in the Appendix A of RFC4303 and the window size was increased to 64. Tested against OpenBSD, Linux (strongswan) and Windows. No objection from the usual suspects.
Diffstat (limited to 'sys/crypto')
-rw-r--r--sys/crypto/cryptodev.h14
-rw-r--r--sys/crypto/cryptosoft.c31
2 files changed, 36 insertions, 9 deletions
diff --git a/sys/crypto/cryptodev.h b/sys/crypto/cryptodev.h
index 8f345f4f5ea..b7add969bc4 100644
--- a/sys/crypto/cryptodev.h
+++ b/sys/crypto/cryptodev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptodev.h,v 1.55 2010/12/16 16:56:08 jsg Exp $ */
+/* $OpenBSD: cryptodev.h,v 1.56 2012/06/29 14:48:04 mikeb Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -108,7 +108,8 @@
#define CRYPTO_AES_192_GMAC 25
#define CRYPTO_AES_256_GMAC 26
#define CRYPTO_AES_GMAC 27
-#define CRYPTO_ALGORITHM_MAX 27 /* Keep updated */
+#define CRYPTO_ESN 28 /* Support for Extended Sequence Numbers */
+#define CRYPTO_ALGORITHM_MAX 28 /* Keep updated */
/* Algorithm flags */
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
@@ -121,7 +122,12 @@ struct cryptoini {
int cri_klen; /* Key length, in bits */
int cri_rnd; /* Algorithm rounds, where relevant */
caddr_t cri_key; /* key to use */
- u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
+ union {
+ u_int8_t iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
+ u_int8_t esn[4]; /* high-order ESN */
+ } u;
+#define cri_iv u.iv
+#define cri_esn u.esn
struct cryptoini *cri_next;
};
@@ -138,8 +144,10 @@ struct cryptodesc {
#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
#define CRD_F_COMP 0x10 /* Set when doing compression */
+#define CRD_F_ESN 0x20 /* Set when ESN field is provided */
struct cryptoini CRD_INI; /* Initialization/context data */
+#define crd_esn CRD_INI.cri_esn
#define crd_iv CRD_INI.cri_iv
#define crd_key CRD_INI.cri_key
#define crd_rnd CRD_INI.cri_rnd
diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c
index 6e2406b444d..962b09e15f3 100644
--- a/sys/crypto/cryptosoft.c
+++ b/sys/crypto/cryptosoft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptosoft.c,v 1.63 2011/01/11 23:00:21 markus Exp $ */
+/* $OpenBSD: cryptosoft.c,v 1.64 2012/06/29 14:48:04 mikeb Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -446,6 +446,9 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
if (err)
return err;
+ if (crd->crd_flags & CRD_F_ESN)
+ axf->Update(&ctx, crd->crd_esn, 4);
+
switch (sw->sw_alg) {
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
@@ -505,7 +508,7 @@ swcr_combined(struct cryptop *crp)
struct uio *uio = NULL;
caddr_t buf = (caddr_t)crp->crp_buf;
uint32_t *blkp;
- int i, blksz, ivlen, outtype, len;
+ int aadlen, blksz, i, ivlen, outtype, left, len;
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
for (sw = swcr_sessions[crp->crp_sid & 0xffffffff];
@@ -576,10 +579,22 @@ swcr_combined(struct cryptop *crp)
axf->Reinit(&ctx, iv, ivlen);
/* Supply MAC with AAD */
- for (i = 0; i < crda->crd_len; i += blksz) {
- len = MIN(crda->crd_len - i, blksz);
- COPYDATA(outtype, buf, crda->crd_skip + i, len, blk);
- axf->Update(&ctx, blk, len);
+ aadlen = crda->crd_len;
+ if (crda->crd_flags & CRD_F_ESN)
+ aadlen += 4;
+ for (i = 0; i < aadlen; i += blksz) {
+ len = 0;
+ if (i < crda->crd_len) {
+ len = MIN(crda->crd_len - i, blksz);
+ COPYDATA(outtype, buf, crda->crd_skip + i, len, blk);
+ }
+ left = blksz - len;
+ if (crda->crd_flags & CRD_F_ESN && left > 0) {
+ bcopy(crda->crd_esn, blk + len, MIN(left, aadlen - i));
+ len += MIN(left, aadlen - i);
+ }
+ bzero(blk + len, blksz - len);
+ axf->Update(&ctx, blk, blksz);
}
if (exf->reinit)
@@ -937,6 +952,9 @@ swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
cxf = &comp_algo_deflate;
(*swd)->sw_cxf = cxf;
break;
+ case CRYPTO_ESN:
+ /* nothing to do */
+ break;
default:
swcr_freesession(i);
return EINVAL;
@@ -1192,6 +1210,7 @@ swcr_init(void)
algs[CRYPTO_AES_128_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_AES_192_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_AES_256_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
+ algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED;
crypto_register(swcr_id, algs, swcr_newsession,
swcr_freesession, swcr_process);