linux-stable/drivers/crypto/starfive/jh7110-hash.c
Rob Herring b0cc7491c9 crypto: drivers - Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate
of_platform_bus_type before it as merged into the regular platform bus.
As part of that merge prepping Arm DT support 13 years ago, they
"temporarily" include each other. They also include platform_device.h
and of.h. As a result, there's a pretty much random mix of those include
files used throughout the tree. In order to detangle these headers and
replace the implicit includes with struct declarations, users need to
explicitly include the correct includes.

Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-08-23 11:04:23 +08:00

916 lines
26 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Hash function and HMAC support for StarFive driver
*
* Copyright (c) 2022 StarFive Technology
*
*/
#include <crypto/engine.h>
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include "jh7110-cryp.h"
#include <linux/amba/pl080.h>
#include <linux/clk.h>
#include <linux/dma-direct.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#define STARFIVE_HASH_REGS_OFFSET 0x300
#define STARFIVE_HASH_SHACSR (STARFIVE_HASH_REGS_OFFSET + 0x0)
#define STARFIVE_HASH_SHAWDR (STARFIVE_HASH_REGS_OFFSET + 0x4)
#define STARFIVE_HASH_SHARDR (STARFIVE_HASH_REGS_OFFSET + 0x8)
#define STARFIVE_HASH_SHAWSR (STARFIVE_HASH_REGS_OFFSET + 0xC)
#define STARFIVE_HASH_SHAWLEN3 (STARFIVE_HASH_REGS_OFFSET + 0x10)
#define STARFIVE_HASH_SHAWLEN2 (STARFIVE_HASH_REGS_OFFSET + 0x14)
#define STARFIVE_HASH_SHAWLEN1 (STARFIVE_HASH_REGS_OFFSET + 0x18)
#define STARFIVE_HASH_SHAWLEN0 (STARFIVE_HASH_REGS_OFFSET + 0x1C)
#define STARFIVE_HASH_SHAWKR (STARFIVE_HASH_REGS_OFFSET + 0x20)
#define STARFIVE_HASH_SHAWKLEN (STARFIVE_HASH_REGS_OFFSET + 0x24)
#define STARFIVE_HASH_BUFLEN SHA512_BLOCK_SIZE
#define STARFIVE_HASH_RESET 0x2
static inline int starfive_hash_wait_busy(struct starfive_cryp_ctx *ctx)
{
struct starfive_cryp_dev *cryp = ctx->cryp;
u32 status;
return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status,
!(status & STARFIVE_HASH_BUSY), 10, 100000);
}
static inline int starfive_hash_wait_key_done(struct starfive_cryp_ctx *ctx)
{
struct starfive_cryp_dev *cryp = ctx->cryp;
u32 status;
return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status,
(status & STARFIVE_HASH_KEY_DONE), 10, 100000);
}
static int starfive_hash_hmac_key(struct starfive_cryp_ctx *ctx)
{
struct starfive_cryp_request_ctx *rctx = ctx->rctx;
struct starfive_cryp_dev *cryp = ctx->cryp;
int klen = ctx->keylen, loop;
unsigned int *key = (unsigned int *)ctx->key;
unsigned char *cl;
writel(ctx->keylen, cryp->base + STARFIVE_HASH_SHAWKLEN);
rctx->csr.hash.hmac = 1;
rctx->csr.hash.key_flag = 1;
writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR);
for (loop = 0; loop < klen / sizeof(unsigned int); loop++, key++)
writel(*key, cryp->base + STARFIVE_HASH_SHAWKR);
if (klen & 0x3) {
cl = (unsigned char *)key;
for (loop = 0; loop < (klen & 0x3); loop++, cl++)
writeb(*cl, cryp->base + STARFIVE_HASH_SHAWKR);
}
if (starfive_hash_wait_key_done(ctx))
return dev_err_probe(cryp->dev, -ETIMEDOUT, "starfive_hash_wait_key_done error\n");
return 0;
}
static void starfive_hash_start(void *param)
{
struct starfive_cryp_ctx *ctx = param;
struct starfive_cryp_request_ctx *rctx = ctx->rctx;
struct starfive_cryp_dev *cryp = ctx->cryp;
union starfive_alg_cr alg_cr;
union starfive_hash_csr csr;
u32 stat;
dma_unmap_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE);
alg_cr.v = 0;
alg_cr.clear = 1;
writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET);
csr.v = readl(cryp->base + STARFIVE_HASH_SHACSR);
csr.firstb = 0;
csr.final = 1;
stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
stat &= ~STARFIVE_IE_MASK_HASH_DONE;
writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET);
writel(csr.v, cryp->base + STARFIVE_HASH_SHACSR);
}
static int starfive_hash_xmit_dma(struct starfive_cryp_ctx *ctx)
{
struct starfive_cryp_request_ctx *rctx = ctx->rctx;
struct starfive_cryp_dev *cryp = ctx->cryp;
struct dma_async_tx_descriptor *in_desc;
union starfive_alg_cr alg_cr;
int total_len;
int ret;
if (!rctx->total) {
starfive_hash_start(ctx);
return 0;
}
writel(rctx->total, cryp->base + STARFIVE_DMA_IN_LEN_OFFSET);
total_len = rctx->total;
total_len = (total_len & 0x3) ? (((total_len >> 2) + 1) << 2) : total_len;
sg_dma_len(rctx->in_sg) = total_len;
alg_cr.v = 0;
alg_cr.start = 1;
alg_cr.hash_dma_en = 1;
writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET);
ret = dma_map_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE);
if (!ret)
return dev_err_probe(cryp->dev, -EINVAL, "dma_map_sg() error\n");
cryp->cfg_in.direction = DMA_MEM_TO_DEV;
cryp->cfg_in.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cryp->cfg_in.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cryp->cfg_in.src_maxburst = cryp->dma_maxburst;
cryp->cfg_in.dst_maxburst = cryp->dma_maxburst;
cryp->cfg_in.dst_addr = cryp->phys_base + STARFIVE_ALG_FIFO_OFFSET;
dmaengine_slave_config(cryp->tx, &cryp->cfg_in);
in_desc = dmaengine_prep_slave_sg(cryp->tx, rctx->in_sg,
ret, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!in_desc)
return -EINVAL;
in_desc->callback = starfive_hash_start;
in_desc->callback_param = ctx;
dmaengine_submit(in_desc);
dma_async_issue_pending(cryp->tx);
return 0;
}
static int starfive_hash_xmit(struct starfive_cryp_ctx *ctx)
{
struct starfive_cryp_request_ctx *rctx = ctx->rctx;
struct starfive_cryp_dev *cryp = ctx->cryp;
int ret = 0;
rctx->csr.hash.v = 0;
rctx->csr.hash.reset = 1;
writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR);
if (starfive_hash_wait_busy(ctx))
return dev_err_probe(cryp->dev, -ETIMEDOUT, "Error resetting engine.\n");
rctx->csr.hash.v = 0;
rctx->csr.hash.mode = ctx->hash_mode;
rctx->csr.hash.ie = 1;
if (ctx->is_hmac) {
ret = starfive_hash_hmac_key(ctx);
if (ret)
return ret;
} else {
rctx->csr.hash.start = 1;
rctx->csr.hash.firstb = 1;
writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR);
}
return starfive_hash_xmit_dma(ctx);
}
static int starfive_hash_copy_hash(struct ahash_request *req)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
int count, *data;
int mlen;
if (!req->result)
return 0;
mlen = rctx->digsize / sizeof(u32);
data = (u32 *)req->result;
for (count = 0; count < mlen; count++)
data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR);
return 0;
}
void starfive_hash_done_task(unsigned long param)
{
struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)param;
int err = cryp->err;
if (!err)
err = starfive_hash_copy_hash(cryp->req.hreq);
/* Reset to clear hash_done in irq register*/
writel(STARFIVE_HASH_RESET, cryp->base + STARFIVE_HASH_SHACSR);
crypto_finalize_hash_request(cryp->engine, cryp->req.hreq, err);
}
static int starfive_hash_check_aligned(struct scatterlist *sg, size_t total, size_t align)
{
int len = 0;
if (!total)
return 0;
if (!IS_ALIGNED(total, align))
return -EINVAL;
while (sg) {
if (!IS_ALIGNED(sg->offset, sizeof(u32)))
return -EINVAL;
if (!IS_ALIGNED(sg->length, align))
return -EINVAL;
len += sg->length;
sg = sg_next(sg);
}
if (len != total)
return -EINVAL;
return 0;
}
static int starfive_hash_one_request(struct crypto_engine *engine, void *areq)
{
struct ahash_request *req = container_of(areq, struct ahash_request,
base);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
struct starfive_cryp_dev *cryp = ctx->cryp;
if (!cryp)
return -ENODEV;
return starfive_hash_xmit(ctx);
}
static int starfive_hash_init(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src,
req->result, req->nbytes);
return crypto_ahash_init(&rctx->ahash_fbk_req);
}
static int starfive_hash_update(struct ahash_request *req)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src,
req->result, req->nbytes);
return crypto_ahash_update(&rctx->ahash_fbk_req);
}
static int starfive_hash_final(struct ahash_request *req)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src,
req->result, req->nbytes);
return crypto_ahash_final(&rctx->ahash_fbk_req);
}
static int starfive_hash_finup(struct ahash_request *req)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src,
req->result, req->nbytes);
return crypto_ahash_finup(&rctx->ahash_fbk_req);
}
static int starfive_hash_digest_fb(struct ahash_request *req)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req, req->base.flags,
req->base.complete, req->base.data);
ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src,
req->result, req->nbytes);
return crypto_ahash_digest(&rctx->ahash_fbk_req);
}
static int starfive_hash_digest(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct starfive_cryp_dev *cryp = ctx->cryp;
memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx));
cryp->req.hreq = req;
rctx->total = req->nbytes;
rctx->in_sg = req->src;
rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
rctx->digsize = crypto_ahash_digestsize(tfm);
rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total);
ctx->rctx = rctx;
if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize))
return starfive_hash_digest_fb(req);
return crypto_transfer_hash_request_to_engine(cryp->engine, req);
}
static int starfive_hash_export(struct ahash_request *req, void *out)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
return crypto_ahash_export(&rctx->ahash_fbk_req, out);
}
static int starfive_hash_import(struct ahash_request *req, const void *in)
{
struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm);
ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk);
ahash_request_set_callback(&rctx->ahash_fbk_req,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP,
req->base.complete, req->base.data);
return crypto_ahash_import(&rctx->ahash_fbk_req, in);
}
static int starfive_hash_init_tfm(struct crypto_ahash *hash,
const char *alg_name,
unsigned int mode)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->cryp = starfive_cryp_find_dev(ctx);
if (!ctx->cryp)
return -ENODEV;
ctx->ahash_fbk = crypto_alloc_ahash(alg_name, 0,
CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->ahash_fbk))
return dev_err_probe(ctx->cryp->dev, PTR_ERR(ctx->ahash_fbk),
"starfive_hash: Could not load fallback driver.\n");
crypto_ahash_set_statesize(hash, crypto_ahash_statesize(ctx->ahash_fbk));
crypto_ahash_set_reqsize(hash, sizeof(struct starfive_cryp_request_ctx) +
crypto_ahash_reqsize(ctx->ahash_fbk));
ctx->keylen = 0;
ctx->hash_mode = mode;
return 0;
}
static void starfive_hash_exit_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
crypto_free_ahash(ctx->ahash_fbk);
}
static int starfive_hash_long_setkey(struct starfive_cryp_ctx *ctx,
const u8 *key, unsigned int keylen,
const char *alg_name)
{
struct crypto_wait wait;
struct ahash_request *req;
struct scatterlist sg;
struct crypto_ahash *ahash_tfm;
u8 *buf;
int ret;
ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0);
if (IS_ERR(ahash_tfm))
return PTR_ERR(ahash_tfm);
req = ahash_request_alloc(ahash_tfm, GFP_KERNEL);
if (!req) {
ret = -ENOMEM;
goto err_free_ahash;
}
crypto_init_wait(&wait);
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
crypto_req_done, &wait);
crypto_ahash_clear_flags(ahash_tfm, ~0);
buf = kzalloc(keylen + STARFIVE_HASH_BUFLEN, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
goto err_free_req;
}
memcpy(buf, key, keylen);
sg_init_one(&sg, buf, keylen);
ahash_request_set_crypt(req, &sg, ctx->key, keylen);
ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
kfree(buf);
err_free_req:
ahash_request_free(req);
err_free_ahash:
crypto_free_ahash(ahash_tfm);
return ret;
}
static int starfive_hash_setkey(struct crypto_ahash *hash,
const u8 *key, unsigned int keylen)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
unsigned int digestsize = crypto_ahash_digestsize(hash);
unsigned int blocksize = crypto_ahash_blocksize(hash);
const char *alg_name;
crypto_ahash_setkey(ctx->ahash_fbk, key, keylen);
if (keylen <= blocksize) {
memcpy(ctx->key, key, keylen);
ctx->keylen = keylen;
return 0;
}
ctx->keylen = digestsize;
switch (digestsize) {
case SHA224_DIGEST_SIZE:
alg_name = "sha224-starfive";
break;
case SHA256_DIGEST_SIZE:
if (ctx->hash_mode == STARFIVE_HASH_SM3)
alg_name = "sm3-starfive";
else
alg_name = "sha256-starfive";
break;
case SHA384_DIGEST_SIZE:
alg_name = "sha384-starfive";
break;
case SHA512_DIGEST_SIZE:
alg_name = "sha512-starfive";
break;
default:
return -EINVAL;
}
return starfive_hash_long_setkey(ctx, key, keylen, alg_name);
}
static int starfive_sha224_init_tfm(struct crypto_ahash *hash)
{
return starfive_hash_init_tfm(hash, "sha224-generic",
STARFIVE_HASH_SHA224);
}
static int starfive_sha256_init_tfm(struct crypto_ahash *hash)
{
return starfive_hash_init_tfm(hash, "sha256-generic",
STARFIVE_HASH_SHA256);
}
static int starfive_sha384_init_tfm(struct crypto_ahash *hash)
{
return starfive_hash_init_tfm(hash, "sha384-generic",
STARFIVE_HASH_SHA384);
}
static int starfive_sha512_init_tfm(struct crypto_ahash *hash)
{
return starfive_hash_init_tfm(hash, "sha512-generic",
STARFIVE_HASH_SHA512);
}
static int starfive_sm3_init_tfm(struct crypto_ahash *hash)
{
return starfive_hash_init_tfm(hash, "sm3-generic",
STARFIVE_HASH_SM3);
}
static int starfive_hmac_sha224_init_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->is_hmac = true;
return starfive_hash_init_tfm(hash, "hmac(sha224-generic)",
STARFIVE_HASH_SHA224);
}
static int starfive_hmac_sha256_init_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->is_hmac = true;
return starfive_hash_init_tfm(hash, "hmac(sha256-generic)",
STARFIVE_HASH_SHA256);
}
static int starfive_hmac_sha384_init_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->is_hmac = true;
return starfive_hash_init_tfm(hash, "hmac(sha384-generic)",
STARFIVE_HASH_SHA384);
}
static int starfive_hmac_sha512_init_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->is_hmac = true;
return starfive_hash_init_tfm(hash, "hmac(sha512-generic)",
STARFIVE_HASH_SHA512);
}
static int starfive_hmac_sm3_init_tfm(struct crypto_ahash *hash)
{
struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash);
ctx->is_hmac = true;
return starfive_hash_init_tfm(hash, "hmac(sm3-generic)",
STARFIVE_HASH_SM3);
}
static struct ahash_engine_alg algs_sha2_sm3[] = {
{
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_sha224_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.halg = {
.digestsize = SHA224_DIGEST_SIZE,
.statesize = sizeof(struct sha256_state),
.base = {
.cra_name = "sha224",
.cra_driver_name = "sha224-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_hmac_sha224_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.setkey = starfive_hash_setkey,
.base.halg = {
.digestsize = SHA224_DIGEST_SIZE,
.statesize = sizeof(struct sha256_state),
.base = {
.cra_name = "hmac(sha224)",
.cra_driver_name = "sha224-hmac-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_sha256_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.halg = {
.digestsize = SHA256_DIGEST_SIZE,
.statesize = sizeof(struct sha256_state),
.base = {
.cra_name = "sha256",
.cra_driver_name = "sha256-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_hmac_sha256_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.setkey = starfive_hash_setkey,
.base.halg = {
.digestsize = SHA256_DIGEST_SIZE,
.statesize = sizeof(struct sha256_state),
.base = {
.cra_name = "hmac(sha256)",
.cra_driver_name = "sha256-hmac-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_sha384_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.halg = {
.digestsize = SHA384_DIGEST_SIZE,
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "sha384",
.cra_driver_name = "sha384-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_hmac_sha384_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.setkey = starfive_hash_setkey,
.base.halg = {
.digestsize = SHA384_DIGEST_SIZE,
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "hmac(sha384)",
.cra_driver_name = "sha384-hmac-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_sha512_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.halg = {
.digestsize = SHA512_DIGEST_SIZE,
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "sha512",
.cra_driver_name = "sha512-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_hmac_sha512_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.setkey = starfive_hash_setkey,
.base.halg = {
.digestsize = SHA512_DIGEST_SIZE,
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "hmac(sha512)",
.cra_driver_name = "sha512-hmac-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_sm3_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.halg = {
.digestsize = SM3_DIGEST_SIZE,
.statesize = sizeof(struct sm3_state),
.base = {
.cra_name = "sm3",
.cra_driver_name = "sm3-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SM3_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
}, {
.base.init = starfive_hash_init,
.base.update = starfive_hash_update,
.base.final = starfive_hash_final,
.base.finup = starfive_hash_finup,
.base.digest = starfive_hash_digest,
.base.export = starfive_hash_export,
.base.import = starfive_hash_import,
.base.init_tfm = starfive_hmac_sm3_init_tfm,
.base.exit_tfm = starfive_hash_exit_tfm,
.base.setkey = starfive_hash_setkey,
.base.halg = {
.digestsize = SM3_DIGEST_SIZE,
.statesize = sizeof(struct sm3_state),
.base = {
.cra_name = "hmac(sm3)",
.cra_driver_name = "sm3-hmac-starfive",
.cra_priority = 200,
.cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SM3_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
}
},
.op = {
.do_one_request = starfive_hash_one_request,
},
},
};
int starfive_hash_register_algs(void)
{
return crypto_engine_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3));
}
void starfive_hash_unregister_algs(void)
{
crypto_engine_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3));
}