diff options
author | Andrey Pronin <apronin@chromium.org> | 2020-01-02 13:23:46 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-01-16 04:34:44 +0000 |
commit | 53534ea1da670669eec5be9144ddc549b9fe6bc3 (patch) | |
tree | 2ede72a1b6bbfa5761ae5cfde8e9ad333d512e83 | |
parent | cedc4f22ac54aa2e91f5b7c8e6a6a8f07a3f05e6 (diff) | |
download | chrome-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.c | 37 |
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; |