Linux cryptographic layer development
 help / color / mirror / Atom feed
* [PATCH v3 00/19] crypto: talitos - Driver cleanup
@ 2026-07-21 13:40 Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 01/19] crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API Paul Louvel
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

The Freescale Integrated Security Engine (SEC) aka "Talitos" driver
implementation is a monolithic ~3800-line file that mixes SEC1 and SEC2
hardware variants with hash, skcipher, aead and hwrng algorithm.

This series reorganises the driver to improve readability and
maintainability:

- Split the driver into a dedicated directory with separate files for
  hash, skcipher, aead, and hwrng implementations.

- Modernise the crypto API usage: adopt {init,exit}_tfm (deprecated
  cra_init/cra_exit), use CRYPTO_AHASH_ALG_BLOCK_ONLY to eliminate
  manual partial-block buffering, and use macros to deduplicate
  algorithm definitions.

- Introduce a is_sec1() helper to get rid of is_sec1 variables /
  parameters.

- Define descriptor/pointer structures for each hardware version,
  instead of using a single structure and anonymous union.

No functional changes are intended except for patch 1.

This series depends on the "crypto: talitos - bug fixes" series :
https://patch.msgid.link/20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
Changes in v3:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v2: https://patch.msgid.link/20260611-7-1-rc1_talitos_cleanup-v2-0-aa4a813ce69b@bootlin.com

Changes in v2:
- Fixed compilation warnings and errors.
- Instead of using ops to dispatch SEC1/SEC2 variants, keep the small
  helpers, and introduce is_sec1() inline function that can use static
  key branching in case both hardware version are compiled.
- Dropped the SEC1/SEC2 function variants inside the core driver file.
- Reworded the cover letter for clarity.
- Link to v1: https://patch.msgid.link/20260528-7-1-rc1_talitos_cleanup-v1-0-cb1ad6cdea49@bootlin.com

To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
Cc: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Paul Louvel (19):
      crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API
      crypto: talitos - Move driver into dedicated directory
      crypto: talitos - Add missing includes to driver header file
      crypto: talitos/hwrng - Move into separate file
      crypto: talitos - Prepare crypto implementation file splitting
      crypto: talitos/hash - Move into separate file
      crypto: talitos/skcipher - Move into separate file
      crypto: talitos/aead - Move into separate file
      crypto: talitos/hash - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/skcipher - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/aead - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/hash - Use macro for algorithm definitions
      crypto: talitos/skcipher - Use macro for algorithm definitions
      crypto: talitos/aead - Use macro for algorithm definitions
      crypto: talitos - Remove alg settings in talitos_register_common()
      crypto: talitos - Introduce is_sec1() helper with static key support
      crypto: talitos - Replace has_ftr_sec1() with is_sec1() static key helper
      crypto: talitos - Introduce per-SEC-version descriptor and pointer structures
      crypto: talitos - Remove TALITOS_DESC_SIZE macro

 drivers/crypto/Kconfig                    |   38 +-
 drivers/crypto/Makefile                   |    2 +-
 drivers/crypto/talitos.c                  | 3640 -----------------------------
 drivers/crypto/talitos/Kconfig            |   36 +
 drivers/crypto/talitos/Makefile           |    3 +
 drivers/crypto/talitos/talitos-aead.c     |  657 ++++++
 drivers/crypto/talitos/talitos-hash.c     |  695 ++++++
 drivers/crypto/talitos/talitos-rng.c      |   93 +
 drivers/crypto/talitos/talitos-skcipher.c |  356 +++
 drivers/crypto/talitos/talitos.c          | 1337 +++++++++++
 drivers/crypto/{ => talitos}/talitos.h    |  316 ++-
 11 files changed, 3467 insertions(+), 3706 deletions(-)
---
base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
change-id: 20260518-7-1-rc1_talitos_cleanup-9231a64e29fa
prerequisite-change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc:v3
prerequisite-patch-id: 7b364911e4b8d1c1033eb14e67ed24dac6a4bc13
prerequisite-patch-id: 2c1cd7fdd003d9a116a697efa25d1716d548389f
prerequisite-patch-id: b12bdbf565747609e0cfe0609a42cf69b5d816a1
prerequisite-patch-id: 72cb2bc0fc2a48a5a029b049c199f4c86085cf04
prerequisite-patch-id: 5f1f5ad6add760161bd48875df48c0893aa12613
prerequisite-patch-id: 934931086968229434d15a2f2358aeb7e6975a1d
prerequisite-patch-id: 8a0b4828fc0690e0c841bc9adcc6568bb522e0e8
prerequisite-patch-id: 1d870f32e7dbf9a8bd3b8979558544107693e0f4
prerequisite-patch-id: 758c18d7c9fabb14bd90df62e5e8a62a6f880db4
prerequisite-patch-id: ce6e9e585f8edc1861ae6bb8fbdd836c20cbd290
prerequisite-patch-id: 9446dc03e442ea81c5f5b39e802e01b37da29971

Best regards,
--  
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 01/19] crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 02/19] crypto: talitos - Move driver into dedicated directory Paul Louvel
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

The hash implementation maintained a software buffer to accumulate
partial blocks across update() calls, copying data to/from scatterlists
with sg_copy_to_buffer()/sg_pcopy_to_buffer() and chaining in a virtual
scatterlist entry.  This is unnecessary now with
CRYPTO_AHASH_ALG_BLOCK_ONLY flag.

Remove unnecessary fields in the request and export structure. On
completion, pass any remaining tail bytes back via
ahash_request_complete() so that the core re-submits them with the next
request.

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos.c | 168 +++++++++++++++++------------------------------
 1 file changed, 62 insertions(+), 106 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 584508963241..99853faf20e8 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -935,31 +935,26 @@ struct talitos_ctx {
 	unsigned int authkeylen;
 };
 
-#define HASH_MAX_BLOCK_SIZE		SHA512_BLOCK_SIZE
 #define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
 
 struct talitos_ahash_req_ctx {
 	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
+	u8 padding_buf[64];
+	u64 message_size;
 	unsigned int hw_context_size;
-	u8 buf[2][HASH_MAX_BLOCK_SIZE];
-	int buf_idx;
 	unsigned int swinit;
 	unsigned int first_request;
 	unsigned int last_request;
 	unsigned int to_hash_later;
-	unsigned int nbuf;
-	struct scatterlist bufsl[2];
-	struct scatterlist *psrc;
 };
 
 struct talitos_export_state {
 	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
-	u8 buf[HASH_MAX_BLOCK_SIZE];
+	u64 message_size;
 	unsigned int swinit;
 	unsigned int first_request;
 	unsigned int last_request;
 	unsigned int to_hash_later;
-	unsigned int nbuf;
 };
 
 static int aead_setkey(struct crypto_aead *authenc,
@@ -1826,14 +1821,8 @@ static void ahash_done(struct device *dev,
 	struct talitos_edesc *next;
 
 	if (is_sec1) {
-		if (!req_ctx->last_request && req_ctx->to_hash_later) {
-			/* Position any partial block for next update/final/finup */
-			req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
-			req_ctx->nbuf = req_ctx->to_hash_later;
-		}
-
 		free_edesc_list_from(areq, edesc);
-		ahash_request_complete(areq, err);
+		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
 	} else {
 		next = edesc->next_desc;
 
@@ -1851,14 +1840,9 @@ static void ahash_done(struct device *dev,
 			return;
 		}
 out:
-		if (!req_ctx->last_request && req_ctx->to_hash_later) {
-			/* Position any partial block for next update/final/finup */
-			req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
-			req_ctx->nbuf = req_ctx->to_hash_later;
-		}
 		if (err && next)
 			free_edesc_list_from(areq, next);
-		ahash_request_complete(areq, err);
+		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
 	}
 }
 
@@ -1866,21 +1850,21 @@ static void ahash_done(struct device *dev,
  * SEC1 doesn't like hashing of 0 sized message, so we do the padding
  * ourself and submit a padded block
  */
-static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
-			       struct talitos_edesc *edesc,
-			       struct talitos_ptr *ptr)
+static void talitos_handle_buggy_hash(struct talitos_ahash_req_ctx *req_ctx,
+				      struct talitos_ctx *ctx,
+				      struct talitos_edesc *edesc,
+				      struct talitos_ptr *ptr)
 {
-	static u8 padded_hash[64] = {
-		0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	};
+	__be64 len = cpu_to_be64(req_ctx->message_size << 3);
+
+	memset(req_ctx->padding_buf, 0, sizeof(req_ctx->padding_buf));
+	req_ctx->padding_buf[0] = 0x80;
+	memcpy(&req_ctx->padding_buf[56], &len, sizeof(len));
 
 	pr_err_once("Bug in SEC1, padding ourself\n");
 	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
-	map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
-			       (char *)padded_hash, DMA_TO_DEVICE);
+	map_single_talitos_ptr(ctx->dev, ptr, sizeof(req_ctx->padding_buf),
+			       (char *)req_ctx->padding_buf, DMA_TO_DEVICE);
 }
 
 static void common_nonsnoop_hash(struct talitos_edesc *edesc,
@@ -1945,7 +1929,7 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
 	/* last DWORD empty */
 
 	if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
-		talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
+		talitos_handle_buggy_hash(req_ctx, ctx, edesc, &desc->ptr[3]);
 
 	if (sync_needed)
 		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
@@ -1978,7 +1962,7 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
 	size_t offset = 0;
 
 	do {
-		src = scatterwalk_ffwd(tmp, req_ctx->psrc, offset);
+		src = scatterwalk_ffwd(tmp, areq->src, offset);
 
 		to_hash_this_desc =
 			min(nbytes, ALIGN_DOWN(desc_max, blocksize));
@@ -1991,8 +1975,7 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
 			return edesc;
 		}
 
-		edesc->src =
-			scatterwalk_ffwd(edesc->bufsl, req_ctx->psrc, offset);
+		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
 		edesc->desc.hdr = ctx->desc_hdr_template;
 		edesc->first = offset == 0;
 		edesc->last = nbytes - to_hash_this_desc == 0;
@@ -2045,62 +2028,17 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
 	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
 	unsigned int nbytes_to_hash;
 	unsigned int to_hash_later;
-	unsigned int nsg;
-	int nents;
 	struct device *dev = ctx->dev;
-	u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
 	int ret;
 
-	if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <= blocksize)) {
-		/* Buffer up to one whole block */
-		nents = sg_nents_for_len(areq->src, nbytes);
-		if (nents < 0) {
-			dev_err(dev, "Invalid number of src SG.\n");
-			return nents;
-		}
-		sg_copy_to_buffer(areq->src, nents,
-				  ctx_buf + req_ctx->nbuf, nbytes);
-		req_ctx->nbuf += nbytes;
-		return 0;
-	}
-
-	/* At least (blocksize + 1) bytes are available to hash */
-	nbytes_to_hash = nbytes + req_ctx->nbuf;
-	to_hash_later = nbytes_to_hash & (blocksize - 1);
+	nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
+	to_hash_later = nbytes - nbytes_to_hash;
 
-	if (req_ctx->last_request)
+	if (req_ctx->last_request) {
+		nbytes_to_hash = nbytes;
 		to_hash_later = 0;
-	else if (to_hash_later)
-		/* There is a partial block. Hash the full block(s) now */
-		nbytes_to_hash -= to_hash_later;
-	else {
-		/* Keep one block buffered */
-		nbytes_to_hash -= blocksize;
-		to_hash_later = blocksize;
-	}
-
-	/* Chain in any previously buffered data */
-	if (req_ctx->nbuf) {
-		nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
-		sg_init_table(req_ctx->bufsl, nsg);
-		sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
-		if (nsg > 1)
-			sg_chain(req_ctx->bufsl, 2, areq->src);
-		req_ctx->psrc = req_ctx->bufsl;
-	} else
-		req_ctx->psrc = areq->src;
-
-	if (to_hash_later) {
-		nents = sg_nents_for_len(areq->src, nbytes);
-		if (nents < 0) {
-			dev_err(dev, "Invalid number of src SG.\n");
-			return nents;
-		}
-		sg_pcopy_to_buffer(areq->src, nents,
-				   req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
-				      to_hash_later,
-				      nbytes - to_hash_later);
 	}
+
 	req_ctx->to_hash_later = to_hash_later;
 
 	edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
@@ -2125,8 +2063,6 @@ static int ahash_init(struct ahash_request *areq)
 	dma_addr_t dma;
 
 	/* Initialize the context */
-	req_ctx->buf_idx = 0;
-	req_ctx->nbuf = 0;
 	req_ctx->first_request = 1;
 	req_ctx->swinit = 0; /* assume h/w init of context */
 	size =	(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
@@ -2223,12 +2159,11 @@ static int ahash_export(struct ahash_request *areq, void *out)
 
 	memcpy(export->hw_context, req_ctx->hw_context,
 	       req_ctx->hw_context_size);
-	memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
 	export->swinit = req_ctx->swinit;
 	export->first_request = req_ctx->first_request;
 	export->last_request = req_ctx->last_request;
 	export->to_hash_later = req_ctx->to_hash_later;
-	export->nbuf = req_ctx->nbuf;
+	export->message_size = req_ctx->message_size;
 
 	return 0;
 }
@@ -2249,12 +2184,11 @@ static int ahash_import(struct ahash_request *areq, const void *in)
 			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
 	req_ctx->hw_context_size = size;
 	memcpy(req_ctx->hw_context, export->hw_context, size);
-	memcpy(req_ctx->buf[0], export->buf, export->nbuf);
 	req_ctx->swinit = export->swinit;
 	req_ctx->first_request = export->first_request;
 	req_ctx->last_request = export->last_request;
 	req_ctx->to_hash_later = export->to_hash_later;
-	req_ctx->nbuf = export->nbuf;
+	req_ctx->message_size = export->message_size;
 
 	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
 			     DMA_TO_DEVICE);
@@ -2932,8 +2866,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "md5",
 				.cra_driver_name = "md5-talitos",
 				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2948,8 +2884,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "sha1",
 				.cra_driver_name = "sha1-talitos",
 				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2964,8 +2902,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "sha224",
 				.cra_driver_name = "sha224-talitos",
 				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2980,8 +2920,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "sha256",
 				.cra_driver_name = "sha256-talitos",
 				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2996,8 +2938,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "sha384",
 				.cra_driver_name = "sha384-talitos",
 				.cra_blocksize = SHA384_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3012,8 +2956,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "sha512",
 				.cra_driver_name = "sha512-talitos",
 				.cra_blocksize = SHA512_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3028,8 +2974,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(md5)",
 				.cra_driver_name = "hmac-md5-talitos",
 				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3044,8 +2992,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(sha1)",
 				.cra_driver_name = "hmac-sha1-talitos",
 				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3060,8 +3010,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(sha224)",
 				.cra_driver_name = "hmac-sha224-talitos",
 				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3076,8 +3028,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(sha256)",
 				.cra_driver_name = "hmac-sha256-talitos",
 				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3092,8 +3046,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(sha384)",
 				.cra_driver_name = "hmac-sha384-talitos",
 				.cra_blocksize = SHA384_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3108,8 +3064,10 @@ static struct talitos_alg_template driver_algs[] = {
 				.cra_name = "hmac(sha512)",
 				.cra_driver_name = "hmac-sha512-talitos",
 				.cra_blocksize = SHA512_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
 				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY,
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
 			}
 		},
 		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -3181,8 +3139,6 @@ static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
 				   algt.alg.hash);
 
 	ctx->keylen = 0;
-	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
-				 sizeof(struct talitos_ahash_req_ctx));
 
 	return talitos_init_common(ctx, talitos_alg);
 }

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 02/19] crypto: talitos - Move driver into dedicated directory
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 01/19] crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 03/19] crypto: talitos - Add missing includes to driver header file Paul Louvel
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Move the talitos driver files from drivers/crypto/ into
drivers/crypto/talitos/ to accommodate upcoming code
reorganization.

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/Kconfig                 | 38 +---------------------------------
 drivers/crypto/Makefile                |  2 +-
 drivers/crypto/talitos/Kconfig         | 36 ++++++++++++++++++++++++++++++++
 drivers/crypto/talitos/Makefile        |  1 +
 drivers/crypto/{ => talitos}/talitos.c |  0
 drivers/crypto/{ => talitos}/talitos.h |  0
 6 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index d23b58b81ca3..783b5dc42a42 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -253,43 +253,7 @@ config CRYPTO_DEV_HIFN_795X_RNG
 	  on the HIFN 795x crypto adapters.
 
 source "drivers/crypto/caam/Kconfig"
-
-config CRYPTO_DEV_TALITOS
-	tristate "Talitos Freescale Security Engine (SEC)"
-	select CRYPTO_AEAD
-	select CRYPTO_AUTHENC
-	select CRYPTO_SKCIPHER
-	select CRYPTO_HASH
-	select CRYPTO_LIB_DES
-	select HW_RANDOM
-	depends on FSL_SOC
-	help
-	  Say 'Y' here to use the Freescale Security Engine (SEC)
-	  to offload cryptographic algorithm computation.
-
-	  The Freescale SEC is present on PowerQUICC 'E' processors, such
-	  as the MPC8349E and MPC8548E.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called talitos.
-
-config CRYPTO_DEV_TALITOS1
-	bool "SEC1 (SEC 1.0 and SEC Lite 1.2)"
-	depends on CRYPTO_DEV_TALITOS
-	depends on PPC_8xx || PPC_82xx
-	default y
-	help
-	  Say 'Y' here to use the Freescale Security Engine (SEC) version 1.0
-	  found on MPC82xx or the Freescale Security Engine (SEC Lite)
-	  version 1.2 found on MPC8xx
-
-config CRYPTO_DEV_TALITOS2
-	bool "SEC2+ (SEC version 2.0 or upper)"
-	depends on CRYPTO_DEV_TALITOS
-	default y if !PPC_8xx
-	help
-	  Say 'Y' here to use the Freescale Security Engine (SEC)
-	  version 2 and following as found on MPC83xx, MPC85xx, etc ...
+source "drivers/crypto/talitos/Kconfig"
 
 config CRYPTO_DEV_PPC4XX
 	tristate "Driver AMCC PPC4xx crypto accelerator"
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 283bbc650b5b..a059139d4a75 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_CRYPTO_DEV_SA2UL) += sa2ul.o
 obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
 obj-$(CONFIG_CRYPTO_DEV_SL3516) += gemini/
 obj-y += stm32/
-obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
+obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos/
 obj-$(CONFIG_CRYPTO_DEV_TEGRA) += tegra/
 obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio/
 obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
