From 1d74cb74d9d7fd99d44fdf7c5f713b48762b5952 Mon Sep 17 00:00:00 2001 From: Ruibin Chang Date: Wed, 27 Mar 2024 16:57:51 +0800 Subject: [PATCH] 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 --- drivers/crypto/CMakeLists.txt | 1 + drivers/crypto/Kconfig.it8xxx2 | 11 + drivers/crypto/crypto_it8xxx2_sha_v2.c | 350 ++++++++++++++++++++ dts/bindings/crypto/ite,it8xxx2-sha-v2.yaml | 12 + dts/riscv/ite/it82xx2.dtsi | 6 + soc/ite/ec/common/chip_chipregs.h | 3 + soc/ite/ec/it8xxx2/Kconfig | 5 + soc/ite/ec/it8xxx2/linker.ld | 13 +- 8 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 drivers/crypto/crypto_it8xxx2_sha_v2.c create mode 100644 dts/bindings/crypto/ite,it8xxx2-sha-v2.yaml diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 68b63aef6ee..4cdf7a6e8b8 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -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_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_V2 crypto_it8xxx2_sha_v2.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/drivers/crypto/Kconfig.it8xxx2 b/drivers/crypto/Kconfig.it8xxx2 index d38062db84c..8c14dbfd64d 100644 --- a/drivers/crypto/Kconfig.it8xxx2 +++ b/drivers/crypto/Kconfig.it8xxx2 @@ -11,3 +11,14 @@ config CRYPTO_IT8XXX2_SHA This driver supports SHA256 hardware accelerator of the it8xxx2 series. It requires 256 + 256 bytes in the RAM's first 4k-bytes to calculate 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. diff --git a/drivers/crypto/crypto_it8xxx2_sha_v2.c b/drivers/crypto/crypto_it8xxx2_sha_v2.c new file mode 100644 index 00000000000..48eae76c673 --- /dev/null +++ b/drivers/crypto/crypto_it8xxx2_sha_v2.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2024 ITE Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ite_it8xxx2_sha_v2 + +#include +#include +#include +#include +#include + +#include +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); diff --git a/dts/bindings/crypto/ite,it8xxx2-sha-v2.yaml b/dts/bindings/crypto/ite,it8xxx2-sha-v2.yaml new file mode 100644 index 00000000000..94d9d664d9c --- /dev/null +++ b/dts/bindings/crypto/ite,it8xxx2-sha-v2.yaml @@ -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 diff --git a/dts/riscv/ite/it82xx2.dtsi b/dts/riscv/ite/it82xx2.dtsi index 67689192661..a9ab8b206cf 100644 --- a/dts/riscv/ite/it82xx2.dtsi +++ b/dts/riscv/ite/it82xx2.dtsi @@ -998,5 +998,11 @@ num-in-endpoints = <10>; num-out-endpoints = <5>; }; + + sha0: crypto@f03c00 { + compatible = "ite,it8xxx2-sha-v2"; + reg = <0x00f03c00 0x5>; + status = "disabled"; + }; }; }; diff --git a/soc/ite/ec/common/chip_chipregs.h b/soc/ite/ec/common/chip_chipregs.h index dc0c3552a50..71176c366d6 100644 --- a/soc/ite/ec/common/chip_chipregs.h +++ b/soc/ite/ec/common/chip_chipregs.h @@ -1633,6 +1633,8 @@ struct gctrl_it8xxx2_regs { /* 0x06: Reset Status */ #define IT8XXX2_GCTRL_LRS (BIT(1) | BIT(0)) #define IT8XXX2_GCTRL_IWDTR BIT(1) +/* 0x0B: Wait Next 65K Rising */ +#define IT8XXX2_GCTRL_WN65K 0x00 /* 0x10: Reset Control DMM */ #define IT8XXX2_GCTRL_UART1SD BIT(3) #define IT8XXX2_GCTRL_UART2SD BIT(2) @@ -1652,6 +1654,7 @@ struct gctrl_it8xxx2_regs { #define IT8XXX2_GCTRL_EPLR_ENABLE BIT(0) /* 0x46: Pin Multi-function Enable 3 */ #define IT8XXX2_GCTRL_SMB3PSEL BIT(6) +#define IT8XXX2_GCTRL_SRAM_CRYPTO_USED BIT(5) /* 0x4B: ETWD and UART Control */ #define IT8XXX2_GCTRL_ETWD_HW_RST_EN BIT(0) /* 0x5D: RISCV ILM Configuration 0 */ diff --git a/soc/ite/ec/it8xxx2/Kconfig b/soc/ite/ec/it8xxx2/Kconfig index 0b544158e34..0e40836acfd 100644 --- a/soc/ite/ec/it8xxx2/Kconfig +++ b/soc/ite/ec/it8xxx2/Kconfig @@ -168,6 +168,11 @@ config SOC_IT8XXX2_SHA256_HW_ACCELERATE If we enable this config, because HW limits, the sha256 data must place in 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 config SOC_IT8XXX2_FLASH_SIZE_BYTES diff --git a/soc/ite/ec/it8xxx2/linker.ld b/soc/ite/ec/it8xxx2/linker.ld index 255c4144e11..95b7d679bac 100644 --- a/soc/ite/ec/it8xxx2/linker.ld +++ b/soc/ite/ec/it8xxx2/linker.ld @@ -65,10 +65,6 @@ #define MPU_ALIGN(region_size) . = ALIGN(4) #endif -#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE -#define SHA256_BLOCK_SIZE 0x200 -#endif - #include MEMORY @@ -161,7 +157,7 @@ SECTIONS /* Pad to match allocation of block in RAM, * maintaining code alignment against ILM */ __sha256_pad_block_start = .; - . = . + SHA256_BLOCK_SIZE; + . = . + CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE; #endif /* Specially-tagged functions in SoC sources */ KEEP(*(.__ram_code)) @@ -249,10 +245,11 @@ SECTIONS __sha256_ram_block_size = \ ABSOLUTE(. - __sha256_ram_block_start); __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)), \ - "512bytes must in SRAM first 4kbytes"); + "sha256 ram block must in SRAM first 4kbytes"); ASSERT(((ABSOLUTE(__sha256_ram_block_start) & 0xfff) == \ (ABSOLUTE(__sha256_pad_block_start) & 0xfff)), \ "sha256 ram block needs the same offset with sha256 rom block");