5#include "sw/device/silicon_creator/lib/drivers/hmac.h"
7#include "hw/top/dt/hmac.h"
12#include "sw/device/silicon_creator/lib/error.h"
14#include "hw/top/hmac_regs.h"
18static inline uint32_t hmac_base(
void) {
19 return dt_hmac_primary_reg_block(kHmacDt);
22static void hmac_configure(
bool big_endian_digest,
bool hmac_mode) {
24 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET, 0u);
27 abs_mmio_write32(hmac_base() + HMAC_INTR_ENABLE_REG_OFFSET, 0u);
28 abs_mmio_write32(hmac_base() + HMAC_INTR_STATE_REG_OFFSET, UINT32_MAX);
31 reg = bitfield_bit32_write(reg, HMAC_CFG_DIGEST_SWAP_BIT, big_endian_digest);
32 reg = bitfield_bit32_write(reg, HMAC_CFG_ENDIAN_SWAP_BIT,
false);
33 reg = bitfield_bit32_write(reg, HMAC_CFG_SHA_EN_BIT,
true);
34 reg = bitfield_bit32_write(reg, HMAC_CFG_HMAC_EN_BIT, hmac_mode);
36 reg = bitfield_field32_write(reg, HMAC_CFG_DIGEST_SIZE_FIELD,
37 HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256);
38 reg = bitfield_field32_write(reg, HMAC_CFG_KEY_LENGTH_FIELD,
39 HMAC_CFG_KEY_LENGTH_VALUE_KEY_256);
40 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET, reg);
43void sc_hmac_hmac_sha256_configure(
bool big_endian_digest, hmac_key_t key) {
44 hmac_configure(big_endian_digest,
true);
45 for (
size_t i = 0; i < kHmacKeyNumWords; ++i) {
46 abs_mmio_write32(hmac_base() + HMAC_KEY_0_REG_OFFSET + i *
sizeof(uint32_t),
51void hmac_sha256_configure(
bool big_endian_digest) {
52 hmac_configure(big_endian_digest,
false);
55inline void hmac_sha256_start(
void) {
56 uint32_t cmd = bitfield_bit32_write(0, HMAC_CMD_HASH_START_BIT,
true);
57 abs_mmio_write32(hmac_base() + HMAC_CMD_REG_OFFSET, cmd);
60void hmac_sha256_update(
const void *data,
size_t len) {
61 const uint8_t *data_sent = (
const uint8_t *)data;
64 for (; len != 0 && (uintptr_t)data_sent & 3; --len) {
65 abs_mmio_write8(hmac_base() + HMAC_MSG_FIFO_REG_OFFSET, *data_sent++);
68 for (; len >=
sizeof(uint32_t); len -=
sizeof(uint32_t)) {
69 uint32_t data_aligned = read_32(data_sent);
70 abs_mmio_write32(hmac_base() + HMAC_MSG_FIFO_REG_OFFSET, data_aligned);
71 data_sent +=
sizeof(uint32_t);
75 for (; len != 0; --len) {
76 abs_mmio_write8(hmac_base() + HMAC_MSG_FIFO_REG_OFFSET, *data_sent++);
80void hmac_sha256_update_words(
const uint32_t *data,
size_t len) {
81 for (
size_t i = 0; i < len; i++) {
82 abs_mmio_write32(hmac_base() + HMAC_MSG_FIFO_REG_OFFSET, data[i]);
86inline void hmac_sha256_process(
void) {
87 uint32_t cmd = bitfield_bit32_write(0, HMAC_CMD_HASH_PROCESS_BIT,
true);
88 abs_mmio_write32(hmac_base() + HMAC_CMD_REG_OFFSET, cmd);
96static void wait_for_done(
void) {
99 reg = abs_mmio_read32(hmac_base() + HMAC_INTR_STATE_REG_OFFSET);
100 }
while (!bitfield_bit32_read(reg, HMAC_INTR_STATE_HMAC_DONE_BIT));
101 abs_mmio_write32(hmac_base() + HMAC_INTR_STATE_REG_OFFSET, reg);
104void hmac_sha256_final_truncated(uint32_t *digest,
size_t len) {
107 uint32_t result, incr;
108 uint32_t reg = abs_mmio_read32(hmac_base() + HMAC_CFG_REG_OFFSET);
109 if (bitfield_bit32_read(reg, HMAC_CFG_DIGEST_SWAP_BIT)) {
111 result = HMAC_DIGEST_0_REG_OFFSET;
112 incr =
sizeof(uint32_t);
117 result = HMAC_DIGEST_7_REG_OFFSET;
118 incr = (uint32_t) -
sizeof(uint32_t);
124 len = len <= kHmacDigestNumWords ? len : kHmacDigestNumWords;
125 for (uint32_t i = 0; i < len; ++i, result += incr) {
126 digest[i] = abs_mmio_read32(hmac_base() + result);
130void hmac_sha256(
const void *data,
size_t len, hmac_digest_t *digest) {
132 hmac_sha256_update(data, len);
133 hmac_sha256_process();
134 hmac_sha256_final(digest);
137void sc_hmac_hmac_sha256(
const void *data,
size_t len, hmac_key_t key,
138 bool big_endian_digest, hmac_digest_t *digest) {
139 sc_hmac_hmac_sha256_init(key, big_endian_digest);
140 hmac_sha256_update(data, len);
141 hmac_sha256_process();
142 hmac_sha256_final(digest);
145void hmac_sha256_save(hmac_context_t *ctx) {
148 uint32_t cmd = bitfield_bit32_write(0, HMAC_CMD_HASH_STOP_BIT,
true);
149 abs_mmio_write32(hmac_base() + HMAC_CMD_REG_OFFSET, cmd);
155 for (uint32_t i = 0; i < kHmacDigestNumWords; i++) {
156 ctx->digest[i] = abs_mmio_read32(hmac_base() + HMAC_DIGEST_0_REG_OFFSET +
157 i *
sizeof(uint32_t));
162 abs_mmio_read32(hmac_base() + HMAC_MSG_LENGTH_LOWER_REG_OFFSET);
164 abs_mmio_read32(hmac_base() + HMAC_MSG_LENGTH_UPPER_REG_OFFSET);
167 uint32_t cfg = abs_mmio_read32(hmac_base() + HMAC_CFG_REG_OFFSET);
168 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET,
169 bitfield_bit32_write(cfg, HMAC_CFG_SHA_EN_BIT,
false));
172 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET, cfg);
175void hmac_sha256_restore(
const hmac_context_t *ctx) {
178 uint32_t cfg = abs_mmio_read32(hmac_base() + HMAC_CFG_REG_OFFSET);
179 cfg = bitfield_bit32_write(cfg, HMAC_CFG_SHA_EN_BIT,
false);
180 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET, cfg);
185 for (uint32_t i = 0; i < kHmacDigestNumWords; i++) {
187 hmac_base() + HMAC_DIGEST_0_REG_OFFSET + i *
sizeof(uint32_t),
192 abs_mmio_write32(hmac_base() + HMAC_MSG_LENGTH_LOWER_REG_OFFSET,
194 abs_mmio_write32(hmac_base() + HMAC_MSG_LENGTH_UPPER_REG_OFFSET,
198 cfg = bitfield_bit32_write(cfg, HMAC_CFG_SHA_EN_BIT,
true);
199 abs_mmio_write32(hmac_base() + HMAC_CFG_REG_OFFSET, cfg);
202 uint32_t cmd = bitfield_bit32_write(0, HMAC_CMD_HASH_CONTINUE_BIT,
true);
203 abs_mmio_write32(hmac_base() + HMAC_CMD_REG_OFFSET, cmd);
206extern void sc_hmac_hmac_sha256_init(hmac_key_t key,
bool big_endian_digest);
207extern void hmac_sha256_init(
void);
208extern void hmac_sha256_final(hmac_digest_t *digest);