diff --git a/drivers/crypto/talitos/Kconfig b/drivers/crypto/talitos/Kconfig
new file mode 100644
index 000000000000..c3470553a966
--- /dev/null
+++ b/drivers/crypto/talitos/Kconfig
@@ -0,0 +1,36 @@
+config CRYPTO_DEV_TALITOS
+	tristate "Talitos Freescale Security Engine (SEC)"
+	select CRYPTO_AEAD
+	select CRYPTO_AUTHENC
+	select CRYPTO_SKCIPHER
+	select CRYPTO_HASH
+	select CRYPTO_LIB_DES
+	select HW_RANDOM
+	depends on FSL_SOC
+	help
+	  Say 'Y' here to use the Freescale Security Engine (SEC)
+	  to offload cryptographic algorithm computation.
+
+	  The Freescale SEC is present on PowerQUICC 'E' processors, such
+	  as the MPC8349E and MPC8548E.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called talitos.
+
+config CRYPTO_DEV_TALITOS1
+	bool "SEC1 (SEC 1.0 and SEC Lite 1.2)"
+	depends on CRYPTO_DEV_TALITOS
+	depends on PPC_8xx || PPC_82xx
+	default y
+	help
+	  Say 'Y' here to use the Freescale Security Engine (SEC) version 1.0
+	  found on MPC82xx or the Freescale Security Engine (SEC Lite)
+	  version 1.2 found on MPC8xx
+
+config CRYPTO_DEV_TALITOS2
+	bool "SEC2+ (SEC version 2.0 or upper)"
+	depends on CRYPTO_DEV_TALITOS
+	default y if !PPC_8xx
+	help
+	  Say 'Y' here to use the Freescale Security Engine (SEC)
+	  version 2 and following as found on MPC83xx, MPC85xx, etc ...
diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
new file mode 100644
index 000000000000..fcc5db5e63c2
--- /dev/null
+++ b/drivers/crypto/talitos/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos/talitos.c
similarity index 100%
rename from drivers/crypto/talitos.c
rename to drivers/crypto/talitos/talitos.c
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos/talitos.h
similarity index 100%
rename from drivers/crypto/talitos.h
rename to drivers/crypto/talitos/talitos.h

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 03/19] crypto: talitos - Add missing includes to driver header file
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 01/19] crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 02/19] crypto: talitos - Move driver into dedicated directory Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 04/19] crypto: talitos/hwrng - Move into separate file Paul Louvel
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Add explicit includes for types used by the header file to make
it self-contained and fix implicit include dependencies.

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos/talitos.c | 3 ---
 drivers/crypto/talitos/talitos.h | 6 ++++++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
index 99853faf20e8..753481d3189a 100644
--- a/drivers/crypto/talitos/talitos.c
+++ b/drivers/crypto/talitos/talitos.c
@@ -15,10 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
 #include <linux/crypto.h>
-#include <linux/hw_random.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
index d4ff8d589f46..56e36a65ddcc 100644
--- a/drivers/crypto/talitos/talitos.h
+++ b/drivers/crypto/talitos/talitos.h
@@ -5,6 +5,12 @@
  * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
  */
 
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/interrupt.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+
 #define TALITOS_TIMEOUT 100000
 #define TALITOS1_MAX_DATA_LEN 32768
 #define TALITOS2_MAX_DATA_LEN 65535

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 04/19] crypto: talitos/hwrng - Move into separate file
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
                   ` (2 preceding siblings ...)
  2026-07-21 13:40 ` [PATCH v3 03/19] crypto: talitos - Add missing includes to driver header file Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 05/19] crypto: talitos - Prepare crypto implementation file splitting Paul Louvel
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Move the hardware random number generator implementation from
talitos.c into a dedicated talitos-rng.c file.

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos/Makefile      |  2 +
 drivers/crypto/talitos/talitos-rng.c | 93 ++++++++++++++++++++++++++++++++++++
 drivers/crypto/talitos/talitos.c     | 83 --------------------------------
 drivers/crypto/talitos/talitos.h     |  5 ++
 4 files changed, 100 insertions(+), 83 deletions(-)

diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
index fcc5db5e63c2..901ec681f010 100644
--- a/drivers/crypto/talitos/Makefile
+++ b/drivers/crypto/talitos/Makefile
@@ -1 +1,3 @@
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
+
+talitos-y := talitos.o talitos-rng.o
diff --git a/drivers/crypto/talitos/talitos-rng.c b/drivers/crypto/talitos/talitos-rng.c
new file mode 100644
index 000000000000..3aa00de33b25
--- /dev/null
+++ b/drivers/crypto/talitos/talitos-rng.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Freescale SEC (talitos) device hardware random number generator implementation
+ *
+ * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "talitos.h"
+
+static int talitos_rng_data_present(struct hwrng *rng, int wait)
+{
+	struct device *dev = (struct device *)rng->priv;
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	u32 ofl;
+	int i;
+
+	for (i = 0; i < 20; i++) {
+		ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
+		      TALITOS_RNGUSR_LO_OFL;
+		if (ofl || !wait)
+			break;
+		udelay(10);
+	}
+
+	return !!ofl;
+}
+
+static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	struct device *dev = (struct device *)rng->priv;
+	struct talitos_private *priv = dev_get_drvdata(dev);
+
+	/* rng fifo requires 64-bit accesses */
+	*data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
+	*data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
+
+	return sizeof(u32);
+}
+
+static int talitos_rng_init(struct hwrng *rng)
+{
+	struct device *dev = (struct device *)rng->priv;
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	unsigned int timeout = TALITOS_TIMEOUT;
+
+	setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
+	while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
+		 & TALITOS_RNGUSR_LO_RD)
+	       && --timeout)
+		cpu_relax();
+	if (timeout == 0) {
+		dev_err(dev, "failed to reset rng hw\n");
+		return -ENODEV;
+	}
+
+	/* start generating */
+	setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
+
+	return 0;
+}
+
+int talitos_register_rng(struct device *dev)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	int err;
+
+	priv->rng.name		= dev_driver_string(dev);
+	priv->rng.init		= talitos_rng_init;
+	priv->rng.data_present	= talitos_rng_data_present;
+	priv->rng.data_read	= talitos_rng_data_read;
+	priv->rng.priv		= (unsigned long)dev;
+
+	err = hwrng_register(&priv->rng);
+	if (!err)
+		priv->rng_registered = true;
+
+	return err;
+}
+
+void talitos_unregister_rng(struct device *dev)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+
+	if (!priv->rng_registered)
+		return;
+
+	hwrng_unregister(&priv->rng);
+	priv->rng_registered = false;
+}
diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
index 753481d3189a..074f399b6327 100644
--- a/drivers/crypto/talitos/talitos.c
+++ b/drivers/crypto/talitos/talitos.c
@@ -820,89 +820,6 @@ DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
 DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
 		       1)
 
-/*
- * hwrng
- */
-static int talitos_rng_data_present(struct hwrng *rng, int wait)
-{
-	struct device *dev = (struct device *)rng->priv;
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	u32 ofl;
-	int i;
-
-	for (i = 0; i < 20; i++) {
-		ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
-		      TALITOS_RNGUSR_LO_OFL;
-		if (ofl || !wait)
-			break;
-		udelay(10);
-	}
-
-	return !!ofl;
-}
-
-static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
-{
-	struct device *dev = (struct device *)rng->priv;
-	struct talitos_private *priv = dev_get_drvdata(dev);
-
-	/* rng fifo requires 64-bit accesses */
-	*data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
-	*data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
-
-	return sizeof(u32);
-}
-
-static int talitos_rng_init(struct hwrng *rng)
-{
-	struct device *dev = (struct device *)rng->priv;
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	unsigned int timeout = TALITOS_TIMEOUT;
-
-	setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
-	while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
-		 & TALITOS_RNGUSR_LO_RD)
-	       && --timeout)
-		cpu_relax();
-	if (timeout == 0) {
-		dev_err(dev, "failed to reset rng hw\n");
-		return -ENODEV;
-	}
-
-	/* start generating */
-	setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
-
-	return 0;
-}
-
-static int talitos_register_rng(struct device *dev)
-{
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	int err;
-
-	priv->rng.name		= dev_driver_string(dev);
-	priv->rng.init		= talitos_rng_init;
-	priv->rng.data_present	= talitos_rng_data_present;
-	priv->rng.data_read	= talitos_rng_data_read;
-	priv->rng.priv		= (unsigned long)dev;
-
-	err = hwrng_register(&priv->rng);
-	if (!err)
-		priv->rng_registered = true;
-
-	return err;
-}
-
-static void talitos_unregister_rng(struct device *dev)
-{
-	struct talitos_private *priv = dev_get_drvdata(dev);
-
-	if (!priv->rng_registered)
-		return;
-
-	hwrng_unregister(&priv->rng);
-	priv->rng_registered = false;
-}
 
 /*
  * crypto alg
diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
index 56e36a65ddcc..fa8c71b1f90f 100644
--- a/drivers/crypto/talitos/talitos.h
+++ b/drivers/crypto/talitos/talitos.h
@@ -431,3 +431,8 @@ static inline bool has_ftr_sec1(struct talitos_private *priv)
 #define DESC_PTR_LNKTBL_JUMP			0x80
 #define DESC_PTR_LNKTBL_RET			0x02
 #define DESC_PTR_LNKTBL_NEXT			0x01
+
+/* Hardware RNG */
+
+int talitos_register_rng(struct device *dev);
+void talitos_unregister_rng(struct device *dev);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 05/19] crypto: talitos - Prepare crypto implementation file splitting
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
                   ` (3 preceding siblings ...)
  2026-07-21 13:40 ` [PATCH v3 04/19] crypto: talitos/hwrng - Move into separate file Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 06/19] crypto: talitos/hash - Move into separate file Paul Louvel
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Move all talitos helpers and inline them inside the header file.
Remove the static qualifier for the core functions of the driver, they
will be called inside each crypto implementation file.

Add the common structures too.

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos/talitos.c | 182 ++++++---------------------------------
 drivers/crypto/talitos/talitos.h | 167 +++++++++++++++++++++++++++++++++++
 2 files changed, 194 insertions(+), 155 deletions(-)

diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
index 074f399b6327..dc92b98ec5ef 100644
--- a/drivers/crypto/talitos/talitos.c
+++ b/drivers/crypto/talitos/talitos.c
@@ -40,99 +40,6 @@
 
 #include "talitos.h"
 
-static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
-			   unsigned int len, bool is_sec1)
-{
-	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
-	if (is_sec1) {
-		ptr->len1 = cpu_to_be16(len);
-	} else {
-		ptr->len = cpu_to_be16(len);
-		ptr->eptr = upper_32_bits(dma_addr);
-	}
-}
-
-static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
-			     struct talitos_ptr *src_ptr, bool is_sec1)
-{
-	dst_ptr->ptr = src_ptr->ptr;
-	if (is_sec1) {
-		dst_ptr->len1 = src_ptr->len1;
-	} else {
-		dst_ptr->len = src_ptr->len;
-		dst_ptr->eptr = src_ptr->eptr;
-	}
-}
-
-static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
-					   bool is_sec1)
-{
-	if (is_sec1)
-		return be16_to_cpu(ptr->len1);
-	else
-		return be16_to_cpu(ptr->len);
-}
-
-static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
-				   bool is_sec1)
-{
-	if (!is_sec1)
-		ptr->j_extent = val;
-}
-
-static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
-{
-	if (!is_sec1)
-		ptr->j_extent |= val;
-}
-
-/*
- * map virtual single (contiguous) pointer to h/w descriptor pointer
- */
-static void __map_single_talitos_ptr(struct device *dev,
-				     struct talitos_ptr *ptr,
-				     unsigned int len, void *data,
-				     enum dma_data_direction dir,
-				     unsigned long attrs)
-{
-	dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	bool is_sec1 = has_ftr_sec1(priv);
-
-	to_talitos_ptr(ptr, dma_addr, len, is_sec1);
-}
-
-static void map_single_talitos_ptr(struct device *dev,
-				   struct talitos_ptr *ptr,
-				   unsigned int len, void *data,
-				   enum dma_data_direction dir)
-{
-	__map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
-}
-
-static void map_single_talitos_ptr_nosync(struct device *dev,
-					  struct talitos_ptr *ptr,
-					  unsigned int len, void *data,
-					  enum dma_data_direction dir)
-{
-	__map_single_talitos_ptr(dev, ptr, len, data, dir,
-				 DMA_ATTR_SKIP_CPU_SYNC);
-}
-
-/*
- * unmap bus single (contiguous) h/w descriptor pointer
- */
-static void unmap_single_talitos_ptr(struct device *dev,
-				     struct talitos_ptr *ptr,
-				     enum dma_data_direction dir)
-{
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	bool is_sec1 = has_ftr_sec1(priv);
-
-	dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
-			 from_talitos_ptr_len(ptr, is_sec1), dir);
-}
-
 static int reset_channel(struct device *dev, int ch)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
@@ -303,11 +210,11 @@ static void dma_map_request(struct device *dev, struct talitos_request *request,
  * callback must check err and feedback in descriptor header
  * for device processing status.
  */
-static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
-			  void (*callback)(struct device *dev,
-					   struct talitos_desc *desc,
-					   void *context, int error),
-			  void *context)
+int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
+		   void (*callback)(struct device *dev,
+				    struct talitos_desc *desc,
+				    void *context, int error),
+		   void *context)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
 	struct talitos_request *request;
@@ -830,24 +737,6 @@ DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
  * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
  */
 #define TALITOS_CRA_PRIORITY_AEAD_HSNA	(TALITOS_CRA_PRIORITY - 1)
-#ifdef CONFIG_CRYPTO_DEV_TALITOS2
-#define TALITOS_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
-#else
-#define TALITOS_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + SHA256_BLOCK_SIZE)
-#endif
-#define TALITOS_MAX_IV_LENGTH		16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
-
-struct talitos_ctx {
-	struct device *dev;
-	int ch;
-	__be32 desc_hdr_template;
-	u8 key[TALITOS_MAX_KEY_SIZE];
-	u8 iv[TALITOS_MAX_IV_LENGTH];
-	dma_addr_t dma_key;
-	unsigned int keylen;
-	unsigned int enckeylen;
-	unsigned int authkeylen;
-};
 
 #define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
 
@@ -941,7 +830,7 @@ static int aead_des3_setkey(struct crypto_aead *authenc,
 	return err;
 }
 
-static void talitos_sg_unmap(struct device *dev,
+void talitos_sg_unmap(struct device *dev,
 			     struct talitos_edesc *edesc,
 			     struct scatterlist *src,
 			     struct scatterlist *dst,
@@ -1126,7 +1015,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
 	return count;
 }
 
-static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
+int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
 			      unsigned int len, struct talitos_edesc *edesc,
 			      struct talitos_ptr *ptr, int sg_count,
 			      unsigned int offset, int tbl_off, int elen,
@@ -1163,7 +1052,7 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
 	return sg_count;
 }
 
-static int talitos_sg_map(struct device *dev, struct scatterlist *src,
+int talitos_sg_map(struct device *dev, struct scatterlist *src,
 			  unsigned int len, struct talitos_edesc *edesc,
 			  struct talitos_ptr *ptr, int sg_count,
 			  unsigned int offset, int tbl_off)
@@ -1301,17 +1190,17 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 /*
  * allocate and map the extended descriptor
  */
-static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
-						 struct scatterlist *src,
-						 struct scatterlist *dst,
-						 u8 *iv,
-						 unsigned int assoclen,
-						 unsigned int cryptlen,
-						 unsigned int authsize,
-						 unsigned int ivsize,
-						 int icv_stashing,
-						 u32 cryptoflags,
-						 bool encrypt)
+struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
+					  struct scatterlist *src,
+					  struct scatterlist *dst,
+					  u8 *iv,
+					  unsigned int assoclen,
+					  unsigned int cryptlen,
+					  unsigned int authsize,
+					  unsigned int ivsize,
+					  int icv_stashing,
+					  u32 cryptoflags,
+					  bool encrypt)
 {
 	struct talitos_edesc *edesc;
 	int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
@@ -2176,18 +2065,6 @@ static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
 	return 0;
 }
 
-
-struct talitos_alg_template {
-	u32 type;
-	u32 priority;
-	union {
-		struct skcipher_alg skcipher;
-		struct ahash_alg hash;
-		struct aead_alg aead;
-	} alg;
-	__be32 desc_hdr_template;
-};
-
 static struct talitos_alg_template driver_algs[] = {
 	/* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
 	{	.type = CRYPTO_ALG_TYPE_AEAD,
@@ -2990,14 +2867,8 @@ static struct talitos_alg_template driver_algs[] = {
 	}
 };
 
-struct talitos_crypto_alg {
-	struct list_head entry;
-	struct device *dev;
-	struct talitos_alg_template algt;
-};
-
-static int talitos_init_common(struct talitos_ctx *ctx,
-			       struct talitos_crypto_alg *talitos_alg)
+int talitos_init_common(struct talitos_ctx *ctx,
+			struct talitos_crypto_alg *talitos_alg)
 {
 	struct talitos_private *priv;
 
@@ -3057,7 +2928,7 @@ static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
 	return talitos_init_common(ctx, talitos_alg);
 }
 
-static void talitos_cra_exit(struct crypto_tfm *tfm)
+void talitos_cra_exit(struct crypto_tfm *tfm)
 {
 	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
 	struct device *dev = ctx->dev;
@@ -3071,7 +2942,7 @@ static void talitos_cra_exit(struct crypto_tfm *tfm)
  * type and primary/secondary execution units required match the hw
  * capabilities description provided in the device tree node.
  */
-static int hw_supports(struct device *dev, __be32 desc_hdr_template)
+int talitos_hw_supports(struct device *dev, __be32 desc_hdr_template)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
 	int ret;
@@ -3108,7 +2979,7 @@ static void talitos_remove(struct platform_device *ofdev)
 		list_del(&t_alg->entry);
 	}
 
-	if (hw_supports(dev, DESC_HDR_SEL0_RNG))
+	if (talitos_hw_supports(dev, DESC_HDR_SEL0_RNG))
 		talitos_unregister_rng(dev);
 
 	for (i = 0; i < 2; i++)
@@ -3417,7 +3288,7 @@ static int talitos_probe(struct platform_device *ofdev)
 	}
 
 	/* register the RNG, if available */
