All of lore.kernel.org
 help / color / mirror / Atom feed
From: Herbert Xu <herbert@gondor.apana.org.au>
To: Linux Crypto Mailing List <linux-crypto@vger.kernel.org>
Subject: [PATCH 07/15] crypto: adiantum - Use lskcipher instead of cipher
Date: Tue, 5 Dec 2023 17:52:33 +0800	[thread overview]
Message-ID: <3ec460107b256268dd00069fff7d92bcc975259e.1707815065.git.herbert@gondor.apana.org.au> (raw)
In-Reply-To: <cover.1707815065.git.herbert@gondor.apana.org.au>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 10369 bytes --]

Use the new lskcipher interface for simple block cipher.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 crypto/adiantum.c | 130 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 96 insertions(+), 34 deletions(-)

diff --git a/crypto/adiantum.c b/crypto/adiantum.c
index 60f3883b736a..ee55b1f8565c 100644
--- a/crypto/adiantum.c
+++ b/crypto/adiantum.c
@@ -32,7 +32,6 @@
 
 #include <crypto/b128ops.h>
 #include <crypto/chacha.h>
-#include <crypto/internal/cipher.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/poly1305.h>
 #include <crypto/internal/skcipher.h>
@@ -63,13 +62,13 @@
 
 struct adiantum_instance_ctx {
 	struct crypto_skcipher_spawn streamcipher_spawn;
-	struct crypto_cipher_spawn blockcipher_spawn;
+	struct crypto_lskcipher_spawn blockcipher_spawn;
 	struct crypto_shash_spawn hash_spawn;
 };
 
 struct adiantum_tfm_ctx {
 	struct crypto_skcipher *streamcipher;
-	struct crypto_cipher *blockcipher;
+	struct crypto_lskcipher *blockcipher;
 	struct crypto_shash *hash;
 	struct poly1305_core_key header_hash_key;
 };
@@ -157,12 +156,12 @@ static int adiantum_setkey(struct crypto_skcipher *tfm, const u8 *key,
 	keyp = data->derived_keys;
 
 	/* Set the block cipher key (K_E) */
-	crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
-	crypto_cipher_set_flags(tctx->blockcipher,
-				crypto_skcipher_get_flags(tfm) &
-				CRYPTO_TFM_REQ_MASK);
-	err = crypto_cipher_setkey(tctx->blockcipher, keyp,
-				   BLOCKCIPHER_KEY_SIZE);
+	crypto_lskcipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
+	crypto_lskcipher_set_flags(tctx->blockcipher,
+				   crypto_skcipher_get_flags(tfm) &
+				   CRYPTO_TFM_REQ_MASK);
+	err = crypto_lskcipher_setkey(tctx->blockcipher, keyp,
+				     BLOCKCIPHER_KEY_SIZE);
 	if (err)
 		goto out;
 	keyp += BLOCKCIPHER_KEY_SIZE;
@@ -287,9 +286,14 @@ static int adiantum_finish(struct skcipher_request *req)
 	int err;
 
 	/* If decrypting, decrypt C_M with the block cipher to get P_M */
-	if (!rctx->enc)
-		crypto_cipher_decrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
-					  rctx->rbuf.bytes);
+	if (!rctx->enc) {
+		err = crypto_lskcipher_decrypt(tctx->blockcipher,
+					       rctx->rbuf.bytes,
+					       rctx->rbuf.bytes,
+					       BLOCKCIPHER_BLOCK_SIZE, NULL);
+		if (err)
+			return err;
+	}
 
 	/*
 	 * Second hash step
@@ -379,9 +383,14 @@ static int adiantum_crypt(struct skcipher_request *req, bool enc)
 	le128_add(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest);
 
 	/* If encrypting, encrypt P_M with the block cipher to get C_M */
