All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Herbert Xu" <herbert@gondor.apana.org.au>
To: Ard Biesheuvel <ardb@kernel.org>,
	Stephan Mueller <smueller@chronox.de>,
	Linux Crypto Mailing List <linux-crypto@vger.kernel.org>,
	Eric Biggers <ebiggers@kernel.org>
Subject: [v3 PATCH 14/31] crypto: x86/chacha - Add support for chaining
Date: Tue, 28 Jul 2020 17:19:10 +1000	[thread overview]
Message-ID: <E1k0JtG-0006Ot-1C@fornost.hmeau.com> (raw)
In-Reply-To: 20200728071746.GA22352@gondor.apana.org.au

As it stands chacha cannot do chaining.  That is, it has to handle
each request as a whole.  This patch adds support for chaining when
the CRYPTO_TFM_REQ_MORE flag is set.
    
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 arch/x86/crypto/chacha_glue.c |   55 +++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 16 deletions(-)

diff --git a/arch/x86/crypto/chacha_glue.c b/arch/x86/crypto/chacha_glue.c
index e67a59130025e..96cbdcbfe4f8f 100644
--- a/arch/x86/crypto/chacha_glue.c
+++ b/arch/x86/crypto/chacha_glue.c
@@ -6,14 +6,16 @@
  * Copyright (C) 2015 Martin Willi
  */
 
-#include <crypto/algapi.h>
 #include <crypto/internal/chacha.h>
 #include <crypto/internal/simd.h>
-#include <crypto/internal/skcipher.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/simd.h>
 
+#define CHACHA_STATE_ALIGN 16
+#define CHACHA_REQSIZE sizeof(struct chacha_reqctx) + \
+		       ((CHACHA_STATE_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
+
 asmlinkage void chacha_block_xor_ssse3(u32 *state, u8 *dst, const u8 *src,
 				       unsigned int len, int nrounds);
 asmlinkage void chacha_4block_xor_ssse3(u32 *state, u8 *dst, const u8 *src,
@@ -38,6 +40,12 @@ static __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_simd);
 static __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_avx2);
 static __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_avx512vl);
 
+static inline struct chacha_reqctx *chacha_request_ctx(
+	struct skcipher_request *req)
+{
+	return PTR_ALIGN(skcipher_request_ctx(req), CHACHA_STATE_ALIGN);
+}
+
 static unsigned int chacha_advance(unsigned int len, unsigned int maxblocks)
 {
 	len = min(len, maxblocks * CHACHA_BLOCK_SIZE);
@@ -159,16 +167,16 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes,
 }
 EXPORT_SYMBOL(chacha_crypt_arch);
 
-static int chacha_simd_stream_xor(struct skcipher_request *req,
-				  const struct chacha_ctx *ctx, const u8 *iv)
+static int chacha_simd_stream_xor(struct skcipher_request *req, int nrounds)
 {
-	u32 state[CHACHA_STATE_WORDS] __aligned(8);
+	struct chacha_reqctx *rctx = chacha_request_ctx(req);
 	struct skcipher_walk walk;
+	u32 *state = rctx->state;
 	int err;
 
-	err = skcipher_walk_virt(&walk, req, false);
+	rctx->init = req->base.flags & CRYPTO_TFM_REQ_MORE;
 
-	chacha_init_generic(state, ctx->key, iv);
+	err = skcipher_walk_virt(&walk, req, false);
 
 	while (walk.nbytes > 0) {
 		unsigned int nbytes = walk.nbytes;
@@ -180,12 +188,12 @@ static int chacha_simd_stream_xor(struct skcipher_request *req,
 		    !crypto_simd_usable()) {
 			chacha_crypt_generic(state, walk.dst.virt.addr,
 					     walk.src.virt.addr, nbytes,
-					     ctx->nrounds);
+					     nrounds);
 		} else {
 			kernel_fpu_begin();
 			chacha_dosimd(state, walk.dst.virt.addr,
 				      walk.src.virt.addr, nbytes,
-				      ctx->nrounds);
+				      nrounds);
 			kernel_fpu_end();
 		}
 		err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