-	if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
+	if (talitos_hw_supports(dev, DESC_HDR_SEL0_RNG)) {
 		err = talitos_register_rng(dev);
 		if (err) {
 			dev_err(dev, "failed to register hwrng: %d\n", err);
@@ -3428,7 +3299,8 @@ static int talitos_probe(struct platform_device *ofdev)
 
 	/* register crypto algorithms the device supports */
 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
-		if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
+		if (talitos_hw_supports(dev,
+					driver_algs[i].desc_hdr_template)) {
 			struct talitos_crypto_alg *t_alg;
 			struct crypto_alg *alg = NULL;
 
diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
index fa8c71b1f90f..81331914801b 100644
--- a/drivers/crypto/talitos/talitos.h
+++ b/drivers/crypto/talitos/talitos.h
@@ -5,7 +5,13 @@
  * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
  */
 
+#include <crypto/aes.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/sha2.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
 #include <linux/hw_random.h>
 #include <linux/interrupt.h>
 #include <linux/scatterlist.h>
@@ -19,6 +25,13 @@
 #define PRIMARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 28) & 0xf)
 #define SECONDARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 16) & 0xf)
 
+#ifdef CONFIG_CRYPTO_DEV_TALITOS2
+#define TALITOS_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
+#else
+#define TALITOS_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + SHA256_BLOCK_SIZE)
+#endif
+#define TALITOS_MAX_IV_LENGTH		16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
+
 /* descriptor pointer entry */
 struct talitos_ptr {
 	union {
@@ -174,6 +187,35 @@ struct talitos_private {
 
 };
 
+struct talitos_ctx {
+	struct device *dev;
+	int ch;
+	__be32 desc_hdr_template;
+	u8 key[TALITOS_MAX_KEY_SIZE];
+	u8 iv[TALITOS_MAX_IV_LENGTH];
+	dma_addr_t dma_key;
+	unsigned int keylen;
+	unsigned int enckeylen;
+	unsigned int authkeylen;
+};
+
+struct talitos_alg_template {
+	u32 type;
+	u32 priority;
+	union {
+		struct skcipher_alg skcipher;
+		struct ahash_alg hash;
+		struct aead_alg aead;
+	} alg;
+	__be32 desc_hdr_template;
+};
+
+struct talitos_crypto_alg {
+	struct list_head entry;
+	struct device *dev;
+	struct talitos_alg_template algt;
+};
+
 /* .features flag */
 #define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
 #define TALITOS_FTR_HW_AUTH_CHECK 0x00000002
@@ -432,6 +474,131 @@ static inline bool has_ftr_sec1(struct talitos_private *priv)
 #define DESC_PTR_LNKTBL_RET			0x02
 #define DESC_PTR_LNKTBL_NEXT			0x01
 
+static inline void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
+				  unsigned int len, bool is_sec1)
+{
+	ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
+	if (is_sec1) {
+		ptr->len1 = cpu_to_be16(len);
+	} else {
+		ptr->len = cpu_to_be16(len);
+		ptr->eptr = upper_32_bits(dma_addr);
+	}
+}
+
+static inline void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
+				    struct talitos_ptr *src_ptr, bool is_sec1)
+{
+	dst_ptr->ptr = src_ptr->ptr;
+	if (is_sec1) {
+		dst_ptr->len1 = src_ptr->len1;
+	} else {
+		dst_ptr->len = src_ptr->len;
+		dst_ptr->eptr = src_ptr->eptr;
+	}
+}
+
+static inline unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
+						  bool is_sec1)
+{
+	if (is_sec1)
+		return be16_to_cpu(ptr->len1);
+	else
+		return be16_to_cpu(ptr->len);
+}
+
+static inline void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
+					  bool is_sec1)
+{
+	if (!is_sec1)
+		ptr->j_extent = val;
+}
+
+static inline void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val,
+					 bool is_sec1)
+{
+	if (!is_sec1)
+		ptr->j_extent |= val;
+}
+
+/*
+ * map virtual single (contiguous) pointer to h/w descriptor pointer
+ */
+static void __map_single_talitos_ptr(struct device *dev,
+				     struct talitos_ptr *ptr, unsigned int len,
+				     void *data, enum dma_data_direction dir,
+				     unsigned long attrs)
+{
+	dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	bool is_sec1 = has_ftr_sec1(priv);
+
+	to_talitos_ptr(ptr, dma_addr, len, is_sec1);
+}
+
+static inline void map_single_talitos_ptr(struct device *dev,
+					  struct talitos_ptr *ptr,
+					  unsigned int len, void *data,
+					  enum dma_data_direction dir)
+{
+	__map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
+}
+
+static inline void map_single_talitos_ptr_nosync(struct device *dev,
+						 struct talitos_ptr *ptr,
+						 unsigned int len, void *data,
+						 enum dma_data_direction dir)
+{
+	__map_single_talitos_ptr(dev, ptr, len, data, dir,
+				 DMA_ATTR_SKIP_CPU_SYNC);
+}
+
+/*
+ * unmap bus single (contiguous) h/w descriptor pointer
+ */
+static inline void unmap_single_talitos_ptr(struct device *dev,
+					    struct talitos_ptr *ptr,
+					    enum dma_data_direction dir)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	bool is_sec1 = has_ftr_sec1(priv);
+
+	dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
+			 from_talitos_ptr_len(ptr, is_sec1), dir);
+}
+
+int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
+		   void (*callback)(struct device *dev,
+				    struct talitos_desc *desc, void *context,
+				    int error),
+		   void *context);
+
+void talitos_sg_unmap(struct device *dev, struct talitos_edesc *edesc,
+		      struct scatterlist *src, struct scatterlist *dst,
+		      unsigned int len, unsigned int offset);
+int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
+		       unsigned int len, struct talitos_edesc *edesc,
+		       struct talitos_ptr *ptr, int sg_count,
+		       unsigned int offset, int tbl_off, int elen, bool force,
+		       int align);
+int talitos_sg_map(struct device *dev, struct scatterlist *src,
+		   unsigned int len, struct talitos_edesc *edesc,
+		   struct talitos_ptr *ptr, int sg_count, unsigned int offset,
+		   int tbl_off);
+
+struct talitos_edesc *
+talitos_edesc_alloc(struct device *dev, struct scatterlist *src,
+		    struct scatterlist *dst, u8 *iv, unsigned int assoclen,
+		    unsigned int cryptlen, unsigned int authsize,
+		    unsigned int ivsize, int icv_stashing, u32 cryptoflags,
+		    bool encrypt);
+
+int talitos_hw_supports(struct device *dev, __be32 desc_hdr_template);
+
+int talitos_init_common(struct talitos_ctx *ctx,
+			struct talitos_crypto_alg *talitos_alg);
+void talitos_cra_exit(struct crypto_tfm *tfm);
+
 /* Hardware RNG */
 
 int talitos_register_rng(struct device *dev);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 06/19] crypto: talitos/hash - Move into separate file
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
                   ` (4 preceding siblings ...)
  2026-07-21 13:40 ` [PATCH v3 05/19] crypto: talitos - Prepare crypto implementation file splitting Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:40 ` [PATCH v3 07/19] crypto: talitos/skcipher " Paul Louvel
  2026-07-21 13:54 ` [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Move the ahash algorithm implementations from talitos.c into a dedicated
talitos-hash.c file.

Add a helper that will be called in each crypto implementation file for
registration.

Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos/Makefile       |   2 +-
 drivers/crypto/talitos/talitos-hash.c | 823 ++++++++++++++++++++++++++++++++
 drivers/crypto/talitos/talitos.c      | 851 +++-------------------------------
 drivers/crypto/talitos/talitos.h      |   7 +
 4 files changed, 894 insertions(+), 789 deletions(-)

diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
index 901ec681f010..40d37f9364ef 100644
--- a/drivers/crypto/talitos/Makefile
+++ b/drivers/crypto/talitos/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 
-talitos-y := talitos.o talitos-rng.o
+talitos-y := talitos.o talitos-rng.o talitos-hash.o
diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
new file mode 100644
index 000000000000..bce9f9901ce8
--- /dev/null
+++ b/drivers/crypto/talitos/talitos-hash.c
@@ -0,0 +1,823 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Freescale SEC (talitos) hash implementation
+ *
+ * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
+ */
+
+#include <linux/scatterlist.h>
+
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+#include <crypto/md5.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/sha1.h>
+
+#include "talitos.h"
+
+#define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
+
+struct talitos_ahash_req_ctx {
+	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
+	u8 padding_buf[64];
+	u64 message_size;
+	unsigned int hw_context_size;
+	unsigned int swinit;
+	unsigned int first_request;
+	unsigned int last_request;
+	unsigned int to_hash_later;
+};
+
+struct talitos_export_state {
+	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
+	u64 message_size;
+	unsigned int swinit;
+	unsigned int first_request;
+	unsigned int last_request;
+	unsigned int to_hash_later;
+};
+
+static void common_nonsnoop_hash_unmap(struct device *dev,
+				       struct talitos_edesc *edesc,
+				       struct ahash_request *areq)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	bool is_sec1 = has_ftr_sec1(priv);
+	struct talitos_desc *desc = &edesc->desc;
+
+	unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
+
+	if (edesc->last && req_ctx->last_request)
+		memcpy(areq->result, req_ctx->hw_context,
+		       crypto_ahash_digestsize(tfm));
+
+	if (edesc->src)
+		talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
+
+	/* When using hashctx-in, must unmap it. */
+	if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
+		unmap_single_talitos_ptr(dev, &desc->ptr[1],
+					 DMA_TO_DEVICE);
+
+	if (edesc->dma_len)
+		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+				 DMA_BIDIRECTIONAL);
+}
+
+static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
+{
+	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+	struct talitos_edesc *next;
+
+	while (edesc) {
+		next = edesc->next_desc;
+		common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
+		kfree(edesc);
+		edesc = next;
+	}
+}
+
+static void ahash_done(struct device *dev,
+		       struct talitos_desc *desc, void *context,
+		       int err)
+{
+	struct ahash_request *areq = context;
+	struct talitos_edesc *edesc =
+		 container_of(desc, struct talitos_edesc, desc);
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct talitos_edesc *next;
+
+	if (is_sec1) {
+		free_edesc_list_from(areq, edesc);
+		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
+	} else {
+		next = edesc->next_desc;
+
+		common_nonsnoop_hash_unmap(dev, edesc, areq);
+		kfree(edesc);
+
+		if (err)
+			goto out;
+
+		if (next) {
+			err = talitos_submit(dev, ctx->ch, &next->desc,
+					     ahash_done, areq);
+			if (err != -EINPROGRESS)
+				goto out;
+			return;
+		}
+out:
+		if (err && next)
+			free_edesc_list_from(areq, next);
+		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
+	}
+}
+
+/*
+ * SEC1 doesn't like hashing of 0 sized message, so we do the padding
+ * ourself and submit a padded block
+ */
+static void talitos_handle_buggy_hash(struct talitos_ahash_req_ctx *req_ctx,
+				      struct talitos_ctx *ctx,
+				      struct talitos_edesc *edesc,
+				      struct talitos_ptr *ptr)
+{
+	__be64 len = cpu_to_be64(req_ctx->message_size << 3);
+
+	memset(req_ctx->padding_buf, 0, sizeof(req_ctx->padding_buf));
+	req_ctx->padding_buf[0] = 0x80;
+	memcpy(&req_ctx->padding_buf[56], &len, sizeof(len));
+
+	pr_err_once("Bug in SEC1, padding ourself\n");
+	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
+	map_single_talitos_ptr(ctx->dev, ptr, sizeof(req_ctx->padding_buf),
+			       (char *)req_ctx->padding_buf, DMA_TO_DEVICE);
+}
+
+static void common_nonsnoop_hash(struct talitos_edesc *edesc,
+				 struct ahash_request *areq,
+				 unsigned int length)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct device *dev = ctx->dev;
+	struct talitos_desc *desc = &edesc->desc;
+	bool sync_needed = false;
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	bool is_sec1 = has_ftr_sec1(priv);
+	int sg_count;
+
+	/* first DWORD empty */
+
+	/* hash context in */
+	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
+		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
+					      req_ctx->hw_context_size,
+					      req_ctx->hw_context,
+					      DMA_TO_DEVICE);
+		req_ctx->swinit = 0;
+	}
+	/* Indicate next op is not the first. */
+	req_ctx->first_request = 0;
+
+	/* HMAC key */
+	if (ctx->keylen)
+		to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
+			       is_sec1);
+
+	sg_count = edesc->src_nents ?: 1;
+	if (is_sec1 && sg_count > 1)
+		sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
+	else if (length)
+		sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
+
+	/*
+	 * data in
+	 */
+	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
+				  sg_count, 0, 0);
+	if (sg_count > 1)
+		sync_needed = true;
+
+	/* fifth DWORD empty */
+
+	/* hash/HMAC out -or- hash context out */
+	if (edesc->last && req_ctx->last_request)
+		map_single_talitos_ptr(dev, &desc->ptr[5],
+				       crypto_ahash_digestsize(tfm),
+				       req_ctx->hw_context, DMA_FROM_DEVICE);
+	else
+		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
+					      req_ctx->hw_context_size,
+					      req_ctx->hw_context,
+					      DMA_FROM_DEVICE);
+
+	/* last DWORD empty */
+
+	if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
+		talitos_handle_buggy_hash(req_ctx, ctx, edesc, &desc->ptr[3]);
+
+	if (sync_needed)
+		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+					   edesc->dma_len, DMA_BIDIRECTIONAL);
+}
+
+static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
+					       struct scatterlist *src,
+					       unsigned int nbytes)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+
+	return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
+				   nbytes, 0, 0, 0, areq->base.flags, false);
+}
+
+static struct talitos_edesc *
+ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
+			  unsigned int blocksize, bool is_sec1)
+{
+	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
+	size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
+				    TALITOS2_MAX_DATA_LEN;
+	struct scatterlist tmp[2];
+	size_t to_hash_this_desc;
+	struct scatterlist *src;
+	size_t offset = 0;
+
+	do {
+		src = scatterwalk_ffwd(tmp, areq->src, offset);
+
+		to_hash_this_desc =
+			min(nbytes, ALIGN_DOWN(desc_max, blocksize));
+
+		/* Allocate extended descriptor */
+		edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
+		if (IS_ERR(edesc)) {
+			if (first)
+				free_edesc_list_from(areq, first);
+			return edesc;
+		}
+
+		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
+		edesc->desc.hdr = ctx->desc_hdr_template;
+		edesc->first = offset == 0;
+		edesc->last = nbytes - to_hash_this_desc == 0;
+
+		/* On last one, request SEC to pad; otherwise continue */
+		if (req_ctx->last_request && edesc->last)
+			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
+		else
+			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
+
+		/* request SEC to INIT hash. */
+		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
+			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
+
+		/*
+		 * When the tfm context has a keylen, it's an HMAC.
+		 * A first or last (ie. not middle) descriptor must request HMAC.
+		 */
+		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
+				    (req_ctx->last_request && edesc->last)))
+			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
+
+		/* clear the DN bit  */
+		if (is_sec1 && !edesc->last)
+			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
+
+		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
+
+		offset += to_hash_this_desc;
+		nbytes -= to_hash_this_desc;
+
+		if (!prev_edesc)
+			first = edesc;
+		else
+			prev_edesc->next_desc = edesc;
+		prev_edesc = edesc;
+	} while (nbytes);
+
+	return first;
+}
+
+static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct talitos_edesc *edesc;
+	unsigned int blocksize =
+			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
+	unsigned int nbytes_to_hash;
+	unsigned int to_hash_later;
+	struct device *dev = ctx->dev;
+	int ret;
+
+	nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
+	to_hash_later = nbytes - nbytes_to_hash;
+
+	if (req_ctx->last_request) {
+		nbytes_to_hash = nbytes;
+		to_hash_later = 0;
+	}
+
+	req_ctx->to_hash_later = to_hash_later;
+
+	edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
+					  is_sec1);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
+	if (ret != -EINPROGRESS)
+		free_edesc_list_from(areq, edesc);
+
+	return ret;
+}
+
+static int ahash_init(struct ahash_request *areq)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct device *dev = ctx->dev;
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	unsigned int size;
+	dma_addr_t dma;
+
+	/* Initialize the context */
+	req_ctx->first_request = 1;
+	req_ctx->swinit = 0; /* assume h/w init of context */
+	size =	(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
+			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+	req_ctx->hw_context_size = size;
+	req_ctx->last_request = 0;
+
+	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
+			     DMA_TO_DEVICE);
+	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
+
+	return 0;
+}
+
+/*
+ * on h/w without explicit sha224 support, we initialize h/w context
+ * manually with sha224 constants, and tell it to run sha256.
+ */
+static int ahash_init_sha224_swinit(struct ahash_request *areq)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+
+	req_ctx->hw_context[0] = SHA224_H0;
+	req_ctx->hw_context[1] = SHA224_H1;
+	req_ctx->hw_context[2] = SHA224_H2;
+	req_ctx->hw_context[3] = SHA224_H3;
+	req_ctx->hw_context[4] = SHA224_H4;
+	req_ctx->hw_context[5] = SHA224_H5;
+	req_ctx->hw_context[6] = SHA224_H6;
+	req_ctx->hw_context[7] = SHA224_H7;
+
+	/* init 64-bit count */
+	req_ctx->hw_context[8] = 0;
+	req_ctx->hw_context[9] = 0;
+
+	ahash_init(areq);
+	req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
+
+	return 0;
+}
+
+static int ahash_update(struct ahash_request *areq)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+
+	req_ctx->last_request = 0;
+
+	return ahash_process_req(areq, areq->nbytes);
+}
+
+static int ahash_final(struct ahash_request *areq)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+
+	req_ctx->last_request = 1;
+
+	return ahash_process_req(areq, 0);
+}
+
+static int ahash_finup(struct ahash_request *areq)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+
+	req_ctx->last_request = 1;
+
+	return ahash_process_req(areq, areq->nbytes);
+}
+
+static int ahash_digest(struct ahash_request *areq)
+{
+	ahash_init(areq);
+	return ahash_finup(areq);
+}
+
+static int ahash_digest_sha224_swinit(struct ahash_request *areq)
+{
+	ahash_init_sha224_swinit(areq);
+	return ahash_finup(areq);
+}
+
+static int ahash_export(struct ahash_request *areq, void *out)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct talitos_export_state *export = out;
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct device *dev = ctx->dev;
+	dma_addr_t dma;
+
+	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
+			     DMA_FROM_DEVICE);
+	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
+
+	memcpy(export->hw_context, req_ctx->hw_context,
+	       req_ctx->hw_context_size);
+	export->swinit = req_ctx->swinit;
+	export->first_request = req_ctx->first_request;
+	export->last_request = req_ctx->last_request;
+	export->to_hash_later = req_ctx->to_hash_later;
+	export->message_size = req_ctx->message_size;
+
+	return 0;
+}
+
+static int ahash_import(struct ahash_request *areq, const void *in)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct device *dev = ctx->dev;
+	const struct talitos_export_state *export = in;
+	unsigned int size;
+	dma_addr_t dma;
+
+	memset(req_ctx, 0, sizeof(*req_ctx));
+	size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
+			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+	req_ctx->hw_context_size = size;
+	memcpy(req_ctx->hw_context, export->hw_context, size);
+	req_ctx->swinit = export->swinit;
+	req_ctx->first_request = export->first_request;
+	req_ctx->last_request = export->last_request;
+	req_ctx->to_hash_later = export->to_hash_later;
+	req_ctx->message_size = export->message_size;
+
+	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
+			     DMA_TO_DEVICE);
+	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
+
+	return 0;
+}
+
+static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
+		   u8 *hash)
+{
+	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+
+	struct scatterlist sg[1];
+	struct ahash_request *req;
+	struct crypto_wait wait;
+	int ret;
+
+	crypto_init_wait(&wait);
+
+	req = ahash_request_alloc(tfm, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	/* Keep tfm keylen == 0 during hash of the long key */
+	ctx->keylen = 0;
+	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+				   crypto_req_done, &wait);
+
+	sg_init_one(&sg[0], key, keylen);
+
+	ahash_request_set_crypt(req, sg, hash, keylen);
+	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
+
+	ahash_request_free(req);
+
+	return ret;
+}
+
+static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
+			unsigned int keylen)
+{
+	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+	struct device *dev = ctx->dev;
+	unsigned int blocksize =
+			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+	unsigned int digestsize = crypto_ahash_digestsize(tfm);
+	unsigned int keysize = keylen;
+	u8 hash[SHA512_DIGEST_SIZE];
+	int ret;
+
+	if (keylen <= blocksize)
+		memcpy(ctx->key, key, keysize);
+	else {
+		/* Must get the hash of the long key */
+		ret = keyhash(tfm, key, keylen, hash);
+
+		if (ret)
+			return -EINVAL;
+
+		keysize = digestsize;
+		memcpy(ctx->key, hash, digestsize);
+	}
+
+	if (ctx->keylen)
+		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
+
+	ctx->keylen = keysize;
+	ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
+
+	return 0;
+}
+
+static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct talitos_crypto_alg *talitos_alg;
+	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	talitos_alg = container_of(__crypto_ahash_alg(alg),
+				   struct talitos_crypto_alg,
+				   algt.alg.hash);
+
+	ctx->keylen = 0;
+
+	return talitos_init_common(ctx, talitos_alg);
+}
+
+static struct talitos_alg_template hash_driver_algs[] = {
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = MD5_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "md5",
+				.cra_driver_name = "md5-talitos",
+				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_MD5,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA1_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "sha1",
+				.cra_driver_name = "sha1-talitos",
+				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA1,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA224_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "sha224",
+				.cra_driver_name = "sha224-talitos",
+				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA224,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA256_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "sha256",
+				.cra_driver_name = "sha256-talitos",
+				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA256,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA384_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "sha384",
+				.cra_driver_name = "sha384-talitos",
+				.cra_blocksize = SHA384_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUB |
+				     DESC_HDR_MODE0_MDEUB_SHA384,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA512_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "sha512",
+				.cra_driver_name = "sha512-talitos",
+				.cra_blocksize = SHA512_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUB |
+				     DESC_HDR_MODE0_MDEUB_SHA512,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = MD5_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(md5)",
+				.cra_driver_name = "hmac-md5-talitos",
+				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_MD5,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA1_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(sha1)",
+				.cra_driver_name = "hmac-sha1-talitos",
+				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA1,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA224_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(sha224)",
+				.cra_driver_name = "hmac-sha224-talitos",
+				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA224,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA256_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(sha256)",
+				.cra_driver_name = "hmac-sha256-talitos",
+				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUA |
+				     DESC_HDR_MODE0_MDEU_SHA256,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA384_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(sha384)",
+				.cra_driver_name = "hmac-sha384-talitos",
+				.cra_blocksize = SHA384_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUB |
+				     DESC_HDR_MODE0_MDEUB_SHA384,
+	},
+	{	.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.hash = {
+			.halg.digestsize = SHA512_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
+			.halg.base = {
+				.cra_name = "hmac(sha512)",
+				.cra_driver_name = "hmac-sha512-talitos",
+				.cra_blocksize = SHA512_BLOCK_SIZE,
+				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
+				.cra_flags = CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_ALLOCATES_MEMORY |
+					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
+			}
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_MDEUB |
+				     DESC_HDR_MODE0_MDEUB_SHA512,
+	}
+};
+
+int talitos_register_hash(struct device *dev)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	struct ahash_alg *ahash_alg;
+	struct crypto_alg *alg;
+	size_t i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(hash_driver_algs); i++) {
+		if (!talitos_hw_supports(dev,
+					 hash_driver_algs[i].desc_hdr_template))
+			continue;
+
+		ahash_alg = &hash_driver_algs[i].alg.hash;
+		alg = &ahash_alg->halg.base;
+
+		alg->cra_init = talitos_cra_init_ahash;
+		alg->cra_exit = talitos_cra_exit;
+		ahash_alg->init = ahash_init;
+		ahash_alg->update = ahash_update;
+		ahash_alg->final = ahash_final;
+		ahash_alg->finup = ahash_finup;
+		ahash_alg->digest = ahash_digest;
+		if (!strncmp(alg->cra_name, "hmac", 4))
+			ahash_alg->setkey = ahash_setkey;
+		ahash_alg->import = ahash_import;
+		ahash_alg->export = ahash_export;
+
+		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
+		    !strncmp(alg->cra_name, "hmac", 4)) {
+			/* not supported */
+			continue;
+		}
+
+		if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
+		    (!strcmp(alg->cra_name, "sha224") ||
+		     !strcmp(alg->cra_name, "hmac(sha224)"))) {
+			ahash_alg->init = ahash_init_sha224_swinit;
+			ahash_alg->digest = ahash_digest_sha224_swinit;
+			hash_driver_algs[i].desc_hdr_template =
+				DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				DESC_HDR_SEL0_MDEUA |
+				DESC_HDR_MODE0_MDEU_SHA256;
+		}
+
+		ret = talitos_register_common(dev, &hash_driver_algs[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
index dc92b98ec5ef..2d5688b1c81e 100644
--- a/drivers/crypto/talitos/talitos.c
+++ b/drivers/crypto/talitos/talitos.c
@@ -738,28 +738,6 @@ DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
  */
 #define TALITOS_CRA_PRIORITY_AEAD_HSNA	(TALITOS_CRA_PRIORITY - 1)
 
-#define TALITOS_MDEU_MAX_CONTEXT_SIZE	TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
-
-struct talitos_ahash_req_ctx {
-	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
-	u8 padding_buf[64];
-	u64 message_size;
-	unsigned int hw_context_size;
-	unsigned int swinit;
-	unsigned int first_request;
-	unsigned int last_request;
-	unsigned int to_hash_later;
-};
-
-struct talitos_export_state {
-	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
-	u64 message_size;
-	unsigned int swinit;
-	unsigned int first_request;
-	unsigned int last_request;
-	unsigned int to_hash_later;
-};
-
 static int aead_setkey(struct crypto_aead *authenc,
 		       const u8 *key, unsigned int keylen)
 {
@@ -1568,503 +1546,6 @@ static int skcipher_decrypt(struct skcipher_request *areq)
 	return common_nonsnoop(edesc, areq, skcipher_done);
 }
 
-static void common_nonsnoop_hash_unmap(struct device *dev,
-				       struct talitos_edesc *edesc,
-				       struct ahash_request *areq)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	bool is_sec1 = has_ftr_sec1(priv);
-	struct talitos_desc *desc = &edesc->desc;
-
-	unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
-
-	if (edesc->last && req_ctx->last_request)
-		memcpy(areq->result, req_ctx->hw_context,
-		       crypto_ahash_digestsize(tfm));
-
-	if (edesc->src)
-		talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
-
-	/* When using hashctx-in, must unmap it. */
-	if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
-		unmap_single_talitos_ptr(dev, &desc->ptr[1],
-					 DMA_TO_DEVICE);
-
-	if (edesc->dma_len)
-		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
-				 DMA_BIDIRECTIONAL);
-}
-
-static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
-{
-	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-	struct talitos_edesc *next;
-
-	while (edesc) {
-		next = edesc->next_desc;
-		common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
-		kfree(edesc);
-		edesc = next;
-	}
-}
-
-static void ahash_done(struct device *dev,
-		       struct talitos_desc *desc, void *context,
-		       int err)
-{
-	struct ahash_request *areq = context;
-	struct talitos_edesc *edesc =
-		 container_of(desc, struct talitos_edesc, desc);
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct talitos_edesc *next;
-
-	if (is_sec1) {
-		free_edesc_list_from(areq, edesc);
-		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
-	} else {
-		next = edesc->next_desc;
-
-		common_nonsnoop_hash_unmap(dev, edesc, areq);
-		kfree(edesc);
-
-		if (err)
-			goto out;
-
-		if (next) {
-			err = talitos_submit(dev, ctx->ch, &next->desc,
-					     ahash_done, areq);
-			if (err != -EINPROGRESS)
-				goto out;
-			return;
-		}
-out:
-		if (err && next)
-			free_edesc_list_from(areq, next);
-		ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
-	}
-}
-
-/*
- * SEC1 doesn't like hashing of 0 sized message, so we do the padding
- * ourself and submit a padded block
- */
-static void talitos_handle_buggy_hash(struct talitos_ahash_req_ctx *req_ctx,
-				      struct talitos_ctx *ctx,
-				      struct talitos_edesc *edesc,
-				      struct talitos_ptr *ptr)
-{
-	__be64 len = cpu_to_be64(req_ctx->message_size << 3);
-
-	memset(req_ctx->padding_buf, 0, sizeof(req_ctx->padding_buf));
-	req_ctx->padding_buf[0] = 0x80;
-	memcpy(&req_ctx->padding_buf[56], &len, sizeof(len));
-
-	pr_err_once("Bug in SEC1, padding ourself\n");
-	edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
-	map_single_talitos_ptr(ctx->dev, ptr, sizeof(req_ctx->padding_buf),
-			       (char *)req_ctx->padding_buf, DMA_TO_DEVICE);
-}
-
-static void common_nonsnoop_hash(struct talitos_edesc *edesc,
-				 struct ahash_request *areq,
-				 unsigned int length)
-{
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct device *dev = ctx->dev;
-	struct talitos_desc *desc = &edesc->desc;
-	bool sync_needed = false;
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	bool is_sec1 = has_ftr_sec1(priv);
-	int sg_count;
-
-	/* first DWORD empty */
-
-	/* hash context in */
-	if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
-		map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
-					      req_ctx->hw_context_size,
-					      req_ctx->hw_context,
-					      DMA_TO_DEVICE);
-		req_ctx->swinit = 0;
-	}
-	/* Indicate next op is not the first. */
-	req_ctx->first_request = 0;
-
-	/* HMAC key */
-	if (ctx->keylen)
-		to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
-			       is_sec1);
-
-	sg_count = edesc->src_nents ?: 1;
-	if (is_sec1 && sg_count > 1)
-		sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
-	else if (length)
-		sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
-
-	/*
-	 * data in
-	 */
-	sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
-				  sg_count, 0, 0);
-	if (sg_count > 1)
-		sync_needed = true;
-
-	/* fifth DWORD empty */
-
-	/* hash/HMAC out -or- hash context out */
-	if (edesc->last && req_ctx->last_request)
-		map_single_talitos_ptr(dev, &desc->ptr[5],
-				       crypto_ahash_digestsize(tfm),
-				       req_ctx->hw_context, DMA_FROM_DEVICE);
-	else
-		map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
-					      req_ctx->hw_context_size,
-					      req_ctx->hw_context,
-					      DMA_FROM_DEVICE);
-
-	/* last DWORD empty */
-
-	if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
-		talitos_handle_buggy_hash(req_ctx, ctx, edesc, &desc->ptr[3]);
-
-	if (sync_needed)
-		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
-					   edesc->dma_len, DMA_BIDIRECTIONAL);
-}
-
-static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
-					       struct scatterlist *src,
-					       unsigned int nbytes)
-{
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-
-	return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
-				   nbytes, 0, 0, 0, areq->base.flags, false);
-}
-
-static struct talitos_edesc *
-ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
-			  unsigned int blocksize, bool is_sec1)
-{
-	struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
-	size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
-				    TALITOS2_MAX_DATA_LEN;
-	struct scatterlist tmp[2];
-	size_t to_hash_this_desc;
-	struct scatterlist *src;
-	size_t offset = 0;
-
-	do {
-		src = scatterwalk_ffwd(tmp, areq->src, offset);
-
-		to_hash_this_desc =
-			min(nbytes, ALIGN_DOWN(desc_max, blocksize));
-
-		/* Allocate extended descriptor */
-		edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
-		if (IS_ERR(edesc)) {
-			if (first)
-				free_edesc_list_from(areq, first);
-			return edesc;
-		}
-
-		edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
-		edesc->desc.hdr = ctx->desc_hdr_template;
-		edesc->first = offset == 0;
-		edesc->last = nbytes - to_hash_this_desc == 0;
-
-		/* On last one, request SEC to pad; otherwise continue */
-		if (req_ctx->last_request && edesc->last)
-			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
-		else
-			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
-
-		/* request SEC to INIT hash. */
-		if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
-			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
-
-		/*
-		 * When the tfm context has a keylen, it's an HMAC.
-		 * A first or last (ie. not middle) descriptor must request HMAC.
-		 */
-		if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
-				    (req_ctx->last_request && edesc->last)))
-			edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
-
-		/* clear the DN bit  */
-		if (is_sec1 && !edesc->last)
-			edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
-
-		common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
-
-		offset += to_hash_this_desc;
-		nbytes -= to_hash_this_desc;
-
-		if (!prev_edesc)
-			first = edesc;
-		else
-			prev_edesc->next_desc = edesc;
-		prev_edesc = edesc;
-	} while (nbytes);
-
-	return first;
-}
-
-static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
-{
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct talitos_edesc *edesc;
-	unsigned int blocksize =
-			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
-	bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
-	unsigned int nbytes_to_hash;
-	unsigned int to_hash_later;
-	struct device *dev = ctx->dev;
-	int ret;
-
-	nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
-	to_hash_later = nbytes - nbytes_to_hash;
-
-	if (req_ctx->last_request) {
-		nbytes_to_hash = nbytes;
-		to_hash_later = 0;
-	}
-
-	req_ctx->to_hash_later = to_hash_later;
-
-	edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
-					  is_sec1);
-	if (IS_ERR(edesc))
-		return PTR_ERR(edesc);
-
-	ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
-	if (ret != -EINPROGRESS)
-		free_edesc_list_from(areq, edesc);
-
-	return ret;
-}
-
-static int ahash_init(struct ahash_request *areq)
-{
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct device *dev = ctx->dev;
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	unsigned int size;
-	dma_addr_t dma;
-
-	/* Initialize the context */
-	req_ctx->first_request = 1;
-	req_ctx->swinit = 0; /* assume h/w init of context */
-	size =	(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
-			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
-			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
-	req_ctx->hw_context_size = size;
-	req_ctx->last_request = 0;
-
-	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
-			     DMA_TO_DEVICE);
-	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
-
-	return 0;
-}
-
-/*
- * on h/w without explicit sha224 support, we initialize h/w context
- * manually with sha224 constants, and tell it to run sha256.
- */
-static int ahash_init_sha224_swinit(struct ahash_request *areq)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-
-	req_ctx->hw_context[0] = SHA224_H0;
-	req_ctx->hw_context[1] = SHA224_H1;
-	req_ctx->hw_context[2] = SHA224_H2;
-	req_ctx->hw_context[3] = SHA224_H3;
-	req_ctx->hw_context[4] = SHA224_H4;
-	req_ctx->hw_context[5] = SHA224_H5;
-	req_ctx->hw_context[6] = SHA224_H6;
-	req_ctx->hw_context[7] = SHA224_H7;
-
-	/* init 64-bit count */
-	req_ctx->hw_context[8] = 0;
-	req_ctx->hw_context[9] = 0;
-
-	ahash_init(areq);
-	req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
-
-	return 0;
-}
-
-static int ahash_update(struct ahash_request *areq)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-
-	req_ctx->last_request = 0;
-
-	return ahash_process_req(areq, areq->nbytes);
-}
-
-static int ahash_final(struct ahash_request *areq)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-
-	req_ctx->last_request = 1;
-
-	return ahash_process_req(areq, 0);
-}
-
-static int ahash_finup(struct ahash_request *areq)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-
-	req_ctx->last_request = 1;
-
-	return ahash_process_req(areq, areq->nbytes);
-}
-
-static int ahash_digest(struct ahash_request *areq)
-{
-	ahash_init(areq);
-	return ahash_finup(areq);
-}
-
-static int ahash_digest_sha224_swinit(struct ahash_request *areq)
-{
-	ahash_init_sha224_swinit(areq);
-	return ahash_finup(areq);
-}
-
-static int ahash_export(struct ahash_request *areq, void *out)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct talitos_export_state *export = out;
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct device *dev = ctx->dev;
-	dma_addr_t dma;
-
-	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
-			     DMA_FROM_DEVICE);
-	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
-
-	memcpy(export->hw_context, req_ctx->hw_context,
-	       req_ctx->hw_context_size);
-	export->swinit = req_ctx->swinit;
-	export->first_request = req_ctx->first_request;
-	export->last_request = req_ctx->last_request;
-	export->to_hash_later = req_ctx->to_hash_later;
-	export->message_size = req_ctx->message_size;
-
-	return 0;
-}
-
-static int ahash_import(struct ahash_request *areq, const void *in)
-{
-	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
-	struct device *dev = ctx->dev;
-	const struct talitos_export_state *export = in;
-	unsigned int size;
-	dma_addr_t dma;
-
-	memset(req_ctx, 0, sizeof(*req_ctx));
-	size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
-			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
-			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
-	req_ctx->hw_context_size = size;
-	memcpy(req_ctx->hw_context, export->hw_context, size);
-	req_ctx->swinit = export->swinit;
-	req_ctx->first_request = export->first_request;
-	req_ctx->last_request = export->last_request;
-	req_ctx->to_hash_later = export->to_hash_later;
-	req_ctx->message_size = export->message_size;
-
-	dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
-			     DMA_TO_DEVICE);
-	dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
-
-	return 0;
-}
-
-static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
-		   u8 *hash)
-{
-	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-
-	struct scatterlist sg[1];
-	struct ahash_request *req;
-	struct crypto_wait wait;
-	int ret;
-
-	crypto_init_wait(&wait);
-
-	req = ahash_request_alloc(tfm, GFP_KERNEL);
-	if (!req)
-		return -ENOMEM;
-
-	/* Keep tfm keylen == 0 during hash of the long key */
-	ctx->keylen = 0;
-	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   crypto_req_done, &wait);
-
-	sg_init_one(&sg[0], key, keylen);
-
-	ahash_request_set_crypt(req, sg, hash, keylen);
-	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
-
-	ahash_request_free(req);
-
-	return ret;
-}
-
-static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
-			unsigned int keylen)
-{
-	struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-	struct device *dev = ctx->dev;
-	unsigned int blocksize =
-			crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
-	unsigned int digestsize = crypto_ahash_digestsize(tfm);
-	unsigned int keysize = keylen;
-	u8 hash[SHA512_DIGEST_SIZE];
-	int ret;
-
-	if (keylen <= blocksize)
-		memcpy(ctx->key, key, keysize);
-	else {
-		/* Must get the hash of the long key */
-		ret = keyhash(tfm, key, keylen, hash);
-
-		if (ret)
-			return -EINVAL;
-
-		keysize = digestsize;
-		memcpy(ctx->key, hash, digestsize);
-	}
-
-	if (ctx->keylen)
-		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
-
-	ctx->keylen = keysize;
-	ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
-
-	return 0;
-}
-
 static struct talitos_alg_template driver_algs[] = {
 	/* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
 	{	.type = CRYPTO_ALG_TYPE_AEAD,
@@ -2648,223 +2129,6 @@ static struct talitos_alg_template driver_algs[] = {
 		                     DESC_HDR_MODE0_DEU_CBC |
 		                     DESC_HDR_MODE0_DEU_3DES,
 	},
-	/* AHASH algorithms. */
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = MD5_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "md5",
-				.cra_driver_name = "md5-talitos",
-				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_MD5,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA1_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "sha1",
-				.cra_driver_name = "sha1-talitos",
-				.cra_blocksize = SHA1_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA1,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA224_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "sha224",
-				.cra_driver_name = "sha224-talitos",
-				.cra_blocksize = SHA224_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA224,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA256_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "sha256",
-				.cra_driver_name = "sha256-talitos",
-				.cra_blocksize = SHA256_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA256,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA384_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "sha384",
-				.cra_driver_name = "sha384-talitos",
-				.cra_blocksize = SHA384_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUB |
-				     DESC_HDR_MODE0_MDEUB_SHA384,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA512_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "sha512",
-				.cra_driver_name = "sha512-talitos",
-				.cra_blocksize = SHA512_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUB |
-				     DESC_HDR_MODE0_MDEUB_SHA512,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = MD5_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(md5)",
-				.cra_driver_name = "hmac-md5-talitos",
-				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_MD5,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA1_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(sha1)",
-				.cra_driver_name = "hmac-sha1-talitos",
-				.cra_blocksize = SHA1_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA1,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA224_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(sha224)",
-				.cra_driver_name = "hmac-sha224-talitos",
-				.cra_blocksize = SHA224_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA224,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA256_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(sha256)",
-				.cra_driver_name = "hmac-sha256-talitos",
-				.cra_blocksize = SHA256_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUA |
-				     DESC_HDR_MODE0_MDEU_SHA256,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA384_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(sha384)",
-				.cra_driver_name = "hmac-sha384-talitos",
-				.cra_blocksize = SHA384_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUB |
-				     DESC_HDR_MODE0_MDEUB_SHA384,
-	},
-	{	.type = CRYPTO_ALG_TYPE_AHASH,
-		.alg.hash = {
-			.halg.digestsize = SHA512_DIGEST_SIZE,
-			.halg.statesize = sizeof(struct talitos_export_state),
-			.halg.base = {
-				.cra_name = "hmac(sha512)",
-				.cra_driver_name = "hmac-sha512-talitos",
-				.cra_blocksize = SHA512_BLOCK_SIZE,
-				.cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
-				.cra_flags = CRYPTO_ALG_ASYNC |
-					     CRYPTO_ALG_ALLOCATES_MEMORY |
-					     CRYPTO_AHASH_ALG_BLOCK_ONLY,
-			}
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_MDEUB |
-				     DESC_HDR_MODE0_MDEUB_SHA512,
-	}
 };
 
 int talitos_init_common(struct talitos_ctx *ctx,
@@ -2913,21 +2177,6 @@ static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
 	return talitos_init_common(ctx, talitos_alg);
 }
 
