meta-st-stm32mp/recipes-kernel/linux/linux-stm32mp/5.15/5.15.24/0004-ARM-5.15.24-stm32mp1-r...

1540 lines
45 KiB
Diff

From a3e88eba0837217682d75a26b81498d6476d0cc2 Mon Sep 17 00:00:00 2001
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
Date: Tue, 31 May 2022 11:51:37 +0200
Subject: [PATCH 04/22] ARM-5.15.24-stm32mp1-r1-CRYPTO
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
---
drivers/crypto/stm32/stm32-cryp.c | 50 +-
drivers/crypto/stm32/stm32-hash.c | 839 ++++++++++++++++++++++--------
2 files changed, 662 insertions(+), 227 deletions(-)
diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
index 81eb136b6..59ef54112 100644
--- a/drivers/crypto/stm32/stm32-cryp.c
+++ b/drivers/crypto/stm32/stm32-cryp.c
@@ -232,6 +232,11 @@ static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp)
!(status & SR_BUSY), 10, 100000);
}
+static inline void stm32_cryp_enable(struct stm32_cryp *cryp)
+{
+ writel_relaxed(readl_relaxed(cryp->regs + CRYP_CR) | CR_CRYPEN, cryp->regs + CRYP_CR);
+}
+
static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp)
{
u32 status;
@@ -535,9 +540,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
/* Disable interrupt */
stm32_cryp_write(cryp, CRYP_IMSCR, 0);
- /* Set key */
- stm32_cryp_hw_write_key(cryp);
-
/* Set configuration */
cfg = CR_DATA8 | CR_FFLUSH;
@@ -563,23 +565,36 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
/* AES ECB/CBC decrypt: run key preparation first */
if (is_decrypt(cryp) &&
((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) {
- stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN);
+ /* Configure in key preparation mode */
+ stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP);
+
+ /* Set key only after full configuration done */
+ stm32_cryp_hw_write_key(cryp);
+ /* Start prepare key */
+ stm32_cryp_enable(cryp);
/* Wait for end of processing */
ret = stm32_cryp_wait_busy(cryp);
if (ret) {
dev_err(cryp->dev, "Timeout (key preparation)\n");
return ret;
}
- }
- cfg |= hw_mode;
+ cfg |= hw_mode | CR_DEC_NOT_ENC;
- if (is_decrypt(cryp))
- cfg |= CR_DEC_NOT_ENC;
+ /* Apply updated config (Decrypt + algo) and flush */
+ stm32_cryp_write(cryp, CRYP_CR, cfg);
+ } else {
+ cfg |= hw_mode;
+ if (is_decrypt(cryp))
+ cfg |= CR_DEC_NOT_ENC;
- /* Apply config and flush (valid when CRYPEN = 0) */
- stm32_cryp_write(cryp, CRYP_CR, cfg);
+ /* Apply config and flush */
+ stm32_cryp_write(cryp, CRYP_CR, cfg);
+
+ /* Set key only after configuration done */
+ stm32_cryp_hw_write_key(cryp);
+ }
switch (hw_mode) {
case CR_AES_GCM:
@@ -607,9 +622,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
}
/* Enable now */
- cfg |= CR_CRYPEN;
-
- stm32_cryp_write(cryp, CRYP_CR, cfg);
+ stm32_cryp_enable(cryp);
return 0;
}
@@ -1761,7 +1774,8 @@ static int stm32_cryp_probe(struct platform_device *pdev)
cryp->clk = devm_clk_get(dev, NULL);
if (IS_ERR(cryp->clk)) {
- dev_err(dev, "Could not get clock\n");
+ dev_err_probe(dev, PTR_ERR(cryp->clk), "Could not get clock\n");
+
return PTR_ERR(cryp->clk);
}
@@ -1779,7 +1793,11 @@ static int stm32_cryp_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
rst = devm_reset_control_get(dev, NULL);
- if (!IS_ERR(rst)) {
+ if (IS_ERR(rst)) {
+ ret = PTR_ERR(rst);
+ if (ret == -EPROBE_DEFER)
+ goto err_rst;
+ } else {
reset_control_assert(rst);
udelay(2);
reset_control_deassert(rst);
@@ -1830,7 +1848,7 @@ static int stm32_cryp_probe(struct platform_device *pdev)
spin_lock(&cryp_list.lock);
list_del(&cryp->list);
spin_unlock(&cryp_list.lock);
-
+err_rst:
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
index d33006d43..383324f5f 100644
--- a/drivers/crypto/stm32/stm32-hash.c
+++ b/drivers/crypto/stm32/stm32-hash.c
@@ -27,6 +27,7 @@
#include <crypto/scatterwalk.h>
#include <crypto/sha1.h>
#include <crypto/sha2.h>
+#include <crypto/sha3.h>
#include <crypto/internal/hash.h>
#define HASH_CR 0x00
@@ -49,11 +50,6 @@
#define HASH_CR_DMAA BIT(14)
#define HASH_CR_LKEY BIT(16)
-#define HASH_CR_ALGO_SHA1 0x0
-#define HASH_CR_ALGO_MD5 0x80
-#define HASH_CR_ALGO_SHA224 0x40000
-#define HASH_CR_ALGO_SHA256 0x40080
-
/* Interrupt */
#define HASH_DINIE BIT(0)
#define HASH_DCIE BIT(1)
@@ -62,9 +58,6 @@
#define HASH_MASK_CALC_COMPLETION BIT(0)
#define HASH_MASK_DATA_INPUT BIT(1)
-/* Context swap register */
-#define HASH_CSR_REGISTER_NUMBER 53
-
/* Status Flags */
#define HASH_SR_DATA_INPUT_READY BIT(0)
#define HASH_SR_OUTPUT_READY BIT(1)
@@ -75,6 +68,17 @@
#define HASH_STR_NBLW_MASK GENMASK(4, 0)
#define HASH_STR_DCAL BIT(8)
+/* HWCFGR Register */
+#define HASH_HWCFG_DMA_MASK GENMASK(3, 0)
+
+/* CSR register */
+#define HASH_CSR_NB_SHA256_HMAC 54
+#define HASH_CSR_NB_SHA256 22
+#define HASH_CSR_NB_SHA512_HMAC 103
+#define HASH_CSR_NB_SHA512 91
+#define HASH_CSR_NB_SHA3_HMAC 88
+#define HASH_CSR_NB_SHA3 72
+
#define HASH_FLAGS_INIT BIT(0)
#define HASH_FLAGS_OUTPUT_READY BIT(1)
#define HASH_FLAGS_CPU BIT(2)
@@ -83,20 +87,19 @@
#define HASH_FLAGS_HMAC_INIT BIT(5)
#define HASH_FLAGS_HMAC_FINAL BIT(6)
#define HASH_FLAGS_HMAC_KEY BIT(7)
-
+#define HASH_FLAGS_SHA3_MODE BIT(8)
#define HASH_FLAGS_FINAL BIT(15)
#define HASH_FLAGS_FINUP BIT(16)
-#define HASH_FLAGS_ALGO_MASK GENMASK(21, 18)
-#define HASH_FLAGS_MD5 BIT(18)
-#define HASH_FLAGS_SHA1 BIT(19)
-#define HASH_FLAGS_SHA224 BIT(20)
-#define HASH_FLAGS_SHA256 BIT(21)
-#define HASH_FLAGS_ERRORS BIT(22)
-#define HASH_FLAGS_HMAC BIT(23)
+#define HASH_FLAGS_ALGO_MASK GENMASK(20, 17)
+#define HASH_FLAGS_ALGO_SHIFT 17
+#define HASH_FLAGS_ERRORS BIT(21)
+#define HASH_FLAGS_HMAC BIT(22)
#define HASH_OP_UPDATE 1
#define HASH_OP_FINAL 2
+#define HASH_BURST_LEVEL 4
+
enum stm32_hash_data_format {
HASH_DATA_32_BITS = 0x0,
HASH_DATA_16_BITS = 0x1,
@@ -104,17 +107,26 @@ enum stm32_hash_data_format {
HASH_DATA_1_BIT = 0x3
};
-#define HASH_BUFLEN 256
-#define HASH_LONG_KEY 64
-#define HASH_MAX_KEY_SIZE (SHA256_BLOCK_SIZE * 8)
-#define HASH_QUEUE_LENGTH 16
-#define HASH_DMA_THRESHOLD 50
+enum stm32_hash_algo {
+ HASH_SHA1 = 0,
+ HASH_MD5 = 1,
+ HASH_SHA224 = 2,
+ HASH_SHA256 = 3,
+ HASH_SHA3_224 = 4,
+ HASH_SHA3_256 = 5,
+ HASH_SHA3_384 = 6,
+ HASH_SHA3_512 = 7,
+ HASH_SHA384 = 12,
+ HASH_SHA512 = 15,
+};
+#define HASH_MAX_BUFLEN (SHA3_224_BLOCK_SIZE + 4)
+#define HASH_MAX_KEY_SIZE (SHA512_BLOCK_SIZE * 8)
+#define HASH_QUEUE_LENGTH 60
#define HASH_AUTOSUSPEND_DELAY 50
struct stm32_hash_ctx {
struct crypto_engine_ctx enginectx;
- struct stm32_hash_dev *hdev;
unsigned long flags;
u8 key[HASH_MAX_KEY_SIZE];
@@ -126,8 +138,7 @@ struct stm32_hash_request_ctx {
unsigned long flags;
unsigned long op;
- u8 digest[SHA256_DIGEST_SIZE] __aligned(sizeof(u32));
- size_t digcnt;
+ u8 digest[SHA512_DIGEST_SIZE] __aligned(sizeof(u32));
size_t bufcnt;
size_t buflen;
@@ -143,7 +154,7 @@ struct stm32_hash_request_ctx {
u8 data_type;
- u8 buffer[HASH_BUFLEN] __aligned(sizeof(u32));
+ u8 buffer[HASH_MAX_BUFLEN] __aligned(sizeof(u32));
/* Export Context */
u32 *hw_context;
@@ -155,8 +166,9 @@ struct stm32_hash_algs_info {
};
struct stm32_hash_pdata {
- struct stm32_hash_algs_info *algs_info;
- size_t algs_info_size;
+ const int alg_shift;
+ const struct stm32_hash_algs_info *algs_info;
+ size_t algs_info_size;
};
struct stm32_hash_dev {
@@ -167,10 +179,10 @@ struct stm32_hash_dev {
void __iomem *io_base;
phys_addr_t phys_base;
u32 dma_mode;
- u32 dma_maxburst;
struct ahash_request *req;
struct crypto_engine *engine;
+ struct crypto_queue queue;
int err;
unsigned long flags;
@@ -212,11 +224,18 @@ static inline int stm32_hash_wait_busy(struct stm32_hash_dev *hdev)
!(status & HASH_SR_BUSY), 10, 10000);
}
+static inline int stm32_hash_wait_dinis(struct stm32_hash_dev *hdev)
+{
+ u32 status;
+
+ return readl_relaxed_poll_timeout(hdev->io_base + HASH_SR, status,
+ (status & HASH_SR_DATA_INPUT_READY), 10, 10000);
+}
+
static void stm32_hash_set_nblw(struct stm32_hash_dev *hdev, int length)
{
- u32 reg;
+ u32 reg = stm32_hash_read(hdev, HASH_STR);
- reg = stm32_hash_read(hdev, HASH_STR);
reg &= ~(HASH_STR_NBLW_MASK);
reg |= (8U * ((length) % 4U));
stm32_hash_write(hdev, HASH_STR, reg);
@@ -254,44 +273,32 @@ static void stm32_hash_write_ctrl(struct stm32_hash_dev *hdev)
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(hdev->req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(hdev->req);
struct stm32_hash_ctx *ctx = crypto_ahash_ctx(tfm);
-
+ u32 alg = (rctx->flags & HASH_FLAGS_ALGO_MASK) >> HASH_FLAGS_ALGO_SHIFT;
u32 reg = HASH_CR_INIT;
- if (!(hdev->flags & HASH_FLAGS_INIT)) {
- switch (rctx->flags & HASH_FLAGS_ALGO_MASK) {
- case HASH_FLAGS_MD5:
- reg |= HASH_CR_ALGO_MD5;
- break;
- case HASH_FLAGS_SHA1:
- reg |= HASH_CR_ALGO_SHA1;
- break;
- case HASH_FLAGS_SHA224:
- reg |= HASH_CR_ALGO_SHA224;
- break;
- case HASH_FLAGS_SHA256:
- reg |= HASH_CR_ALGO_SHA256;
- break;
- default:
- reg |= HASH_CR_ALGO_MD5;
- }
+ if (hdev->pdata->alg_shift == 7)
+ reg |= ((alg & BIT(1)) << 17) | ((alg & BIT(0)) << 7);
+ else
+ reg |= alg << hdev->pdata->alg_shift;
- reg |= (rctx->data_type << HASH_CR_DATATYPE_POS);
+ reg |= (rctx->data_type << HASH_CR_DATATYPE_POS);
- if (rctx->flags & HASH_FLAGS_HMAC) {
- hdev->flags |= HASH_FLAGS_HMAC;
- reg |= HASH_CR_MODE;
- if (ctx->keylen > HASH_LONG_KEY)
- reg |= HASH_CR_LKEY;
- }
+ if (rctx->flags & HASH_FLAGS_HMAC) {
+ hdev->flags |= HASH_FLAGS_HMAC;
+ reg |= HASH_CR_MODE;
+ if (ctx->keylen > (rctx->buflen - sizeof(uint32_t)))
+ reg |= HASH_CR_LKEY;
+ }
- stm32_hash_write(hdev, HASH_IMR, HASH_DCIE);
+ stm32_hash_write(hdev, HASH_IMR, HASH_DCIE);
+ stm32_hash_write(hdev, HASH_CR, reg);
+ stm32_hash_read(hdev, HASH_SR);
- stm32_hash_write(hdev, HASH_CR, reg);
+ hdev->flags |= HASH_FLAGS_INIT;
- hdev->flags |= HASH_FLAGS_INIT;
+ dev_dbg(hdev->dev, "Write Control %x\n", reg);
- dev_dbg(hdev->dev, "Write Control %x\n", reg);
- }
+ rctx->buflen = rctx->buflen - sizeof(uint32_t);
}
static void stm32_hash_append_sg(struct stm32_hash_request_ctx *rctx)
@@ -328,11 +335,12 @@ static void stm32_hash_append_sg(struct stm32_hash_request_ctx *rctx)
}
}
-static int stm32_hash_xmit_cpu(struct stm32_hash_dev *hdev,
- const u8 *buf, size_t length, int final)
+static int stm32_hash_xmit_cpu(struct stm32_hash_request_ctx *rctx,
+ size_t length, int final)
{
+ const u32 *buffer = (const u32 *)rctx->buffer;
+ struct stm32_hash_dev *hdev = rctx->hdev;
unsigned int count, len32;
- const u32 *buffer = (const u32 *)buf;
u32 reg;
if (final)
@@ -345,10 +353,8 @@ static int stm32_hash_xmit_cpu(struct stm32_hash_dev *hdev,
hdev->flags |= HASH_FLAGS_CPU;
- stm32_hash_write_ctrl(hdev);
-
- if (stm32_hash_wait_busy(hdev))
- return -ETIMEDOUT;
+ if (!(hdev->flags & HASH_FLAGS_INIT))
+ stm32_hash_write_ctrl(hdev);
if ((hdev->flags & HASH_FLAGS_HMAC) &&
(!(hdev->flags & HASH_FLAGS_HMAC_KEY))) {
@@ -371,6 +377,7 @@ static int stm32_hash_xmit_cpu(struct stm32_hash_dev *hdev,
return -ETIMEDOUT;
stm32_hash_write_key(hdev);
}
+
return -EINPROGRESS;
}
@@ -386,12 +393,12 @@ static int stm32_hash_update_cpu(struct stm32_hash_dev *hdev)
final = (rctx->flags & HASH_FLAGS_FINUP);
- while ((rctx->total >= rctx->buflen) ||
- (rctx->bufcnt + rctx->total >= rctx->buflen)) {
+ while ((rctx->total > rctx->buflen) ||
+ (rctx->bufcnt + rctx->total > rctx->buflen)) {
stm32_hash_append_sg(rctx);
bufcnt = rctx->bufcnt;
rctx->bufcnt = 0;
- err = stm32_hash_xmit_cpu(hdev, rctx->buffer, bufcnt, 0);
+ err = stm32_hash_xmit_cpu(rctx, bufcnt, 0);
}
stm32_hash_append_sg(rctx);
@@ -399,7 +406,7 @@ static int stm32_hash_update_cpu(struct stm32_hash_dev *hdev)
if (final) {
bufcnt = rctx->bufcnt;
rctx->bufcnt = 0;
- err = stm32_hash_xmit_cpu(hdev, rctx->buffer, bufcnt,
+ err = stm32_hash_xmit_cpu(rctx, bufcnt,
(rctx->flags & HASH_FLAGS_FINUP));
}
@@ -482,7 +489,7 @@ static int stm32_hash_hmac_dma_send(struct stm32_hash_dev *hdev)
struct stm32_hash_ctx *ctx = crypto_ahash_ctx(tfm);
int err;
- if (ctx->keylen < HASH_DMA_THRESHOLD || (hdev->dma_mode == 1)) {
+ if (ctx->keylen < rctx->buflen || (hdev->dma_mode == 1)) {
err = stm32_hash_write_key(hdev);
if (stm32_hash_wait_busy(hdev))
return -ETIMEDOUT;
@@ -517,8 +524,8 @@ static int stm32_hash_dma_init(struct stm32_hash_dev *hdev)
dma_conf.direction = DMA_MEM_TO_DEV;
dma_conf.dst_addr = hdev->phys_base + HASH_DIN;
dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- dma_conf.src_maxburst = hdev->dma_maxburst;
- dma_conf.dst_maxburst = hdev->dma_maxburst;
+ dma_conf.src_maxburst = HASH_BURST_LEVEL;
+ dma_conf.dst_maxburst = HASH_BURST_LEVEL;
dma_conf.device_fc = false;
chan = dma_request_chan(hdev->dev, "in");
@@ -552,11 +559,11 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev)
rctx->total = hdev->req->nbytes;
rctx->nents = sg_nents(rctx->sg);
-
if (rctx->nents < 0)
return -EINVAL;
- stm32_hash_write_ctrl(hdev);
+ if (!(hdev->flags & HASH_FLAGS_INIT))
+ stm32_hash_write_ctrl(hdev);
if (hdev->flags & HASH_FLAGS_HMAC) {
err = stm32_hash_hmac_dma_send(hdev);
@@ -633,21 +640,17 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev)
return err;
}
-static struct stm32_hash_dev *stm32_hash_find_dev(struct stm32_hash_ctx *ctx)
+static struct stm32_hash_dev *stm32_hash_find_dev(struct stm32_hash_request_ctx *rctx)
{
- struct stm32_hash_dev *hdev = NULL, *tmp;
+ struct stm32_hash_dev *hdev = NULL;
- spin_lock_bh(&stm32_hash.lock);
- if (!ctx->hdev) {
- list_for_each_entry(tmp, &stm32_hash.dev_list, list) {
- hdev = tmp;
- break;
- }
- ctx->hdev = hdev;
- } else {
- hdev = ctx->hdev;
- }
+ if (rctx->hdev)
+ return rctx->hdev;
+ spin_lock_bh(&stm32_hash.lock);
+ hdev = list_first_entry(&stm32_hash.dev_list, struct stm32_hash_dev, list);
+ list_move_tail(&hdev->list, &stm32_hash.dev_list);
+ rctx->hdev = hdev;
spin_unlock_bh(&stm32_hash.lock);
return hdev;
@@ -656,16 +659,17 @@ static struct stm32_hash_dev *stm32_hash_find_dev(struct stm32_hash_ctx *ctx)
static bool stm32_hash_dma_aligned_data(struct ahash_request *req)
{
struct scatterlist *sg;
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
+ struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+ struct stm32_hash_dev *hdev = rctx->hdev;
int i;
- if (req->nbytes <= HASH_DMA_THRESHOLD)
+ if ((!hdev->dma_lch) || (req->nbytes <= rctx->buflen))
return false;
if (sg_nents(req->src) > 1) {
if (hdev->dma_mode == 1)
return false;
+
for_each_sg(req->src, sg, sg_nents(req->src), i) {
if ((!IS_ALIGNED(sg->length, sizeof(u32))) &&
(!sg_is_last(sg)))
@@ -684,37 +688,61 @@ static int stm32_hash_init(struct ahash_request *req)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct stm32_hash_ctx *ctx = crypto_ahash_ctx(tfm);
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
+ struct stm32_hash_dev *hdev;
+ bool sha3_mode = ctx->flags & HASH_FLAGS_SHA3_MODE;
- rctx->hdev = hdev;
+ rctx->hdev = NULL;
+ hdev = stm32_hash_find_dev(rctx);
+ if (!hdev)
+ return -ENODEV;
rctx->flags = HASH_FLAGS_CPU;
- rctx->digcnt = crypto_ahash_digestsize(tfm);
- switch (rctx->digcnt) {
+ if (sha3_mode)
+ rctx->flags |= HASH_FLAGS_SHA3_MODE;
+
+ switch (crypto_ahash_digestsize(tfm)) {
case MD5_DIGEST_SIZE:
- rctx->flags |= HASH_FLAGS_MD5;
+ rctx->flags |= HASH_MD5 << HASH_FLAGS_ALGO_SHIFT;
break;
case SHA1_DIGEST_SIZE:
- rctx->flags |= HASH_FLAGS_SHA1;
+ rctx->flags |= HASH_SHA1 << HASH_FLAGS_ALGO_SHIFT;
break;
case SHA224_DIGEST_SIZE:
- rctx->flags |= HASH_FLAGS_SHA224;
+ if (sha3_mode)
+ rctx->flags |= HASH_SHA3_224 << HASH_FLAGS_ALGO_SHIFT;
+ else
+ rctx->flags |= HASH_SHA224 << HASH_FLAGS_ALGO_SHIFT;
break;
case SHA256_DIGEST_SIZE:
- rctx->flags |= HASH_FLAGS_SHA256;
+ if (sha3_mode)
+ rctx->flags |= HASH_SHA3_256 << HASH_FLAGS_ALGO_SHIFT;
+ else
+ rctx->flags |= HASH_SHA256 << HASH_FLAGS_ALGO_SHIFT;
+ break;
+ case SHA384_DIGEST_SIZE:
+ if (sha3_mode)
+ rctx->flags |= HASH_SHA3_384 << HASH_FLAGS_ALGO_SHIFT;
+ else
+ rctx->flags |= HASH_SHA384 << HASH_FLAGS_ALGO_SHIFT;
+ break;
+ case SHA512_DIGEST_SIZE:
+ if (sha3_mode)
+ rctx->flags |= HASH_SHA3_512 << HASH_FLAGS_ALGO_SHIFT;
+ else
+ rctx->flags |= HASH_SHA512 << HASH_FLAGS_ALGO_SHIFT;
break;
default:
return -EINVAL;
}
+ rctx->buflen = crypto_ahash_blocksize(tfm) + sizeof(uint32_t);
rctx->bufcnt = 0;
- rctx->buflen = HASH_BUFLEN;
rctx->total = 0;
rctx->offset = 0;
rctx->data_type = HASH_DATA_8_BITS;
- memset(rctx->buffer, 0, HASH_BUFLEN);
+ memset(rctx->buffer, 0, rctx->buflen);
if (ctx->flags & HASH_FLAGS_HMAC)
rctx->flags |= HASH_FLAGS_HMAC;
@@ -741,8 +769,7 @@ static int stm32_hash_final_req(struct stm32_hash_dev *hdev)
if (!(rctx->flags & HASH_FLAGS_CPU))
err = stm32_hash_dma_send(hdev);
else
- err = stm32_hash_xmit_cpu(hdev, rctx->buffer, buflen, 1);
-
+ err = stm32_hash_xmit_cpu(rctx, buflen, 1);
return err;
}
@@ -750,39 +777,31 @@ static int stm32_hash_final_req(struct stm32_hash_dev *hdev)
static void stm32_hash_copy_hash(struct ahash_request *req)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ unsigned int hashsize = crypto_ahash_digestsize(tfm);
__be32 *hash = (void *)rctx->digest;
- unsigned int i, hashsize;
-
- switch (rctx->flags & HASH_FLAGS_ALGO_MASK) {
- case HASH_FLAGS_MD5:
- hashsize = MD5_DIGEST_SIZE;
- break;
- case HASH_FLAGS_SHA1:
- hashsize = SHA1_DIGEST_SIZE;
- break;
- case HASH_FLAGS_SHA224:
- hashsize = SHA224_DIGEST_SIZE;
- break;
- case HASH_FLAGS_SHA256:
- hashsize = SHA256_DIGEST_SIZE;
- break;
- default:
- return;
- }
+ unsigned int i;
+ u32 reg;
for (i = 0; i < hashsize / sizeof(u32); i++)
hash[i] = cpu_to_be32(stm32_hash_read(rctx->hdev,
HASH_HREG(i)));
+
+ reg = stm32_hash_read(rctx->hdev, HASH_SR);
+ reg &= ~HASH_SR_OUTPUT_READY;
+ stm32_hash_write(rctx->hdev, HASH_SR, reg);
}
static int stm32_hash_finish(struct ahash_request *req)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ unsigned int digsize = crypto_ahash_digestsize(tfm);
if (!req->result)
return -EINVAL;
- memcpy(req->result, rctx->digest, rctx->digcnt);
+ memcpy(req->result, rctx->digest, digsize);
return 0;
}
@@ -799,7 +818,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err)
HASH_FLAGS_INIT | HASH_FLAGS_DMA_READY |
HASH_FLAGS_OUTPUT_READY | HASH_FLAGS_HMAC |
HASH_FLAGS_HMAC_INIT | HASH_FLAGS_HMAC_FINAL |
- HASH_FLAGS_HMAC_KEY);
+ HASH_FLAGS_HMAC_KEY | HASH_FLAGS_SHA3_MODE);
} else {
rctx->flags |= HASH_FLAGS_ERRORS;
}
@@ -810,8 +829,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err)
crypto_finalize_hash_request(hdev->engine, req, err);
}
-static int stm32_hash_hw_init(struct stm32_hash_dev *hdev,
- struct stm32_hash_request_ctx *rctx)
+static int stm32_hash_hw_init(struct stm32_hash_dev *hdev)
{
pm_runtime_get_sync(hdev->dev);
@@ -839,38 +857,30 @@ static int stm32_hash_prepare_req(struct crypto_engine *engine, void *areq)
{
struct ahash_request *req = container_of(areq, struct ahash_request,
base);
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
- struct stm32_hash_request_ctx *rctx;
-
- if (!hdev)
- return -ENODEV;
+ struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+ struct stm32_hash_dev *hdev = rctx->hdev;
hdev->req = req;
- rctx = ahash_request_ctx(req);
-
dev_dbg(hdev->dev, "processing new req, op: %lu, nbytes %d\n",
rctx->op, req->nbytes);
- return stm32_hash_hw_init(hdev, rctx);
+ return stm32_hash_hw_init(hdev);
}
static int stm32_hash_one_request(struct crypto_engine *engine, void *areq)
{
struct ahash_request *req = container_of(areq, struct ahash_request,
base);
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
- struct stm32_hash_request_ctx *rctx;
+ struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+ struct stm32_hash_dev *hdev = rctx->hdev;
int err = 0;
- if (!hdev)
- return -ENODEV;
-
hdev->req = req;
- rctx = ahash_request_ctx(req);
+ err = stm32_hash_hw_init(hdev);
+ if (err)
+ return err;
if (rctx->op == HASH_OP_UPDATE)
err = stm32_hash_update_req(hdev);
@@ -887,8 +897,7 @@ static int stm32_hash_one_request(struct crypto_engine *engine, void *areq)
static int stm32_hash_enqueue(struct ahash_request *req, unsigned int op)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- struct stm32_hash_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
- struct stm32_hash_dev *hdev = ctx->hdev;
+ struct stm32_hash_dev *hdev = rctx->hdev;
rctx->op = op;
@@ -899,14 +908,16 @@ static int stm32_hash_update(struct ahash_request *req)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- if (!req->nbytes || !(rctx->flags & HASH_FLAGS_CPU))
+ if ((!req->nbytes) || !(rctx->flags & HASH_FLAGS_CPU))
return 0;
+ stm32_hash_find_dev(rctx);
+
rctx->total = req->nbytes;
rctx->sg = req->src;
rctx->offset = 0;
- if ((rctx->bufcnt + rctx->total < rctx->buflen)) {
+ if (rctx->bufcnt + rctx->total <= rctx->buflen) {
stm32_hash_append_sg(rctx);
return 0;
}
@@ -926,15 +937,10 @@ static int stm32_hash_final(struct ahash_request *req)
static int stm32_hash_finup(struct ahash_request *req)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
int err1, err2;
rctx->flags |= HASH_FLAGS_FINUP;
- if (hdev->dma_lch && stm32_hash_dma_aligned_data(req))
- rctx->flags &= ~HASH_FLAGS_CPU;
-
err1 = stm32_hash_update(req);
if (err1 == -EINPROGRESS || err1 == -EBUSY)
@@ -951,32 +957,81 @@ static int stm32_hash_finup(struct ahash_request *req)
static int stm32_hash_digest(struct ahash_request *req)
{
- return stm32_hash_init(req) ?: stm32_hash_finup(req);
+ int ret;
+ struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
+
+ ret = stm32_hash_init(req);
+ if (ret)
+ return ret;
+
+ if (stm32_hash_dma_aligned_data(req))
+ rctx->flags &= ~HASH_FLAGS_CPU;
+
+ return stm32_hash_finup(req);
+}
+
+static int hash_swap_reg(struct stm32_hash_request_ctx *rctx)
+{
+ switch ((rctx->flags & HASH_FLAGS_ALGO_MASK) >>
+ HASH_FLAGS_ALGO_SHIFT) {
+ case HASH_MD5:
+ case HASH_SHA1:
+ case HASH_SHA224:
+ case HASH_SHA256:
+ if (rctx->flags & HASH_FLAGS_HMAC)
+ return HASH_CSR_NB_SHA256_HMAC;
+ else
+ return HASH_CSR_NB_SHA256;
+ break;
+
+ case HASH_SHA384:
+ case HASH_SHA512:
+ if (rctx->flags & HASH_FLAGS_HMAC)
+ return HASH_CSR_NB_SHA512_HMAC;
+ else
+ return HASH_CSR_NB_SHA512;
+ break;
+
+ case HASH_SHA3_224:
+ case HASH_SHA3_256:
+ case HASH_SHA3_384:
+ case HASH_SHA3_512:
+ if (rctx->flags & HASH_FLAGS_HMAC)
+ return HASH_CSR_NB_SHA3_HMAC;
+ else
+ return HASH_CSR_NB_SHA3;
+ break;
+
+ default:
+ return -EINVAL;
+ }
}
static int stm32_hash_export(struct ahash_request *req, void *out)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
+ struct stm32_hash_dev *hdev = rctx->hdev;
u32 *preg;
unsigned int i;
+ int swap_reg;
pm_runtime_get_sync(hdev->dev);
while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY))
cpu_relax();
- rctx->hw_context = kmalloc_array(3 + HASH_CSR_REGISTER_NUMBER,
- sizeof(u32),
- GFP_KERNEL);
+ swap_reg = hash_swap_reg(rctx);
+ if (swap_reg < 0)
+ return swap_reg;
+
+ rctx->hw_context = kmalloc_array(3 + swap_reg, sizeof(u32), GFP_KERNEL);
preg = rctx->hw_context;
*preg++ = stm32_hash_read(hdev, HASH_IMR);
*preg++ = stm32_hash_read(hdev, HASH_STR);
*preg++ = stm32_hash_read(hdev, HASH_CR);
- for (i = 0; i < HASH_CSR_REGISTER_NUMBER; i++)
+ for (i = 0; i < swap_reg; i++)
*preg++ = stm32_hash_read(hdev, HASH_CSR(i));
pm_runtime_mark_last_busy(hdev->dev);
@@ -990,14 +1045,14 @@ static int stm32_hash_export(struct ahash_request *req, void *out)
static int stm32_hash_import(struct ahash_request *req, const void *in)
{
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req);
- struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
- struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
+ struct stm32_hash_dev *hdev;
const u32 *preg = in;
u32 reg;
unsigned int i;
+ int swap_reg;
memcpy(rctx, in, sizeof(*rctx));
-
+ hdev = rctx->hdev;
preg = rctx->hw_context;
pm_runtime_get_sync(hdev->dev);
@@ -1008,7 +1063,11 @@ static int stm32_hash_import(struct ahash_request *req, const void *in)
reg = *preg++ | HASH_CR_INIT;
stm32_hash_write(hdev, HASH_CR, reg);
- for (i = 0; i < HASH_CSR_REGISTER_NUMBER; i++)
+ swap_reg = hash_swap_reg(rctx);
+ if (swap_reg < 0)
+ return swap_reg;
+
+ for (i = 0; i < swap_reg; i++)
stm32_hash_write(hdev, HASH_CSR(i), *preg++);
pm_runtime_mark_last_busy(hdev->dev);
@@ -1034,8 +1093,7 @@ static int stm32_hash_setkey(struct crypto_ahash *tfm,
return 0;
}
-static int stm32_hash_cra_init_algs(struct crypto_tfm *tfm,
- const char *algs_hmac_name)
+static int stm32_hash_cra_init_algs(struct crypto_tfm *tfm, u32 algs_flags)
{
struct stm32_hash_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -1044,8 +1102,8 @@ static int stm32_hash_cra_init_algs(struct crypto_tfm *tfm,
ctx->keylen = 0;
- if (algs_hmac_name)
- ctx->flags |= HASH_FLAGS_HMAC;
+ if (algs_flags)
+ ctx->flags |= algs_flags;
ctx->enginectx.op.do_one_request = stm32_hash_one_request;
ctx->enginectx.op.prepare_request = stm32_hash_prepare_req;
@@ -1055,27 +1113,23 @@ static int stm32_hash_cra_init_algs(struct crypto_tfm *tfm,
static int stm32_hash_cra_init(struct crypto_tfm *tfm)
{
- return stm32_hash_cra_init_algs(tfm, NULL);
+ return stm32_hash_cra_init_algs(tfm, 0);
}
-static int stm32_hash_cra_md5_init(struct crypto_tfm *tfm)
+static int stm32_hash_cra_hmac_init(struct crypto_tfm *tfm)
{
- return stm32_hash_cra_init_algs(tfm, "md5");
+ return stm32_hash_cra_init_algs(tfm, HASH_FLAGS_HMAC);
}
-static int stm32_hash_cra_sha1_init(struct crypto_tfm *tfm)
+static int stm32_hash_cra_sha3_init(struct crypto_tfm *tfm)
{
- return stm32_hash_cra_init_algs(tfm, "sha1");
+ return stm32_hash_cra_init_algs(tfm, HASH_FLAGS_SHA3_MODE);
}
-static int stm32_hash_cra_sha224_init(struct crypto_tfm *tfm)
+static int stm32_hash_cra_sha3_hmac_init(struct crypto_tfm *tfm)
{
- return stm32_hash_cra_init_algs(tfm, "sha224");
-}
-
-static int stm32_hash_cra_sha256_init(struct crypto_tfm *tfm)
-{
- return stm32_hash_cra_init_algs(tfm, "sha256");
+ return stm32_hash_cra_init_algs(tfm, HASH_FLAGS_SHA3_MODE |
+ HASH_FLAGS_HMAC);
}
static irqreturn_t stm32_hash_irq_thread(int irq, void *dev_id)
@@ -1110,8 +1164,6 @@ static irqreturn_t stm32_hash_irq_handler(int irq, void *dev_id)
reg = stm32_hash_read(hdev, HASH_SR);
if (reg & HASH_SR_OUTPUT_READY) {
- reg &= ~HASH_SR_OUTPUT_READY;
- stm32_hash_write(hdev, HASH_SR, reg);
hdev->flags |= HASH_FLAGS_OUTPUT_READY;
/* Disable IT*/
stm32_hash_write(hdev, HASH_IMR, 0);
@@ -1121,7 +1173,7 @@ static irqreturn_t stm32_hash_irq_handler(int irq, void *dev_id)
return IRQ_NONE;
}
-static struct ahash_alg algs_md5_sha1[] = {
+static struct ahash_alg algs_md5[] = {
{
.init = stm32_hash_init,
.update = stm32_hash_update,
@@ -1132,7 +1184,8 @@ static struct ahash_alg algs_md5_sha1[] = {
.import = stm32_hash_import,
.halg = {
.digestsize = MD5_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "md5",
.cra_driver_name = "stm32-md5",
@@ -1158,7 +1211,8 @@ static struct ahash_alg algs_md5_sha1[] = {
.setkey = stm32_hash_setkey,
.halg = {
.digestsize = MD5_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "hmac(md5)",
.cra_driver_name = "stm32-hmac-md5",
@@ -1168,11 +1222,14 @@ static struct ahash_alg algs_md5_sha1[] = {
.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct stm32_hash_ctx),
.cra_alignmask = 3,
- .cra_init = stm32_hash_cra_md5_init,
+ .cra_init = stm32_hash_cra_hmac_init,
.cra_module = THIS_MODULE,
}
}
- },
+ }
+};
+
+static struct ahash_alg algs_sha1[] = {
{
.init = stm32_hash_init,
.update = stm32_hash_update,
@@ -1183,7 +1240,8 @@ static struct ahash_alg algs_md5_sha1[] = {
.import = stm32_hash_import,
.halg = {
.digestsize = SHA1_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "sha1",
.cra_driver_name = "stm32-sha1",
@@ -1209,7 +1267,8 @@ static struct ahash_alg algs_md5_sha1[] = {
.setkey = stm32_hash_setkey,
.halg = {
.digestsize = SHA1_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "hmac(sha1)",
.cra_driver_name = "stm32-hmac-sha1",
@@ -1219,7 +1278,7 @@ static struct ahash_alg algs_md5_sha1[] = {
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct stm32_hash_ctx),
.cra_alignmask = 3,
- .cra_init = stm32_hash_cra_sha1_init,
+ .cra_init = stm32_hash_cra_hmac_init,
.cra_module = THIS_MODULE,
}
}
@@ -1237,7 +1296,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.import = stm32_hash_import,
.halg = {
.digestsize = SHA224_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "sha224",
.cra_driver_name = "stm32-sha224",
@@ -1263,7 +1323,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.import = stm32_hash_import,
.halg = {
.digestsize = SHA224_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "hmac(sha224)",
.cra_driver_name = "stm32-hmac-sha224",
@@ -1273,7 +1334,7 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct stm32_hash_ctx),
.cra_alignmask = 3,
- .cra_init = stm32_hash_cra_sha224_init,
+ .cra_init = stm32_hash_cra_hmac_init,
.cra_module = THIS_MODULE,
}
}
@@ -1288,7 +1349,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.import = stm32_hash_import,
.halg = {
.digestsize = SHA256_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "sha256",
.cra_driver_name = "stm32-sha256",
@@ -1314,7 +1376,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.setkey = stm32_hash_setkey,
.halg = {
.digestsize = SHA256_DIGEST_SIZE,
- .statesize = sizeof(struct stm32_hash_request_ctx),
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
.base = {
.cra_name = "hmac(sha256)",
.cra_driver_name = "stm32-hmac-sha256",
@@ -1324,13 +1387,339 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct stm32_hash_ctx),
.cra_alignmask = 3,
- .cra_init = stm32_hash_cra_sha256_init,
+ .cra_init = stm32_hash_cra_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+};
+
+
+static struct ahash_alg algs_sha384_sha512[] = {
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha384",
+ .cra_driver_name = "stm32-sha384",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .setkey = stm32_hash_setkey,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha384)",
+ .cra_driver_name = "stm32-hmac-sha384",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha512",
+ .cra_driver_name = "stm32-sha512",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .setkey = stm32_hash_setkey,
+ .halg = {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha512)",
+ .cra_driver_name = "stm32-hmac-sha512",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_hmac_init,
.cra_module = THIS_MODULE,
}
}
},
};
+static struct ahash_alg algs_sha3[] = {
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA3_224_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha3-224",
+ .cra_driver_name = "stm32-sha3-224",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .setkey = stm32_hash_setkey,
+ .halg = {
+ .digestsize = SHA3_224_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha3-224)",
+ .cra_driver_name = "stm32-hmac-sha3-224",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA3_256_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha3-256",
+ .cra_driver_name = "stm32-sha3-256",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .setkey = stm32_hash_setkey,
+ .halg = {
+ .digestsize = SHA3_256_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha3-256)",
+ .cra_driver_name = "stm32-hmac-sha3-256",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA3_384_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha3-384",
+ .cra_driver_name = "stm32-sha3-384",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .setkey = stm32_hash_setkey,
+ .halg = {
+ .digestsize = SHA3_384_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha3-384)",
+ .cra_driver_name = "stm32-hmac-sha3-384",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .halg = {
+ .digestsize = SHA3_512_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "sha3-512",
+ .cra_driver_name = "stm32-sha3-512",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ },
+ {
+ .init = stm32_hash_init,
+ .update = stm32_hash_update,
+ .final = stm32_hash_final,
+ .finup = stm32_hash_finup,
+ .digest = stm32_hash_digest,
+ .export = stm32_hash_export,
+ .import = stm32_hash_import,
+ .setkey = stm32_hash_setkey,
+ .halg = {
+ .digestsize = SHA3_512_DIGEST_SIZE,
+ .statesize = sizeof(struct stm32_hash_request_ctx) +
+ HASH_MAX_BUFLEN,
+ .base = {
+ .cra_name = "hmac(sha3-512)",
+ .cra_driver_name = "stm32-hmac-sha3-512",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = SHA3_512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct stm32_hash_ctx),
+ .cra_alignmask = 3,
+ .cra_init = stm32_hash_cra_sha3_hmac_init,
+ .cra_module = THIS_MODULE,
+ }
+ }
+ }
+};
+
+
static int stm32_hash_register_algs(struct stm32_hash_dev *hdev)
{
unsigned int i, j;
@@ -1372,20 +1761,29 @@ static int stm32_hash_unregister_algs(struct stm32_hash_dev *hdev)
static struct stm32_hash_algs_info stm32_hash_algs_info_stm32f4[] = {
{
- .algs_list = algs_md5_sha1,
- .size = ARRAY_SIZE(algs_md5_sha1),
+ .algs_list = algs_md5,
+ .size = ARRAY_SIZE(algs_md5),
+ },
+ {
+ .algs_list = algs_sha1,
+ .size = ARRAY_SIZE(algs_sha1),
},
};
static const struct stm32_hash_pdata stm32_hash_pdata_stm32f4 = {
+ .alg_shift = 7,
.algs_info = stm32_hash_algs_info_stm32f4,
.algs_info_size = ARRAY_SIZE(stm32_hash_algs_info_stm32f4),
};
static struct stm32_hash_algs_info stm32_hash_algs_info_stm32f7[] = {
{
- .algs_list = algs_md5_sha1,
- .size = ARRAY_SIZE(algs_md5_sha1),
+ .algs_list = algs_md5,
+ .size = ARRAY_SIZE(algs_md5),
+ },
+ {
+ .algs_list = algs_sha1,
+ .size = ARRAY_SIZE(algs_sha1),
},
{
.algs_list = algs_sha224_sha256,
@@ -1394,19 +1792,41 @@ static struct stm32_hash_algs_info stm32_hash_algs_info_stm32f7[] = {
};
static const struct stm32_hash_pdata stm32_hash_pdata_stm32f7 = {
+ .alg_shift = 7,
.algs_info = stm32_hash_algs_info_stm32f7,
.algs_info_size = ARRAY_SIZE(stm32_hash_algs_info_stm32f7),
};
-static const struct of_device_id stm32_hash_of_match[] = {
+
+static struct stm32_hash_algs_info stm32_hash_algs_info_stm32mp13[] = {
+ {
+ .algs_list = algs_sha1,
+ .size = ARRAY_SIZE(algs_sha1),
+ },
+ {
+ .algs_list = algs_sha224_sha256,
+ .size = ARRAY_SIZE(algs_sha224_sha256),
+ },
{
- .compatible = "st,stm32f456-hash",
- .data = &stm32_hash_pdata_stm32f4,
+ .algs_list = algs_sha384_sha512,
+ .size = ARRAY_SIZE(algs_sha384_sha512),
},
{
- .compatible = "st,stm32f756-hash",
- .data = &stm32_hash_pdata_stm32f7,
+ .algs_list = algs_sha3,
+ .size = ARRAY_SIZE(algs_sha3),
},
+};
+
+static const struct stm32_hash_pdata stm32_hash_pdata_stm32mp13 = {
+ .alg_shift = 17,
+ .algs_info = stm32_hash_algs_info_stm32mp13,
+ .algs_info_size = ARRAY_SIZE(stm32_hash_algs_info_stm32mp13),
+};
+
+static const struct of_device_id stm32_hash_of_match[] = {
+ { .compatible = "st,stm32f456-hash", .data = &stm32_hash_pdata_stm32f4 },
+ { .compatible = "st,stm32f756-hash", .data = &stm32_hash_pdata_stm32f7 },
+ { .compatible = "st,stm32mp13-hash", .data = &stm32_hash_pdata_stm32mp13 },
{},
};
@@ -1421,12 +1841,6 @@ static int stm32_hash_get_of_match(struct stm32_hash_dev *hdev,
return -EINVAL;
}
- if (of_property_read_u32(dev->of_node, "dma-maxburst",
- &hdev->dma_maxburst)) {
- dev_info(dev, "dma-maxburst not specified, using 0\n");
- hdev->dma_maxburst = 0;
- }
-
return 0;
}
@@ -1494,6 +1908,8 @@ static int stm32_hash_probe(struct platform_device *pdev)
reset_control_deassert(hdev->rst);
}
+ crypto_init_queue(&hdev->queue, HASH_QUEUE_LENGTH);
+
hdev->dev = dev;
platform_set_drvdata(pdev, hdev);
@@ -1502,7 +1918,7 @@ static int stm32_hash_probe(struct platform_device *pdev)
switch (ret) {
case 0:
break;
- case -ENOENT:
+ case -ENODEV:
dev_dbg(dev, "DMA mode not available\n");
break;
default:
@@ -1524,7 +1940,8 @@ static int stm32_hash_probe(struct platform_device *pdev)
if (ret)
goto err_engine_start;
- hdev->dma_mode = stm32_hash_read(hdev, HASH_HWCFGR);
+ hdev->dma_mode = stm32_hash_read(hdev, HASH_HWCFGR) &
+ HASH_HWCFG_DMA_MASK;
/* Register algos */
ret = stm32_hash_register_algs(hdev);
@@ -1633,6 +2050,6 @@ static struct platform_driver stm32_hash_driver = {
module_platform_driver(stm32_hash_driver);
-MODULE_DESCRIPTION("STM32 SHA1/224/256 & MD5 (HMAC) hw accelerator driver");
+MODULE_DESCRIPTION("STM32 SHA1/SHA2/SHA3 & MD5 (HMAC) hw accelerator driver");
MODULE_AUTHOR("Lionel Debieve <lionel.debieve@st.com>");
MODULE_LICENSE("GPL v2");
--
2.25.1