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;