Merge changes I8b882c0c,I45be3620

* changes:
  Launch secure_env from the host and connect from the guest.
  Integrate PureSoftKeymaster in secure_env.
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index bcc3010..76e97c3 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -515,6 +515,7 @@
       instance.set_keyboard_server_port(7000 + num - 1);
       instance.set_touch_server_port(7100 + num - 1);
     }
+    instance.set_keymaster_vsock_port(7200 + num - 1);
 
     instance.set_device_title(FLAGS_device_title);
 
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index 6b7f7c8..e624e7c 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -413,3 +413,13 @@
     LaunchTpmSimulator(process_monitor, config);
   }
 }
+
+void LaunchSecureEnvironment(cvd::ProcessMonitor* process_monitor,
+                             const vsoc::CuttlefishConfig& config) {
+  auto port = config.ForDefaultInstance().keymaster_vsock_port();
+  auto server = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  cvd::Command command(vsoc::DefaultHostArtifactsPath("bin/secure_env"));
+  command.AddParameter("-keymaster_fd=", server);
+  process_monitor->StartSubprocess(std::move(command),
+                                   GetOnSubprocessExitCallback(config));
+}
diff --git a/host/commands/run_cvd/launch.h b/host/commands/run_cvd/launch.h
index af3ec40..650886b 100644
--- a/host/commands/run_cvd/launch.h
+++ b/host/commands/run_cvd/launch.h
@@ -42,3 +42,6 @@
 
 void LaunchMetrics(cvd::ProcessMonitor* process_monitor,
                                   const vsoc::CuttlefishConfig& config);
+
+void LaunchSecureEnvironment(cvd::ProcessMonitor* process_monitor,
+                             const vsoc::CuttlefishConfig& config);
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index c72237e..5cd2b81 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -424,6 +424,7 @@
   LaunchConfigServer(*config, &process_monitor);
   LaunchTombstoneReceiverIfEnabled(*config, &process_monitor);
   LaunchTpm(&process_monitor, *config);
+  LaunchSecureEnvironment(&process_monitor, *config);
 
   // The streamer needs to launch before the VMM because it serves on several
   // sockets (input devices, vsock frame server) when using crosvm.
diff --git a/host/commands/secure_env/Android.bp b/host/commands/secure_env/Android.bp
index 018718c..8d8efe7 100644
--- a/host/commands/secure_env/Android.bp
+++ b/host/commands/secure_env/Android.bp
@@ -16,11 +16,13 @@
 cc_binary_host {
     name: "secure_env",
     srcs: [
+        "keymaster_responder.cpp",
         "secure_env.cpp",
     ],
     shared_libs: [
         "libbase",
         "libcuttlefish_fs",
+        "libcuttlefish_security",
         "libcuttlefish_utils",
         "libkeymaster_portable",
         "libkeymaster_messages",
@@ -28,9 +30,13 @@
         "liblog",
         "libcrypto",
         "libcutils",
+        "libpuresoftkeymasterdevice_host",
     ],
     static_libs: [
         "libgflags",
     ],
     defaults: ["cuttlefish_host_only"],
+    cflags: [
+        "-fno-rtti", // Required for libkeymaster_portable
+    ],
 }
