drivers/crypto/crypto_it8xxx2_sha_v2.c: implement sha v2 for it82xx2 series

Implement a new version crypto_it8xxx2_sha_v2 driver for it82xx2 series.

Signed-off-by: Ruibin Chang <Ruibin.Chang@ite.com.tw>
This commit is contained in:
Ruibin Chang 2024-03-27 16:57:51 +08:00 committed by Carles Cufí
parent a3f0ae9b0f
commit 1d74cb74d9
8 changed files with 393 additions and 8 deletions

View file

@ -11,5 +11,6 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_INTEL_SHA crypto_intel_sha.c)
zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c)
zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c)
zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c)
zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA_V2 crypto_it8xxx2_sha_v2.c)
zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c)
zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS)

View file

@ -11,3 +11,14 @@ config CRYPTO_IT8XXX2_SHA
This driver supports SHA256 hardware accelerator of the it8xxx2 series. This driver supports SHA256 hardware accelerator of the it8xxx2 series.
It requires 256 + 256 bytes in the RAM's first 4k-bytes to calculate It requires 256 + 256 bytes in the RAM's first 4k-bytes to calculate
SHA256 hash. SHA256 hash.
config CRYPTO_IT8XXX2_SHA_V2
bool "ITE IT8XXX2 SHA V2 driver"
default y
depends on DT_HAS_ITE_IT8XXX2_SHA_V2_ENABLED
select SOC_IT8XXX2_SHA256_HW_ACCELERATE
help
Enable ITE IT8XXX2 SHA V2 driver.
This driver supports SHA256 hardware accelerator of the it82xx2 series.
It requires 1024 + 256 bytes in the RAM's first 4k-bytes to calculate
SHA256 hash.

View file

