Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Sep 2014 04:52:39 GMT
From:      John-Mark Gurney <jmg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 1199888 for review
Message-ID:  <201409080452.s884qdER030292@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@1199888?ac=10

Change 1199888 by jmg@jmg_carbon2 on 2014/09/05 17:25:29

	commit this code before I delete it all, incase I want to go back
	to it...   I've decided that the best way forward is to convert
	everything to an iov, and have all the code operate on an iov...
	
	This eliminates some of the crazy abstraction that his code has,
	eliminates extra function callls, and will be useful for expanding
	to the aesni driver..

Affected files ...

.. //depot/projects/opencrypto/sys/opencrypto/criov.c#2 edit
.. //depot/projects/opencrypto/sys/opencrypto/cryptodev.h#7 edit
.. //depot/projects/opencrypto/sys/opencrypto/cryptosoft.c#9 edit

Differences ...

==== //depot/projects/opencrypto/sys/opencrypto/criov.c#2 (text+ko) ====

@@ -159,6 +159,13 @@
 }
 
 void
+buf_copyback(caddr_t buf, int off, int size, caddr_t in)
+{
+
+	bcopy(in, buf + off, size);
+}
+
+void
 crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
 {
 
@@ -196,3 +203,46 @@
 		error = (*f)(arg, buf + off, len);
 	return (error);
 }
+
+void
+crypto_mbuftoiovec(struct mbuf *mbuf, struct iovec **iovptr, int *cnt,
+    int *allocated)
+{
+	struct iovec *iov;
+	struct mbuf *m, *mtmp;
+	int i, j;
+
+	*allocated = 0;
+	iov = *iovptr;
+	if (iov == NULL)
+		*cnt = 0;
+
+	m = mbuf;
+	i = 0;
+	while (m != NULL) {
+		if (i == *cnt) {
+			/* we need to allocate a larger array */
+			j = 1;
+			mtmp = m;
+			while ((mtmp = mtmp->m_next) != NULL)
+				j++;
+			iov = malloc(sizeof *iov * (i + j), M_TEMP, M_WAITOK);
+			*allocated = 1;
+			*cnt = i + j;
+			memcpy(iov, *iovptr, sizeof *iov * i);
+		}
+
+		iov[i].iov_base = m->m_data;
+		iov[i].iov_len = m->m_len;
+
+		i++;
+		m = m->m_next;
+	}
+
+	if (*allocated)
+		KASSERT(*cnt == i, ("did not allocate correct amount: %d != %d",
+		    *cnt, i));
+
+	*iovptr = iov;
+	*cnt = i;
+}

==== //depot/projects/opencrypto/sys/opencrypto/cryptodev.h#7 (text+ko) ====

@@ -463,6 +463,11 @@
 extern	int cuio_apply(struct uio *uio, int off, int len,
 	    int (*f)(void *, void *, u_int), void *arg);
 
+extern	void buf_copyback(caddr_t buf, int off, int len, caddr_t in);
+
+extern	void crypto_mbuftoiovec(struct mbuf *mbuf, struct iovec **iovptr,
+	    int *cnt, int *allocated);
+
 extern	void crypto_copyback(int flags, caddr_t buf, int off, int size,
 	    caddr_t in);
 extern	void crypto_copydata(int flags, caddr_t buf, int off, int size,

==== //depot/projects/opencrypto/sys/opencrypto/cryptosoft.c#9 (text+ko) ====

@@ -76,6 +76,111 @@
 static	int swcr_freesession(device_t dev, u_int64_t tid);
 static	int swcr_freesession_locked(device_t dev, u_int64_t tid);
 
+typedef void (*copybackfun_t)(void *, int, int, caddr_t);
+
+struct blkdata {
+	void	(*fun)(caddr_t, u_int8_t *);
+	caddr_t	arg;
+	uint8_t	blk[EALG_MAX_BLOCK_LEN];
+	int	blksize;
+	int	blkoff;
+	int	cnt;
+	void	(*copyback)(void *, int, int, caddr_t);
+	void	*copybackarg;
+};
+
+struct cbcdata {
+	struct blkdata	bd;
+	void		(*fun)(caddr_t, u_int8_t *);
+	caddr_t		arg;
+	uint8_t		iv[EALG_MAX_BLOCK_LEN];
+};
+
+static int
+blkdata(void *arg, void *dataarg, u_int len)
+{
+	uint8_t *data;
+	struct blkdata *bd;
+	int blksize;
+	int cnt;
+
+	data = (uint8_t *)dataarg;
+	bd = (struct blkdata *)arg;
+	blksize = bd->blksize;
+
+	/* process remaining from before */
+	if (bd->cnt) {
+		cnt = MIN(blksize - bd->cnt, len);
+		memcpy(&bd->blk[bd->cnt], data, cnt);
+		bd->cnt += cnt;
+
+		if (bd->cnt == blksize) {
+			bd->fun(bd->arg, bd->blk);
+			bd->copyback(bd->copybackarg, bd->blkoff, blksize,
+			    bd->blk);
+			bd->blkoff += blksize;
+			bd->cnt = 0;
+		} else
+			return 0;
+
+		len -= cnt;
+		data += cnt;
+	}
+
+	while (len >= blksize) {
+		bd->fun(bd->arg, data);
+
+		len -= blksize;
+		data += blksize;
+		bd->blkoff += blksize;
+	}
+
+	/* keep the remaining around for the next call */
+	if (len) {
+		bd->cnt = len;
+		memcpy(bd->blk, data, len);
+	}
+
+	return 0;
+}
+
+static void
+cbcencdata(caddr_t arg, uint8_t *in)
+{
+	struct cbcdata *cd;
+	int i;
+
+        cd = (struct cbcdata *)arg;
+
+	for (i = 0; i < cd->bd.blksize; i++) {
+		in[i] ^= cd->iv[i];
+	}
+
+	cd->fun(cd->arg, in);
+
+	bcopy(in, cd->iv, cd->bd.blksize);
+}
+
+static void
+cbcdecdata(caddr_t arg, uint8_t *in)
+{
+	uint8_t		oiv[EALG_MAX_BLOCK_LEN];
+	struct cbcdata *cd;
+	int i;
+
+        cd = (struct cbcdata *)arg;
+
+	bcopy(in, oiv, cd->bd.blksize);
+
+	cd->fun(cd->arg, in);
+
+	for (i = 0; i < cd->bd.blksize; i++) {
+		in[i] ^= cd->iv[i];
+	}
+
+	bcopy(oiv, cd->iv, cd->bd.blksize);
+}
+
 /*
  * Apply a symmetric encryption/decryption algorithm.
  */
@@ -83,10 +188,11 @@
 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
     int flags)
 {
-	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN];
-	unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
+	struct cbcdata cd;
+	struct blkdata bd;
+	unsigned char iv[EALG_MAX_BLOCK_LEN];
 	struct enc_xform *exf;