-static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg = tfm->__crt_alg;
-	struct talitos_crypto_alg *talitos_alg;
-	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
-
-	talitos_alg = container_of(__crypto_ahash_alg(alg),
-				   struct talitos_crypto_alg,
-				   algt.alg.hash);
-
-	ctx->keylen = 0;
-
-	return talitos_init_common(ctx, talitos_alg);
-}
-
 void talitos_cra_exit(struct crypto_tfm *tfm)
 {
 	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -2993,6 +2242,65 @@ static void talitos_remove(struct platform_device *ofdev)
 		tasklet_kill(&priv->done_task[1]);
 }
 
+static void talitos_alg_set_common(struct talitos_private *priv,
+				   struct crypto_alg *alg, u32 custom_priority,
+				   u32 type)
+{
+	alg->cra_module = THIS_MODULE;
+	if (custom_priority)
+		alg->cra_priority = custom_priority;
+	else
+		alg->cra_priority = TALITOS_CRA_PRIORITY;
+	if (has_ftr_sec1(priv) && type != CRYPTO_ALG_TYPE_AHASH)
+		alg->cra_alignmask = 3;
+	else
+		alg->cra_alignmask = 0;
+	alg->cra_ctxsize = sizeof(struct talitos_ctx);
+	alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
+}
+
+int talitos_register_common(struct device *dev,
+			    struct talitos_alg_template *template)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	struct talitos_crypto_alg *t_alg;
+	struct crypto_alg *alg;
+	int ret;
+
+	t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
+			     GFP_KERNEL);
+	if (!t_alg)
+		return -ENOMEM;
+
+	t_alg->algt = *template;
+
+	switch (t_alg->algt.type) {
+	case CRYPTO_ALG_TYPE_AHASH:
+		alg = &t_alg->algt.alg.hash.halg.base;
+		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
+				       t_alg->algt.type);
+		ret = crypto_register_ahash(&t_alg->algt.alg.hash);
+		break;
+	default:
+		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
+		devm_kfree(dev, t_alg);
+		return -EINVAL;
+	}
+
+	if (ret) {
+		dev_err(dev, "%s alg registration failed\n",
+			alg->cra_driver_name);
+		devm_kfree(dev, t_alg);
+		return 0;
+	}
+
+	t_alg->dev = dev;
+
+	list_add_tail(&t_alg->entry, &priv->alg_list);
+
+	return 0;
+}
+
 static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
 						    struct talitos_alg_template
 						           *template)