@ -0,0 +1,350 @@
/*
* Copyright (c) 2024 ITE Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT ite_it8xxx2_sha_v2
#include <zephyr/kernel.h>
#include <zephyr/crypto/crypto.h>
#include <zephyr/sys/byteorder.h>
#include <chip_chipregs.h>
#include <errno.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sha_it8xxx2, CONFIG_CRYPTO_LOG_LEVEL);
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
"support only one sha compatible node");
#define IT8XXX2_SHA_REGS_BASE DT_REG_ADDR(DT_NODELABEL(sha0))
/* 0x00: SHA Control Register */
#define IT8XXX2_REG_SHACR (0x00)
#define IT8XXX2_SEL1SHA1 BIT(6)
#define IT8XXX2_SELSHA2ALL (BIT(5) | BIT(4))
#define IT8XXX2_SHAWB BIT(2)
#define IT8XXX2_SHAINI BIT(1)
#define IT8XXX2_SHAEXE BIT(0)
/* 0x01: SHA Status Register */
#define IT8XXX2_REG_SHASR (0x01)
#define IT8XXX2_SHAIE BIT(3)
#define IT8XXX2_SHAIS BIT(2)
#define IT8XXX2_SHABUSY BIT(0)
/* 0x02: SHA Execution Counter Register */
#define IT8XXX2_REG_SHAECR (0x02)
#define IT8XXX2_SHAEXEC_64Byte 0x0
#define IT8XXX2_SHAEXEC_512Byte 0x7
#define IT8XXX2_SHAEXEC_1KByte 0xf
/* 0x03: SHA DLM Base Address 0 Register */
#define IT8XXX2_REG_SHADBA0R (0x03)
/* 0x04: SHA DLM Base Address 1 Register */
#define IT8XXX2_REG_SHADBA1R (0x04)
#define SHA_SHA256_HASH_LEN 32
#define SHA_SHA256_BLOCK_LEN 64
#define SHA_SHA256_SRAM_BUF 1024
#define SHA_SHA256_HASH_LEN_WORDS (SHA_SHA256_HASH_LEN / sizeof(uint32_t))
#define SHA_SHA256_BLOCK_LEN_WORDS (SHA_SHA256_BLOCK_LEN / sizeof(uint32_t))
#define SHA_SHA256_SRAM_BUF_WORDS (SHA_SHA256_SRAM_BUF / sizeof(uint32_t))
#define SHA_SHA256_CALCULATE_TIMEOUT_US 150
#define SHA_SHA256_WRITE_BACK_TIMEOUT_US 45
#define SHA_SHA256_WAIT_NEXT_CLOCK_TIME_US 15
/*
* This struct is used by the hardware and must be stored in RAM first 4k-byte
* and aligned on a 256-byte boundary.
*/
struct chip_sha256_ctx {
union {
/* SHA data buffer */
uint32_t w_sha[SHA_SHA256_SRAM_BUF_WORDS];
uint8_t w_input[SHA_SHA256_SRAM_BUF];
};
/* H[0] ~ H[7] */
uint32_t h[SHA_SHA256_HASH_LEN_WORDS];
uint32_t sha_init;
uint32_t w_input_index;
uint32_t total_len;
} __aligned(256);
Z_GENERIC_SECTION(.__sha256_ram_block) struct chip_sha256_ctx chip_ctx;
static void it8xxx2_sha256_init(bool init_k)
{
chip_ctx.sha_init = init_k;
chip_ctx.w_input_index = 0;
chip_ctx.total_len = 0;
/* Set DLM address for input data */
sys_write8(((uint32_t)&chip_ctx) & 0xc0,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHADBA0R);
sys_write8(((uint32_t)&chip_ctx) >> 8,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHADBA1R);
}
static int it8xxx2_sha256_module_calculation(void)
{
struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
uint32_t key, count;
uint8_t sha_ctrl;
bool timeout = true;
sha_ctrl = sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHACR);
if (chip_ctx.sha_init) {
sha_ctrl |= (IT8XXX2_SHAINI | IT8XXX2_SHAEXE);
chip_ctx.sha_init = 0;
} else {
sha_ctrl |= IT8XXX2_SHAEXE;
}
/*
* Global interrupt is disabled because the CPU cannot access memory
* via the DLM (Data Local Memory) bus while HW module is computing
* hash.
*/
key = irq_lock();
/* Crypto use SRAM */
gctrl_regs->GCTRL_PMER3 |= IT8XXX2_GCTRL_SRAM_CRYPTO_USED;
sys_write8(sha_ctrl, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHACR);
/*
* HW 64 bytes data calculation ~= 4us;
* HW 1024 bytes data calculation ~= 66us.
*/
for (count = 0; count <= (SHA_SHA256_CALCULATE_TIMEOUT_US /
SHA_SHA256_WAIT_NEXT_CLOCK_TIME_US); count++) {
/* Delay 15us */
gctrl_regs->GCTRL_WNCKR = IT8XXX2_GCTRL_WN65K;
if ((sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHASR) & IT8XXX2_SHAIS)) {
timeout = 0;
break;
}
}
sys_write8(IT8XXX2_SHAIS, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHASR);
/* CPU use SRAM */
gctrl_regs->GCTRL_PMER3 &= ~IT8XXX2_GCTRL_SRAM_CRYPTO_USED;
gctrl_regs->GCTRL_PMER3;
irq_unlock(key);
if (timeout) {
LOG_ERR("HW execute sha256 calculation timeout");
it8xxx2_sha256_init(true);
return -ETIMEDOUT;
}
chip_ctx.w_input_index = 0;
return 0;
}
static int it8xxx2_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt,
bool finish)
{
struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
uint32_t rem_len = pkt->in_len;
uint32_t in_buf_idx = 0;
uint32_t i, key, count;
uint8_t sha_ctrl;
bool timeout = true;
int ret;
while (rem_len) {
/* Data length >= 1KB */
if (rem_len >= SHA_SHA256_SRAM_BUF) {
rem_len = rem_len - SHA_SHA256_SRAM_BUF;
for (i = 0; i < SHA_SHA256_SRAM_BUF; i++) {
chip_ctx.w_input[chip_ctx.w_input_index++] =
pkt->in_buf[in_buf_idx++];
}
/* HW automatically load 1KB data from DLM */
sys_write8(IT8XXX2_SHAEXEC_1KByte,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHAECR);
ret = it8xxx2_sha256_module_calculation();
if (ret) {
return ret;
}
} else {
/* 0 <= Data length < 1KB */
while (rem_len) {
rem_len--;
chip_ctx.w_input[chip_ctx.w_input_index++] =
pkt->in_buf[in_buf_idx++];
/*
* If fill full 64byte then execute HW calculation.
* If not, will execute in later finish block.
*/
if (chip_ctx.w_input_index >= SHA_SHA256_BLOCK_LEN) {
/* HW automatically load 64Bytes data from DLM */
sys_write8(IT8XXX2_SHAEXEC_64Byte,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHAECR);
ret = it8xxx2_sha256_module_calculation();
if (ret) {
return ret;
}
}
}
}
}
chip_ctx.total_len += pkt->in_len;
if (finish) {
uint32_t *ob_ptr = (uint32_t *)pkt->out_buf;
/* Pre-processing (Padding) */
memset(&chip_ctx.w_input[chip_ctx.w_input_index],
0, SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index);
chip_ctx.w_input[chip_ctx.w_input_index] = 0x80;
/*
* Handles the boundary case of rest data:
* Because the last eight bytes are bit length field of sha256 rule.
* If the data index >= 56, it needs to trigger HW to calculate,
* then fill 0 data and the last eight bytes bit length, and calculate again.
*/
if (chip_ctx.w_input_index >= 56) {
/* HW automatically load 64Bytes data from DLM */
sys_write8(IT8XXX2_SHAEXEC_64Byte,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHAECR);
ret = it8xxx2_sha256_module_calculation();
if (ret) {
return ret;
}
memset(&chip_ctx.w_input[chip_ctx.w_input_index],
0, SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index);
}
/*
* Since input data (big-endian) are copied 1byte by 1byte to
* it8xxx2 memory (little-endian), so the bit length needs to
* be transformed into big-endian format and then write to memory.
*/
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8);
/* HW automatically load 64Bytes data from DLM */
sys_write8(IT8XXX2_SHAEXEC_64Byte, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHAECR);
ret = it8xxx2_sha256_module_calculation();
if (ret) {
return ret;
}
/* HW write back the hash result to DLM */
/* Set DLM address for input data */
sys_write8(((uint32_t)&chip_ctx.h) & 0xc0,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHADBA0R);
sys_write8(((uint32_t)&chip_ctx.h) >> 8,
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHADBA1R);
key = irq_lock();
/* Crypto use SRAM */
gctrl_regs->GCTRL_PMER3 |= IT8XXX2_GCTRL_SRAM_CRYPTO_USED;
sha_ctrl = sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHACR);
sys_write8(sha_ctrl | IT8XXX2_SHAWB, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHACR);
/* HW write back the hash result to DLM ~= 1us */
for (count = 0; count <= (SHA_SHA256_WRITE_BACK_TIMEOUT_US /
SHA_SHA256_WAIT_NEXT_CLOCK_TIME_US); count++) {
/* Delay 15us */
gctrl_regs->GCTRL_WNCKR = IT8XXX2_GCTRL_WN65K;
if ((sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHASR)
& IT8XXX2_SHAIS)) {
timeout = 0;
break;
}
}
sys_write8(IT8XXX2_SHAIS, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHASR);
/* CPU use SRAM */
gctrl_regs->GCTRL_PMER3 &= ~IT8XXX2_GCTRL_SRAM_CRYPTO_USED;
gctrl_regs->GCTRL_PMER3;
irq_unlock(key);
if (timeout) {
LOG_ERR("HW write back hash timeout");
it8xxx2_sha256_init(true);
return -ETIMEDOUT;
}
for (i = 0; i < SHA_SHA256_HASH_LEN_WORDS; i++) {
ob_ptr[i] = chip_ctx.h[i];
}
it8xxx2_sha256_init(true);
}
return 0;
}
static int it8xxx2_hash_session_free(const struct device *dev,
struct hash_ctx *ctx)
{
it8xxx2_sha256_init(true);
return 0;
}
static inline int it8xxx2_query_hw_caps(const struct device *dev)
{
return (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS);
}
static int it8xxx2_hash_begin_session(const struct device *dev,
struct hash_ctx *ctx, enum hash_algo algo)
{
if (algo != CRYPTO_HASH_ALGO_SHA256) {
LOG_ERR("Unsupported algorithm");
return -EINVAL;
}
if (ctx->flags & ~(it8xxx2_query_hw_caps(dev))) {
LOG_ERR("Unsupported flag");
return -EINVAL;
}
it8xxx2_sha256_init(true);
ctx->hash_hndlr = it8xxx2_hash_handler;
return 0;
}
static int it8xxx2_sha_init(const struct device *dev)
{
struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
/* CPU use SRAM */
gctrl_regs->GCTRL_PMER3 &= ~IT8XXX2_GCTRL_SRAM_CRYPTO_USED;
gctrl_regs->GCTRL_PMER3;
it8xxx2_sha256_init(true);
/* Select SHA-2 Family, SHA-256 */
sys_write8(0, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHACR);
/* SHA interrupt disable */
sys_write8(0, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHASR);
return 0;
}
static struct crypto_driver_api it8xxx2_crypto_api = {
.hash_begin_session = it8xxx2_hash_begin_session,
.hash_free_session = it8xxx2_hash_session_free,
.query_hw_caps = it8xxx2_query_hw_caps,
};
DEVICE_DT_INST_DEFINE(0, &it8xxx2_sha_init, NULL, NULL, NULL, POST_KERNEL,
CONFIG_CRYPTO_INIT_PRIORITY, &it8xxx2_crypto_api);

