1301422e3SAntoine Tenart // SPDX-License-Identifier: GPL-2.0
21b44c5a6SAntoine Ténart /*
31b44c5a6SAntoine Ténart  * Copyright (C) 2017 Marvell
41b44c5a6SAntoine Ténart  *
51b44c5a6SAntoine Ténart  * Antoine Tenart <antoine.tenart@free-electrons.com>
61b44c5a6SAntoine Ténart  */
71b44c5a6SAntoine Ténart 
8aed3731eSAntoine Ténart #include <crypto/hmac.h>
9293f89cfSOfer Heifetz #include <crypto/md5.h>
101b44c5a6SAntoine Ténart #include <crypto/sha.h>
111b44c5a6SAntoine Ténart #include <linux/device.h>
121b44c5a6SAntoine Ténart #include <linux/dma-mapping.h>
131b44c5a6SAntoine Ténart #include <linux/dmapool.h>
141b44c5a6SAntoine Ténart 
151b44c5a6SAntoine Ténart #include "safexcel.h"
161b44c5a6SAntoine Ténart 
171b44c5a6SAntoine Ténart struct safexcel_ahash_ctx {
181b44c5a6SAntoine Ténart 	struct safexcel_context base;
191b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv;
201b44c5a6SAntoine Ténart 
211b44c5a6SAntoine Ténart 	u32 alg;
221b44c5a6SAntoine Ténart 
230de54fb1SAntoine Tenart 	u32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)];
240de54fb1SAntoine Tenart 	u32 opad[SHA512_DIGEST_SIZE / sizeof(u32)];
251b44c5a6SAntoine Ténart };
261b44c5a6SAntoine Ténart 
271b44c5a6SAntoine Ténart struct safexcel_ahash_req {
281b44c5a6SAntoine Ténart 	bool last_req;
291b44c5a6SAntoine Ténart 	bool finish;
301b44c5a6SAntoine Ténart 	bool hmac;
311eb7b403SOfer Heifetz 	bool needs_inv;
321b44c5a6SAntoine Ténart 
33c957f8b3SAntoine Ténart 	int nents;
34b8592027SOfer Heifetz 	dma_addr_t result_dma;
35c957f8b3SAntoine Ténart 
36b869648cSAntoine Tenart 	u32 digest;
37b869648cSAntoine Tenart 
381b44c5a6SAntoine Ténart 	u8 state_sz;    /* expected sate size, only set once */
39b460edb6SAntoine Tenart 	u32 state[SHA512_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32));
401b44c5a6SAntoine Ténart 
41b460edb6SAntoine Tenart 	u64 len[2];
42b460edb6SAntoine Tenart 	u64 processed[2];
431b44c5a6SAntoine Ténart 
44dc5268b6SPascal van Leeuwen 	u8 cache[SHA512_BLOCK_SIZE] __aligned(sizeof(u32));
45cff9a175SAntoine Tenart 	dma_addr_t cache_dma;
46cff9a175SAntoine Tenart 	unsigned int cache_sz;
47cff9a175SAntoine Tenart 
48dc5268b6SPascal van Leeuwen 	u8 cache_next[SHA512_BLOCK_SIZE] __aligned(sizeof(u32));
491b44c5a6SAntoine Ténart };
501b44c5a6SAntoine Ténart 
51b460edb6SAntoine Tenart static inline u64 safexcel_queued_len(struct safexcel_ahash_req *req)
52b460edb6SAntoine Tenart {
53ccd65a20SAntoine Tenart 	u64 len, processed;
54b460edb6SAntoine Tenart 
55ccd65a20SAntoine Tenart 	len = (0xffffffff * req->len[1]) + req->len[0];
56ccd65a20SAntoine Tenart 	processed = (0xffffffff * req->processed[1]) + req->processed[0];
57ccd65a20SAntoine Tenart 
58ccd65a20SAntoine Tenart 	return len - processed;
59b460edb6SAntoine Tenart }
60b460edb6SAntoine Tenart 
611b44c5a6SAntoine Ténart static void safexcel_hash_token(struct safexcel_command_desc *cdesc,
621b44c5a6SAntoine Ténart 				u32 input_length, u32 result_length)
631b44c5a6SAntoine Ténart {
641b44c5a6SAntoine Ténart 	struct safexcel_token *token =
651b44c5a6SAntoine Ténart 		(struct safexcel_token *)cdesc->control_data.token;
661b44c5a6SAntoine Ténart 
671b44c5a6SAntoine Ténart 	token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
681b44c5a6SAntoine Ténart 	token[0].packet_length = input_length;
691b44c5a6SAntoine Ténart 	token[0].stat = EIP197_TOKEN_STAT_LAST_HASH;
701b44c5a6SAntoine Ténart 	token[0].instructions = EIP197_TOKEN_INS_TYPE_HASH;
711b44c5a6SAntoine Ténart 
721b44c5a6SAntoine Ténart 	token[1].opcode = EIP197_TOKEN_OPCODE_INSERT;
731b44c5a6SAntoine Ténart 	token[1].packet_length = result_length;
741b44c5a6SAntoine Ténart 	token[1].stat = EIP197_TOKEN_STAT_LAST_HASH |
751b44c5a6SAntoine Ténart 			EIP197_TOKEN_STAT_LAST_PACKET;
761b44c5a6SAntoine Ténart 	token[1].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
771b44c5a6SAntoine Ténart 				EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
781b44c5a6SAntoine Ténart }
791b44c5a6SAntoine Ténart 
801b44c5a6SAntoine Ténart static void safexcel_context_control(struct safexcel_ahash_ctx *ctx,
811b44c5a6SAntoine Ténart 				     struct safexcel_ahash_req *req,
821b44c5a6SAntoine Ténart 				     struct safexcel_command_desc *cdesc,
8325bc9551SAntoine Tenart 				     unsigned int digestsize)
841b44c5a6SAntoine Ténart {
85b460edb6SAntoine Tenart 	struct safexcel_crypto_priv *priv = ctx->priv;
861b44c5a6SAntoine Ténart 	int i;
871b44c5a6SAntoine Ténart 
881b44c5a6SAntoine Ténart 	cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_HASH_OUT;
891b44c5a6SAntoine Ténart 	cdesc->control_data.control0 |= ctx->alg;
90b869648cSAntoine Tenart 	cdesc->control_data.control0 |= req->digest;
911b44c5a6SAntoine Ténart 
92b869648cSAntoine Tenart 	if (req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED) {
93b460edb6SAntoine Tenart 		if (req->processed[0] || req->processed[1]) {
94293f89cfSOfer Heifetz 			if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_MD5)
95293f89cfSOfer Heifetz 				cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(5);
96293f89cfSOfer Heifetz 			else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA1)
971b44c5a6SAntoine Ténart 				cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(6);
981b44c5a6SAntoine Ténart 			else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA224 ||
991b44c5a6SAntoine Ténart 				 ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA256)
1001b44c5a6SAntoine Ténart 				cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(9);
1019e46eafdSAntoine Tenart 			else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA384 ||
1029e46eafdSAntoine Tenart 				 ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA512)
103b460edb6SAntoine Tenart 				cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(17);
1041b44c5a6SAntoine Ténart 
1051b44c5a6SAntoine Ténart 			cdesc->control_data.control1 |= CONTEXT_CONTROL_DIGEST_CNT;
1061b44c5a6SAntoine Ténart 		} else {
1071b44c5a6SAntoine Ténart 			cdesc->control_data.control0 |= CONTEXT_CONTROL_RESTART_HASH;
1081b44c5a6SAntoine Ténart 		}
1091b44c5a6SAntoine Ténart 
110dc5268b6SPascal van Leeuwen 		if (!req->finish)
111dc5268b6SPascal van Leeuwen 			cdesc->control_data.control0 |= CONTEXT_CONTROL_NO_FINISH_HASH;
112dc5268b6SPascal van Leeuwen 
1131b44c5a6SAntoine Ténart 		/*
1141b44c5a6SAntoine Ténart 		 * Copy the input digest if needed, and setup the context
1151b44c5a6SAntoine Ténart 		 * fields. Do this now as we need it to setup the first command
1161b44c5a6SAntoine Ténart 		 * descriptor.
1171b44c5a6SAntoine Ténart 		 */
118b460edb6SAntoine Tenart 		if (req->processed[0] || req->processed[1]) {
1191b44c5a6SAntoine Ténart 			for (i = 0; i < digestsize / sizeof(u32); i++)
1201b44c5a6SAntoine Ténart 				ctx->base.ctxr->data[i] = cpu_to_le32(req->state[i]);
1211b44c5a6SAntoine Ténart 
122b460edb6SAntoine Tenart 			if (req->finish) {
123b460edb6SAntoine Tenart 				u64 count = req->processed[0] / EIP197_COUNTER_BLOCK_SIZE;
124b460edb6SAntoine Tenart 				count += ((0xffffffff / EIP197_COUNTER_BLOCK_SIZE) *
125b460edb6SAntoine Tenart 					  req->processed[1]);
126b460edb6SAntoine Tenart 
127b460edb6SAntoine Tenart 				/* This is a haredware limitation, as the
128b460edb6SAntoine Tenart 				 * counter must fit into an u32. This represents
129b460edb6SAntoine Tenart 				 * a farily big amount of input data, so we
130b460edb6SAntoine Tenart 				 * shouldn't see this.
131b460edb6SAntoine Tenart 				 */
132b460edb6SAntoine Tenart 				if (unlikely(count & 0xffff0000)) {
133b460edb6SAntoine Tenart 					dev_warn(priv->dev,
134b460edb6SAntoine Tenart 						 "Input data is too big\n");
135b460edb6SAntoine Tenart 					return;
136b460edb6SAntoine Tenart 				}
137b460edb6SAntoine Tenart 
138b460edb6SAntoine Tenart 				ctx->base.ctxr->data[i] = cpu_to_le32(count);
139b460edb6SAntoine Tenart 			}
1401b44c5a6SAntoine Ténart 		}
141b869648cSAntoine Tenart 	} else if (req->digest == CONTEXT_CONTROL_DIGEST_HMAC) {
1424505bb02SAntoine Tenart 		cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(2 * req->state_sz / sizeof(u32));
1431b44c5a6SAntoine Ténart 
1444505bb02SAntoine Tenart 		memcpy(ctx->base.ctxr->data, ctx->ipad, req->state_sz);
1454505bb02SAntoine Tenart 		memcpy(ctx->base.ctxr->data + req->state_sz / sizeof(u32),
1464505bb02SAntoine Tenart 		       ctx->opad, req->state_sz);
1471b44c5a6SAntoine Ténart 	}
1481b44c5a6SAntoine Ténart }
1491b44c5a6SAntoine Ténart 
1501eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring,
1511b44c5a6SAntoine Ténart 				      struct crypto_async_request *async,
1521b44c5a6SAntoine Ténart 				      bool *should_complete, int *ret)
1531b44c5a6SAntoine Ténart {
1541b44c5a6SAntoine Ténart 	struct safexcel_result_desc *rdesc;
1551b44c5a6SAntoine Ténart 	struct ahash_request *areq = ahash_request_cast(async);
1561b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
1571b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *sreq = ahash_request_ctx(areq);
158b460edb6SAntoine Tenart 	u64 cache_len;
1591b44c5a6SAntoine Ténart 
1601b44c5a6SAntoine Ténart 	*ret = 0;
1611b44c5a6SAntoine Ténart 
1621b44c5a6SAntoine Ténart 	rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
1631b44c5a6SAntoine Ténart 	if (IS_ERR(rdesc)) {
1641b44c5a6SAntoine Ténart 		dev_err(priv->dev,
1651b44c5a6SAntoine Ténart 			"hash: result: could not retrieve the result descriptor\n");
1661b44c5a6SAntoine Ténart 		*ret = PTR_ERR(rdesc);
167bdfd1909SAntoine Tenart 	} else {
168bdfd1909SAntoine Tenart 		*ret = safexcel_rdesc_check_errors(priv, rdesc);
1691b44c5a6SAntoine Ténart 	}
1701b44c5a6SAntoine Ténart 
1711b44c5a6SAntoine Ténart 	safexcel_complete(priv, ring);
1721b44c5a6SAntoine Ténart 
173c957f8b3SAntoine Ténart 	if (sreq->nents) {
174c957f8b3SAntoine Ténart 		dma_unmap_sg(priv->dev, areq->src, sreq->nents, DMA_TO_DEVICE);
175c957f8b3SAntoine Ténart 		sreq->nents = 0;
176c957f8b3SAntoine Ténart 	}
1771b44c5a6SAntoine Ténart 
178b8592027SOfer Heifetz 	if (sreq->result_dma) {
179b8592027SOfer Heifetz 		dma_unmap_single(priv->dev, sreq->result_dma, sreq->state_sz,
180b8592027SOfer Heifetz 				 DMA_FROM_DEVICE);
181b8592027SOfer Heifetz 		sreq->result_dma = 0;
182b8592027SOfer Heifetz 	}
183b8592027SOfer Heifetz 
184cff9a175SAntoine Tenart 	if (sreq->cache_dma) {
185cff9a175SAntoine Tenart 		dma_unmap_single(priv->dev, sreq->cache_dma, sreq->cache_sz,
186cff9a175SAntoine Tenart 				 DMA_TO_DEVICE);
187cff9a175SAntoine Tenart 		sreq->cache_dma = 0;
188aa524286SAntoine Tenart 		sreq->cache_sz = 0;
189cff9a175SAntoine Tenart 	}
1901b44c5a6SAntoine Ténart 
191b89a8159SAntoine Tenart 	if (sreq->finish)
192b89a8159SAntoine Tenart 		memcpy(areq->result, sreq->state,
193b89a8159SAntoine Tenart 		       crypto_ahash_digestsize(ahash));
194b89a8159SAntoine Tenart 
195b460edb6SAntoine Tenart 	cache_len = safexcel_queued_len(sreq);
1961b44c5a6SAntoine Ténart 	if (cache_len)
1971b44c5a6SAntoine Ténart 		memcpy(sreq->cache, sreq->cache_next, cache_len);
1981b44c5a6SAntoine Ténart 
1991b44c5a6SAntoine Ténart 	*should_complete = true;
2001b44c5a6SAntoine Ténart 
2011b44c5a6SAntoine Ténart 	return 1;
2021b44c5a6SAntoine Ténart }
2031b44c5a6SAntoine Ténart 
2041eb7b403SOfer Heifetz static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
2051eb7b403SOfer Heifetz 				   int *commands, int *results)
2061b44c5a6SAntoine Ténart {
2071b44c5a6SAntoine Ténart 	struct ahash_request *areq = ahash_request_cast(async);
2081b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
2091b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
2101b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
2111b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv = ctx->priv;
2121b44c5a6SAntoine Ténart 	struct safexcel_command_desc *cdesc, *first_cdesc = NULL;
2131b44c5a6SAntoine Ténart 	struct safexcel_result_desc *rdesc;
2141b44c5a6SAntoine Ténart 	struct scatterlist *sg;
215082ec2d4SAntoine Tenart 	int i, extra = 0, n_cdesc = 0, ret = 0;
216082ec2d4SAntoine Tenart 	u64 queued, len, cache_len, cache_max;
217082ec2d4SAntoine Tenart 
218082ec2d4SAntoine Tenart 	cache_max = crypto_ahash_blocksize(ahash);
2191b44c5a6SAntoine Ténart 
220b460edb6SAntoine Tenart 	queued = len = safexcel_queued_len(req);
221082ec2d4SAntoine Tenart 	if (queued <= cache_max)
2221b44c5a6SAntoine Ténart 		cache_len = queued;
2231b44c5a6SAntoine Ténart 	else
2241b44c5a6SAntoine Ténart 		cache_len = queued - areq->nbytes;
2251b44c5a6SAntoine Ténart 
226809778e0SAntoine Ténart 	if (!req->last_req) {
227809778e0SAntoine Ténart 		/* If this is not the last request and the queued data does not
228809778e0SAntoine Ténart 		 * fit into full blocks, cache it for the next send() call.
2291b44c5a6SAntoine Ténart 		 */
230dc5268b6SPascal van Leeuwen 		extra = queued & (cache_max - 1);
231082ec2d4SAntoine Tenart 
232809778e0SAntoine Ténart 		/* If this is not the last request and the queued data
233809778e0SAntoine Ténart 		 * is a multiple of a block, cache the last one for now.
234809778e0SAntoine Ténart 		 */
235dd4306a6SAntoine Tenart 		if (!extra)
236dc5268b6SPascal van Leeuwen 			extra = cache_max;
237809778e0SAntoine Ténart 
2381b44c5a6SAntoine Ténart 		sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
239809778e0SAntoine Ténart 				   req->cache_next, extra,
240809778e0SAntoine Ténart 				   areq->nbytes - extra);
2411b44c5a6SAntoine Ténart 
2421b44c5a6SAntoine Ténart 		queued -= extra;
2431b44c5a6SAntoine Ténart 		len -= extra;
244dc5268b6SPascal van Leeuwen 
245dc5268b6SPascal van Leeuwen 		if (!queued) {
246dc5268b6SPascal van Leeuwen 			*commands = 0;
247dc5268b6SPascal van Leeuwen 			*results = 0;
248dc5268b6SPascal van Leeuwen 			return 0;
249dc5268b6SPascal van Leeuwen 		}
250809778e0SAntoine Ténart 	}
2511b44c5a6SAntoine Ténart 
2521b44c5a6SAntoine Ténart 	/* Add a command descriptor for the cached data, if any */
2531b44c5a6SAntoine Ténart 	if (cache_len) {
254cff9a175SAntoine Tenart 		req->cache_dma = dma_map_single(priv->dev, req->cache,
2551b44c5a6SAntoine Ténart 						cache_len, DMA_TO_DEVICE);
2569744fec9SOfer Heifetz 		if (dma_mapping_error(priv->dev, req->cache_dma))
257cff9a175SAntoine Tenart 			return -EINVAL;
2581b44c5a6SAntoine Ténart 
259cff9a175SAntoine Tenart 		req->cache_sz = cache_len;
2601b44c5a6SAntoine Ténart 		first_cdesc = safexcel_add_cdesc(priv, ring, 1,
2611b44c5a6SAntoine Ténart 						 (cache_len == len),
262cff9a175SAntoine Tenart 						 req->cache_dma, cache_len, len,
2631b44c5a6SAntoine Ténart 						 ctx->base.ctxr_dma);
2641b44c5a6SAntoine Ténart 		if (IS_ERR(first_cdesc)) {
2651b44c5a6SAntoine Ténart 			ret = PTR_ERR(first_cdesc);
2661b44c5a6SAntoine Ténart 			goto unmap_cache;
2671b44c5a6SAntoine Ténart 		}
2681b44c5a6SAntoine Ténart 		n_cdesc++;
2691b44c5a6SAntoine Ténart 
2701b44c5a6SAntoine Ténart 		queued -= cache_len;
2711b44c5a6SAntoine Ténart 		if (!queued)
2721b44c5a6SAntoine Ténart 			goto send_command;
2731b44c5a6SAntoine Ténart 	}
2741b44c5a6SAntoine Ténart 
2751b44c5a6SAntoine Ténart 	/* Now handle the current ahash request buffer(s) */
276583d7e19SAntoine Tenart 	req->nents = dma_map_sg(priv->dev, areq->src, sg_nents(areq->src),
2771b44c5a6SAntoine Ténart 				DMA_TO_DEVICE);
278c957f8b3SAntoine Ténart 	if (!req->nents) {
2791b44c5a6SAntoine Ténart 		ret = -ENOMEM;
2801b44c5a6SAntoine Ténart 		goto cdesc_rollback;
2811b44c5a6SAntoine Ténart 	}
2821b44c5a6SAntoine Ténart 
283c957f8b3SAntoine Ténart 	for_each_sg(areq->src, sg, req->nents, i) {
2841b44c5a6SAntoine Ténart 		int sglen = sg_dma_len(sg);
2851b44c5a6SAntoine Ténart 
2861b44c5a6SAntoine Ténart 		/* Do not overflow the request */
287b460edb6SAntoine Tenart 		if (queued < sglen)
2881b44c5a6SAntoine Ténart 			sglen = queued;
2891b44c5a6SAntoine Ténart 
2901b44c5a6SAntoine Ténart 		cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,
2911b44c5a6SAntoine Ténart 					   !(queued - sglen), sg_dma_address(sg),
2921b44c5a6SAntoine Ténart 					   sglen, len, ctx->base.ctxr_dma);
2931b44c5a6SAntoine Ténart 		if (IS_ERR(cdesc)) {
2941b44c5a6SAntoine Ténart 			ret = PTR_ERR(cdesc);
29557433b58SAntoine Tenart 			goto unmap_sg;
2961b44c5a6SAntoine Ténart 		}
2971b44c5a6SAntoine Ténart 		n_cdesc++;
2981b44c5a6SAntoine Ténart 
2991b44c5a6SAntoine Ténart 		if (n_cdesc == 1)
3001b44c5a6SAntoine Ténart 			first_cdesc = cdesc;
3011b44c5a6SAntoine Ténart 
3021b44c5a6SAntoine Ténart 		queued -= sglen;
3031b44c5a6SAntoine Ténart 		if (!queued)
3041b44c5a6SAntoine Ténart 			break;
3051b44c5a6SAntoine Ténart 	}
3061b44c5a6SAntoine Ténart 
3071b44c5a6SAntoine Ténart send_command:
3081b44c5a6SAntoine Ténart 	/* Setup the context options */
30925bc9551SAntoine Tenart 	safexcel_context_control(ctx, req, first_cdesc, req->state_sz);
3101b44c5a6SAntoine Ténart 
3111b44c5a6SAntoine Ténart 	/* Add the token */
3121b44c5a6SAntoine Ténart 	safexcel_hash_token(first_cdesc, len, req->state_sz);
3131b44c5a6SAntoine Ténart 
314b8592027SOfer Heifetz 	req->result_dma = dma_map_single(priv->dev, req->state, req->state_sz,
315b8592027SOfer Heifetz 					 DMA_FROM_DEVICE);
316b8592027SOfer Heifetz 	if (dma_mapping_error(priv->dev, req->result_dma)) {
3171b44c5a6SAntoine Ténart 		ret = -EINVAL;
31857433b58SAntoine Tenart 		goto unmap_sg;
3191b44c5a6SAntoine Ténart 	}
3201b44c5a6SAntoine Ténart 
3211b44c5a6SAntoine Ténart 	/* Add a result descriptor */
322b8592027SOfer Heifetz 	rdesc = safexcel_add_rdesc(priv, ring, 1, 1, req->result_dma,
3231b44c5a6SAntoine Ténart 				   req->state_sz);
3241b44c5a6SAntoine Ténart 	if (IS_ERR(rdesc)) {
3251b44c5a6SAntoine Ténart 		ret = PTR_ERR(rdesc);
32657240a78SAntoine Tenart 		goto unmap_result;
3271b44c5a6SAntoine Ténart 	}
3281b44c5a6SAntoine Ténart 
3299744fec9SOfer Heifetz 	safexcel_rdr_req_set(priv, ring, rdesc, &areq->base);
3301b44c5a6SAntoine Ténart 
331b460edb6SAntoine Tenart 	req->processed[0] += len;
332b460edb6SAntoine Tenart 	if (req->processed[0] < len)
333b460edb6SAntoine Tenart 		req->processed[1]++;
334b460edb6SAntoine Tenart 
3351b44c5a6SAntoine Ténart 	*commands = n_cdesc;
3361b44c5a6SAntoine Ténart 	*results = 1;
3371b44c5a6SAntoine Ténart 	return 0;
3381b44c5a6SAntoine Ténart 
33957240a78SAntoine Tenart unmap_result:
34057433b58SAntoine Tenart 	dma_unmap_single(priv->dev, req->result_dma, req->state_sz,
34157433b58SAntoine Tenart 			 DMA_FROM_DEVICE);
34257433b58SAntoine Tenart unmap_sg:
34357240a78SAntoine Tenart 	dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE);
3441b44c5a6SAntoine Ténart cdesc_rollback:
3451b44c5a6SAntoine Ténart 	for (i = 0; i < n_cdesc; i++)
3461b44c5a6SAntoine Ténart 		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
3471b44c5a6SAntoine Ténart unmap_cache:
348cff9a175SAntoine Tenart 	if (req->cache_dma) {
349cff9a175SAntoine Tenart 		dma_unmap_single(priv->dev, req->cache_dma, req->cache_sz,
350cff9a175SAntoine Tenart 				 DMA_TO_DEVICE);
351aa524286SAntoine Tenart 		req->cache_dma = 0;
352cff9a175SAntoine Tenart 		req->cache_sz = 0;
3531b44c5a6SAntoine Ténart 	}
3541b44c5a6SAntoine Ténart 
3551b44c5a6SAntoine Ténart 	return ret;
3561b44c5a6SAntoine Ténart }
3571b44c5a6SAntoine Ténart 
3581b44c5a6SAntoine Ténart static inline bool safexcel_ahash_needs_inv_get(struct ahash_request *areq)
3591b44c5a6SAntoine Ténart {
3601b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
3611b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
3621b44c5a6SAntoine Ténart 	unsigned int state_w_sz = req->state_sz / sizeof(u32);
363b460edb6SAntoine Tenart 	u64 processed;
3641b44c5a6SAntoine Ténart 	int i;
3651b44c5a6SAntoine Ténart 
366b460edb6SAntoine Tenart 	processed = req->processed[0] / EIP197_COUNTER_BLOCK_SIZE;
367b460edb6SAntoine Tenart 	processed += (0xffffffff / EIP197_COUNTER_BLOCK_SIZE) * req->processed[1];
368b460edb6SAntoine Tenart 
3691b44c5a6SAntoine Ténart 	for (i = 0; i < state_w_sz; i++)
3701b44c5a6SAntoine Ténart 		if (ctx->base.ctxr->data[i] != cpu_to_le32(req->state[i]))
3711b44c5a6SAntoine Ténart 			return true;
3721b44c5a6SAntoine Ténart 
373b460edb6SAntoine Tenart 	if (ctx->base.ctxr->data[state_w_sz] != cpu_to_le32(processed))
3741b44c5a6SAntoine Ténart 		return true;
3751b44c5a6SAntoine Ténart 
3761b44c5a6SAntoine Ténart 	return false;
3771b44c5a6SAntoine Ténart }
3781b44c5a6SAntoine Ténart 
3791b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,
3801b44c5a6SAntoine Ténart 				      int ring,
3811b44c5a6SAntoine Ténart 				      struct crypto_async_request *async,
3821b44c5a6SAntoine Ténart 				      bool *should_complete, int *ret)
3831b44c5a6SAntoine Ténart {
3841b44c5a6SAntoine Ténart 	struct safexcel_result_desc *rdesc;
3851b44c5a6SAntoine Ténart 	struct ahash_request *areq = ahash_request_cast(async);
3861b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
3871b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(ahash);
3881b44c5a6SAntoine Ténart 	int enq_ret;
3891b44c5a6SAntoine Ténart 
3901b44c5a6SAntoine Ténart 	*ret = 0;
3911b44c5a6SAntoine Ténart 
3921b44c5a6SAntoine Ténart 	rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
3931b44c5a6SAntoine Ténart 	if (IS_ERR(rdesc)) {
3941b44c5a6SAntoine Ténart 		dev_err(priv->dev,
3951b44c5a6SAntoine Ténart 			"hash: invalidate: could not retrieve the result descriptor\n");
3961b44c5a6SAntoine Ténart 		*ret = PTR_ERR(rdesc);
397cda3e73aSAntoine Tenart 	} else {
398cda3e73aSAntoine Tenart 		*ret = safexcel_rdesc_check_errors(priv, rdesc);
3991b44c5a6SAntoine Ténart 	}
4001b44c5a6SAntoine Ténart 
4011b44c5a6SAntoine Ténart 	safexcel_complete(priv, ring);
4021b44c5a6SAntoine Ténart 
4031b44c5a6SAntoine Ténart 	if (ctx->base.exit_inv) {
4041b44c5a6SAntoine Ténart 		dma_pool_free(priv->context_pool, ctx->base.ctxr,
4051b44c5a6SAntoine Ténart 			      ctx->base.ctxr_dma);
4061b44c5a6SAntoine Ténart 
4071b44c5a6SAntoine Ténart 		*should_complete = true;
4081b44c5a6SAntoine Ténart 		return 1;
4091b44c5a6SAntoine Ténart 	}
4101b44c5a6SAntoine Ténart 
41186671abbSAntoine Ténart 	ring = safexcel_select_ring(priv);
41286671abbSAntoine Ténart 	ctx->base.ring = ring;
4131b44c5a6SAntoine Ténart 
41486671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
41586671abbSAntoine Ténart 	enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, async);
41686671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
4171b44c5a6SAntoine Ténart 
4181b44c5a6SAntoine Ténart 	if (enq_ret != -EINPROGRESS)
4191b44c5a6SAntoine Ténart 		*ret = enq_ret;
4201b44c5a6SAntoine Ténart 
4218472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
4228472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
42386671abbSAntoine Ténart 
4241b44c5a6SAntoine Ténart 	*should_complete = false;
4251b44c5a6SAntoine Ténart 
4261b44c5a6SAntoine Ténart 	return 1;
4271b44c5a6SAntoine Ténart }
4281b44c5a6SAntoine Ténart 
4291eb7b403SOfer Heifetz static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring,
4301eb7b403SOfer Heifetz 				  struct crypto_async_request *async,
4311eb7b403SOfer Heifetz 				  bool *should_complete, int *ret)
4321eb7b403SOfer Heifetz {
4331eb7b403SOfer Heifetz 	struct ahash_request *areq = ahash_request_cast(async);
4341eb7b403SOfer Heifetz 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
4351eb7b403SOfer Heifetz 	int err;
4361eb7b403SOfer Heifetz 
43753c83e91SAntoine Tenart 	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && req->needs_inv);
438871df319SAntoine Ténart 
4391eb7b403SOfer Heifetz 	if (req->needs_inv) {
4401eb7b403SOfer Heifetz 		req->needs_inv = false;
4411eb7b403SOfer Heifetz 		err = safexcel_handle_inv_result(priv, ring, async,
4421eb7b403SOfer Heifetz 						 should_complete, ret);
4431eb7b403SOfer Heifetz 	} else {
4441eb7b403SOfer Heifetz 		err = safexcel_handle_req_result(priv, ring, async,
4451eb7b403SOfer Heifetz 						 should_complete, ret);
4461eb7b403SOfer Heifetz 	}
4471eb7b403SOfer Heifetz 
4481eb7b403SOfer Heifetz 	return err;
4491eb7b403SOfer Heifetz }
4501eb7b403SOfer Heifetz 
4511b44c5a6SAntoine Ténart static int safexcel_ahash_send_inv(struct crypto_async_request *async,
4529744fec9SOfer Heifetz 				   int ring, int *commands, int *results)
4531b44c5a6SAntoine Ténart {
4541b44c5a6SAntoine Ténart 	struct ahash_request *areq = ahash_request_cast(async);
4551b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
4561b44c5a6SAntoine Ténart 	int ret;
4571b44c5a6SAntoine Ténart 
4585290ad6eSOfer Heifetz 	ret = safexcel_invalidate_cache(async, ctx->priv,
4599744fec9SOfer Heifetz 					ctx->base.ctxr_dma, ring);
4601b44c5a6SAntoine Ténart 	if (unlikely(ret))
4611b44c5a6SAntoine Ténart 		return ret;
4621b44c5a6SAntoine Ténart 
4631b44c5a6SAntoine Ténart 	*commands = 1;
4641b44c5a6SAntoine Ténart 	*results = 1;
4651b44c5a6SAntoine Ténart 
4661b44c5a6SAntoine Ténart 	return 0;
4671b44c5a6SAntoine Ténart }
4681b44c5a6SAntoine Ténart 
4691eb7b403SOfer Heifetz static int safexcel_ahash_send(struct crypto_async_request *async,
4709744fec9SOfer Heifetz 			       int ring, int *commands, int *results)
4711eb7b403SOfer Heifetz {
4721eb7b403SOfer Heifetz 	struct ahash_request *areq = ahash_request_cast(async);
4731eb7b403SOfer Heifetz 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
4741eb7b403SOfer Heifetz 	int ret;
4751eb7b403SOfer Heifetz 
4761eb7b403SOfer Heifetz 	if (req->needs_inv)
4779744fec9SOfer Heifetz 		ret = safexcel_ahash_send_inv(async, ring, commands, results);
4781eb7b403SOfer Heifetz 	else
4799744fec9SOfer Heifetz 		ret = safexcel_ahash_send_req(async, ring, commands, results);
4809744fec9SOfer Heifetz 
4811eb7b403SOfer Heifetz 	return ret;
4821eb7b403SOfer Heifetz }
4831eb7b403SOfer Heifetz 
4841b44c5a6SAntoine Ténart static int safexcel_ahash_exit_inv(struct crypto_tfm *tfm)
4851b44c5a6SAntoine Ténart {
4861b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
4871b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv = ctx->priv;
48861824806SAntoine Tenart 	EIP197_REQUEST_ON_STACK(req, ahash, EIP197_AHASH_REQ_SIZE);
4897cad2fabSAntoine Ténart 	struct safexcel_ahash_req *rctx = ahash_request_ctx(req);
4903e1166b9SArnd Bergmann 	struct safexcel_inv_result result = {};
49186671abbSAntoine Ténart 	int ring = ctx->base.ring;
4921b44c5a6SAntoine Ténart 
493b926213dSAntoine Tenart 	memset(req, 0, EIP197_AHASH_REQ_SIZE);
4941b44c5a6SAntoine Ténart 
4951b44c5a6SAntoine Ténart 	/* create invalidation request */
4961b44c5a6SAntoine Ténart 	init_completion(&result.completion);
4977cad2fabSAntoine Ténart 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
4981b44c5a6SAntoine Ténart 				   safexcel_inv_complete, &result);
4991b44c5a6SAntoine Ténart 
5007cad2fabSAntoine Ténart 	ahash_request_set_tfm(req, __crypto_ahash_cast(tfm));
5017cad2fabSAntoine Ténart 	ctx = crypto_tfm_ctx(req->base.tfm);
5021b44c5a6SAntoine Ténart 	ctx->base.exit_inv = true;
5031eb7b403SOfer Heifetz 	rctx->needs_inv = true;
5041b44c5a6SAntoine Ténart 
50586671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
5067cad2fabSAntoine Ténart 	crypto_enqueue_request(&priv->ring[ring].queue, &req->base);
50786671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
5081b44c5a6SAntoine Ténart 
5098472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
5108472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
5111b44c5a6SAntoine Ténart 
512b7007dbcSAntoine Tenart 	wait_for_completion(&result.completion);
5131b44c5a6SAntoine Ténart 
5141b44c5a6SAntoine Ténart 	if (result.error) {
5151b44c5a6SAntoine Ténart 		dev_warn(priv->dev, "hash: completion error (%d)\n",
5161b44c5a6SAntoine Ténart 			 result.error);
5171b44c5a6SAntoine Ténart 		return result.error;
5181b44c5a6SAntoine Ténart 	}
5191b44c5a6SAntoine Ténart 
5201b44c5a6SAntoine Ténart 	return 0;
5211b44c5a6SAntoine Ténart }
5221b44c5a6SAntoine Ténart 
523cc75f5ceSAntoine Ténart /* safexcel_ahash_cache: cache data until at least one request can be sent to
524cc75f5ceSAntoine Ténart  * the engine, aka. when there is at least 1 block size in the pipe.
525cc75f5ceSAntoine Ténart  */
526082ec2d4SAntoine Tenart static int safexcel_ahash_cache(struct ahash_request *areq, u32 cache_max)
5271b44c5a6SAntoine Ténart {
5281b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
529b460edb6SAntoine Tenart 	u64 queued, cache_len;
5301b44c5a6SAntoine Ténart 
531cc75f5ceSAntoine Ténart 	/* queued: everything accepted by the driver which will be handled by
532cc75f5ceSAntoine Ténart 	 * the next send() calls.
533cc75f5ceSAntoine Ténart 	 * tot sz handled by update() - tot sz handled by send()
534cc75f5ceSAntoine Ténart 	 */
535b460edb6SAntoine Tenart 	queued = safexcel_queued_len(req);
536b460edb6SAntoine Tenart 	/* cache_len: everything accepted by the driver but not sent yet,
537b460edb6SAntoine Tenart 	 * tot sz handled by update() - last req sz - tot sz handled by send()
538b460edb6SAntoine Tenart 	 */
539b460edb6SAntoine Tenart 	cache_len = queued - areq->nbytes;
5401b44c5a6SAntoine Ténart 
5411b44c5a6SAntoine Ténart 	/*
5421b44c5a6SAntoine Ténart 	 * In case there isn't enough bytes to proceed (less than a
5431b44c5a6SAntoine Ténart 	 * block size), cache the data until we have enough.
5441b44c5a6SAntoine Ténart 	 */
545082ec2d4SAntoine Tenart 	if (cache_len + areq->nbytes <= cache_max) {
5461b44c5a6SAntoine Ténart 		sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
5471b44c5a6SAntoine Ténart 				   req->cache + cache_len,
5481b44c5a6SAntoine Ténart 				   areq->nbytes, 0);
5491b44c5a6SAntoine Ténart 		return areq->nbytes;
5501b44c5a6SAntoine Ténart 	}
5511b44c5a6SAntoine Ténart 
552dfbcc08fSAntoine Ténart 	/* We couldn't cache all the data */
5531b44c5a6SAntoine Ténart 	return -E2BIG;
5541b44c5a6SAntoine Ténart }
5551b44c5a6SAntoine Ténart 
5561b44c5a6SAntoine Ténart static int safexcel_ahash_enqueue(struct ahash_request *areq)
5571b44c5a6SAntoine Ténart {
5581b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
5591b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
5601b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv = ctx->priv;
56186671abbSAntoine Ténart 	int ret, ring;
5621b44c5a6SAntoine Ténart 
5631eb7b403SOfer Heifetz 	req->needs_inv = false;
5641b44c5a6SAntoine Ténart 
565c4daf4ccSOfer Heifetz 	if (ctx->base.ctxr) {
56653c83e91SAntoine Tenart 		if (priv->flags & EIP197_TRC_CACHE && !ctx->base.needs_inv &&
567b460edb6SAntoine Tenart 		    (req->processed[0] || req->processed[1]) &&
568b869648cSAntoine Tenart 		    req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
569c4daf4ccSOfer Heifetz 			/* We're still setting needs_inv here, even though it is
570c4daf4ccSOfer Heifetz 			 * cleared right away, because the needs_inv flag can be
571c4daf4ccSOfer Heifetz 			 * set in other functions and we want to keep the same
572c4daf4ccSOfer Heifetz 			 * logic.
573c4daf4ccSOfer Heifetz 			 */
5741b44c5a6SAntoine Ténart 			ctx->base.needs_inv = safexcel_ahash_needs_inv_get(areq);
5751b44c5a6SAntoine Ténart 
5761eb7b403SOfer Heifetz 		if (ctx->base.needs_inv) {
5771eb7b403SOfer Heifetz 			ctx->base.needs_inv = false;
5781eb7b403SOfer Heifetz 			req->needs_inv = true;
5791eb7b403SOfer Heifetz 		}
5801b44c5a6SAntoine Ténart 	} else {
5811b44c5a6SAntoine Ténart 		ctx->base.ring = safexcel_select_ring(priv);
5821b44c5a6SAntoine Ténart 		ctx->base.ctxr = dma_pool_zalloc(priv->context_pool,
5831b44c5a6SAntoine Ténart 						 EIP197_GFP_FLAGS(areq->base),
5841b44c5a6SAntoine Ténart 						 &ctx->base.ctxr_dma);
5851b44c5a6SAntoine Ténart 		if (!ctx->base.ctxr)
5861b44c5a6SAntoine Ténart 			return -ENOMEM;
5871b44c5a6SAntoine Ténart 	}
5881b44c5a6SAntoine Ténart 
58986671abbSAntoine Ténart 	ring = ctx->base.ring;
5901b44c5a6SAntoine Ténart 
59186671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
59286671abbSAntoine Ténart 	ret = crypto_enqueue_request(&priv->ring[ring].queue, &areq->base);
59386671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
59486671abbSAntoine Ténart 
5958472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
5968472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
5971b44c5a6SAntoine Ténart 
5981b44c5a6SAntoine Ténart 	return ret;
5991b44c5a6SAntoine Ténart }
6001b44c5a6SAntoine Ténart 
6011b44c5a6SAntoine Ténart static int safexcel_ahash_update(struct ahash_request *areq)
6021b44c5a6SAntoine Ténart {
6031b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
6041b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
605082ec2d4SAntoine Tenart 	u32 cache_max;
6061b44c5a6SAntoine Ténart 
6071b44c5a6SAntoine Ténart 	/* If the request is 0 length, do nothing */
6081b44c5a6SAntoine Ténart 	if (!areq->nbytes)
6091b44c5a6SAntoine Ténart 		return 0;
6101b44c5a6SAntoine Ténart 
611b460edb6SAntoine Tenart 	req->len[0] += areq->nbytes;
612b460edb6SAntoine Tenart 	if (req->len[0] < areq->nbytes)
613b460edb6SAntoine Tenart 		req->len[1]++;
6141b44c5a6SAntoine Ténart 
615082ec2d4SAntoine Tenart 	cache_max = crypto_ahash_blocksize(ahash);
616082ec2d4SAntoine Tenart 
617082ec2d4SAntoine Tenart 	safexcel_ahash_cache(areq, cache_max);
6181b44c5a6SAntoine Ténart 
6191b44c5a6SAntoine Ténart 	/*
6201b44c5a6SAntoine Ténart 	 * We're not doing partial updates when performing an hmac request.
6211b44c5a6SAntoine Ténart 	 * Everything will be handled by the final() call.
6221b44c5a6SAntoine Ténart 	 */
623b869648cSAntoine Tenart 	if (req->digest == CONTEXT_CONTROL_DIGEST_HMAC)
6241b44c5a6SAntoine Ténart 		return 0;
6251b44c5a6SAntoine Ténart 
6261b44c5a6SAntoine Ténart 	if (req->hmac)
6271b44c5a6SAntoine Ténart 		return safexcel_ahash_enqueue(areq);
6281b44c5a6SAntoine Ténart 
6291b44c5a6SAntoine Ténart 	if (!req->last_req &&
630082ec2d4SAntoine Tenart 	    safexcel_queued_len(req) > cache_max)
6311b44c5a6SAntoine Ténart 		return safexcel_ahash_enqueue(areq);
6321b44c5a6SAntoine Ténart 
6331b44c5a6SAntoine Ténart 	return 0;
6341b44c5a6SAntoine Ténart }
6351b44c5a6SAntoine Ténart 
6361b44c5a6SAntoine Ténart static int safexcel_ahash_final(struct ahash_request *areq)
6371b44c5a6SAntoine Ténart {
6381b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
6391b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
6401b44c5a6SAntoine Ténart 
6411b44c5a6SAntoine Ténart 	req->last_req = true;
6421b44c5a6SAntoine Ténart 	req->finish = true;
6431b44c5a6SAntoine Ténart 
6441b44c5a6SAntoine Ténart 	/* If we have an overall 0 length request */
645b460edb6SAntoine Tenart 	if (!req->len[0] && !req->len[1] && !areq->nbytes) {
646293f89cfSOfer Heifetz 		if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_MD5)
647293f89cfSOfer Heifetz 			memcpy(areq->result, md5_zero_message_hash,
648293f89cfSOfer Heifetz 			       MD5_DIGEST_SIZE);
649293f89cfSOfer Heifetz 		else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA1)
6501b44c5a6SAntoine Ténart 			memcpy(areq->result, sha1_zero_message_hash,
6511b44c5a6SAntoine Ténart 			       SHA1_DIGEST_SIZE);
6521b44c5a6SAntoine Ténart 		else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA224)
6531b44c5a6SAntoine Ténart 			memcpy(areq->result, sha224_zero_message_hash,
6541b44c5a6SAntoine Ténart 			       SHA224_DIGEST_SIZE);
6551b44c5a6SAntoine Ténart 		else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA256)
6561b44c5a6SAntoine Ténart 			memcpy(areq->result, sha256_zero_message_hash,
6571b44c5a6SAntoine Ténart 			       SHA256_DIGEST_SIZE);
6589e46eafdSAntoine Tenart 		else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA384)
6599e46eafdSAntoine Tenart 			memcpy(areq->result, sha384_zero_message_hash,
6609e46eafdSAntoine Tenart 			       SHA384_DIGEST_SIZE);
661b460edb6SAntoine Tenart 		else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA512)
662b460edb6SAntoine Tenart 			memcpy(areq->result, sha512_zero_message_hash,
663b460edb6SAntoine Tenart 			       SHA512_DIGEST_SIZE);
6641b44c5a6SAntoine Ténart 
6651b44c5a6SAntoine Ténart 		return 0;
6661b44c5a6SAntoine Ténart 	}
6671b44c5a6SAntoine Ténart 
6681b44c5a6SAntoine Ténart 	return safexcel_ahash_enqueue(areq);
6691b44c5a6SAntoine Ténart }
6701b44c5a6SAntoine Ténart 
6711b44c5a6SAntoine Ténart static int safexcel_ahash_finup(struct ahash_request *areq)
6721b44c5a6SAntoine Ténart {
6731b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
6741b44c5a6SAntoine Ténart 
6751b44c5a6SAntoine Ténart 	req->last_req = true;
6761b44c5a6SAntoine Ténart 	req->finish = true;
6771b44c5a6SAntoine Ténart 
6781b44c5a6SAntoine Ténart 	safexcel_ahash_update(areq);
6791b44c5a6SAntoine Ténart 	return safexcel_ahash_final(areq);
6801b44c5a6SAntoine Ténart }
6811b44c5a6SAntoine Ténart 
6821b44c5a6SAntoine Ténart static int safexcel_ahash_export(struct ahash_request *areq, void *out)
6831b44c5a6SAntoine Ténart {
6841b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
6851b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
6861b44c5a6SAntoine Ténart 	struct safexcel_ahash_export_state *export = out;
687082ec2d4SAntoine Tenart 	u32 cache_sz;
688082ec2d4SAntoine Tenart 
689082ec2d4SAntoine Tenart 	cache_sz = crypto_ahash_blocksize(ahash);
6901b44c5a6SAntoine Ténart 
691b460edb6SAntoine Tenart 	export->len[0] = req->len[0];
692b460edb6SAntoine Tenart 	export->len[1] = req->len[1];
693b460edb6SAntoine Tenart 	export->processed[0] = req->processed[0];
694b460edb6SAntoine Tenart 	export->processed[1] = req->processed[1];
6951b44c5a6SAntoine Ténart 
696b869648cSAntoine Tenart 	export->digest = req->digest;
697b869648cSAntoine Tenart 
6981b44c5a6SAntoine Ténart 	memcpy(export->state, req->state, req->state_sz);
699082ec2d4SAntoine Tenart 	memcpy(export->cache, req->cache, cache_sz);
7001b44c5a6SAntoine Ténart 
7011b44c5a6SAntoine Ténart 	return 0;
7021b44c5a6SAntoine Ténart }
7031b44c5a6SAntoine Ténart 
7041b44c5a6SAntoine Ténart static int safexcel_ahash_import(struct ahash_request *areq, const void *in)
7051b44c5a6SAntoine Ténart {
7061b44c5a6SAntoine Ténart 	struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
7071b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
7081b44c5a6SAntoine Ténart 	const struct safexcel_ahash_export_state *export = in;
709082ec2d4SAntoine Tenart 	u32 cache_sz;
7101b44c5a6SAntoine Ténart 	int ret;
7111b44c5a6SAntoine Ténart 
7121b44c5a6SAntoine Ténart 	ret = crypto_ahash_init(areq);
7131b44c5a6SAntoine Ténart 	if (ret)
7141b44c5a6SAntoine Ténart 		return ret;
7151b44c5a6SAntoine Ténart 
716082ec2d4SAntoine Tenart 	cache_sz = crypto_ahash_blocksize(ahash);
717082ec2d4SAntoine Tenart 
718b460edb6SAntoine Tenart 	req->len[0] = export->len[0];
719b460edb6SAntoine Tenart 	req->len[1] = export->len[1];
720b460edb6SAntoine Tenart 	req->processed[0] = export->processed[0];
721b460edb6SAntoine Tenart 	req->processed[1] = export->processed[1];
7221b44c5a6SAntoine Ténart 
723b869648cSAntoine Tenart 	req->digest = export->digest;
724b869648cSAntoine Tenart 
725082ec2d4SAntoine Tenart 	memcpy(req->cache, export->cache, cache_sz);
7261b44c5a6SAntoine Ténart 	memcpy(req->state, export->state, req->state_sz);
7271b44c5a6SAntoine Ténart 
7281b44c5a6SAntoine Ténart 	return 0;
7291b44c5a6SAntoine Ténart }
7301b44c5a6SAntoine Ténart 
7311b44c5a6SAntoine Ténart static int safexcel_ahash_cra_init(struct crypto_tfm *tfm)
7321b44c5a6SAntoine Ténart {
7331b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
7341b44c5a6SAntoine Ténart 	struct safexcel_alg_template *tmpl =
7351b44c5a6SAntoine Ténart 		container_of(__crypto_ahash_alg(tfm->__crt_alg),
7361b44c5a6SAntoine Ténart 			     struct safexcel_alg_template, alg.ahash);
7371b44c5a6SAntoine Ténart 
7381b44c5a6SAntoine Ténart 	ctx->priv = tmpl->priv;
7391eb7b403SOfer Heifetz 	ctx->base.send = safexcel_ahash_send;
7401eb7b403SOfer Heifetz 	ctx->base.handle_result = safexcel_handle_result;
7411b44c5a6SAntoine Ténart 
7421b44c5a6SAntoine Ténart 	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
7431b44c5a6SAntoine Ténart 				 sizeof(struct safexcel_ahash_req));
7441b44c5a6SAntoine Ténart 	return 0;
7451b44c5a6SAntoine Ténart }
7461b44c5a6SAntoine Ténart 
7471b44c5a6SAntoine Ténart static int safexcel_sha1_init(struct ahash_request *areq)
7481b44c5a6SAntoine Ténart {
7491b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
7501b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
7511b44c5a6SAntoine Ténart 
7521b44c5a6SAntoine Ténart 	memset(req, 0, sizeof(*req));
7531b44c5a6SAntoine Ténart 
7541b44c5a6SAntoine Ténart 	req->state[0] = SHA1_H0;
7551b44c5a6SAntoine Ténart 	req->state[1] = SHA1_H1;
7561b44c5a6SAntoine Ténart 	req->state[2] = SHA1_H2;
7571b44c5a6SAntoine Ténart 	req->state[3] = SHA1_H3;
7581b44c5a6SAntoine Ténart 	req->state[4] = SHA1_H4;
7591b44c5a6SAntoine Ténart 
7601b44c5a6SAntoine Ténart 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
761b869648cSAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
7621b44c5a6SAntoine Ténart 	req->state_sz = SHA1_DIGEST_SIZE;
7631b44c5a6SAntoine Ténart 
7641b44c5a6SAntoine Ténart 	return 0;
7651b44c5a6SAntoine Ténart }
7661b44c5a6SAntoine Ténart 
7671b44c5a6SAntoine Ténart static int safexcel_sha1_digest(struct ahash_request *areq)
7681b44c5a6SAntoine Ténart {
7691b44c5a6SAntoine Ténart 	int ret = safexcel_sha1_init(areq);
7701b44c5a6SAntoine Ténart 
7711b44c5a6SAntoine Ténart 	if (ret)
7721b44c5a6SAntoine Ténart 		return ret;
7731b44c5a6SAntoine Ténart 
7741b44c5a6SAntoine Ténart 	return safexcel_ahash_finup(areq);
7751b44c5a6SAntoine Ténart }
7761b44c5a6SAntoine Ténart 
7771b44c5a6SAntoine Ténart static void safexcel_ahash_cra_exit(struct crypto_tfm *tfm)
7781b44c5a6SAntoine Ténart {
7791b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
7801b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv = ctx->priv;
7811b44c5a6SAntoine Ténart 	int ret;
7821b44c5a6SAntoine Ténart 
7831b44c5a6SAntoine Ténart 	/* context not allocated, skip invalidation */
7841b44c5a6SAntoine Ténart 	if (!ctx->base.ctxr)
7851b44c5a6SAntoine Ténart 		return;
7861b44c5a6SAntoine Ténart 
78753c83e91SAntoine Tenart 	if (priv->flags & EIP197_TRC_CACHE) {
7881b44c5a6SAntoine Ténart 		ret = safexcel_ahash_exit_inv(tfm);
7891b44c5a6SAntoine Ténart 		if (ret)
7901b44c5a6SAntoine Ténart 			dev_warn(priv->dev, "hash: invalidation error %d\n", ret);
791871df319SAntoine Ténart 	} else {
792871df319SAntoine Ténart 		dma_pool_free(priv->context_pool, ctx->base.ctxr,
793871df319SAntoine Ténart 			      ctx->base.ctxr_dma);
794871df319SAntoine Ténart 	}
7951b44c5a6SAntoine Ténart }
7961b44c5a6SAntoine Ténart 
7971b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_sha1 = {
7981b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
7995eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
8001b44c5a6SAntoine Ténart 	.alg.ahash = {
8011b44c5a6SAntoine Ténart 		.init = safexcel_sha1_init,
8021b44c5a6SAntoine Ténart 		.update = safexcel_ahash_update,
8031b44c5a6SAntoine Ténart 		.final = safexcel_ahash_final,
8041b44c5a6SAntoine Ténart 		.finup = safexcel_ahash_finup,
8051b44c5a6SAntoine Ténart 		.digest = safexcel_sha1_digest,
8061b44c5a6SAntoine Ténart 		.export = safexcel_ahash_export,
8071b44c5a6SAntoine Ténart 		.import = safexcel_ahash_import,
8081b44c5a6SAntoine Ténart 		.halg = {
8091b44c5a6SAntoine Ténart 			.digestsize = SHA1_DIGEST_SIZE,
8101b44c5a6SAntoine Ténart 			.statesize = sizeof(struct safexcel_ahash_export_state),
8111b44c5a6SAntoine Ténart 			.base = {
8121b44c5a6SAntoine Ténart 				.cra_name = "sha1",
8131b44c5a6SAntoine Ténart 				.cra_driver_name = "safexcel-sha1",
8141b44c5a6SAntoine Ténart 				.cra_priority = 300,
8151b44c5a6SAntoine Ténart 				.cra_flags = CRYPTO_ALG_ASYNC |
8161b44c5a6SAntoine Ténart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
8171b44c5a6SAntoine Ténart 				.cra_blocksize = SHA1_BLOCK_SIZE,
8181b44c5a6SAntoine Ténart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
8191b44c5a6SAntoine Ténart 				.cra_init = safexcel_ahash_cra_init,
8201b44c5a6SAntoine Ténart 				.cra_exit = safexcel_ahash_cra_exit,
8211b44c5a6SAntoine Ténart 				.cra_module = THIS_MODULE,
8221b44c5a6SAntoine Ténart 			},
8231b44c5a6SAntoine Ténart 		},
8241b44c5a6SAntoine Ténart 	},
8251b44c5a6SAntoine Ténart };
8261b44c5a6SAntoine Ténart 
8271b44c5a6SAntoine Ténart static int safexcel_hmac_sha1_init(struct ahash_request *areq)
8281b44c5a6SAntoine Ténart {
829b869648cSAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
8301b44c5a6SAntoine Ténart 
8311b44c5a6SAntoine Ténart 	safexcel_sha1_init(areq);
832b869648cSAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
8331b44c5a6SAntoine Ténart 	return 0;
8341b44c5a6SAntoine Ténart }
8351b44c5a6SAntoine Ténart 
8361b44c5a6SAntoine Ténart static int safexcel_hmac_sha1_digest(struct ahash_request *areq)
8371b44c5a6SAntoine Ténart {
8381b44c5a6SAntoine Ténart 	int ret = safexcel_hmac_sha1_init(areq);
8391b44c5a6SAntoine Ténart 
8401b44c5a6SAntoine Ténart 	if (ret)
8411b44c5a6SAntoine Ténart 		return ret;
8421b44c5a6SAntoine Ténart 
8431b44c5a6SAntoine Ténart 	return safexcel_ahash_finup(areq);
8441b44c5a6SAntoine Ténart }
8451b44c5a6SAntoine Ténart 
8461b44c5a6SAntoine Ténart struct safexcel_ahash_result {
8471b44c5a6SAntoine Ténart 	struct completion completion;
8481b44c5a6SAntoine Ténart 	int error;
8491b44c5a6SAntoine Ténart };
8501b44c5a6SAntoine Ténart 
8511b44c5a6SAntoine Ténart static void safexcel_ahash_complete(struct crypto_async_request *req, int error)
8521b44c5a6SAntoine Ténart {
8531b44c5a6SAntoine Ténart 	struct safexcel_ahash_result *result = req->data;
8541b44c5a6SAntoine Ténart 
8551b44c5a6SAntoine Ténart 	if (error == -EINPROGRESS)
8561b44c5a6SAntoine Ténart 		return;
8571b44c5a6SAntoine Ténart 
8581b44c5a6SAntoine Ténart 	result->error = error;
8591b44c5a6SAntoine Ténart 	complete(&result->completion);
8601b44c5a6SAntoine Ténart }
8611b44c5a6SAntoine Ténart 
8621b44c5a6SAntoine Ténart static int safexcel_hmac_init_pad(struct ahash_request *areq,
8631b44c5a6SAntoine Ténart 				  unsigned int blocksize, const u8 *key,
8641b44c5a6SAntoine Ténart 				  unsigned int keylen, u8 *ipad, u8 *opad)
8651b44c5a6SAntoine Ténart {
8661b44c5a6SAntoine Ténart 	struct safexcel_ahash_result result;
8671b44c5a6SAntoine Ténart 	struct scatterlist sg;
8681b44c5a6SAntoine Ténart 	int ret, i;
8691b44c5a6SAntoine Ténart 	u8 *keydup;
8701b44c5a6SAntoine Ténart 
8711b44c5a6SAntoine Ténart 	if (keylen <= blocksize) {
8721b44c5a6SAntoine Ténart 		memcpy(ipad, key, keylen);
8731b44c5a6SAntoine Ténart 	} else {
8741b44c5a6SAntoine Ténart 		keydup = kmemdup(key, keylen, GFP_KERNEL);
8751b44c5a6SAntoine Ténart 		if (!keydup)
8761b44c5a6SAntoine Ténart 			return -ENOMEM;
8771b44c5a6SAntoine Ténart 
8781b44c5a6SAntoine Ténart 		ahash_request_set_callback(areq, CRYPTO_TFM_REQ_MAY_BACKLOG,
8791b44c5a6SAntoine Ténart 					   safexcel_ahash_complete, &result);
8801b44c5a6SAntoine Ténart 		sg_init_one(&sg, keydup, keylen);
8811b44c5a6SAntoine Ténart 		ahash_request_set_crypt(areq, &sg, ipad, keylen);
8821b44c5a6SAntoine Ténart 		init_completion(&result.completion);
8831b44c5a6SAntoine Ténart 
8841b44c5a6SAntoine Ténart 		ret = crypto_ahash_digest(areq);
8854dc5475aSAntoine Tenart 		if (ret == -EINPROGRESS || ret == -EBUSY) {
8861b44c5a6SAntoine Ténart 			wait_for_completion_interruptible(&result.completion);
8871b44c5a6SAntoine Ténart 			ret = result.error;
8881b44c5a6SAntoine Ténart 		}
8891b44c5a6SAntoine Ténart 
8901b44c5a6SAntoine Ténart 		/* Avoid leaking */
8911b44c5a6SAntoine Ténart 		memzero_explicit(keydup, keylen);
8921b44c5a6SAntoine Ténart 		kfree(keydup);
8931b44c5a6SAntoine Ténart 
8941b44c5a6SAntoine Ténart 		if (ret)
8951b44c5a6SAntoine Ténart 			return ret;
8961b44c5a6SAntoine Ténart 
8971b44c5a6SAntoine Ténart 		keylen = crypto_ahash_digestsize(crypto_ahash_reqtfm(areq));
8981b44c5a6SAntoine Ténart 	}
8991b44c5a6SAntoine Ténart 
9001b44c5a6SAntoine Ténart 	memset(ipad + keylen, 0, blocksize - keylen);
9011b44c5a6SAntoine Ténart 	memcpy(opad, ipad, blocksize);
9021b44c5a6SAntoine Ténart 
9031b44c5a6SAntoine Ténart 	for (i = 0; i < blocksize; i++) {
904aed3731eSAntoine Ténart 		ipad[i] ^= HMAC_IPAD_VALUE;
905aed3731eSAntoine Ténart 		opad[i] ^= HMAC_OPAD_VALUE;
9061b44c5a6SAntoine Ténart 	}
9071b44c5a6SAntoine Ténart 
9081b44c5a6SAntoine Ténart 	return 0;
9091b44c5a6SAntoine Ténart }
9101b44c5a6SAntoine Ténart 
9111b44c5a6SAntoine Ténart static int safexcel_hmac_init_iv(struct ahash_request *areq,
9121b44c5a6SAntoine Ténart 				 unsigned int blocksize, u8 *pad, void *state)
9131b44c5a6SAntoine Ténart {
9141b44c5a6SAntoine Ténart 	struct safexcel_ahash_result result;
9151b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req;
9161b44c5a6SAntoine Ténart 	struct scatterlist sg;
9171b44c5a6SAntoine Ténart 	int ret;
9181b44c5a6SAntoine Ténart 
9191b44c5a6SAntoine Ténart 	ahash_request_set_callback(areq, CRYPTO_TFM_REQ_MAY_BACKLOG,
9201b44c5a6SAntoine Ténart 				   safexcel_ahash_complete, &result);
9211b44c5a6SAntoine Ténart 	sg_init_one(&sg, pad, blocksize);
9221b44c5a6SAntoine Ténart 	ahash_request_set_crypt(areq, &sg, pad, blocksize);
9231b44c5a6SAntoine Ténart 	init_completion(&result.completion);
9241b44c5a6SAntoine Ténart 
9251b44c5a6SAntoine Ténart 	ret = crypto_ahash_init(areq);
9261b44c5a6SAntoine Ténart 	if (ret)
9271b44c5a6SAntoine Ténart 		return ret;
9281b44c5a6SAntoine Ténart 
9291b44c5a6SAntoine Ténart 	req = ahash_request_ctx(areq);
9301b44c5a6SAntoine Ténart 	req->hmac = true;
9311b44c5a6SAntoine Ténart 	req->last_req = true;
9321b44c5a6SAntoine Ténart 
9331b44c5a6SAntoine Ténart 	ret = crypto_ahash_update(areq);
93412bf4142SOfer Heifetz 	if (ret && ret != -EINPROGRESS && ret != -EBUSY)
9351b44c5a6SAntoine Ténart 		return ret;
9361b44c5a6SAntoine Ténart 
9371b44c5a6SAntoine Ténart 	wait_for_completion_interruptible(&result.completion);
9381b44c5a6SAntoine Ténart 	if (result.error)
9391b44c5a6SAntoine Ténart 		return result.error;
9401b44c5a6SAntoine Ténart 
9411b44c5a6SAntoine Ténart 	return crypto_ahash_export(areq, state);
9421b44c5a6SAntoine Ténart }
9431b44c5a6SAntoine Ténart 
944f6beaea3SAntoine Tenart int safexcel_hmac_setkey(const char *alg, const u8 *key, unsigned int keylen,
945f6beaea3SAntoine Tenart 			 void *istate, void *ostate)
9461b44c5a6SAntoine Ténart {
9471b44c5a6SAntoine Ténart 	struct ahash_request *areq;
9481b44c5a6SAntoine Ténart 	struct crypto_ahash *tfm;
9491b44c5a6SAntoine Ténart 	unsigned int blocksize;
9501b44c5a6SAntoine Ténart 	u8 *ipad, *opad;
9511b44c5a6SAntoine Ténart 	int ret;
9521b44c5a6SAntoine Ténart 
95385d7311fSEric Biggers 	tfm = crypto_alloc_ahash(alg, 0, 0);
9541b44c5a6SAntoine Ténart 	if (IS_ERR(tfm))
9551b44c5a6SAntoine Ténart 		return PTR_ERR(tfm);
9561b44c5a6SAntoine Ténart 
9571b44c5a6SAntoine Ténart 	areq = ahash_request_alloc(tfm, GFP_KERNEL);
9581b44c5a6SAntoine Ténart 	if (!areq) {
9591b44c5a6SAntoine Ténart 		ret = -ENOMEM;
9601b44c5a6SAntoine Ténart 		goto free_ahash;
9611b44c5a6SAntoine Ténart 	}
9621b44c5a6SAntoine Ténart 
9631b44c5a6SAntoine Ténart 	crypto_ahash_clear_flags(tfm, ~0);
9641b44c5a6SAntoine Ténart 	blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
9651b44c5a6SAntoine Ténart 
9666396bb22SKees Cook 	ipad = kcalloc(2, blocksize, GFP_KERNEL);
9671b44c5a6SAntoine Ténart 	if (!ipad) {
9681b44c5a6SAntoine Ténart 		ret = -ENOMEM;
9691b44c5a6SAntoine Ténart 		goto free_request;
9701b44c5a6SAntoine Ténart 	}
9711b44c5a6SAntoine Ténart 
9721b44c5a6SAntoine Ténart 	opad = ipad + blocksize;
9731b44c5a6SAntoine Ténart 
9741b44c5a6SAntoine Ténart 	ret = safexcel_hmac_init_pad(areq, blocksize, key, keylen, ipad, opad);
9751b44c5a6SAntoine Ténart 	if (ret)
9761b44c5a6SAntoine Ténart 		goto free_ipad;
9771b44c5a6SAntoine Ténart 
9781b44c5a6SAntoine Ténart 	ret = safexcel_hmac_init_iv(areq, blocksize, ipad, istate);
9791b44c5a6SAntoine Ténart 	if (ret)
9801b44c5a6SAntoine Ténart 		goto free_ipad;
9811b44c5a6SAntoine Ténart 
9821b44c5a6SAntoine Ténart 	ret = safexcel_hmac_init_iv(areq, blocksize, opad, ostate);
9831b44c5a6SAntoine Ténart 
9841b44c5a6SAntoine Ténart free_ipad:
9851b44c5a6SAntoine Ténart 	kfree(ipad);
9861b44c5a6SAntoine Ténart free_request:
9871b44c5a6SAntoine Ténart 	ahash_request_free(areq);
9881b44c5a6SAntoine Ténart free_ahash:
9891b44c5a6SAntoine Ténart 	crypto_free_ahash(tfm);
9901b44c5a6SAntoine Ténart 
9911b44c5a6SAntoine Ténart 	return ret;
9921b44c5a6SAntoine Ténart }
9931b44c5a6SAntoine Ténart 
99473f36ea7SAntoine Tenart static int safexcel_hmac_alg_setkey(struct crypto_ahash *tfm, const u8 *key,
99573f36ea7SAntoine Tenart 				    unsigned int keylen, const char *alg,
99673f36ea7SAntoine Tenart 				    unsigned int state_sz)
9971b44c5a6SAntoine Ténart {
9981b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
999871df319SAntoine Ténart 	struct safexcel_crypto_priv *priv = ctx->priv;
10001b44c5a6SAntoine Ténart 	struct safexcel_ahash_export_state istate, ostate;
10011b44c5a6SAntoine Ténart 	int ret, i;
10021b44c5a6SAntoine Ténart 
100373f36ea7SAntoine Tenart 	ret = safexcel_hmac_setkey(alg, key, keylen, &istate, &ostate);
10041b44c5a6SAntoine Ténart 	if (ret)
10051b44c5a6SAntoine Ténart 		return ret;
10061b44c5a6SAntoine Ténart 
100753c83e91SAntoine Tenart 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr) {
100873f36ea7SAntoine Tenart 		for (i = 0; i < state_sz / sizeof(u32); i++) {
10091b44c5a6SAntoine Ténart 			if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
10101b44c5a6SAntoine Ténart 			    ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
10111b44c5a6SAntoine Ténart 				ctx->base.needs_inv = true;
10121b44c5a6SAntoine Ténart 				break;
10131b44c5a6SAntoine Ténart 			}
10141b44c5a6SAntoine Ténart 		}
1015c4daf4ccSOfer Heifetz 	}
10161b44c5a6SAntoine Ténart 
101773f36ea7SAntoine Tenart 	memcpy(ctx->ipad, &istate.state, state_sz);
101873f36ea7SAntoine Tenart 	memcpy(ctx->opad, &ostate.state, state_sz);
101942ef3bedSAntoine Ténart 
10201b44c5a6SAntoine Ténart 	return 0;
10211b44c5a6SAntoine Ténart }
10221b44c5a6SAntoine Ténart 
102373f36ea7SAntoine Tenart static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
102473f36ea7SAntoine Tenart 				     unsigned int keylen)
102573f36ea7SAntoine Tenart {
102673f36ea7SAntoine Tenart 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha1",
102773f36ea7SAntoine Tenart 					SHA1_DIGEST_SIZE);
102873f36ea7SAntoine Tenart }
102973f36ea7SAntoine Tenart 
10301b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_hmac_sha1 = {
10311b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
10325eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
10331b44c5a6SAntoine Ténart 	.alg.ahash = {
10341b44c5a6SAntoine Ténart 		.init = safexcel_hmac_sha1_init,
10351b44c5a6SAntoine Ténart 		.update = safexcel_ahash_update,
10361b44c5a6SAntoine Ténart 		.final = safexcel_ahash_final,
10371b44c5a6SAntoine Ténart 		.finup = safexcel_ahash_finup,
10381b44c5a6SAntoine Ténart 		.digest = safexcel_hmac_sha1_digest,
10391b44c5a6SAntoine Ténart 		.setkey = safexcel_hmac_sha1_setkey,
10401b44c5a6SAntoine Ténart 		.export = safexcel_ahash_export,
10411b44c5a6SAntoine Ténart 		.import = safexcel_ahash_import,
10421b44c5a6SAntoine Ténart 		.halg = {
10431b44c5a6SAntoine Ténart 			.digestsize = SHA1_DIGEST_SIZE,
10441b44c5a6SAntoine Ténart 			.statesize = sizeof(struct safexcel_ahash_export_state),
10451b44c5a6SAntoine Ténart 			.base = {
10461b44c5a6SAntoine Ténart 				.cra_name = "hmac(sha1)",
10471b44c5a6SAntoine Ténart 				.cra_driver_name = "safexcel-hmac-sha1",
10481b44c5a6SAntoine Ténart 				.cra_priority = 300,
10491b44c5a6SAntoine Ténart 				.cra_flags = CRYPTO_ALG_ASYNC |
10501b44c5a6SAntoine Ténart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
10511b44c5a6SAntoine Ténart 				.cra_blocksize = SHA1_BLOCK_SIZE,
10521b44c5a6SAntoine Ténart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
10531b44c5a6SAntoine Ténart 				.cra_init = safexcel_ahash_cra_init,
10541b44c5a6SAntoine Ténart 				.cra_exit = safexcel_ahash_cra_exit,
10551b44c5a6SAntoine Ténart 				.cra_module = THIS_MODULE,
10561b44c5a6SAntoine Ténart 			},
10571b44c5a6SAntoine Ténart 		},
10581b44c5a6SAntoine Ténart 	},
10591b44c5a6SAntoine Ténart };
10601b44c5a6SAntoine Ténart 
10611b44c5a6SAntoine Ténart static int safexcel_sha256_init(struct ahash_request *areq)
10621b44c5a6SAntoine Ténart {
10631b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
10641b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
10651b44c5a6SAntoine Ténart 
10661b44c5a6SAntoine Ténart 	memset(req, 0, sizeof(*req));
10671b44c5a6SAntoine Ténart 
10681b44c5a6SAntoine Ténart 	req->state[0] = SHA256_H0;
10691b44c5a6SAntoine Ténart 	req->state[1] = SHA256_H1;
10701b44c5a6SAntoine Ténart 	req->state[2] = SHA256_H2;
10711b44c5a6SAntoine Ténart 	req->state[3] = SHA256_H3;
10721b44c5a6SAntoine Ténart 	req->state[4] = SHA256_H4;
10731b44c5a6SAntoine Ténart 	req->state[5] = SHA256_H5;
10741b44c5a6SAntoine Ténart 	req->state[6] = SHA256_H6;
10751b44c5a6SAntoine Ténart 	req->state[7] = SHA256_H7;
10761b44c5a6SAntoine Ténart 
10771b44c5a6SAntoine Ténart 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
1078b869648cSAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
10791b44c5a6SAntoine Ténart 	req->state_sz = SHA256_DIGEST_SIZE;
10801b44c5a6SAntoine Ténart 
10811b44c5a6SAntoine Ténart 	return 0;
10821b44c5a6SAntoine Ténart }
10831b44c5a6SAntoine Ténart 
10841b44c5a6SAntoine Ténart static int safexcel_sha256_digest(struct ahash_request *areq)
10851b44c5a6SAntoine Ténart {
10861b44c5a6SAntoine Ténart 	int ret = safexcel_sha256_init(areq);
10871b44c5a6SAntoine Ténart 
10881b44c5a6SAntoine Ténart 	if (ret)
10891b44c5a6SAntoine Ténart 		return ret;
10901b44c5a6SAntoine Ténart 
10911b44c5a6SAntoine Ténart 	return safexcel_ahash_finup(areq);
10921b44c5a6SAntoine Ténart }
10931b44c5a6SAntoine Ténart 
10941b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_sha256 = {
10951b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
10965eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
10971b44c5a6SAntoine Ténart 	.alg.ahash = {
10981b44c5a6SAntoine Ténart 		.init = safexcel_sha256_init,
10991b44c5a6SAntoine Ténart 		.update = safexcel_ahash_update,
11001b44c5a6SAntoine Ténart 		.final = safexcel_ahash_final,
11011b44c5a6SAntoine Ténart 		.finup = safexcel_ahash_finup,
11021b44c5a6SAntoine Ténart 		.digest = safexcel_sha256_digest,
11031b44c5a6SAntoine Ténart 		.export = safexcel_ahash_export,
11041b44c5a6SAntoine Ténart 		.import = safexcel_ahash_import,
11051b44c5a6SAntoine Ténart 		.halg = {
11061b44c5a6SAntoine Ténart 			.digestsize = SHA256_DIGEST_SIZE,
11071b44c5a6SAntoine Ténart 			.statesize = sizeof(struct safexcel_ahash_export_state),
11081b44c5a6SAntoine Ténart 			.base = {
11091b44c5a6SAntoine Ténart 				.cra_name = "sha256",
11101b44c5a6SAntoine Ténart 				.cra_driver_name = "safexcel-sha256",
11111b44c5a6SAntoine Ténart 				.cra_priority = 300,
11121b44c5a6SAntoine Ténart 				.cra_flags = CRYPTO_ALG_ASYNC |
11131b44c5a6SAntoine Ténart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
11141b44c5a6SAntoine Ténart 				.cra_blocksize = SHA256_BLOCK_SIZE,
11151b44c5a6SAntoine Ténart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
11161b44c5a6SAntoine Ténart 				.cra_init = safexcel_ahash_cra_init,
11171b44c5a6SAntoine Ténart 				.cra_exit = safexcel_ahash_cra_exit,
11181b44c5a6SAntoine Ténart 				.cra_module = THIS_MODULE,
11191b44c5a6SAntoine Ténart 			},
11201b44c5a6SAntoine Ténart 		},
11211b44c5a6SAntoine Ténart 	},
11221b44c5a6SAntoine Ténart };
11231b44c5a6SAntoine Ténart 
11241b44c5a6SAntoine Ténart static int safexcel_sha224_init(struct ahash_request *areq)
11251b44c5a6SAntoine Ténart {
11261b44c5a6SAntoine Ténart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
11271b44c5a6SAntoine Ténart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
11281b44c5a6SAntoine Ténart 
11291b44c5a6SAntoine Ténart 	memset(req, 0, sizeof(*req));
11301b44c5a6SAntoine Ténart 
11311b44c5a6SAntoine Ténart 	req->state[0] = SHA224_H0;
11321b44c5a6SAntoine Ténart 	req->state[1] = SHA224_H1;
11331b44c5a6SAntoine Ténart 	req->state[2] = SHA224_H2;
11341b44c5a6SAntoine Ténart 	req->state[3] = SHA224_H3;
11351b44c5a6SAntoine Ténart 	req->state[4] = SHA224_H4;
11361b44c5a6SAntoine Ténart 	req->state[5] = SHA224_H5;
11371b44c5a6SAntoine Ténart 	req->state[6] = SHA224_H6;
11381b44c5a6SAntoine Ténart 	req->state[7] = SHA224_H7;
11391b44c5a6SAntoine Ténart 
11401b44c5a6SAntoine Ténart 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
1141b869648cSAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
11421b44c5a6SAntoine Ténart 	req->state_sz = SHA256_DIGEST_SIZE;
11431b44c5a6SAntoine Ténart 
11441b44c5a6SAntoine Ténart 	return 0;
11451b44c5a6SAntoine Ténart }
11461b44c5a6SAntoine Ténart 
11471b44c5a6SAntoine Ténart static int safexcel_sha224_digest(struct ahash_request *areq)
11481b44c5a6SAntoine Ténart {
11491b44c5a6SAntoine Ténart 	int ret = safexcel_sha224_init(areq);
11501b44c5a6SAntoine Ténart 
11511b44c5a6SAntoine Ténart 	if (ret)
11521b44c5a6SAntoine Ténart 		return ret;
11531b44c5a6SAntoine Ténart 
11541b44c5a6SAntoine Ténart 	return safexcel_ahash_finup(areq);
11551b44c5a6SAntoine Ténart }
11561b44c5a6SAntoine Ténart 
11571b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_sha224 = {
11581b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
11595eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
11601b44c5a6SAntoine Ténart 	.alg.ahash = {
11611b44c5a6SAntoine Ténart 		.init = safexcel_sha224_init,
11621b44c5a6SAntoine Ténart 		.update = safexcel_ahash_update,
11631b44c5a6SAntoine Ténart 		.final = safexcel_ahash_final,
11641b44c5a6SAntoine Ténart 		.finup = safexcel_ahash_finup,
11651b44c5a6SAntoine Ténart 		.digest = safexcel_sha224_digest,
11661b44c5a6SAntoine Ténart 		.export = safexcel_ahash_export,
11671b44c5a6SAntoine Ténart 		.import = safexcel_ahash_import,
11681b44c5a6SAntoine Ténart 		.halg = {
11691b44c5a6SAntoine Ténart 			.digestsize = SHA224_DIGEST_SIZE,
11701b44c5a6SAntoine Ténart 			.statesize = sizeof(struct safexcel_ahash_export_state),
11711b44c5a6SAntoine Ténart 			.base = {
11721b44c5a6SAntoine Ténart 				.cra_name = "sha224",
11731b44c5a6SAntoine Ténart 				.cra_driver_name = "safexcel-sha224",
11741b44c5a6SAntoine Ténart 				.cra_priority = 300,
11751b44c5a6SAntoine Ténart 				.cra_flags = CRYPTO_ALG_ASYNC |
11761b44c5a6SAntoine Ténart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
11771b44c5a6SAntoine Ténart 				.cra_blocksize = SHA224_BLOCK_SIZE,
11781b44c5a6SAntoine Ténart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
11791b44c5a6SAntoine Ténart 				.cra_init = safexcel_ahash_cra_init,
11801b44c5a6SAntoine Ténart 				.cra_exit = safexcel_ahash_cra_exit,
11811b44c5a6SAntoine Ténart 				.cra_module = THIS_MODULE,
11821b44c5a6SAntoine Ténart 			},
11831b44c5a6SAntoine Ténart 		},
11841b44c5a6SAntoine Ténart 	},
11851b44c5a6SAntoine Ténart };
118673f36ea7SAntoine Tenart 
11873ad618d8SAntoine Tenart static int safexcel_hmac_sha224_setkey(struct crypto_ahash *tfm, const u8 *key,
11883ad618d8SAntoine Tenart 				       unsigned int keylen)
11893ad618d8SAntoine Tenart {
11903ad618d8SAntoine Tenart 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha224",
11913ad618d8SAntoine Tenart 					SHA256_DIGEST_SIZE);
11923ad618d8SAntoine Tenart }
11933ad618d8SAntoine Tenart 
11943ad618d8SAntoine Tenart static int safexcel_hmac_sha224_init(struct ahash_request *areq)
11953ad618d8SAntoine Tenart {
11963ad618d8SAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
11973ad618d8SAntoine Tenart 
11983ad618d8SAntoine Tenart 	safexcel_sha224_init(areq);
11993ad618d8SAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
12003ad618d8SAntoine Tenart 	return 0;
12013ad618d8SAntoine Tenart }
12023ad618d8SAntoine Tenart 
12033ad618d8SAntoine Tenart static int safexcel_hmac_sha224_digest(struct ahash_request *areq)
12043ad618d8SAntoine Tenart {
12053ad618d8SAntoine Tenart 	int ret = safexcel_hmac_sha224_init(areq);
12063ad618d8SAntoine Tenart 
12073ad618d8SAntoine Tenart 	if (ret)
12083ad618d8SAntoine Tenart 		return ret;
12093ad618d8SAntoine Tenart 
12103ad618d8SAntoine Tenart 	return safexcel_ahash_finup(areq);
12113ad618d8SAntoine Tenart }
12123ad618d8SAntoine Tenart 
12133ad618d8SAntoine Tenart struct safexcel_alg_template safexcel_alg_hmac_sha224 = {
12143ad618d8SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
12155eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
12163ad618d8SAntoine Tenart 	.alg.ahash = {
12173ad618d8SAntoine Tenart 		.init = safexcel_hmac_sha224_init,
12183ad618d8SAntoine Tenart 		.update = safexcel_ahash_update,
12193ad618d8SAntoine Tenart 		.final = safexcel_ahash_final,
12203ad618d8SAntoine Tenart 		.finup = safexcel_ahash_finup,
12213ad618d8SAntoine Tenart 		.digest = safexcel_hmac_sha224_digest,
12223ad618d8SAntoine Tenart 		.setkey = safexcel_hmac_sha224_setkey,
12233ad618d8SAntoine Tenart 		.export = safexcel_ahash_export,
12243ad618d8SAntoine Tenart 		.import = safexcel_ahash_import,
12253ad618d8SAntoine Tenart 		.halg = {
12263ad618d8SAntoine Tenart 			.digestsize = SHA224_DIGEST_SIZE,
12273ad618d8SAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
12283ad618d8SAntoine Tenart 			.base = {
12293ad618d8SAntoine Tenart 				.cra_name = "hmac(sha224)",
12303ad618d8SAntoine Tenart 				.cra_driver_name = "safexcel-hmac-sha224",
12313ad618d8SAntoine Tenart 				.cra_priority = 300,
12323ad618d8SAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
12333ad618d8SAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
12343ad618d8SAntoine Tenart 				.cra_blocksize = SHA224_BLOCK_SIZE,
12353ad618d8SAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
12363ad618d8SAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
12373ad618d8SAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
12383ad618d8SAntoine Tenart 				.cra_module = THIS_MODULE,
12393ad618d8SAntoine Tenart 			},
12403ad618d8SAntoine Tenart 		},
12413ad618d8SAntoine Tenart 	},
12423ad618d8SAntoine Tenart };
12433ad618d8SAntoine Tenart 
124473f36ea7SAntoine Tenart static int safexcel_hmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key,
124573f36ea7SAntoine Tenart 				     unsigned int keylen)
124673f36ea7SAntoine Tenart {
124773f36ea7SAntoine Tenart 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha256",
124873f36ea7SAntoine Tenart 					SHA256_DIGEST_SIZE);
124973f36ea7SAntoine Tenart }
125073f36ea7SAntoine Tenart 
125173f36ea7SAntoine Tenart static int safexcel_hmac_sha256_init(struct ahash_request *areq)
125273f36ea7SAntoine Tenart {
125373f36ea7SAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
125473f36ea7SAntoine Tenart 
125573f36ea7SAntoine Tenart 	safexcel_sha256_init(areq);
125673f36ea7SAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
125773f36ea7SAntoine Tenart 	return 0;
125873f36ea7SAntoine Tenart }
125973f36ea7SAntoine Tenart 
126073f36ea7SAntoine Tenart static int safexcel_hmac_sha256_digest(struct ahash_request *areq)
126173f36ea7SAntoine Tenart {
126273f36ea7SAntoine Tenart 	int ret = safexcel_hmac_sha256_init(areq);
126373f36ea7SAntoine Tenart 
126473f36ea7SAntoine Tenart 	if (ret)
126573f36ea7SAntoine Tenart 		return ret;
126673f36ea7SAntoine Tenart 
126773f36ea7SAntoine Tenart 	return safexcel_ahash_finup(areq);
126873f36ea7SAntoine Tenart }
126973f36ea7SAntoine Tenart 
127073f36ea7SAntoine Tenart struct safexcel_alg_template safexcel_alg_hmac_sha256 = {
127173f36ea7SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
12725eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
127373f36ea7SAntoine Tenart 	.alg.ahash = {
127473f36ea7SAntoine Tenart 		.init = safexcel_hmac_sha256_init,
127573f36ea7SAntoine Tenart 		.update = safexcel_ahash_update,
127673f36ea7SAntoine Tenart 		.final = safexcel_ahash_final,
127773f36ea7SAntoine Tenart 		.finup = safexcel_ahash_finup,
127873f36ea7SAntoine Tenart 		.digest = safexcel_hmac_sha256_digest,
127973f36ea7SAntoine Tenart 		.setkey = safexcel_hmac_sha256_setkey,
128073f36ea7SAntoine Tenart 		.export = safexcel_ahash_export,
128173f36ea7SAntoine Tenart 		.import = safexcel_ahash_import,
128273f36ea7SAntoine Tenart 		.halg = {
128373f36ea7SAntoine Tenart 			.digestsize = SHA256_DIGEST_SIZE,
128473f36ea7SAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
128573f36ea7SAntoine Tenart 			.base = {
128673f36ea7SAntoine Tenart 				.cra_name = "hmac(sha256)",
128773f36ea7SAntoine Tenart 				.cra_driver_name = "safexcel-hmac-sha256",
128873f36ea7SAntoine Tenart 				.cra_priority = 300,
128973f36ea7SAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
129073f36ea7SAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
129173f36ea7SAntoine Tenart 				.cra_blocksize = SHA256_BLOCK_SIZE,
129273f36ea7SAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
129373f36ea7SAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
129473f36ea7SAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
129573f36ea7SAntoine Tenart 				.cra_module = THIS_MODULE,
129673f36ea7SAntoine Tenart 			},
129773f36ea7SAntoine Tenart 		},
129873f36ea7SAntoine Tenart 	},
129973f36ea7SAntoine Tenart };
1300b460edb6SAntoine Tenart 
1301b460edb6SAntoine Tenart static int safexcel_sha512_init(struct ahash_request *areq)
1302b460edb6SAntoine Tenart {
1303b460edb6SAntoine Tenart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
1304b460edb6SAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
1305b460edb6SAntoine Tenart 
1306b460edb6SAntoine Tenart 	memset(req, 0, sizeof(*req));
1307b460edb6SAntoine Tenart 
1308b460edb6SAntoine Tenart 	req->state[0] = lower_32_bits(SHA512_H0);
1309b460edb6SAntoine Tenart 	req->state[1] = upper_32_bits(SHA512_H0);
1310b460edb6SAntoine Tenart 	req->state[2] = lower_32_bits(SHA512_H1);
1311b460edb6SAntoine Tenart 	req->state[3] = upper_32_bits(SHA512_H1);
1312b460edb6SAntoine Tenart 	req->state[4] = lower_32_bits(SHA512_H2);
1313b460edb6SAntoine Tenart 	req->state[5] = upper_32_bits(SHA512_H2);
1314b460edb6SAntoine Tenart 	req->state[6] = lower_32_bits(SHA512_H3);
1315b460edb6SAntoine Tenart 	req->state[7] = upper_32_bits(SHA512_H3);
1316b460edb6SAntoine Tenart 	req->state[8] = lower_32_bits(SHA512_H4);
1317b460edb6SAntoine Tenart 	req->state[9] = upper_32_bits(SHA512_H4);
1318b460edb6SAntoine Tenart 	req->state[10] = lower_32_bits(SHA512_H5);
1319b460edb6SAntoine Tenart 	req->state[11] = upper_32_bits(SHA512_H5);
1320b460edb6SAntoine Tenart 	req->state[12] = lower_32_bits(SHA512_H6);
1321b460edb6SAntoine Tenart 	req->state[13] = upper_32_bits(SHA512_H6);
1322b460edb6SAntoine Tenart 	req->state[14] = lower_32_bits(SHA512_H7);
1323b460edb6SAntoine Tenart 	req->state[15] = upper_32_bits(SHA512_H7);
1324b460edb6SAntoine Tenart 
1325b460edb6SAntoine Tenart 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;
1326b460edb6SAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
1327b460edb6SAntoine Tenart 	req->state_sz = SHA512_DIGEST_SIZE;
1328b460edb6SAntoine Tenart 
1329b460edb6SAntoine Tenart 	return 0;
1330b460edb6SAntoine Tenart }
1331b460edb6SAntoine Tenart 
1332b460edb6SAntoine Tenart static int safexcel_sha512_digest(struct ahash_request *areq)
1333b460edb6SAntoine Tenart {
1334b460edb6SAntoine Tenart 	int ret = safexcel_sha512_init(areq);
1335b460edb6SAntoine Tenart 
1336b460edb6SAntoine Tenart 	if (ret)
1337b460edb6SAntoine Tenart 		return ret;
1338b460edb6SAntoine Tenart 
1339b460edb6SAntoine Tenart 	return safexcel_ahash_finup(areq);
1340b460edb6SAntoine Tenart }
1341b460edb6SAntoine Tenart 
1342b460edb6SAntoine Tenart struct safexcel_alg_template safexcel_alg_sha512 = {
1343b460edb6SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
13445eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
1345b460edb6SAntoine Tenart 	.alg.ahash = {
1346b460edb6SAntoine Tenart 		.init = safexcel_sha512_init,
1347b460edb6SAntoine Tenart 		.update = safexcel_ahash_update,
1348b460edb6SAntoine Tenart 		.final = safexcel_ahash_final,
1349b460edb6SAntoine Tenart 		.finup = safexcel_ahash_finup,
1350b460edb6SAntoine Tenart 		.digest = safexcel_sha512_digest,
1351b460edb6SAntoine Tenart 		.export = safexcel_ahash_export,
1352b460edb6SAntoine Tenart 		.import = safexcel_ahash_import,
1353b460edb6SAntoine Tenart 		.halg = {
1354b460edb6SAntoine Tenart 			.digestsize = SHA512_DIGEST_SIZE,
1355b460edb6SAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
1356b460edb6SAntoine Tenart 			.base = {
1357b460edb6SAntoine Tenart 				.cra_name = "sha512",
1358b460edb6SAntoine Tenart 				.cra_driver_name = "safexcel-sha512",
1359b460edb6SAntoine Tenart 				.cra_priority = 300,
1360b460edb6SAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
1361b460edb6SAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
1362b460edb6SAntoine Tenart 				.cra_blocksize = SHA512_BLOCK_SIZE,
1363b460edb6SAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
1364b460edb6SAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
1365b460edb6SAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
1366b460edb6SAntoine Tenart 				.cra_module = THIS_MODULE,
1367b460edb6SAntoine Tenart 			},
1368b460edb6SAntoine Tenart 		},
1369b460edb6SAntoine Tenart 	},
1370b460edb6SAntoine Tenart };
13710de54fb1SAntoine Tenart 
13729e46eafdSAntoine Tenart static int safexcel_sha384_init(struct ahash_request *areq)
13739e46eafdSAntoine Tenart {
13749e46eafdSAntoine Tenart 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
13759e46eafdSAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
13769e46eafdSAntoine Tenart 
13779e46eafdSAntoine Tenart 	memset(req, 0, sizeof(*req));
13789e46eafdSAntoine Tenart 
13799e46eafdSAntoine Tenart 	req->state[0] = lower_32_bits(SHA384_H0);
13809e46eafdSAntoine Tenart 	req->state[1] = upper_32_bits(SHA384_H0);
13819e46eafdSAntoine Tenart 	req->state[2] = lower_32_bits(SHA384_H1);
13829e46eafdSAntoine Tenart 	req->state[3] = upper_32_bits(SHA384_H1);
13839e46eafdSAntoine Tenart 	req->state[4] = lower_32_bits(SHA384_H2);
13849e46eafdSAntoine Tenart 	req->state[5] = upper_32_bits(SHA384_H2);
13859e46eafdSAntoine Tenart 	req->state[6] = lower_32_bits(SHA384_H3);
13869e46eafdSAntoine Tenart 	req->state[7] = upper_32_bits(SHA384_H3);
13879e46eafdSAntoine Tenart 	req->state[8] = lower_32_bits(SHA384_H4);
13889e46eafdSAntoine Tenart 	req->state[9] = upper_32_bits(SHA384_H4);
13899e46eafdSAntoine Tenart 	req->state[10] = lower_32_bits(SHA384_H5);
13909e46eafdSAntoine Tenart 	req->state[11] = upper_32_bits(SHA384_H5);
13919e46eafdSAntoine Tenart 	req->state[12] = lower_32_bits(SHA384_H6);
13929e46eafdSAntoine Tenart 	req->state[13] = upper_32_bits(SHA384_H6);
13939e46eafdSAntoine Tenart 	req->state[14] = lower_32_bits(SHA384_H7);
13949e46eafdSAntoine Tenart 	req->state[15] = upper_32_bits(SHA384_H7);
13959e46eafdSAntoine Tenart 
13969e46eafdSAntoine Tenart 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;
13979e46eafdSAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
13989e46eafdSAntoine Tenart 	req->state_sz = SHA512_DIGEST_SIZE;
13999e46eafdSAntoine Tenart 
14009e46eafdSAntoine Tenart 	return 0;
14019e46eafdSAntoine Tenart }
14029e46eafdSAntoine Tenart 
14039e46eafdSAntoine Tenart static int safexcel_sha384_digest(struct ahash_request *areq)
14049e46eafdSAntoine Tenart {
14059e46eafdSAntoine Tenart 	int ret = safexcel_sha384_init(areq);
14069e46eafdSAntoine Tenart 
14079e46eafdSAntoine Tenart 	if (ret)
14089e46eafdSAntoine Tenart 		return ret;
14099e46eafdSAntoine Tenart 
14109e46eafdSAntoine Tenart 	return safexcel_ahash_finup(areq);
14119e46eafdSAntoine Tenart }
14129e46eafdSAntoine Tenart 
14139e46eafdSAntoine Tenart struct safexcel_alg_template safexcel_alg_sha384 = {
14149e46eafdSAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
14155eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
14169e46eafdSAntoine Tenart 	.alg.ahash = {
14179e46eafdSAntoine Tenart 		.init = safexcel_sha384_init,
14189e46eafdSAntoine Tenart 		.update = safexcel_ahash_update,
14199e46eafdSAntoine Tenart 		.final = safexcel_ahash_final,
14209e46eafdSAntoine Tenart 		.finup = safexcel_ahash_finup,
14219e46eafdSAntoine Tenart 		.digest = safexcel_sha384_digest,
14229e46eafdSAntoine Tenart 		.export = safexcel_ahash_export,
14239e46eafdSAntoine Tenart 		.import = safexcel_ahash_import,
14249e46eafdSAntoine Tenart 		.halg = {
14259e46eafdSAntoine Tenart 			.digestsize = SHA384_DIGEST_SIZE,
14269e46eafdSAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
14279e46eafdSAntoine Tenart 			.base = {
14289e46eafdSAntoine Tenart 				.cra_name = "sha384",
14299e46eafdSAntoine Tenart 				.cra_driver_name = "safexcel-sha384",
14309e46eafdSAntoine Tenart 				.cra_priority = 300,
14319e46eafdSAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
14329e46eafdSAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
14339e46eafdSAntoine Tenart 				.cra_blocksize = SHA384_BLOCK_SIZE,
14349e46eafdSAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
14359e46eafdSAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
14369e46eafdSAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
14379e46eafdSAntoine Tenart 				.cra_module = THIS_MODULE,
14389e46eafdSAntoine Tenart 			},
14399e46eafdSAntoine Tenart 		},
14409e46eafdSAntoine Tenart 	},
14419e46eafdSAntoine Tenart };
14429e46eafdSAntoine Tenart 
14430de54fb1SAntoine Tenart static int safexcel_hmac_sha512_setkey(struct crypto_ahash *tfm, const u8 *key,
14440de54fb1SAntoine Tenart 				       unsigned int keylen)
14450de54fb1SAntoine Tenart {
14460de54fb1SAntoine Tenart 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha512",
14470de54fb1SAntoine Tenart 					SHA512_DIGEST_SIZE);
14480de54fb1SAntoine Tenart }
14490de54fb1SAntoine Tenart 
14500de54fb1SAntoine Tenart static int safexcel_hmac_sha512_init(struct ahash_request *areq)
14510de54fb1SAntoine Tenart {
14520de54fb1SAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
14530de54fb1SAntoine Tenart 
14540de54fb1SAntoine Tenart 	safexcel_sha512_init(areq);
14550de54fb1SAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
14560de54fb1SAntoine Tenart 	return 0;
14570de54fb1SAntoine Tenart }
14580de54fb1SAntoine Tenart 
14590de54fb1SAntoine Tenart static int safexcel_hmac_sha512_digest(struct ahash_request *areq)
14600de54fb1SAntoine Tenart {
14610de54fb1SAntoine Tenart 	int ret = safexcel_hmac_sha512_init(areq);
14620de54fb1SAntoine Tenart 
14630de54fb1SAntoine Tenart 	if (ret)
14640de54fb1SAntoine Tenart 		return ret;
14650de54fb1SAntoine Tenart 
14660de54fb1SAntoine Tenart 	return safexcel_ahash_finup(areq);
14670de54fb1SAntoine Tenart }
14680de54fb1SAntoine Tenart 
14690de54fb1SAntoine Tenart struct safexcel_alg_template safexcel_alg_hmac_sha512 = {
14700de54fb1SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
14715eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
14720de54fb1SAntoine Tenart 	.alg.ahash = {
14730de54fb1SAntoine Tenart 		.init = safexcel_hmac_sha512_init,
14740de54fb1SAntoine Tenart 		.update = safexcel_ahash_update,
14750de54fb1SAntoine Tenart 		.final = safexcel_ahash_final,
14760de54fb1SAntoine Tenart 		.finup = safexcel_ahash_finup,
14770de54fb1SAntoine Tenart 		.digest = safexcel_hmac_sha512_digest,
14780de54fb1SAntoine Tenart 		.setkey = safexcel_hmac_sha512_setkey,
14790de54fb1SAntoine Tenart 		.export = safexcel_ahash_export,
14800de54fb1SAntoine Tenart 		.import = safexcel_ahash_import,
14810de54fb1SAntoine Tenart 		.halg = {
14820de54fb1SAntoine Tenart 			.digestsize = SHA512_DIGEST_SIZE,
14830de54fb1SAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
14840de54fb1SAntoine Tenart 			.base = {
14850de54fb1SAntoine Tenart 				.cra_name = "hmac(sha512)",
14860de54fb1SAntoine Tenart 				.cra_driver_name = "safexcel-hmac-sha512",
14870de54fb1SAntoine Tenart 				.cra_priority = 300,
14880de54fb1SAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
14890de54fb1SAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
14900de54fb1SAntoine Tenart 				.cra_blocksize = SHA512_BLOCK_SIZE,
14910de54fb1SAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
14920de54fb1SAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
14930de54fb1SAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
14940de54fb1SAntoine Tenart 				.cra_module = THIS_MODULE,
14950de54fb1SAntoine Tenart 			},
14960de54fb1SAntoine Tenart 		},
14970de54fb1SAntoine Tenart 	},
14980de54fb1SAntoine Tenart };
14991f5d5d98SAntoine Tenart 
15001f5d5d98SAntoine Tenart static int safexcel_hmac_sha384_setkey(struct crypto_ahash *tfm, const u8 *key,
15011f5d5d98SAntoine Tenart 				       unsigned int keylen)
15021f5d5d98SAntoine Tenart {
15031f5d5d98SAntoine Tenart 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha384",
15041f5d5d98SAntoine Tenart 					SHA512_DIGEST_SIZE);
15051f5d5d98SAntoine Tenart }
15061f5d5d98SAntoine Tenart 
15071f5d5d98SAntoine Tenart static int safexcel_hmac_sha384_init(struct ahash_request *areq)
15081f5d5d98SAntoine Tenart {
15091f5d5d98SAntoine Tenart 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
15101f5d5d98SAntoine Tenart 
15111f5d5d98SAntoine Tenart 	safexcel_sha384_init(areq);
15121f5d5d98SAntoine Tenart 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
15131f5d5d98SAntoine Tenart 	return 0;
15141f5d5d98SAntoine Tenart }
15151f5d5d98SAntoine Tenart 
15161f5d5d98SAntoine Tenart static int safexcel_hmac_sha384_digest(struct ahash_request *areq)
15171f5d5d98SAntoine Tenart {
15181f5d5d98SAntoine Tenart 	int ret = safexcel_hmac_sha384_init(areq);
15191f5d5d98SAntoine Tenart 
15201f5d5d98SAntoine Tenart 	if (ret)
15211f5d5d98SAntoine Tenart 		return ret;
15221f5d5d98SAntoine Tenart 
15231f5d5d98SAntoine Tenart 	return safexcel_ahash_finup(areq);
15241f5d5d98SAntoine Tenart }
15251f5d5d98SAntoine Tenart 
15261f5d5d98SAntoine Tenart struct safexcel_alg_template safexcel_alg_hmac_sha384 = {
15271f5d5d98SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AHASH,
15285eb09118SAntoine Tenart 	.engines = EIP97IES | EIP197B | EIP197D,
15291f5d5d98SAntoine Tenart 	.alg.ahash = {
15301f5d5d98SAntoine Tenart 		.init = safexcel_hmac_sha384_init,
15311f5d5d98SAntoine Tenart 		.update = safexcel_ahash_update,
15321f5d5d98SAntoine Tenart 		.final = safexcel_ahash_final,
15331f5d5d98SAntoine Tenart 		.finup = safexcel_ahash_finup,
15341f5d5d98SAntoine Tenart 		.digest = safexcel_hmac_sha384_digest,
15351f5d5d98SAntoine Tenart 		.setkey = safexcel_hmac_sha384_setkey,
15361f5d5d98SAntoine Tenart 		.export = safexcel_ahash_export,
15371f5d5d98SAntoine Tenart 		.import = safexcel_ahash_import,
15381f5d5d98SAntoine Tenart 		.halg = {
15391f5d5d98SAntoine Tenart 			.digestsize = SHA384_DIGEST_SIZE,
15401f5d5d98SAntoine Tenart 			.statesize = sizeof(struct safexcel_ahash_export_state),
15411f5d5d98SAntoine Tenart 			.base = {
15421f5d5d98SAntoine Tenart 				.cra_name = "hmac(sha384)",
15431f5d5d98SAntoine Tenart 				.cra_driver_name = "safexcel-hmac-sha384",
15441f5d5d98SAntoine Tenart 				.cra_priority = 300,
15451f5d5d98SAntoine Tenart 				.cra_flags = CRYPTO_ALG_ASYNC |
15461f5d5d98SAntoine Tenart 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
15471f5d5d98SAntoine Tenart 				.cra_blocksize = SHA384_BLOCK_SIZE,
15481f5d5d98SAntoine Tenart 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
15491f5d5d98SAntoine Tenart 				.cra_init = safexcel_ahash_cra_init,
15501f5d5d98SAntoine Tenart 				.cra_exit = safexcel_ahash_cra_exit,
15511f5d5d98SAntoine Tenart 				.cra_module = THIS_MODULE,
15521f5d5d98SAntoine Tenart 			},
15531f5d5d98SAntoine Tenart 		},
15541f5d5d98SAntoine Tenart 	},
15551f5d5d98SAntoine Tenart };
1556293f89cfSOfer Heifetz 
1557293f89cfSOfer Heifetz static int safexcel_md5_init(struct ahash_request *areq)
1558293f89cfSOfer Heifetz {
1559293f89cfSOfer Heifetz 	struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
1560293f89cfSOfer Heifetz 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
1561293f89cfSOfer Heifetz 
1562293f89cfSOfer Heifetz 	memset(req, 0, sizeof(*req));
1563293f89cfSOfer Heifetz 
1564293f89cfSOfer Heifetz 	req->state[0] = MD5_H0;
1565293f89cfSOfer Heifetz 	req->state[1] = MD5_H1;
1566293f89cfSOfer Heifetz 	req->state[2] = MD5_H2;
1567293f89cfSOfer Heifetz 	req->state[3] = MD5_H3;
1568293f89cfSOfer Heifetz 
1569293f89cfSOfer Heifetz 	ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_MD5;
1570293f89cfSOfer Heifetz 	req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
1571293f89cfSOfer Heifetz 	req->state_sz = MD5_DIGEST_SIZE;
1572293f89cfSOfer Heifetz 
1573293f89cfSOfer Heifetz 	return 0;
1574293f89cfSOfer Heifetz }
1575293f89cfSOfer Heifetz 
1576293f89cfSOfer Heifetz static int safexcel_md5_digest(struct ahash_request *areq)
1577293f89cfSOfer Heifetz {
1578293f89cfSOfer Heifetz 	int ret = safexcel_md5_init(areq);
1579293f89cfSOfer Heifetz 
1580293f89cfSOfer Heifetz 	if (ret)
1581293f89cfSOfer Heifetz 		return ret;
1582293f89cfSOfer Heifetz 
1583293f89cfSOfer Heifetz 	return safexcel_ahash_finup(areq);
1584293f89cfSOfer Heifetz }
1585293f89cfSOfer Heifetz 
1586293f89cfSOfer Heifetz struct safexcel_alg_template safexcel_alg_md5 = {
1587293f89cfSOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_AHASH,
1588293f89cfSOfer Heifetz 	.engines = EIP97IES | EIP197B | EIP197D,
1589293f89cfSOfer Heifetz 	.alg.ahash = {
1590293f89cfSOfer Heifetz 		.init = safexcel_md5_init,
1591293f89cfSOfer Heifetz 		.update = safexcel_ahash_update,
1592293f89cfSOfer Heifetz 		.final = safexcel_ahash_final,
1593293f89cfSOfer Heifetz 		.finup = safexcel_ahash_finup,
1594293f89cfSOfer Heifetz 		.digest = safexcel_md5_digest,
1595293f89cfSOfer Heifetz 		.export = safexcel_ahash_export,
1596293f89cfSOfer Heifetz 		.import = safexcel_ahash_import,
1597293f89cfSOfer Heifetz 		.halg = {
1598293f89cfSOfer Heifetz 			.digestsize = MD5_DIGEST_SIZE,
1599293f89cfSOfer Heifetz 			.statesize = sizeof(struct safexcel_ahash_export_state),
1600293f89cfSOfer Heifetz 			.base = {
1601293f89cfSOfer Heifetz 				.cra_name = "md5",
1602293f89cfSOfer Heifetz 				.cra_driver_name = "safexcel-md5",
1603293f89cfSOfer Heifetz 				.cra_priority = 300,
1604293f89cfSOfer Heifetz 				.cra_flags = CRYPTO_ALG_ASYNC |
1605293f89cfSOfer Heifetz 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
1606293f89cfSOfer Heifetz 				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
1607293f89cfSOfer Heifetz 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
1608293f89cfSOfer Heifetz 				.cra_init = safexcel_ahash_cra_init,
1609293f89cfSOfer Heifetz 				.cra_exit = safexcel_ahash_cra_exit,
1610293f89cfSOfer Heifetz 				.cra_module = THIS_MODULE,
1611293f89cfSOfer Heifetz 			},
1612293f89cfSOfer Heifetz 		},
1613293f89cfSOfer Heifetz 	},
1614293f89cfSOfer Heifetz };
1615b471e4b9SOfer Heifetz 
1616b471e4b9SOfer Heifetz static int safexcel_hmac_md5_init(struct ahash_request *areq)
1617b471e4b9SOfer Heifetz {
1618b471e4b9SOfer Heifetz 	struct safexcel_ahash_req *req = ahash_request_ctx(areq);
1619b471e4b9SOfer Heifetz 
1620b471e4b9SOfer Heifetz 	safexcel_md5_init(areq);
1621b471e4b9SOfer Heifetz 	req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
1622b471e4b9SOfer Heifetz 	return 0;
1623b471e4b9SOfer Heifetz }
1624b471e4b9SOfer Heifetz 
1625b471e4b9SOfer Heifetz static int safexcel_hmac_md5_setkey(struct crypto_ahash *tfm, const u8 *key,
1626b471e4b9SOfer Heifetz 				     unsigned int keylen)
1627b471e4b9SOfer Heifetz {
1628b471e4b9SOfer Heifetz 	return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-md5",
1629b471e4b9SOfer Heifetz 					MD5_DIGEST_SIZE);
1630b471e4b9SOfer Heifetz }
1631b471e4b9SOfer Heifetz 
1632b471e4b9SOfer Heifetz static int safexcel_hmac_md5_digest(struct ahash_request *areq)
1633b471e4b9SOfer Heifetz {
1634b471e4b9SOfer Heifetz 	int ret = safexcel_hmac_md5_init(areq);
1635b471e4b9SOfer Heifetz 
1636b471e4b9SOfer Heifetz 	if (ret)
1637b471e4b9SOfer Heifetz 		return ret;
1638b471e4b9SOfer Heifetz 
1639b471e4b9SOfer Heifetz 	return safexcel_ahash_finup(areq);
1640b471e4b9SOfer Heifetz }
1641b471e4b9SOfer Heifetz 
1642b471e4b9SOfer Heifetz struct safexcel_alg_template safexcel_alg_hmac_md5 = {
1643b471e4b9SOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_AHASH,
1644b471e4b9SOfer Heifetz 	.engines = EIP97IES | EIP197B | EIP197D,
1645b471e4b9SOfer Heifetz 	.alg.ahash = {
1646b471e4b9SOfer Heifetz 		.init = safexcel_hmac_md5_init,
1647b471e4b9SOfer Heifetz 		.update = safexcel_ahash_update,
1648b471e4b9SOfer Heifetz 		.final = safexcel_ahash_final,
1649b471e4b9SOfer Heifetz 		.finup = safexcel_ahash_finup,
1650b471e4b9SOfer Heifetz 		.digest = safexcel_hmac_md5_digest,
1651b471e4b9SOfer Heifetz 		.setkey = safexcel_hmac_md5_setkey,
1652b471e4b9SOfer Heifetz 		.export = safexcel_ahash_export,
1653b471e4b9SOfer Heifetz 		.import = safexcel_ahash_import,
1654b471e4b9SOfer Heifetz 		.halg = {
1655b471e4b9SOfer Heifetz 			.digestsize = MD5_DIGEST_SIZE,
1656b471e4b9SOfer Heifetz 			.statesize = sizeof(struct safexcel_ahash_export_state),
1657b471e4b9SOfer Heifetz 			.base = {
1658b471e4b9SOfer Heifetz 				.cra_name = "hmac(md5)",
1659b471e4b9SOfer Heifetz 				.cra_driver_name = "safexcel-hmac-md5",
1660b471e4b9SOfer Heifetz 				.cra_priority = 300,
1661b471e4b9SOfer Heifetz 				.cra_flags = CRYPTO_ALG_ASYNC |
1662b471e4b9SOfer Heifetz 					     CRYPTO_ALG_KERN_DRIVER_ONLY,
1663b471e4b9SOfer Heifetz 				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
1664b471e4b9SOfer Heifetz 				.cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
1665b471e4b9SOfer Heifetz 				.cra_init = safexcel_ahash_cra_init,
1666b471e4b9SOfer Heifetz 				.cra_exit = safexcel_ahash_cra_exit,
1667b471e4b9SOfer Heifetz 				.cra_module = THIS_MODULE,
1668b471e4b9SOfer Heifetz 			},
1669b471e4b9SOfer Heifetz 		},
1670b471e4b9SOfer Heifetz 	},
1671b471e4b9SOfer Heifetz };
1672