Module Name:    src
Committed By:   riastradh
Date:           Sat Jun 13 22:15:06 UTC 2020

Modified Files:
        src/sys/dev: cgd.c cgd_crypto.c cgd_crypto.h

Log Message:
Eliminate uio indirection for cgd crypto.

We don't actually use it, and we only ever used it kludgily in the
CBC encryption direction in the past anyway.


To generate a diff of this commit:
cvs rdiff -u -r1.131 -r1.132 src/sys/dev/cgd.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/cgd_crypto.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/cgd_crypto.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/cgd.c
diff -u src/sys/dev/cgd.c:1.131 src/sys/dev/cgd.c:1.132
--- src/sys/dev/cgd.c:1.131	Sat Jun 13 18:42:22 2020
+++ src/sys/dev/cgd.c	Sat Jun 13 22:15:06 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd.c,v 1.131 2020/06/13 18:42:22 riastradh Exp $ */
+/* $NetBSD: cgd.c,v 1.132 2020/06/13 22:15:06 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.131 2020/06/13 18:42:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.132 2020/06/13 22:15:06 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1541,46 +1541,26 @@ cgd_cipher(struct cgd_softc *sc, void *d
 	char		*dst = dstv;
 	char		*src = srcv;
 	cfunc_cipher	*cipher = sc->sc_cfuncs->cf_cipher;
-	struct uio	dstuio;
-	struct uio	srcuio;
-	struct iovec	dstiov[2];
-	struct iovec	srciov[2];
 	size_t		blocksize = sc->sc_cdata.cf_blocksize;
 	size_t		todo;
 	char		blkno_buf[CGD_MAXBLOCKSIZE];
 
 	DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
 
-	KASSERTMSG(len % blocksize == 0,
-	    "cgd_cipher: len %% blocksize != 0");
-
+	KASSERT(len % blocksize == 0);
 	/* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
-	KASSERTMSG(sizeof(daddr_t) <= blocksize,
-	    "cgd_cipher: sizeof(daddr_t) > blocksize");
-
-	KASSERTMSG(blocksize <= CGD_MAXBLOCKSIZE,
-	    "cgd_cipher: blocksize > CGD_MAXBLOCKSIZE");
-
-	dstuio.uio_iov = dstiov;
-	dstuio.uio_iovcnt = 1;
-
-	srcuio.uio_iov = srciov;
-	srcuio.uio_iovcnt = 1;
+	KASSERT(sizeof(daddr_t) <= blocksize);
+	KASSERT(blocksize <= CGD_MAXBLOCKSIZE);
 
 	for (; len > 0; len -= todo) {
 		todo = MIN(len, secsize);
 
-		dstiov[0].iov_base = dst;
-		srciov[0].iov_base = src;
-		dstiov[0].iov_len  = todo;
-		srciov[0].iov_len  = todo;
-
 		memset(blkno_buf, 0x0, blocksize);
 		blkno2blkno_buf(blkno_buf, blkno);
 		IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
 		    blkno_buf, blocksize));
 
-		cipher(sc->sc_cdata.cf_priv, &dstuio, &srcuio, blkno_buf, dir);
+		cipher(sc->sc_cdata.cf_priv, dst, src, todo, blkno_buf, dir);
 
 		dst += todo;
 		src += todo;

Index: src/sys/dev/cgd_crypto.c
diff -u src/sys/dev/cgd_crypto.c:1.22 src/sys/dev/cgd_crypto.c:1.23
--- src/sys/dev/cgd_crypto.c:1.22	Sat Jun 13 18:40:14 2020
+++ src/sys/dev/cgd_crypto.c	Sat Jun 13 22:15:06 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd_crypto.c,v 1.22 2020/06/13 18:40:14 riastradh Exp $ */
+/* $NetBSD: cgd_crypto.c,v 1.23 2020/06/13 22:15:06 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.22 2020/06/13 18:40:14 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.23 2020/06/13 22:15:06 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -109,66 +109,6 @@ cryptfuncs_find(const char *alg)
 	return NULL;
 }
 
-typedef void	(*cipher_func)(void *, void *, const void *, size_t);
-
-static void
-cgd_cipher_uio(void *privdata, cipher_func cipher,
-	struct uio *dstuio, struct uio *srcuio);
-
-/*
- * cgd_cipher_uio takes a simple cbc or xts cipher and iterates
- * it over two struct uio's.  It presumes that the cipher function
- * that is passed to it keeps the IV state between calls.
- *
- * We assume that the caller has ensured that each segment is evenly
- * divisible by the block size, which for the cgd is a valid assumption.
- * If we were to make this code more generic, we might need to take care
- * of this case, either by issuing an error or copying the data.
- */
-
-static void
-cgd_cipher_uio(void *privdata, cipher_func cipher,
-    struct uio *dstuio, struct uio *srcuio)
-{
-	const struct iovec	*dst;
-	const struct iovec	*src;
-	int		 dstnum;
-	int		 dstoff = 0;
-	int		 srcnum;
-	int		 srcoff = 0;
-
-	dst = dstuio->uio_iov;
-	dstnum = dstuio->uio_iovcnt;
-	src = srcuio->uio_iov;
-	srcnum = srcuio->uio_iovcnt;
-	for (;;) {
-		int l = MIN(dst->iov_len - dstoff, src->iov_len - srcoff);
-		uint8_t *d = (uint8_t *)dst->iov_base + dstoff;
-		const uint8_t *s = (const uint8_t *)src->iov_base + srcoff;
-
-		cipher(privdata, d, s, l);
-
-		dstoff += l;
-		srcoff += l;
-		/*
-		 * We assume that {dst,src} == {dst,src}->iov_len,
-		 * because it should not be possible for it not to be.
-		 */
-		if (dstoff == dst->iov_len) {
-			dstoff = 0;
-			dstnum--;
-			dst++;
-		}
-		if (srcoff == src->iov_len) {
-			srcoff = 0;
-			srcnum--;
-			src++;
-		}
-		if (!srcnum || !dstnum)
-			break;
-	}
-}
-
 /*
  *  AES Framework
  */
