summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-09-10 15:42:37 -0700
committerCommit Bot <commit-bot@chromium.org>2021-09-15 02:17:02 +0000
commite33cd20b6898e8a8896795425dc4e9c7c51d12be (patch)
tree85923775498beaa878ee444c02cf3b663b25e4b5
parentd83a3c89d3733b8ca49f95b93a8c2e4c7db5689e (diff)
downloadchrome-ec-e33cd20b6898e8a8896795425dc4e9c7c51d12be.tar.gz
cr50: switch to FIPS key gen for U2F and G2F
For G2F switched to proper use of DRBG. For U2F added support for 512-bit entropy, changed DRBG instantiation in FIPS path. BUG=b:134594373 TEST=make BOARD=cr50 CRYPTO_TEST=1; u2f_tests in ccd, tpm_test.py Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: I1acf9947317a8b2f1b53cee0b2d81829c54336d5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3161506 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Andrey Pronin <apronin@chromium.org>
-rw-r--r--board/cr50/dcrypto/u2f.c80
-rw-r--r--test/u2f.c1
2 files changed, 68 insertions, 13 deletions
diff --git a/board/cr50/dcrypto/u2f.c b/board/cr50/dcrypto/u2f.c
index 91c80577b6..15bdddcbe8 100644
--- a/board/cr50/dcrypto/u2f.c
+++ b/board/cr50/dcrypto/u2f.c
@@ -171,16 +171,42 @@ static enum ec_error_list u2f_origin_user_key_pair(
return EC_ERROR_INVAL;
}
- /* TODO(sukhomlinov): implement new FIPS path. */
if (!app_hw_device_id(U2F_ORIGIN, state->hmac_key, dev_salt))
return EC_ERROR_UNKNOWN;
- hmac_drbg_init(&drbg, state->drbg_entropy, P256_NBYTES, dev_salt,
- P256_NBYTES, NULL, 0);
+ /* Check that U2F state is valid. */
+ if (state->drbg_entropy_size != 64 && state->drbg_entropy_size != 32)
+ return EC_ERROR_HW_INTERNAL;
- hmac_drbg_generate(&drbg, key_seed, sizeof(key_seed), key_handle,
- key_handle_size);
+ if (state->drbg_entropy_size == 32) {
+ /**
+ * Legacy path, seeding DRBG not as NIST SP 800-90A requires.
+ */
+ hmac_drbg_init(&drbg, state->drbg_entropy,
+ state->drbg_entropy_size, dev_salt, P256_NBYTES,
+ NULL, 0);
+ hmac_drbg_generate(&drbg, key_seed, sizeof(key_seed),
+ key_handle, key_handle_size);
+ } else {
+ /**
+ * FIPS-compliant path.
+ *
+ * Seed DRBG with:
+ * 512 bit of entropy from TRNG (stored outside module
+ * boundary).
+ * nonce = key_handle - contains fresh, unique 256-bit random
+ * personalization strint - empty
+ */
+ hmac_drbg_init(&drbg, state->drbg_entropy,
+ state->drbg_entropy_size, key_handle,
+ key_handle_size, NULL, 0);
+ /**
+ * Additional data = Device_ID (constant coming from HW).
+ */
+ hmac_drbg_generate(&drbg, key_seed, sizeof(key_seed), dev_salt,
+ P256_NBYTES);
+ }
if (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, key_seed))
return EC_ERROR_TRY_AGAIN;
@@ -412,19 +438,47 @@ enum ec_error_list u2f_sign(const struct u2f_state *state,
static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
p256_int *pk_x, p256_int *pk_y)
{
- uint8_t buf[SHA256_DIGEST_SIZE];
+ uint32_t buf[SHA256_DIGEST_WORDS];
/* Incorporate HIK & diversification constant. */
- if (!app_hw_device_id(U2F_ATTEST, state->salt, (uint32_t *)buf))
+ if (!app_hw_device_id(U2F_ATTEST, state->salt, buf))
+ return false;
+
+ /* Check that U2F state is valid. */
+ if (state->drbg_entropy_size != 64 && state->drbg_entropy_size != 32)
return false;
- /* Generate unbiased private key (non-FIPS path). */
- while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, buf)) {
- struct sha256_ctx sha;
+ if (state->drbg_entropy_size != 64) {
+ /* Generate unbiased private key (non-FIPS path). */
+ while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ (uint8_t *)buf)) {
+ struct sha256_ctx sha;
- SHA256_hw_init(&sha);
- SHA256_update(&sha, buf, sizeof(buf));
- memcpy(buf, SHA256_final(&sha), sizeof(buf));
+ SHA256_hw_init(&sha);
+ SHA256_update(&sha, buf, sizeof(buf));
+ memcpy(buf, SHA256_final(&sha), sizeof(buf));
+ }
+ } else {
+ struct drbg_ctx drbg;
+ uint8_t key_candidate[P256_NBYTES];
+ /**
+ * Entropy = 512 of entropy from TRNG
+ * Nonce = 256-bit random
+ * Personalization string = []
+ */
+ hmac_drbg_init(&drbg, state->drbg_entropy,
+ state->drbg_entropy_size, state->salt,
+ sizeof(state->salt), NULL, 0);
+
+ do {
+ /**
+ * Additional data = constant coming from HW.
+ */
+ hmac_drbg_generate(&drbg, key_candidate,
+ sizeof(key_candidate), buf,
+ sizeof(buf));
+ } while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ key_candidate));
}
return true;
diff --git a/test/u2f.c b/test/u2f.c
index 047c62b7df..0ef0d55f42 100644
--- a/test/u2f.c
+++ b/test/u2f.c
@@ -82,6 +82,7 @@ static struct u2f_state state;
struct u2f_state *u2f_get_state(void)
{
+ state.drbg_entropy_size = 64;
return &state;
}