trusty: keymaster: Implement get_key_characteristics

Test: builds
Change-Id: I6e6a28d8eec5ff91a9e8c82597593857732407f3
diff --git a/trusty/keymaster/trusty_keymaster_device.cpp b/trusty/keymaster/trusty_keymaster_device.cpp
index f668046..7ada002 100644
--- a/trusty/keymaster/trusty_keymaster_device.cpp
+++ b/trusty/keymaster/trusty_keymaster_device.cpp
@@ -148,6 +148,18 @@
     return tmp;
 }
 
+template <typename RequestType>
+void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
+                         RequestType* request) {
+    request->additional_params.Clear();
+    if (client_id) {
+        request->additional_params.push_back(TAG_APPLICATION_ID, *client_id);
+    }
+    if (app_data) {
+        request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data);
+    }
+}
+
 }  //  unnamed namespace
 
 keymaster_error_t TrustyKeymasterDevice::configure(const keymaster_key_param_set_t* params) {
@@ -234,6 +246,30 @@
     const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id,
     const keymaster_blob_t* app_data, keymaster_key_characteristics_t* characteristics) {
     ALOGD("Device received get_key_characteristics");
+
+    if (error_ != KM_ERROR_OK) {
+        return error_;
+    }
+    if (!key_blob || !key_blob->key_material) {
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+    }
+    if (!characteristics) {
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+
+    GetKeyCharacteristicsRequest request;
+    request.SetKeyMaterial(*key_blob);
+    AddClientAndAppData(client_id, app_data, &request);
+
+    GetKeyCharacteristicsResponse response;
+    keymaster_error_t err = Send(KM_GET_KEY_CHARACTERISTICS, request, &response);
+    if (err != KM_ERROR_OK) {
+        return err;
+    }
+
+    response.enforced.CopyToParamSet(&characteristics->hw_enforced);
+    response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
+
     return KM_ERROR_OK;
 }