[sw/lib] Add sha256 wrapper
Add hw_SHA256 API matching the embedded cryptoc interface available in
sw/vendor/cryptoc. The API is implemented on top of the HMAC library.
Rename the sanity_hmac/sanity_hmac test as hmac/sha256_test to better
reflect the purpose of the code module.
diff --git a/sw/exts/common/options.mk b/sw/exts/common/options.mk
index 35e13da..2f8be87 100644
--- a/sw/exts/common/options.mk
+++ b/sw/exts/common/options.mk
@@ -21,6 +21,7 @@
EXT_DIR := $(SW_DIR)/exts/common
EXT_SRCS := $(EXT_DIR)/_crt.c
EXT_ASMS :=
+VENDOR_DIR := $(SW_DIR)/vendor
RV_TOOLS ?= /tools/riscv/bin/
OBJCOPY ?= $(subst gcc,objcopy,$(wordlist 1,1,$(CC)))
@@ -40,6 +41,6 @@
DEPS = $(OBJS:%.o=%.d)
LIBS =-L$(LIB_DIR) -l$(LIB_NAME)
-INCS +=-I$(LIB_DIR)
+INCS +=-I$(LIB_DIR) -I$(VENDOR_DIR)
OUTFILES := $(EXE).elf $(EXE).vmem $(EXE).bin $(EXE).dis $(EXE).map
diff --git a/sw/lib/Makefile b/sw/lib/Makefile
index 922cd58..5220ca0 100644
--- a/sw/lib/Makefile
+++ b/sw/lib/Makefile
@@ -5,18 +5,20 @@
# Generate a baremetal application for the microcontroller
DIF_SRCS = uart.c gpio.c spi_device.c flash_ctrl.c hmac.c usbdev.c rv_timer.c
-EXT_SRCS = usb_controlep.c usb_simpleserial.c irq.c handler.c
+EXT_SRCS = usb_controlep.c usb_simpleserial.c irq.c handler.c hw_sha256.c
EXT_ASMS = irq_vectors.S
GENHDRS := ${DIF_SRCS:.c=_regs.h}
GENHDR_BASE := ${DIF_SRCS:.c=}
ARCH = rv32imc
# ARCH = rv32im # to disable compressed instructions
-RV_TOOLS ?= /tools/riscv/bin/
+RV_TOOLS ?= /tools/riscv/bin
+INCS += -I../vendor
CC := ${RV_TOOLS}/riscv32-unknown-elf-gcc
CFLAGS ?= -Wall -g -Os -march=$(ARCH) -mabi=ilp32 -static -mcmodel=medany \
- -fvisibility=hidden -nostdlib -nostartfiles
+ -fvisibility=hidden -nostdlib -nostartfiles $(INCS)
+
ifeq ($(SIM),1)
CFLAGS += -DSIMULATION
@@ -37,9 +39,6 @@
all: $(OUTFILES)
-%.o: %.c %.S
- $(CC) $(CFLAGS) -MMD -c $(INCS) -o $@ $<
-
define header_gen
$1.c: $1_regs.h
diff --git a/sw/lib/hw_sha256.c b/sw/lib/hw_sha256.c
new file mode 100644
index 0000000..b6563eb
--- /dev/null
+++ b/sw/lib/hw_sha256.c
@@ -0,0 +1,41 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "hw_sha256.h"
+
+#include "hmac.h"
+
+static const HASH_VTAB HW_SHA256_VTAB = {hw_SHA256_init, hw_SHA256_update,
+ hw_SHA256_final, hw_SHA256_hash,
+ SHA256_DIGEST_SIZE};
+
+static void sha256_init() {
+ hmac_cfg_t config = {.mode = HMAC_OP_SHA256,
+ .input_endian_swap = 1,
+ .digest_endian_swap = 1,
+ .keys = {0}};
+ hmac_init(config);
+}
+
+void hw_SHA256_init(HW_SHA256_CTX *ctx) {
+ // TODO: For security, need to make sure HMAC is not stuck in progress.
+ ctx->f = &HW_SHA256_VTAB;
+ sha256_init();
+}
+
+void hw_SHA256_update(HW_SHA256_CTX *ctx, const void *data, size_t len) {
+ hmac_update(data, len);
+}
+
+const uint8_t *hw_SHA256_final(HW_SHA256_CTX *ctx) {
+ hmac_done((uint32_t *)ctx->buf);
+ return ctx->buf;
+}
+
+const uint8_t *hw_SHA256_hash(const void *data, size_t len, uint8_t *digest) {
+ sha256_init();
+ hmac_update(data, len);
+ hmac_done((uint32_t *)digest);
+ return digest;
+}
diff --git a/sw/lib/hw_sha256.h b/sw/lib/hw_sha256.h
new file mode 100644
index 0000000..178fc49
--- /dev/null
+++ b/sw/lib/hw_sha256.h
@@ -0,0 +1,51 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef _F_LIB_SHA256_H__
+#define _F_LIB_SHA256_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "cryptoc/hash-internal.h"
+
+typedef HASH_CTX HW_SHA256_CTX;
+
+#define SHA256_DIGEST_SIZE 32
+
+/**
+ * hw_SHA256_init initializes |ctx|.
+ *
+ * @param ctx SHA256 context.
+ */
+void hw_SHA256_init(HW_SHA256_CTX *ctx);
+
+/**
+ * hw_SHA256_update adds |len| bytes from |data| to |ctx|.
+ *
+ * @param ctx SHA256 context.
+ * @param data Input buffer.
+ * @param len Number of bytes to add.
+ */
+void hw_SHA256_update(HW_SHA256_CTX *ctx, const void *data, size_t len);
+
+/**
+ * hw_SHA256_final adds the final padding to |ctx| and calculates digest.
+ *
+ * @param ctx SHA256 context.
+ *
+ * @return pointer to digest buffer held in |ctx|.
+ */
+const uint8_t *hw_SHA256_final(HW_SHA256_CTX *ctx);
+
+/**
+ * hw_SHA256_hash writes |digest| from |len| bytes of |data|.
+ *
+ * @param data Input buffer.
+ * @param len Number of bytes to add.
+ * @param digest Output buffer.
+ */
+const uint8_t *hw_SHA256_hash(const void *data, size_t len, uint8_t *digest);
+
+#endif // _F_LIB_SHA256_H__
diff --git a/sw/tests/sanity_hmac/Makefile b/sw/tests/hmac/Makefile
similarity index 87%
rename from sw/tests/sanity_hmac/Makefile
rename to sw/tests/hmac/Makefile
index 28da267..61f3e40 100644
--- a/sw/tests/sanity_hmac/Makefile
+++ b/sw/tests/hmac/Makefile
@@ -4,8 +4,8 @@
#
# Generate a baremetal application for the microcontroller
-NAME = sanity_hmac
-SRCS = sanity_hmac.c
+NAME = sha256_test
+SRCS = sha256_test.c
PROGRAM_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
include ${PROGRAM_DIR}/../../exts/common/options.mk
diff --git a/sw/tests/sanity_hmac/sanity_hmac.c b/sw/tests/hmac/sha256_test.c
similarity index 61%
rename from sw/tests/sanity_hmac/sanity_hmac.c
rename to sw/tests/hmac/sha256_test.c
index 00cc30f..dd3c23b 100644
--- a/sw/tests/sanity_hmac/sanity_hmac.c
+++ b/sw/tests/hmac/sha256_test.c
@@ -7,18 +7,12 @@
#include "common.h"
#include "flash_ctrl.h"
-#include "hmac.h"
-#include "hmac_regs.h"
+#include "hw_sha256.h"
#include "uart.h"
-typedef union digest {
- uint8_t b[32];
- uint32_t w[8];
-} digest_t;
-
typedef struct test_data {
uint32_t digest[8];
- char sha_input[512];
+ char data[512];
} test_data_t;
test_data_t test = {
@@ -29,23 +23,16 @@
int main(int argc, char **argv) {
uint32_t error = 0;
- digest_t digest;
+ uint32_t digest[8];
uart_init(UART_BAUD_RATE);
- uart_send_str("SHA256 test.\r\n");
+ uart_send_str("Running SHA256 test\r\n");
- hmac_cfg_t setup = {.mode = HMAC_OP_SHA256,
- .input_endian_swap = 1,
- .digest_endian_swap = 1,
- .keys = {0}};
-
- hmac_init(setup);
- hmac_update(test.sha_input, strlen(test.sha_input));
- hmac_done(digest.w);
+ hw_SHA256_hash(test.data, strlen(test.data), (uint8_t *)digest);
for (uint32_t i = 0; i < 8; i++) {
- if (digest.w[i] != test.digest[i]) {
- REG32(FLASH_CTRL_SCRATCH(0)) = digest.w[i];
+ if (digest[i] != test.digest[i]) {
+ REG32(FLASH_CTRL_SCRATCH(0)) = digest[i];
error++;
break;
}