@@ -3038,37 +2346,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
 			return ERR_PTR(-ENOTSUPP);
 		}
 		break;
-	case CRYPTO_ALG_TYPE_AHASH:
-		alg = &t_alg->algt.alg.hash.halg.base;
-		alg->cra_init = talitos_cra_init_ahash;
-		alg->cra_exit = talitos_cra_exit;
-		t_alg->algt.alg.hash.init = ahash_init;
-		t_alg->algt.alg.hash.update = ahash_update;
-		t_alg->algt.alg.hash.final = ahash_final;
-		t_alg->algt.alg.hash.finup = ahash_finup;
-		t_alg->algt.alg.hash.digest = ahash_digest;
-		if (!strncmp(alg->cra_name, "hmac", 4))
-			t_alg->algt.alg.hash.setkey = ahash_setkey;
-		t_alg->algt.alg.hash.import = ahash_import;
-		t_alg->algt.alg.hash.export = ahash_export;
-
-		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
-		    !strncmp(alg->cra_name, "hmac", 4)) {
-			devm_kfree(dev, t_alg);
-			return ERR_PTR(-ENOTSUPP);
-		}
-		if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
-		    (!strcmp(alg->cra_name, "sha224") ||
-		     !strcmp(alg->cra_name, "hmac(sha224)"))) {
-			t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
-			t_alg->algt.alg.hash.digest =
-				ahash_digest_sha224_swinit;
-			t_alg->algt.desc_hdr_template =
-					DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-					DESC_HDR_SEL0_MDEUA |
-					DESC_HDR_MODE0_MDEU_SHA256;
-		}
-		break;
 	default:
 		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
 		devm_kfree(dev, t_alg);
@@ -3297,6 +2574,10 @@ static int talitos_probe(struct platform_device *ofdev)
 			dev_info(dev, "hwrng\n");
 	}
 
