Module Name:    src
Committed By:   bad
Date:           Sat Apr 19 12:29:25 UTC 2014

Modified Files:
        src/doc: CHANGES
        src/share/man/man4: ubsec.4
        src/sys/dev/pci: ubsec.c ubsecreg.h ubsecvar.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.1915 -r1.1916 src/doc/CHANGES
cvs rdiff -u -r1.4 -r1.5 src/share/man/man4/ubsec.4
cvs rdiff -u -r1.39 -r1.40 src/sys/dev/pci/ubsec.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/pci/ubsecreg.h
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/pci/ubsecvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/doc/CHANGES
diff -u src/doc/CHANGES:1.1915 src/doc/CHANGES:1.1916
--- src/doc/CHANGES:1.1915	Sat Apr 19 06:20:51 2014
+++ src/doc/CHANGES	Sat Apr 19 12:29:25 2014
@@ -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]

Index: src/share/man/man4/ubsec.4
diff -u src/share/man/man4/ubsec.4:1.4 src/share/man/man4/ubsec.4:1.5
--- src/share/man/man4/ubsec.4:1.4	Thu Apr 29 19:42:29 2004
+++ src/share/man/man4/ubsec.4	Sat Apr 19 12:29:24 2014
@@ -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 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.

Index: src/sys/dev/pci/ubsec.c
diff -u src/sys/dev/pci/ubsec.c:1.39 src/sys/dev/pci/ubsec.c:1.40
--- src/sys/dev/pci/ubsec.c:1.39	Fri Apr 18 22:25:58 2014
+++ src/sys/dev/pci/ubsec.c	Sat Apr 19 12:29:24 2014
@@ -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 (ja...@thought.net)
@@ -35,12 +35,12 @@
  */
 
 #include <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 s
 	    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 *s
 				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 *s
 	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 *s
 #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 
 	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 
 	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 
 			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 
 		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 
 	}
 
 	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 
 		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 
 	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;
+
+		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;
 
-		ctxl = (struct ubsec_pktctx_long *)((char *)dmap->d_alloc.dma_vaddr +
+		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, s
 	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,

Index: src/sys/dev/pci/ubsecreg.h
diff -u src/sys/dev/pci/ubsecreg.h:1.3 src/sys/dev/pci/ubsecreg.h:1.4
--- src/sys/dev/pci/ubsecreg.h:1.3	Sun Nov 17 23:20:18 2013
+++ src/sys/dev/pci/ubsecreg.h	Sat Apr 19 12:29:24 2014
@@ -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 */

Index: src/sys/dev/pci/ubsecvar.h
diff -u src/sys/dev/pci/ubsecvar.h:1.8 src/sys/dev/pci/ubsecvar.h:1.9
--- src/sys/dev/pci/ubsecvar.h:1.8	Fri Apr 18 22:25:58 2014
+++ src/sys/dev/pci/ubsecvar.h	Sat Apr 19 12:29:24 2014
@@ -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 {

Reply via email to