162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * StarFive AES acceleration driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2022 StarFive Technology 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <crypto/engine.h> 962306a36Sopenharmony_ci#include <crypto/gcm.h> 1062306a36Sopenharmony_ci#include <crypto/internal/aead.h> 1162306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 1262306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 1362306a36Sopenharmony_ci#include "jh7110-cryp.h" 1462306a36Sopenharmony_ci#include <linux/err.h> 1562306a36Sopenharmony_ci#include <linux/iopoll.h> 1662306a36Sopenharmony_ci#include <linux/kernel.h> 1762306a36Sopenharmony_ci#include <linux/slab.h> 1862306a36Sopenharmony_ci#include <linux/string.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define STARFIVE_AES_REGS_OFFSET 0x100 2162306a36Sopenharmony_ci#define STARFIVE_AES_AESDIO0R (STARFIVE_AES_REGS_OFFSET + 0x0) 2262306a36Sopenharmony_ci#define STARFIVE_AES_KEY0 (STARFIVE_AES_REGS_OFFSET + 0x4) 2362306a36Sopenharmony_ci#define STARFIVE_AES_KEY1 (STARFIVE_AES_REGS_OFFSET + 0x8) 2462306a36Sopenharmony_ci#define STARFIVE_AES_KEY2 (STARFIVE_AES_REGS_OFFSET + 0xC) 2562306a36Sopenharmony_ci#define STARFIVE_AES_KEY3 (STARFIVE_AES_REGS_OFFSET + 0x10) 2662306a36Sopenharmony_ci#define STARFIVE_AES_KEY4 (STARFIVE_AES_REGS_OFFSET + 0x14) 2762306a36Sopenharmony_ci#define STARFIVE_AES_KEY5 (STARFIVE_AES_REGS_OFFSET + 0x18) 2862306a36Sopenharmony_ci#define STARFIVE_AES_KEY6 (STARFIVE_AES_REGS_OFFSET + 0x1C) 2962306a36Sopenharmony_ci#define STARFIVE_AES_KEY7 (STARFIVE_AES_REGS_OFFSET + 0x20) 3062306a36Sopenharmony_ci#define STARFIVE_AES_CSR (STARFIVE_AES_REGS_OFFSET + 0x24) 3162306a36Sopenharmony_ci#define STARFIVE_AES_IV0 (STARFIVE_AES_REGS_OFFSET + 0x28) 3262306a36Sopenharmony_ci#define STARFIVE_AES_IV1 (STARFIVE_AES_REGS_OFFSET + 0x2C) 3362306a36Sopenharmony_ci#define STARFIVE_AES_IV2 (STARFIVE_AES_REGS_OFFSET + 0x30) 3462306a36Sopenharmony_ci#define STARFIVE_AES_IV3 (STARFIVE_AES_REGS_OFFSET + 0x34) 3562306a36Sopenharmony_ci#define STARFIVE_AES_NONCE0 (STARFIVE_AES_REGS_OFFSET + 0x3C) 3662306a36Sopenharmony_ci#define STARFIVE_AES_NONCE1 (STARFIVE_AES_REGS_OFFSET + 0x40) 3762306a36Sopenharmony_ci#define STARFIVE_AES_NONCE2 (STARFIVE_AES_REGS_OFFSET + 0x44) 3862306a36Sopenharmony_ci#define STARFIVE_AES_NONCE3 (STARFIVE_AES_REGS_OFFSET + 0x48) 3962306a36Sopenharmony_ci#define STARFIVE_AES_ALEN0 (STARFIVE_AES_REGS_OFFSET + 0x4C) 4062306a36Sopenharmony_ci#define STARFIVE_AES_ALEN1 (STARFIVE_AES_REGS_OFFSET + 0x50) 4162306a36Sopenharmony_ci#define STARFIVE_AES_MLEN0 (STARFIVE_AES_REGS_OFFSET + 0x54) 4262306a36Sopenharmony_ci#define STARFIVE_AES_MLEN1 (STARFIVE_AES_REGS_OFFSET + 0x58) 4362306a36Sopenharmony_ci#define STARFIVE_AES_IVLEN (STARFIVE_AES_REGS_OFFSET + 0x5C) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define FLG_MODE_MASK GENMASK(2, 0) 4662306a36Sopenharmony_ci#define FLG_ENCRYPT BIT(4) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* Misc */ 4962306a36Sopenharmony_ci#define CCM_B0_ADATA 0x40 5062306a36Sopenharmony_ci#define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32)) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic inline int starfive_aes_wait_busy(struct starfive_cryp_dev *cryp) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci u32 status; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci return readl_relaxed_poll_timeout(cryp->base + STARFIVE_AES_CSR, status, 5762306a36Sopenharmony_ci !(status & STARFIVE_AES_BUSY), 10, 100000); 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic inline int starfive_aes_wait_keydone(struct starfive_cryp_dev *cryp) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci u32 status; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci return readl_relaxed_poll_timeout(cryp->base + STARFIVE_AES_CSR, status, 6562306a36Sopenharmony_ci (status & STARFIVE_AES_KEY_DONE), 10, 100000); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic inline int starfive_aes_wait_gcmdone(struct starfive_cryp_dev *cryp) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci u32 status; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci return readl_relaxed_poll_timeout(cryp->base + STARFIVE_AES_CSR, status, 7362306a36Sopenharmony_ci (status & STARFIVE_AES_GCM_DONE), 10, 100000); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic inline int is_gcm(struct starfive_cryp_dev *cryp) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci return (cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_GCM; 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic inline int is_encrypt(struct starfive_cryp_dev *cryp) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci return cryp->flags & FLG_ENCRYPT; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic void starfive_aes_aead_hw_start(struct starfive_cryp_ctx *ctx, u32 hw_mode) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 8962306a36Sopenharmony_ci unsigned int value; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci switch (hw_mode) { 9262306a36Sopenharmony_ci case STARFIVE_AES_MODE_GCM: 9362306a36Sopenharmony_ci value = readl(ctx->cryp->base + STARFIVE_AES_CSR); 9462306a36Sopenharmony_ci value |= STARFIVE_AES_GCM_START; 9562306a36Sopenharmony_ci writel(value, cryp->base + STARFIVE_AES_CSR); 9662306a36Sopenharmony_ci starfive_aes_wait_gcmdone(cryp); 9762306a36Sopenharmony_ci break; 9862306a36Sopenharmony_ci case STARFIVE_AES_MODE_CCM: 9962306a36Sopenharmony_ci value = readl(ctx->cryp->base + STARFIVE_AES_CSR); 10062306a36Sopenharmony_ci value |= STARFIVE_AES_CCM_START; 10162306a36Sopenharmony_ci writel(value, cryp->base + STARFIVE_AES_CSR); 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic inline void starfive_aes_set_ivlen(struct starfive_cryp_ctx *ctx) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci if (is_gcm(cryp)) 11162306a36Sopenharmony_ci writel(GCM_AES_IV_SIZE, cryp->base + STARFIVE_AES_IVLEN); 11262306a36Sopenharmony_ci else 11362306a36Sopenharmony_ci writel(AES_BLOCK_SIZE, cryp->base + STARFIVE_AES_IVLEN); 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic inline void starfive_aes_set_alen(struct starfive_cryp_ctx *ctx) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci writel(upper_32_bits(cryp->assoclen), cryp->base + STARFIVE_AES_ALEN0); 12162306a36Sopenharmony_ci writel(lower_32_bits(cryp->assoclen), cryp->base + STARFIVE_AES_ALEN1); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic inline void starfive_aes_set_mlen(struct starfive_cryp_ctx *ctx) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci writel(upper_32_bits(cryp->total_in), cryp->base + STARFIVE_AES_MLEN0); 12962306a36Sopenharmony_ci writel(lower_32_bits(cryp->total_in), cryp->base + STARFIVE_AES_MLEN1); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic inline int starfive_aes_ccm_check_iv(const u8 *iv) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci /* 2 <= L <= 8, so 1 <= L' <= 7. */ 13562306a36Sopenharmony_ci if (iv[0] < 1 || iv[0] > 7) 13662306a36Sopenharmony_ci return -EINVAL; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci return 0; 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic int starfive_aes_write_iv(struct starfive_cryp_ctx *ctx, u32 *iv) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci writel(iv[0], cryp->base + STARFIVE_AES_IV0); 14662306a36Sopenharmony_ci writel(iv[1], cryp->base + STARFIVE_AES_IV1); 14762306a36Sopenharmony_ci writel(iv[2], cryp->base + STARFIVE_AES_IV2); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci if (is_gcm(cryp)) { 15062306a36Sopenharmony_ci if (starfive_aes_wait_gcmdone(cryp)) 15162306a36Sopenharmony_ci return -ETIMEDOUT; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci return 0; 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci writel(iv[3], cryp->base + STARFIVE_AES_IV3); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci return 0; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic inline void starfive_aes_get_iv(struct starfive_cryp_dev *cryp, u32 *iv) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci iv[0] = readl(cryp->base + STARFIVE_AES_IV0); 16462306a36Sopenharmony_ci iv[1] = readl(cryp->base + STARFIVE_AES_IV1); 16562306a36Sopenharmony_ci iv[2] = readl(cryp->base + STARFIVE_AES_IV2); 16662306a36Sopenharmony_ci iv[3] = readl(cryp->base + STARFIVE_AES_IV3); 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic inline void starfive_aes_write_nonce(struct starfive_cryp_ctx *ctx, u32 *nonce) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci writel(nonce[0], cryp->base + STARFIVE_AES_NONCE0); 17462306a36Sopenharmony_ci writel(nonce[1], cryp->base + STARFIVE_AES_NONCE1); 17562306a36Sopenharmony_ci writel(nonce[2], cryp->base + STARFIVE_AES_NONCE2); 17662306a36Sopenharmony_ci writel(nonce[3], cryp->base + STARFIVE_AES_NONCE3); 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic int starfive_aes_write_key(struct starfive_cryp_ctx *ctx) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 18262306a36Sopenharmony_ci u32 *key = (u32 *)ctx->key; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (ctx->keylen >= AES_KEYSIZE_128) { 18562306a36Sopenharmony_ci writel(key[0], cryp->base + STARFIVE_AES_KEY0); 18662306a36Sopenharmony_ci writel(key[1], cryp->base + STARFIVE_AES_KEY1); 18762306a36Sopenharmony_ci writel(key[2], cryp->base + STARFIVE_AES_KEY2); 18862306a36Sopenharmony_ci writel(key[3], cryp->base + STARFIVE_AES_KEY3); 18962306a36Sopenharmony_ci } 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci if (ctx->keylen >= AES_KEYSIZE_192) { 19262306a36Sopenharmony_ci writel(key[4], cryp->base + STARFIVE_AES_KEY4); 19362306a36Sopenharmony_ci writel(key[5], cryp->base + STARFIVE_AES_KEY5); 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if (ctx->keylen >= AES_KEYSIZE_256) { 19762306a36Sopenharmony_ci writel(key[6], cryp->base + STARFIVE_AES_KEY6); 19862306a36Sopenharmony_ci writel(key[7], cryp->base + STARFIVE_AES_KEY7); 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (starfive_aes_wait_keydone(cryp)) 20262306a36Sopenharmony_ci return -ETIMEDOUT; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci return 0; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic int starfive_aes_ccm_init(struct starfive_cryp_ctx *ctx) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 21062306a36Sopenharmony_ci u8 iv[AES_BLOCK_SIZE], b0[AES_BLOCK_SIZE]; 21162306a36Sopenharmony_ci unsigned int textlen; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci memcpy(iv, cryp->req.areq->iv, AES_BLOCK_SIZE); 21462306a36Sopenharmony_ci memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* Build B0 */ 21762306a36Sopenharmony_ci memcpy(b0, iv, AES_BLOCK_SIZE); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci b0[0] |= (8 * ((cryp->authsize - 2) / 2)); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci if (cryp->assoclen) 22262306a36Sopenharmony_ci b0[0] |= CCM_B0_ADATA; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci textlen = cryp->total_in; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci b0[AES_BLOCK_SIZE - 2] = textlen >> 8; 22762306a36Sopenharmony_ci b0[AES_BLOCK_SIZE - 1] = textlen & 0xFF; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci starfive_aes_write_nonce(ctx, (u32 *)b0); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic int starfive_aes_hw_init(struct starfive_cryp_ctx *ctx) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 23762306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 23862306a36Sopenharmony_ci u32 hw_mode; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci /* reset */ 24162306a36Sopenharmony_ci rctx->csr.aes.v = 0; 24262306a36Sopenharmony_ci rctx->csr.aes.aesrst = 1; 24362306a36Sopenharmony_ci writel(rctx->csr.aes.v, cryp->base + STARFIVE_AES_CSR); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci /* csr setup */ 24662306a36Sopenharmony_ci hw_mode = cryp->flags & FLG_MODE_MASK; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci rctx->csr.aes.v = 0; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci switch (ctx->keylen) { 25162306a36Sopenharmony_ci case AES_KEYSIZE_128: 25262306a36Sopenharmony_ci rctx->csr.aes.keymode = STARFIVE_AES_KEYMODE_128; 25362306a36Sopenharmony_ci break; 25462306a36Sopenharmony_ci case AES_KEYSIZE_192: 25562306a36Sopenharmony_ci rctx->csr.aes.keymode = STARFIVE_AES_KEYMODE_192; 25662306a36Sopenharmony_ci break; 25762306a36Sopenharmony_ci case AES_KEYSIZE_256: 25862306a36Sopenharmony_ci rctx->csr.aes.keymode = STARFIVE_AES_KEYMODE_256; 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci rctx->csr.aes.mode = hw_mode; 26362306a36Sopenharmony_ci rctx->csr.aes.cmode = !is_encrypt(cryp); 26462306a36Sopenharmony_ci rctx->csr.aes.ie = 1; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci if (hw_mode == STARFIVE_AES_MODE_CFB || 26762306a36Sopenharmony_ci hw_mode == STARFIVE_AES_MODE_OFB) 26862306a36Sopenharmony_ci rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_128; 26962306a36Sopenharmony_ci else 27062306a36Sopenharmony_ci rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if (cryp->side_chan) { 27362306a36Sopenharmony_ci rctx->csr.aes.delay_aes = 1; 27462306a36Sopenharmony_ci rctx->csr.aes.vaes_start = 1; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci writel(rctx->csr.aes.v, cryp->base + STARFIVE_AES_CSR); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci cryp->err = starfive_aes_write_key(ctx); 28062306a36Sopenharmony_ci if (cryp->err) 28162306a36Sopenharmony_ci return cryp->err; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci switch (hw_mode) { 28462306a36Sopenharmony_ci case STARFIVE_AES_MODE_GCM: 28562306a36Sopenharmony_ci starfive_aes_set_alen(ctx); 28662306a36Sopenharmony_ci starfive_aes_set_mlen(ctx); 28762306a36Sopenharmony_ci starfive_aes_set_ivlen(ctx); 28862306a36Sopenharmony_ci starfive_aes_aead_hw_start(ctx, hw_mode); 28962306a36Sopenharmony_ci starfive_aes_write_iv(ctx, (void *)cryp->req.areq->iv); 29062306a36Sopenharmony_ci break; 29162306a36Sopenharmony_ci case STARFIVE_AES_MODE_CCM: 29262306a36Sopenharmony_ci starfive_aes_set_alen(ctx); 29362306a36Sopenharmony_ci starfive_aes_set_mlen(ctx); 29462306a36Sopenharmony_ci starfive_aes_ccm_init(ctx); 29562306a36Sopenharmony_ci starfive_aes_aead_hw_start(ctx, hw_mode); 29662306a36Sopenharmony_ci break; 29762306a36Sopenharmony_ci case STARFIVE_AES_MODE_OFB: 29862306a36Sopenharmony_ci case STARFIVE_AES_MODE_CFB: 29962306a36Sopenharmony_ci case STARFIVE_AES_MODE_CBC: 30062306a36Sopenharmony_ci case STARFIVE_AES_MODE_CTR: 30162306a36Sopenharmony_ci starfive_aes_write_iv(ctx, (void *)cryp->req.sreq->iv); 30262306a36Sopenharmony_ci break; 30362306a36Sopenharmony_ci default: 30462306a36Sopenharmony_ci break; 30562306a36Sopenharmony_ci } 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci return cryp->err; 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic int starfive_aes_read_authtag(struct starfive_cryp_dev *cryp) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci int i, start_addr; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (starfive_aes_wait_busy(cryp)) 31562306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ETIMEDOUT, 31662306a36Sopenharmony_ci "Timeout waiting for tag generation."); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci start_addr = STARFIVE_AES_NONCE0; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci if (is_gcm(cryp)) 32162306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++, start_addr += 4) 32262306a36Sopenharmony_ci cryp->tag_out[i] = readl(cryp->base + start_addr); 32362306a36Sopenharmony_ci else 32462306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++) 32562306a36Sopenharmony_ci cryp->tag_out[i] = readl(cryp->base + STARFIVE_AES_AESDIO0R); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci if (is_encrypt(cryp)) { 32862306a36Sopenharmony_ci scatterwalk_copychunks(cryp->tag_out, &cryp->out_walk, cryp->authsize, 1); 32962306a36Sopenharmony_ci } else { 33062306a36Sopenharmony_ci scatterwalk_copychunks(cryp->tag_in, &cryp->in_walk, cryp->authsize, 0); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci if (crypto_memneq(cryp->tag_in, cryp->tag_out, cryp->authsize)) 33362306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -EBADMSG, "Failed tag verification\n"); 33462306a36Sopenharmony_ci } 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci return 0; 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic void starfive_aes_finish_req(struct starfive_cryp_dev *cryp) 34062306a36Sopenharmony_ci{ 34162306a36Sopenharmony_ci union starfive_aes_csr csr; 34262306a36Sopenharmony_ci int err = cryp->err; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (!err && cryp->authsize) 34562306a36Sopenharmony_ci err = starfive_aes_read_authtag(cryp); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci if (!err && ((cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_CBC || 34862306a36Sopenharmony_ci (cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_CTR)) 34962306a36Sopenharmony_ci starfive_aes_get_iv(cryp, (void *)cryp->req.sreq->iv); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* reset irq flags*/ 35262306a36Sopenharmony_ci csr.v = 0; 35362306a36Sopenharmony_ci csr.aesrst = 1; 35462306a36Sopenharmony_ci writel(csr.v, cryp->base + STARFIVE_AES_CSR); 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci if (cryp->authsize) 35762306a36Sopenharmony_ci crypto_finalize_aead_request(cryp->engine, cryp->req.areq, err); 35862306a36Sopenharmony_ci else 35962306a36Sopenharmony_ci crypto_finalize_skcipher_request(cryp->engine, cryp->req.sreq, 36062306a36Sopenharmony_ci err); 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_civoid starfive_aes_done_task(unsigned long param) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)param; 36662306a36Sopenharmony_ci u32 block[AES_BLOCK_32]; 36762306a36Sopenharmony_ci u32 stat; 36862306a36Sopenharmony_ci int i; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++) 37162306a36Sopenharmony_ci block[i] = readl(cryp->base + STARFIVE_AES_AESDIO0R); 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, AES_BLOCK_SIZE, 37462306a36Sopenharmony_ci cryp->total_out), 1); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci cryp->total_out -= min_t(size_t, AES_BLOCK_SIZE, cryp->total_out); 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci if (!cryp->total_out) { 37962306a36Sopenharmony_ci starfive_aes_finish_req(cryp); 38062306a36Sopenharmony_ci return; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci memset(block, 0, AES_BLOCK_SIZE); 38462306a36Sopenharmony_ci scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, AES_BLOCK_SIZE, 38562306a36Sopenharmony_ci cryp->total_in), 0); 38662306a36Sopenharmony_ci cryp->total_in -= min_t(size_t, AES_BLOCK_SIZE, cryp->total_in); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++) 38962306a36Sopenharmony_ci writel(block[i], cryp->base + STARFIVE_AES_AESDIO0R); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET); 39262306a36Sopenharmony_ci stat &= ~STARFIVE_IE_MASK_AES_DONE; 39362306a36Sopenharmony_ci writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET); 39462306a36Sopenharmony_ci} 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic int starfive_aes_gcm_write_adata(struct starfive_cryp_ctx *ctx) 39762306a36Sopenharmony_ci{ 39862306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 39962306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 40062306a36Sopenharmony_ci u32 *buffer; 40162306a36Sopenharmony_ci int total_len, loop; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci total_len = ALIGN(cryp->assoclen, AES_BLOCK_SIZE) / sizeof(unsigned int); 40462306a36Sopenharmony_ci buffer = (u32 *)rctx->adata; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci for (loop = 0; loop < total_len; loop += 4) { 40762306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_NONCE0); 40862306a36Sopenharmony_ci buffer++; 40962306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_NONCE1); 41062306a36Sopenharmony_ci buffer++; 41162306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_NONCE2); 41262306a36Sopenharmony_ci buffer++; 41362306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_NONCE3); 41462306a36Sopenharmony_ci buffer++; 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci if (starfive_aes_wait_gcmdone(cryp)) 41862306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ETIMEDOUT, 41962306a36Sopenharmony_ci "Timeout processing gcm aad block"); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci return 0; 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic int starfive_aes_ccm_write_adata(struct starfive_cryp_ctx *ctx) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 42762306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 42862306a36Sopenharmony_ci u32 *buffer; 42962306a36Sopenharmony_ci u8 *ci; 43062306a36Sopenharmony_ci int total_len, loop; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci total_len = cryp->assoclen; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci ci = rctx->adata; 43562306a36Sopenharmony_ci writeb(*ci, cryp->base + STARFIVE_AES_AESDIO0R); 43662306a36Sopenharmony_ci ci++; 43762306a36Sopenharmony_ci writeb(*ci, cryp->base + STARFIVE_AES_AESDIO0R); 43862306a36Sopenharmony_ci ci++; 43962306a36Sopenharmony_ci total_len -= 2; 44062306a36Sopenharmony_ci buffer = (u32 *)ci; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci for (loop = 0; loop < 3; loop++, buffer++) 44362306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_AESDIO0R); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci total_len -= 12; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci while (total_len > 0) { 44862306a36Sopenharmony_ci for (loop = 0; loop < AES_BLOCK_32; loop++, buffer++) 44962306a36Sopenharmony_ci writel(*buffer, cryp->base + STARFIVE_AES_AESDIO0R); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci total_len -= AES_BLOCK_SIZE; 45262306a36Sopenharmony_ci } 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci if (starfive_aes_wait_busy(cryp)) 45562306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ETIMEDOUT, 45662306a36Sopenharmony_ci "Timeout processing ccm aad block"); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci return 0; 45962306a36Sopenharmony_ci} 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic int starfive_aes_prepare_req(struct skcipher_request *req, 46262306a36Sopenharmony_ci struct aead_request *areq) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx; 46562306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx; 46662306a36Sopenharmony_ci struct starfive_cryp_dev *cryp; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci if (!req && !areq) 46962306a36Sopenharmony_ci return -EINVAL; 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci ctx = req ? crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)) : 47262306a36Sopenharmony_ci crypto_aead_ctx(crypto_aead_reqtfm(areq)); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci cryp = ctx->cryp; 47562306a36Sopenharmony_ci rctx = req ? skcipher_request_ctx(req) : aead_request_ctx(areq); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci if (req) { 47862306a36Sopenharmony_ci cryp->req.sreq = req; 47962306a36Sopenharmony_ci cryp->total_in = req->cryptlen; 48062306a36Sopenharmony_ci cryp->total_out = req->cryptlen; 48162306a36Sopenharmony_ci cryp->assoclen = 0; 48262306a36Sopenharmony_ci cryp->authsize = 0; 48362306a36Sopenharmony_ci } else { 48462306a36Sopenharmony_ci cryp->req.areq = areq; 48562306a36Sopenharmony_ci cryp->assoclen = areq->assoclen; 48662306a36Sopenharmony_ci cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq)); 48762306a36Sopenharmony_ci if (is_encrypt(cryp)) { 48862306a36Sopenharmony_ci cryp->total_in = areq->cryptlen; 48962306a36Sopenharmony_ci cryp->total_out = areq->cryptlen; 49062306a36Sopenharmony_ci } else { 49162306a36Sopenharmony_ci cryp->total_in = areq->cryptlen - cryp->authsize; 49262306a36Sopenharmony_ci cryp->total_out = cryp->total_in; 49362306a36Sopenharmony_ci } 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci rctx->in_sg = req ? req->src : areq->src; 49762306a36Sopenharmony_ci scatterwalk_start(&cryp->in_walk, rctx->in_sg); 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci rctx->out_sg = req ? req->dst : areq->dst; 50062306a36Sopenharmony_ci scatterwalk_start(&cryp->out_walk, rctx->out_sg); 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci if (cryp->assoclen) { 50362306a36Sopenharmony_ci rctx->adata = kzalloc(ALIGN(cryp->assoclen, AES_BLOCK_SIZE), GFP_KERNEL); 50462306a36Sopenharmony_ci if (!rctx->adata) 50562306a36Sopenharmony_ci return dev_err_probe(cryp->dev, -ENOMEM, 50662306a36Sopenharmony_ci "Failed to alloc memory for adata"); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci scatterwalk_copychunks(rctx->adata, &cryp->in_walk, cryp->assoclen, 0); 50962306a36Sopenharmony_ci scatterwalk_copychunks(NULL, &cryp->out_walk, cryp->assoclen, 2); 51062306a36Sopenharmony_ci } 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci ctx->rctx = rctx; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci return starfive_aes_hw_init(ctx); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_cistatic int starfive_aes_do_one_req(struct crypto_engine *engine, void *areq) 51862306a36Sopenharmony_ci{ 51962306a36Sopenharmony_ci struct skcipher_request *req = 52062306a36Sopenharmony_ci container_of(areq, struct skcipher_request, base); 52162306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = 52262306a36Sopenharmony_ci crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)); 52362306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 52462306a36Sopenharmony_ci u32 block[AES_BLOCK_32]; 52562306a36Sopenharmony_ci u32 stat; 52662306a36Sopenharmony_ci int err; 52762306a36Sopenharmony_ci int i; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci err = starfive_aes_prepare_req(req, NULL); 53062306a36Sopenharmony_ci if (err) 53162306a36Sopenharmony_ci return err; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci /* 53462306a36Sopenharmony_ci * Write first plain/ciphertext block to start the module 53562306a36Sopenharmony_ci * then let irq tasklet handle the rest of the data blocks. 53662306a36Sopenharmony_ci */ 53762306a36Sopenharmony_ci scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, AES_BLOCK_SIZE, 53862306a36Sopenharmony_ci cryp->total_in), 0); 53962306a36Sopenharmony_ci cryp->total_in -= min_t(size_t, AES_BLOCK_SIZE, cryp->total_in); 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++) 54262306a36Sopenharmony_ci writel(block[i], cryp->base + STARFIVE_AES_AESDIO0R); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET); 54562306a36Sopenharmony_ci stat &= ~STARFIVE_IE_MASK_AES_DONE; 54662306a36Sopenharmony_ci writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET); 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci return 0; 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic int starfive_aes_init_tfm(struct crypto_skcipher *tfm) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_skcipher_ctx(tfm); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci ctx->cryp = starfive_cryp_find_dev(ctx); 55662306a36Sopenharmony_ci if (!ctx->cryp) 55762306a36Sopenharmony_ci return -ENODEV; 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, sizeof(struct starfive_cryp_request_ctx) + 56062306a36Sopenharmony_ci sizeof(struct skcipher_request)); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci return 0; 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_cistatic int starfive_aes_aead_do_one_req(struct crypto_engine *engine, void *areq) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci struct aead_request *req = 56862306a36Sopenharmony_ci container_of(areq, struct aead_request, base); 56962306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = 57062306a36Sopenharmony_ci crypto_aead_ctx(crypto_aead_reqtfm(req)); 57162306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 57262306a36Sopenharmony_ci struct starfive_cryp_request_ctx *rctx = ctx->rctx; 57362306a36Sopenharmony_ci u32 block[AES_BLOCK_32]; 57462306a36Sopenharmony_ci u32 stat; 57562306a36Sopenharmony_ci int err; 57662306a36Sopenharmony_ci int i; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci err = starfive_aes_prepare_req(NULL, req); 57962306a36Sopenharmony_ci if (err) 58062306a36Sopenharmony_ci return err; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci if (!cryp->assoclen) 58362306a36Sopenharmony_ci goto write_text; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci if ((cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_CCM) 58662306a36Sopenharmony_ci cryp->err = starfive_aes_ccm_write_adata(ctx); 58762306a36Sopenharmony_ci else 58862306a36Sopenharmony_ci cryp->err = starfive_aes_gcm_write_adata(ctx); 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci kfree(rctx->adata); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci if (cryp->err) 59362306a36Sopenharmony_ci return cryp->err; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ciwrite_text: 59662306a36Sopenharmony_ci if (!cryp->total_in) 59762306a36Sopenharmony_ci goto finish_req; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* 60062306a36Sopenharmony_ci * Write first plain/ciphertext block to start the module 60162306a36Sopenharmony_ci * then let irq tasklet handle the rest of the data blocks. 60262306a36Sopenharmony_ci */ 60362306a36Sopenharmony_ci scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, AES_BLOCK_SIZE, 60462306a36Sopenharmony_ci cryp->total_in), 0); 60562306a36Sopenharmony_ci cryp->total_in -= min_t(size_t, AES_BLOCK_SIZE, cryp->total_in); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_32; i++) 60862306a36Sopenharmony_ci writel(block[i], cryp->base + STARFIVE_AES_AESDIO0R); 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET); 61162306a36Sopenharmony_ci stat &= ~STARFIVE_IE_MASK_AES_DONE; 61262306a36Sopenharmony_ci writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET); 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci return 0; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cifinish_req: 61762306a36Sopenharmony_ci starfive_aes_finish_req(cryp); 61862306a36Sopenharmony_ci return 0; 61962306a36Sopenharmony_ci} 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_cistatic int starfive_aes_aead_init_tfm(struct crypto_aead *tfm) 62262306a36Sopenharmony_ci{ 62362306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_aead_ctx(tfm); 62462306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 62562306a36Sopenharmony_ci struct crypto_tfm *aead = crypto_aead_tfm(tfm); 62662306a36Sopenharmony_ci struct crypto_alg *alg = aead->__crt_alg; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci ctx->cryp = starfive_cryp_find_dev(ctx); 62962306a36Sopenharmony_ci if (!ctx->cryp) 63062306a36Sopenharmony_ci return -ENODEV; 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci if (alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) { 63362306a36Sopenharmony_ci ctx->aead_fbk = crypto_alloc_aead(alg->cra_name, 0, 63462306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK); 63562306a36Sopenharmony_ci if (IS_ERR(ctx->aead_fbk)) 63662306a36Sopenharmony_ci return dev_err_probe(cryp->dev, PTR_ERR(ctx->aead_fbk), 63762306a36Sopenharmony_ci "%s() failed to allocate fallback for %s\n", 63862306a36Sopenharmony_ci __func__, alg->cra_name); 63962306a36Sopenharmony_ci } 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci crypto_aead_set_reqsize(tfm, sizeof(struct starfive_cryp_ctx) + 64262306a36Sopenharmony_ci sizeof(struct aead_request)); 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci return 0; 64562306a36Sopenharmony_ci} 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_cistatic void starfive_aes_aead_exit_tfm(struct crypto_aead *tfm) 64862306a36Sopenharmony_ci{ 64962306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_aead_ctx(tfm); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci crypto_free_aead(ctx->aead_fbk); 65262306a36Sopenharmony_ci} 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_cistatic int starfive_aes_crypt(struct skcipher_request *req, unsigned long flags) 65562306a36Sopenharmony_ci{ 65662306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 65762306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_skcipher_ctx(tfm); 65862306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 65962306a36Sopenharmony_ci unsigned int blocksize_align = crypto_skcipher_blocksize(tfm) - 1; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci cryp->flags = flags; 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci if ((cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_ECB || 66462306a36Sopenharmony_ci (cryp->flags & FLG_MODE_MASK) == STARFIVE_AES_MODE_CBC) 66562306a36Sopenharmony_ci if (req->cryptlen & blocksize_align) 66662306a36Sopenharmony_ci return -EINVAL; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci return crypto_transfer_skcipher_request_to_engine(cryp->engine, req); 66962306a36Sopenharmony_ci} 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_cistatic int starfive_aes_aead_crypt(struct aead_request *req, unsigned long flags) 67262306a36Sopenharmony_ci{ 67362306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 67462306a36Sopenharmony_ci struct starfive_cryp_dev *cryp = ctx->cryp; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci cryp->flags = flags; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci /* 67962306a36Sopenharmony_ci * HW engine could not perform CCM tag verification on 68062306a36Sopenharmony_ci * non-blocksize aligned text, use fallback algo instead 68162306a36Sopenharmony_ci */ 68262306a36Sopenharmony_ci if (ctx->aead_fbk && !is_encrypt(cryp)) { 68362306a36Sopenharmony_ci struct aead_request *subreq = aead_request_ctx(req); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci aead_request_set_tfm(subreq, ctx->aead_fbk); 68662306a36Sopenharmony_ci aead_request_set_callback(subreq, req->base.flags, 68762306a36Sopenharmony_ci req->base.complete, req->base.data); 68862306a36Sopenharmony_ci aead_request_set_crypt(subreq, req->src, 68962306a36Sopenharmony_ci req->dst, req->cryptlen, req->iv); 69062306a36Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci return crypto_aead_decrypt(subreq); 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci return crypto_transfer_aead_request_to_engine(cryp->engine, req); 69662306a36Sopenharmony_ci} 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_cistatic int starfive_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, 69962306a36Sopenharmony_ci unsigned int keylen) 70062306a36Sopenharmony_ci{ 70162306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_skcipher_ctx(tfm); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci if (!key || !keylen) 70462306a36Sopenharmony_ci return -EINVAL; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci if (keylen != AES_KEYSIZE_128 && 70762306a36Sopenharmony_ci keylen != AES_KEYSIZE_192 && 70862306a36Sopenharmony_ci keylen != AES_KEYSIZE_256) 70962306a36Sopenharmony_ci return -EINVAL; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 71262306a36Sopenharmony_ci ctx->keylen = keylen; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci return 0; 71562306a36Sopenharmony_ci} 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_cistatic int starfive_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key, 71862306a36Sopenharmony_ci unsigned int keylen) 71962306a36Sopenharmony_ci{ 72062306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_aead_ctx(tfm); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci if (!key || !keylen) 72362306a36Sopenharmony_ci return -EINVAL; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci if (keylen != AES_KEYSIZE_128 && 72662306a36Sopenharmony_ci keylen != AES_KEYSIZE_192 && 72762306a36Sopenharmony_ci keylen != AES_KEYSIZE_256) 72862306a36Sopenharmony_ci return -EINVAL; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 73162306a36Sopenharmony_ci ctx->keylen = keylen; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci if (ctx->aead_fbk) 73462306a36Sopenharmony_ci return crypto_aead_setkey(ctx->aead_fbk, key, keylen); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci return 0; 73762306a36Sopenharmony_ci} 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_cistatic int starfive_aes_gcm_setauthsize(struct crypto_aead *tfm, 74062306a36Sopenharmony_ci unsigned int authsize) 74162306a36Sopenharmony_ci{ 74262306a36Sopenharmony_ci return crypto_gcm_check_authsize(authsize); 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_cistatic int starfive_aes_ccm_setauthsize(struct crypto_aead *tfm, 74662306a36Sopenharmony_ci unsigned int authsize) 74762306a36Sopenharmony_ci{ 74862306a36Sopenharmony_ci struct starfive_cryp_ctx *ctx = crypto_aead_ctx(tfm); 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci switch (authsize) { 75162306a36Sopenharmony_ci case 4: 75262306a36Sopenharmony_ci case 6: 75362306a36Sopenharmony_ci case 8: 75462306a36Sopenharmony_ci case 10: 75562306a36Sopenharmony_ci case 12: 75662306a36Sopenharmony_ci case 14: 75762306a36Sopenharmony_ci case 16: 75862306a36Sopenharmony_ci break; 75962306a36Sopenharmony_ci default: 76062306a36Sopenharmony_ci return -EINVAL; 76162306a36Sopenharmony_ci } 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci return crypto_aead_setauthsize(ctx->aead_fbk, authsize); 76462306a36Sopenharmony_ci} 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_cistatic int starfive_aes_ecb_encrypt(struct skcipher_request *req) 76762306a36Sopenharmony_ci{ 76862306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_ECB | FLG_ENCRYPT); 76962306a36Sopenharmony_ci} 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_cistatic int starfive_aes_ecb_decrypt(struct skcipher_request *req) 77262306a36Sopenharmony_ci{ 77362306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_ECB); 77462306a36Sopenharmony_ci} 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_cistatic int starfive_aes_cbc_encrypt(struct skcipher_request *req) 77762306a36Sopenharmony_ci{ 77862306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CBC | FLG_ENCRYPT); 77962306a36Sopenharmony_ci} 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_cistatic int starfive_aes_cbc_decrypt(struct skcipher_request *req) 78262306a36Sopenharmony_ci{ 78362306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CBC); 78462306a36Sopenharmony_ci} 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_cistatic int starfive_aes_cfb_encrypt(struct skcipher_request *req) 78762306a36Sopenharmony_ci{ 78862306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB | FLG_ENCRYPT); 78962306a36Sopenharmony_ci} 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_cistatic int starfive_aes_cfb_decrypt(struct skcipher_request *req) 79262306a36Sopenharmony_ci{ 79362306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB); 79462306a36Sopenharmony_ci} 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_cistatic int starfive_aes_ofb_encrypt(struct skcipher_request *req) 79762306a36Sopenharmony_ci{ 79862306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB | FLG_ENCRYPT); 79962306a36Sopenharmony_ci} 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_cistatic int starfive_aes_ofb_decrypt(struct skcipher_request *req) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB); 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_cistatic int starfive_aes_ctr_encrypt(struct skcipher_request *req) 80762306a36Sopenharmony_ci{ 80862306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CTR | FLG_ENCRYPT); 80962306a36Sopenharmony_ci} 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_cistatic int starfive_aes_ctr_decrypt(struct skcipher_request *req) 81262306a36Sopenharmony_ci{ 81362306a36Sopenharmony_ci return starfive_aes_crypt(req, STARFIVE_AES_MODE_CTR); 81462306a36Sopenharmony_ci} 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_cistatic int starfive_aes_gcm_encrypt(struct aead_request *req) 81762306a36Sopenharmony_ci{ 81862306a36Sopenharmony_ci return starfive_aes_aead_crypt(req, STARFIVE_AES_MODE_GCM | FLG_ENCRYPT); 81962306a36Sopenharmony_ci} 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_cistatic int starfive_aes_gcm_decrypt(struct aead_request *req) 82262306a36Sopenharmony_ci{ 82362306a36Sopenharmony_ci return starfive_aes_aead_crypt(req, STARFIVE_AES_MODE_GCM); 82462306a36Sopenharmony_ci} 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_cistatic int starfive_aes_ccm_encrypt(struct aead_request *req) 82762306a36Sopenharmony_ci{ 82862306a36Sopenharmony_ci int ret; 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci ret = starfive_aes_ccm_check_iv(req->iv); 83162306a36Sopenharmony_ci if (ret) 83262306a36Sopenharmony_ci return ret; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci return starfive_aes_aead_crypt(req, STARFIVE_AES_MODE_CCM | FLG_ENCRYPT); 83562306a36Sopenharmony_ci} 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_cistatic int starfive_aes_ccm_decrypt(struct aead_request *req) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci int ret; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci ret = starfive_aes_ccm_check_iv(req->iv); 84262306a36Sopenharmony_ci if (ret) 84362306a36Sopenharmony_ci return ret; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci return starfive_aes_aead_crypt(req, STARFIVE_AES_MODE_CCM); 84662306a36Sopenharmony_ci} 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_cistatic struct skcipher_engine_alg skcipher_algs[] = { 84962306a36Sopenharmony_ci{ 85062306a36Sopenharmony_ci .base.init = starfive_aes_init_tfm, 85162306a36Sopenharmony_ci .base.setkey = starfive_aes_setkey, 85262306a36Sopenharmony_ci .base.encrypt = starfive_aes_ecb_encrypt, 85362306a36Sopenharmony_ci .base.decrypt = starfive_aes_ecb_decrypt, 85462306a36Sopenharmony_ci .base.min_keysize = AES_MIN_KEY_SIZE, 85562306a36Sopenharmony_ci .base.max_keysize = AES_MAX_KEY_SIZE, 85662306a36Sopenharmony_ci .base.base = { 85762306a36Sopenharmony_ci .cra_name = "ecb(aes)", 85862306a36Sopenharmony_ci .cra_driver_name = "starfive-ecb-aes", 85962306a36Sopenharmony_ci .cra_priority = 200, 86062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 86162306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 86262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 86362306a36Sopenharmony_ci .cra_alignmask = 0xf, 86462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 86562306a36Sopenharmony_ci }, 86662306a36Sopenharmony_ci .op = { 86762306a36Sopenharmony_ci .do_one_request = starfive_aes_do_one_req, 86862306a36Sopenharmony_ci }, 86962306a36Sopenharmony_ci}, { 87062306a36Sopenharmony_ci .base.init = starfive_aes_init_tfm, 87162306a36Sopenharmony_ci .base.setkey = starfive_aes_setkey, 87262306a36Sopenharmony_ci .base.encrypt = starfive_aes_cbc_encrypt, 87362306a36Sopenharmony_ci .base.decrypt = starfive_aes_cbc_decrypt, 87462306a36Sopenharmony_ci .base.min_keysize = AES_MIN_KEY_SIZE, 87562306a36Sopenharmony_ci .base.max_keysize = AES_MAX_KEY_SIZE, 87662306a36Sopenharmony_ci .base.ivsize = AES_BLOCK_SIZE, 87762306a36Sopenharmony_ci .base.base = { 87862306a36Sopenharmony_ci .cra_name = "cbc(aes)", 87962306a36Sopenharmony_ci .cra_driver_name = "starfive-cbc-aes", 88062306a36Sopenharmony_ci .cra_priority = 200, 88162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 88262306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 88362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 88462306a36Sopenharmony_ci .cra_alignmask = 0xf, 88562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 88662306a36Sopenharmony_ci }, 88762306a36Sopenharmony_ci .op = { 88862306a36Sopenharmony_ci .do_one_request = starfive_aes_do_one_req, 88962306a36Sopenharmony_ci }, 89062306a36Sopenharmony_ci}, { 89162306a36Sopenharmony_ci .base.init = starfive_aes_init_tfm, 89262306a36Sopenharmony_ci .base.setkey = starfive_aes_setkey, 89362306a36Sopenharmony_ci .base.encrypt = starfive_aes_ctr_encrypt, 89462306a36Sopenharmony_ci .base.decrypt = starfive_aes_ctr_decrypt, 89562306a36Sopenharmony_ci .base.min_keysize = AES_MIN_KEY_SIZE, 89662306a36Sopenharmony_ci .base.max_keysize = AES_MAX_KEY_SIZE, 89762306a36Sopenharmony_ci .base.ivsize = AES_BLOCK_SIZE, 89862306a36Sopenharmony_ci .base.base = { 89962306a36Sopenharmony_ci .cra_name = "ctr(aes)", 90062306a36Sopenharmony_ci .cra_driver_name = "starfive-ctr-aes", 90162306a36Sopenharmony_ci .cra_priority = 200, 90262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 90362306a36Sopenharmony_ci .cra_blocksize = 1, 90462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 90562306a36Sopenharmony_ci .cra_alignmask = 0xf, 90662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 90762306a36Sopenharmony_ci }, 90862306a36Sopenharmony_ci .op = { 90962306a36Sopenharmony_ci .do_one_request = starfive_aes_do_one_req, 91062306a36Sopenharmony_ci }, 91162306a36Sopenharmony_ci}, { 91262306a36Sopenharmony_ci .base.init = starfive_aes_init_tfm, 91362306a36Sopenharmony_ci .base.setkey = starfive_aes_setkey, 91462306a36Sopenharmony_ci .base.encrypt = starfive_aes_cfb_encrypt, 91562306a36Sopenharmony_ci .base.decrypt = starfive_aes_cfb_decrypt, 91662306a36Sopenharmony_ci .base.min_keysize = AES_MIN_KEY_SIZE, 91762306a36Sopenharmony_ci .base.max_keysize = AES_MAX_KEY_SIZE, 91862306a36Sopenharmony_ci .base.ivsize = AES_BLOCK_SIZE, 91962306a36Sopenharmony_ci .base.base = { 92062306a36Sopenharmony_ci .cra_name = "cfb(aes)", 92162306a36Sopenharmony_ci .cra_driver_name = "starfive-cfb-aes", 92262306a36Sopenharmony_ci .cra_priority = 200, 92362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 92462306a36Sopenharmony_ci .cra_blocksize = 1, 92562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 92662306a36Sopenharmony_ci .cra_alignmask = 0xf, 92762306a36Sopenharmony_ci .cra_module = THIS_MODULE, 92862306a36Sopenharmony_ci }, 92962306a36Sopenharmony_ci .op = { 93062306a36Sopenharmony_ci .do_one_request = starfive_aes_do_one_req, 93162306a36Sopenharmony_ci }, 93262306a36Sopenharmony_ci}, { 93362306a36Sopenharmony_ci .base.init = starfive_aes_init_tfm, 93462306a36Sopenharmony_ci .base.setkey = starfive_aes_setkey, 93562306a36Sopenharmony_ci .base.encrypt = starfive_aes_ofb_encrypt, 93662306a36Sopenharmony_ci .base.decrypt = starfive_aes_ofb_decrypt, 93762306a36Sopenharmony_ci .base.min_keysize = AES_MIN_KEY_SIZE, 93862306a36Sopenharmony_ci .base.max_keysize = AES_MAX_KEY_SIZE, 93962306a36Sopenharmony_ci .base.ivsize = AES_BLOCK_SIZE, 94062306a36Sopenharmony_ci .base.base = { 94162306a36Sopenharmony_ci .cra_name = "ofb(aes)", 94262306a36Sopenharmony_ci .cra_driver_name = "starfive-ofb-aes", 94362306a36Sopenharmony_ci .cra_priority = 200, 94462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 94562306a36Sopenharmony_ci .cra_blocksize = 1, 94662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 94762306a36Sopenharmony_ci .cra_alignmask = 0xf, 94862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 94962306a36Sopenharmony_ci }, 95062306a36Sopenharmony_ci .op = { 95162306a36Sopenharmony_ci .do_one_request = starfive_aes_do_one_req, 95262306a36Sopenharmony_ci }, 95362306a36Sopenharmony_ci}, 95462306a36Sopenharmony_ci}; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_cistatic struct aead_engine_alg aead_algs[] = { 95762306a36Sopenharmony_ci{ 95862306a36Sopenharmony_ci .base.setkey = starfive_aes_aead_setkey, 95962306a36Sopenharmony_ci .base.setauthsize = starfive_aes_gcm_setauthsize, 96062306a36Sopenharmony_ci .base.encrypt = starfive_aes_gcm_encrypt, 96162306a36Sopenharmony_ci .base.decrypt = starfive_aes_gcm_decrypt, 96262306a36Sopenharmony_ci .base.init = starfive_aes_aead_init_tfm, 96362306a36Sopenharmony_ci .base.exit = starfive_aes_aead_exit_tfm, 96462306a36Sopenharmony_ci .base.ivsize = GCM_AES_IV_SIZE, 96562306a36Sopenharmony_ci .base.maxauthsize = AES_BLOCK_SIZE, 96662306a36Sopenharmony_ci .base.base = { 96762306a36Sopenharmony_ci .cra_name = "gcm(aes)", 96862306a36Sopenharmony_ci .cra_driver_name = "starfive-gcm-aes", 96962306a36Sopenharmony_ci .cra_priority = 200, 97062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC, 97162306a36Sopenharmony_ci .cra_blocksize = 1, 97262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 97362306a36Sopenharmony_ci .cra_alignmask = 0xf, 97462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 97562306a36Sopenharmony_ci }, 97662306a36Sopenharmony_ci .op = { 97762306a36Sopenharmony_ci .do_one_request = starfive_aes_aead_do_one_req, 97862306a36Sopenharmony_ci }, 97962306a36Sopenharmony_ci}, { 98062306a36Sopenharmony_ci .base.setkey = starfive_aes_aead_setkey, 98162306a36Sopenharmony_ci .base.setauthsize = starfive_aes_ccm_setauthsize, 98262306a36Sopenharmony_ci .base.encrypt = starfive_aes_ccm_encrypt, 98362306a36Sopenharmony_ci .base.decrypt = starfive_aes_ccm_decrypt, 98462306a36Sopenharmony_ci .base.init = starfive_aes_aead_init_tfm, 98562306a36Sopenharmony_ci .base.exit = starfive_aes_aead_exit_tfm, 98662306a36Sopenharmony_ci .base.ivsize = AES_BLOCK_SIZE, 98762306a36Sopenharmony_ci .base.maxauthsize = AES_BLOCK_SIZE, 98862306a36Sopenharmony_ci .base.base = { 98962306a36Sopenharmony_ci .cra_name = "ccm(aes)", 99062306a36Sopenharmony_ci .cra_driver_name = "starfive-ccm-aes", 99162306a36Sopenharmony_ci .cra_priority = 200, 99262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 99362306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 99462306a36Sopenharmony_ci .cra_blocksize = 1, 99562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct starfive_cryp_ctx), 99662306a36Sopenharmony_ci .cra_alignmask = 0xf, 99762306a36Sopenharmony_ci .cra_module = THIS_MODULE, 99862306a36Sopenharmony_ci }, 99962306a36Sopenharmony_ci .op = { 100062306a36Sopenharmony_ci .do_one_request = starfive_aes_aead_do_one_req, 100162306a36Sopenharmony_ci }, 100262306a36Sopenharmony_ci}, 100362306a36Sopenharmony_ci}; 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ciint starfive_aes_register_algs(void) 100662306a36Sopenharmony_ci{ 100762306a36Sopenharmony_ci int ret; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci ret = crypto_engine_register_skciphers(skcipher_algs, ARRAY_SIZE(skcipher_algs)); 101062306a36Sopenharmony_ci if (ret) 101162306a36Sopenharmony_ci return ret; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci ret = crypto_engine_register_aeads(aead_algs, ARRAY_SIZE(aead_algs)); 101462306a36Sopenharmony_ci if (ret) 101562306a36Sopenharmony_ci crypto_engine_unregister_skciphers(skcipher_algs, ARRAY_SIZE(skcipher_algs)); 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_ci return ret; 101862306a36Sopenharmony_ci} 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_civoid starfive_aes_unregister_algs(void) 102162306a36Sopenharmony_ci{ 102262306a36Sopenharmony_ci crypto_engine_unregister_aeads(aead_algs, ARRAY_SIZE(aead_algs)); 102362306a36Sopenharmony_ci crypto_engine_unregister_skciphers(skcipher_algs, ARRAY_SIZE(skcipher_algs)); 102462306a36Sopenharmony_ci} 1025