Skip to content

Commit 8f8b223

Browse files
Yunshao-Chiangkartben
authored andcommitted
drivers: crypto: add it51xxx sha256 driver
Implement a crypto sha256 driver for it51xxx series. Signed-off-by: Yunshao Chiang <[email protected]>
1 parent cec116c commit 8f8b223

File tree

9 files changed

+349
-0
lines changed

9 files changed

+349
-0
lines changed

boards/ite/it515xx_evb/it515xx_evb.dts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,7 @@
149149
pinctrl-0 = <&tach0a_gpd6_default>;
150150
pinctrl-names = "default";
151151
};
152+
153+
&sha256 {
154+
status = "okay";
155+
};

drivers/crypto/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_NRF_ECB crypto_nrf_ecb.c)
1010
zephyr_library_sources_ifdef(CONFIG_CRYPTO_INTEL_SHA crypto_intel_sha.c)
1111
zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c)
1212
zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c)
13+
zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT51XXX_SHA crypto_it51xxx_sha.c)
1314
zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c)
1415
zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA_V2 crypto_it8xxx2_sha_v2.c)
1516
zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c)

drivers/crypto/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ source "drivers/crypto/Kconfig.nrf_ecb"
8080
source "drivers/crypto/Kconfig.intel"
8181
source "drivers/crypto/Kconfig.npcx"
8282
source "drivers/crypto/Kconfig.xec"
83+
source "drivers/crypto/Kconfig.it51xxx"
8384
source "drivers/crypto/Kconfig.it8xxx2"
8485
source "drivers/crypto/Kconfig.mcux_dcp"
8586
source "drivers/crypto/Kconfig.si32"

drivers/crypto/Kconfig.it51xxx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 ITE Corporation.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config CRYPTO_IT51XXX_SHA
5+
bool "ITE IT51XXX SHA driver"
6+
default y
7+
depends on DT_HAS_ITE_IT51XXX_SHA_ENABLED
8+
select SOC_IT51XXX_SHA256_HW_ACCELERATE
9+
help
10+
The IT51XXX hardware supports SHA-256 calculation, which is faster than
11+
the firmware implementation.

