162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Hash function and HMAC support for StarFive driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2022 StarFive Technology 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <crypto/engine.h> 1062306a36Sopenharmony_ci#include <crypto/internal/hash.h> 1162306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 1262306a36Sopenharmony_ci#include "jh7110-cryp.h" 1362306a36Sopenharmony_ci#include <linux/amba/pl080.h> 1462306a36Sopenharmony_ci#include <linux/clk.h> 1562306a36Sopenharmony_ci#include <linux/dma-direct.h> 1662306a36Sopenharmony_ci#include <linux/interrupt.h> 1762306a36Sopenharmony_ci#include <linux/iopoll.h> 1862306a36Sopenharmony_ci#include <linux/kernel.h> 1962306a36Sopenharmony_ci#include <linux/module.h> 2062306a36Sopenharmony_ci#include <linux/platform_device.h> 2162306a36Sopenharmony_ci#include <linux/pm_runtime.h> 2262306a36Sopenharmony_ci#include <linux/reset.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define STARFIVE_HASH_REGS_OFFSET 0x300 2562306a36Sopenharmony_ci#define STARFIVE_HASH_SHACSR (STARFIVE_HASH_REGS_OFFSET + 0x0) 2662306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWDR (STARFIVE_HASH_REGS_OFFSET + 0x4) 2762306a36Sopenharmony_ci#define STARFIVE_HASH_SHARDR (STARFIVE_HASH_REGS_OFFSET + 0x8) 2862306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWSR (STARFIVE_HASH_REGS_OFFSET + 0xC) 2962306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWLEN3 (STARFIVE_HASH_REGS_OFFSET + 0x10) 3062306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWLEN2 (STARFIVE_HASH_REGS_OFFSET + 0x14) 3162306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWLEN1 (STARFIVE_HASH_REGS_OFFSET + 0x18) 3262306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWLEN0 (STARFIVE_HASH_REGS_OFFSET + 0x1C) 3362306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWKR (STARFIVE_HASH_REGS_OFFSET + 0x20) 3462306a36Sopenharmony_ci#define STARFIVE_HASH_SHAWKLEN (STARFIVE_HASH_REGS_OFFSET + 0x24) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define STARFIVE_HASH_BUFLEN SHA512_BLOCK_SIZE 3762306a36Sopenharmony_ci#define STARFIVE_HASH_RESET 0x2 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic inline int starfive_hash_wait_busy(struct starfive_cryp_ctx *ctx) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 4262306a36Sopenharmony_ci u32 status; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, 4562306a36Sopenharmony_ci !(status & STARFIVE_HASH_BUSY), 10, 100000); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic inline int starfive_hash_wait_key_done(struct starfive_cryp_ctx *ctx) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 5162306a36Sopenharmony_ci u32 status; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, 5462306a36Sopenharmony_ci (status & STARFIVE_HASH_KEY_DONE), 10, 100000); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic int starfive_hash_hmac_key(struct starfive_cryp_ctx *ctx) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 6062306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 6162306a36Sopenharmony_ci int klen = ctx->keylen, loop; 6262306a36Sopenharmony_ci unsigned int *key = (unsigned int *)ctx->key; 6362306a36Sopenharmony_ci unsigned char *cl; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci writel(ctx->keylen, cryp->base + STARFIVE_HASH_SHAWKLEN); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci rctx->csr.hash.hmac = 1; 6862306a36Sopenharmony_ci rctx->csr.hash.key_flag = 1; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci for (loop = 0; loop < klen / sizeof(unsigned int); loop++, key++) 7362306a36Sopenharmony_ci writel(*key, cryp->base + STARFIVE_HASH_SHAWKR); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci if (klen & 0x3) { 7662306a36Sopenharmony_ci cl = (unsigned char *)key; 7762306a36Sopenharmony_ci for (loop = 0; loop < (klen & 0x3); loop++, cl++) 7862306a36Sopenharmony_ci writeb(*cl, cryp->base + STARFIVE_HASH_SHAWKR); 7962306a36Sopenharmony_ci } 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (starfive_hash_wait_key_done(ctx)) 8262306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ETIMEDOUT, "starfive_hash_wait_key_done error\n"); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci return 0; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic void starfive_hash_start(void *param) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = param; 9062306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 9162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 9262306a36Sopenharmony_ci union starfive_alg_cr alg_cr; 9362306a36Sopenharmony_ci union starfive_hash_csr csr; 9462306a36Sopenharmony_ci u32 stat; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci dma_unmap_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci alg_cr.v = 0; 9962306a36Sopenharmony_ci alg_cr.clear = 1; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci csr.v = readl(cryp->base + STARFIVE_HASH_SHACSR); 10462306a36Sopenharmony_ci csr.firstb = 0; 10562306a36Sopenharmony_ci csr.final = 1; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET); 10862306a36Sopenharmony_ci stat &= ~STARFIVE_IE_MASK_HASH_DONE; 10962306a36Sopenharmony_ci writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET); 11062306a36Sopenharmony_ci writel(csr.v, cryp->base + STARFIVE_HASH_SHACSR); 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic int starfive_hash_xmit_dma(struct starfive_cryp_ctx *ctx) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 11662306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 11762306a36Sopenharmony_ci struct dma_async_tx_descriptor *in_desc; 11862306a36Sopenharmony_ci union starfive_alg_cr alg_cr; 11962306a36Sopenharmony_ci int total_len; 12062306a36Sopenharmony_ci int ret; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (!rctx->total) { 12362306a36Sopenharmony_ci starfive_hash_start(ctx); 12462306a36Sopenharmony_ci return 0; 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci writel(rctx->total, cryp->base + STARFIVE_DMA_IN_LEN_OFFSET); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci total_len = rctx->total; 13062306a36Sopenharmony_ci total_len = (total_len & 0x3) ? (((total_len >> 2) + 1) << 2) : total_len; 13162306a36Sopenharmony_ci sg_dma_len(rctx->in_sg) = total_len; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci alg_cr.v = 0; 13462306a36Sopenharmony_ci alg_cr.start = 1; 13562306a36Sopenharmony_ci alg_cr.hash_dma_en = 1; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci ret = dma_map_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); 14062306a36Sopenharmony_ci if (!ret) 14162306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -EINVAL, "dma_map_sg() error\n"); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci cryp->cfg_in.direction = DMA_MEM_TO_DEV; 14462306a36Sopenharmony_ci cryp->cfg_in.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 14562306a36Sopenharmony_ci cryp->cfg_in.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 14662306a36Sopenharmony_ci cryp->cfg_in.src_maxburst = cryp->dma_maxburst; 14762306a36Sopenharmony_ci cryp->cfg_in.dst_maxburst = cryp->dma_maxburst; 14862306a36Sopenharmony_ci cryp->cfg_in.dst_addr = cryp->phys_base + STARFIVE_ALG_FIFO_OFFSET; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci dmaengine_slave_config(cryp->tx, &cryp->cfg_in); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci in_desc = dmaengine_prep_slave_sg(cryp->tx, rctx->in_sg, 15362306a36Sopenharmony_ci ret, DMA_MEM_TO_DEV, 15462306a36Sopenharmony_ci DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if (!in_desc) 15762306a36Sopenharmony_ci return -EINVAL; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci in_desc->callback = starfive_hash_start; 16062306a36Sopenharmony_ci in_desc->callback_param = ctx; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci dmaengine_submit(in_desc); 16362306a36Sopenharmony_ci dma_async_issue_pending(cryp->tx); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci return 0; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic int starfive_hash_xmit(struct starfive_cryp_ctx *ctx) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 17162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 17262306a36Sopenharmony_ci int ret = 0; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci rctx->csr.hash.v = 0; 17562306a36Sopenharmony_ci rctx->csr.hash.reset = 1; 17662306a36Sopenharmony_ci writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci if (starfive_hash_wait_busy(ctx)) 17962306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ETIMEDOUT, "Error resetting engine.\n"); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci rctx->csr.hash.v = 0; 18262306a36Sopenharmony_ci rctx->csr.hash.mode = ctx->hash_mode; 18362306a36Sopenharmony_ci rctx->csr.hash.ie = 1; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci if (ctx->is_hmac) { 18662306a36Sopenharmony_ci ret = starfive_hash_hmac_key(ctx); 18762306a36Sopenharmony_ci if (ret) 18862306a36Sopenharmony_ci return ret; 18962306a36Sopenharmony_ci } else { 19062306a36Sopenharmony_ci rctx->csr.hash.start = 1; 19162306a36Sopenharmony_ci rctx->csr.hash.firstb = 1; 19262306a36Sopenharmony_ci writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci return starfive_hash_xmit_dma(ctx); 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic int starfive_hash_copy_hash(struct ahash_request *req) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 20162306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 20262306a36Sopenharmony_ci int count, *data; 20362306a36Sopenharmony_ci int mlen; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci if (!req->result) 20662306a36Sopenharmony_ci return 0; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci mlen = rctx->digsize / sizeof(u32); 20962306a36Sopenharmony_ci data = (u32 *)req->result; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci for (count = 0; count < mlen; count++) 21262306a36Sopenharmony_ci data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci return 0; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_civoid starfive_hash_done_task(unsigned long param) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)param; 22062306a36Sopenharmony_ci int err = cryp->err; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci if (!err) 22362306a36Sopenharmony_ci err = starfive_hash_copy_hash(cryp->req.hreq); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* Reset to clear hash_done in irq register*/ 22662306a36Sopenharmony_ci writel(STARFIVE_HASH_RESET, cryp->base + STARFIVE_HASH_SHACSR); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci crypto_finalize_hash_request(cryp->engine, cryp->req.hreq, err); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic int starfive_hash_check_aligned(struct scatterlist *sg, size_t total, size_t align) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci int len = 0; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci if (!total) 23662306a36Sopenharmony_ci return 0; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci if (!IS_ALIGNED(total, align)) 23962306a36Sopenharmony_ci return -EINVAL; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci while (sg) { 24262306a36Sopenharmony_ci if (!IS_ALIGNED(sg->offset, sizeof(u32))) 24362306a36Sopenharmony_ci return -EINVAL; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (!IS_ALIGNED(sg->length, align)) 24662306a36Sopenharmony_ci return -EINVAL; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci len += sg->length; 24962306a36Sopenharmony_ci sg = sg_next(sg); 25062306a36Sopenharmony_ci } 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci if (len != total) 25362306a36Sopenharmony_ci return -EINVAL; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci return 0; 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic int starfive_hash_one_request(struct crypto_engine *engine, void *areq) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci struct ahash_request *req = container_of(areq, struct ahash_request, 26162306a36Sopenharmony_ci base); 26262306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 26362306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (!cryp) 26662306a36Sopenharmony_ci return -ENODEV; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci return starfive_hash_xmit(ctx); 26962306a36Sopenharmony_ci} 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic int starfive_hash_init(struct ahash_request *req) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 27462306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 27562306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 27862306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 27962306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 28062306a36Sopenharmony_ci req->base.complete, req->base.data); 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 28362306a36Sopenharmony_ci req->result, req->nbytes); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci return crypto_ahash_init(&rctx->ahash_fbk_req); 28662306a36Sopenharmony_ci} 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_cistatic int starfive_hash_update(struct ahash_request *req) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 29162306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 29262306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 29562306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 29662306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 29762306a36Sopenharmony_ci req->base.complete, req->base.data); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 30062306a36Sopenharmony_ci req->result, req->nbytes); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci return crypto_ahash_update(&rctx->ahash_fbk_req); 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_cistatic int starfive_hash_final(struct ahash_request *req) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 30862306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 30962306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 31262306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 31362306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 31462306a36Sopenharmony_ci req->base.complete, req->base.data); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 31762306a36Sopenharmony_ci req->result, req->nbytes); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci return crypto_ahash_final(&rctx->ahash_fbk_req); 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cistatic int starfive_hash_finup(struct ahash_request *req) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 32562306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 32662306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 32962306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 33062306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 33162306a36Sopenharmony_ci req->base.complete, req->base.data); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 33462306a36Sopenharmony_ci req->result, req->nbytes); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci return crypto_ahash_finup(&rctx->ahash_fbk_req); 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic int starfive_hash_digest_fb(struct ahash_request *req) 34062306a36Sopenharmony_ci{ 34162306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 34262306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 34362306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 34662306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, req->base.flags, 34762306a36Sopenharmony_ci req->base.complete, req->base.data); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, 35062306a36Sopenharmony_ci req->result, req->nbytes); 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci return crypto_ahash_digest(&rctx->ahash_fbk_req); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic int starfive_hash_digest(struct ahash_request *req) 35662306a36Sopenharmony_ci{ 35762306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 35862306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 35962306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 36062306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci cryp->req.hreq = req; 36562306a36Sopenharmony_ci rctx->total = req->nbytes; 36662306a36Sopenharmony_ci rctx->in_sg = req->src; 36762306a36Sopenharmony_ci rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); 36862306a36Sopenharmony_ci rctx->digsize = crypto_ahash_digestsize(tfm); 36962306a36Sopenharmony_ci rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); 37062306a36Sopenharmony_ci ctx->rctx = rctx; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize)) 37362306a36Sopenharmony_ci return starfive_hash_digest_fb(req); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci return crypto_transfer_hash_request_to_engine(cryp->engine, req); 37662306a36Sopenharmony_ci} 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistatic int starfive_hash_export(struct ahash_request *req, void *out) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 38162306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 38262306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 38562306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 38662306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 38762306a36Sopenharmony_ci req->base.complete, req->base.data); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci return crypto_ahash_export(&rctx->ahash_fbk_req, out); 39062306a36Sopenharmony_ci} 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_cistatic int starfive_hash_import(struct ahash_request *req, const void *in) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); 39562306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 39662306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); 39962306a36Sopenharmony_ci ahash_request_set_callback(&rctx->ahash_fbk_req, 40062306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, 40162306a36Sopenharmony_ci req->base.complete, req->base.data); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci return crypto_ahash_import(&rctx->ahash_fbk_req, in); 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic int starfive_hash_init_tfm(struct crypto_ahash *hash, 40762306a36Sopenharmony_ci const char *alg_name, 40862306a36Sopenharmony_ci unsigned int mode) 40962306a36Sopenharmony_ci{ 41062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci ctx->cryp = starfive_cryp_find_dev(ctx); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci if (!ctx->cryp) 41562306a36Sopenharmony_ci return -ENODEV; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci ctx->ahash_fbk = crypto_alloc_ahash(alg_name, 0, 41862306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci if (IS_ERR(ctx->ahash_fbk)) 42162306a36Sopenharmony_ci return dev_err_probe(ctx->cryp->dev, PTR_ERR(ctx->ahash_fbk), 42262306a36Sopenharmony_ci "starfive_hash: Could not load fallback driver.\n"); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci crypto_ahash_set_statesize(hash, crypto_ahash_statesize(ctx->ahash_fbk)); 42562306a36Sopenharmony_ci crypto_ahash_set_reqsize(hash, sizeof(struct starfive_cryp_request_ctx) + 42662306a36Sopenharmony_ci crypto_ahash_reqsize(ctx->ahash_fbk)); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci ctx->keylen = 0; 42962306a36Sopenharmony_ci ctx->hash_mode = mode; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci return 0; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic void starfive_hash_exit_tfm(struct crypto_ahash *hash) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci crypto_free_ahash(ctx->ahash_fbk); 43962306a36Sopenharmony_ci} 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_cistatic int starfive_hash_long_setkey(struct starfive_cryp_ctx *ctx, 44262306a36Sopenharmony_ci const u8 *key, unsigned int keylen, 44362306a36Sopenharmony_ci const char *alg_name) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci struct crypto_wait wait; 44662306a36Sopenharmony_ci struct ahash_request *req; 44762306a36Sopenharmony_ci struct scatterlist sg; 44862306a36Sopenharmony_ci struct crypto_ahash *ahash_tfm; 44962306a36Sopenharmony_ci u8 *buf; 45062306a36Sopenharmony_ci int ret; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); 45362306a36Sopenharmony_ci if (IS_ERR(ahash_tfm)) 45462306a36Sopenharmony_ci return PTR_ERR(ahash_tfm); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); 45762306a36Sopenharmony_ci if (!req) { 45862306a36Sopenharmony_ci ret = -ENOMEM; 45962306a36Sopenharmony_ci goto err_free_ahash; 46062306a36Sopenharmony_ci } 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci crypto_init_wait(&wait); 46362306a36Sopenharmony_ci ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 46462306a36Sopenharmony_ci crypto_req_done, &wait); 46562306a36Sopenharmony_ci crypto_ahash_clear_flags(ahash_tfm, ~0); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci buf = kzalloc(keylen + STARFIVE_HASH_BUFLEN, GFP_KERNEL); 46862306a36Sopenharmony_ci if (!buf) { 46962306a36Sopenharmony_ci ret = -ENOMEM; 47062306a36Sopenharmony_ci goto err_free_req; 47162306a36Sopenharmony_ci } 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci memcpy(buf, key, keylen); 47462306a36Sopenharmony_ci sg_init_one(&sg, buf, keylen); 47562306a36Sopenharmony_ci ahash_request_set_crypt(req, &sg, ctx->key, keylen); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci kfree(buf); 48062306a36Sopenharmony_cierr_free_req: 48162306a36Sopenharmony_ci ahash_request_free(req); 48262306a36Sopenharmony_cierr_free_ahash: 48362306a36Sopenharmony_ci crypto_free_ahash(ahash_tfm); 48462306a36Sopenharmony_ci return ret; 48562306a36Sopenharmony_ci} 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_cistatic int starfive_hash_setkey(struct crypto_ahash *hash, 48862306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 49162306a36Sopenharmony_ci unsigned int digestsize = crypto_ahash_digestsize(hash); 49262306a36Sopenharmony_ci unsigned int blocksize = crypto_ahash_blocksize(hash); 49362306a36Sopenharmony_ci const char *alg_name; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci crypto_ahash_setkey(ctx->ahash_fbk, key, keylen); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci if (keylen <= blocksize) { 49862306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 49962306a36Sopenharmony_ci ctx->keylen = keylen; 50062306a36Sopenharmony_ci return 0; 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci ctx->keylen = digestsize; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci switch (digestsize) { 50662306a36Sopenharmony_ci case SHA224_DIGEST_SIZE: 50762306a36Sopenharmony_ci alg_name = "sha224-starfive"; 50862306a36Sopenharmony_ci break; 50962306a36Sopenharmony_ci case SHA256_DIGEST_SIZE: 51062306a36Sopenharmony_ci if (ctx->hash_mode == STARFIVE_HASH_SM3) 51162306a36Sopenharmony_ci alg_name = "sm3-starfive"; 51262306a36Sopenharmony_ci else 51362306a36Sopenharmony_ci alg_name = "sha256-starfive"; 51462306a36Sopenharmony_ci break; 51562306a36Sopenharmony_ci case SHA384_DIGEST_SIZE: 51662306a36Sopenharmony_ci alg_name = "sha384-starfive"; 51762306a36Sopenharmony_ci break; 51862306a36Sopenharmony_ci case SHA512_DIGEST_SIZE: 51962306a36Sopenharmony_ci alg_name = "sha512-starfive"; 52062306a36Sopenharmony_ci break; 52162306a36Sopenharmony_ci default: 52262306a36Sopenharmony_ci return -EINVAL; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci return starfive_hash_long_setkey(ctx, key, keylen, alg_name); 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic int starfive_sha224_init_tfm(struct crypto_ahash *hash) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "sha224-generic", 53162306a36Sopenharmony_ci STARFIVE_HASH_SHA224); 53262306a36Sopenharmony_ci} 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_cistatic int starfive_sha256_init_tfm(struct crypto_ahash *hash) 53562306a36Sopenharmony_ci{ 53662306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "sha256-generic", 53762306a36Sopenharmony_ci STARFIVE_HASH_SHA256); 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_cistatic int starfive_sha384_init_tfm(struct crypto_ahash *hash) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "sha384-generic", 54362306a36Sopenharmony_ci STARFIVE_HASH_SHA384); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_cistatic int starfive_sha512_init_tfm(struct crypto_ahash *hash) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "sha512-generic", 54962306a36Sopenharmony_ci STARFIVE_HASH_SHA512); 55062306a36Sopenharmony_ci} 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_cistatic int starfive_sm3_init_tfm(struct crypto_ahash *hash) 55362306a36Sopenharmony_ci{ 55462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "sm3-generic", 55562306a36Sopenharmony_ci STARFIVE_HASH_SM3); 55662306a36Sopenharmony_ci} 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_cistatic int starfive_hmac_sha224_init_tfm(struct crypto_ahash *hash) 55962306a36Sopenharmony_ci{ 56062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci ctx->is_hmac = true; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "hmac(sha224-generic)", 56562306a36Sopenharmony_ci STARFIVE_HASH_SHA224); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_cistatic int starfive_hmac_sha256_init_tfm(struct crypto_ahash *hash) 56962306a36Sopenharmony_ci{ 57062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci ctx->is_hmac = true; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "hmac(sha256-generic)", 57562306a36Sopenharmony_ci STARFIVE_HASH_SHA256); 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic int starfive_hmac_sha384_init_tfm(struct crypto_ahash *hash) 57962306a36Sopenharmony_ci{ 58062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci ctx->is_hmac = true; 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "hmac(sha384-generic)", 58562306a36Sopenharmony_ci STARFIVE_HASH_SHA384); 58662306a36Sopenharmony_ci} 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistatic int starfive_hmac_sha512_init_tfm(struct crypto_ahash *hash) 58962306a36Sopenharmony_ci{ 59062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci ctx->is_hmac = true; 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "hmac(sha512-generic)", 59562306a36Sopenharmony_ci STARFIVE_HASH_SHA512); 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic int starfive_hmac_sm3_init_tfm(struct crypto_ahash *hash) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci ctx->is_hmac = true; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci return starfive_hash_init_tfm(hash, "hmac(sm3-generic)", 60562306a36Sopenharmony_ci STARFIVE_HASH_SM3); 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistatic struct ahash_engine_alg algs_sha2_sm3[] = { 60962306a36Sopenharmony_ci{ 61062306a36Sopenharmony_ci .base.init = starfive_hash_init, 61162306a36Sopenharmony_ci .base.update = starfive_hash_update, 61262306a36Sopenharmony_ci .base.final = starfive_hash_final, 61362306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 61462306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 61562306a36Sopenharmony_ci .base.export = starfive_hash_export, 61662306a36Sopenharmony_ci .base.import = starfive_hash_import, 61762306a36Sopenharmony_ci .base.init_tfm = starfive_sha224_init_tfm, 61862306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 61962306a36Sopenharmony_ci .base.halg = { 62062306a36Sopenharmony_ci .digestsize = SHA224_DIGEST_SIZE, 62162306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 62262306a36Sopenharmony_ci .base = { 62362306a36Sopenharmony_ci .cra_name = "sha224", 62462306a36Sopenharmony_ci .cra_driver_name = "sha224-starfive", 62562306a36Sopenharmony_ci .cra_priority = 200, 62662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 62762306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 62862306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 62962306a36Sopenharmony_ci .cra_blocksize = SHA224_BLOCK_SIZE, 63062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 63162306a36Sopenharmony_ci .cra_alignmask = 3, 63262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci }, 63562306a36Sopenharmony_ci .op = { 63662306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 63762306a36Sopenharmony_ci }, 63862306a36Sopenharmony_ci}, { 63962306a36Sopenharmony_ci .base.init = starfive_hash_init, 64062306a36Sopenharmony_ci .base.update = starfive_hash_update, 64162306a36Sopenharmony_ci .base.final = starfive_hash_final, 64262306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 64362306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 64462306a36Sopenharmony_ci .base.export = starfive_hash_export, 64562306a36Sopenharmony_ci .base.import = starfive_hash_import, 64662306a36Sopenharmony_ci .base.init_tfm = starfive_hmac_sha224_init_tfm, 64762306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 64862306a36Sopenharmony_ci .base.setkey = starfive_hash_setkey, 64962306a36Sopenharmony_ci .base.halg = { 65062306a36Sopenharmony_ci .digestsize = SHA224_DIGEST_SIZE, 65162306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 65262306a36Sopenharmony_ci .base = { 65362306a36Sopenharmony_ci .cra_name = "hmac(sha224)", 65462306a36Sopenharmony_ci .cra_driver_name = "sha224-hmac-starfive", 65562306a36Sopenharmony_ci .cra_priority = 200, 65662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 65762306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 65862306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 65962306a36Sopenharmony_ci .cra_blocksize = SHA224_BLOCK_SIZE, 66062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 66162306a36Sopenharmony_ci .cra_alignmask = 3, 66262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci }, 66562306a36Sopenharmony_ci .op = { 66662306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 66762306a36Sopenharmony_ci }, 66862306a36Sopenharmony_ci}, { 66962306a36Sopenharmony_ci .base.init = starfive_hash_init, 67062306a36Sopenharmony_ci .base.update = starfive_hash_update, 67162306a36Sopenharmony_ci .base.final = starfive_hash_final, 67262306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 67362306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 67462306a36Sopenharmony_ci .base.export = starfive_hash_export, 67562306a36Sopenharmony_ci .base.import = starfive_hash_import, 67662306a36Sopenharmony_ci .base.init_tfm = starfive_sha256_init_tfm, 67762306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 67862306a36Sopenharmony_ci .base.halg = { 67962306a36Sopenharmony_ci .digestsize = SHA256_DIGEST_SIZE, 68062306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 68162306a36Sopenharmony_ci .base = { 68262306a36Sopenharmony_ci .cra_name = "sha256", 68362306a36Sopenharmony_ci .cra_driver_name = "sha256-starfive", 68462306a36Sopenharmony_ci .cra_priority = 200, 68562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 68662306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 68762306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 68862306a36Sopenharmony_ci .cra_blocksize = SHA256_BLOCK_SIZE, 68962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 69062306a36Sopenharmony_ci .cra_alignmask = 3, 69162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 69262306a36Sopenharmony_ci } 69362306a36Sopenharmony_ci }, 69462306a36Sopenharmony_ci .op = { 69562306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 69662306a36Sopenharmony_ci }, 69762306a36Sopenharmony_ci}, { 69862306a36Sopenharmony_ci .base.init = starfive_hash_init, 69962306a36Sopenharmony_ci .base.update = starfive_hash_update, 70062306a36Sopenharmony_ci .base.final = starfive_hash_final, 70162306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 70262306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 70362306a36Sopenharmony_ci .base.export = starfive_hash_export, 70462306a36Sopenharmony_ci .base.import = starfive_hash_import, 70562306a36Sopenharmony_ci .base.init_tfm = starfive_hmac_sha256_init_tfm, 70662306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 70762306a36Sopenharmony_ci .base.setkey = starfive_hash_setkey, 70862306a36Sopenharmony_ci .base.halg = { 70962306a36Sopenharmony_ci .digestsize = SHA256_DIGEST_SIZE, 71062306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 71162306a36Sopenharmony_ci .base = { 71262306a36Sopenharmony_ci .cra_name = "hmac(sha256)", 71362306a36Sopenharmony_ci .cra_driver_name = "sha256-hmac-starfive", 71462306a36Sopenharmony_ci .cra_priority = 200, 71562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 71662306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 71762306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 71862306a36Sopenharmony_ci .cra_blocksize = SHA256_BLOCK_SIZE, 71962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 72062306a36Sopenharmony_ci .cra_alignmask = 3, 72162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 72262306a36Sopenharmony_ci } 72362306a36Sopenharmony_ci }, 72462306a36Sopenharmony_ci .op = { 72562306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 72662306a36Sopenharmony_ci }, 72762306a36Sopenharmony_ci}, { 72862306a36Sopenharmony_ci .base.init = starfive_hash_init, 72962306a36Sopenharmony_ci .base.update = starfive_hash_update, 73062306a36Sopenharmony_ci .base.final = starfive_hash_final, 73162306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 73262306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 73362306a36Sopenharmony_ci .base.export = starfive_hash_export, 73462306a36Sopenharmony_ci .base.import = starfive_hash_import, 73562306a36Sopenharmony_ci .base.init_tfm = starfive_sha384_init_tfm, 73662306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 73762306a36Sopenharmony_ci .base.halg = { 73862306a36Sopenharmony_ci .digestsize = SHA384_DIGEST_SIZE, 73962306a36Sopenharmony_ci .statesize = sizeof(struct sha512_state), 74062306a36Sopenharmony_ci .base = { 74162306a36Sopenharmony_ci .cra_name = "sha384", 74262306a36Sopenharmony_ci .cra_driver_name = "sha384-starfive", 74362306a36Sopenharmony_ci .cra_priority = 200, 74462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 74562306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 74662306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 74762306a36Sopenharmony_ci .cra_blocksize = SHA384_BLOCK_SIZE, 74862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 74962306a36Sopenharmony_ci .cra_alignmask = 3, 75062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 75162306a36Sopenharmony_ci } 75262306a36Sopenharmony_ci }, 75362306a36Sopenharmony_ci .op = { 75462306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 75562306a36Sopenharmony_ci }, 75662306a36Sopenharmony_ci}, { 75762306a36Sopenharmony_ci .base.init = starfive_hash_init, 75862306a36Sopenharmony_ci .base.update = starfive_hash_update, 75962306a36Sopenharmony_ci .base.final = starfive_hash_final, 76062306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 76162306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 76262306a36Sopenharmony_ci .base.export = starfive_hash_export, 76362306a36Sopenharmony_ci .base.import = starfive_hash_import, 76462306a36Sopenharmony_ci .base.init_tfm = starfive_hmac_sha384_init_tfm, 76562306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 76662306a36Sopenharmony_ci .base.setkey = starfive_hash_setkey, 76762306a36Sopenharmony_ci .base.halg = { 76862306a36Sopenharmony_ci .digestsize = SHA384_DIGEST_SIZE, 76962306a36Sopenharmony_ci .statesize = sizeof(struct sha512_state), 77062306a36Sopenharmony_ci .base = { 77162306a36Sopenharmony_ci .cra_name = "hmac(sha384)", 77262306a36Sopenharmony_ci .cra_driver_name = "sha384-hmac-starfive", 77362306a36Sopenharmony_ci .cra_priority = 200, 77462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 77562306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 77662306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 77762306a36Sopenharmony_ci .cra_blocksize = SHA384_BLOCK_SIZE, 77862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 77962306a36Sopenharmony_ci .cra_alignmask = 3, 78062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 78162306a36Sopenharmony_ci } 78262306a36Sopenharmony_ci }, 78362306a36Sopenharmony_ci .op = { 78462306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 78562306a36Sopenharmony_ci }, 78662306a36Sopenharmony_ci}, { 78762306a36Sopenharmony_ci .base.init = starfive_hash_init, 78862306a36Sopenharmony_ci .base.update = starfive_hash_update, 78962306a36Sopenharmony_ci .base.final = starfive_hash_final, 79062306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 79162306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 79262306a36Sopenharmony_ci .base.export = starfive_hash_export, 79362306a36Sopenharmony_ci .base.import = starfive_hash_import, 79462306a36Sopenharmony_ci .base.init_tfm = starfive_sha512_init_tfm, 79562306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 79662306a36Sopenharmony_ci .base.halg = { 79762306a36Sopenharmony_ci .digestsize = SHA512_DIGEST_SIZE, 79862306a36Sopenharmony_ci .statesize = sizeof(struct sha512_state), 79962306a36Sopenharmony_ci .base = { 80062306a36Sopenharmony_ci .cra_name = "sha512", 80162306a36Sopenharmony_ci .cra_driver_name = "sha512-starfive", 80262306a36Sopenharmony_ci .cra_priority = 200, 80362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 80462306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 80562306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 80662306a36Sopenharmony_ci .cra_blocksize = SHA512_BLOCK_SIZE, 80762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 80862306a36Sopenharmony_ci .cra_alignmask = 3, 80962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci }, 81262306a36Sopenharmony_ci .op = { 81362306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 81462306a36Sopenharmony_ci }, 81562306a36Sopenharmony_ci}, { 81662306a36Sopenharmony_ci .base.init = starfive_hash_init, 81762306a36Sopenharmony_ci .base.update = starfive_hash_update, 81862306a36Sopenharmony_ci .base.final = starfive_hash_final, 81962306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 82062306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 82162306a36Sopenharmony_ci .base.export = starfive_hash_export, 82262306a36Sopenharmony_ci .base.import = starfive_hash_import, 82362306a36Sopenharmony_ci .base.init_tfm = starfive_hmac_sha512_init_tfm, 82462306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 82562306a36Sopenharmony_ci .base.setkey = starfive_hash_setkey, 82662306a36Sopenharmony_ci .base.halg = { 82762306a36Sopenharmony_ci .digestsize = SHA512_DIGEST_SIZE, 82862306a36Sopenharmony_ci .statesize = sizeof(struct sha512_state), 82962306a36Sopenharmony_ci .base = { 83062306a36Sopenharmony_ci .cra_name = "hmac(sha512)", 83162306a36Sopenharmony_ci .cra_driver_name = "sha512-hmac-starfive", 83262306a36Sopenharmony_ci .cra_priority = 200, 83362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 83462306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 83562306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 83662306a36Sopenharmony_ci .cra_blocksize = SHA512_BLOCK_SIZE, 83762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 83862306a36Sopenharmony_ci .cra_alignmask = 3, 83962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 84062306a36Sopenharmony_ci } 84162306a36Sopenharmony_ci }, 84262306a36Sopenharmony_ci .op = { 84362306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 84462306a36Sopenharmony_ci }, 84562306a36Sopenharmony_ci}, { 84662306a36Sopenharmony_ci .base.init = starfive_hash_init, 84762306a36Sopenharmony_ci .base.update = starfive_hash_update, 84862306a36Sopenharmony_ci .base.final = starfive_hash_final, 84962306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 85062306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 85162306a36Sopenharmony_ci .base.export = starfive_hash_export, 85262306a36Sopenharmony_ci .base.import = starfive_hash_import, 85362306a36Sopenharmony_ci .base.init_tfm = starfive_sm3_init_tfm, 85462306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 85562306a36Sopenharmony_ci .base.halg = { 85662306a36Sopenharmony_ci .digestsize = SM3_DIGEST_SIZE, 85762306a36Sopenharmony_ci .statesize = sizeof(struct sm3_state), 85862306a36Sopenharmony_ci .base = { 85962306a36Sopenharmony_ci .cra_name = "sm3", 86062306a36Sopenharmony_ci .cra_driver_name = "sm3-starfive", 86162306a36Sopenharmony_ci .cra_priority = 200, 86262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 86362306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 86462306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 86562306a36Sopenharmony_ci .cra_blocksize = SM3_BLOCK_SIZE, 86662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 86762306a36Sopenharmony_ci .cra_alignmask = 3, 86862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 86962306a36Sopenharmony_ci } 87062306a36Sopenharmony_ci }, 87162306a36Sopenharmony_ci .op = { 87262306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 87362306a36Sopenharmony_ci }, 87462306a36Sopenharmony_ci}, { 87562306a36Sopenharmony_ci .base.init = starfive_hash_init, 87662306a36Sopenharmony_ci .base.update = starfive_hash_update, 87762306a36Sopenharmony_ci .base.final = starfive_hash_final, 87862306a36Sopenharmony_ci .base.finup = starfive_hash_finup, 87962306a36Sopenharmony_ci .base.digest = starfive_hash_digest, 88062306a36Sopenharmony_ci .base.export = starfive_hash_export, 88162306a36Sopenharmony_ci .base.import = starfive_hash_import, 88262306a36Sopenharmony_ci .base.init_tfm = starfive_hmac_sm3_init_tfm, 88362306a36Sopenharmony_ci .base.exit_tfm = starfive_hash_exit_tfm, 88462306a36Sopenharmony_ci .base.setkey = starfive_hash_setkey, 88562306a36Sopenharmony_ci .base.halg = { 88662306a36Sopenharmony_ci .digestsize = SM3_DIGEST_SIZE, 88762306a36Sopenharmony_ci .statesize = sizeof(struct sm3_state), 88862306a36Sopenharmony_ci .base = { 88962306a36Sopenharmony_ci .cra_name = "hmac(sm3)", 89062306a36Sopenharmony_ci .cra_driver_name = "sm3-hmac-starfive", 89162306a36Sopenharmony_ci .cra_priority = 200, 89262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 89362306a36Sopenharmony_ci CRYPTO_ALG_TYPE_AHASH | 89462306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 89562306a36Sopenharmony_ci .cra_blocksize = SM3_BLOCK_SIZE, 89662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 89762306a36Sopenharmony_ci .cra_alignmask = 3, 89862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 89962306a36Sopenharmony_ci } 90062306a36Sopenharmony_ci }, 90162306a36Sopenharmony_ci .op = { 90262306a36Sopenharmony_ci .do_one_request = starfive_hash_one_request, 90362306a36Sopenharmony_ci }, 90462306a36Sopenharmony_ci}, 90562306a36Sopenharmony_ci}; 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ciint starfive_hash_register_algs(void) 90862306a36Sopenharmony_ci{ 90962306a36Sopenharmony_ci return crypto_engine_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 91062306a36Sopenharmony_ci} 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_civoid starfive_hash_unregister_algs(void) 91362306a36Sopenharmony_ci{ 91462306a36Sopenharmony_ci crypto_engine_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); 91562306a36Sopenharmony_ci} 916