-	if (enc)
-		crypto_cipher_encrypt_one(tctx->blockcipher, rctx->rbuf.bytes,
-					  rctx->rbuf.bytes);
+	if (enc) {
+		err = crypto_lskcipher_encrypt(tctx->blockcipher,
+					       rctx->rbuf.bytes,
+					       rctx->rbuf.bytes,
+					       BLOCKCIPHER_BLOCK_SIZE, NULL);
+		if (err)
+			return err;
+	}
 
 	/* Initialize the rest of the XChaCha IV (first part is C_M) */
 	BUILD_BUG_ON(BLOCKCIPHER_BLOCK_SIZE != 16);
@@ -430,7 +439,7 @@ static int adiantum_init_tfm(struct crypto_skcipher *tfm)
 	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
 	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
 	struct crypto_skcipher *streamcipher;
-	struct crypto_cipher *blockcipher;
+	struct crypto_lskcipher *blockcipher;
 	struct crypto_shash *hash;
 	unsigned int subreq_size;
 	int err;
@@ -439,7 +448,7 @@ static int adiantum_init_tfm(struct crypto_skcipher *tfm)
 	if (IS_ERR(streamcipher))
 		return PTR_ERR(streamcipher);
 
-	blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
+	blockcipher = crypto_spawn_lskcipher(&ictx->blockcipher_spawn);
 	if (IS_ERR(blockcipher)) {
 		err = PTR_ERR(blockcipher);
 		goto err_free_streamcipher;
@@ -470,7 +479,7 @@ static int adiantum_init_tfm(struct crypto_skcipher *tfm)
 	return 0;
 
 err_free_blockcipher:
-	crypto_free_cipher(blockcipher);
+	crypto_free_lskcipher(blockcipher);
 err_free_streamcipher:
 	crypto_free_skcipher(streamcipher);
 	return err;
@@ -481,7 +490,7 @@ static void adiantum_exit_tfm(struct crypto_skcipher *tfm)
 	struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
 
 	crypto_free_skcipher(tctx->streamcipher);
-	crypto_free_cipher(tctx->blockcipher);
+	crypto_free_lskcipher(tctx->blockcipher);
 	crypto_free_shash(tctx->hash);
 }
 
@@ -490,7 +499,7 @@ static void adiantum_free_instance(struct skcipher_instance *inst)
 	struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
 
 	crypto_drop_skcipher(&ictx->streamcipher_spawn);
-	crypto_drop_cipher(&ictx->blockcipher_spawn);
+	crypto_drop_lskcipher(&ictx->blockcipher_spawn);
 	crypto_drop_shash(&ictx->hash_spawn);
 	kfree(inst);
 }
@@ -500,17 +509,21 @@ static void adiantum_free_instance(struct skcipher_instance *inst)
  * See the comment at the beginning of this file.
  */
 static bool adiantum_supported_algorithms(struct skcipher_alg_common *streamcipher_alg,
-					  struct crypto_alg *blockcipher_alg,
+					  struct lskcipher_alg *blockcipher_alg,
 					  struct shash_alg *hash_alg)
 {
 	if (strcmp(streamcipher_alg->base.cra_name, "xchacha12") != 0 &&
 	    strcmp(streamcipher_alg->base.cra_name, "xchacha20") != 0)
 		return false;
 
-	if (blockcipher_alg->cra_cipher.cia_min_keysize > BLOCKCIPHER_KEY_SIZE ||
-	    blockcipher_alg->cra_cipher.cia_max_keysize < BLOCKCIPHER_KEY_SIZE)
+	if (blockcipher_alg->co.min_keysize > BLOCKCIPHER_KEY_SIZE ||
+	    blockcipher_alg->co.max_keysize < BLOCKCIPHER_KEY_SIZE)
 		return false;
-	if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
+	if (blockcipher_alg->co.base.cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
+		return false;
+	if (blockcipher_alg->co.ivsize)
+		return false;
+	if (blockcipher_alg->co.statesize)
 		return false;
 
 	if (strcmp(hash_alg->base.cra_name, "nhpoly1305") != 0)
@@ -526,8 +539,12 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 	struct skcipher_instance *inst;
 	struct adiantum_instance_ctx *ictx;
 	struct skcipher_alg_common *streamcipher_alg;
-	struct crypto_alg *blockcipher_alg;
+	char ecb_driver_name[CRYPTO_MAX_ALG_NAME];
+	struct lskcipher_alg *blockcipher_alg;
+	char ecb_name[CRYPTO_MAX_ALG_NAME];
+	const char *cipher_driver_name;
 	struct shash_alg *hash_alg;
+	const char *cipher_name;
 	int err;
 
 	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
@@ -548,12 +565,27 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 	streamcipher_alg = crypto_spawn_skcipher_alg_common(&ictx->streamcipher_spawn);
 
 	/* Block cipher, e.g. "aes" */
-	err = crypto_grab_cipher(&ictx->blockcipher_spawn,
-				 skcipher_crypto_instance(inst),
-				 crypto_attr_alg_name(tb[2]), 0, mask);
+	cipher_name = crypto_attr_alg_name(tb[2]);
+	cipher_driver_name = cipher_name;
+	err = crypto_grab_lskcipher(&ictx->blockcipher_spawn,
+				    skcipher_crypto_instance(inst),
+				    cipher_name, 0, mask);
+
+	ecb_name[0] = 0;
+	if (err == -ENOENT) {
+		err = -ENAMETOOLONG;
+		if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)",
+			     cipher_name) >= CRYPTO_MAX_ALG_NAME)
+			goto err_free_inst;
+
+		err = crypto_grab_lskcipher(&ictx->blockcipher_spawn,
+					    skcipher_crypto_instance(inst),
+					    ecb_name, 0, mask);
+	}
+
 	if (err)
 		goto err_free_inst;
