git: 2cd838281b44 - main - cryptosoft: Remove CBC handling from swcr_encdec.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 16 Dec 2021 22:09:30 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=2cd838281b44e337236b0606e89fb5bf58e86032

commit 2cd838281b44e337236b0606e89fb5bf58e86032
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-12-16 21:48:15 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2021-12-16 21:48:15 +0000

    cryptosoft: Remove CBC handling from swcr_encdec.
    
    All of the CBC ciphers now handle block chaining in the enc_xform.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D33489
---
 sys/opencrypto/cryptosoft.c | 65 ++++++---------------------------------------
 1 file changed, 8 insertions(+), 57 deletions(-)

diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index ebbc90aac05b..62dae55f1537 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -100,14 +100,13 @@ swcr_null(const struct swcr_session *ses, struct cryptop *crp)
 static int
 swcr_encdec(const struct swcr_session *ses, struct cryptop *crp)
 {
-	unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN];
-	unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN];
+	unsigned char blk[EALG_MAX_BLOCK_LEN];
 	const struct crypto_session_params *csp;
 	const struct enc_xform *exf;
 	const struct swcr_encdec *sw;
 	void *ctx;
 	size_t inlen, outlen;
-	int i, blks, resid;
+	int blks, resid;
 	struct crypto_buffer_cursor cc_in, cc_out;
 	const unsigned char *inblk;
 	unsigned char *outblk;
@@ -142,17 +141,8 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp)
 	} else
 		memcpy(ctx, sw->sw_ctx, exf->ctxsize);
 
-	crypto_read_iv(crp, iv);
-
-	if (exf->reinit) {
-		/*
-		 * xforms that provide a reinit method perform all IV
-		 * handling themselves.
-		 */
-		exf->reinit(ctx, iv, csp->csp_ivlen);
-	}
-
-	ivp = iv;
+	crypto_read_iv(crp, blk);
+	exf->reinit(ctx, blk, csp->csp_ivlen);
 
 	crypto_cursor_init(&cc_in, &crp->crp_buf);
 	crypto_cursor_advance(&cc_in, crp->crp_payload_start);
@@ -186,45 +176,11 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp)
 		if (outlen < blks)
 			outblk = blk;
 
-		/*
-		 * Ciphers without a 'reinit' hook are assumed to be
-		 * used in CBC mode where the chaining is done here.
-		 */
-		if (exf->reinit != NULL) {
-			if (encrypting)
-				exf->encrypt(ctx, inblk, outblk);
-			else
-				exf->decrypt(ctx, inblk, outblk);
-		} else if (encrypting) {
-			/* XOR with previous block */
-			for (i = 0; i < blks; i++)
-				outblk[i] = inblk[i] ^ ivp[i];
-
-			exf->encrypt(ctx, outblk, outblk);
-
-			/*
-			 * Keep encrypted block for XOR'ing
-			 * with next block
-			 */
-			memcpy(iv, outblk, blks);
-			ivp = iv;
-		} else {	/* decrypt */
-			/*
-			 * Keep encrypted block for XOR'ing
-			 * with next block
-			 */
-			nivp = (ivp == iv) ? iv2 : iv;
-			memcpy(nivp, inblk, blks);
-
+		if (encrypting)
+			exf->encrypt(ctx, inblk, outblk);
+		else
 			exf->decrypt(ctx, inblk, outblk);
 
-			/* XOR with previous block */
-			for (i = 0; i < blks; i++)
-				outblk[i] ^= ivp[i];
-
-			ivp = nivp;
-		}
-
 		if (inlen < blks) {
 			inblk = crypto_cursor_segment(&cc_in, &inlen);
 		} else {
@@ -249,10 +205,7 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp)
 	if (resid > 0) {
 		KASSERT(exf->native_blocksize != 0,
 		    ("%s: partial block of %d bytes for cipher %s",
-		    __func__, i, exf->name));
-		KASSERT(exf->reinit != NULL,
-		    ("%s: partial block cipher %s without reinit hook",
-		    __func__, exf->name));
+		    __func__, resid, exf->name));
 		KASSERT(resid < blks, ("%s: partial block too big", __func__));
 
 		inblk = crypto_cursor_segment(&cc_in, &inlen);
@@ -275,8 +228,6 @@ swcr_encdec(const struct swcr_session *ses, struct cryptop *crp)
 
 	explicit_bzero(ctx, exf->ctxsize);
 	explicit_bzero(blk, sizeof(blk));
-	explicit_bzero(iv, sizeof(iv));
-	explicit_bzero(iv2, sizeof(iv2));
 	return (0);
 }