View file

@ -0,0 +1,12 @@
# Copyright (c) 2024, ITE Corporation
# SPDX-License-Identifier: Apache-2.0
description: ITE IT8XXX2 Crypto SHA accelerator V2.
compatible: "ite,it8xxx2-sha-v2"
include: base.yaml
properties:
reg:
required: true

View file

@ -998,5 +998,11 @@
num-in-endpoints = <10>; num-in-endpoints = <10>;
num-out-endpoints = <5>; num-out-endpoints = <5>;
}; };
sha0: crypto@f03c00 {
compatible = "ite,it8xxx2-sha-v2";
reg = <0x00f03c00 0x5>;
status = "disabled";
};
}; };
}; };

View file

@ -1633,6 +1633,8 @@ struct gctrl_it8xxx2_regs {
/* 0x06: Reset Status */ /* 0x06: Reset Status */
#define IT8XXX2_GCTRL_LRS (BIT(1) | BIT(0)) #define IT8XXX2_GCTRL_LRS (BIT(1) | BIT(0))
#define IT8XXX2_GCTRL_IWDTR BIT(1) #define IT8XXX2_GCTRL_IWDTR BIT(1)
/* 0x0B: Wait Next 65K Rising */
#define IT8XXX2_GCTRL_WN65K 0x00
/* 0x10: Reset Control DMM */ /* 0x10: Reset Control DMM */
#define IT8XXX2_GCTRL_UART1SD BIT(3) #define IT8XXX2_GCTRL_UART1SD BIT(3)
#define IT8XXX2_GCTRL_UART2SD BIT(2) #define IT8XXX2_GCTRL_UART2SD BIT(2)
@ -1652,6 +1654,7 @@ struct gctrl_it8xxx2_regs {
#define IT8XXX2_GCTRL_EPLR_ENABLE BIT(0) #define IT8XXX2_GCTRL_EPLR_ENABLE BIT(0)
/* 0x46: Pin Multi-function Enable 3 */ /* 0x46: Pin Multi-function Enable 3 */
#define IT8XXX2_GCTRL_SMB3PSEL BIT(6) #define IT8XXX2_GCTRL_SMB3PSEL BIT(6)
#define IT8XXX2_GCTRL_SRAM_CRYPTO_USED BIT(5)
/* 0x4B: ETWD and UART Control */ /* 0x4B: ETWD and UART Control */
#define IT8XXX2_GCTRL_ETWD_HW_RST_EN BIT(0) #define IT8XXX2_GCTRL_ETWD_HW_RST_EN BIT(0)
/* 0x5D: RISCV ILM Configuration 0 */ /* 0x5D: RISCV ILM Configuration 0 */

View file

@ -168,6 +168,11 @@ config SOC_IT8XXX2_SHA256_HW_ACCELERATE
If we enable this config, because HW limits, the sha256 data must place in If we enable this config, because HW limits, the sha256 data must place in
first 4KB of RAM. first 4KB of RAM.
config SOC_IT8XXX2_SHA256_BLOCK_SIZE
hex
default 0x500 if SOC_IT82002_AW || SOC_IT82202_AX || SOC_IT82302_AX
default 0x200
DT_CHOSEN_ZEPHYR_FLASH := zephyr,flash DT_CHOSEN_ZEPHYR_FLASH := zephyr,flash
config SOC_IT8XXX2_FLASH_SIZE_BYTES config SOC_IT8XXX2_FLASH_SIZE_BYTES

View file

@ -65,10 +65,6 @@
#define MPU_ALIGN(region_size) . = ALIGN(4) #define MPU_ALIGN(region_size) . = ALIGN(4)
#endif #endif
#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE
#define SHA256_BLOCK_SIZE 0x200
#endif
#include <zephyr/linker/linker-devnull.h> #include <zephyr/linker/linker-devnull.h>
MEMORY MEMORY
@ -161,7 +157,7 @@ SECTIONS
/* Pad to match allocation of block in RAM, /* Pad to match allocation of block in RAM,
* maintaining code alignment against ILM */ * maintaining code alignment against ILM */
__sha256_pad_block_start = .; __sha256_pad_block_start = .;
. = . + SHA256_BLOCK_SIZE; . = . + CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE;
#endif #endif
/* Specially-tagged functions in SoC sources */ /* Specially-tagged functions in SoC sources */
KEEP(*(.__ram_code)) KEEP(*(.__ram_code))
@ -249,10 +245,11 @@ SECTIONS
__sha256_ram_block_size = \ __sha256_ram_block_size = \
ABSOLUTE(. - __sha256_ram_block_start); ABSOLUTE(. - __sha256_ram_block_start);
__sha256_ram_block_end = .; __sha256_ram_block_end = .;
ASSERT((__sha256_ram_block_size == SHA256_BLOCK_SIZE), \
"We need 512bytes for HW sha256 module"); ASSERT((__sha256_ram_block_size == CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE), \
"Not compatible ram size for HW sha256 module");
ASSERT((__sha256_ram_block_end < (RAM_BASE + 0x1000)), \ ASSERT((__sha256_ram_block_end < (RAM_BASE + 0x1000)), \
"512bytes must in SRAM first 4kbytes"); "sha256 ram block must in SRAM first 4kbytes");
ASSERT(((ABSOLUTE(__sha256_ram_block_start) & 0xfff) == \ ASSERT(((ABSOLUTE(__sha256_ram_block_start) & 0xfff) == \
(ABSOLUTE(__sha256_pad_block_start) & 0xfff)), \ (ABSOLUTE(__sha256_pad_block_start) & 0xfff)), \
"sha256 ram block needs the same offset with sha256 rom block"); "sha256 ram block needs the same offset with sha256 rom block");