11 #include "hmac_regs.h"
19 static uint32_t get_status(
const dif_hmac_t *hmac) {
20 return mmio_region_read32(hmac->base_addr, HMAC_STATUS_REG_OFFSET);
31 static uint32_t get_fifo_entry_count(
const dif_hmac_t *hmac) {
38 static uint32_t get_fifo_available_space(
const dif_hmac_t *hmac) {
39 return HMAC_MSG_FIFO_SIZE_WORDS - get_fifo_entry_count(hmac);
58 static dif_result_t dif_hmac_calculate_device_config_value(
61 bool swap_message_endianness;
64 swap_message_endianness =
true;
67 swap_message_endianness =
false;
74 bool swap_digest_endianness;
77 swap_digest_endianness =
true;
80 swap_digest_endianness =
false;
89 *device_config, HMAC_CFG_ENDIAN_SWAP_BIT, swap_message_endianness);
91 *device_config, HMAC_CFG_DIGEST_SWAP_BIT, swap_digest_endianness);
104 uint32_t reg = mmio_region_read32(hmac->base_addr, HMAC_CFG_REG_OFFSET);
114 for (
size_t i = 0; i < 8; ++i) {
115 const ptrdiff_t word_offset = (ptrdiff_t)(i *
sizeof(uint32_t));
116 mmio_region_write32(hmac->base_addr, HMAC_KEY_7_REG_OFFSET - word_offset,
117 read_32((
char *)key + word_offset));
127 HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256);
129 HMAC_CFG_KEY_LENGTH_VALUE_KEY_256);
131 mmio_region_write32(hmac->base_addr, HMAC_CFG_REG_OFFSET, reg);
135 HMAC_CMD_HASH_START_BIT);
146 uint32_t reg = mmio_region_read32(hmac->base_addr, HMAC_CFG_REG_OFFSET);
157 HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256);
159 HMAC_CFG_KEY_LENGTH_VALUE_KEY_256);
162 mmio_region_write32(hmac->base_addr, HMAC_CFG_REG_OFFSET, reg);
166 HMAC_CMD_HASH_START_BIT);
172 size_t len,
size_t *bytes_sent) {
173 if (hmac == NULL || data == NULL) {
177 const uint8_t *data_sent = (
const uint8_t *)data;
178 size_t bytes_remaining = len;
180 while (bytes_remaining > 0 && get_fifo_available_space(hmac) > 0) {
181 bool word_aligned = (uintptr_t)data_sent %
sizeof(uint32_t) == 0;
182 size_t bytes_written = 0;
184 if (bytes_remaining <
sizeof(uint32_t) || !word_aligned) {
187 mmio_region_write8(hmac->base_addr, HMAC_MSG_FIFO_REG_OFFSET, *data_sent);
191 uint32_t word =
read_32(data_sent);
192 mmio_region_write32(hmac->base_addr, HMAC_MSG_FIFO_REG_OFFSET, word);
193 bytes_written =
sizeof(uint32_t);
196 bytes_remaining -= bytes_written;
197 data_sent += bytes_written;
200 if (bytes_sent != NULL) {
201 *bytes_sent = len - bytes_remaining;
204 if (bytes_remaining > 0) {
212 uint32_t *num_entries) {
213 if (hmac == NULL || num_entries == NULL) {
217 *num_entries = get_fifo_entry_count(hmac);
224 if (hmac == NULL || msg_len == NULL) {
228 mmio_region_read32(hmac->base_addr, HMAC_MSG_LENGTH_LOWER_REG_OFFSET);
230 mmio_region_read32(hmac->base_addr, HMAC_MSG_LENGTH_UPPER_REG_OFFSET);
232 *msg_len = (msg_upper << 32) | msg_lower;
243 HMAC_CMD_HASH_PROCESS_BIT);
252 for (
size_t i = 0; i <
ARRAYSIZE(digest->digest); ++i) {
253 digest->digest[i] = mmio_region_read32(
255 HMAC_DIGEST_7_REG_OFFSET - (ptrdiff_t)(i *
sizeof(uint32_t)));
261 if (hmac == NULL || digest == NULL) {
267 HMAC_INTR_STATE_HMAC_DONE_BIT);
271 hmac->base_addr, HMAC_STATUS_REG_OFFSET, HMAC_STATUS_FIFO_EMPTY_BIT);
275 HMAC_INTR_STATE_HMAC_ERR_BIT);
285 HMAC_INTR_STATE_HMAC_DONE_BIT);
286 }
else if (!fifo_empty) {
290 read_digest(hmac, digest);
292 if (disable_after_done) {
295 uint32_t device_config =
296 mmio_region_read32(hmac->base_addr, HMAC_CFG_REG_OFFSET);
303 HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_NONE);
306 HMAC_CFG_KEY_LENGTH_VALUE_KEY_256);
308 mmio_region_write32(hmac->base_addr, HMAC_CFG_REG_OFFSET, device_config);
316 if (hmac == NULL || digest == NULL) {
319 mmio_region_write32(hmac->base_addr, HMAC_WIPE_SECRET_REG_OFFSET, entropy);
320 read_digest(hmac, digest);