-	int i, k, j, blks;
+	int blks;
 
 	exf = sw->sw_exf;
 	blks = exf->blocksize;
@@ -133,7 +239,20 @@
 			return (error);
 	}
 
-	ivp = iv;
+	bd = (struct blkdata){};
+	bd.fun = (crd->crd_flags & CRD_F_ENCRYPT) ? exf->encrypt :
+	    exf->decrypt;
+	bd.arg = sw->sw_kschedule;
+	bd.blksize = blks;
+	bd.blkoff = crd->crd_skip;
+        if ((flags & CRYPTO_F_IMBUF) != 0)
+                bd.copyback = (copybackfun_t)m_copyback;
+        else if ((flags & CRYPTO_F_IOV) != 0)
+		bd.copyback = (copybackfun_t)cuio_copyback;
+        else
+		bd.copyback = (copybackfun_t)buf_copyback;
+
+	bd.copybackarg = buf;
 
 	if (exf->reinit) {
 		/*
@@ -142,59 +261,20 @@
 		 */
 		exf->reinit(sw->sw_kschedule, iv);
 
-		for (i = crd->crd_skip;
-		    i < crd->crd_skip + crd->crd_len; i += blks) {
-			crypto_copydata(flags, buf, i, blks, blk);
-
-			if (crd->crd_flags & CRD_F_ENCRYPT)
-				exf->encrypt(sw->sw_kschedule, blk);
-			else
-				exf->decrypt(sw->sw_kschedule, blk);
-
-			crypto_copyback(flags, buf, i, blks, blk);
-		}
+		crypto_apply(flags, buf, crd->crd_skip, crd->crd_len, blkdata,
+		    &bd);
 	} else {
-		for (i = crd->crd_skip;
-		    i < crd->crd_skip + crd->crd_len; i += blks) {
-			crypto_copydata(flags, buf, i, blks, blk);
+		cd.bd = bd;
 
-			if (crd->crd_flags & CRD_F_ENCRYPT) {
-				/* XOR with previous block */
-				for (k = 0; k < blks; k++)
-					blk[k] ^= ivp[k];
+		cd.fun = bd.fun;
+		cd.arg = bd.arg;
 
-				exf->encrypt(sw->sw_kschedule, blk);
+		cd.bd.fun = (crd->crd_flags & CRD_F_ENCRYPT) ? cbcencdata :
+		    cbcdecdata;
+		cd.bd.arg = (caddr_t)&cd;
 
-				/*
-				 * Keep encrypted block for XOR'ing
-				 * with next block
-				 */
-				bcopy(blk, iv, blks);
-				ivp = iv;
-			} else {	/* decrypt */
-				/*
-				 * Keep encrypted block for XOR'ing
-				 * with next block
-				 */
-				if (ivp == iv)
-					bcopy(blk, piv, blks);
-				else
-					bcopy(blk, iv, blks);
-
-				exf->decrypt(sw->sw_kschedule, blk);
-
-				/* XOR with previous block */
-				for (j = 0; j < blks; j++)
-					blk[j] ^= ivp[j];
-
-				if (ivp == iv)
-					bcopy(piv, iv, blks);
-				else
-					ivp = iv;
-			}
-
-			crypto_copyback(flags, buf, i, blks, blk);
-		}
+		crypto_apply(flags, buf, crd->crd_skip, crd->crd_len, blkdata,
+		    &cd);
 	}
 
 	return 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409080452.s884qdER030292>