@@ -197,33 +205,45 @@ static int chacha_simd_stream_xor(struct skcipher_request *req,
 static int chacha_simd(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct chacha_reqctx *rctx = chacha_request_ctx(req);
 	struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
 
-	return chacha_simd_stream_xor(req, ctx, req->iv);
+	if (!rctx->init)
+		chacha_init_generic(rctx->state, ctx->key, req->iv);
+
+	return chacha_simd_stream_xor(req, ctx->nrounds);
 }
 
 static int xchacha_simd(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct chacha_reqctx *rctx = chacha_request_ctx(req);
 	struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
-	u32 state[CHACHA_STATE_WORDS] __aligned(8);
-	struct chacha_ctx subctx;
+	int nrounds = ctx->nrounds;
+	u32 *state = rctx->state;
 	u8 real_iv[16];
+	u32 key[8];
+
+	if (rctx->init)
+		goto skip_init;
 
 	chacha_init_generic(state, ctx->key, req->iv);
 
 	if (req->cryptlen > CHACHA_BLOCK_SIZE && crypto_simd_usable()) {
 		kernel_fpu_begin();
-		hchacha_block_ssse3(state, subctx.key, ctx->nrounds);
+		hchacha_block_ssse3(state, key, nrounds);
 		kernel_fpu_end();
 	} else {
-		hchacha_block_generic(state, subctx.key, ctx->nrounds);
+		hchacha_block_generic(state, key, nrounds);
 	}
-	subctx.nrounds = ctx->nrounds;
 
 	memcpy(&real_iv[0], req->iv + 24, 8);
 	memcpy(&real_iv[8], req->iv + 16, 8);
-	return chacha_simd_stream_xor(req, &subctx, real_iv);
+
+	chacha_init_generic(state, key, real_iv);
+
+skip_init:
+	return chacha_simd_stream_xor(req, nrounds);
 }
 
 static struct skcipher_alg algs[] = {
@@ -239,6 +259,7 @@ static struct skcipher_alg algs[] = {
 		.max_keysize		= CHACHA_KEY_SIZE,
 		.ivsize			= CHACHA_IV_SIZE,
 		.chunksize		= CHACHA_BLOCK_SIZE,
+		.reqsize		= CHACHA_REQSIZE,
 		.setkey			= chacha20_setkey,
 		.encrypt		= chacha_simd,
 		.decrypt		= chacha_simd,
@@ -254,6 +275,7 @@ static struct skcipher_alg algs[] = {
 		.max_keysize		= CHACHA_KEY_SIZE,
 		.ivsize			= XCHACHA_IV_SIZE,
 		.chunksize		= CHACHA_BLOCK_SIZE,
+		.reqsize		= CHACHA_REQSIZE,
 		.setkey			= chacha20_setkey,
 		.encrypt		= xchacha_simd,
 		.decrypt		= xchacha_simd,
@@ -269,6 +291,7 @@ static struct skcipher_alg algs[] = {
 		.max_keysize		= CHACHA_KEY_SIZE,
 		.ivsize			= XCHACHA_IV_SIZE,
 		.chunksize		= CHACHA_BLOCK_SIZE,
+		.reqsize		= CHACHA_REQSIZE,
 		.setkey			= chacha12_setkey,
 		.encrypt		= xchacha_simd,
 		.decrypt		= xchacha_simd,

  parent reply	other threads:[~2020-07-28  7:19 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-28  7:17 [v3 PATCH 0/31] crypto: skcipher - Add support for no chaining and partial chaining Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 1/31] crypto: skcipher - Add final chunk size field for chaining Herbert Xu
2020-07-28 17:15   ` Eric Biggers
2020-07-28 17:22     ` Herbert Xu
2020-07-28 17:26       ` Ard Biesheuvel
2020-07-28 17:30         ` Herbert Xu
2020-07-28 17:46           ` Ard Biesheuvel
2020-07-28 22:12             ` Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 2/31] crypto: algif_skcipher - Add support for final_chunksize Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 3/31] crypto: cts - Add support for chaining Herbert Xu
2020-07-28 11:05   ` Ard Biesheuvel
2020-07-28 11:53     ` Herbert Xu
2020-07-28 11:59       ` Ard Biesheuvel
2020-07-28 12:03         ` Herbert Xu
2020-07-28 12:08           ` Ard Biesheuvel
2020-07-28 12:19             ` Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 4/31] crypto: arm64/aes-glue - Add support for chaining CTS Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 5/31] crypto: nitrox " Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 6/31] crypto: ccree " Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 7/31] crypto: skcipher - Add alg reqsize field Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 8/31] crypto: skcipher - Initialise requests to zero Herbert Xu
2020-07-28 17:10   ` Eric Biggers
2020-07-29  3:38     ` Herbert Xu
2020-07-28  7:18 ` [v3 PATCH 9/31] crypto: cryptd - Add support for chaining Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 10/31] crypto: chacha-generic " Herbert Xu
2020-08-10 15:20   ` Horia Geantă
2020-08-11  0:57     ` Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 11/31] crypto: arm/chacha " Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 12/31] crypto: arm64/chacha " Herbert Xu
2020-07-29  6:16   ` Ard Biesheuvel
2020-07-29  6:28     ` Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 13/31] crypto: mips/chacha " Herbert Xu
2020-07-28  7:19 ` Herbert Xu [this message]
2020-07-28  7:19 ` [v3 PATCH 15/31] crypto: inside-secure - Set final_chunksize on chacha Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 16/31] crypto: caam/qi2 " Herbert Xu
2020-08-10 15:24   ` Horia Geantă
2020-07-28  7:19 ` [v3 PATCH 17/31] crypto: ctr - Allow rfc3686 to be chained Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 18/31] crypto: crypto4xx - Remove rfc3686 implementation Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 19/31] crypto: caam - Remove rfc3686 implementations Herbert Xu
2020-08-10 16:47   ` Horia Geantă
2020-08-11  0:59     ` Herbert Xu
2020-08-11  7:32       ` Horia Geantă
2020-08-11  7:34         ` Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 20/31] crypto: nitrox - Set final_chunksize on rfc3686 Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 21/31] crypto: ccp - Remove rfc3686 implementation Herbert Xu
2020-08-06 19:16   ` John Allen
2020-07-28  7:19 ` [v3 PATCH 22/31] crypto: chelsio " Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 23/31] crypto: inside-secure - Set final_chunksize on rfc3686 Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 24/31] crypto: ixp4xx - Remove rfc3686 implementation Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 25/31] crypto: nx - Set final_chunksize on rfc3686 Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 26/31] crypto: essiv - Set final_chunksize Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 27/31] crypto: simd - Add support for chaining Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 28/31] crypto: arm64/essiv - Set final_chunksize Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 29/31] crypto: ccree - Set final_chunksize on essiv Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 30/31] crypto: kw - Set final_chunksize Herbert Xu
2020-07-28  7:19 ` [v3 PATCH 31/31] crypto: salsa20-generic - dd support for chaining Herbert Xu
2020-07-28 17:19 ` [v3 PATCH 0/31] crypto: skcipher - Add support for no chaining and partial chaining Eric Biggers
2020-07-29  3:40   ` Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1k0JtG-0006Ot-1C@fornost.hmeau.com \
    --to=herbert@gondor.apana.org.au \
    --cc=ardb@kernel.org \
    --cc=ebiggers@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=smueller@chronox.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.