summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2022-01-28 19:57:45 -0800
committerCommit Bot <commit-bot@chromium.org>2022-01-31 23:21:40 +0000
commitff49166b382db46f31b8bf1be12196439bc90d02 (patch)
tree80fd99dfc52e8d98f732731a2405062fe9155d56
parent12d62b7996952bb8108af286e312481cecad02a1 (diff)
downloadchrome-ec-firmware-brya-14505.71.B-cr50_stab.tar.gz
1. ECDSA pair-wise consistency test failure wasn't updating FIPS status. Added new failure bit FIPS_FATAL_ECDSA_PWCT. 2. ECDSA KAT was only simulating error in verify, but not in sign. Split 'fips ecdsa' into 'fips ecver' and 'fips ecsign'. 3. Added a way to introduce self-integrity error by not updating FIPS module digest with 'FIPS_BREAK=1' during build. 4. Added reporting of FIPS module digest. BUG=b:134594373 TEST=make CRYPTO_TEST=1; in ccd test: fips pwct; tpm_test.py should fail; fips should print error. - fips ecver; fips test reports ECDSA error fips ecsign; fips test reports ECDSA error - FIPS module digest is printed - FIPS_BREAK=1 make CRYPTO_TEST=1 produce build with zero digest reporint FIPS self-integrity error. Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: Ib0a92c118f07a76e4b52eaf9b011ff4f73a02c61 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3425998 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/dcrypto/dcrypto.h5
-rw-r--r--board/cr50/dcrypto/fips.c7
-rw-r--r--board/cr50/dcrypto/fips.h26
-rw-r--r--board/cr50/dcrypto/p256_ec.c12
-rw-r--r--board/cr50/fips_cmd.c15
-rwxr-xr-xutil/inject_fips_fingerprint.sh3
6 files changed, 46 insertions, 22 deletions
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index 0dc0af78f0..0dbf60df9b 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -1111,6 +1111,11 @@ bool fips_rand_bytes(void *buffer, size_t len)
*/
void *always_memset(void *d, int c, size_t n);
+/**
+ * FIPS module digest for reporting.
+ */
+extern const struct sha256_digest fips_integrity;
+
#ifdef __cplusplus
}
#endif
diff --git a/board/cr50/dcrypto/fips.c b/board/cr50/dcrypto/fips.c
index c1b5454545..1a6c9318a0 100644
--- a/board/cr50/dcrypto/fips.c
+++ b/board/cr50/dcrypto/fips.c
@@ -446,14 +446,17 @@ static bool fips_ecdsa_sign_verify_kat(void)
p256_from_bin(msg_digest, &msg);
+ if (fips_break_cmd == FIPS_BREAK_ECDSA_SIGN)
+ msg.a[0] ^= 0x80; /* inject 1-bit error. */
+
/* KAT for ECDSA signing with fixed k. */
passed = dcrypto_p256_ecdsa_sign_raw(&k, &d, &msg, &r, &s) - DCRYPTO_OK;
passed |= DCRYPTO_equals(r.a, R.a, sizeof(R)) - DCRYPTO_OK;
passed |= DCRYPTO_equals(s.a, S.a, sizeof(S)) - DCRYPTO_OK;
- if (fips_break_cmd == FIPS_BREAK_ECDSA)
- msg.a[0] ^= 1;
+ if (fips_break_cmd == FIPS_BREAK_ECDSA_VER)
+ msg.a[0] ^= 1; /* inject another 1-bit error. */
/* KAT for verification */
passed |=
diff --git a/board/cr50/dcrypto/fips.h b/board/cr50/dcrypto/fips.h
index cfd39bb1fc..ca1fd689f0 100644
--- a/board/cr50/dcrypto/fips.h
+++ b/board/cr50/dcrypto/fips.h
@@ -37,14 +37,10 @@ enum fips_status {
#endif
FIPS_FATAL_SELF_INTEGRITY = 1 << 10,
FIPS_FATAL_BN_MATH = 1 << 11,
+ FIPS_FATAL_ECDSA_PWCT = 1 << 12,
FIPS_FATAL_OTHER = 1 << 15,
-/* For CRYPTO_TEST ignore self-integrity errors. */
-#ifdef CRYPTO_TEST_SETUP
- FIPS_ERROR_MASK = 0xffff & ~FIPS_FATAL_SELF_INTEGRITY,
-#else
FIPS_ERROR_MASK = 0xffff,
-#endif
FIPS_RFU_MASK = 0x7fff0000
};
@@ -56,13 +52,14 @@ enum fips_break {
FIPS_BREAK_SHA256 = 2,
FIPS_BREAK_HMAC_SHA256 = 3,
FIPS_BREAK_HMAC_DRBG = 4,
- FIPS_BREAK_ECDSA = 5,
- FIPS_BREAK_ECDSA_PWCT = 6,
+ FIPS_BREAK_ECDSA_VER = 5,
+ FIPS_BREAK_ECDSA_SIGN = 6,
+ FIPS_BREAK_ECDSA_PWCT = 7,
#ifdef CONFIG_FIPS_AES_CBC_256
- FIPS_BREAK_AES256 = 7,
+ FIPS_BREAK_AES256 = 8,
#endif
#ifdef CONFIG_FIPS_RSA2048
- FIPS_BREAK_RSA2048 = 8,
+ FIPS_BREAK_RSA2048 = 9,
#endif
};
@@ -82,15 +79,16 @@ enum fips_cmd {
FIPS_CMD_BREAK_SHA256 = 4,
FIPS_CMD_BREAK_HMAC_SHA256 = 5,
FIPS_CMD_BREAK_HMAC_DRBG = 6,
- FIPS_CMD_BREAK_ECDSA = 7,
- FIPS_CMD_BREAK_ECDSA_PWCT = 8,
+ FIPS_CMD_BREAK_ECDSA_VER = 7,
+ FIPS_CMD_BREAK_ECDSA_SIGN = 8,
+ FIPS_CMD_BREAK_ECDSA_PWCT = 9,
#ifdef CONFIG_FIPS_AES_CBC_256
- FIPS_CMD_BREAK_AES256 = 9,
+ FIPS_CMD_BREAK_AES256 = 10,
#endif
#ifdef CONFIG_FIPS_RSA2048
- FIPS_CMD_BREAK_RSA2048 = 10,
+ FIPS_CMD_BREAK_RSA2048 = 11,
#endif
- FIPS_CMD_NO_BREAK = 11
+ FIPS_CMD_NO_BREAK = 12
};
/* These symbols defined in core/cortex-m/ec.lds.S. */
diff --git a/board/cr50/dcrypto/p256_ec.c b/board/cr50/dcrypto/p256_ec.c
index ac39813abb..6fae0cb52c 100644
--- a/board/cr50/dcrypto/p256_ec.c
+++ b/board/cr50/dcrypto/p256_ec.c
@@ -117,10 +117,18 @@ enum dcrypto_result dcrypto_p256_key_pwct(struct drbg_ctx *drbg,
#endif
result = dcrypto_p256_fips_sign_internal(drbg, d, &message, &r, &s);
- if (result != DCRYPTO_OK)
+ if (result != DCRYPTO_OK) {
+ fips_set_status(FIPS_FATAL_ECDSA_PWCT);
return result;
+ }
+
+ result = dcrypto_p256_ecdsa_verify(x, y, &message, &r, &s);
+ if (result != DCRYPTO_OK) {
+ fips_set_status(FIPS_FATAL_ECDSA_PWCT);
+ return result;
+ }
- return dcrypto_p256_ecdsa_verify(x, y, &message, &r, &s);
+ return result;
}
/**
diff --git a/board/cr50/fips_cmd.c b/board/cr50/fips_cmd.c
index 816e5280d6..8ed25914e8 100644
--- a/board/cr50/fips_cmd.c
+++ b/board/cr50/fips_cmd.c
@@ -38,6 +38,8 @@ static void fips_print_mode(void)
{
enum fips_status status = fips_status();
+ CPRINTS("FIPS module digest %ph...",
+ HEX_BUF(&fips_integrity, 8));
if (status == FIPS_UNINITIALIZED)
CPRINTS("FIPS mode not initialized");
else if (status & FIPS_ERROR_MASK)
@@ -150,8 +152,10 @@ static int cmd_fips_status(int argc, char **argv)
fips_break_cmd = FIPS_BREAK_HMAC_SHA256;
else if (!strncmp(argv[1], "drbg", 4))
fips_break_cmd = FIPS_BREAK_HMAC_DRBG;
- else if (!strncmp(argv[1], "ecdsa", 5))
- fips_break_cmd = FIPS_BREAK_ECDSA;
+ else if (!strncmp(argv[1], "ecver", 5))
+ fips_break_cmd = FIPS_BREAK_ECDSA_VER;
+ else if (!strncmp(argv[1], "ecsign", 6))
+ fips_break_cmd = FIPS_BREAK_ECDSA_SIGN;
else if (!strncmp(argv[1], "pwct", 4))
fips_break_cmd = FIPS_BREAK_ECDSA_PWCT;
else if (!strncmp(argv[1], "none", 4))
@@ -217,8 +221,11 @@ static enum vendor_cmd_rc fips_cmd(enum vendor_cmd_cc code, void *buf,
case FIPS_CMD_BREAK_HMAC_DRBG:
fips_break_cmd = FIPS_BREAK_HMAC_DRBG;
break;
- case FIPS_CMD_BREAK_ECDSA:
- fips_break_cmd = FIPS_BREAK_ECDSA;
+ case FIPS_CMD_BREAK_ECDSA_VER:
+ fips_break_cmd = FIPS_BREAK_ECDSA_VER;
+ break;
+ case FIPS_CMD_BREAK_ECDSA_SIGN:
+ fips_break_cmd = FIPS_BREAK_ECDSA_SIGN;
break;
#ifdef CONFIG_FIPS_AES_CBC_256
case FIPS_CMD_BREAK_AES256:
diff --git a/util/inject_fips_fingerprint.sh b/util/inject_fips_fingerprint.sh
index a079c44401..056c98b682 100755
--- a/util/inject_fips_fingerprint.sh
+++ b/util/inject_fips_fingerprint.sh
@@ -70,6 +70,9 @@ main() {
sha256sum "${fips_body}" | xxd -r -p -l 32 > "${fips_checksum_dump}"
cp "${rw_elf_in}" "${rw_elf_out}"
+
+ # don't update digest if run with FIPS_BREAK=1
+ [ -v FIPS_BREAK ] && return 0
${objcopy} --update-section "${checksum_section}"="${fips_checksum_dump}" \
"${rw_elf_out}"
}