-	blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
+	blockcipher_alg = crypto_spawn_lskcipher_alg(&ictx->blockcipher_spawn);
 
 	/* NHPoly1305 ε-∆U hash function */
 	nhpoly1305_name = crypto_attr_alg_name(tb[3]);
@@ -571,22 +603,52 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 					   hash_alg)) {
 		pr_warn("Unsupported Adiantum instantiation: (%s,%s,%s)\n",
 			streamcipher_alg->base.cra_name,
-			blockcipher_alg->cra_name, hash_alg->base.cra_name);
+			blockcipher_alg->co.base.cra_name,
+			hash_alg->base.cra_name);
 		err = -EINVAL;
 		goto err_free_inst;
 	}
 
 	/* Instance fields */
 
+	cipher_name = blockcipher_alg->co.base.cra_name;
+	cipher_driver_name = blockcipher_alg->co.base.cra_driver_name;
+	if (ecb_name[0]) {
+		int len;
+
+		err = -EINVAL;
+		len = strscpy(ecb_name, &blockcipher_alg->co.base.cra_name[4],
+			      sizeof(ecb_name));
+		if (len < 2)
+			goto err_free_inst;
+
+		if (ecb_name[len - 1] != ')')
+			goto err_free_inst;
+
+		ecb_name[len - 1] = 0;
+		cipher_name = ecb_name;
+
+		len = strscpy(ecb_driver_name, &blockcipher_alg->co.base.cra_driver_name[4],
+			      sizeof(ecb_driver_name));
+		if (len < 2)
+			goto err_free_inst;
+
+		if (ecb_driver_name[len - 1] != ')')
+			goto err_free_inst;
+
+		ecb_driver_name[len - 1] = 0;
+		cipher_driver_name = ecb_driver_name;
+	}
+
 	err = -ENAMETOOLONG;
 	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
 		     "adiantum(%s,%s)", streamcipher_alg->base.cra_name,
-		     blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
+		     cipher_name) >= CRYPTO_MAX_ALG_NAME)
 		goto err_free_inst;
 	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 		     "adiantum(%s,%s,%s)",
 		     streamcipher_alg->base.cra_driver_name,
-		     blockcipher_alg->cra_driver_name,
+		     cipher_driver_name,
 		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
 		goto err_free_inst;
 
