summaryrefslogtreecommitdiff
path: root/board/cr50/u2f.c
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2020-07-23 17:57:08 -0700
committerCommit Bot <commit-bot@chromium.org>2020-08-18 05:55:41 +0000
commit4b4bbc8d761225b260625584dadbc6d4e623ef2d (patch)
treea540022243de10afb4b677c119611564609f728b /board/cr50/u2f.c
parent4e9e48219c254654027040a09a181f377784b281 (diff)
downloadchrome-ec-firmware-zork-13421.B-cr50_stab.tar.gz
This is a reland of d2627d12bb21308f49a72cadaf47a0a86730a960 with one modification: The versioned key handle header (the old "key handle" concept) is now used in the derivation of authorization_hmac. This is to tie the key handle to the authorization secret. Original change's description: > 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> BUG=b:144861739 TEST=See original CL's TEST above Cq-Depend: chromium:2327865 Change-Id: Ia1b0b4a585ec604398cfa730354ae1a91e7bc00b Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2355177 Reviewed-by: Andrey Pronin <apronin@chromium.org>
Diffstat (limited to 'board/cr50/u2f.c')
-rw-r--r--board/cr50/u2f.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/board/cr50/u2f.c b/board/cr50/u2f.c
index 7c6273823c..7fe1f6484f 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,27 @@ 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 struct u2f_versioned_key_handle_header *header,
+ 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, (uint8_t *)header,
+ sizeof(struct u2f_versioned_key_handle_header));
+ HASH_update(&ctx.hash, auth_time_secret_hash, SHA256_DIGEST_SIZE);
+
+ 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];