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

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

Change 1199151 by jmg@jmg_carbon2 on 2014/08/24 02:48:49

	simplify the code, don't unroll the iov, mbuf and linear bufs,
	instead, use the helper functions...  Yes, this will probably
	be a bit slowerly, but, there are cleaner ways to do this...
	
	A better solution is to create a helper function that will
	properly pass blocks down, as the _apply function may pass
	partial blocks that will be continued in a future call...
	
	This can be done for both reinit'd and CBC blocked algos...

Affected files ...

.. //depot/projects/opencrypto/sys/opencrypto/cryptosoft.c#7 edit

Differences ...

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

@@ -83,7 +83,7 @@
 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], *idat;
+	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN];
 	unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
 	struct enc_xform *exf;
 	int i, k, j, blks;
@@ -112,7 +112,7 @@
 			crypto_copyback(flags, buf, crd->crd_inject, blks, iv);
 
 	} else {	/* Decryption */
-			/* IV explicitly provided ? */
+		/* IV explicitly provided ? */
 		if (crd->crd_flags & CRD_F_IV_EXPLICIT)
 			bcopy(crd->crd_iv, iv, blks);
 		else {
@@ -126,6 +126,7 @@
 
 		if (sw->sw_kschedule)
 			exf->zerokey(&(sw->sw_kschedule));
+
 		error = exf->setkey(&sw->sw_kschedule,
 				crd->crd_key, crd->crd_klen / 8);
 		if (error)
@@ -134,333 +135,69 @@
 
 	ivp = iv;
 
-	/*
-	 * xforms that provide a reinit method perform all IV
-	 * handling themselves.
-	 */
-	if (exf->reinit)
+	if (exf->reinit) {
+		/*
+		 * xforms that provide a reinit method perform all IV
+		 * handling themselves.
+		 */
 		exf->reinit(sw->sw_kschedule, iv);
 
-	if (flags & CRYPTO_F_IMBUF) {
-		struct mbuf *m = (struct mbuf *) buf;
+		for (i = crd->crd_skip;
+		    i < crd->crd_skip + crd->crd_len; i += blks) {
+			crypto_copydata(flags, buf, i, blks, blk);
 
-		/* Find beginning of data */
-		m = m_getptr(m, crd->crd_skip, &k);
-		if (m == NULL)
-			return EINVAL;
+			if (crd->crd_flags & CRD_F_ENCRYPT)
+				exf->encrypt(sw->sw_kschedule, blk);
+			else
+				exf->decrypt(sw->sw_kschedule, blk);
 
-		i = crd->crd_len;
-
-		while (i > 0) {
-			/*
-			 * If there's insufficient data at the end of
-			 * an mbuf, we have to do some copying.
-			 */
-			if (m->m_len < k + blks && m->m_len != k) {
-				m_copydata(m, k, blks, blk);
-
-				/* Actual encryption/decryption */
-				if (exf->reinit) {
-					if (crd->crd_flags & CRD_F_ENCRYPT) {
-						exf->encrypt(sw->sw_kschedule,
-						    blk);
-					} else {
-						exf->decrypt(sw->sw_kschedule,
-						    blk);
-					}
-				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
-					/* XOR with previous block */
-					for (j = 0; j < blks; j++)
-						blk[j] ^= ivp[j];
-
-					exf->encrypt(sw->sw_kschedule, blk);
-
-					/*
-					 * 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;
-				}
-
-				/* Copy back decrypted block */
-				m_copyback(m, k, blks, blk);
-
-				/* Advance pointer */
-				m = m_getptr(m, k + blks, &k);
-				if (m == NULL)
-					return EINVAL;
-
-				i -= blks;
-
-				/* Could be done... */
-				if (i == 0)
-					break;
-			}
-
-			/* Skip possibly empty mbufs */
-			if (k == m->m_len) {
-				for (m = m->m_next; m && m->m_len == 0;
-				    m = m->m_next)
-					;
-				k = 0;
-			}
-
-			/* Sanity check */
-			if (m == NULL)
-				return EINVAL;
-
-			/*
-			 * Warning: idat may point to garbage here, but
-			 * we only use it in the while() loop, only if
-			 * there are indeed enough data.
-			 */
-			idat = mtod(m, unsigned char *) + k;
-
-	   		while (m->m_len >= k + blks && i > 0) {
-				if (exf->reinit) {
-					if (crd->crd_flags & CRD_F_ENCRYPT) {
-						exf->encrypt(sw->sw_kschedule,
-						    idat);
-					} else {
-						exf->decrypt(sw->sw_kschedule,
-						    idat);
-					}
-				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
-					/* XOR with previous block/IV */
-					for (j = 0; j < blks; j++)
-						idat[j] ^= ivp[j];
-
-					exf->encrypt(sw->sw_kschedule, idat);
-					ivp = idat;
-				} else {	/* decrypt */
-					/*
-					 * Keep encrypted block to be used
-					 * in next block's processing.
-					 */
-					if (ivp == iv)
-						bcopy(idat, piv, blks);
-					else
-						bcopy(idat, iv, blks);
-
-					exf->decrypt(sw->sw_kschedule, idat);
-
-					/* XOR with previous block/IV */
-					for (j = 0; j < blks; j++)
-						idat[j] ^= ivp[j];
-
-					if (ivp == iv)
-						bcopy(piv, iv, blks);
-					else
-						ivp = iv;
-				}
-
-				idat += blks;
-				k += blks;
-				i -= blks;
-			}
+			crypto_copyback(flags, buf, i, blks, blk);
 		}
+	} else {
+		for (i = crd->crd_skip;
+		    i < crd->crd_skip + crd->crd_len; i += blks) {
+			crypto_copydata(flags, buf, i, blks, blk);
 
-		return 0; /* Done with mbuf encryption/decryption */
-	} else if (flags & CRYPTO_F_IOV) {
-		struct uio *uio = (struct uio *) buf;
-		struct iovec *iov;
+			if (crd->crd_flags & CRD_F_ENCRYPT) {
+				/* XOR with previous block */
+				for (k = 0; k < blks; k++)
+					blk[k] ^= ivp[k];
 
-		/* Find beginning of data */
-		iov = cuio_getptr(uio, crd->crd_skip, &k);
-		if (iov == NULL)
-			return EINVAL;
+				exf->encrypt(sw->sw_kschedule, blk);
 
-		i = crd->crd_len;
-
-		while (i > 0) {
-			/*
-			 * If there's insufficient data at the end of
-			 * an iovec, we have to do some copying.
-			 */
-			if (iov->iov_len < k + blks && iov->iov_len != k) {
-				cuio_copydata(uio, k, blks, blk);
-
-				/* Actual encryption/decryption */
-				if (exf->reinit) {
-					if (crd->crd_flags & CRD_F_ENCRYPT) {
-						exf->encrypt(sw->sw_kschedule,
-						    blk);
-					} else {
-						exf->decrypt(sw->sw_kschedule,
-						    blk);
-					}
-				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
-					/* XOR with previous block */
-					for (j = 0; j < blks; j++)
-						blk[j] ^= ivp[j];
-
-					exf->encrypt(sw->sw_kschedule, blk);
-
-					/*
-					 * Keep encrypted block for XOR'ing
-					 * with next block
-					 */
+				/*
+				 * 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);
-					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);
+				exf->decrypt(sw->sw_kschedule, blk);
 
-					/* XOR with previous block */
-					for (j = 0; j < blks; j++)
-						blk[j] ^= ivp[j];
+				/* XOR with previous block */
+				for (j = 0; j < blks; j++)
+					blk[j] ^= ivp[j];
 
-					if (ivp == iv)
-						bcopy(piv, iv, blks);
-					else
-						ivp = iv;
-				}
-
-				/* Copy back decrypted block */
-				cuio_copyback(uio, k, blks, blk);
-
-				/* Advance pointer */
-				iov = cuio_getptr(uio, k + blks, &k);
-				if (iov == NULL)
-					return EINVAL;
-
-				i -= blks;
-
-				/* Could be done... */
-				if (i == 0)
-					break;
-			}
-
-			/*
-			 * Warning: idat may point to garbage here, but
-			 * we only use it in the while() loop, only if
-			 * there are indeed enough data.
-			 */
-			idat = (char *)iov->iov_base + k;
-
-	   		while (iov->iov_len >= k + blks && i > 0) {
-				if (exf->reinit) {
-					if (crd->crd_flags & CRD_F_ENCRYPT) {
-						exf->encrypt(sw->sw_kschedule,
-						    idat);
-					} else {
-						exf->decrypt(sw->sw_kschedule,
-						    idat);
-					}
-				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
-					/* XOR with previous block/IV */
-					for (j = 0; j < blks; j++)
-						idat[j] ^= ivp[j];
-
-					exf->encrypt(sw->sw_kschedule, idat);
-					ivp = idat;
-				} else {	/* decrypt */
-					/*
-					 * Keep encrypted block to be used
-					 * in next block's processing.
-					 */
-					if (ivp == iv)
-						bcopy(idat, piv, blks);
-					else
-						bcopy(idat, iv, blks);
-
-					exf->decrypt(sw->sw_kschedule, idat);
-
-					/* XOR with previous block/IV */
-					for (j = 0; j < blks; j++)
-						idat[j] ^= ivp[j];
-
-					if (ivp == iv)
-						bcopy(piv, iv, blks);
-					else
-						ivp = iv;
-				}
-
-				idat += blks;
-				k += blks;
-				i -= blks;
-			}
-			if (k == iov->iov_len) {
-				iov++;
-				k = 0;
-			}
-		}
-
-		return 0; /* Done with iovec encryption/decryption */
-	} else {	/* contiguous buffer */
-		if (exf->reinit) {
-			for (i = crd->crd_skip;
-			    i < crd->crd_skip + crd->crd_len; i += blks) {
-				if (crd->crd_flags & CRD_F_ENCRYPT)
-					exf->encrypt(sw->sw_kschedule, buf + i);
+				if (ivp == iv)
+					bcopy(piv, iv, blks);
 				else
-					exf->decrypt(sw->sw_kschedule, buf + i);
-			}
-		} else if (crd->crd_flags & CRD_F_ENCRYPT) {
-			for (i = crd->crd_skip;
-			    i < crd->crd_skip + crd->crd_len; i += blks) {
-				/* XOR with the IV/previous block, as appropriate. */
-				if (i == crd->crd_skip)
-					for (k = 0; k < blks; k++)
-						buf[i + k] ^= ivp[k];
-				else
-					for (k = 0; k < blks; k++)
-						buf[i + k] ^= buf[i + k - blks];
-				exf->encrypt(sw->sw_kschedule, buf + i);
+					ivp = iv;
 			}
-		} else {		/* Decrypt */
-			/*
-			 * Start at the end, so we don't need to keep the encrypted
-			 * block as the IV for the next block.
-			 */
-			for (i = crd->crd_skip + crd->crd_len - blks;
-			    i >= crd->crd_skip; i -= blks) {
-				exf->decrypt(sw->sw_kschedule, buf + i);
 
-				/* XOR with the IV/previous block, as appropriate */
-				if (i == crd->crd_skip)
-					for (k = 0; k < blks; k++)
-						buf[i + k] ^= ivp[k];
-				else
-					for (k = 0; k < blks; k++)
-						buf[i + k] ^= buf[i + k - blks];
-			}
+			crypto_copyback(flags, buf, i, blks, blk);
 		}
-
-		return 0; /* Done with contiguous buffer encryption/decryption */
 	}
 
-	/* Unreachable */
-	return EINVAL;
+	return 0;
 }
 
 static void



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