+	err = talitos_register_hash(dev);
+	if (err)
+		goto err_out;
+
 	/* register crypto algorithms the device supports */
 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
 		if (talitos_hw_supports(dev,
@@ -3324,12 +2605,6 @@ static int talitos_probe(struct platform_device *ofdev)
 					&t_alg->algt.alg.aead);
 				alg = &t_alg->algt.alg.aead.base;
 				break;
-
-			case CRYPTO_ALG_TYPE_AHASH:
-				err = crypto_register_ahash(
-						&t_alg->algt.alg.hash);
-				alg = &t_alg->algt.alg.hash.halg.base;
-				break;
 			}
 			if (err) {
 				dev_err(dev, "%s alg registration failed\n",
diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
index 81331914801b..e59c85e3196c 100644
--- a/drivers/crypto/talitos/talitos.h
+++ b/drivers/crypto/talitos/talitos.h
@@ -599,7 +599,14 @@ int talitos_init_common(struct talitos_ctx *ctx,
 			struct talitos_crypto_alg *talitos_alg);
 void talitos_cra_exit(struct crypto_tfm *tfm);
 
+int talitos_register_common(struct device *dev,
+			    struct talitos_alg_template *template);
+
 /* Hardware RNG */
 
 int talitos_register_rng(struct device *dev);
 void talitos_unregister_rng(struct device *dev);
+
+/* Hash */
+
+int talitos_register_hash(struct device *dev);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 07/19] crypto: talitos/skcipher - Move into separate file
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
                   ` (5 preceding siblings ...)
  2026-07-21 13:40 ` [PATCH v3 06/19] crypto: talitos/hash - Move into separate file Paul Louvel
@ 2026-07-21 13:40 ` Paul Louvel
  2026-07-21 13:42   ` Paul Louvel
  2026-07-21 13:54 ` [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
  7 siblings, 1 reply; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:40 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

Move the skcipher algorithm implementations from talitos.c into
a dedicated talitos-skcipher.c file.

Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
 drivers/crypto/talitos/Makefile           |   2 +-
 drivers/crypto/talitos/talitos-skcipher.c | 399 ++++++++++++++++++++++++++++++
 drivers/crypto/talitos/talitos.c          | 377 +---------------------------
 drivers/crypto/talitos/talitos.h          |   1 +
 4 files changed, 411 insertions(+), 368 deletions(-)

diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
index 40d37f9364ef..d4f19f2f6375 100644
--- a/drivers/crypto/talitos/Makefile
+++ b/drivers/crypto/talitos/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 
-talitos-y := talitos.o talitos-rng.o talitos-hash.o
+talitos-y := talitos.o talitos-rng.o talitos-hash.o talitos-skcipher.o
diff --git a/drivers/crypto/talitos/talitos-skcipher.c b/drivers/crypto/talitos/talitos-skcipher.c
new file mode 100644
index 000000000000..f80373610aa4
--- /dev/null
+++ b/drivers/crypto/talitos/talitos-skcipher.c
@@ -0,0 +1,399 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Freescale SEC (talitos) skcipher implementation
+ *
+ * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
+ */
+
+#include <crypto/internal/des.h>
+#include <crypto/internal/skcipher.h>
+
+#include "talitos.h"
+
+static void common_nonsnoop_unmap(struct device *dev,
+				  struct talitos_edesc *edesc,
+				  struct skcipher_request *areq)
+{
+	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
+
+	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
+	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
+
+	if (edesc->dma_len)
+		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+				 DMA_BIDIRECTIONAL);
+}
+
+static void skcipher_done(struct device *dev,
+			    struct talitos_desc *desc, void *context,
+			    int err)
+{
+	struct skcipher_request *areq = context;
+	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
+	struct talitos_edesc *edesc;
+
+	edesc = container_of(desc, struct talitos_edesc, desc);
+
+	common_nonsnoop_unmap(dev, edesc, areq);
+	memcpy(areq->iv, ctx->iv, ivsize);
+
+	kfree(edesc);
+
+	skcipher_request_complete(areq, err);
+}
+
+static int common_nonsnoop(struct talitos_edesc *edesc,
+			   struct skcipher_request *areq,
+			   void (*callback) (struct device *dev,
+					     struct talitos_desc *desc,
+					     void *context, int error))
+{
+	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	struct device *dev = ctx->dev;
+	struct talitos_desc *desc = &edesc->desc;
+	unsigned int cryptlen = areq->cryptlen;
+	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
+	int sg_count, ret;
+	bool sync_needed = false;
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	bool is_sec1 = has_ftr_sec1(priv);
+	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
+		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
+
+	/* first DWORD empty */
+
+	/* cipher iv */
+	to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
+
+	/* cipher key */
+	to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
+
+	sg_count = edesc->src_nents ?: 1;
+	if (is_sec1 && sg_count > 1)
+		sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
+				  cryptlen);
+	else
+		sg_count = dma_map_sg(dev, areq->src, sg_count,
+				      (areq->src == areq->dst) ?
+				      DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
+	/*
+	 * cipher in
+	 */
+	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
+				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
+	if (sg_count > 1)
+		sync_needed = true;
+
+	/* cipher out */
+	if (areq->src != areq->dst) {
+		sg_count = edesc->dst_nents ? : 1;
+		if (!is_sec1 || sg_count == 1)
+			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
+	}
+
+	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
+			     sg_count, 0, (edesc->src_nents + 1));
+	if (ret > 1)
+		sync_needed = true;
+
+	/* iv out */
+	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
+			       DMA_FROM_DEVICE);
+
+	/* last DWORD empty */
+
+	if (sync_needed)
+		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+					   edesc->dma_len, DMA_BIDIRECTIONAL);
+
+	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
+	if (ret != -EINPROGRESS) {
+		common_nonsnoop_unmap(dev, edesc, areq);
+		kfree(edesc);
+	}
+	return ret;
+}
+
+static int skcipher_setkey(struct crypto_skcipher *cipher,
+			     const u8 *key, unsigned int keylen)
+{
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	struct device *dev = ctx->dev;
+
+	if (ctx->keylen)
+		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
+
+	memcpy(&ctx->key, key, keylen);
+	ctx->keylen = keylen;
+
+	ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
+
+	return 0;
+}
+
+static int skcipher_des_setkey(struct crypto_skcipher *cipher,
+				 const u8 *key, unsigned int keylen)
+{
+	return verify_skcipher_des_key(cipher, key) ?:
+	       skcipher_setkey(cipher, key, keylen);
+}
+
+static int skcipher_des3_setkey(struct crypto_skcipher *cipher,
+				  const u8 *key, unsigned int keylen)
+{
+	return verify_skcipher_des3_key(cipher, key) ?:
+	       skcipher_setkey(cipher, key, keylen);
+}
+
+static int skcipher_aes_setkey(struct crypto_skcipher *cipher,
+				  const u8 *key, unsigned int keylen)
+{
+	if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
+	    keylen == AES_KEYSIZE_256)
+		return skcipher_setkey(cipher, key, keylen);
+
+	return -EINVAL;
+}
+
+static struct talitos_edesc *skcipher_edesc_alloc(struct skcipher_request *
+						    areq, bool encrypt)
+{
+	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
+
+	return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
+				   areq->iv, 0, areq->cryptlen, 0, ivsize, 0,
+				   areq->base.flags, encrypt);
+}
+
+static int skcipher_encrypt(struct skcipher_request *areq)
+{
+	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	struct talitos_edesc *edesc;
+	unsigned int blocksize =
+			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
+
+	if (!areq->cryptlen)
+		return 0;
+
+	if (areq->cryptlen % blocksize)
+		return -EINVAL;
+
+	/* allocate extended descriptor */
+	edesc = skcipher_edesc_alloc(areq, true);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	/* set encrypt */
+	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
+
+	return common_nonsnoop(edesc, areq, skcipher_done);
+}
+
+static int skcipher_decrypt(struct skcipher_request *areq)
+{
+	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
+	struct talitos_edesc *edesc;
+	unsigned int blocksize =
+			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
+
+	if (!areq->cryptlen)
+		return 0;
+
+	if (areq->cryptlen % blocksize)
+		return -EINVAL;
+
+	/* allocate extended descriptor */
+	edesc = skcipher_edesc_alloc(areq, false);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
+
+	return common_nonsnoop(edesc, areq, skcipher_done);
+}
+
+static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
+{
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct talitos_crypto_alg *talitos_alg;
+	struct talitos_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+	talitos_alg = container_of(alg, struct talitos_crypto_alg,
+				   algt.alg.skcipher);
+
+	return talitos_init_common(ctx, talitos_alg);
+}
+
+static struct talitos_alg_template skcipher_driver_algs[] = {
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "ecb(aes)",
+			.base.cra_driver_name = "ecb-aes-talitos",
+			.base.cra_blocksize = AES_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.setkey = skcipher_aes_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_AESU,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "cbc(aes)",
+			.base.cra_driver_name = "cbc-aes-talitos",
+			.base.cra_blocksize = AES_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.ivsize = AES_BLOCK_SIZE,
+			.setkey = skcipher_aes_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_AESU |
+				     DESC_HDR_MODE0_AESU_CBC,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "ctr(aes)",
+			.base.cra_driver_name = "ctr-aes-talitos",
+			.base.cra_blocksize = 1,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.ivsize = AES_BLOCK_SIZE,
+			.setkey = skcipher_aes_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
+				     DESC_HDR_SEL0_AESU |
+				     DESC_HDR_MODE0_AESU_CTR,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "ctr(aes)",
+			.base.cra_driver_name = "ctr-aes-talitos",
+			.base.cra_blocksize = 1,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.ivsize = AES_BLOCK_SIZE,
+			.setkey = skcipher_aes_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_AESU |
+				     DESC_HDR_MODE0_AESU_CTR,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "ecb(des)",
+			.base.cra_driver_name = "ecb-des-talitos",
+			.base.cra_blocksize = DES_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = DES_KEY_SIZE,
+			.max_keysize = DES_KEY_SIZE,
+			.setkey = skcipher_des_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_DEU,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "cbc(des)",
+			.base.cra_driver_name = "cbc-des-talitos",
+			.base.cra_blocksize = DES_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = DES_KEY_SIZE,
+			.max_keysize = DES_KEY_SIZE,
+			.ivsize = DES_BLOCK_SIZE,
+			.setkey = skcipher_des_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_DEU |
+				     DESC_HDR_MODE0_DEU_CBC,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "ecb(des3_ede)",
+			.base.cra_driver_name = "ecb-3des-talitos",
+			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = DES3_EDE_KEY_SIZE,
+			.max_keysize = DES3_EDE_KEY_SIZE,
+			.setkey = skcipher_des3_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_DEU |
+				     DESC_HDR_MODE0_DEU_3DES,
+	},
+	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+		.alg.skcipher = {
+			.base.cra_name = "cbc(des3_ede)",
+			.base.cra_driver_name = "cbc-3des-talitos",
+			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.base.cra_flags = CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_ALLOCATES_MEMORY,
+			.min_keysize = DES3_EDE_KEY_SIZE,
+			.max_keysize = DES3_EDE_KEY_SIZE,
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.setkey = skcipher_des3_setkey,
+		},
+		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+				     DESC_HDR_SEL0_DEU |
+				     DESC_HDR_MODE0_DEU_CBC |
+				     DESC_HDR_MODE0_DEU_3DES,
+	},
+};
+
+int talitos_register_skcipher(struct device *dev)
+{
+	struct talitos_private *priv = dev_get_drvdata(dev);
+	struct skcipher_alg *skcipher_alg;
+	struct crypto_alg *alg;
+	size_t i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(skcipher_driver_algs); i++) {
+		if (!talitos_hw_supports(
+			    dev, skcipher_driver_algs[i].desc_hdr_template))
+			continue;
+
+		skcipher_alg = &skcipher_driver_algs[i].alg.skcipher;
+		alg = &skcipher_alg->base;
+
+		alg->cra_exit = talitos_cra_exit;
+		if (has_ftr_sec1(priv))
+			alg->cra_alignmask = 3;
+
+		skcipher_alg->init = talitos_cra_init_skcipher;
+		skcipher_alg->setkey = skcipher_alg->setkey ?: skcipher_setkey;
+		skcipher_alg->encrypt = skcipher_encrypt;
+		skcipher_alg->decrypt = skcipher_decrypt;
+
+		if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
+		    DESC_TYPE(skcipher_driver_algs[i].desc_hdr_template) !=
+			    DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
+			continue;
+		}
+
+		ret = talitos_register_common(dev, &skcipher_driver_algs[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
index 2d5688b1c81e..4b77253e04fa 100644
--- a/drivers/crypto/talitos/talitos.c
+++ b/drivers/crypto/talitos/talitos.c
@@ -1337,215 +1337,6 @@ static int aead_decrypt(struct aead_request *req)
 	return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done);
 }
 
-static int skcipher_setkey(struct crypto_skcipher *cipher,
-			     const u8 *key, unsigned int keylen)
-{
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	struct device *dev = ctx->dev;
-
-	if (ctx->keylen)
-		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
-
-	memcpy(&ctx->key, key, keylen);
-	ctx->keylen = keylen;
-
-	ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
-
-	return 0;
-}
-
-static int skcipher_des_setkey(struct crypto_skcipher *cipher,
-				 const u8 *key, unsigned int keylen)
-{
-	return verify_skcipher_des_key(cipher, key) ?:
-	       skcipher_setkey(cipher, key, keylen);
-}
-
-static int skcipher_des3_setkey(struct crypto_skcipher *cipher,
-				  const u8 *key, unsigned int keylen)
-{
-	return verify_skcipher_des3_key(cipher, key) ?:
-	       skcipher_setkey(cipher, key, keylen);
-}
-
-static int skcipher_aes_setkey(struct crypto_skcipher *cipher,
-				  const u8 *key, unsigned int keylen)
-{
-	if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
-	    keylen == AES_KEYSIZE_256)
-		return skcipher_setkey(cipher, key, keylen);
-
-	return -EINVAL;
-}
-
-static void common_nonsnoop_unmap(struct device *dev,
-				  struct talitos_edesc *edesc,
-				  struct skcipher_request *areq)
-{
-	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
-
-	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
-	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
-
-	if (edesc->dma_len)
-		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
-				 DMA_BIDIRECTIONAL);
-}
-
-static void skcipher_done(struct device *dev,
-			    struct talitos_desc *desc, void *context,
-			    int err)
-{
-	struct skcipher_request *areq = context;
-	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
-	struct talitos_edesc *edesc;
-
-	edesc = container_of(desc, struct talitos_edesc, desc);
-
-	common_nonsnoop_unmap(dev, edesc, areq);
-	memcpy(areq->iv, ctx->iv, ivsize);
-
-	kfree(edesc);
-
-	skcipher_request_complete(areq, err);
-}
-
-static int common_nonsnoop(struct talitos_edesc *edesc,
-			   struct skcipher_request *areq,
-			   void (*callback) (struct device *dev,
-					     struct talitos_desc *desc,
-					     void *context, int error))
-{
-	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	struct device *dev = ctx->dev;
-	struct talitos_desc *desc = &edesc->desc;
-	unsigned int cryptlen = areq->cryptlen;
-	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
-	int sg_count, ret;
-	bool sync_needed = false;
-	struct talitos_private *priv = dev_get_drvdata(dev);
-	bool is_sec1 = has_ftr_sec1(priv);
-	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
-		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
-
-	/* first DWORD empty */
-
-	/* cipher iv */
-	to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
-
-	/* cipher key */
-	to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
-
-	sg_count = edesc->src_nents ?: 1;
-	if (is_sec1 && sg_count > 1)
-		sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
-				  cryptlen);
-	else
-		sg_count = dma_map_sg(dev, areq->src, sg_count,
-				      (areq->src == areq->dst) ?
-				      DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
-	/*
-	 * cipher in
-	 */
-	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
-				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
-	if (sg_count > 1)
-		sync_needed = true;
-
-	/* cipher out */
-	if (areq->src != areq->dst) {
-		sg_count = edesc->dst_nents ? : 1;
-		if (!is_sec1 || sg_count == 1)
-			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
-	}
-
-	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
-			     sg_count, 0, (edesc->src_nents + 1));
-	if (ret > 1)
-		sync_needed = true;
-
-	/* iv out */
-	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
-			       DMA_FROM_DEVICE);
-
-	/* last DWORD empty */
-
-	if (sync_needed)
-		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
-					   edesc->dma_len, DMA_BIDIRECTIONAL);
-
-	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
-	if (ret != -EINPROGRESS) {
-		common_nonsnoop_unmap(dev, edesc, areq);
-		kfree(edesc);
-	}
-	return ret;
-}
-
-static struct talitos_edesc *skcipher_edesc_alloc(struct skcipher_request *
-						    areq, bool encrypt)
-{
-	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
-
-	return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
-				   areq->iv, 0, areq->cryptlen, 0, ivsize, 0,
-				   areq->base.flags, encrypt);
-}
-
-static int skcipher_encrypt(struct skcipher_request *areq)
-{
-	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	struct talitos_edesc *edesc;
-	unsigned int blocksize =
-			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
-
-	if (!areq->cryptlen)
-		return 0;
-
-	if (areq->cryptlen % blocksize)
-		return -EINVAL;
-
-	/* allocate extended descriptor */
-	edesc = skcipher_edesc_alloc(areq, true);
-	if (IS_ERR(edesc))
-		return PTR_ERR(edesc);
-
-	/* set encrypt */
-	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
-
-	return common_nonsnoop(edesc, areq, skcipher_done);
-}
-
-static int skcipher_decrypt(struct skcipher_request *areq)
-{
-	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
-	struct talitos_edesc *edesc;
-	unsigned int blocksize =
-			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
-
-	if (!areq->cryptlen)
-		return 0;
-
-	if (areq->cryptlen % blocksize)
-		return -EINVAL;
-
-	/* allocate extended descriptor */
-	edesc = skcipher_edesc_alloc(areq, false);
-	if (IS_ERR(edesc))
-		return PTR_ERR(edesc);
-
-	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
-
-	return common_nonsnoop(edesc, areq, skcipher_done);
-}
-
 static struct talitos_alg_template driver_algs[] = {
 	/* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
 	{	.type = CRYPTO_ALG_TYPE_AEAD,
@@ -2004,131 +1795,6 @@ static struct talitos_alg_template driver_algs[] = {
 				     DESC_HDR_MODE1_MDEU_PAD |
 				     DESC_HDR_MODE1_MDEU_MD5_HMAC,
 	},
-	/* SKCIPHER algorithms. */
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "ecb(aes)",
-			.base.cra_driver_name = "ecb-aes-talitos",
-			.base.cra_blocksize = AES_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = AES_MIN_KEY_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE,
-			.setkey = skcipher_aes_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_AESU,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "cbc(aes)",
-			.base.cra_driver_name = "cbc-aes-talitos",
-			.base.cra_blocksize = AES_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = AES_MIN_KEY_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE,
-			.ivsize = AES_BLOCK_SIZE,
-			.setkey = skcipher_aes_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_AESU |
-				     DESC_HDR_MODE0_AESU_CBC,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "ctr(aes)",
-			.base.cra_driver_name = "ctr-aes-talitos",
-			.base.cra_blocksize = 1,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = AES_MIN_KEY_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE,
-			.ivsize = AES_BLOCK_SIZE,
-			.setkey = skcipher_aes_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
-				     DESC_HDR_SEL0_AESU |
-				     DESC_HDR_MODE0_AESU_CTR,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "ctr(aes)",
-			.base.cra_driver_name = "ctr-aes-talitos",
-			.base.cra_blocksize = 1,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = AES_MIN_KEY_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE,
-			.ivsize = AES_BLOCK_SIZE,
-			.setkey = skcipher_aes_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_AESU |
-				     DESC_HDR_MODE0_AESU_CTR,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "ecb(des)",
-			.base.cra_driver_name = "ecb-des-talitos",
-			.base.cra_blocksize = DES_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = DES_KEY_SIZE,
-			.max_keysize = DES_KEY_SIZE,
-			.setkey = skcipher_des_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_DEU,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "cbc(des)",
-			.base.cra_driver_name = "cbc-des-talitos",
-			.base.cra_blocksize = DES_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = DES_KEY_SIZE,
-			.max_keysize = DES_KEY_SIZE,
-			.ivsize = DES_BLOCK_SIZE,
-			.setkey = skcipher_des_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_DEU |
-				     DESC_HDR_MODE0_DEU_CBC,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "ecb(des3_ede)",
-			.base.cra_driver_name = "ecb-3des-talitos",
-			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = DES3_EDE_KEY_SIZE,
-			.max_keysize = DES3_EDE_KEY_SIZE,
-			.setkey = skcipher_des3_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-				     DESC_HDR_SEL0_DEU |
-				     DESC_HDR_MODE0_DEU_3DES,
-	},
-	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-		.alg.skcipher = {
-			.base.cra_name = "cbc(des3_ede)",
-			.base.cra_driver_name = "cbc-3des-talitos",
-			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
-			.base.cra_flags = CRYPTO_ALG_ASYNC |
-					  CRYPTO_ALG_ALLOCATES_MEMORY,
-			.min_keysize = DES3_EDE_KEY_SIZE,
-			.max_keysize = DES3_EDE_KEY_SIZE,
-			.ivsize = DES3_EDE_BLOCK_SIZE,
-			.setkey = skcipher_des3_setkey,
-		},
-		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
-			             DESC_HDR_SEL0_DEU |
-		                     DESC_HDR_MODE0_DEU_CBC |
-		                     DESC_HDR_MODE0_DEU_3DES,
-	},
 };
 
 int talitos_init_common(struct talitos_ctx *ctx,
@@ -2165,18 +1831,6 @@ static int talitos_cra_init_aead(struct crypto_aead *tfm)
 	return talitos_init_common(ctx, talitos_alg);
 }
 
-static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
-{
-	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
-	struct talitos_crypto_alg *talitos_alg;
-	struct talitos_ctx *ctx = crypto_skcipher_ctx(tfm);
-
-	talitos_alg = container_of(alg, struct talitos_crypto_alg,
-				   algt.alg.skcipher);
-
-	return talitos_init_common(ctx, talitos_alg);
-}
-
 void talitos_cra_exit(struct crypto_tfm *tfm)
 {
 	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -2281,6 +1935,12 @@ int talitos_register_common(struct device *dev,
 				       t_alg->algt.type);
 		ret = crypto_register_ahash(&t_alg->algt.alg.hash);
 		break;
+	case CRYPTO_ALG_TYPE_SKCIPHER:
+		alg = &t_alg->algt.alg.skcipher.base;
+		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
+				       t_alg->algt.type);
+		ret = crypto_register_skcipher(&t_alg->algt.alg.skcipher);
+		break;
 	default:
 		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
 		devm_kfree(dev, t_alg);
@@ -2317,21 +1977,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
 	t_alg->algt = *template;
 
 	switch (t_alg->algt.type) {
-	case CRYPTO_ALG_TYPE_SKCIPHER:
-		alg = &t_alg->algt.alg.skcipher.base;
-		alg->cra_exit = talitos_cra_exit;
-		t_alg->algt.alg.skcipher.init = talitos_cra_init_skcipher;
-		t_alg->algt.alg.skcipher.setkey =
-			t_alg->algt.alg.skcipher.setkey ?: skcipher_setkey;
-		t_alg->algt.alg.skcipher.encrypt = skcipher_encrypt;
-		t_alg->algt.alg.skcipher.decrypt = skcipher_decrypt;
-		if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
-		    DESC_TYPE(t_alg->algt.desc_hdr_template) !=
-		    DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
-			devm_kfree(dev, t_alg);
-			return ERR_PTR(-ENOTSUPP);
-		}
-		break;
 	case CRYPTO_ALG_TYPE_AEAD:
 		alg = &t_alg->algt.alg.aead.base;
 		alg->cra_exit = talitos_cra_exit;
@@ -2578,6 +2223,10 @@ static int talitos_probe(struct platform_device *ofdev)
 	if (err)
 		goto err_out;
 
+	err = talitos_register_skcipher(dev);
+	if (err)
+		goto err_out;
+
 	/* register crypto algorithms the device supports */
 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
 		if (talitos_hw_supports(dev,
@@ -2594,12 +2243,6 @@ static int talitos_probe(struct platform_device *ofdev)
 			}
 
 			switch (t_alg->algt.type) {
-			case CRYPTO_ALG_TYPE_SKCIPHER:
-				err = crypto_register_skcipher(
-						&t_alg->algt.alg.skcipher);
-				alg = &t_alg->algt.alg.skcipher.base;
-				break;
-
 			case CRYPTO_ALG_TYPE_AEAD:
 				err = crypto_register_aead(
 					&t_alg->algt.alg.aead);
diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
index e59c85e3196c..4a803ad6349d 100644
--- a/drivers/crypto/talitos/talitos.h
+++ b/drivers/crypto/talitos/talitos.h
@@ -610,3 +610,4 @@ void talitos_unregister_rng(struct device *dev);
 /* Hash */
 
 int talitos_register_hash(struct device *dev);
+int talitos_register_skcipher(struct device *dev);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 07/19] crypto: talitos/skcipher - Move into separate file
  2026-07-21 13:40 ` [PATCH v3 07/19] crypto: talitos/skcipher " Paul Louvel
@ 2026-07-21 13:42   ` Paul Louvel
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:42 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel

Somehow, B4 did not account for my change log for V3 in the cover letter.
Please discard this series.

Thanks,
Paul.

On 7/21/26 3:40 PM, Paul Louvel wrote:
> Move the skcipher algorithm implementations from talitos.c into
> a dedicated talitos-skcipher.c file.
>
> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
>   drivers/crypto/talitos/Makefile           |   2 +-
>   drivers/crypto/talitos/talitos-skcipher.c | 399 ++++++++++++++++++++++++++++++
>   drivers/crypto/talitos/talitos.c          | 377 +---------------------------
>   drivers/crypto/talitos/talitos.h          |   1 +
>   4 files changed, 411 insertions(+), 368 deletions(-)
>
> diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
> index 40d37f9364ef..d4f19f2f6375 100644
> --- a/drivers/crypto/talitos/Makefile
> +++ b/drivers/crypto/talitos/Makefile
> @@ -1,3 +1,3 @@
>   obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
>   
> -talitos-y := talitos.o talitos-rng.o talitos-hash.o
> +talitos-y := talitos.o talitos-rng.o talitos-hash.o talitos-skcipher.o
> diff --git a/drivers/crypto/talitos/talitos-skcipher.c b/drivers/crypto/talitos/talitos-skcipher.c
> new file mode 100644
> index 000000000000..f80373610aa4
> --- /dev/null
> +++ b/drivers/crypto/talitos/talitos-skcipher.c
> @@ -0,0 +1,399 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * Freescale SEC (talitos) skcipher implementation
> + *
> + * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
> + */
> +
> +#include <crypto/internal/des.h>
> +#include <crypto/internal/skcipher.h>
> +
> +#include "talitos.h"
> +
> +static void common_nonsnoop_unmap(struct device *dev,
> +				  struct talitos_edesc *edesc,
> +				  struct skcipher_request *areq)
> +{
> +	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
> +
> +	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
> +	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
> +
> +	if (edesc->dma_len)
> +		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
> +				 DMA_BIDIRECTIONAL);
> +}
> +
> +static void skcipher_done(struct device *dev,
> +			    struct talitos_desc *desc, void *context,
> +			    int err)
> +{
> +	struct skcipher_request *areq = context;
> +	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> +	struct talitos_edesc *edesc;
> +
> +	edesc = container_of(desc, struct talitos_edesc, desc);
> +
> +	common_nonsnoop_unmap(dev, edesc, areq);
> +	memcpy(areq->iv, ctx->iv, ivsize);
> +
> +	kfree(edesc);
> +
> +	skcipher_request_complete(areq, err);
> +}
> +
> +static int common_nonsnoop(struct talitos_edesc *edesc,
> +			   struct skcipher_request *areq,
> +			   void (*callback) (struct device *dev,
> +					     struct talitos_desc *desc,
> +					     void *context, int error))
> +{
> +	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	struct device *dev = ctx->dev;
> +	struct talitos_desc *desc = &edesc->desc;
> +	unsigned int cryptlen = areq->cryptlen;
> +	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> +	int sg_count, ret;
> +	bool sync_needed = false;
> +	struct talitos_private *priv = dev_get_drvdata(dev);
> +	bool is_sec1 = has_ftr_sec1(priv);
> +	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
> +		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
> +
> +	/* first DWORD empty */
> +
> +	/* cipher iv */
> +	to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
> +
> +	/* cipher key */
> +	to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
> +
> +	sg_count = edesc->src_nents ?: 1;
> +	if (is_sec1 && sg_count > 1)
> +		sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
> +				  cryptlen);
> +	else
> +		sg_count = dma_map_sg(dev, areq->src, sg_count,
> +				      (areq->src == areq->dst) ?
> +				      DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
> +	/*
> +	 * cipher in
> +	 */
> +	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
> +				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
> +	if (sg_count > 1)
> +		sync_needed = true;
> +
> +	/* cipher out */
> +	if (areq->src != areq->dst) {
> +		sg_count = edesc->dst_nents ? : 1;
> +		if (!is_sec1 || sg_count == 1)
> +			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
> +	}
> +
> +	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
> +			     sg_count, 0, (edesc->src_nents + 1));
> +	if (ret > 1)
> +		sync_needed = true;
> +
> +	/* iv out */
> +	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
> +			       DMA_FROM_DEVICE);
> +
> +	/* last DWORD empty */
> +
> +	if (sync_needed)
> +		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
> +					   edesc->dma_len, DMA_BIDIRECTIONAL);
> +
> +	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
> +	if (ret != -EINPROGRESS) {
> +		common_nonsnoop_unmap(dev, edesc, areq);
> +		kfree(edesc);
> +	}
> +	return ret;
> +}
> +
> +static int skcipher_setkey(struct crypto_skcipher *cipher,
> +			     const u8 *key, unsigned int keylen)
> +{
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	struct device *dev = ctx->dev;
> +
> +	if (ctx->keylen)
> +		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
> +
> +	memcpy(&ctx->key, key, keylen);
> +	ctx->keylen = keylen;
> +
> +	ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
> +
> +	return 0;
> +}
> +
> +static int skcipher_des_setkey(struct crypto_skcipher *cipher,
> +				 const u8 *key, unsigned int keylen)
> +{
> +	return verify_skcipher_des_key(cipher, key) ?:
> +	       skcipher_setkey(cipher, key, keylen);
> +}
> +
> +static int skcipher_des3_setkey(struct crypto_skcipher *cipher,
> +				  const u8 *key, unsigned int keylen)
> +{
> +	return verify_skcipher_des3_key(cipher, key) ?:
> +	       skcipher_setkey(cipher, key, keylen);
> +}
> +
> +static int skcipher_aes_setkey(struct crypto_skcipher *cipher,
> +				  const u8 *key, unsigned int keylen)
> +{
> +	if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
> +	    keylen == AES_KEYSIZE_256)
> +		return skcipher_setkey(cipher, key, keylen);
> +
> +	return -EINVAL;
> +}
> +
> +static struct talitos_edesc *skcipher_edesc_alloc(struct skcipher_request *
> +						    areq, bool encrypt)
> +{
> +	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> +
> +	return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
> +				   areq->iv, 0, areq->cryptlen, 0, ivsize, 0,
> +				   areq->base.flags, encrypt);
> +}
> +
> +static int skcipher_encrypt(struct skcipher_request *areq)
> +{
> +	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	struct talitos_edesc *edesc;
> +	unsigned int blocksize =
> +			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
> +
> +	if (!areq->cryptlen)
> +		return 0;
> +
> +	if (areq->cryptlen % blocksize)
> +		return -EINVAL;
> +
> +	/* allocate extended descriptor */
> +	edesc = skcipher_edesc_alloc(areq, true);
> +	if (IS_ERR(edesc))
> +		return PTR_ERR(edesc);
> +
> +	/* set encrypt */
> +	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
> +
> +	return common_nonsnoop(edesc, areq, skcipher_done);
> +}
> +
> +static int skcipher_decrypt(struct skcipher_request *areq)
> +{
> +	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> +	struct talitos_edesc *edesc;
> +	unsigned int blocksize =
> +			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
> +
> +	if (!areq->cryptlen)
> +		return 0;
> +
> +	if (areq->cryptlen % blocksize)
> +		return -EINVAL;
> +
> +	/* allocate extended descriptor */
> +	edesc = skcipher_edesc_alloc(areq, false);
> +	if (IS_ERR(edesc))
> +		return PTR_ERR(edesc);
> +
> +	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
> +
> +	return common_nonsnoop(edesc, areq, skcipher_done);
> +}
> +
> +static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
> +{
> +	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> +	struct talitos_crypto_alg *talitos_alg;
> +	struct talitos_ctx *ctx = crypto_skcipher_ctx(tfm);
> +
> +	talitos_alg = container_of(alg, struct talitos_crypto_alg,
> +				   algt.alg.skcipher);
> +
> +	return talitos_init_common(ctx, talitos_alg);
> +}
> +
> +static struct talitos_alg_template skcipher_driver_algs[] = {
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "ecb(aes)",
> +			.base.cra_driver_name = "ecb-aes-talitos",
> +			.base.cra_blocksize = AES_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = AES_MIN_KEY_SIZE,
> +			.max_keysize = AES_MAX_KEY_SIZE,
> +			.setkey = skcipher_aes_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_AESU,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "cbc(aes)",
> +			.base.cra_driver_name = "cbc-aes-talitos",
> +			.base.cra_blocksize = AES_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = AES_MIN_KEY_SIZE,
> +			.max_keysize = AES_MAX_KEY_SIZE,
> +			.ivsize = AES_BLOCK_SIZE,
> +			.setkey = skcipher_aes_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_AESU |
> +				     DESC_HDR_MODE0_AESU_CBC,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "ctr(aes)",
> +			.base.cra_driver_name = "ctr-aes-talitos",
> +			.base.cra_blocksize = 1,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = AES_MIN_KEY_SIZE,
> +			.max_keysize = AES_MAX_KEY_SIZE,
> +			.ivsize = AES_BLOCK_SIZE,
> +			.setkey = skcipher_aes_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
> +				     DESC_HDR_SEL0_AESU |
> +				     DESC_HDR_MODE0_AESU_CTR,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "ctr(aes)",
> +			.base.cra_driver_name = "ctr-aes-talitos",
> +			.base.cra_blocksize = 1,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = AES_MIN_KEY_SIZE,
> +			.max_keysize = AES_MAX_KEY_SIZE,
> +			.ivsize = AES_BLOCK_SIZE,
> +			.setkey = skcipher_aes_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_AESU |
> +				     DESC_HDR_MODE0_AESU_CTR,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "ecb(des)",
> +			.base.cra_driver_name = "ecb-des-talitos",
> +			.base.cra_blocksize = DES_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = DES_KEY_SIZE,
> +			.max_keysize = DES_KEY_SIZE,
> +			.setkey = skcipher_des_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_DEU,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "cbc(des)",
> +			.base.cra_driver_name = "cbc-des-talitos",
> +			.base.cra_blocksize = DES_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = DES_KEY_SIZE,
> +			.max_keysize = DES_KEY_SIZE,
> +			.ivsize = DES_BLOCK_SIZE,
> +			.setkey = skcipher_des_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_DEU |
> +				     DESC_HDR_MODE0_DEU_CBC,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "ecb(des3_ede)",
> +			.base.cra_driver_name = "ecb-3des-talitos",
> +			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = DES3_EDE_KEY_SIZE,
> +			.max_keysize = DES3_EDE_KEY_SIZE,
> +			.setkey = skcipher_des3_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_DEU |
> +				     DESC_HDR_MODE0_DEU_3DES,
> +	},
> +	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +		.alg.skcipher = {
> +			.base.cra_name = "cbc(des3_ede)",
> +			.base.cra_driver_name = "cbc-3des-talitos",
> +			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
> +			.base.cra_flags = CRYPTO_ALG_ASYNC |
> +					  CRYPTO_ALG_ALLOCATES_MEMORY,
> +			.min_keysize = DES3_EDE_KEY_SIZE,
> +			.max_keysize = DES3_EDE_KEY_SIZE,
> +			.ivsize = DES3_EDE_BLOCK_SIZE,
> +			.setkey = skcipher_des3_setkey,
> +		},
> +		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> +				     DESC_HDR_SEL0_DEU |
> +				     DESC_HDR_MODE0_DEU_CBC |
> +				     DESC_HDR_MODE0_DEU_3DES,
> +	},
> +};
> +
> +int talitos_register_skcipher(struct device *dev)
> +{
> +	struct talitos_private *priv = dev_get_drvdata(dev);
> +	struct skcipher_alg *skcipher_alg;
> +	struct crypto_alg *alg;
> +	size_t i;
> +	int ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(skcipher_driver_algs); i++) {
> +		if (!talitos_hw_supports(
> +			    dev, skcipher_driver_algs[i].desc_hdr_template))
> +			continue;
> +
> +		skcipher_alg = &skcipher_driver_algs[i].alg.skcipher;
> +		alg = &skcipher_alg->base;
> +
> +		alg->cra_exit = talitos_cra_exit;
> +		if (has_ftr_sec1(priv))
> +			alg->cra_alignmask = 3;
> +
> +		skcipher_alg->init = talitos_cra_init_skcipher;
> +		skcipher_alg->setkey = skcipher_alg->setkey ?: skcipher_setkey;
> +		skcipher_alg->encrypt = skcipher_encrypt;
> +		skcipher_alg->decrypt = skcipher_decrypt;
> +
> +		if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
> +		    DESC_TYPE(skcipher_driver_algs[i].desc_hdr_template) !=
> +			    DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
> +			continue;
> +		}
> +
> +		ret = talitos_register_common(dev, &skcipher_driver_algs[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
> index 2d5688b1c81e..4b77253e04fa 100644
> --- a/drivers/crypto/talitos/talitos.c
> +++ b/drivers/crypto/talitos/talitos.c
> @@ -1337,215 +1337,6 @@ static int aead_decrypt(struct aead_request *req)
>   	return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done);
>   }
>   
> -static int skcipher_setkey(struct crypto_skcipher *cipher,
> -			     const u8 *key, unsigned int keylen)
> -{
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	struct device *dev = ctx->dev;
> -
> -	if (ctx->keylen)
> -		dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
> -
> -	memcpy(&ctx->key, key, keylen);
> -	ctx->keylen = keylen;
> -
> -	ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
> -
> -	return 0;
> -}
> -
> -static int skcipher_des_setkey(struct crypto_skcipher *cipher,
> -				 const u8 *key, unsigned int keylen)
> -{
> -	return verify_skcipher_des_key(cipher, key) ?:
> -	       skcipher_setkey(cipher, key, keylen);
> -}
> -
> -static int skcipher_des3_setkey(struct crypto_skcipher *cipher,
> -				  const u8 *key, unsigned int keylen)
> -{
> -	return verify_skcipher_des3_key(cipher, key) ?:
> -	       skcipher_setkey(cipher, key, keylen);
> -}
> -
> -static int skcipher_aes_setkey(struct crypto_skcipher *cipher,
> -				  const u8 *key, unsigned int keylen)
> -{
> -	if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
> -	    keylen == AES_KEYSIZE_256)
> -		return skcipher_setkey(cipher, key, keylen);
> -
> -	return -EINVAL;
> -}
> -
> -static void common_nonsnoop_unmap(struct device *dev,
> -				  struct talitos_edesc *edesc,
> -				  struct skcipher_request *areq)
> -{
> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
> -
> -	talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
> -	unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
> -
> -	if (edesc->dma_len)
> -		dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
> -				 DMA_BIDIRECTIONAL);
> -}
> -
> -static void skcipher_done(struct device *dev,
> -			    struct talitos_desc *desc, void *context,
> -			    int err)
> -{
> -	struct skcipher_request *areq = context;
> -	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> -	struct talitos_edesc *edesc;
> -
> -	edesc = container_of(desc, struct talitos_edesc, desc);
> -
> -	common_nonsnoop_unmap(dev, edesc, areq);
> -	memcpy(areq->iv, ctx->iv, ivsize);
> -
> -	kfree(edesc);
> -
> -	skcipher_request_complete(areq, err);
> -}
> -
> -static int common_nonsnoop(struct talitos_edesc *edesc,
> -			   struct skcipher_request *areq,
> -			   void (*callback) (struct device *dev,
> -					     struct talitos_desc *desc,
> -					     void *context, int error))
> -{
> -	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	struct device *dev = ctx->dev;
> -	struct talitos_desc *desc = &edesc->desc;
> -	unsigned int cryptlen = areq->cryptlen;
> -	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> -	int sg_count, ret;
> -	bool sync_needed = false;
> -	struct talitos_private *priv = dev_get_drvdata(dev);
> -	bool is_sec1 = has_ftr_sec1(priv);
> -	bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
> -		      (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
> -
> -	/* first DWORD empty */
> -
> -	/* cipher iv */
> -	to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
> -
> -	/* cipher key */
> -	to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
> -
> -	sg_count = edesc->src_nents ?: 1;
> -	if (is_sec1 && sg_count > 1)
> -		sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
> -				  cryptlen);
> -	else
> -		sg_count = dma_map_sg(dev, areq->src, sg_count,
> -				      (areq->src == areq->dst) ?
> -				      DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
> -	/*
> -	 * cipher in
> -	 */
> -	sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
> -				      sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
> -	if (sg_count > 1)
> -		sync_needed = true;
> -
> -	/* cipher out */
> -	if (areq->src != areq->dst) {
> -		sg_count = edesc->dst_nents ? : 1;
> -		if (!is_sec1 || sg_count == 1)
> -			dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
> -	}
> -
> -	ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
> -			     sg_count, 0, (edesc->src_nents + 1));
> -	if (ret > 1)
> -		sync_needed = true;
> -
> -	/* iv out */
> -	map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
> -			       DMA_FROM_DEVICE);
> -
> -	/* last DWORD empty */
> -
> -	if (sync_needed)
> -		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
> -					   edesc->dma_len, DMA_BIDIRECTIONAL);
> -
> -	ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
> -	if (ret != -EINPROGRESS) {
> -		common_nonsnoop_unmap(dev, edesc, areq);
> -		kfree(edesc);
> -	}
> -	return ret;
> -}
> -
> -static struct talitos_edesc *skcipher_edesc_alloc(struct skcipher_request *
> -						    areq, bool encrypt)
> -{
> -	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	unsigned int ivsize = crypto_skcipher_ivsize(cipher);
> -
> -	return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
> -				   areq->iv, 0, areq->cryptlen, 0, ivsize, 0,
> -				   areq->base.flags, encrypt);
> -}
> -
> -static int skcipher_encrypt(struct skcipher_request *areq)
> -{
> -	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	struct talitos_edesc *edesc;
> -	unsigned int blocksize =
> -			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
> -
> -	if (!areq->cryptlen)
> -		return 0;
> -
> -	if (areq->cryptlen % blocksize)
> -		return -EINVAL;
> -
> -	/* allocate extended descriptor */
> -	edesc = skcipher_edesc_alloc(areq, true);
> -	if (IS_ERR(edesc))
> -		return PTR_ERR(edesc);
> -
> -	/* set encrypt */
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
> -
> -	return common_nonsnoop(edesc, areq, skcipher_done);
> -}
> -
> -static int skcipher_decrypt(struct skcipher_request *areq)
> -{
> -	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
> -	struct talitos_edesc *edesc;
> -	unsigned int blocksize =
> -			crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
> -
> -	if (!areq->cryptlen)
> -		return 0;
> -
> -	if (areq->cryptlen % blocksize)
> -		return -EINVAL;
> -
> -	/* allocate extended descriptor */
> -	edesc = skcipher_edesc_alloc(areq, false);
> -	if (IS_ERR(edesc))
> -		return PTR_ERR(edesc);
> -
> -	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
> -
> -	return common_nonsnoop(edesc, areq, skcipher_done);
> -}
> -
>   static struct talitos_alg_template driver_algs[] = {
>   	/* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
>   	{	.type = CRYPTO_ALG_TYPE_AEAD,
> @@ -2004,131 +1795,6 @@ static struct talitos_alg_template driver_algs[] = {
>   				     DESC_HDR_MODE1_MDEU_PAD |
>   				     DESC_HDR_MODE1_MDEU_MD5_HMAC,
>   	},
> -	/* SKCIPHER algorithms. */
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "ecb(aes)",
> -			.base.cra_driver_name = "ecb-aes-talitos",
> -			.base.cra_blocksize = AES_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = AES_MIN_KEY_SIZE,
> -			.max_keysize = AES_MAX_KEY_SIZE,
> -			.setkey = skcipher_aes_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_AESU,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "cbc(aes)",
> -			.base.cra_driver_name = "cbc-aes-talitos",
> -			.base.cra_blocksize = AES_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = AES_MIN_KEY_SIZE,
> -			.max_keysize = AES_MAX_KEY_SIZE,
> -			.ivsize = AES_BLOCK_SIZE,
> -			.setkey = skcipher_aes_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_AESU |
> -				     DESC_HDR_MODE0_AESU_CBC,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "ctr(aes)",
> -			.base.cra_driver_name = "ctr-aes-talitos",
> -			.base.cra_blocksize = 1,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = AES_MIN_KEY_SIZE,
> -			.max_keysize = AES_MAX_KEY_SIZE,
> -			.ivsize = AES_BLOCK_SIZE,
> -			.setkey = skcipher_aes_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
> -				     DESC_HDR_SEL0_AESU |
> -				     DESC_HDR_MODE0_AESU_CTR,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "ctr(aes)",
> -			.base.cra_driver_name = "ctr-aes-talitos",
> -			.base.cra_blocksize = 1,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = AES_MIN_KEY_SIZE,
> -			.max_keysize = AES_MAX_KEY_SIZE,
> -			.ivsize = AES_BLOCK_SIZE,
> -			.setkey = skcipher_aes_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_AESU |
> -				     DESC_HDR_MODE0_AESU_CTR,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "ecb(des)",
> -			.base.cra_driver_name = "ecb-des-talitos",
> -			.base.cra_blocksize = DES_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = DES_KEY_SIZE,
> -			.max_keysize = DES_KEY_SIZE,
> -			.setkey = skcipher_des_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_DEU,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "cbc(des)",
> -			.base.cra_driver_name = "cbc-des-talitos",
> -			.base.cra_blocksize = DES_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = DES_KEY_SIZE,
> -			.max_keysize = DES_KEY_SIZE,
> -			.ivsize = DES_BLOCK_SIZE,
> -			.setkey = skcipher_des_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_DEU |
> -				     DESC_HDR_MODE0_DEU_CBC,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "ecb(des3_ede)",
> -			.base.cra_driver_name = "ecb-3des-talitos",
> -			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = DES3_EDE_KEY_SIZE,
> -			.max_keysize = DES3_EDE_KEY_SIZE,
> -			.setkey = skcipher_des3_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -				     DESC_HDR_SEL0_DEU |
> -				     DESC_HDR_MODE0_DEU_3DES,
> -	},
> -	{	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -		.alg.skcipher = {
> -			.base.cra_name = "cbc(des3_ede)",
> -			.base.cra_driver_name = "cbc-3des-talitos",
> -			.base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
> -			.base.cra_flags = CRYPTO_ALG_ASYNC |
> -					  CRYPTO_ALG_ALLOCATES_MEMORY,
> -			.min_keysize = DES3_EDE_KEY_SIZE,
> -			.max_keysize = DES3_EDE_KEY_SIZE,
> -			.ivsize = DES3_EDE_BLOCK_SIZE,
> -			.setkey = skcipher_des3_setkey,
> -		},
> -		.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
> -			             DESC_HDR_SEL0_DEU |
> -		                     DESC_HDR_MODE0_DEU_CBC |
> -		                     DESC_HDR_MODE0_DEU_3DES,
> -	},
>   };
>   
>   int talitos_init_common(struct talitos_ctx *ctx,
> @@ -2165,18 +1831,6 @@ static int talitos_cra_init_aead(struct crypto_aead *tfm)
>   	return talitos_init_common(ctx, talitos_alg);
>   }
>   
> -static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
> -{
> -	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> -	struct talitos_crypto_alg *talitos_alg;
> -	struct talitos_ctx *ctx = crypto_skcipher_ctx(tfm);
> -
> -	talitos_alg = container_of(alg, struct talitos_crypto_alg,
> -				   algt.alg.skcipher);
> -
> -	return talitos_init_common(ctx, talitos_alg);
> -}
> -
>   void talitos_cra_exit(struct crypto_tfm *tfm)
>   {
>   	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
> @@ -2281,6 +1935,12 @@ int talitos_register_common(struct device *dev,
>   				       t_alg->algt.type);
>   		ret = crypto_register_ahash(&t_alg->algt.alg.hash);
>   		break;
> +	case CRYPTO_ALG_TYPE_SKCIPHER:
> +		alg = &t_alg->algt.alg.skcipher.base;
> +		talitos_alg_set_common(priv, alg, t_alg->algt.priority,
> +				       t_alg->algt.type);
> +		ret = crypto_register_skcipher(&t_alg->algt.alg.skcipher);
> +		break;
>   	default:
>   		dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
>   		devm_kfree(dev, t_alg);
> @@ -2317,21 +1977,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
>   	t_alg->algt = *template;
>   
>   	switch (t_alg->algt.type) {
> -	case CRYPTO_ALG_TYPE_SKCIPHER:
> -		alg = &t_alg->algt.alg.skcipher.base;
> -		alg->cra_exit = talitos_cra_exit;
> -		t_alg->algt.alg.skcipher.init = talitos_cra_init_skcipher;
> -		t_alg->algt.alg.skcipher.setkey =
> -			t_alg->algt.alg.skcipher.setkey ?: skcipher_setkey;
> -		t_alg->algt.alg.skcipher.encrypt = skcipher_encrypt;
> -		t_alg->algt.alg.skcipher.decrypt = skcipher_decrypt;
> -		if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
> -		    DESC_TYPE(t_alg->algt.desc_hdr_template) !=
> -		    DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
> -			devm_kfree(dev, t_alg);
> -			return ERR_PTR(-ENOTSUPP);
> -		}
> -		break;
>   	case CRYPTO_ALG_TYPE_AEAD:
>   		alg = &t_alg->algt.alg.aead.base;
>   		alg->cra_exit = talitos_cra_exit;
> @@ -2578,6 +2223,10 @@ static int talitos_probe(struct platform_device *ofdev)
>   	if (err)
>   		goto err_out;
>   
> +	err = talitos_register_skcipher(dev);
> +	if (err)
> +		goto err_out;
> +
>   	/* register crypto algorithms the device supports */
>   	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
>   		if (talitos_hw_supports(dev,
> @@ -2594,12 +2243,6 @@ static int talitos_probe(struct platform_device *ofdev)
>   			}
>   
>   			switch (t_alg->algt.type) {
> -			case CRYPTO_ALG_TYPE_SKCIPHER:
> -				err = crypto_register_skcipher(
> -						&t_alg->algt.alg.skcipher);
> -				alg = &t_alg->algt.alg.skcipher.base;
> -				break;
> -
>   			case CRYPTO_ALG_TYPE_AEAD:
>   				err = crypto_register_aead(
>   					&t_alg->algt.alg.aead);
> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
> index e59c85e3196c..4a803ad6349d 100644
> --- a/drivers/crypto/talitos/talitos.h
> +++ b/drivers/crypto/talitos/talitos.h
> @@ -610,3 +610,4 @@ void talitos_unregister_rng(struct device *dev);
>   /* Hash */
>   
>   int talitos_register_hash(struct device *dev);
> +int talitos_register_skcipher(struct device *dev);
>
-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 00/19] crypto: talitos - Driver cleanup
@ 2026-07-21 13:43 Paul Louvel
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:43 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

The Freescale Integrated Security Engine (SEC) aka "Talitos" driver
implementation is a monolithic ~3800-line file that mixes SEC1 and SEC2
hardware variants with hash, skcipher, aead and hwrng algorithm.

This series reorganises the driver to improve readability and
maintainability:

- Split the driver into a dedicated directory with separate files for
  hash, skcipher, aead, and hwrng implementations.

- Modernise the crypto API usage: adopt {init,exit}_tfm (deprecated
  cra_init/cra_exit), use CRYPTO_AHASH_ALG_BLOCK_ONLY to eliminate
  manual partial-block buffering, and use macros to deduplicate
  algorithm definitions.

- Introduce a is_sec1() helper to get rid of is_sec1 variables /
  parameters.

- Define descriptor/pointer structures for each hardware version,
  instead of using a single structure and anonymous union.

No functional changes are intended except for patch 1.

This series depends on the "crypto: talitos - bug fixes" series :
https://patch.msgid.link/20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
Changes in v3:
- Upon Herbert's remark on FINAL_NONZERO flag not working with algorithms
  like md5, I removed the flag entirely for all algorithms.
  Only the SEC1 revision is buggy when sending 0 byte descriptor
  : the hardware yield an error. On the SEC2, this bug is not present
  and can accept zero byte descriptor if the hardware auto-pad.
  This bug is mitigated for SEC1 with software padding in
  talitos_handle_buggy_hash().
  It had to be slightly change in PATCH 1 because of the removal of
  FINAL_NONZERO : the message length in bits was always zero. Now, a
  zero byte request can happen after a handful of non-zero byte
  requests.
  Keep track of the message length in the request context, and put the
  message length in bits as a 64-bit big endian integer at the end of
  the padding.
  Allocate a buffer per ahash request instead of using a static buffer,
  since it is now written to.
- Link to v2: https://patch.msgid.link/20260611-7-1-rc1_talitos_cleanup-v2-0-aa4a813ce69b@bootlin.com

Changes in v2:
- Fixed compilation warnings and errors.
- Instead of using ops to dispatch SEC1/SEC2 variants, keep the small
  helpers, and introduce is_sec1() inline function that can use static
  key branching in case both hardware version are compiled.
- Dropped the SEC1/SEC2 function variants inside the core driver file.
- Reworded the cover letter for clarity.
- Link to v1: https://patch.msgid.link/20260528-7-1-rc1_talitos_cleanup-v1-0-cb1ad6cdea49@bootlin.com

To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
Cc: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Paul Louvel (19):
      crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API
      crypto: talitos - Move driver into dedicated directory
      crypto: talitos - Add missing includes to driver header file
      crypto: talitos/hwrng - Move into separate file
      crypto: talitos - Prepare crypto implementation file splitting
      crypto: talitos/hash - Move into separate file
      crypto: talitos/skcipher - Move into separate file
      crypto: talitos/aead - Move into separate file
      crypto: talitos/hash - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/skcipher - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/aead - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/hash - Use macro for algorithm definitions
      crypto: talitos/skcipher - Use macro for algorithm definitions
      crypto: talitos/aead - Use macro for algorithm definitions
      crypto: talitos - Remove alg settings in talitos_register_common()
      crypto: talitos - Introduce is_sec1() helper with static key support
      crypto: talitos - Replace has_ftr_sec1() with is_sec1() static key helper
      crypto: talitos - Introduce per-SEC-version descriptor and pointer structures
      crypto: talitos - Remove TALITOS_DESC_SIZE macro

 drivers/crypto/Kconfig                    |   38 +-
 drivers/crypto/Makefile                   |    2 +-
 drivers/crypto/talitos.c                  | 3640 -----------------------------
 drivers/crypto/talitos/Kconfig            |   36 +
 drivers/crypto/talitos/Makefile           |    3 +
 drivers/crypto/talitos/talitos-aead.c     |  657 ++++++
 drivers/crypto/talitos/talitos-hash.c     |  695 ++++++
 drivers/crypto/talitos/talitos-rng.c      |   93 +
 drivers/crypto/talitos/talitos-skcipher.c |  356 +++
 drivers/crypto/talitos/talitos.c          | 1337 +++++++++++
 drivers/crypto/{ => talitos}/talitos.h    |  316 ++-
 11 files changed, 3467 insertions(+), 3706 deletions(-)
---
base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
change-id: 20260518-7-1-rc1_talitos_cleanup-9231a64e29fa
prerequisite-change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc:v3
prerequisite-patch-id: 7b364911e4b8d1c1033eb14e67ed24dac6a4bc13
prerequisite-patch-id: 2c1cd7fdd003d9a116a697efa25d1716d548389f
prerequisite-patch-id: b12bdbf565747609e0cfe0609a42cf69b5d816a1
prerequisite-patch-id: 72cb2bc0fc2a48a5a029b049c199f4c86085cf04
prerequisite-patch-id: 5f1f5ad6add760161bd48875df48c0893aa12613
prerequisite-patch-id: 934931086968229434d15a2f2358aeb7e6975a1d
prerequisite-patch-id: 8a0b4828fc0690e0c841bc9adcc6568bb522e0e8
prerequisite-patch-id: 1d870f32e7dbf9a8bd3b8979558544107693e0f4
prerequisite-patch-id: 758c18d7c9fabb14bd90df62e5e8a62a6f880db4
prerequisite-patch-id: ce6e9e585f8edc1861ae6bb8fbdd836c20cbd290
prerequisite-patch-id: 9446dc03e442ea81c5f5b39e802e01b37da29971

Best regards,
--  
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 00/19] crypto: talitos - Driver cleanup
  2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
                   ` (6 preceding siblings ...)
  2026-07-21 13:40 ` [PATCH v3 07/19] crypto: talitos/skcipher " Paul Louvel
@ 2026-07-21 13:54 ` Paul Louvel
  7 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:54 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel

Hi,

Sorry, I forgot to write and close by cover letter before sending it --'

On 7/21/26 3:40 PM, Paul Louvel wrote:
> The Freescale Integrated Security Engine (SEC) aka "Talitos" driver
> implementation is a monolithic ~3800-line file that mixes SEC1 and SEC2
> hardware variants with hash, skcipher, aead and hwrng algorithm.
>
> This series reorganises the driver to improve readability and
> maintainability:
>
> - Split the driver into a dedicated directory with separate files for
>    hash, skcipher, aead, and hwrng implementations.
>
> - Modernise the crypto API usage: adopt {init,exit}_tfm (deprecated
>    cra_init/cra_exit), use CRYPTO_AHASH_ALG_BLOCK_ONLY to eliminate
>    manual partial-block buffering, and use macros to deduplicate
>    algorithm definitions.
>
> - Introduce a is_sec1() helper to get rid of is_sec1 variables /
>    parameters.
>
> - Define descriptor/pointer structures for each hardware version,
>    instead of using a single structure and anonymous union.
>
> No functional changes are intended except for patch 1.
>
> This series depends on the "crypto: talitos - bug fixes" series :
> https://patch.msgid.link/20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com
>
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
> Changes in v3:
> - EDITME: describe what is new in this series revision.
> - EDITME: use bulletpoints and terse descriptions.
> - Link to v2: https://patch.msgid.link/20260611-7-1-rc1_talitos_cleanup-v2-0-aa4a813ce69b@bootlin.com
>
> Changes in v2:
> - Fixed compilation warnings and errors.
> - Instead of using ops to dispatch SEC1/SEC2 variants, keep the small
>    helpers, and introduce is_sec1() inline function that can use static
>    key branching in case both hardware version are compiled.
> - Dropped the SEC1/SEC2 function variants inside the core driver file.
> - Reworded the cover letter for clarity.
> - Link to v1: https://patch.msgid.link/20260528-7-1-rc1_talitos_cleanup-v1-0-cb1ad6cdea49@bootlin.com
>
> To: Herbert Xu <herbert@gondor.apana.org.au>
> To: "David S. Miller" <davem@davemloft.net>
> Cc: linux-crypto@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
>
> ---
> Paul Louvel (19):
>        crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API
>        crypto: talitos - Move driver into dedicated directory
>        crypto: talitos - Add missing includes to driver header file
>        crypto: talitos/hwrng - Move into separate file
>        crypto: talitos - Prepare crypto implementation file splitting
>        crypto: talitos/hash - Move into separate file
>        crypto: talitos/skcipher - Move into separate file
>        crypto: talitos/aead - Move into separate file
>        crypto: talitos/hash - Convert to {init,exit}_tfm type-specific API
>        crypto: talitos/skcipher - Convert to {init,exit}_tfm type-specific API
>        crypto: talitos/aead - Convert to {init,exit}_tfm type-specific API
>        crypto: talitos/hash - Use macro for algorithm definitions
>        crypto: talitos/skcipher - Use macro for algorithm definitions
>        crypto: talitos/aead - Use macro for algorithm definitions
>        crypto: talitos - Remove alg settings in talitos_register_common()
>        crypto: talitos - Introduce is_sec1() helper with static key support
>        crypto: talitos - Replace has_ftr_sec1() with is_sec1() static key helper
>        crypto: talitos - Introduce per-SEC-version descriptor and pointer structures
>        crypto: talitos - Remove TALITOS_DESC_SIZE macro
>
>   drivers/crypto/Kconfig                    |   38 +-
>   drivers/crypto/Makefile                   |    2 +-
>   drivers/crypto/talitos.c                  | 3640 -----------------------------
>   drivers/crypto/talitos/Kconfig            |   36 +
>   drivers/crypto/talitos/Makefile           |    3 +
>   drivers/crypto/talitos/talitos-aead.c     |  657 ++++++
>   drivers/crypto/talitos/talitos-hash.c     |  695 ++++++
>   drivers/crypto/talitos/talitos-rng.c      |   93 +
>   drivers/crypto/talitos/talitos-skcipher.c |  356 +++
>   drivers/crypto/talitos/talitos.c          | 1337 +++++++++++
>   drivers/crypto/{ => talitos}/talitos.h    |  316 ++-
>   11 files changed, 3467 insertions(+), 3706 deletions(-)
> ---
> base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
> change-id: 20260518-7-1-rc1_talitos_cleanup-9231a64e29fa
> prerequisite-change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc:v3
> prerequisite-patch-id: 7b364911e4b8d1c1033eb14e67ed24dac6a4bc13
> prerequisite-patch-id: 2c1cd7fdd003d9a116a697efa25d1716d548389f
> prerequisite-patch-id: b12bdbf565747609e0cfe0609a42cf69b5d816a1
> prerequisite-patch-id: 72cb2bc0fc2a48a5a029b049c199f4c86085cf04
> prerequisite-patch-id: 5f1f5ad6add760161bd48875df48c0893aa12613
> prerequisite-patch-id: 934931086968229434d15a2f2358aeb7e6975a1d
> prerequisite-patch-id: 8a0b4828fc0690e0c841bc9adcc6568bb522e0e8
> prerequisite-patch-id: 1d870f32e7dbf9a8bd3b8979558544107693e0f4
> prerequisite-patch-id: 758c18d7c9fabb14bd90df62e5e8a62a6f880db4
> prerequisite-patch-id: ce6e9e585f8edc1861ae6bb8fbdd836c20cbd290
> prerequisite-patch-id: 9446dc03e442ea81c5f5b39e802e01b37da29971
>
> Best regards,
> --
> Paul Louvel, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
-- 
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 00/19] crypto: talitos - Driver cleanup
@ 2026-07-21 13:59 Paul Louvel
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Louvel @ 2026-07-21 13:59 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller
  Cc: Thomas Petazzoni, Herve Codina, Christophe Leroy, linux-crypto,
	linux-kernel, Paul Louvel