drivers/crypto/crypto_it51xxx_sha.c

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
/*
2+
* Copyright (c) 2025 ITE Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT ite_it51xxx_sha
8+
9+
#include <errno.h>
10+
#include <it51xxx/chip_chipregs.h>
11+
#include <zephyr/crypto/crypto.h>
12+
#include <zephyr/kernel.h>
13+
#include <zephyr/sys/byteorder.h>
14+
15+
#include <zephyr/logging/log.h>
16+
LOG_MODULE_REGISTER(crypto_it51xxx_sha, CONFIG_CRYPTO_LOG_LEVEL);
17+
18+
#define IT51XXX_SHA_REGS_BASE DT_REG_ADDR(DT_NODELABEL(sha256))
19+
20+
/* 0x00: SHA Control Register (SHACR) */
21+
#define IT51XXX_SHACR (IT51XXX_SHA_REGS_BASE + 0x00)
22+
#define IT51XXX_SHAWB BIT(2)
23+
#define IT51XXX_SHAINI BIT(1)
24+
#define IT51XXX_SHAEXE BIT(0)
25+
/* 0x01: SHA Status Register (SHASR)*/
26+
#define IT51XXX_SHASR (IT51XXX_SHA_REGS_BASE + 0x01)
27+
#define IT51XXX_SHAIE BIT(3)
28+
#define IT51XXX_SHAIS BIT(2)
29+
#define IT51XXX_SHABUSY BIT(0)
30+
/* 0x02: SHA Execution Counter Register (SHAECR) */
31+
#define IT51XXX_SHAECR (IT51XXX_SHA_REGS_BASE + 0x02)
32+
#define IT51XXX_SHAEXEC_64_BYTE 0x00
33+
#define IT51XXX_SHAEXEC_1K_BYTE 0x0F
34+
/* 0x03: SHA DLM Base Address 0 Register (SHADBA0R) */
35+
#define IT51XXX_SHADBA0R (IT51XXX_SHA_REGS_BASE + 0x03)
36+
/* 0x04: SHA DLM Base Address 1 Register (SHADBA1R) */
37+
#define IT51XXX_SHADBA1R (IT51XXX_SHA_REGS_BASE + 0x04)
38+
/* 0x05: SHA Setting Register (SHASETR) */
39+
#define IT51XXX_SHASETR (IT51XXX_SHA_REGS_BASE + 0x05)
40+
#define IT51XXX_SHA256 0x00
41+
/* 0x06: SHA DLM Base Address 2 Register (SHADBA2R) */
42+
#define IT51XXX_SHADBA2R (IT51XXX_SHA_REGS_BASE + 0x06)
43+
44+
#define SHA_SHA256_HASH_LEN 32
45+
#define SHA_SHA256_BLOCK_LEN 64
46+
#define SHA_SHA256_HASH_LEN_WORDS (SHA_SHA256_HASH_LEN / sizeof(uint32_t))
47+
#define SHA_SHA256_BLOCK_LEN_WORDS (SHA_SHA256_BLOCK_LEN / sizeof(uint32_t))
48+
49+
/*
50+
* If the input message is more than 1K bytes, taking 10K bytes for example,
51+
* it should run 10 times SHA hardwired loading and execution, and process 1K bytes each time.
52+
*/
53+
#define SHA_HW_MAX_INPUT_LEN 1024
54+
#define SHA_HW_MAX_INPUT_LEN_WORDS (SHA_HW_MAX_INPUT_LEN / sizeof(uint32_t))
55+
56+
/*
57+
* This struct is used by the hardware and must be stored in RAM first 4k-byte
58+
* and aligned on a 256-byte boundary.
59+
*/
60+
struct chip_sha256_ctx {
61+
union {
62+
/* SHA data buffer */
63+
uint32_t w_sha[SHA_HW_MAX_INPUT_LEN_WORDS];
64+
uint8_t w_input[SHA_HW_MAX_INPUT_LEN];
65+
};
66+
/* H[0] ~ H[7] */
67+
uint32_t h[SHA_SHA256_HASH_LEN_WORDS];
68+
uint32_t sha_init;
69+
uint32_t w_input_index;
70+
uint32_t total_len;
71+
} __aligned(256);
72+
73+
Z_GENERIC_SECTION(.__sha256_ram_block) struct chip_sha256_ctx chip_ctx;
74+
75+
static void it51xxx_sha256_init(bool init_k)
76+
{
77+
chip_ctx.sha_init = init_k;
78+
chip_ctx.total_len = 0;
79+
chip_ctx.w_input_index = 0;
80+
81+
/* Set DLM address for input data */
82+
sys_write8(((uint32_t)&chip_ctx) & 0xC0, IT51XXX_SHADBA0R);
83+
sys_write8(((uint32_t)&chip_ctx) >> 8, IT51XXX_SHADBA1R);
84+
sys_write8(((uint32_t)&chip_ctx) >> 16, IT51XXX_SHADBA2R);
85+
}
86+
87+
static void it51xxx_sha256_module_calculation(void)
88+
{
89+
uint32_t key;
90+
91+
/*
92+
* Global interrupt is disabled because the CPU cannot access memory
93+
* via the DLM (Data Local Memory) bus while HW module is computing
94+
* hash.
95+
*/
96+
key = irq_lock();
97+
98+
if (chip_ctx.sha_init) {
99+
chip_ctx.sha_init = 0;
100+
sys_write8(IT51XXX_SHAINI | IT51XXX_SHAEXE, IT51XXX_SHACR);
101+
} else {
102+
sys_write8(IT51XXX_SHAEXE, IT51XXX_SHACR);
103+
}
104+
105+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
106+
};
107+
sys_write8(IT51XXX_SHAIS, IT51XXX_SHASR);
108+
109+
irq_unlock(key);
110+
111+
chip_ctx.w_input_index = 0;
112+
}
113+
114+
static int it51xxx_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish)
115+
{
116+
uint32_t i;
117+
uint32_t in_buf_idx = 0;
118+
uint32_t key;
119+
uint32_t rem_len = pkt->in_len;
120+
121+
/* data length >= 1KiB */
122+
while (rem_len >= SHA_HW_MAX_INPUT_LEN) {
123+
rem_len = rem_len - SHA_HW_MAX_INPUT_LEN;
124+
125+
for (i = 0; i < SHA_HW_MAX_INPUT_LEN; i++) {
126+
chip_ctx.w_input[chip_ctx.w_input_index++] = pkt->in_buf[in_buf_idx++];
127+
}
128+
129+
/* HW automatically load 1KB data from DLM */
130+
sys_write8(IT51XXX_SHAEXEC_1K_BYTE, IT51XXX_SHAECR);
131+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
132+
};
133+
134+
it51xxx_sha256_module_calculation();
135+
}
136+
137+
/* 0 <= data length < 1KiB */
138+
while (rem_len) {
139+
rem_len--;
140+
chip_ctx.w_input[chip_ctx.w_input_index++] = pkt->in_buf[in_buf_idx++];
141+
142+
/*
143+
* If fill full 64byte then execute HW calculation.
144+
* If not, will execute in later finish block.
145+
*/
146+
if (chip_ctx.w_input_index >= SHA_SHA256_BLOCK_LEN) {
147+
/* HW automatically load 64 bytes data from DLM */
148+
sys_write8(IT51XXX_SHAEXEC_64_BYTE, IT51XXX_SHAECR);
149+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
150+
};
151+
152+
it51xxx_sha256_module_calculation();
153+
}
154+
}
155+
156+
chip_ctx.total_len += pkt->in_len;
157+
158+
if (finish) {
159+
uint32_t *out_buf_ptr = (uint32_t *)pkt->out_buf;
160+
161+
/* Pre-processing (Padding) */
162+
chip_ctx.w_input[chip_ctx.w_input_index++] = 0x80;
163+
memset(&chip_ctx.w_input[chip_ctx.w_input_index], 0,
164+
SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index);
165+
166+
/*
167+
* Handles the boundary case of rest data:
168+
* Because the last eight bytes are bit length field of SHA256 rule.
169+
* If the data index >= 56, it needs to trigger HW to calculate,
170+
* then fill 0 data and the last eight bytes bit length, and calculate
171+
* again.
172+
*/
173+
if (chip_ctx.w_input_index >= 56) {
174+
/* HW automatically load 64Bytes data from DLM */
175+
sys_write8(IT51XXX_SHAEXEC_64_BYTE, IT51XXX_SHAECR);
176+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
177+
};
178+
179+
it51xxx_sha256_module_calculation();
180+
181+
memset(&chip_ctx.w_input[chip_ctx.w_input_index], 0,
182+
SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index);
183+
}
184+
185+
/*
186+
* Since input data (big-endian) are copied 1byte by 1byte to
187+
* it51xxx memory (little-endian), so the bit length needs to
188+
* be transformed into big-endian format and then write to memory.
189+
*/
190+
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8);
191+
192+
/* HW automatically load 64Bytes data from DLM */
193+
sys_write8(IT51XXX_SHAEXEC_64_BYTE, IT51XXX_SHAECR);
194+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
195+
};
196+
197+
it51xxx_sha256_module_calculation();
198+
199+
/* HW write back the hash result to DLM */
200+
/* Set DLM address for input data */
201+
sys_write8(((uint32_t)&chip_ctx.h) & 0xC0, IT51XXX_SHADBA0R);
202+
sys_write8(((uint32_t)&chip_ctx.h) >> 8, IT51XXX_SHADBA1R);
203+
204+
key = irq_lock();
205+
206+
sys_write8(IT51XXX_SHAWB, IT51XXX_SHACR);
207+
while (sys_read8(IT51XXX_SHASR) & IT51XXX_SHABUSY) {
208+
};
209+
210+
sys_write8(IT51XXX_SHAIS, IT51XXX_SHASR);
211+
212+
irq_unlock(key);
213+
214+
for (i = 0; i < SHA_SHA256_HASH_LEN_WORDS; i++) {
215+
out_buf_ptr[i] = chip_ctx.h[i];
216+
}
217+
218+
it51xxx_sha256_init(true);
219+
}
220+
221+
return 0;
222+
}
223+
224+
static int it51xxx_hash_session_free(const struct device *dev, struct hash_ctx *ctx)
225+
{
226+
it51xxx_sha256_init(true);
227+
228+
return 0;
229+
}
230+
231+
static inline int it51xxx_query_hw_caps(const struct device *dev)
232+
{
233+
return (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS);
234+
}
235+
236+
static int it51xxx_hash_begin_session(const struct device *dev, struct hash_ctx *ctx,
237+
enum hash_algo algo)
238+
{
239+
if (algo != CRYPTO_HASH_ALGO_SHA256) {
240+
LOG_ERR("Unsupported algorithm");
241+
return -EINVAL;
242+
}
243+
244+
if (ctx->flags & ~(it51xxx_query_hw_caps(dev))) {
245+
LOG_ERR("Unsupported flag");
246+
return -EINVAL;
247+
}
248+
249+
it51xxx_sha256_init(true);
250+
ctx->hash_hndlr = it51xxx_hash_handler;
251+
252+
return 0;
253+
}
254+
255+
static int it51xxx_sha_init(const struct device *dev)
256+
{
257+
it51xxx_sha256_init(true);
258+
259+
/* Select SHA-2 Family, SHA-256 */
260+
sys_write8(IT51XXX_SHA256, IT51XXX_SHASETR);
261+
262+
/* SHA interrupt disable */
263+
sys_write8(sys_read8(IT51XXX_SHASR) & ~IT51XXX_SHAIE, IT51XXX_SHASR);
264+
265+
return 0;
266+
}
267+
268+
static DEVICE_API(crypto, it51xxx_crypto_api) = {
269+
.hash_begin_session = it51xxx_hash_begin_session,
270+
.hash_free_session = it51xxx_hash_session_free,
271+
.query_hw_caps = it51xxx_query_hw_caps,
272+
};
273+
274+
DEVICE_DT_INST_DEFINE(0, &it51xxx_sha_init, NULL, NULL, NULL, POST_KERNEL,
275+
CONFIG_CRYPTO_INIT_PRIORITY, &it51xxx_crypto_api);
276+
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "support only one sha compatible node");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 ITE Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: ITE IT51XXX Crypto SHA accelerator.
5+
6+
compatible: "ite,it51xxx-sha"
7+
8+
include: base.yaml
9+
10+
properties:
11+
reg:
12+
required: true