@@ -601,7 +663,7 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 	 */
 	inst->alg.base.cra_priority = (4 * streamcipher_alg->base.cra_priority +
 				       2 * hash_alg->base.cra_priority +
-				       blockcipher_alg->cra_priority) / 7;
+				       blockcipher_alg->co.base.cra_priority) / 7;
 
 	inst->alg.setkey = adiantum_setkey;
 	inst->alg.encrypt = adiantum_encrypt;
@@ -611,6 +673,7 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.min_keysize = streamcipher_alg->min_keysize;
 	inst->alg.max_keysize = streamcipher_alg->max_keysize;
 	inst->alg.ivsize = TWEAK_SIZE;
+	inst->alg.co.twopass = true;
 
 	inst->free = adiantum_free_instance;
 
@@ -646,4 +709,3 @@ MODULE_DESCRIPTION("Adiantum length-preserving encryption mode");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
 MODULE_ALIAS_CRYPTO("adiantum");
-MODULE_IMPORT_NS(CRYPTO_INTERNAL);
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


  parent reply	other threads:[~2024-02-13  9:16 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-13  9:04 [PATCH 00/15] crypto: Add twopass lskcipher for adiantum Herbert Xu
2023-12-02  4:55 ` [PATCH 01/15] crypto: skcipher - Add tailsize attribute Herbert Xu
2024-02-14 23:44   ` Eric Biggers
2024-02-15  6:40     ` Herbert Xu
2024-02-23  6:01       ` Eric Biggers
2023-12-02  5:42 ` [PATCH 02/15] crypto: algif_skcipher - Add support for tailsize Herbert Xu
2023-12-04 10:24 ` [PATCH 04/15] crypto: xts - Convert from skcipher to lskcipher Herbert Xu
2023-12-05  6:09 ` [PATCH 05/15] crypto: skcipher - Add twopass attribute Herbert Xu
2023-12-05  6:13 ` [PATCH 06/15] crypto: algif_skcipher - Disallow nonincremental algorithms Herbert Xu
2024-02-14 22:56   ` Eric Biggers
2024-02-15  6:47     ` Herbert Xu
2024-02-23  6:00       ` Eric Biggers
2023-12-05  9:52 ` Herbert Xu [this message]
2023-12-06  4:46 ` [PATCH 08/15] crypto: skcipher - Add incremental support to lskcipher wrapper Herbert Xu
2023-12-06  5:49 ` [PATCH 09/15] crypto: chacha-generic - Convert from skcipher to lskcipher Herbert Xu
2024-02-14 23:41   ` Eric Biggers
2024-02-15  6:52     ` Herbert Xu
2023-12-06  6:05 ` [PATCH 10/15] crypto: skcipher - Move nesting check into ecb Herbert Xu
2023-12-06  8:55 ` [PATCH 11/15] crypto: skcipher - Propagate zero-length requests to lskcipher Herbert Xu
2023-12-07 10:03 ` [PATCH 03/15] crypto: skcipher - Remove ivsize check for lskcipher simple templates Herbert Xu
2023-12-07 10:13 ` [PATCH 12/15] crypto: cts - Convert from skcipher to lskcipher Herbert Xu
2023-12-29 10:47 ` [PATCH 13/15] crypto: cts,xts - Update parameters blocksize/chunksize/tailsize Herbert Xu
2024-02-14 23:00   ` Eric Biggers
2024-02-15  7:57     ` Herbert Xu
2024-02-23  6:09       ` Eric Biggers
2023-12-30  7:16 ` [PATCH 14/15] crypto: lskcipher - Export incremental interface internally Herbert Xu
2024-02-13  8:48 ` [PATCH 15/15] crypto: adiantum - Convert from skcipher to lskcipher Herbert Xu
2024-02-14 23:35 ` [PATCH 00/15] crypto: Add twopass lskcipher for adiantum Eric Biggers
2024-02-15  8:20   ` Herbert Xu
2024-02-23  6:39     ` Eric Biggers

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=3ec460107b256268dd00069fff7d92bcc975259e.1707815065.git.herbert@gondor.apana.org.au \
    --to=herbert@gondor.apana.org.au \
    --cc=linux-crypto@vger.kernel.org \
    /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.