summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-08-12 17:55:22 -0700
committerCommit Bot <commit-bot@chromium.org>2021-08-16 18:21:47 +0000
commit994efaeb57aaa023e38b547ceede69930ed687fc (patch)
tree464ba8c9c37dfccb8e7359b83b00618bebf4554a
parent5d24282d7db3854c4a6adf925c75b7573de5617d (diff)
downloadchrome-ec-stabilize-14163.B-cr50_stab.tar.gz
cr50: final touches to remove cryptoc dependencystabilize-14163.B-cr50_stab
To implement FIPS module we need to bring many crypto functions in the module boundary. Unfortunately, cryptoc is a third-party library used by dcrypto code in cr50. Cryptoc is also not well-maintained and shared with other projects. While just making local copy of cryptoc would solve an issue, it's suboptimal as prevents from many optimizations and improvements. 1. Clean-up of #include dependencies on cryptoc 2. Build configuration drops linking with cryptoc for cr50 3. Dcrypto SHA512 code updated to compile and partially tested. It is about 4x faster on large messages, and about 620 bytes larger. Added an config option to use Dcrypto version as software, but not enabled. More testing is needed to make sure it's safe and doesn't have unintended interactions with RSA and ECDSA Dcrypto code. BUG=b:138578318 TEST=make BOARD=cr50 CRYPTO_TEST=1; tpm_test Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: I030b60b75daeec9c8ef079017a73345829bf7f0b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3093093 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/board.h13
-rw-r--r--board/cr50/build.mk15
-rw-r--r--board/cr50/dcrypto/dcrypto_sha512.c267
-rw-r--r--board/cr50/dcrypto/hmac_sw.c2
-rw-r--r--board/cr50/dcrypto/hmacsha2.h28
-rw-r--r--board/cr50/dcrypto/p256_ecies.c10
-rw-r--r--board/cr50/dcrypto/sha512.c20
-rw-r--r--board/cr50/fips_rand.c1
-rw-r--r--board/cr50/tpm2/rsa.c1
-rw-r--r--chip/g/build.mk4
-rw-r--r--chip/g/flash.c1
-rw-r--r--chip/g/upgrade_fw.c1
-rw-r--r--include/config.h14
13 files changed, 262 insertions, 115 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 7a73753260..4d886da85d 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -164,6 +164,19 @@
#define CONFIG_UPTO_SHA512
#define CONFIG_DCRYPTO_RSA_SPEEDUP
+/**
+ * Make sw version equal to hw. Unlike SHA2-256, dcrypto implementation
+ * of SHA2-512/384 allows to save context, so can fully replace software
+ * implementation.
+ */
+#define CONFIG_SHA512_HW_EQ_SW
+
+/* Don't link with third_party/cryptoc. */
+#undef CONFIG_LIBCRYPTOC
+
+/* Don't use DCRYPTO code from chip/g. */
+#undef CONFIG_DCRYPTO
+
/* Implement custom udelay, due to usec hwtimer imprecision. */
#define CONFIG_HW_SPECIFIC_UDELAY
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index ed45ca2963..e3b2555a8d 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -32,10 +32,15 @@ else
# Need to generate a .hex file
all: hex
-# The simulator components have their own subdirectory
+ifeq ($(CONFIG_DCRYPTO_BOARD),y)
+# chip/g/build.mk also adds chip/g/dcrypto for CONFIG_DCRYPTO
+# so, only add it if we build RW with CONFIG_DCRYPTO_BOARD
CFLAGS += -I$(realpath $(BDIR)/dcrypto)
-CFLAGS += -I$(realpath $(BDIR)/tpm2)
dirs-y += $(BDIR)/dcrypto
+endif
+
+# The simulator components have their own subdirectory
+CFLAGS += -I$(realpath $(BDIR)/tpm2)
dirs-y += $(BDIR)/tpm2
# Objects that we need to build
@@ -53,7 +58,6 @@ board-${CONFIG_USB_SPI_V2} += usb_spi.o
board-${CONFIG_USB_I2C} += usb_i2c.o
board-y += recovery_button.o
-# TODO(mruthven): add cryptoc the fips boundary
fips-y=
fips-y += fips.o
fips-y += fips_rand.o
@@ -82,7 +86,12 @@ fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha256.o
ifeq ($(CONFIG_UPTO_SHA512),y)
ifeq ($(CONFIG_DCRYPTO_SHA512),y)
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/dcrypto_sha512.o
+# we may still want to have software implementation
+ifneq ($(CONFIG_SHA512_HW_EQ_SW),y)
+fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha512.o
+endif
else
+# only software version
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha512.o
endif
endif
diff --git a/board/cr50/dcrypto/dcrypto_sha512.c b/board/cr50/dcrypto/dcrypto_sha512.c
index bb404b28d7..271b46ec9c 100644
--- a/board/cr50/dcrypto/dcrypto_sha512.c
+++ b/board/cr50/dcrypto/dcrypto_sha512.c
@@ -7,8 +7,6 @@
#include "internal.h"
#include "registers.h"
-#include "cryptoc/sha512.h"
-
#ifdef CRYPTO_TEST_SETUP
/* test and benchmark */
@@ -16,6 +14,7 @@
#include "console.h"
#include "hooks.h"
#include "task.h"
+#include "watchdog.h"
#define cyclecounter() GREG32(M3, DWT_CYCCNT)
#define START_PROFILE(x) \
@@ -499,8 +498,8 @@ static void dcrypto_SHA512_setup(void)
dcrypto_imem_load(0, IMEM_dcrypto, ARRAY_SIZE(IMEM_dcrypto));
}
-static void dcrypto_SHA512_Transform(LITE_SHA512_CTX *ctx, const uint32_t *buf,
- size_t nwords)
+static void dcrypto_SHA512_Transform(struct sha512_ctx *ctx,
+ const uint32_t *buf, size_t nwords)
{
int result = 0;
struct DMEM_sha512 *p512 =
@@ -543,12 +542,11 @@ static void dcrypto_SHA512_Transform(LITE_SHA512_CTX *ctx, const uint32_t *buf,
END_PROFILE(t_transform)
}
-static void dcrypto_SHA512_update(LITE_SHA512_CTX *ctx, const void *data,
- size_t len)
+void SHA512_hw_update(struct sha512_ctx *ctx, const void *data, size_t len)
{
- int i = (int) (ctx->count & (sizeof(ctx->buf) - 1));
- const uint8_t *p = (const uint8_t *) data;
- uint8_t *d = &ctx->buf[i];
+ int i = (int)(ctx->count & (sizeof(ctx->b8) - 1));
+ const uint8_t *p = (const uint8_t *)data;
+ uint8_t *d = &ctx->b8[i];
ctx->count += len;
@@ -556,28 +554,27 @@ static void dcrypto_SHA512_update(LITE_SHA512_CTX *ctx, const void *data,
dcrypto_SHA512_setup();
/* Take fast path for 32-bit aligned 1KB inputs */
- if (i == 0 && len == 1024 && (((intptr_t) data) & 3) == 0) {
- dcrypto_SHA512_Transform(ctx, (const uint32_t *) data, 8 * 32);
+ if (i == 0 && len == 1024 && (((intptr_t)data) & 3) == 0) {
+ dcrypto_SHA512_Transform(ctx, (const uint32_t *)data, 8 * 32);
} else {
- if (len <= sizeof(ctx->buf) - i) {
+ if (len <= sizeof(ctx->b8) - i) {
memcpy(d, p, len);
- if (len == sizeof(ctx->buf) - i) {
+ if (len == sizeof(ctx->b8) - i) {
dcrypto_SHA512_Transform(
- ctx, (uint32_t *) (ctx->buf), 32);
+ ctx, (uint32_t *)(ctx->b8), 32);
}
} else {
- memcpy(d, p, sizeof(ctx->buf) - i);
- dcrypto_SHA512_Transform(ctx, (uint32_t *) (ctx->buf),
- 32);
- d = ctx->buf;
- len -= (sizeof(ctx->buf) - i);
- p += (sizeof(ctx->buf) - i);
- while (len >= sizeof(ctx->buf)) {
- memcpy(d, p, sizeof(ctx->buf));
- p += sizeof(ctx->buf);
- len -= sizeof(ctx->buf);
+ memcpy(d, p, sizeof(ctx->b8) - i);
+ dcrypto_SHA512_Transform(ctx, ctx->b32, 32);
+ d = ctx->b8;
+ len -= (sizeof(ctx->b8) - i);
+ p += (sizeof(ctx->b8) - i);
+ while (len >= sizeof(ctx->b8)) {
+ memcpy(d, p, sizeof(ctx->b8));
+ p += sizeof(ctx->b8);
+ len -= sizeof(ctx->b8);
dcrypto_SHA512_Transform(
- ctx, (uint32_t *) (ctx->buf), 32);
+ ctx, (uint32_t *)(ctx->b8), 32);
}
/* Leave remainder in ctx->buf */
memcpy(d, p, len);
@@ -586,11 +583,11 @@ static void dcrypto_SHA512_update(LITE_SHA512_CTX *ctx, const void *data,
dcrypto_unlock();
}
-static const uint8_t *dcrypto_SHA512_final(LITE_SHA512_CTX *ctx)
+struct sha512_digest *SHA512_hw_final(struct sha512_ctx *ctx)
{
uint64_t cnt = ctx->count * 8;
- int i = (int) (ctx->count & (sizeof(ctx->buf) - 1));
- uint8_t *p = &ctx->buf[i];
+ int i = (int) (ctx->count & (sizeof(ctx->b8) - 1));
+ uint8_t *p = &ctx->b8[i];
*p++ = 0x80;
i++;
@@ -598,15 +595,15 @@ static const uint8_t *dcrypto_SHA512_final(LITE_SHA512_CTX *ctx)
dcrypto_init_and_lock();
dcrypto_SHA512_setup();
- if (i > sizeof(ctx->buf) - 16) {
- memset(p, 0, sizeof(ctx->buf) - i);
- dcrypto_SHA512_Transform(ctx, (uint32_t *) (ctx->buf), 32);
+ if (i > sizeof(ctx->b8) - 16) {
+ memset(p, 0, sizeof(ctx->b8) - i);
+ dcrypto_SHA512_Transform(ctx, ctx->b32, 32);
i = 0;
- p = ctx->buf;
+ p = ctx->b8;
}
- memset(p, 0, sizeof(ctx->buf) - 8 - i);
- p += sizeof(ctx->buf) - 8 - i;
+ memset(p, 0, sizeof(ctx->b8) - 8 - i);
+ p += sizeof(ctx->b8) - 8 - i;
for (i = 0; i < 8; ++i) {
uint8_t tmp = (uint8_t)(cnt >> 56);
@@ -614,9 +611,9 @@ static const uint8_t *dcrypto_SHA512_final(LITE_SHA512_CTX *ctx)
*p++ = tmp;
}
- dcrypto_SHA512_Transform(ctx, (uint32_t *) (ctx->buf), 32);
+ dcrypto_SHA512_Transform(ctx, ctx->b32, 32);
- p = ctx->buf;
+ p = ctx->b8;
for (i = 0; i < 8; i++) {
uint64_t tmp = ctx->state[i];
*p++ = (uint8_t)(tmp >> 56);
@@ -630,40 +627,138 @@ static const uint8_t *dcrypto_SHA512_final(LITE_SHA512_CTX *ctx)
}
dcrypto_unlock();
- return ctx->buf;
+ return &ctx->digest;
}
-const uint8_t *DCRYPTO_SHA512_hash(const void *data, size_t len,
- uint8_t *digest)
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha512_ctx));
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha384_ctx));
+
+static void SHA512_hw_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA512_hw_init);
+
+static void SHA384_hw_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA384_hw_init);
+
+static void SHA512_hw_update_as_hash(union hash_ctx *const ctx,
+ const void *data, size_t len)
+ __alias(SHA512_hw_update);
+
+static const union sha_digests *SHA512_final_as_hash(union hash_ctx *const ctx)
+ __alias(SHA512_hw_final);
+
+void SHA384_hw_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA512_hw_update);
+
+const struct sha384_digest *SHA384_hw_final(struct sha384_ctx *const ctx)
+ __alias(SHA512_hw_final);
+
+const struct sha512_digest *SHA512_hw_hash(const void *data, size_t len,
+ struct sha512_digest *digest)
{
- LITE_SHA512_CTX ctx;
+ struct sha512_ctx ctx;
- DCRYPTO_SHA512_init(&ctx);
- dcrypto_SHA512_update(&ctx, data, len);
- memcpy(digest, dcrypto_SHA512_final(&ctx), SHA512_DIGEST_SIZE);
+ SHA512_hw_init(&ctx);
+ SHA512_hw_update(&ctx, data, len);
+ memcpy(digest, SHA512_hw_final(&ctx), SHA512_DIGEST_SIZE);
return digest;
}
-static const HASH_VTAB dcrypto_SHA512_VTAB = {
- DCRYPTO_SHA512_init, dcrypto_SHA512_update, dcrypto_SHA512_final,
- DCRYPTO_SHA512_hash, SHA512_DIGEST_SIZE};
-
-void DCRYPTO_SHA512_init(LITE_SHA512_CTX *ctx)
+void SHA512_hw_init(struct sha512_ctx *ctx)
{
- SHA512_init(ctx);
+ static const struct hash_vtable dcrypto_SHA512_VTAB = {
+ SHA512_hw_init_as_hash, SHA512_hw_update_as_hash,
+ SHA512_final_as_hash, HMAC_sw_final,
+ SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE,
+ sizeof(struct sha512_ctx)
+ };
+ static const uint64_t sha512_init[SHA512_DIGEST_DWORDS] = {
+ 0x6a09e667f3bcc908ll, 0xbb67ae8584caa73bll,
+ 0x3c6ef372fe94f82bll, 0xa54ff53a5f1d36f1ll,
+ 0x510e527fade682d1ll, 0x9b05688c2b3e6c1fll,
+ 0x1f83d9abfb41bd6bll, 0x5be0cd19137e2179ll
+ };
+
+ memcpy(ctx->state, sha512_init, sizeof(ctx->state));
+ ctx->count = 0;
ctx->f = &dcrypto_SHA512_VTAB;
}
+const struct sha384_digest *SHA384_hw_hash(const void *data, size_t len,
+ struct sha384_digest *digest)
+{
+ struct sha384_ctx ctx;
+
+ SHA384_hw_init(&ctx);
+ SHA384_hw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA384_hw_final(&ctx)->b8, SHA384_DIGEST_SIZE);
+ return digest;
+}
+
+void SHA384_hw_init(struct sha512_ctx *ctx)
+{
+ static const struct hash_vtable dcrypto_SHA384_VTAB = {
+ SHA384_hw_init_as_hash, SHA512_hw_update_as_hash,
+ SHA512_final_as_hash, HMAC_sw_final,
+ SHA384_DIGEST_SIZE, SHA512_BLOCK_SIZE,
+ sizeof(struct sha384_ctx)
+ };
+ static const uint64_t sha384_init[SHA512_DIGEST_DWORDS] = {
+ 0xcbbb9d5dc1059ed8ll, 0x629a292a367cd507ll,
+ 0x9159015a3070dd17ll, 0x152fecd8f70e5939ll,
+ 0x67332667ffc00b31ll, 0x8eb44a8768581511ll,
+ 0xdb0c2e0d64f98fa7ll, 0x47b5481dbefa4fa4ll
+ };
+
+ memcpy(ctx->state, sha384_init, sizeof(ctx->state));
+
+ ctx->count = 0;
+ ctx->f = &dcrypto_SHA384_VTAB;
+}
+
+#if defined(CONFIG_SHA512_HW_EQ_SW)
+/**
+ * Make sw version equal to hw. Unlike SHA2-256, dcrypto implementation
+ * of SHA2-512/384 allows to save context, so can fully replace software
+ * implementation.
+ */
+const struct sha512_digest *SHA512_sw_hash(const void *data, size_t len,
+ struct sha512_digest *digest)
+ __alias(SHA512_hw_hash);
+
+
+void SHA512_sw_init(struct sha512_ctx *const ctx) __alias(SHA512_hw_init);
+
+void SHA512_sw_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA512_hw_update);
+
+const struct sha512_digest *SHA512_sw_final(struct sha512_ctx *const ctx)
+ __alias(SHA512_hw_final);
+
+
+const struct sha384_digest *SHA384_sw_hash(const void *data, size_t len,
+ struct sha384_digest *digest)
+ __alias(SHA384_hw_hash);
+
+void SHA384_sw_init(struct sha384_ctx *const ctx) __alias(SHA384_hw_init);
+
+void SHA384_sw_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA384_hw_update);
+
+const struct sha384_digest *SHA384_sw_final(struct sha384_ctx *const ctx)
+ __alias(SHA384_hw_final);
+
+#endif
+
#ifdef CRYPTO_TEST_SETUP
static uint32_t msg[256]; // 1KB
static int msg_len;
static int msg_loops;
-static LITE_SHA512_CTX sw;
-static LITE_SHA512_CTX hw;
-static const uint8_t *sw_digest;
-static const uint8_t *hw_digest;
+static struct sha512_ctx sw;
+static struct sha512_ctx hw;
+static const struct sha512_digest *sw_digest;
+static const struct sha512_digest *hw_digest;
static uint32_t t_sw;
static uint32_t t_hw;
@@ -677,40 +772,38 @@ static void run_sha512_cmd(void)
t_hw = 0;
START_PROFILE(t_sw)
- SHA512_init(&sw);
+ SHA512_sw_init(&sw);
for (i = 0; i < msg_loops; ++i) {
- HASH_update(&sw, msg, msg_len);
+ SHA512_update(&sw, msg, msg_len);
}
- sw_digest = HASH_final(&sw);
+ sw_digest = SHA512_final(&sw);
END_PROFILE(t_sw)
+ watchdog_reload();
+
START_PROFILE(t_hw)
- DCRYPTO_SHA512_init(&hw);
+ SHA512_hw_init(&hw);
for (i = 0; i < msg_loops; ++i) {
- HASH_update(&hw, msg, msg_len);
+ SHA512_update(&hw, msg, msg_len);
}
- hw_digest = HASH_final(&hw);
+ hw_digest = SHA512_final(&hw);
END_PROFILE(t_hw)
+ watchdog_reload();
+
ccprintf("sw(%u):\n", t_sw);
- for (i = 0; i < 64; ++i)
- ccprintf("%02x", sw_digest[i]);
+ for (i = 0; i < SHA512_DIGEST_SIZE; ++i)
+ ccprintf("%02x", sw_digest->b8[i]);
ccprintf("\n");
ccprintf("hw(%u/%u/%u):\n", t_hw, t_transform, t_dcrypto);
- for (i = 0; i < 64; ++i)
- ccprintf("%02x", hw_digest[i]);
+ for (i = 0; i < SHA512_DIGEST_SIZE; ++i)
+ ccprintf("%02x", hw_digest->b8[i]);
ccprintf("\n");
-
- task_set_event(TASK_ID_CONSOLE, TASK_EVENT_CUSTOM_BIT(0), 0);
}
-DECLARE_DEFERRED(run_sha512_cmd);
static int cmd_sha512_bench(int argc, char *argv[])
{
- const int max_time = 1000000;
- uint32_t events;
-
memset(msg, '!', sizeof(msg));
if (argc > 1) {
@@ -722,33 +815,28 @@ static int cmd_sha512_bench(int argc, char *argv[])
msg_len = sizeof(msg);
}
- hook_call_deferred(&run_sha512_cmd_data, 0);
- ccprintf("Will wait up to %d ms\n", (max_time + 500) / 1000);
-
- events = task_wait_event_mask(TASK_EVENT_CUSTOM_BIT(0), max_time);
- if (!(events & TASK_EVENT_CUSTOM_BIT(0))) {
- ccprintf("Timed out, you might want to reboot...\n");
- return EC_ERROR_TIMEOUT;
- }
+ run_sha512_cmd();
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(sha512_bench, cmd_sha512_bench, NULL, NULL);
-static void run_sha512_test(void)
+static int cmd_sha512_test(int argc, char *argv[])
{
- int i;
+ size_t i;
+
+ ccprintf("sha512 self-test started!\n");
for (i = 0; i < 129; ++i) {
memset(msg, i, i);
+ watchdog_reload();
+ SHA512_sw_init(&sw);
+ SHA512_update(&sw, msg, i);
+ sw_digest = SHA512_final(&sw);
- SHA512_init(&sw);
- HASH_update(&sw, msg, i);
- sw_digest = HASH_final(&sw);
-
- DCRYPTO_SHA512_init(&hw);
- HASH_update(&hw, msg, i);
- hw_digest = HASH_final(&hw);
+ SHA512_hw_init(&hw);
+ SHA512_update(&hw, msg, i);
+ hw_digest = SHA512_final(&hw);
if (memcmp(sw_digest, hw_digest, SHA512_DIGEST_SIZE) != 0) {
ccprintf("sha512 self-test fail at %d!\n", i);
@@ -757,14 +845,7 @@ static void run_sha512_test(void)
}
ccprintf("sha512 self-test PASS!\n");
- task_set_event(TASK_ID_CONSOLE, TASK_EVENT_CUSTOM_BIT(0), 0);
-}
-DECLARE_DEFERRED(run_sha512_test);
-static int cmd_sha512_test(int argc, char *argv[])
-{
- hook_call_deferred(&run_sha512_test_data, 0);
- task_wait_event_mask(TASK_EVENT_CUSTOM_BIT(0), 1000000);
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(sha512_test, cmd_sha512_test, NULL, NULL);
diff --git a/board/cr50/dcrypto/hmac_sw.c b/board/cr50/dcrypto/hmac_sw.c
index 91e056546d..3e62906540 100644
--- a/board/cr50/dcrypto/hmac_sw.c
+++ b/board/cr50/dcrypto/hmac_sw.c
@@ -8,8 +8,6 @@
#include <stdint.h>
-#include "cryptoc/util.h"
-
/**
* Generic software HMAC support for any type of hash.
*/
diff --git a/board/cr50/dcrypto/hmacsha2.h b/board/cr50/dcrypto/hmacsha2.h
index 6d9c842c1e..45e5245a65 100644
--- a/board/cr50/dcrypto/hmacsha2.h
+++ b/board/cr50/dcrypto/hmacsha2.h
@@ -302,8 +302,8 @@ static inline const struct sha1_digest *SHA1_final(struct sha1_ctx *const ctx)
return &ctx->f->final((union hash_ctx *)ctx)->sha1;
}
-static inline const struct sha256_digest *
-SHA256_final(struct sha256_ctx *const ctx)
+static inline const struct sha256_digest *SHA256_final(
+ struct sha256_ctx *const ctx)
{
return &ctx->f->final((union hash_ctx *)ctx)->sha256;
}
@@ -448,6 +448,30 @@ const struct sha512_digest *SHA512_sw_final(struct sha512_ctx *ctx);
const struct sha512_digest *SHA512_sw_hash(const void *data, size_t len,
struct sha512_digest *digest);
+static inline void SHA384_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+
+static inline const struct sha384_digest *SHA384_final(
+ struct sha384_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha384;
+}
+
+static inline void SHA512_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+
+static inline const struct sha512_digest *SHA512_final(
+ struct sha512_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha512;
+}
+
/**
* HMAC SHA2-384 initialization.
*/
diff --git a/board/cr50/dcrypto/p256_ecies.c b/board/cr50/dcrypto/p256_ecies.c
index d5afb2edbc..250e6e5aaf 100644
--- a/board/cr50/dcrypto/p256_ecies.c
+++ b/board/cr50/dcrypto/p256_ecies.c
@@ -9,8 +9,6 @@
#include "trng.h"
#include "util.h"
-#include "cryptoc/sha256.h"
-
#define AES_KEY_BYTES 16
#define HMAC_KEY_BYTES 32
@@ -38,7 +36,7 @@ size_t DCRYPTO_ecies_encrypt(
uint8_t key[AES_KEY_BYTES + HMAC_KEY_BYTES];
const uint8_t *aes_key;
const uint8_t *hmac_key;
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
uint8_t *outp = out;
uint8_t *ciphertext;
@@ -98,7 +96,7 @@ size_t DCRYPTO_ecies_encrypt(
/* Calculate HMAC(auth_data || ciphertext). */
HMAC_SHA256_hw_init(&ctx, hmac_key, HMAC_KEY_BYTES);
- HASH_update(&ctx.hash, outp, in_len);
+ HMAC_SHA256_update(&ctx, outp, in_len);
outp += in_len;
memcpy(outp, HMAC_SHA256_hw_final(&ctx), SHA256_DIGEST_SIZE);
outp += SHA256_DIGEST_SIZE;
@@ -120,7 +118,7 @@ size_t DCRYPTO_ecies_decrypt(
uint8_t key[AES_KEY_BYTES + HMAC_KEY_BYTES];
const uint8_t *aes_key;
const uint8_t *hmac_key;
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
const uint8_t *inp = in;
uint8_t *outp = out;
@@ -159,7 +157,7 @@ size_t DCRYPTO_ecies_decrypt(
aes_key = &key[0];
hmac_key = &key[AES_KEY_BYTES];
HMAC_SHA256_hw_init(&ctx, hmac_key, HMAC_KEY_BYTES);
- HASH_update(&ctx.hash, inp, in_len);
+ HMAC_SHA256_update(&ctx, inp, in_len);
if (!DCRYPTO_equals(inp + in_len, HMAC_SHA256_hw_final(&ctx),
SHA256_DIGEST_SIZE))
return 0;
diff --git a/board/cr50/dcrypto/sha512.c b/board/cr50/dcrypto/sha512.c
index 31b0d47c1a..07ba988422 100644
--- a/board/cr50/dcrypto/sha512.c
+++ b/board/cr50/dcrypto/sha512.c
@@ -242,6 +242,7 @@ const struct sha384_digest *SHA384_sw_hash(const void *data, size_t len,
return digest;
}
+#if defined(CONFIG_SHA512_HW_EQ_SW) || !defined(CONFIG_DCRYPTO_SHA512)
/**
* We don't support HW-accelerated SHA384/SHA512 yet, so alias it to software.
*/
@@ -249,9 +250,26 @@ const struct sha512_digest *SHA512_hw_hash(const void *data, size_t len,
struct sha512_digest *digest)
__alias(SHA512_sw_hash);
+
+void SHA512_hw_init(struct sha512_ctx *const ctx) __alias(SHA512_sw_init);
+
+void SHA512_hw_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA512_sw_update);
+
+const struct sha512_digest *SHA512_hw_final(struct sha512_ctx *const ctx)
+ __alias(SHA512_sw_final);
+
+
const struct sha384_digest *SHA384_hw_hash(const void *data, size_t len,
struct sha384_digest *digest)
__alias(SHA384_sw_hash);
-void SHA512_hw_init(struct sha512_ctx *const ctx) __alias(SHA512_sw_init);
void SHA384_hw_init(struct sha384_ctx *const ctx) __alias(SHA384_sw_init);
+
+void SHA384_hw_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA384_sw_update);
+
+const struct sha384_digest *SHA384_hw_final(struct sha384_ctx *const ctx)
+ __alias(SHA384_sw_final);
+
+#endif
diff --git a/board/cr50/fips_rand.c b/board/cr50/fips_rand.c
index a214f9196e..85ffa9ef6c 100644
--- a/board/cr50/fips_rand.c
+++ b/board/cr50/fips_rand.c
@@ -4,7 +4,6 @@
*/
#include "console.h"
-#include "cryptoc/util.h"
#include "fips.h"
#include "fips_rand.h"
#include "flash_log.h"
diff --git a/board/cr50/tpm2/rsa.c b/board/cr50/tpm2/rsa.c
index 9d15d66823..f40996c9f5 100644
--- a/board/cr50/tpm2/rsa.c
+++ b/board/cr50/tpm2/rsa.c
@@ -10,7 +10,6 @@
#include "dcrypto.h"
#include "trng.h"
-#include "cryptoc/util.h"
#include <assert.h>
diff --git a/chip/g/build.mk b/chip/g/build.mk
index 80bc997b59..4d9bd6f7b8 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -13,8 +13,11 @@ CPPFLAGS += -I$(abspath .)
CPPFLAGS += -I$(abspath ./builtin)
CPPFLAGS += -I$(abspath ./chip/$(CHIP))
CPPFLAGS += -I$(INCLUDE_ROOT)
+dirs-y += chip/g/dcrypto
endif
+CPPFLAGS += -I$(realpath ../../third_party/cryptoc/include)
+
# Required chip modules
chip-y = clock.o gpio.o hwtimer.o pre_init.o system.o
chip-$(CONFIG_BOARD_ID_SUPPORT) += board_id.o
@@ -90,7 +93,6 @@ chip-$(CONFIG_I2C_PERIPH)+= i2cp.o
chip-$(CONFIG_LOW_POWER_IDLE)+=idle.o
chip-$(CONFIG_FLASH_PHYSICAL) += flash.o
-dirs-y += chip/g/dcrypto
ifneq ($(CONFIG_CUSTOMIZED_RO),)
custom-ro_objs-y = chip/g/clock.o
diff --git a/chip/g/flash.c b/chip/g/flash.c
index ba0e9459ae..c3b3753e4a 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -41,7 +41,6 @@
#include "common.h"
#include "board_id.h"
#include "console.h"
-#include "cryptoc/util.h"
#include "extension.h"
#include "flash.h"
#include "flash_log.h"
diff --git a/chip/g/upgrade_fw.c b/chip/g/upgrade_fw.c
index 9bbf796f0b..ca1043b22a 100644
--- a/chip/g/upgrade_fw.c
+++ b/chip/g/upgrade_fw.c
@@ -9,7 +9,6 @@
#include "byteorder.h"
#include "compile_time_macros.h"
#include "console.h"
-#include "cryptoc/sha.h"
#include "dcrypto/dcrypto.h"
#include "extension.h"
#include "flash.h"
diff --git a/include/config.h b/include/config.h
index bc183476ac..8914c92725 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1374,16 +1374,24 @@
#undef CONFIG_DCRYPTO_RSA_SPEEDUP
/*
- * When enabled, accelerate sha512 using the generic crypto engine;
- * only supported on CR50
+ * When enabled, accelerate sha512/384 using the generic crypto engine;
+ * only supported on CR50. It is about 4x faster, but ~620 bytes larger.
*/
#undef CONFIG_DCRYPTO_SHA512
/*
- * When enabled build support for SHA-384/512, requires CONFIG_DCRYPTO.
+ * When enabled build support for SHA-384/512, requires CONFIG_DCRYPTO or
+ * CONFIG_DCRYPTO_BOARD.
*/
#undef CONFIG_UPTO_SHA512
+/**
+ * Make sw version of SHA2-512/384 equal to hw(dcrypto).
+ * Unlike SHA2-256, dcrypto implementation of SHA2-512/384 allows to save
+ * context, so can fully replace software implementation.
+ */
+#undef CONFIG_SHA512_HW_EQ_SW
+
/*
* When enabled ignore version et al during fw upgrade for chip/g.
*/