summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-08-26 14:57:06 -0700
committerCommit Bot <commit-bot@chromium.org>2021-08-31 17:06:06 +0000
commit8ddc58e3ce801e2ce72e78fc28bf026436dc22b2 (patch)
tree2547ea394f34b70c81b9470475998a7e1d04d9ca
parent6b7b22bc5abf09c823451f12b50559c197ed6c32 (diff)
downloadchrome-ec-8ddc58e3ce801e2ce72e78fc28bf026436dc22b2.tar.gz
cr50: merge crypto_enabled() and fips_crypto_allowed()
We need to block access to all crypto in case of FIPS errors. There are multiple steps to implement, this is one of few. There is common API crypto_enabled() which is used by nvmem and some other functions to check wherever access to crypto is possible. This is same intent as fips_crypto_allowed(), though the latter checks for FIPS KAT errors, while the former checks only key ladder status. Here we make all FIPS errors to revoke access from key ladder, and fips_crypto_allowed() to check key ladder status. This way we also ensure that in case of FIPS errors access to device secrets will be blocked. We moved crypto_api.c from chip/g to board/cr50 to move crypto_enabled() into fips.c and alias it to fips_crypto_enabled(). crypto_api.h is no longer included from dcrypto.h, and compile time assert for cipher salt size is moved to proper place. Since crypto is used by nvmem_init(), move FIPS power-up tests earlier to ensure nvmem_init() can access crypto. BUG=b:197893750 TEST=make CRYPTO_TEST=1; tpm_test; check nvmem is properly initialized on board_init(). Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: If70c2a21d61348bd97a47e26db5d8eec08bbf8ed Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3123836 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/board.c3
-rw-r--r--board/cr50/build.mk2
-rw-r--r--board/cr50/crypto_api.c34
-rw-r--r--board/cr50/dcrypto/app_cipher.c2
-rw-r--r--board/cr50/dcrypto/dcrypto.h6
-rw-r--r--board/cr50/fips.c32
-rw-r--r--board/cr50/fips.h7
-rw-r--r--chip/g/build.mk1
8 files changed, 68 insertions, 19 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 25768d15af..2679af3d86 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -890,6 +890,9 @@ static void board_init(void)
(GREG32(KEYMGR, HKEY_RWR7) == 0xaa66150f);
init_runlevel(PERMISSION_MEDIUM);
+
+ /* Run FIPS power-on tests to enable crypto. */
+ fips_power_on();
/* Initialize NvMem partitions */
nvmem_init();
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index e3b2555a8d..6bc3ba23a4 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -103,7 +103,7 @@ custom-board-ro_objs-${CONFIG_FIPS_UTIL} = $(BDIR)/dcrypto/util.o
# FIPS console and TPM2 commands are outside FIPS module
board-y += fips_cmd.o
-
+board-y += crypto_api.o
board-y += tpm2/NVMem.o
board-y += tpm2/aes.o
board-y += tpm2/ecc.o
diff --git a/board/cr50/crypto_api.c b/board/cr50/crypto_api.c
new file mode 100644
index 0000000000..9a9ed542ab
--- /dev/null
+++ b/board/cr50/crypto_api.c
@@ -0,0 +1,34 @@
+/* Copyright 2021 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.
+ */
+
+#include "crypto_api.h"
+#include "dcrypto.h"
+
+/**
+ * This file is mostly same as chip/g/crypto_api.c, but crypto_enabled()
+ * now is provided from fips.c and has different implementation.
+ */
+void app_compute_hash(const void *p_buf, size_t num_bytes, void *p_hash,
+ size_t hash_len)
+{
+ uint8_t sha1_digest[SHA_DIGEST_SIZE];
+
+ /*
+ * Use the built in dcrypto engine to generate the sha1 hash of the
+ * buffer.
+ */
+ DCRYPTO_SHA1_hash(p_buf, num_bytes, sha1_digest);
+
+ memcpy(p_hash, sha1_digest, MIN(hash_len, sizeof(sha1_digest)));
+
+ if (hash_len > sizeof(sha1_digest))
+ memset((uint8_t *)p_hash + sizeof(sha1_digest), 0,
+ hash_len - sizeof(sha1_digest));
+}
+
+int app_cipher(const void *salt, void *out, const void *in, size_t size)
+{
+ return DCRYPTO_app_cipher(NVMEM, salt, out, in, size);
+}
diff --git a/board/cr50/dcrypto/app_cipher.c b/board/cr50/dcrypto/app_cipher.c
index 125b443ee6..811d6feda1 100644
--- a/board/cr50/dcrypto/app_cipher.c
+++ b/board/cr50/dcrypto/app_cipher.c
@@ -3,6 +3,7 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#include "crypto_api.h"
#include "dcrypto.h"
#include "registers.h"
@@ -141,6 +142,7 @@ int DCRYPTO_app_cipher(enum dcrypto_appid appid, const void *salt,
/* Initialize key, and AES engine. */
uint32_t iv[4];
+ BUILD_ASSERT(sizeof(iv) == CIPHER_SALT_SIZE);
memcpy(iv, salt, sizeof(iv));
if (!aes_init(&ctx, appid, iv))
return 0;
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index ef3c778398..b94bbd7eb3 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -15,8 +15,6 @@ extern "C" {
#include "internal.h"
-#include "crypto_api.h"
-
#include <stddef.h>
enum cipher_mode {
@@ -396,10 +394,6 @@ void DCRYPTO_appkey_finish(struct APPKEY_CTX *ctx);
int DCRYPTO_appkey_derive(enum dcrypto_appid appid, const uint32_t input[8],
uint32_t output[8]);
-/* Number of bytes in the salt object. */
-#define DCRYPTO_CIPHER_SALT_SIZE 16
-BUILD_ASSERT(DCRYPTO_CIPHER_SALT_SIZE == CIPHER_SALT_SIZE);
-
/*
* Encrypt/decrypt a flat blob.
*
diff --git a/board/cr50/fips.c b/board/cr50/fips.c
index 19e6137d29..19cb78ff69 100644
--- a/board/cr50/fips.c
+++ b/board/cr50/fips.c
@@ -46,10 +46,15 @@ uint8_t fips_break_cmd;
#define fips_break_cmd 0
#endif
+/**
+ * Return true if no blocking crypto errors detected.
+ * Until self-integrity works properly (b/138578318), ignore it.
+ * TODO(b/138578318): remove ignoring of FIPS_FATAL_SELF_INTEGRITY.
+ */
static inline bool fips_is_no_crypto_error(void)
{
return (_fips_status &
- (FIPS_ERROR_MASK & (~FIPS_FATAL_SELF_INTEGRITY))) == 0;
+ (FIPS_ERROR_MASK & (~FIPS_FATAL_SELF_INTEGRITY))) == 0;
}
/* Return true if crypto can be used (no failures detected). */
@@ -58,11 +63,14 @@ bool fips_crypto_allowed(void)
/**
* We never allow crypto if there were errors, no matter
* if we are in FIPS approved or not-approved mode.
- * Until self-integrity works properly (b/138578318), ignore it.
- * TODO(b/138578318): remove ignoring of FIPS_FATAL_SELF_INTEGRITY.
*/
return ((_fips_status & FIPS_POWER_UP_TEST_DONE) &&
- fips_is_no_crypto_error());
+ fips_is_no_crypto_error() && DCRYPTO_ladder_is_enabled());
+}
+
+int crypto_enabled(void)
+{
+ return fips_crypto_allowed();
}
void fips_throw_err(enum fips_status err)
@@ -71,13 +79,15 @@ void fips_throw_err(enum fips_status err)
if ((_fips_status & err) == err)
return;
fips_set_status(err);
+ if (!fips_is_no_crypto_error()) {
#ifdef CONFIG_FLASH_LOG
- if (_fips_status & FIPS_ERROR_MASK) {
fips_vtable->flash_log_add_event(FE_LOG_FIPS_FAILURE,
sizeof(_fips_status),
&_fips_status);
- }
#endif
+ /* Revoke access to secrets in HW Key ladder. */
+ DCRYPTO_ladder_revoke();
+ }
}
/**
@@ -599,6 +609,10 @@ void fips_power_up_tests(void)
if (!fips_self_integrity())
_fips_status |= FIPS_FATAL_SELF_INTEGRITY;
+ /* Make sure hardware is properly configured. */
+ if (!DCRYPTO_ladder_is_enabled())
+ _fips_status |= FIPS_FATAL_OTHER;
+
/**
* Since we are very limited on stack and static RAM, acquire
* shared memory for KAT tests temporary larger stack.
@@ -672,8 +686,7 @@ void fips_power_up_tests(void)
fips_last_kat_test_duration = fips_vtable->get_time().val - starttime;
}
-/* Initialize FIPS mode. Executed during power-up and resume from sleep. */
-static void fips_power_on(void)
+void fips_power_on(void)
{
fips_last_kat_test_duration = -1ULL;
/* make sure on power-on / resume it's cleared */
@@ -695,9 +708,6 @@ static void fips_power_on(void)
}
-/* FIPS initialization is last init hook, HOOK_PRIO_FIPS > HOOK_PRIO_LAST */
-DECLARE_HOOK(HOOK_INIT, fips_power_on, HOOK_PRIO_INIT_FIPS);
-
const struct fips_vtable *fips_vtable;
/**
diff --git a/board/cr50/fips.h b/board/cr50/fips.h
index 13d78514d5..5a3a67997c 100644
--- a/board/cr50/fips.h
+++ b/board/cr50/fips.h
@@ -154,6 +154,13 @@ extern const struct fips_vtable *fips_vtable;
*/
void fips_set_callbacks(const struct fips_vtable *vtable);
+/**
+ * Run FIPS self-integrity, power-on and known-answer tests.
+ * Called from board_init() during power-up and resume from sleep.
+ * Enables crypto operation on successful completion.
+ */
+void fips_power_on(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/chip/g/build.mk b/chip/g/build.mk
index 4d9bd6f7b8..c5227412c3 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -31,7 +31,6 @@ chip-$(CONFIG_UART_BITBANG)+= uart_bitbang.o
endif # undef CONFIG_POLLING_UART
chip-$(CONFIG_DCRYPTO)+= crypto_api.o
-chip-$(CONFIG_DCRYPTO_BOARD)+= crypto_api.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/aes.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/aes_cmac.o