Never write to response before reading request
As request and response might share the same buffer, we should finish
all reads from the request before writing to response.
pw_handle_generate_pk violates this rule. Fix it so it won't
accidentally overwrite request data.
BUG=b:267728085
TEST=pinweaver_client biometrics_selftest on betty
Change-Id: I3718eb5ce596f75688569609c06fd3e22b01b38a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/pinweaver/+/4221101
Commit-Queue: Howard Yang <hcyang@google.com>
Tested-by: Howard Yang <hcyang@google.com>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Yi Chou <yich@google.com>
diff --git a/pinweaver.c b/pinweaver.c
index 324962a..065a376 100644
--- a/pinweaver.c
+++ b/pinweaver.c
@@ -1608,6 +1608,7 @@
struct pw_ba_pk_t pk;
uint8_t secret[PW_SECRET_SIZE];
size_t secret_size = PW_SECRET_SIZE;
+ struct pw_ba_ecc_pt_t server_pt;
pinweaver_eal_sha256_ctx_t sha;
if (req_size != sizeof(*request))
@@ -1622,7 +1623,6 @@
if (request->client_pbk.version != 0) {
return PW_ERR_BIO_AUTH_PUBLIC_KEY_VERSION_MISMATCH;
}
- response->server_pbk.version = 0;
if (auth_channel >= PW_BA_PK_ENTRY_COUNT) {
return PW_ERR_BIO_AUTH_CHANNEL_INVALID;
@@ -1637,11 +1637,14 @@
/* Perform ECDH to derive the shared secret. */
ret = pinweaver_eal_ecdh_derive(&request->client_pbk.pt,
- secret, &secret_size, &response->server_pbk.pt);
+ secret, &secret_size, &server_pt);
if (ret != EC_SUCCESS)
return ret;
if (secret_size != PW_SECRET_SIZE)
return PW_ERR_INTERNAL_FAILURE;
+ response->server_pbk.version = 0;
+ pinweaver_eal_memcpy_s(&response->server_pbk.pt,
+ sizeof(server_pt), &server_pt, sizeof(server_pt));
/* sha256 the shared secret into Pk. */
if (pinweaver_eal_sha256_init(&sha)) {