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)) {