keymaster: Check system_state if provisioning is allowed

This adds a dependency on the system_state server. If this changed is
merged into a project that uses the previous keymaster provisioning
scheme, then a system_state server will need to be added that returns
SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED_VALUE_ALLOWED_AT_BOOT for
SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED. This can be done by adding:

TRUSTY_BUILTIN_USER_TASKS += \
	trusty/user/base/app/system_state_server_static \

STATIC_SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED := 2

to the top project .mk file.

Bug: 154033394
Change-Id: I72e227557cc8f9b5c8d1670337d14799ca3bc830
diff --git a/ipc/keymaster_ipc.cpp b/ipc/keymaster_ipc.cpp
index 30c980f..a504ae0 100644
--- a/ipc/keymaster_ipc.cpp
+++ b/ipc/keymaster_ipc.cpp
@@ -16,6 +16,7 @@
 
 #include "keymaster_ipc.h"
 
+#include <lib/system_state/system_state.h>
 #include <lk/macros.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -331,8 +332,21 @@
     }
 }
 
+static bool system_state_provisioning_allowed_at_boot(void) {
+    uint64_t value = system_state_get_flag_default(
+            SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED,
+            SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED_VALUE_NOT_ALLOWED);
+    return value == SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED_VALUE_ALLOWED ||
+           value ==
+                   SYSTEM_STATE_FLAG_PROVISIONING_ALLOWED_VALUE_ALLOWED_AT_BOOT;
+}
+
 static bool provisioning_allowed(void) {
-    return !device->ConfigureCalled();
+    if (device->ConfigureCalled()) {
+        return system_state_provisioning_allowed();
+    } else {
+        return system_state_provisioning_allowed_at_boot();
+    }
 }
 
 // Returns true if |cmd| is only allowed in provisioning mode
diff --git a/rules.mk b/rules.mk
index 96999b1..6f08a9d 100644
--- a/rules.mk
+++ b/rules.mk
@@ -118,6 +118,7 @@
 	trusty/user/base/lib/rng \
 	trusty/user/base/lib/hwkey \
 	trusty/user/base/lib/storage \
+	trusty/user/base/lib/system_state \
 	external/boringssl \
 
 include $(LOCAL_DIR)/atap/rules.mk