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