diff --git a/host/commands/secure_env/keymaster_responder.cpp b/host/commands/secure_env/keymaster_responder.cpp
new file mode 100644
index 0000000..2076866
--- /dev/null
+++ b/host/commands/secure_env/keymaster_responder.cpp
@@ -0,0 +1,104 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "keymaster_responder.h"
+
+#include <android-base/logging.h>
+#include <keymaster/android_keymaster_messages.h>
+
+KeymasterResponder::KeymasterResponder(
+    cvd::KeymasterChannel* channel, keymaster::AndroidKeymaster* keymaster)
+    : channel_(channel), keymaster_(keymaster) {
+}
+
+bool KeymasterResponder::ProcessMessage() {
+  auto request = channel_->ReceiveMessage();
+  if (!request) {
+    LOG(ERROR) << "Could not receive message";
+    return false;
+  }
+  const uint8_t* buffer = request->payload;
+  const uint8_t* end = request->payload + request->payload_size;
+  switch(request->cmd) {
+    using namespace keymaster;
+#define HANDLE_MESSAGE(ENUM_NAME, METHOD_NAME) \
+    case ENUM_NAME: {\
+      METHOD_NAME##Request request; \
+      if (!request.Deserialize(&buffer, end)) { \
+        LOG(ERROR) << "Failed to deserialize " #METHOD_NAME "Request"; \
+        return false; \
+      } \
+      METHOD_NAME##Response response; \
+      keymaster_->METHOD_NAME(request, &response); \
+      return channel_->SendResponse(ENUM_NAME, response); \
+    }
+    HANDLE_MESSAGE(GENERATE_KEY, GenerateKey)
+    HANDLE_MESSAGE(BEGIN_OPERATION, BeginOperation)
+    HANDLE_MESSAGE(UPDATE_OPERATION, UpdateOperation)
+    HANDLE_MESSAGE(FINISH_OPERATION, FinishOperation)
+    HANDLE_MESSAGE(ABORT_OPERATION, AbortOperation)
+    HANDLE_MESSAGE(IMPORT_KEY, ImportKey)
+    HANDLE_MESSAGE(EXPORT_KEY, ExportKey)
+    HANDLE_MESSAGE(GET_VERSION, GetVersion)
+    HANDLE_MESSAGE(GET_SUPPORTED_ALGORITHMS, SupportedAlgorithms)
+    HANDLE_MESSAGE(GET_SUPPORTED_BLOCK_MODES, SupportedBlockModes)
+    HANDLE_MESSAGE(GET_SUPPORTED_PADDING_MODES, SupportedPaddingModes)
+    HANDLE_MESSAGE(GET_SUPPORTED_DIGESTS, SupportedDigests)
+    HANDLE_MESSAGE(GET_SUPPORTED_IMPORT_FORMATS, SupportedImportFormats)
+    HANDLE_MESSAGE(GET_SUPPORTED_EXPORT_FORMATS, SupportedExportFormats)
+    HANDLE_MESSAGE(GET_KEY_CHARACTERISTICS, GetKeyCharacteristics)
+    HANDLE_MESSAGE(ATTEST_KEY, AttestKey)
+    HANDLE_MESSAGE(UPGRADE_KEY, UpgradeKey)
+    HANDLE_MESSAGE(CONFIGURE, Configure)
+    HANDLE_MESSAGE(DELETE_KEY, DeleteKey)
+    HANDLE_MESSAGE(DELETE_ALL_KEYS, DeleteAllKeys)
+    HANDLE_MESSAGE(IMPORT_WRAPPED_KEY, ImportWrappedKey)
+#undef HANDLE_MESSAGE
+#define HANDLE_MESSAGE(ENUM_NAME, METHOD_NAME) \
+    case ENUM_NAME: {\
+      METHOD_NAME##Request request; \
+      if (!request.Deserialize(&buffer, end)) { \
+        LOG(ERROR) << "Failed to deserialize " #METHOD_NAME "Request"; \
+        return false; \
+      } \
+      auto response = keymaster_->METHOD_NAME(request); \
+      return channel_->SendResponse(ENUM_NAME, response); \
+    }
+    HANDLE_MESSAGE(COMPUTE_SHARED_HMAC, ComputeSharedHmac)
+    HANDLE_MESSAGE(VERIFY_AUTHORIZATION, VerifyAuthorization)
+#undef HANDLE_MESSAGE
+#define HANDLE_MESSAGE(ENUM_NAME, METHOD_NAME) \
+    case ENUM_NAME: {\
+      auto response = keymaster_->METHOD_NAME(); \
+      return channel_->SendResponse(ENUM_NAME, response); \
+    }
+    HANDLE_MESSAGE(GET_HMAC_SHARING_PARAMETERS, GetHmacSharingParameters)
+    HANDLE_MESSAGE(EARLY_BOOT_ENDED, EarlyBootEnded)
+    case ADD_RNG_ENTROPY: {
+      AddEntropyRequest request;
+      if (!request.Deserialize(&buffer, end)) {
+        LOG(ERROR) << "Failed to deserialize AddEntropyRequest";
+        return false;
+      }
+      AddEntropyResponse response;
+      keymaster_->AddRngEntropy(request, &response);
+      return channel_->SendResponse(ADD_RNG_ENTROPY, response);
+    }
+    case DESTROY_ATTESTATION_IDS: // Not defined in AndroidKeymaster?
+      break;
+  }
+  LOG(ERROR) << "Unknown request type: " << request->cmd;
+  return false;
+}
diff --git a/host/commands/secure_env/keymaster_responder.h b/host/commands/secure_env/keymaster_responder.h
new file mode 100644
index 0000000..b30c6a4
--- /dev/null
+++ b/host/commands/secure_env/keymaster_responder.h
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <keymaster/android_keymaster.h>
+
+#include "common/libs/security/keymaster_channel.h"
+
+class KeymasterResponder {
+private:
+  cvd::KeymasterChannel* channel_;
+  keymaster::AndroidKeymaster* keymaster_;
+public:
+  KeymasterResponder(cvd::KeymasterChannel* channel,
+                     keymaster::AndroidKeymaster* keymaster);
+
+  bool ProcessMessage();
+};
diff --git a/host/commands/secure_env/secure_env.cpp b/host/commands/secure_env/secure_env.cpp
index 60fc23b..c9edc6b 100644
--- a/host/commands/secure_env/secure_env.cpp
+++ b/host/commands/secure_env/secure_env.cpp
@@ -13,5 +13,39 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-int main() {
+#include <android-base/logging.h>
+#include <gflags/gflags.h>
+#include <keymaster/android_keymaster.h>
+#include <keymaster/contexts/pure_soft_keymaster_context.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/security/keymaster_channel.h"
+#include "host/commands/secure_env/keymaster_responder.h"
+
+// Copied from AndroidKeymaster4Device
+constexpr size_t kOperationTableSize = 16;
+
+DEFINE_int32(keymaster_fd, -1, "A file descriptor for keymaster communication");
+
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv);
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  keymaster::PureSoftKeymasterContext keymaster_context{
+      KM_SECURITY_LEVEL_SOFTWARE};
+  keymaster::AndroidKeymaster keymaster{&keymaster_context, kOperationTableSize};
+
+  CHECK(FLAGS_keymaster_fd != -1)
+      << "TODO(schuffelen): Add keymaster_fd alternative";
+  auto server = cvd::SharedFD::Dup(FLAGS_keymaster_fd);
+  CHECK(server->IsOpen()) << "Could not dup server fd: " << server->StrError();
+  close(FLAGS_keymaster_fd);
+  auto conn = cvd::SharedFD::Accept(*server);
+  CHECK(conn->IsOpen()) << "Unable to open connection: " << conn->StrError();
+  cvd::KeymasterChannel keymaster_channel(conn);
+
+  KeymasterResponder keymaster_responder(&keymaster_channel, &keymaster);
+
+  // TODO(schuffelen): Do this in a thread when adding other HALs
+  while (keymaster_responder.ProcessMessage()) {
+  }
 }
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index d801ca0..af27987 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -181,6 +181,7 @@
 const char* kKeyboardServerPort = "keyboard_server_port";
 
 const char* kRilDns = "ril_dns";
