diff options
author | Yicheng Li <yichengli@chromium.org> | 2020-07-23 17:57:08 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-07-29 23:37:55 +0000 |
commit | d2627d12bb21308f49a72cadaf47a0a86730a960 (patch) | |
tree | 302f2c0b6130c0d0d9296d62f9dec089e4923943 /board | |
parent | 7c6ed95d0f454d5496f8104d5cb4244c3999b5b5 (diff) | |
download | chrome-ec-d2627d12bb21308f49a72cadaf47a0a86730a960.tar.gz |
u2f: Append hmac of auth time secret to versioned KH
When generating versioned KHs, u2fd should send a public derivative
(sha256) of the user's auth time secret to cr50. Cr50 derives an
hmac of it and appends this authorization_hmac to the KH.
When signing versioned KHs, u2fd may supply the unhashed auth time
secret. Cr50 will check the authorization_hmac if no power button press.
If the reconstructed hmac matches authorization_hmac, power button press
is waived.
Currently for v1, we will just prepare the authorization_hmac but not
enforce it. This is because fingerprint and PIN are unable to unlock
the same secret.
While we waive power button press for v1, we can enforce
authorization_hmac whenever auth-time secrets is ready.
BUG=b:144861739
TEST=- Use a known 32-byte "auth-time secret"
- Compute the sha256 of the auth-time secret (this is public)
- u2f_generate with the computed "authTimeSecretHash"
- Add code to u2f_sign command handler such that cr50 computes
the sha256 of the supplied auth-time secret at u2f_sign time
and require power button press if the hmac doesn't match.
- u2f_sign with the true auth-time secret -> observe in logging
that hmac matches, and no power button press required.
- u2f_sign with a wrong auth-time secret -> observe in logging
that hmac doesn't match, and power button press is required
for signing.
Cq-Depend: chromium:2321731
Change-Id: Ib9ae913667f8178ac7a4790f861d7dada972c4a0
Signed-off-by: Yicheng Li <yichengli@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2317047
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/cr50/u2f.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/board/cr50/u2f.c b/board/cr50/u2f.c index 7c6273823c..8bca1d8271 100644 --- a/board/cr50/u2f.c +++ b/board/cr50/u2f.c @@ -201,7 +201,8 @@ int u2f_origin_user_keyhandle(const uint8_t *origin, const uint8_t *user, int u2f_origin_user_versioned_keyhandle( const uint8_t *origin, const uint8_t *user, const uint8_t *origin_seed, - uint8_t version, struct u2f_versioned_key_handle *key_handle) + uint8_t version, + struct u2f_versioned_key_handle_header *key_handle_header) { LITE_HMAC_CTX ctx; struct u2f_state *state = get_state(); @@ -209,16 +210,17 @@ int u2f_origin_user_versioned_keyhandle( if (!state) return EC_ERROR_UNKNOWN; - key_handle->version = version; - memcpy(key_handle->origin_seed, origin_seed, P256_NBYTES); + key_handle_header->version = version; + memcpy(key_handle_header->origin_seed, origin_seed, P256_NBYTES); DCRYPTO_HMAC_SHA256_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE); HASH_update(&ctx.hash, origin, P256_NBYTES); HASH_update(&ctx.hash, user, P256_NBYTES); HASH_update(&ctx.hash, origin_seed, P256_NBYTES); - HASH_update(&ctx.hash, &version, sizeof(key_handle->version)); + HASH_update(&ctx.hash, &version, sizeof(key_handle_header->version)); - memcpy(key_handle->hmac, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE); + memcpy(key_handle_header->kh_hmac, DCRYPTO_HMAC_final(&ctx), + SHA256_DIGEST_SIZE); return EC_SUCCESS; } @@ -250,6 +252,24 @@ int u2f_origin_user_keypair(const uint8_t *key_handle, size_t key_handle_size, return EC_SUCCESS; } +int u2f_authorization_hmac(const uint8_t *authorization_salt, + const uint8_t *auth_time_secret_hash, uint8_t *hmac) +{ + LITE_HMAC_CTX ctx; + struct u2f_state *state = get_state(); + + if (!state) + return EC_ERROR_UNKNOWN; + + DCRYPTO_HMAC_SHA256_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE); + HASH_update(&ctx.hash, authorization_salt, U2F_AUTHORIZATION_SALT_SIZE); + HASH_update(&ctx.hash, auth_time_secret_hash, P256_NBYTES); + + memcpy(hmac, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE); + + return EC_SUCCESS; +} + int u2f_gen_kek(const uint8_t *origin, uint8_t *kek, size_t key_len) { uint32_t buf[P256_NDIGITS]; |