PERFORCE change 1199888 for review
John-Mark Gurney
jmg at FreeBSD.org
Mon Sep 8 04:54:22 UTC 2014
http://p4web.freebsd.org/@@1199888?ac=10
Change 1199888 by jmg at 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;
More information about the p4-projects
mailing list