@@ -178,11 +118,6 @@ struct aes_privdata {
 	keyInstance	ap_deckey;
 };
 
-struct aes_encdata {
-	keyInstance	*ae_key;	/* key for this direction */
-	uint8_t		 ae_iv[CGD_AES_BLOCK_SIZE]; /* Initialization Vector */
-};
-
 static void *
 cgd_cipher_aes_cbc_init(size_t keylen, const void *key, size_t *blocksize)
 {
@@ -212,58 +147,30 @@ cgd_cipher_aes_cbc_destroy(void *data)
 }
 
 static void
-aes_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct aes_encdata	*ae = privdata;
-	cipherInstance		 cipher;
-	int			 cipher_ok __diagused;
-
-	cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, ae->ae_iv);
-	KASSERT(cipher_ok > 0);
-	rijndael_blockEncrypt(&cipher, ae->ae_key, src, /*inputbits*/len * 8,
-	    dst);
-	(void)memcpy(ae->ae_iv, (uint8_t *)dst +
-	    (len - CGD_AES_BLOCK_SIZE), CGD_AES_BLOCK_SIZE);
-}
-
-static void
-aes_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct aes_encdata	*ae = privdata;
-	cipherInstance		 cipher;
-	int			 cipher_ok __diagused;
-
-	cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, ae->ae_iv);
-	KASSERT(cipher_ok > 0);
-	rijndael_blockDecrypt(&cipher, ae->ae_key, src, /*inputbits*/len * 8,
-	    dst);
-	(void)memcpy(ae->ae_iv, (const uint8_t *)src +
-	    (len - CGD_AES_BLOCK_SIZE), CGD_AES_BLOCK_SIZE);
-}
-
-static void
-cgd_cipher_aes_cbc(void *privdata, struct uio *dstuio,
-    struct uio *srcuio, const void *iv, int dir)
+cgd_cipher_aes_cbc(void *privdata, void *dst, const void *src, size_t nbytes,
+    const void *blkno, int dir)
 {
 	struct aes_privdata	*apd = privdata;
-	struct aes_encdata	 encd;
+	uint8_t			 iv[CGD_AES_BLOCK_SIZE] = {0};
 	cipherInstance		 cipher;
 	int			 cipher_ok __diagused;
 
-	/* Compute the CBC IV as AES_k(iv).  */
+	/* Compute the CBC IV as AES_k(blkno).  */
 	cipher_ok = rijndael_cipherInit(&cipher, MODE_ECB, NULL);
 	KASSERT(cipher_ok > 0);
-	rijndael_blockEncrypt(&cipher, &apd->ap_enckey, iv, /*inputbits*/128,
-	    encd.ae_iv);
+	rijndael_blockEncrypt(&cipher, &apd->ap_enckey, blkno, /*nbits*/128,
+	    iv);
 
+	cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, iv);
+	KASSERT(cipher_ok > 0);
 	switch (dir) {
 	case CGD_CIPHER_ENCRYPT:
-		encd.ae_key = &apd->ap_enckey;
-		cgd_cipher_uio(&encd, aes_cbc_enc_int, dstuio, srcuio);
+		rijndael_blockEncrypt(&cipher, &apd->ap_enckey, src,
+		    /*nbits*/nbytes * 8, dst);
 		break;
 	case CGD_CIPHER_DECRYPT:
-		encd.ae_key = &apd->ap_deckey;
-		cgd_cipher_uio(&encd, aes_cbc_dec_int, dstuio, srcuio);
+		rijndael_blockDecrypt(&cipher, &apd->ap_deckey, src,
+		    /*nbits*/nbytes * 8, dst);
 		break;
 	default:
 		panic("%s: unrecognised direction %d", __func__, dir);
@@ -280,11 +187,6 @@ struct aesxts {
 	keyInstance	ax_tweakkey;
 };
 
-struct aesxts_state {
-	struct aesxts	*axs_keys;
-	uint8_t		axs_tweak[CGD_AES_BLOCK_SIZE];
-};
-
 static void *
 cgd_cipher_aes_xts_init(size_t keylen, const void *xtskey, size_t *blocksize)
 {
@@ -322,53 +224,30 @@ cgd_cipher_aes_xts_destroy(void *cookie)
 }
 
 static void
-aes_xts_enc_int(void *state, void *dst, const void *src, size_t len)
-{
-	struct aesxts_state *axs = state;
-	cipherInstance cipher;
-	int cipher_ok __diagused;
-
-	cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, axs->axs_tweak);
-	KASSERT(cipher_ok > 0);
-	rijndael_blockEncrypt(&cipher, &axs->axs_keys->ax_enckey, src,
-	    /*inputbits*/len * 8, dst);
-	memcpy(axs->axs_tweak, cipher.IV, CGD_AES_BLOCK_SIZE);
-}
-
-static void
-aes_xts_dec_int(void *state, void *dst, const void *src, size_t len)
-{
-	struct aesxts_state *axs = state;
-	cipherInstance cipher;
-	int cipher_ok __diagused;
-
-	cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, axs->axs_tweak);
-	KASSERT(cipher_ok > 0);
-	rijndael_blockDecrypt(&cipher, &axs->axs_keys->ax_deckey, src,
-	    /*inputbits*/len * 8, dst);
-	memcpy(axs->axs_tweak, cipher.IV, CGD_AES_BLOCK_SIZE);
-}
-
-static void
-cgd_cipher_aes_xts(void *cookie, struct uio *dstuio, struct uio *srcuio,
-    const void *iv, int dir)
+cgd_cipher_aes_xts(void *cookie, void *dst, const void *src, size_t nbytes,
+    const void *blkno, int dir)
 {
 	struct aesxts *ax = cookie;
-	struct aesxts_state axs = { .axs_keys = ax };
+	uint8_t tweak[CGD_AES_BLOCK_SIZE];
 	cipherInstance cipher;
 	int cipher_ok __diagused;
 
+	/* Compute the initial tweak as AES_k(blkno).  */
 	cipher_ok = rijndael_cipherInit(&cipher, MODE_ECB, NULL);
 	KASSERT(cipher_ok > 0);
-	rijndael_blockEncrypt(&cipher, &ax->ax_tweakkey, iv, /*inputbits*/128,
-	    axs.axs_tweak);
+	rijndael_blockEncrypt(&cipher, &ax->ax_tweakkey, blkno, /*nbits*/128,
+	    tweak);
 
+	cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, tweak);
+	KASSERT(cipher_ok > 0);
 	switch (dir) {
 	case CGD_CIPHER_ENCRYPT:
-		cgd_cipher_uio(&axs, aes_xts_enc_int, dstuio, srcuio);
+		rijndael_blockEncrypt(&cipher, &ax->ax_enckey, src,
+		    /*nbits*/nbytes * 8, dst);
 		break;
 	case CGD_CIPHER_DECRYPT:
-		cgd_cipher_uio(&axs, aes_xts_dec_int, dstuio, srcuio);
+		rijndael_blockDecrypt(&cipher, &ax->ax_deckey, src,
+		    /*nbits*/nbytes * 8, dst);
 		break;
 	default:
 		panic("%s: unrecognised direction %d", __func__, dir);
@@ -385,13 +264,6 @@ struct c3des_privdata {
 	des_key_schedule	cp_key3;
 };
 
-struct c3des_encdata {
-	des_key_schedule	*ce_key1;
-	des_key_schedule	*ce_key2;
-	des_key_schedule	*ce_key3;
-	uint8_t			ce_iv[CGD_3DES_BLOCK_SIZE];
-};
-
 static void *
 cgd_cipher_3des_init(size_t keylen, const void *key, size_t *blocksize)
 {
@@ -428,49 +300,28 @@ cgd_cipher_3des_destroy(void *data)
 }
 
 static void
-c3des_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct	c3des_encdata *ce = privdata;
-
-	des_ede3_cbc_encrypt(src, dst, len, *ce->ce_key1, *ce->ce_key2,
-	    *ce->ce_key3, (des_cblock *)ce->ce_iv, /*encrypt*/1);
-	(void)memcpy(ce->ce_iv, (const uint8_t *)dst +
-	    (len - CGD_3DES_BLOCK_SIZE), CGD_3DES_BLOCK_SIZE);
-}
-
-static void
-c3des_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct	c3des_encdata *ce = privdata;
-
-	des_ede3_cbc_encrypt(src, dst, len, *ce->ce_key1, *ce->ce_key2,
-	    *ce->ce_key3, (des_cblock *)ce->ce_iv, /*encrypt*/0);
-	(void)memcpy(ce->ce_iv, (const uint8_t *)src +
-	    (len - CGD_3DES_BLOCK_SIZE), CGD_3DES_BLOCK_SIZE);
-}
-
-static void
-cgd_cipher_3des_cbc(void *privdata, struct uio *dstuio,
-	struct uio *srcuio, const void *iv, int dir)
+cgd_cipher_3des_cbc(void *privdata, void *dst, const void *src, size_t nbytes,
+    const void *blkno, int dir)
 {
 	struct	c3des_privdata *cp = privdata;
-	struct	c3des_encdata ce;
 	des_cblock zero;
+	uint8_t iv[CGD_3DES_BLOCK_SIZE];
 
-	/* Compute the CBC IV as 3DES_k(iv) = 3DES-CBC_k(iv, 0).  */
+	/* Compute the CBC IV as 3DES_k(blkno) = 3DES-CBC_k(iv=blkno, 0).  */
 	memset(&zero, 0, sizeof(zero));
-	des_ede3_cbc_encrypt(iv, ce.ce_iv, CGD_3DES_BLOCK_SIZE,
+	des_ede3_cbc_encrypt(blkno, iv, CGD_3DES_BLOCK_SIZE,
 	    cp->cp_key1, cp->cp_key2, cp->cp_key3, &zero, /*encrypt*/1);
 
-	ce.ce_key1 = &cp->cp_key1;
-	ce.ce_key2 = &cp->cp_key2;
-	ce.ce_key3 = &cp->cp_key3;
 	switch (dir) {
 	case CGD_CIPHER_ENCRYPT:
-		cgd_cipher_uio(&ce, c3des_cbc_enc_int, dstuio, srcuio);
+		des_ede3_cbc_encrypt(src, dst, nbytes,
+		    cp->cp_key1, cp->cp_key2, cp->cp_key3,
+		    (des_cblock *)iv, /*encrypt*/1);
 		break;
 	case CGD_CIPHER_DECRYPT:
-		cgd_cipher_uio(&ce, c3des_cbc_dec_int, dstuio, srcuio);
+		des_ede3_cbc_encrypt(src, dst, nbytes,
+		    cp->cp_key1, cp->cp_key2, cp->cp_key3,
+		    (des_cblock *)iv, /*encrypt*/0);
 		break;
 	default:
 		panic("%s: unrecognised direction %d", __func__, dir);
@@ -520,48 +371,27 @@ cgd_cipher_bf_destroy(void *data)
 }
 
 static void
-bf_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct	bf_encdata *be = privdata;
-
-	BF_cbc_encrypt(src, dst, len, be->be_key, be->be_iv, /*encrypt*/1);
-	(void)memcpy(be->be_iv, (uint8_t *)dst +
-	    (len - CGD_BF_BLOCK_SIZE), CGD_BF_BLOCK_SIZE);
-}
-
-static void
-bf_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len)
-{
-	struct	bf_encdata *be = privdata;
-
-	BF_cbc_encrypt(src, dst, len, be->be_key, be->be_iv, /*encrypt*/0);
-	(void)memcpy(be->be_iv, (const uint8_t *)src +
-	    (len - CGD_BF_BLOCK_SIZE), CGD_BF_BLOCK_SIZE);
-}
-
-static void
-cgd_cipher_bf_cbc(void *privdata, struct uio *dstuio,
-    struct uio *srcuio, const void *iv, int dir)
+cgd_cipher_bf_cbc(void *privdata, void *dst, const void *src, size_t nbytes,
+    const void *blkno, int dir)
 {
 	struct	bf_privdata *bp = privdata;
-	struct	bf_encdata be;
-	char	zero_iv[CGD_BF_BLOCK_SIZE];
+	uint8_t zero[CGD_BF_BLOCK_SIZE], iv[CGD_BF_BLOCK_SIZE];
 
-	/* Compute the CBC IV as Blowfish_k(iv) = BF_CBC_k(iv, 0).  */
-	memset(zero_iv, 0, sizeof(zero_iv));
-	BF_cbc_encrypt(iv, be.be_iv, CGD_BF_BLOCK_SIZE, &bp->bp_key, zero_iv,
+	/* Compute the CBC IV as Blowfish_k(blkno) = BF_CBC_k(blkno, 0).  */
+	memset(zero, 0, sizeof(zero));
+	BF_cbc_encrypt(blkno, iv, CGD_BF_BLOCK_SIZE, &bp->bp_key, zero,
 	    /*encrypt*/1);
 
-	be.be_key = &bp->bp_key;
 	switch (dir) {
 	case CGD_CIPHER_ENCRYPT:
-		cgd_cipher_uio(&be, bf_cbc_enc_int, dstuio, srcuio);
+		BF_cbc_encrypt(src, dst, nbytes, &bp->bp_key, iv,
+		    /*encrypt*/1);
 		break;
 	case CGD_CIPHER_DECRYPT:
-		cgd_cipher_uio(&be, bf_cbc_dec_int, dstuio, srcuio);
+		BF_cbc_encrypt(src, dst, nbytes, &bp->bp_key, iv,
+		    /*encrypt*/0);
 		break;
 	default:
 		panic("%s: unrecognised direction %d", __func__, dir);
 	}
-
 }

Index: src/sys/dev/cgd_crypto.h
diff -u src/sys/dev/cgd_crypto.h:1.11 src/sys/dev/cgd_crypto.h:1.12
--- src/sys/dev/cgd_crypto.h:1.11	Sat Jun 13 18:35:35 2020
+++ src/sys/dev/cgd_crypto.h	Sat Jun 13 22:15:06 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd_crypto.h,v 1.11 2020/06/13 18:35:35 riastradh Exp $ */
+/* $NetBSD: cgd_crypto.h,v 1.12 2020/06/13 22:15:06 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -41,8 +41,8 @@
 
 typedef void *(cfunc_init)(size_t, const void *, size_t *);
 typedef void  (cfunc_destroy)(void *);
-typedef void  (cfunc_cipher)(void *, struct uio *, struct uio *, const void *,
-				int);
+typedef void  (cfunc_cipher)(void *, void *, const void *, size_t,
+    const void *, int);
 
 struct cryptfuncs {
 	const char		 *cf_name;	/* cipher name */

Reply via email to