summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorYicheng Li <yichengli@chromium.org>2020-07-23 17:57:08 -0700
committerCommit Bot <commit-bot@chromium.org>2020-07-29 23:37:55 +0000
commitd2627d12bb21308f49a72cadaf47a0a86730a960 (patch)
tree302f2c0b6130c0d0d9296d62f9dec089e4923943 /include
parent7c6ed95d0f454d5496f8104d5cb4244c3999b5b5 (diff)
downloadchrome-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 'include')
-rw-r--r--include/u2f.h19
-rw-r--r--include/u2f_impl.h12
2 files changed, 27 insertions, 4 deletions
diff --git a/include/u2f.h b/include/u2f.h
index 61b9677185..3454ba82e8 100644
--- a/include/u2f.h
+++ b/include/u2f.h
@@ -53,15 +53,24 @@ struct u2f_ec_point {
#define U2F_KH_VERSION_1 0x01
+#define U2F_AUTHORIZATION_SALT_SIZE 16
+
struct u2f_key_handle {
uint8_t origin_seed[U2F_P256_SIZE];
uint8_t hmac[U2F_P256_SIZE];
};
-struct u2f_versioned_key_handle {
+struct u2f_versioned_key_handle_header {
uint8_t version;
uint8_t origin_seed[U2F_P256_SIZE];
- uint8_t hmac[U2F_P256_SIZE];
+ uint8_t kh_hmac[U2F_P256_SIZE];
+};
+
+struct u2f_versioned_key_handle {
+ struct u2f_versioned_key_handle_header header;
+ /* Optionally checked in u2f_sign. */
+ uint8_t authorization_salt[U2F_AUTHORIZATION_SALT_SIZE];
+ uint8_t authorization_hmac[U2F_P256_SIZE];
};
/* TODO(louiscollard): Add Descriptions. */
@@ -70,6 +79,11 @@ struct u2f_generate_req {
uint8_t appId[U2F_APPID_SIZE]; /* Application id */
uint8_t userSecret[U2F_P256_SIZE];
uint8_t flags;
+ /*
+ * If generating versioned KH, derive an hmac from it and append to
+ * the key handle. Otherwise unused.
+ */
+ uint8_t authTimeSecretHash[U2F_P256_SIZE];
};
struct u2f_generate_resp {
@@ -93,6 +107,7 @@ struct u2f_sign_req {
struct u2f_sign_versioned_req {
uint8_t appId[U2F_APPID_SIZE]; /* Application id */
uint8_t userSecret[U2F_P256_SIZE];
+ uint8_t authTimeSecret[U2F_P256_SIZE];
uint8_t hash[U2F_P256_SIZE];
uint8_t flags;
struct u2f_versioned_key_handle keyHandle;
diff --git a/include/u2f_impl.h b/include/u2f_impl.h
index 5bd69309c6..9b66c348bf 100644
--- a/include/u2f_impl.h
+++ b/include/u2f_impl.h
@@ -76,13 +76,14 @@ int u2f_origin_user_keyhandle(const uint8_t *origin, const uint8_t *user,
* @param user pointer to user secret
* @param seed pointer to origin-specific random seed
* @param version the version byte to pack; should be greater than 0.
- * @param key_handle buffer to hold the output key handle
+ * @param key_handle_header buffer to hold the output key handle header
*
* @return EC_SUCCESS if a valid keypair was created.
*/
int u2f_origin_user_versioned_keyhandle(
const uint8_t *origin, const uint8_t *user, const uint8_t *seed,
- uint8_t version, struct u2f_versioned_key_handle *key_handle);
+ uint8_t version,
+ struct u2f_versioned_key_handle_header *key_handle_header);
/**
* Generate an origin and user-specific ECDSA keypair from the specified
@@ -101,6 +102,13 @@ int u2f_origin_user_versioned_keyhandle(
int u2f_origin_user_keypair(const uint8_t *key_handle, size_t key_handle_size,
p256_int *d, p256_int *pk_x, p256_int *pk_y);
+/**
+ * Derive an hmac from the given salt and hash. The seed is to make sure the
+ * hmac is different for different key handles of one user.
+ */
+int u2f_authorization_hmac(const uint8_t *authorization_salt,
+ const uint8_t *auth_time_secret_hash, uint8_t *hmac);
+
/***
* Generate a hardware derived 256b private key.
*