From 89fef8a2c6c607ce73183e8eaacdee1fe6cd7ea2 Mon Sep 17 00:00:00 2001 From: bad Date: Sat, 19 Apr 2014 12:29:24 +0000 Subject: [PATCH] Add support for accelerated AES_CBC in ubsec(4) for BCM5823 and newer. Update man-page and bump date. Adjust OpenBSD RCS IDs to reflect roughly the version we are in sync with. --- doc/CHANGES | 4 +- share/man/man4/ubsec.4 | 24 ++-- sys/dev/pci/ubsec.c | 257 ++++++++++++++++++++++++++++++----------- sys/dev/pci/ubsecreg.h | 56 +++++++-- sys/dev/pci/ubsecvar.h | 13 ++- 5 files changed, 259 insertions(+), 95 deletions(-) diff --git a/doc/CHANGES b/doc/CHANGES index c5c06d6d5b0a..991cfdf29d8a 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,4 +1,4 @@ -# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1915 $> +# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1916 $> # # # [Note: This file does not mention every change made to the NetBSD source tree. @@ -390,3 +390,5 @@ Changes from NetBSD 6.0 to NetBSD 7.0: hp300: Add sti(4) at sgc screen console support to bootloader. [tsutsui 20140413] hp300: Add HP9000/425e RTC support. [tsutsui 20140419] + ubsec(4): Add support for AES-CBC modes and BCM586x chips. + [bad 20140419] diff --git a/share/man/man4/ubsec.4 b/share/man/man4/ubsec.4 index a807971a22af..65543da42515 100644 --- a/share/man/man4/ubsec.4 +++ b/share/man/man4/ubsec.4 @@ -1,4 +1,4 @@ -.\" $NetBSD: ubsec.4,v 1.4 2004/04/29 19:42:29 jonathan Exp $ +.\" $NetBSD: ubsec.4,v 1.5 2014/04/19 12:29:24 bad Exp $ .\" $FreeBSD: src/share/man/man4/ubsec.4,v 1.1.2.1 2002/11/21 23:57:24 sam Exp $ .\" $OpenBSD: ubsec.4,v 1.26 2003/09/03 15:55:41 jason Exp $ .\" @@ -26,7 +26,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 10, 2000 +.Dd April 19, 2014 .Dt UBSEC 4 .Os .Sh NAME @@ -43,9 +43,6 @@ driver supports cards containing any of the following chips: The original chipset, no longer made. This extremely rare unit was not very fast, lacked an RNG, and had a number of other bugs. -.It Bluesteel 5601 -A faster and fixed version of the original, with a random number -unit and large number engine added. .It Broadcom BCM5801 A BCM5805 without public key engine or random number generator. .It Broadcom BCM5802 @@ -56,13 +53,19 @@ Faster version of Bluesteel 5601. 64 bit version of the chip, and significantly more advanced. .It Broadcom BCM5821 Faster version of the BCM5820. -(This is the chip found on the Sun Crypto Accelerator 1000.) +This is the chip found on the Sun Crypto Accelerator 1000. .It Broadcom BCM5822 Faster version of the BCM5820. .It Broadcom BCM5823 -Faster version of the BCM5822. -.It Broadcom BCM5823 -Faster version of the BCM5821, with AES hardware. +Faster version of the BCM5822 that also supports AES. +.It Broadcom BCM5825 +Faster PCI Express or PCI-X version of the chip. +.It Broadcom BCM5860 +IPSec/SSL Security Processor that is faster and has more features. +.It Broadcom BCM5861 +Faster version of the BCM5860. +.It Broadcom BCM5862 +Faster version of the BCM5861. .El .Pp The @@ -74,6 +77,7 @@ and thus for .Xr fast_ipsec 4 and .Xr crypto 4 . +The driver also supports acceleration of AES-CBC with the BCM5823 or newer. .Pp On those models which contain a public key engine (almost all of the more recent ones), this feature is registered with the @@ -105,5 +109,3 @@ and subsequently imported to .Nx 2.0 . .Sh BUGS The BCM5801 and BCM5802 have not actually been tested. -.Pp -Whilst some of the newer chips support AES, AES is not supported by the driver. diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c index 6da77a43aba4..b5198cffc7f5 100644 --- a/sys/dev/pci/ubsec.c +++ b/sys/dev/pci/ubsec.c @@ -1,6 +1,6 @@ -/* $NetBSD: ubsec.c,v 1.39 2014/04/18 22:25:58 bad Exp $ */ +/* $NetBSD: ubsec.c,v 1.40 2014/04/19 12:29:24 bad Exp $ */ /* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */ -/* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */ +/* $OpenBSD: ubsec.c,v 1.143 2009/03/27 13:31:30 reyk Exp$ */ /* * Copyright (c) 2000 Jason L. Wright (jason@thought.net) @@ -35,12 +35,12 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.39 2014/04/18 22:25:58 bad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.40 2014/04/19 12:29:24 bad Exp $"); #undef UBSEC_DEBUG /* - * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator + * uBsec 5[56]01, 58xx hardware crypto accelerator */ #include @@ -270,7 +270,7 @@ static const struct ubsec_product { { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5823, UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | - UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, + UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES, BS_STAT_MCR1_DONE | BS_STAT_DMAERR | BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, UBS_MIN_AGGR, @@ -279,7 +279,7 @@ static const struct ubsec_product { { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5825, UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | - UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, + UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES, BS_STAT_MCR1_DONE | BS_STAT_DMAERR | BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, UBS_MIN_AGGR, @@ -290,7 +290,7 @@ static const struct ubsec_product { UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | UBS_FLAGS_LONGCTX | UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | - UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, + UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES, BS_STAT_MCR1_DONE | BS_STAT_DMAERR | BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, @@ -302,7 +302,7 @@ static const struct ubsec_product { UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | UBS_FLAGS_LONGCTX | UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | - UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, + UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES, BS_STAT_MCR1_DONE | BS_STAT_DMAERR | BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, @@ -314,7 +314,7 @@ static const struct ubsec_product { UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | UBS_FLAGS_LONGCTX | UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | - UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, + UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES, BS_STAT_MCR1_DONE | BS_STAT_DMAERR | BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, @@ -463,6 +463,10 @@ ubsec_attach(device_t parent, device_t self, void *aux) ubsec_newsession, ubsec_freesession, ubsec_process, sc); crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC_96, 0, 0, ubsec_newsession, ubsec_freesession, ubsec_process, sc); + if (sc->sc_flags & UBS_FLAGS_AES) { + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, + ubsec_newsession, ubsec_freesession, ubsec_process, sc); + } /* * Reset Broadcom chip @@ -1000,7 +1004,8 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) return (EINVAL); macini = c; } else if (c->cri_alg == CRYPTO_DES_CBC || - c->cri_alg == CRYPTO_3DES_CBC) { + c->cri_alg == CRYPTO_3DES_CBC || + c->cri_alg == CRYPTO_AES_CBC) { if (encini) return (EINVAL); encini = c; @@ -1010,6 +1015,17 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) if (encini == NULL && macini == NULL) return (EINVAL); + if (encini && encini->cri_alg == CRYPTO_AES_CBC) { + switch (encini->cri_klen) { + case 128: + case 192: + case 256: + break; + default: + return (EINVAL); + } + } + if (sc->sc_sessions == NULL) { ses = sc->sc_sessions = (struct ubsec_session *)malloc( sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); @@ -1053,19 +1069,23 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) #endif /* Go ahead and compute key in ubsec's byte order */ + if (encini->cri_alg == CRYPTO_AES_CBC) { + memcpy(ses->ses_key, encini->cri_key, + encini->cri_klen / 8); + } if (encini->cri_alg == CRYPTO_DES_CBC) { - memcpy(&ses->ses_deskey[0], encini->cri_key, 8); - memcpy(&ses->ses_deskey[2], encini->cri_key, 8); - memcpy(&ses->ses_deskey[4], encini->cri_key, 8); + memcpy(&ses->ses_key[0], encini->cri_key, 8); + memcpy(&ses->ses_key[2], encini->cri_key, 8); + memcpy(&ses->ses_key[4], encini->cri_key, 8); } else - memcpy(ses->ses_deskey, encini->cri_key, 24); + memcpy(ses->ses_key, encini->cri_key, 24); - SWAP32(ses->ses_deskey[0]); - SWAP32(ses->ses_deskey[1]); - SWAP32(ses->ses_deskey[2]); - SWAP32(ses->ses_deskey[3]); - SWAP32(ses->ses_deskey[4]); - SWAP32(ses->ses_deskey[5]); + SWAP32(ses->ses_key[0]); + SWAP32(ses->ses_key[1]); + SWAP32(ses->ses_key[2]); + SWAP32(ses->ses_key[3]); + SWAP32(ses->ses_key[4]); + SWAP32(ses->ses_key[5]); } if (macini) { @@ -1172,9 +1192,10 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) int encoffset = 0, macoffset = 0, cpskip, cpoffset; int sskip, dskip, stheend, dtheend; int16_t coffset; - struct ubsec_session *ses; - struct ubsec_pktctx ctx; + struct ubsec_session *ses, key; struct ubsec_dma *dmap = NULL; + u_int16_t flags = 0; + int ivlen = 0, keylen = 0; sc = arg; KASSERT(sc != NULL /*, ("ubsec_process: null softc")*/); @@ -1204,7 +1225,7 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) dmap = q->q_dma; /* Save dma pointer */ /* don't lose the cached dmamaps q_src_map and q_cached_dst_map */ memset(q, 0, offsetof(struct ubsec_q, q_src_map)); - memset(&ctx, 0, sizeof(ctx)); + memset(&key, 0, sizeof(key)); q->q_sesn = UBSEC_SESSION(crp->crp_sid); q->q_dma = dmap; @@ -1242,7 +1263,8 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) maccrd = crd1; enccrd = NULL; } else if (crd1->crd_alg == CRYPTO_DES_CBC || - crd1->crd_alg == CRYPTO_3DES_CBC) { + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC) { maccrd = NULL; enccrd = crd1; } else { @@ -1254,14 +1276,16 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) if ((crd1->crd_alg == CRYPTO_MD5_HMAC_96 || crd1->crd_alg == CRYPTO_SHA1_HMAC_96) && (crd2->crd_alg == CRYPTO_DES_CBC || - crd2->crd_alg == CRYPTO_3DES_CBC) && + crd2->crd_alg == CRYPTO_3DES_CBC || + crd2->crd_alg == CRYPTO_AES_CBC) && ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { maccrd = crd1; enccrd = crd2; } else if ((crd1->crd_alg == CRYPTO_DES_CBC || - crd1->crd_alg == CRYPTO_3DES_CBC) && + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC) && (crd2->crd_alg == CRYPTO_MD5_HMAC_96 || - crd2->crd_alg == CRYPTO_SHA1_HMAC_96) && + crd2->crd_alg == CRYPTO_SHA1_HMAC_96) && (crd1->crd_flags & CRD_F_ENCRYPT)) { enccrd = crd1; maccrd = crd2; @@ -1276,67 +1300,89 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) } if (enccrd) { + if (enccrd->crd_alg == CRYPTO_AES_CBC) { + if ((sc->sc_flags & UBS_FLAGS_AES) == 0) { + /* + * We cannot order the ubsec as requested + */ + ubsecstats.hst_badalg++; + err = EINVAL; + goto errout; + } + flags |= htole16(UBS_PKTCTX_ENC_AES); + switch (enccrd->crd_klen) { + case 128: + case 192: + case 256: + keylen = enccrd->crd_klen / 8; + break; + default: + err = EINVAL; + goto errout; + } + ivlen = 16; + } else { + flags |= htole16(UBS_PKTCTX_ENC_3DES); + ivlen = 8; + keylen = 24; + } + encoffset = enccrd->crd_skip; - ctx.pc_flags |= htole16(UBS_PKTCTX_ENC_3DES); if (enccrd->crd_flags & CRD_F_ENCRYPT) { q->q_flags |= UBSEC_QFLAGS_COPYOUTIV; if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - memcpy(ctx.pc_iv, enccrd->crd_iv, 8); + memcpy(key.ses_iv, enccrd->crd_iv, ivlen); else { - ctx.pc_iv[0] = ses->ses_iv[0]; - ctx.pc_iv[1] = ses->ses_iv[1]; + for (i = 0; i < (ivlen / 4); i++) + key.ses_iv[i] = ses->ses_iv[i]; } if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { if (crp->crp_flags & CRYPTO_F_IMBUF) m_copyback(q->q_src_m, enccrd->crd_inject, - 8, (void *)ctx.pc_iv); + ivlen, (void *)key.ses_iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copyback(q->q_src_io, enccrd->crd_inject, - 8, (void *)ctx.pc_iv); + ivlen, (void *)key.ses_iv); } } else { - ctx.pc_flags |= htole16(UBS_PKTCTX_INBOUND); + flags |= htole16(UBS_PKTCTX_INBOUND); if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - memcpy(ctx.pc_iv, enccrd->crd_iv, 8); + memcpy(key.ses_iv, enccrd->crd_iv, ivlen); else if (crp->crp_flags & CRYPTO_F_IMBUF) m_copydata(q->q_src_m, enccrd->crd_inject, - 8, (void *)ctx.pc_iv); + ivlen, (void *)key.ses_iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copydata(q->q_src_io, enccrd->crd_inject, 8, - (void *)ctx.pc_iv); + (void *)key.ses_iv); } - ctx.pc_deskey[0] = ses->ses_deskey[0]; - ctx.pc_deskey[1] = ses->ses_deskey[1]; - ctx.pc_deskey[2] = ses->ses_deskey[2]; - ctx.pc_deskey[3] = ses->ses_deskey[3]; - ctx.pc_deskey[4] = ses->ses_deskey[4]; - ctx.pc_deskey[5] = ses->ses_deskey[5]; - SWAP32(ctx.pc_iv[0]); - SWAP32(ctx.pc_iv[1]); + for (i = 0; i < (keylen / 4); i++) + key.ses_key[i] = ses->ses_key[i]; + for (i = 0; i < (ivlen / 4); i++) + SWAP32(key.ses_iv[i]); } if (maccrd) { macoffset = maccrd->crd_skip; if (maccrd->crd_alg == CRYPTO_MD5_HMAC_96) - ctx.pc_flags |= htole16(UBS_PKTCTX_AUTH_MD5); + flags |= htole16(UBS_PKTCTX_AUTH_MD5); else - ctx.pc_flags |= htole16(UBS_PKTCTX_AUTH_SHA1); + flags |= htole16(UBS_PKTCTX_AUTH_SHA1); for (i = 0; i < 5; i++) { - ctx.pc_hminner[i] = ses->ses_hminner[i]; - ctx.pc_hmouter[i] = ses->ses_hmouter[i]; + key.ses_hminner[i] = ses->ses_hminner[i]; + key.ses_hmouter[i] = ses->ses_hmouter[i]; - HTOLE32(ctx.pc_hminner[i]); - HTOLE32(ctx.pc_hmouter[i]); + HTOLE32(key.ses_hminner[i]); + HTOLE32(key.ses_hmouter[i]); } } @@ -1381,7 +1427,6 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) cpoffset = cpskip + dtheend; coffset = 0; } - ctx.pc_offset = htole16(coffset >> 2); if (q->q_src_map == NULL) { /* XXX FIXME: jonathan asks, what the heck's that 0xfff0? */ @@ -1656,29 +1701,100 @@ ubsec_process(void *arg, struct cryptop *crp, int hint) dmap->d_dma->d_mcr.mcr_cmdctxp = htole32(dmap->d_alloc.dma_paddr + offsetof(struct ubsec_dmachunk, d_ctx)); - if (sc->sc_flags & UBS_FLAGS_LONGCTX) { - struct ubsec_pktctx_long *ctxl; + if (enccrd && enccrd->crd_alg == CRYPTO_AES_CBC) { + struct ubsec_pktctx_aes128 *aes128; + struct ubsec_pktctx_aes192 *aes192; + struct ubsec_pktctx_aes256 *aes256; + struct ubsec_pktctx_hdr *ph; + u_int8_t *ctx; - ctxl = (struct ubsec_pktctx_long *)((char *)dmap->d_alloc.dma_vaddr + + ctx = (u_int8_t *)(dmap->d_alloc.dma_vaddr) + + offsetof(struct ubsec_dmachunk, d_ctx); + + ph = (struct ubsec_pktctx_hdr *)ctx; + ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_AES); + ph->ph_flags = flags; + ph->ph_offset = htole16(coffset >> 2); + + switch (enccrd->crd_klen) { + case 128: + aes128 = (struct ubsec_pktctx_aes128 *)ctx; + ph->ph_len = htole16(sizeof(*aes128)); + ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_128); + for (i = 0; i < 4; i++) + aes128->pc_aeskey[i] = key.ses_key[i]; + for (i = 0; i < 5; i++) + aes128->pc_hminner[i] = key.ses_hminner[i]; + for (i = 0; i < 5; i++) + aes128->pc_hmouter[i] = key.ses_hmouter[i]; + for (i = 0; i < 4; i++) + aes128->pc_iv[i] = key.ses_iv[i]; + break; + case 192: + aes192 = (struct ubsec_pktctx_aes192 *)ctx; + ph->ph_len = htole16(sizeof(*aes192)); + ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_192); + for (i = 0; i < 6; i++) + aes192->pc_aeskey[i] = key.ses_key[i]; + for (i = 0; i < 5; i++) + aes192->pc_hminner[i] = key.ses_hminner[i]; + for (i = 0; i < 5; i++) + aes192->pc_hmouter[i] = key.ses_hmouter[i]; + for (i = 0; i < 4; i++) + aes192->pc_iv[i] = key.ses_iv[i]; + break; + case 256: + aes256 = (struct ubsec_pktctx_aes256 *)ctx; + ph->ph_len = htole16(sizeof(*aes256)); + ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_256); + for (i = 0; i < 8; i++) + aes256->pc_aeskey[i] = key.ses_key[i]; + for (i = 0; i < 5; i++) + aes256->pc_hminner[i] = key.ses_hminner[i]; + for (i = 0; i < 5; i++) + aes256->pc_hmouter[i] = key.ses_hmouter[i]; + for (i = 0; i < 4; i++) + aes256->pc_iv[i] = key.ses_iv[i]; + break; + } + } else if (sc->sc_flags & UBS_FLAGS_LONGCTX) { + struct ubsec_pktctx_3des *ctx; + struct ubsec_pktctx_hdr *ph; + + ctx = (struct ubsec_pktctx_3des *) + ((u_int8_t *)(dmap->d_alloc.dma_vaddr) + offsetof(struct ubsec_dmachunk, d_ctx)); - /* transform small context into long context */ - ctxl->pc_len = htole16(sizeof(struct ubsec_pktctx_long)); - ctxl->pc_type = htole16(UBS_PKTCTX_TYPE_IPSEC); - ctxl->pc_flags = ctx.pc_flags; - ctxl->pc_offset = ctx.pc_offset; + ph = (struct ubsec_pktctx_hdr *)ctx; + ph->ph_len = htole16(sizeof(*ctx)); + ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_3DES); + ph->ph_flags = flags; + ph->ph_offset = htole16(coffset >> 2); + for (i = 0; i < 6; i++) - ctxl->pc_deskey[i] = ctx.pc_deskey[i]; + ctx->pc_deskey[i] = key.ses_key[i]; for (i = 0; i < 5; i++) - ctxl->pc_hminner[i] = ctx.pc_hminner[i]; + ctx->pc_hminner[i] = key.ses_hminner[i]; for (i = 0; i < 5; i++) - ctxl->pc_hmouter[i] = ctx.pc_hmouter[i]; - ctxl->pc_iv[0] = ctx.pc_iv[0]; - ctxl->pc_iv[1] = ctx.pc_iv[1]; - } else - memcpy((char *)dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx), &ctx, - sizeof(struct ubsec_pktctx)); + ctx->pc_hmouter[i] = key.ses_hmouter[i]; + for (i = 0; i < 2; i++) + ctx->pc_iv[i] = key.ses_iv[i]; + } else { + struct ubsec_pktctx *ctx = (struct ubsec_pktctx *) + ((u_int8_t *)dmap->d_alloc.dma_vaddr + + offsetof(struct ubsec_dmachunk, d_ctx)); + + ctx->pc_flags = flags; + ctx->pc_offset = htole16(coffset >> 2); + for (i = 0; i < 6; i++) + ctx->pc_deskey[i] = key.ses_key[i]; + for (i = 0; i < 5; i++) + ctx->pc_hminner[i] = key.ses_hminner[i]; + for (i = 0; i < 5; i++) + ctx->pc_hmouter[i] = key.ses_hmouter[i]; + for (i = 0; i < 2; i++) + ctx->pc_iv[i] = key.ses_iv[i]; + } mutex_spin_enter(&sc->sc_mtx); SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next); @@ -1752,7 +1868,8 @@ ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q) if (q->q_flags & UBSEC_QFLAGS_COPYOUTIV) { for (crd = crp->crp_desc; crd; crd = crd->crd_next) { if (crd->crd_alg != CRYPTO_DES_CBC && - crd->crd_alg != CRYPTO_3DES_CBC) + crd->crd_alg != CRYPTO_3DES_CBC && + crd->crd_alg != CRYPTO_AES_CBC) continue; if (crp->crp_flags & CRYPTO_F_IMBUF) m_copydata((struct mbuf *)crp->crp_buf, diff --git a/sys/dev/pci/ubsecreg.h b/sys/dev/pci/ubsecreg.h index d6ee66abc38b..3350b34bc4e4 100644 --- a/sys/dev/pci/ubsecreg.h +++ b/sys/dev/pci/ubsecreg.h @@ -1,5 +1,5 @@ -/* $NetBSD: ubsecreg.h,v 1.3 2013/11/17 23:20:18 bad Exp $ */ -/* $OpenBSD: ubsecreg.h,v 1.28 2003/06/04 16:02:41 jason Exp $ */ +/* $NetBSD: ubsecreg.h,v 1.4 2014/04/19 12:29:24 bad Exp $ */ +/* $OpenBSD: ubsecreg.h,v 1.29 2009/03/25 12:17:30 reyk Exp $ */ /* * Copyright (c) 2000 Theo de Raadt @@ -111,6 +111,7 @@ /* BS_INT */ #define BS_INT_DMAINT 0x80000000 /* 5827+, enable DMA intr */ +/* DES/3DES */ struct ubsec_pktctx { u_int32_t pc_deskey[6]; /* 3DES key */ u_int32_t pc_hminner[5]; /* hmac inner state */ @@ -127,17 +128,56 @@ struct ubsec_pktctx { #define UBS_PKTCTX_AUTH_MD5 0x1000 /* use hmac-md5 */ #define UBS_PKTCTX_AUTH_SHA1 0x2000 /* use hmac-sha1 */ -struct ubsec_pktctx_long { - volatile u_int16_t pc_len; /* length of ctx struct */ - volatile u_int16_t pc_type; /* context type, 0 */ - volatile u_int16_t pc_flags; /* flags, same as above */ - volatile u_int16_t pc_offset; /* crypto/auth offset */ +/* "Long" cryptographic operations on newer chipsets */ +#define UBS_PKTCTX_TYPE_IPSEC_3DES 0x0000 +#define UBS_PKTCTX_TYPE_IPSEC_AES 0x0040 + +struct ubsec_pktctx_hdr { + volatile u_int16_t ph_len; /* length of ctx struct */ + volatile u_int16_t ph_type; /* context type, 0 */ + volatile u_int16_t ph_flags; /* flags, same as above */ + volatile u_int16_t ph_offset; /* crypto/auth offset */ +}; + +/* Long version of DES/3DES */ +struct ubsec_pktctx_3des { + struct ubsec_pktctx_hdr pc_hdr; /* Common header */ volatile u_int32_t pc_deskey[6]; /* 3DES key */ volatile u_int32_t pc_iv[2]; /* [3]DES iv */ volatile u_int32_t pc_hminner[5]; /* hmac inner state */ volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ }; -#define UBS_PKTCTX_TYPE_IPSEC 0x0000 + +/* AES uses different structures for each supported key size */ +struct ubsec_pktctx_aes128 { + struct ubsec_pktctx_hdr pc_hdr; /* Common header */ + volatile u_int32_t pc_aeskey[4]; /* AES128 key */ + volatile u_int32_t pc_iv[4]; /* AES iv/ucv */ + volatile u_int32_t pc_hminner[5]; /* hmac inner state */ + volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ +}; + +struct ubsec_pktctx_aes192 { + struct ubsec_pktctx_hdr pc_hdr; /* Common header */ + volatile u_int32_t pc_aeskey[6]; /* AES192 key */ + volatile u_int32_t pc_iv[4]; /* AES iv/icv */ + volatile u_int32_t pc_hminner[5]; /* hmac inner state */ + volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ +}; + +struct ubsec_pktctx_aes256 { + struct ubsec_pktctx_hdr pc_hdr; /* Common header */ + volatile u_int32_t pc_aeskey[8]; /* AES256 key */ + volatile u_int32_t pc_iv[4]; /* AES iv/icv */ + volatile u_int32_t pc_hminner[5]; /* hmac inner state */ + volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ +}; +#define UBS_PKTCTX_ENC_AES 0x8000 /* use aes */ +#define UBS_PKTCTX_MODE_CBC 0x0000 /* Cipher Block Chaining mode */ +#define UBS_PKTCTX_MODE_CTR 0x0400 /* Counter mode */ +#define UBS_PKTCTX_KEYSIZE_128 0x0000 /* AES128 */ +#define UBS_PKTCTX_KEYSIZE_192 0x0100 /* AES192 */ +#define UBS_PKTCTX_KEYSIZE_256 0x0200 /* AES256 */ struct ubsec_pktbuf { volatile u_int32_t pb_addr; /* address of buffer start */ diff --git a/sys/dev/pci/ubsecvar.h b/sys/dev/pci/ubsecvar.h index 249a9f90c516..8797fc2d73cc 100644 --- a/sys/dev/pci/ubsecvar.h +++ b/sys/dev/pci/ubsecvar.h @@ -1,5 +1,5 @@ -/* $NetBSD: ubsecvar.h,v 1.8 2014/04/18 22:25:58 bad Exp $ */ -/* $OpenBSD: ubsecvar.h,v 1.36 2003/06/04 16:02:41 jason Exp $ */ +/* $NetBSD: ubsecvar.h,v 1.9 2014/04/19 12:29:24 bad Exp $ */ +/* $OpenBSD: ubsecvar.h,v 1.38 2009/03/27 13:31:30 reyk Exp $ */ /* * Copyright (c) 2000 Theo de Raadt @@ -116,7 +116,10 @@ struct ubsec_dmachunk { struct ubsec_pktbuf d_dbuf[UBS_MAX_SCATTER-1]; u_int32_t d_macbuf[5]; union { - struct ubsec_pktctx_long ctxl; + struct ubsec_pktctx_aes256 ctx_aes256; + struct ubsec_pktctx_aes192 ctx_aes192; + struct ubsec_pktctx_aes128 ctx_aes128; + struct ubsec_pktctx_3des ctx_3des; struct ubsec_pktctx ctx; } d_ctx; }; @@ -196,10 +199,10 @@ struct ubsec_softc { struct ubsec_session { u_int32_t ses_used; - u_int32_t ses_deskey[6]; /* 3DES key */ + u_int32_t ses_key[8]; /* 3DES/AES key */ u_int32_t ses_hminner[5]; /* hmac inner state */ u_int32_t ses_hmouter[5]; /* hmac outer state */ - u_int32_t ses_iv[2]; /* [3]DES iv */ + u_int32_t ses_iv[4]; /* [3]DES iv or AES iv/icv */ }; struct ubsec_stats {