+const char* kKeymasterVsockPort = "keymaster_vsock_port";
 }  // namespace
 
 namespace vsoc {
@@ -646,6 +647,14 @@
   (*Dictionary())[kKeyboardServerPort] = keyboard_server_port;
 }
 
+int CuttlefishConfig::InstanceSpecific::keymaster_vsock_port() const {
+  return (*Dictionary())[kKeymasterVsockPort].asInt();
+}
+
+void CuttlefishConfig::MutableInstanceSpecific::set_keymaster_vsock_port(int keymaster_vsock_port) {
+  (*Dictionary())[kKeymasterVsockPort] = keymaster_vsock_port;
+}
+
 int CuttlefishConfig::InstanceSpecific::tombstone_receiver_port() const {
   return (*Dictionary())[kTombstoneReceiverPort].asInt();
 }
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index d5a01d6..2ff6500 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -361,6 +361,8 @@
     int host_port() const;
     // Port number to connect to the tpm server on the host
     int tpm_port() const;
+    // Port number to connect to the keymaster server on the host
+    int keymaster_vsock_port() const;
     std::string adb_ip_and_port() const;
     std::string adb_device_name() const;
     std::string device_title() const;
@@ -427,6 +429,7 @@
     void set_frames_server_port(int config_server_port);
     void set_touch_server_port(int config_server_port);
     void set_keyboard_server_port(int config_server_port);
+    void set_keymaster_vsock_port(int keymaster_vsock_port);
     void set_host_port(int host_port);
     void set_tpm_port(int tpm_port);
     void set_adb_ip_and_port(const std::string& ip_port);
diff --git a/host/libs/config/kernel_args.cpp b/host/libs/config/kernel_args.cpp
index a067d2b..b6590ba 100644
--- a/host/libs/config/kernel_args.cpp
+++ b/host/libs/config/kernel_args.cpp
@@ -103,6 +103,9 @@
     kernel_cmdline.push_back(concat("androidboot.vsock_frames_port=", instance.frames_server_port()));
   }
 
+  kernel_cmdline.push_back(concat("androidboot.vsock_keymaster_port=",
+                                  instance.keymaster_vsock_port()));
+
   AppendVector(&kernel_cmdline, config.extra_kernel_cmdline());
 
   return kernel_cmdline;