diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-06-29 14:48:05 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-06-29 14:48:05 +0000 |
commit | 1b047c0a705eb03c70912339bdc1e73ea765c248 (patch) | |
tree | ea7db10e187fb60001d986e0f735e4785773941d /sys/crypto | |
parent | 66b096d9b4ad32616057742460289482a57eef0b (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.h | 14 | ||||
-rw-r--r-- | sys/crypto/cryptosoft.c | 31 |
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); |