From owner-p4-projects@FreeBSD.ORG Mon Sep 8 04:54:22 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 78BA7892; Mon, 8 Sep 2014 04:54:22 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 13E62E4A for ; Mon, 8 Sep 2014 04:52:40 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B16CF10BA for ; Mon, 8 Sep 2014 04:52:39 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.9/8.14.9) with ESMTP id s884qdt0030295 for ; Mon, 8 Sep 2014 04:52:39 GMT (envelope-from jmg@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.9/8.14.9/Submit) id s884qdER030292 for perforce@freebsd.org; Mon, 8 Sep 2014 04:52:39 GMT (envelope-from jmg@freebsd.org) Date: Mon, 8 Sep 2014 04:52:39 GMT Message-Id: <201409080452.s884qdER030292@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jmg@freebsd.org using -f From: John-Mark Gurney Subject: PERFORCE change 1199888 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.18-1 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Sep 2014 04:54:22 -0000 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;