trusty: keymaster: Implement configure

This patch also forces the underlying structure of enum keymaster_command
to be uint32_t.

Test: builds
Change-Id: Ie8969beb9d6a15313456fbe54ef3806f6778ade2
diff --git a/trusty/keymaster/Android.mk b/trusty/keymaster/Android.mk
index 0ebf52d..49e1629 100644
--- a/trusty/keymaster/Android.mk
+++ b/trusty/keymaster/Android.mk
@@ -32,7 +32,7 @@
 LOCAL_MODULE := trusty_keymaster_tipc
 LOCAL_SRC_FILES := \
 	trusty_keymaster_device.cpp \
-	trusty_keymaster_ipc.c \
+	trusty_keymaster_ipc.cpp \
 	trusty_keymaster_main.cpp
 LOCAL_SHARED_LIBRARIES := \
 	libcrypto \
@@ -53,7 +53,7 @@
 LOCAL_MODULE := keystore.trusty
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := module.cpp \
-	trusty_keymaster_ipc.c \
+	trusty_keymaster_ipc.cpp \
 	trusty_keymaster_device.cpp
 LOCAL_CLFAGS = -fvisibility=hidden -Wall -Werror
 LOCAL_SHARED_LIBRARIES := \
diff --git a/trusty/keymaster/keymaster_ipc.h b/trusty/keymaster/keymaster_ipc.h
index 6f49e72..f970e36 100644
--- a/trusty/keymaster/keymaster_ipc.h
+++ b/trusty/keymaster/keymaster_ipc.h
@@ -22,7 +22,7 @@
 #define KEYMASTER_MAX_BUFFER_LENGTH 4096
 
 // Commands
-enum keymaster_command {
+enum keymaster_command : uint32_t {
     KEYMASTER_RESP_BIT              = 1,
     KEYMASTER_REQ_SHIFT             = 1,
 
@@ -42,6 +42,7 @@
     KM_GET_SUPPORTED_IMPORT_FORMATS = (13 << KEYMASTER_REQ_SHIFT),
     KM_GET_SUPPORTED_EXPORT_FORMATS = (14 << KEYMASTER_REQ_SHIFT),
     KM_GET_KEY_CHARACTERISTICS      = (15 << KEYMASTER_REQ_SHIFT),
+    KM_CONFIGURE                    = (18 << KEYMASTER_REQ_SHIFT),
 };
 
 #ifdef __ANDROID__
diff --git a/trusty/keymaster/trusty_keymaster_device.cpp b/trusty/keymaster/trusty_keymaster_device.cpp
index 7f8c53f..5bc879c 100644
--- a/trusty/keymaster/trusty_keymaster_device.cpp
+++ b/trusty/keymaster/trusty_keymaster_device.cpp
@@ -138,6 +138,28 @@
 
 keymaster_error_t TrustyKeymasterDevice::configure(const keymaster_key_param_set_t* params) {
     ALOGD("Device received configure\n");
+
+    if (error_ != KM_ERROR_OK) {
+        return error_;
+    }
+    if (!params) {
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+    }
+
+    AuthorizationSet params_copy(*params);
+    ConfigureRequest request;
+    if (!params_copy.GetTagValue(TAG_OS_VERSION, &request.os_version) ||
+        !params_copy.GetTagValue(TAG_OS_PATCHLEVEL, &request.os_patchlevel)) {
+        ALOGD("Configuration parameters must contain OS version and patch level");
+        return KM_ERROR_INVALID_ARGUMENT;
+    }
+
+    ConfigureResponse response;
+    keymaster_error_t err = Send(KM_CONFIGURE, request, &response);
+    if (err != KM_ERROR_OK) {
+        return err;
+    }
+
     return KM_ERROR_OK;
 }
 
diff --git a/trusty/keymaster/trusty_keymaster_ipc.c b/trusty/keymaster/trusty_keymaster_ipc.cpp
similarity index 95%
rename from trusty/keymaster/trusty_keymaster_ipc.c
rename to trusty/keymaster/trusty_keymaster_ipc.cpp
index 99a85ba..cdc2778 100644
--- a/trusty/keymaster/trusty_keymaster_ipc.c
+++ b/trusty/keymaster/trusty_keymaster_ipc.cpp
@@ -51,7 +51,7 @@
     }
 
     size_t msg_size = in_size + sizeof(struct keymaster_message);
-    struct keymaster_message* msg = malloc(msg_size);
+    struct keymaster_message* msg = reinterpret_cast<struct keymaster_message*>(malloc(msg_size));
     msg->cmd = cmd;
     memcpy(msg->payload, in, in_size);