[sw/lib] Update HMAC lib to new interface
* There is no need to set the input length ahead of time.
* Byte alignment is now supported.
Other changes:
* Remove return type from hmac_done.
diff --git a/sw/lib/common.h b/sw/lib/common.h
index 2b989f2..7908d6e 100644
--- a/sw/lib/common.h
+++ b/sw/lib/common.h
@@ -8,9 +8,6 @@
#include <stdbool.h>
#include <stdint.h>
-// Adjust clock speed to match simulation
-//#define SIMULATION
-
#ifdef SIMULATION
#define CLK_FIXED_FREQ_HZ (500 * 1000)
static const unsigned long UART_BAUD_RATE = 9600;
diff --git a/sw/lib/hmac.c b/sw/lib/hmac.c
index 7318c90..a48e589 100644
--- a/sw/lib/hmac.c
+++ b/sw/lib/hmac.c
@@ -15,21 +15,12 @@
REG32(HMAC_CFG(0)) = hmac_cfg.input_endian_swap << HMAC_CFG_ENDIAN_SWAP |
1 << hmac_cfg.mode |
hmac_cfg.digest_endian_swap << HMAC_CFG_DIGEST_SWAP;
-
- REG32(HMAC_MSG_LENGTH_LOWER(0)) = hmac_cfg.length_lower;
- REG32(HMAC_MSG_LENGTH_UPPER(0)) = hmac_cfg.length_upper;
-
for (int i = 0; i < 8; i++) {
REG32(HMAC_KEY0(0) + i * sizeof(uint32_t)) = hmac_cfg.keys[i];
}
-
- REG32(HMAC_CMD(0)) = -1;
+ REG32(HMAC_CMD(0)) = 1 << HMAC_CMD_HASH_START;
};
-int hmac_fifo_full(void) {
- return (REG32(HMAC_STATUS(0)) >> HMAC_STATUS_FIFO_FULL) & 0x1;
-}
-
static int hmac_fifo_depth(void) {
return (REG32(HMAC_STATUS(0)) >> HMAC_STATUS_FIFO_DEPTH_OFFSET) &
HMAC_STATUS_FIFO_DEPTH_MASK;
@@ -37,15 +28,12 @@
static int fifo_avail(void) { return HMAC_FIFO_MAX - hmac_fifo_depth(); }
-void hmac_write(const void *data, size_t size_in_bytes) {
- const uint8_t *bp;
- const uint32_t *wp;
+void hmac_update(const void *data, size_t size_in_bytes) {
+ const uint32_t *wp = (const uint32_t *)data;
uint32_t bytes_per_word = sizeof(uint32_t) / sizeof(uint8_t);
uint32_t bytes_left_over = (size_in_bytes % bytes_per_word);
size_t words_remaining = size_in_bytes / bytes_per_word;
- wp = (uint32_t *)data;
-
// write in all words
while (words_remaining > 0) {
if (words_remaining > HMAC_FIFO_GROUP_SIZE) {
@@ -63,47 +51,25 @@
REG32(HMAC_MSG_FIFO(0)) = *wp++;
REG32(HMAC_MSG_FIFO(0)) = *wp++;
words_remaining -= HMAC_FIFO_GROUP_SIZE;
-
} else {
REG32(HMAC_MSG_FIFO(0)) = *wp++;
words_remaining--;
};
}
- // TODO: this is necessary because hmac only understands words right now, we
- // cannot do a byte write. Once that is addressed, change following to
- // byte writes directly
- // Despite no byte support, it would have been okay to just read the entire
- // word and write it to hmac, since hmac knows exactly which bytes to ignore /
- // process. The problem however, is that the DV environment does not like
- // reading of unknown data. So imagine if we have one byte (0xab) left over,
- // in DV memory, this is represented as
- // XXXX_XXab. Our environment assertions will fail when a full word read is
- // made to the X's, thus it is converted to byte reads below to avoid that
- // problem
- uint32_t padded_word = 0;
- uint8_t *last_word_ptr = (uint8_t *)&padded_word;
- bp = (uint8_t *)wp;
-
- while (bytes_left_over > 0) {
- *last_word_ptr++ = *bp++;
- bytes_left_over--;
+ const uint8_t *bp = (const uint8_t *)wp;
+ for (; bytes_left_over > 0; --bytes_left_over) {
+ REG8(HMAC_MSG_FIFO(0)) = *bp++;
}
-
- // this word is ignored if no bytes are left over
- REG32(HMAC_MSG_FIFO(0)) = padded_word;
}
-int hmac_done(uint32_t *digest) {
- // TODO need a timeout mechanism
- // wait for done to assert
+void hmac_done(uint32_t *digest) {
+ REG32(HMAC_CMD(0)) = 1 << HMAC_CMD_HASH_PROCESS;
while (!((REG32(HMAC_INTR_STATE(0)) >> HMAC_INTR_STATE_HMAC_DONE) & 0x1)) {
}
+ REG32(HMAC_INTR_STATE(0)) = 1 << HMAC_INTR_STATE_HMAC_DONE;
for (uint32_t i = 0; i < 8; i++) {
*digest++ = REG32(HMAC_DIGEST0(0) + i * sizeof(uintptr_t));
}
-
- // eventually when we timeout, need to return an error code
- return 0;
}
diff --git a/sw/lib/hmac.h b/sw/lib/hmac.h
index 12ee6c1..b78d998 100644
--- a/sw/lib/hmac.h
+++ b/sw/lib/hmac.h
@@ -17,23 +17,16 @@
uint32_t input_endian_swap;
// output swapping only (to digest)
uint32_t digest_endian_swap;
- // length in bits
- uint32_t length_lower;
- // lenght in bits
- uint32_t length_upper;
uint32_t keys[8];
} hmac_cfg_t;
/* Intialize hmac to desired mode. */
void hmac_init(hmac_cfg_t hmac_cfg);
-/* Returns 1 if hmac fifo is full, 0 otherwise. */
-int hmac_fifo_full(void);
-
/* Write |data| to hmac with |size| in Bytes */
-void hmac_write(const void *data, size_t size);
+void hmac_update(const void *data, size_t size_in_bytes);
/* Poll for hmac done and read out digest. */
-int hmac_done(uint32_t *digest);
+void hmac_done(uint32_t *digest);
#endif // _F_LIB_HMAC_H__
diff --git a/sw/tests/sanity_hmac/sanity_hmac.c b/sw/tests/sanity_hmac/sanity_hmac.c
index 95ffdfe..2755d10 100644
--- a/sw/tests/sanity_hmac/sanity_hmac.c
+++ b/sw/tests/sanity_hmac/sanity_hmac.c
@@ -32,22 +32,16 @@
digest_t digest;
uart_init(UART_BAUD_RATE);
+ uart_send_str("Starting Sha256 512 bit hash test.\r\n");
hmac_cfg_t setup = {.mode = Sha256,
.input_endian_swap = 1,
.digest_endian_swap = 1,
- .length_lower = 0,
- .length_upper = 0,
.keys = {0}};
- // length in bits
- setup.length_lower = strlen(test.sha_input) << 3;
-
hmac_init(setup);
-
- hmac_write(test.sha_input, strlen(test.sha_input));
-
- error |= hmac_done(digest.w);
+ hmac_update(test.sha_input, strlen(test.sha_input));
+ hmac_done(digest.w);
for (uint32_t i = 0; i < 8; i++) {
if (digest.w[i] != test.digest[i]) {
@@ -58,11 +52,11 @@
}
if (error) {
- uart_send_str("FAIL!\n");
+ uart_send_str("FAIL!\r\n");
while (1) {
}
} else {
- uart_send_str("PASS!\n");
+ uart_send_str("PASS!\r\n");
__asm__ volatile("wfi;");
}
}