The Freescale Integrated Security Engine (SEC) aka "Talitos" driver
implementation is a monolithic ~3800-line file that mixes SEC1 and SEC2
hardware variants with hash, skcipher, aead and hwrng algorithm.

This series reorganises the driver to improve readability and
maintainability:

- Split the driver into a dedicated directory with separate files for
  hash, skcipher, aead, and hwrng implementations.

- Modernise the crypto API usage: adopt {init,exit}_tfm (deprecated
  cra_init/cra_exit), use CRYPTO_AHASH_ALG_BLOCK_ONLY to eliminate
  manual partial-block buffering, and use macros to deduplicate
  algorithm definitions.

- Introduce a is_sec1() helper to get rid of is_sec1 variables /
  parameters.

- Define descriptor/pointer structures for each hardware version,
  instead of using a single structure and anonymous union.

No functional changes are intended except for patch 1.

This series depends on the "crypto: talitos - bug fixes" series :
https://patch.msgid.link/20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com

Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
Changes in v3:
- Upon Herbert's remark on FINAL_NONZERO flag not working with algorithms
  like md5, I removed the flag entirely for all algorithms.
  Only the SEC1 revision is buggy when sending 0 byte descriptor
  : the hardware yield an error. On the SEC2, this bug is not present
  and can accept zero byte descriptor if the hardware auto-pad.
  This bug is mitigated for SEC1 with software padding in
  talitos_handle_buggy_hash().
  It had to be slightly change in PATCH 1 because of the removal of
  FINAL_NONZERO : the message length in bits was always zero. Now, a
  zero byte request can happen after a handful of non-zero byte
  requests.
  Keep track of the message length in the request context, and put the
  message length in bits as a 64-bit big endian integer at the end of
  the padding.
  Allocate a buffer per ahash request instead of using a static buffer,
  since it is now written to.
