summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@chromium.org>2020-01-02 13:23:46 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-16 04:34:44 +0000
commit53534ea1da670669eec5be9144ddc549b9fe6bc3 (patch)
tree2ede72a1b6bbfa5761ae5cfde8e9ad333d512e83
parentcedc4f22ac54aa2e91f5b7c8e6a6a8f07a3f05e6 (diff)
downloadchrome-ec-53534ea1da670669eec5be9144ddc549b9fe6bc3.tar.gz
cr50: add checks to U2F_ATTEST
This CL adds checks to U2F_ATTEST and rejects signing of the passed data if one of the following conditions is not satisfied: - reserved byte is 0, - public key matches the key associated with the keyhandle. BUG=b:147097407 TEST=test_that <dut> firmware_Cr50U2fCommands Change-Id: I10005742042a182a894eed243e006fcf14f68e28 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1984891 Reviewed-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Andrey Pronin <apronin@chromium.org> Commit-Queue: Andrey Pronin <apronin@chromium.org> Auto-Submit: Andrey Pronin <apronin@chromium.org> (cherry picked from commit aa9cdf2daf1aa2b30866c2d3aa260b47ed40808a) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2003403
-rw-r--r--common/u2f.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/common/u2f.c b/common/u2f.c
index bc55496fb6..8cef638d3a 100644
--- a/common/u2f.c
+++ b/common/u2f.c
@@ -148,6 +148,27 @@ static enum vendor_cmd_rc u2f_generate(enum vendor_cmd_cc code,
}
DECLARE_VENDOR_COMMAND(VENDOR_CC_U2F_GENERATE, u2f_generate);
+static int verify_kh_pubkey(const uint8_t *key_handle,
+ const U2F_EC_POINT *public_key, int *matches) {
+ int rc;
+ U2F_EC_POINT kh_pubkey;
+ p256_int od, opk_x, opk_y;
+
+ rc = u2f_origin_user_keypair(key_handle, &od, &opk_x, &opk_y);
+ if (rc != EC_SUCCESS)
+ return rc;
+
+ /* Reconstruct the public key. */
+ p256_to_bin(&opk_x, kh_pubkey.x);
+ p256_to_bin(&opk_y, kh_pubkey.y);
+ kh_pubkey.pointFormat = U2F_POINT_UNCOMPRESSED;
+
+ *matches =
+ safe_memcmp(&kh_pubkey, public_key, sizeof(U2F_EC_POINT)) == 0;
+
+ return EC_SUCCESS;
+}
+
static int verify_kh_owned(const uint8_t *user_secret, const uint8_t *app_id,
const uint8_t *key_handle, int *owned)
{
@@ -302,16 +323,26 @@ static inline int u2f_attest_verify_reg_resp(const uint8_t *user_secret,
const uint8_t *data)
{
struct G2F_REGISTER_MSG *msg = (void *) data;
- int kh_owned;
+ int verified;
if (data_size != sizeof(struct G2F_REGISTER_MSG))
return VENDOR_RC_NOT_ALLOWED;
+ if (msg->reserved != 0)
+ return VENDOR_RC_NOT_ALLOWED;
+
if (verify_kh_owned(user_secret, msg->app_id, msg->key_handle,
- &kh_owned) != EC_SUCCESS)
+ &verified) != EC_SUCCESS)
+ return VENDOR_RC_INTERNAL_ERROR;
+
+ if (!verified)
+ return VENDOR_RC_NOT_ALLOWED;
+
+ if (verify_kh_pubkey(msg->key_handle, &msg->public_key, &verified) !=
+ EC_SUCCESS)
return VENDOR_RC_INTERNAL_ERROR;
- if (!kh_owned)
+ if (!verified)
return VENDOR_RC_NOT_ALLOWED;
return VENDOR_RC_SUCCESS;