pinweaver: Add block_generate_ba_pk command

Add a command to let the client block future Pk establishments until the
server restarts. See the security consultation bug linked in the linked
bug for more context.

BUG=b:243089341
TEST=build ok
TEST=pinweaver_client block_generate_ba_pk, then biometrics_selftest
should fail. Then after reboot selftest should work again.

Change-Id: Ibe716d596802a93c3180792a7f001527840f4b23
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/pinweaver/+/3911107
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Tested-by: Howard Yang <hcyang@google.com>
Commit-Queue: Howard Yang <hcyang@google.com>
diff --git a/pinweaver.c b/pinweaver.c
index 982bda8..5be8d50 100644
--- a/pinweaver.c
+++ b/pinweaver.c
@@ -94,6 +94,15 @@
  */
 uint32_t pw_restart_count;
 
+#if BIOMETRICS_DEV
+/* If non-zero, Pk establishment is blocked. The client should send a
+ * block_generate_ba_pk command after the client platform passed the stage
+ * that Pk establishment is allowed. This reduces the risk of active attackers
+ * trying to establish Pk with the server.
+ */
+int generate_ba_pk_blocked;
+#endif
+
 /******************************************************************************/
 /* Struct helper functions.
  */
@@ -1609,6 +1618,10 @@
 		return PW_ERR_LENGTH_INVALID;
 	auth_channel = request->auth_channel;
 
+	if (generate_ba_pk_blocked) {
+		return PW_ERR_BIO_AUTH_ACCESS_DENIED;
+	}
+
 	/* Currently we only support v0 public key format. */
 	if (request->client_pbk.version != 0) {
 		return PW_ERR_BIO_AUTH_PUBLIC_KEY_VERSION_MISMATCH;
@@ -1822,6 +1835,12 @@
 
 	return EC_SUCCESS;
 }
+
+static int pw_handle_block_generate_ba_pk()
+{
+	generate_ba_pk_blocked = 1;
+	return EC_SUCCESS;
+}
 #endif
 
 struct merkle_tree_t pw_merkle_tree;
@@ -1833,6 +1852,9 @@
 void pinweaver_init(void)
 {
 	load_merkle_tree(&pw_merkle_tree);
+#if BIOMETRICS_DEV
+	generate_ba_pk_blocked = 0;
+#endif
 }
 
 int get_path_auxiliary_hash_count(const struct merkle_tree_t *merkle_tree)
@@ -2162,6 +2184,9 @@
 					&response->data.start_bio_auth,
 					&resp_length);
 		break;
+	case PW_BLOCK_GENERATE_BA_PK:
+		ret = pw_handle_block_generate_ba_pk();
+		break;
 #endif
 	default:
 		ret = PW_ERR_TYPE_INVALID;
diff --git a/pinweaver_types.h b/pinweaver_types.h
index 92d5a93..602bf65 100644
--- a/pinweaver_types.h
+++ b/pinweaver_types.h
@@ -325,6 +325,7 @@
 	 */
 	PW_GENERATE_BA_PK = 9,
 	PW_START_BIO_AUTH = 10,
+	PW_BLOCK_GENERATE_BA_PK = 11,
 #endif
 };