- Link to v2: https://patch.msgid.link/20260611-7-1-rc1_talitos_cleanup-v2-0-aa4a813ce69b@bootlin.com

Changes in v2:
- Fixed compilation warnings and errors.
- Instead of using ops to dispatch SEC1/SEC2 variants, keep the small
  helpers, and introduce is_sec1() inline function that can use static
  key branching in case both hardware version are compiled.
- Dropped the SEC1/SEC2 function variants inside the core driver file.
- Reworded the cover letter for clarity.
- Link to v1: https://patch.msgid.link/20260528-7-1-rc1_talitos_cleanup-v1-0-cb1ad6cdea49@bootlin.com

To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
Cc: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Paul Louvel (19):
      crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API
      crypto: talitos - Move driver into dedicated directory
      crypto: talitos - Add missing includes to driver header file
      crypto: talitos/hwrng - Move into separate file
      crypto: talitos - Prepare crypto implementation file splitting
      crypto: talitos/hash - Move into separate file
      crypto: talitos/skcipher - Move into separate file
      crypto: talitos/aead - Move into separate file
      crypto: talitos/hash - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/skcipher - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/aead - Convert to {init,exit}_tfm type-specific API
      crypto: talitos/hash - Use macro for algorithm definitions
      crypto: talitos/skcipher - Use macro for algorithm definitions
      crypto: talitos/aead - Use macro for algorithm definitions
      crypto: talitos - Remove alg settings in talitos_register_common()
      crypto: talitos - Introduce is_sec1() helper with static key support
      crypto: talitos - Replace has_ftr_sec1() with is_sec1() static key helper
      crypto: talitos - Introduce per-SEC-version descriptor and pointer structures
      crypto: talitos - Remove TALITOS_DESC_SIZE macro

 drivers/crypto/Kconfig                    |   38 +-
 drivers/crypto/Makefile                   |    2 +-
 drivers/crypto/talitos.c                  | 3640 -----------------------------
 drivers/crypto/talitos/Kconfig            |   36 +
 drivers/crypto/talitos/Makefile           |    3 +
 drivers/crypto/talitos/talitos-aead.c     |  657 ++++++
 drivers/crypto/talitos/talitos-hash.c     |  695 ++++++
 drivers/crypto/talitos/talitos-rng.c      |   93 +
 drivers/crypto/talitos/talitos-skcipher.c |  356 +++
 drivers/crypto/talitos/talitos.c          | 1337 +++++++++++
 drivers/crypto/{ => talitos}/talitos.h    |  316 ++-
 11 files changed, 3467 insertions(+), 3706 deletions(-)
---
base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
change-id: 20260518-7-1-rc1_talitos_cleanup-9231a64e29fa
prerequisite-change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc:v3
prerequisite-patch-id: 7b364911e4b8d1c1033eb14e67ed24dac6a4bc13
prerequisite-patch-id: 2c1cd7fdd003d9a116a697efa25d1716d548389f
prerequisite-patch-id: b12bdbf565747609e0cfe0609a42cf69b5d816a1
prerequisite-patch-id: 72cb2bc0fc2a48a5a029b049c199f4c86085cf04
prerequisite-patch-id: 5f1f5ad6add760161bd48875df48c0893aa12613
prerequisite-patch-id: 934931086968229434d15a2f2358aeb7e6975a1d
prerequisite-patch-id: 8a0b4828fc0690e0c841bc9adcc6568bb522e0e8
prerequisite-patch-id: 1d870f32e7dbf9a8bd3b8979558544107693e0f4
prerequisite-patch-id: 758c18d7c9fabb14bd90df62e5e8a62a6f880db4
prerequisite-patch-id: ce6e9e585f8edc1861ae6bb8fbdd836c20cbd290
prerequisite-patch-id: 9446dc03e442ea81c5f5b39e802e01b37da29971

Best regards,
--  
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-07-21 13:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 13:40 [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
2026-07-21 13:40 ` [PATCH v3 01/19] crypto: talitos/hash - Use CRYPTO_AHASH_BLOCK_ONLY API Paul Louvel
2026-07-21 13:40 ` [PATCH v3 02/19] crypto: talitos - Move driver into dedicated directory Paul Louvel
2026-07-21 13:40 ` [PATCH v3 03/19] crypto: talitos - Add missing includes to driver header file Paul Louvel
2026-07-21 13:40 ` [PATCH v3 04/19] crypto: talitos/hwrng - Move into separate file Paul Louvel
2026-07-21 13:40 ` [PATCH v3 05/19] crypto: talitos - Prepare crypto implementation file splitting Paul Louvel
2026-07-21 13:40 ` [PATCH v3 06/19] crypto: talitos/hash - Move into separate file Paul Louvel
2026-07-21 13:40 ` [PATCH v3 07/19] crypto: talitos/skcipher " Paul Louvel
2026-07-21 13:42   ` Paul Louvel
2026-07-21 13:54 ` [PATCH v3 00/19] crypto: talitos - Driver cleanup Paul Louvel
  -- strict thread matches above, loose matches on Subject: below --
2026-07-21 13:43 Paul Louvel
2026-07-21 13:59 Paul Louvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox