Browse Source
Add SHA256 accelerator support for it8xxx2 series. This driver passes the following test: tests/crypto/crypto_hash/ Signed-off-by: Dino Li <Dino.Li@ite.com.tw>pull/59761/head
7 changed files with 261 additions and 0 deletions
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2023 ITE Corporation. |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
config CRYPTO_IT8XXX2_SHA |
||||
bool "ITE IT8XXX2 SHA driver" |
||||
default y |
||||
depends on DT_HAS_ITE_IT8XXX2_SHA_ENABLED |
||||
select SOC_IT8XXX2_SHA256_HW_ACCELERATE |
||||
help |
||||
Enable ITE IT8XXX2 SHA driver. |
||||
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. |
@ -0,0 +1,225 @@
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2023 ITE Corporation. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#define DT_DRV_COMPAT ite_it8xxx2_sha |
||||
|
||||
#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, |
||||
"unsupported sha instance"); |
||||
|
||||
#define IT8XXX2_SHA_REGS_BASE DT_REG_ADDR(DT_NODELABEL(sha0)) |
||||
|
||||
/* 0x00: Hash Control Register */ |
||||
#define IT8XXX2_REG_HASHCTRLR (0) |
||||
/* 0x01: SHA256 Hash Base Address 1 Register */ |
||||
#define IT8XXX2_REG_SHA_HBADDR (1) |
||||
/* 0x02: SHA256 Hash Base Address 2 Register */ |
||||
#define IT8XXX2_REG_SHA_HBADDR2 (2) |
||||
|
||||
#define IT8XXX2_SHA_START_SHA256 BIT(1) |
||||
|
||||
#define SHA_SHA256_HASH_LEN 32 |
||||
#define SHA_SHA256_BLOCK_LEN 64 |
||||
#define SHA_SHA256_K_LEN 256 |
||||
#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_K_LEN_WORDS (SHA_SHA256_K_LEN / sizeof(uint32_t)) |
||||
|
||||
/*
|
||||
* 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 { |
||||
/* W[0] ~ W[15] */ |
||||
uint32_t w_sha[SHA_SHA256_BLOCK_LEN_WORDS]; |
||||
uint8_t w_input[SHA_SHA256_BLOCK_LEN]; |
||||
}; |
||||
/* reserved */ |
||||
uint32_t reserved1[8]; |
||||
/* H[0] ~ H[7] */ |
||||
uint32_t h[SHA_SHA256_HASH_LEN_WORDS]; |
||||
/* reserved */ |
||||
uint32_t reserved2[30]; |
||||
uint32_t w_input_index; |
||||
uint32_t total_len; |
||||
/* K[0] ~ K[63] */ |
||||
uint32_t k[SHA_SHA256_K_LEN_WORDS]; |
||||
} __aligned(256); |
||||
|
||||
Z_GENERIC_SECTION(.__sha256_ram_block) struct chip_sha256_ctx chip_ctx; |
||||
|
||||
static const uint32_t sha256_h0[SHA_SHA256_HASH_LEN_WORDS] = { |
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, |
||||
0x1f83d9ab, 0x5be0cd19 |
||||
}; |
||||
|
||||
/*
|
||||
* References of K of SHA-256: |
||||
* https://en.wikipedia.org/wiki/SHA-2#Pseudocode
|
||||
*/ |
||||
static const uint32_t sha256_k[SHA_SHA256_K_LEN_WORDS] = { |
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, |
||||
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, |
||||
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, |
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, |
||||
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, |
||||
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
||||
}; |
||||
|
||||
static void it8xxx2_sha256_init(bool init_k) |
||||
{ |
||||
int i; |
||||
|
||||
chip_ctx.total_len = 0; |
||||
chip_ctx.w_input_index = 0; |
||||
|
||||
/* Initialize hash values */ |
||||
for (i = 0; i < ARRAY_SIZE(sha256_h0); i++) { |
||||
chip_ctx.h[i] = sha256_h0[i]; |
||||
} |
||||
/* Initialize array of round constants */ |
||||
if (init_k) { |
||||
for (int i = 0; i < ARRAY_SIZE(sha256_k); i++) { |
||||
chip_ctx.k[i] = sha256_k[i]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void it8xxx2_sha256_module_calculation(void) |
||||
{ |
||||
uint32_t key; |
||||
uint8_t hash_ctrl; |
||||
|
||||
/*
|
||||
* Since W field on it8xxx2 requires big-endian format, change byte |
||||
* order before computing hash. |
||||
*/ |
||||
for (int i = 0; i < SHA_SHA256_BLOCK_LEN_WORDS; i++) { |
||||
chip_ctx.w_sha[i] = sys_cpu_to_be32(chip_ctx.w_sha[i]); |
||||
} |
||||
/*
|
||||
* 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(); |
||||
hash_ctrl = sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_HASHCTRLR); |
||||
sys_write8(hash_ctrl | IT8XXX2_SHA_START_SHA256, |
||||
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_HASHCTRLR); |
||||
hash_ctrl = sys_read8(IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_HASHCTRLR); |
||||
irq_unlock(key); |
||||
|
||||
chip_ctx.w_input_index = 0; |
||||
} |
||||
|
||||
static int it8xxx2_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt, |
||||
bool finish) |
||||
{ |
||||
uint32_t rem_len = pkt->in_len; |
||||
uint32_t in_buf_idx = 0; |
||||
|
||||
while (rem_len--) { |
||||
chip_ctx.w_input[chip_ctx.w_input_index++] = |
||||
pkt->in_buf[in_buf_idx++]; |
||||
if (chip_ctx.w_input_index >= SHA_SHA256_BLOCK_LEN) { |
||||
it8xxx2_sha256_module_calculation(); |
||||
} |
||||
} |
||||
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; |
||||
|
||||
if (chip_ctx.w_input_index >= 56) { |
||||
it8xxx2_sha256_module_calculation(); |
||||
memset(&chip_ctx.w_input[chip_ctx.w_input_index], |
||||
0, SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index); |
||||
} |
||||
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8); |
||||
it8xxx2_sha256_module_calculation(); |
||||
|
||||
for (int i = 0; i < SHA_SHA256_HASH_LEN_WORDS; i++) { |
||||
ob_ptr[i] = sys_be32_to_cpu(chip_ctx.h[i]); |
||||
} |
||||
|
||||
it8xxx2_sha256_init(false); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int it8xxx2_hash_session_free(const struct device *dev, |
||||
struct hash_ctx *ctx) |
||||
{ |
||||
it8xxx2_sha256_init(false); |
||||
|
||||
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 algo"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
if (ctx->flags & ~(it8xxx2_query_hw_caps(dev))) { |
||||
LOG_ERR("Unsupported flag"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
it8xxx2_sha256_init(false); |
||||
ctx->hash_hndlr = it8xxx2_hash_handler; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int it8xxx2_sha_init(const struct device *dev) |
||||
{ |
||||
it8xxx2_sha256_init(true); |
||||
/* Configure base address register for W and H */ |
||||
sys_write8(((uint32_t)&chip_ctx >> 6) & 0xfc, |
||||
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHA_HBADDR); |
||||
/* Configure base address register for K */ |
||||
sys_write8(((uint32_t)&chip_ctx.k >> 6) & 0xfc, |
||||
IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHA_HBADDR2); |
||||
|
||||
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); |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2023, ITE Corporation |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
description: ITE IT8XXX2 Crypto SHA accelerator. |
||||
|
||||
compatible: "ite,it8xxx2-sha" |
||||
|
||||
include: base.yaml |
||||
|
||||
properties: |
||||
reg: |
||||
required: true |
Loading…
Reference in new issue