diff options
author | Vadim Sukhomlinov <sukhomlinov@google.com> | 2021-09-10 15:42:37 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-15 02:17:02 +0000 |
commit | e33cd20b6898e8a8896795425dc4e9c7c51d12be (patch) | |
tree | 85923775498beaa878ee444c02cf3b663b25e4b5 | |
parent | d83a3c89d3733b8ca49f95b93a8c2e4c7db5689e (diff) | |
download | chrome-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.c | 80 | ||||
-rw-r--r-- | test/u2f.c | 1 |
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; } |