summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/npcx/build.mk2
-rw-r--r--chip/npcx/clock.c11
-rw-r--r--chip/npcx/sha256_chip.c141
-rw-r--r--chip/npcx/sha256_chip.h25
-rw-r--r--common/build.mk17
-rw-r--r--common/vboot_hash.c3
-rw-r--r--include/config.h3
-rw-r--r--include/sha256.h8
8 files changed, 207 insertions, 3 deletions
diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk
index 4409c33c5d..a013ef5ef5 100644
--- a/chip/npcx/build.mk
+++ b/chip/npcx/build.mk
@@ -48,6 +48,8 @@ ifneq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),npcx5 npcx7))
chip-y+=lct.o
endif
+chip-$(CONFIG_SHA256_HW_ACCELERATE)+=sha256_chip.o
+
# spi monitor program fw for openocd and UUT(UART Update Tool)
npcx-monitor-fw=chip/npcx/spiflashfw/npcx_monitor
npcx-monitor-fw-bin=${out}/$(npcx-monitor-fw).bin
diff --git a/chip/npcx/clock.c b/chip/npcx/clock.c
index 0f8f737401..ad611973be 100644
--- a/chip/npcx/clock.c
+++ b/chip/npcx/clock.c
@@ -166,11 +166,20 @@ void clock_turbo(void)
#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7
void clock_turbo(void)
{
- /*
+#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
+ /* For NPCX9:
+ * Increase CORE_CLK (CPU) as the same as OSC_CLK. Since
+ * CORE_CLK > 66MHz, we also need to set FIUDIV as 1 but
+ * can keep AHB6DIV to 0.
+ */
+ NPCX_HFCGP = 0x00;
+#else
+ /* For NPCX7:
* Increase CORE_CLK (CPU) as the same as OSC_CLK. Since
* CORE_CLK > 66MHz, we also need to set AHB6DIV and FIUDIV as 1.
*/
NPCX_HFCGP = 0x01;
+#endif
NPCX_HFCBCD = BIT(4);
}
diff --git a/chip/npcx/sha256_chip.c b/chip/npcx/sha256_chip.c
new file mode 100644
index 0000000000..6d2d938895
--- /dev/null
+++ b/chip/npcx/sha256_chip.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* SHA256 module for Chrome EC */
+#include "common.h"
+#include "sha256.h"
+#include "util.h"
+
+enum ncl_status {
+ NCL_STATUS_OK,
+ NCL_STATUS_FAIL,
+ NCL_STATUS_INVALID_PARAM,
+ NCL_STATUS_PARAM_NOT_SUPPORTED,
+ NCL_STATUS_SYSTEM_BUSY,
+ NCL_STATUS_AUTHENTICATION_FAIL,
+ NCL_STATUS_NO_RESPONSE,
+ NCL_STATUS_HARDWARE_ERROR,
+};
+
+enum ncl_sha_type {
+ NCL_SHA_TYPE_2_256 = 0,
+ NCL_SHA_TYPE_2_384 = 1,
+ NCL_SHA_TYPE_2_512 = 2,
+ NCL_SHA_TYPE_NUM
+};
+
+/*
+ * The base address of the table that holds the function pointer for each
+ * SHA256 API in ROM.
+ */
+#define NCL_SHA_BASE_ADDR 0x00000100UL
+struct ncl_sha {
+ /* Get the SHA context size required by SHA APIs. */
+ uint32_t (*get_context_size)(void);
+ /* Initial SHA context. */
+ enum ncl_status (*init_context)(void *ctx);
+ /* Finalize SHA context. */
+ enum ncl_status (*finalize_context)(void *ctx);
+ /* Initiate the SHA hardware module and setups needed parameters. */
+ enum ncl_status (*init)(void *ctx);
+ /*
+ * Prepare the context buffer for a SHA calculation - by loading the
+ * initial SHA-256/384/512 parameters.
+ */
+ enum ncl_status (*start)(void *ctx, enum ncl_sha_type type);
+ /*
+ * Updates the SHA calculation with the additional data. When the
+ * function returns, the hardware and memory buffer shall be ready to
+ * accept new data * buffers for SHA calculation and changes to the data
+ * in data buffer should no longer effect the SHA calculation.
+ */
+ enum ncl_status (*update)(void *ctx, const uint8_t *data, uint32_t Len);
+ /* Return the SHA result (digest.) */
+ enum ncl_status (*finish)(void *ctx, uint8_t *hashDigest);
+ /* Perform a complete SHA calculation */
+ enum ncl_status (*calc)(void *ctx, enum ncl_sha_type type,
+ const uint8_t *data, uint32_t Len, uint8_t *hashDigest);
+ /* Power on/off the SHA module. */
+ enum ncl_status (*power)(void *ctx, uint8_t enable);
+ /* Reset the SHA hardware and terminate any in-progress operations. */
+ enum ncl_status (*reset)(void *ctx);
+};
+
+#define NCL_SHA ((const struct ncl_sha *)NCL_SHA_BASE_ADDR)
+
+void SHA256_init(struct sha256_ctx *ctx)
+{
+ NCL_SHA->init_context(ctx->handle);
+ NCL_SHA->power(ctx->handle, 1);
+ NCL_SHA->init(ctx->handle);
+ NCL_SHA->reset(ctx->handle);
+ NCL_SHA->start(ctx->handle, NCL_SHA_TYPE_2_256);
+}
+
+void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len)
+{
+ NCL_SHA->update(ctx->handle, data, len);
+}
+
+void SHA256_abort(struct sha256_ctx *ctx)
+{
+ NCL_SHA->reset(ctx->handle);
+ NCL_SHA->power(ctx->handle, 0);
+ NCL_SHA->finalize_context(ctx->handle);
+}
+
+uint8_t *SHA256_final(struct sha256_ctx *ctx)
+{
+ NCL_SHA->finish(ctx->handle, ctx->buf);
+ NCL_SHA->power(ctx->handle, 0);
+ NCL_SHA->finalize_context(ctx->handle);
+ return ctx->buf;
+}
+
+static void hmac_SHA256_step(uint8_t *output, uint8_t mask,
+ const uint8_t *key, const int key_len,
+ const uint8_t *data, const int data_len)
+{
+ struct sha256_ctx hmac_ctx;
+ uint8_t *key_pad = hmac_ctx.buf;
+ uint8_t *tmp;
+ int i;
+
+ memset(key_pad, mask, SHA256_BLOCK_SIZE);
+ for (i = 0; i < key_len; i++)
+ key_pad[i] ^= key[i];
+
+ SHA256_init(&hmac_ctx);
+ SHA256_update(&hmac_ctx, key_pad, SHA256_BLOCK_SIZE);
+ SHA256_update(&hmac_ctx, data, data_len);
+ tmp = SHA256_final(&hmac_ctx);
+ memcpy(output, tmp, SHA256_DIGEST_SIZE);
+}
+/*
+ * Note: When the API is called, it will consume about half of TASK_STACK_SIZE
+ * because a variable of structure sha256_ctx is declared in the function
+ * hmac_SHA256_step.
+ */
+void hmac_SHA256(uint8_t *output, const uint8_t *key, const int key_len,
+ const uint8_t *message, const int message_len)
+{
+ /* This code does not support key_len > block_size. */
+ ASSERT(key_len <= SHA256_BLOCK_SIZE);
+
+ /*
+ * i_key_pad = key (zero-padded) ^ 0x36
+ * output = hash(i_key_pad || message)
+ * (Use output as temporary buffer)
+ */
+ hmac_SHA256_step(output, 0x36, key, key_len, message, message_len);
+
+ /*
+ * o_key_pad = key (zero-padded) ^ 0x5c
+ * output = hash(o_key_pad || output)
+ */
+ hmac_SHA256_step(output, 0x5c, key, key_len, output,
+ SHA256_DIGEST_SIZE);
+}
diff --git a/chip/npcx/sha256_chip.h b/chip/npcx/sha256_chip.h
new file mode 100644
index 0000000000..3b9586d962
--- /dev/null
+++ b/chip/npcx/sha256_chip.h
@@ -0,0 +1,25 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_SHA256_CHIP_H
+#define __CROS_EC_SHA256_CHIP_H
+
+#include "common.h"
+
+#define NPCX_SHA256_HANDLE_SIZE 212
+struct sha256_ctx {
+ /* the context handle required for SHA256 API */
+ uint8_t handle[NPCX_SHA256_HANDLE_SIZE];
+ /*
+ * This is used to buffer:
+ * 1. the result (digest) of the SHA256 computation.
+ * 2. the 1st block input data (the key padding) for hmac_SHA256_step.
+ */
+ uint8_t buf[SHA256_BLOCK_SIZE];
+} __aligned(4);
+
+void SHA256_abort(struct sha256_ctx *ctx);
+
+#endif /* __CROS_EC_SHA256_CHIP_H */
diff --git a/common/build.mk b/common/build.mk
index ebaa3cc582..e0350eefb3 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -124,7 +124,13 @@ common-$(CONFIG_ONLINE_CALIB)+=stillness_detector.o kasa.o math_util.o \
mat44.o vec3.o newton_fit.o accel_cal.o online_calibration.o \
mkbp_event.o mag_cal.o math_util.o mat33.o gyro_cal.o gyro_still_det.o
common-$(CONFIG_SHA1)+= sha1.o
-common-$(CONFIG_SHA256)+=sha256.o
+ifeq ($(CONFIG_SHA256),y)
+# use the standard software SHA256 lib if the chip cannot support SHA256
+# hardware accelerator.
+ifeq ($(CONFIG_SHA256_HW_ACCELERATE),)
+common-y+=sha256.o
+endif
+endif
common-$(CONFIG_SOFTWARE_CLZ)+=clz.o
common-$(CONFIG_SOFTWARE_CTZ)+=ctz.o
common-$(CONFIG_CMD_SPI_XFER)+=spi_commands.o
@@ -160,7 +166,14 @@ common-$(CONFIG_USB_UPDATE)+=usb_update.o update_fw.o
common-$(CONFIG_USBC_PPC)+=usbc_ppc.o
common-$(CONFIG_VBOOT_EFS)+=vboot/vboot.o
common-$(CONFIG_VBOOT_EFS2)+=vboot/efs2.o
-common-$(CONFIG_VBOOT_HASH)+=sha256.o vboot_hash.o
+ifeq ($(CONFIG_VBOOT_HASH),y)
+common-y+=vboot_hash.o
+# use the standard software SHA256 lib if the chip cannot support SHA256
+# hardware accelerator.
+ifeq ($(CONFIG_SHA256_HW_ACCELERATE),)
+common-y+=sha256.o
+endif
+endif
common-$(CONFIG_VOLUME_BUTTONS)+=button.o
common-$(CONFIG_VSTORE)+=vstore.o
common-$(CONFIG_WEBUSB_URL)+=webusb_desc.o
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index a08c707630..e3bdf9e6fd 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -67,6 +67,9 @@ void vboot_hash_abort(void)
want_abort = 0;
data_size = 0;
hash = NULL;
+#ifdef CONFIG_SHA256_HW_ACCELERATE
+ SHA256_abort(&ctx);
+#endif
}
}
diff --git a/include/config.h b/include/config.h
index 1921828c70..612afacad7 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3334,6 +3334,9 @@
/* Support computing of other hash sizes (without the VBOOT code) */
#undef CONFIG_SHA256
+/* Compute SHA256 by using chip's hardware accelerator */
+#undef CONFIG_SHA256_HW_ACCELERATE
+
/* Unroll some loops in SHA256_transform for better performance. */
#undef CONFIG_SHA256_UNROLLED
diff --git a/include/sha256.h b/include/sha256.h
index 6671c0ae3a..130a666788 100644
--- a/include/sha256.h
+++ b/include/sha256.h
@@ -13,6 +13,13 @@
#define SHA256_DIGEST_SIZE 32
#define SHA256_BLOCK_SIZE 64
+#ifdef CONFIG_SHA256_HW_ACCELERATE
+/*
+ * The chip's header file must implement the SHA256 context structure and
+ * specific functions for its hardware accelerator module.
+ */
+#include "sha256_chip.h"
+#else
/* SHA256 context */
struct sha256_ctx {
uint32_t h[8];
@@ -21,6 +28,7 @@ struct sha256_ctx {
uint8_t block[2 * SHA256_BLOCK_SIZE];
uint8_t buf[SHA256_DIGEST_SIZE]; /* Used to store the final digest. */
};
+#endif
void SHA256_init(struct sha256_ctx *ctx);
void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len);