dts/riscv/ite/it51xxx.dtsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,5 +1315,11 @@
13151315
io-channel = <3>;
13161316
extern-enable = <0xf016de 1>;
13171317
};
1318+
1319+
sha256: crypto@f03b00 {
1320+
compatible = "ite,it51xxx-sha";
1321+
reg = <0x00f03b00 0x6>;
1322+
status = "disabled";
1323+
};
13181324
};
13191325
};

soc/ite/ec/it51xxx/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ config SOC_IT51XXX_USE_ILM
4040
predictable than executing from Flash directly, and some code (such as code
4141
that writes to the internal Flash) must execute out of RAM.
4242

43+
config SOC_IT51XXX_SHA256_HW_ACCELERATE
44+
bool "HW SHA256 calculation"
45+
help
46+
IT51XXX HW support sha256 calculation, and its calculation is faster than FW.
47+
48+
config SOC_IT515XX_SHA256_DLM_OFFSET
49+
hex
50+
default 0x03E000
51+
depends on SOC_IT51XXX_SHA256_HW_ACCELERATE
52+
help
53+
Due to the hardware requirements of the IT515XX, the SHA-256 data must be
54+
placed within the specific address range (0x83E000 to 0x83EFFF by default).
55+
4356
config ILM_MAX_SIZE
4457
int "ILM Size in kB"
4558
default 4

0 commit comments

Comments
 (0)