aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-10-10 23:04:08 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-10-10 23:04:08 +0000
commit54dd8434b2a7ee3b78c1c3607c06236a77372017 (patch)
treec53d5f9da36d7a35b011d047c95e42a5ccf11120
parentb9fc3f11740454e84a1743fa77e5dbfd6fc4f1c6 (diff)
parent198f9f77e9c9baf39a361fcfed9043d9c5793592 (diff)
downloadcuttlefish-android14-qpr1-s2-release.tar.gz
Change-Id: I716fb85fae7d0489c1727fafbcfc64c38d2ecc63
-rw-r--r--common/libs/security/Android.bp2
-rw-r--r--common/libs/security/channel.cpp32
-rw-r--r--common/libs/security/channel.h68
-rw-r--r--common/libs/security/channel_sharedfd.cpp85
-rw-r--r--common/libs/security/channel_sharedfd.h40
-rw-r--r--common/libs/security/oemlock.h30
-rw-r--r--guest/hals/keymint/rust/src/keymint_hal_main.rs2
-rw-r--r--guest/hals/oemlock/remote/Android.bp42
-rw-r--r--guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.rc4
-rw-r--r--guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.xml10
-rw-r--r--guest/hals/oemlock/remote/remote_oemlock.cpp93
-rw-r--r--guest/hals/oemlock/remote/remote_oemlock.h55
-rw-r--r--guest/hals/oemlock/remote/service.cpp51
-rw-r--r--host/commands/run_cvd/Android.bp29
-rw-r--r--host/commands/run_cvd/launch/secure_env.cpp18
-rw-r--r--host/commands/run_cvd/server_loop.cpp4
-rw-r--r--host/commands/secure_env/Android.bp1
-rw-r--r--host/commands/secure_env/doc/linkage.dot24
-rw-r--r--host/commands/secure_env/doc/linkage.pngbin80403 -> 100802 bytes
-rw-r--r--host/commands/secure_env/doc/linkage.svg315
-rw-r--r--host/commands/secure_env/oemlock.h38
-rw-r--r--host/commands/secure_env/oemlock_responder.cpp65
-rw-r--r--host/commands/secure_env/oemlock_responder.h38
-rw-r--r--host/commands/secure_env/rust/lib.rs2
-rw-r--r--host/commands/secure_env/secure_env_linux_main.cpp155
-rw-r--r--host/commands/secure_env/soft_oemlock.h53
-rw-r--r--host/libs/config/cuttlefish_config.cpp2
-rw-r--r--host/libs/config/cuttlefish_config.h1
-rw-r--r--host/libs/vm_manager/crosvm_manager.cpp21
-rw-r--r--host/libs/vm_manager/qemu_manager.cpp16
-rw-r--r--host/libs/vm_manager/vm_manager.h16
-rw-r--r--shared/config/ueventd.rc8
-rw-r--r--shared/device.mk26
-rw-r--r--shared/sepolicy/vendor/file_contexts10
-rw-r--r--shared/sepolicy/vendor/genfs_contexts14
-rw-r--r--shared/sepolicy/vendor/hal_keymint_rust.te18
-rw-r--r--shared/sepolicy/vendor/hal_oemlock_remote.te14
-rw-r--r--shared/sepolicy/vendor/init.te2
-rw-r--r--shared/sepolicy/vendor/ueventd.te2
-rw-r--r--tests/hal/hal_implementation_test.cpp2
40 files changed, 1160 insertions, 248 deletions
diff --git a/common/libs/security/Android.bp b/common/libs/security/Android.bp
index 758b8bf72..dcc5b705e 100644
--- a/common/libs/security/Android.bp
+++ b/common/libs/security/Android.bp
@@ -21,6 +21,7 @@ cc_library {
name: "libcuttlefish_security",
defaults: ["hidl_defaults", "cuttlefish_host"],
srcs: [
+ "channel.cpp",
"gatekeeper_channel.cpp",
"keymaster_channel.cpp",
],
@@ -39,6 +40,7 @@ cc_library {
"libcuttlefish_fs",
],
srcs: [
+ "channel_sharedfd.cpp",
"confui_sign.cpp",
"gatekeeper_channel_sharedfd.cpp",
"keymaster_channel_sharedfd.cpp",
diff --git a/common/libs/security/channel.cpp b/common/libs/security/channel.cpp
new file mode 100644
index 000000000..009617da1
--- /dev/null
+++ b/common/libs/security/channel.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 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 "common/libs/security/channel.h"
+
+#include "keymaster/android_keymaster_utils.h"
+
+namespace cuttlefish {
+namespace secure_env {
+
+void MessageDestroyer::operator()(RawMessage* ptr) {
+ {
+ keymaster::Eraser(ptr, sizeof(RawMessage) + ptr->payload_size);
+ }
+ std::free(ptr);
+}
+
+} // namespace secure_env
+} // namespace cuttlefish \ No newline at end of file
diff --git a/common/libs/security/channel.h b/common/libs/security/channel.h
new file mode 100644
index 000000000..bbfb86779
--- /dev/null
+++ b/common/libs/security/channel.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2023 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 <memory>
+
+#include "common/libs/utils/result.h"
+
+namespace cuttlefish {
+namespace secure_env {
+
+/**
+ * RawMessage - Header and raw byte payload for a serialized
+ * secure env message.
+ *
+ * @command: the command.
+ * @is_response: flag to mark message as a request/response.
+ * @payload_size: amount of payload data we're going to transfer.
+ * @payload: start of the serialized command specific payload.
+ */
+struct RawMessage {
+ uint32_t command : 31;
+ bool is_response : 1;
+ uint32_t payload_size;
+ uint8_t payload[0];
+};
+
+/**
+ * A destroyer for RawMessage instances created with
+ * CreateMessage. Wipes memory from the RawMessage
+ * instances.
+ */
+class MessageDestroyer {
+ public:
+ void operator()(RawMessage* ptr);
+};
+
+/** An owning pointer for a RawMessage instance. */
+using ManagedMessage = std::unique_ptr<RawMessage, MessageDestroyer>;
+
+/*
+ * Interface for communication channels that synchronously communicate
+ * HAL IPC/RPC calls.
+ */
+class Channel {
+ public:
+ virtual Result<void> SendRequest(uint32_t command, void* message, size_t message_size) = 0;
+ virtual Result<void> SendResponse(uint32_t command, void* message, size_t message_size) = 0;
+ virtual Result<ManagedMessage> ReceiveMessage() = 0;
+ virtual ~Channel() {}
+};
+
+} // namespace secure_env
+} // namespace cuttlefish \ No newline at end of file
diff --git a/common/libs/security/channel_sharedfd.cpp b/common/libs/security/channel_sharedfd.cpp
new file mode 100644
index 000000000..c07d876b0
--- /dev/null
+++ b/common/libs/security/channel_sharedfd.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2023 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 "common/libs/security/channel_sharedfd.h"
+
+#include "common/libs/fs/shared_buf.h"
+
+namespace cuttlefish {
+namespace secure_env {
+namespace {
+
+/**
+ * Allocates memory for a RawMessage carrying a message of size
+ * `payload_size`.
+ */
+Result<ManagedMessage> CreateMessage(uint32_t command, bool is_response, size_t payload_size) {
+ const auto bytes_to_allocate = sizeof(RawMessage) + payload_size;
+ auto memory = std::malloc(bytes_to_allocate);
+ CF_EXPECT(memory != nullptr,
+ "Cannot allocate " << bytes_to_allocate << " bytes for secure_env RPC message");
+ auto message = reinterpret_cast<RawMessage*>(memory);
+ message->command = command;
+ message->is_response = is_response;
+ message->payload_size = payload_size;
+ return ManagedMessage(message);
+}
+
+}
+
+SharedFdChannel::SharedFdChannel(SharedFD input, SharedFD output)
+ : input_(std::move(input)), output_(std::move(output)) {}
+
+Result<void> SharedFdChannel::SendRequest(uint32_t command, void* message, size_t message_size) {
+ return SendMessage(command, false, message, message_size);
+}
+
+Result<void> SharedFdChannel::SendResponse(uint32_t command, void* message, size_t message_size) {
+ return SendMessage(command, true, message, message_size);
+}
+
+Result<ManagedMessage> SharedFdChannel::ReceiveMessage() {
+ struct RawMessage message_header;
+ auto read = ReadExactBinary(input_, &message_header);
+ CF_EXPECT(read == sizeof(RawMessage),
+ "Expected " << sizeof(RawMessage) << ", received " << read << "\n" <<
+ "Could not read message: " << input_->StrError());
+ LOG(DEBUG) << "Received message with id: " << message_header.command;
+
+ auto message = CF_EXPECT(CreateMessage(message_header.command, message_header.is_response,
+ message_header.payload_size));
+ auto message_bytes = reinterpret_cast<char*>(message->payload);
+ read = ReadExact(input_, message_bytes, message->payload_size);
+ CF_EXPECT(read == message->payload_size,
+ "Could not read message: " << input_->StrError());
+
+ return message;
+}
+
+Result<void> SharedFdChannel::SendMessage(uint32_t command, bool response,
+ void* message, size_t message_size) {
+ auto to_send = CF_EXPECT(CreateMessage(command, response, message_size));
+ memcpy(to_send->payload, message, message_size);
+ auto write_size = sizeof(RawMessage) + message_size;
+ auto to_send_bytes = reinterpret_cast<const char*>(to_send.get());
+ auto written = WriteAll(output_, to_send_bytes, write_size);
+ CF_EXPECT(written != -1,
+ "Could not write message: " << output_->StrError());
+ return {};
+}
+
+} // namespace secure_env
+} // namespace cuttlefish \ No newline at end of file
diff --git a/common/libs/security/channel_sharedfd.h b/common/libs/security/channel_sharedfd.h
new file mode 100644
index 000000000..3d0fdbcda
--- /dev/null
+++ b/common/libs/security/channel_sharedfd.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 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 "common/libs/fs/shared_fd.h"
+#include "common/libs/security/channel.h"
+
+namespace cuttlefish {
+namespace secure_env {
+
+class SharedFdChannel : public Channel {
+ public:
+ SharedFdChannel(SharedFD input, SharedFD output);
+ Result<void> SendRequest(uint32_t command, void* message, size_t message_size) override;
+ Result<void> SendResponse(uint32_t command, void* message, size_t message_size) override;
+ Result<ManagedMessage> ReceiveMessage() override;
+
+ private:
+ SharedFD input_;
+ SharedFD output_;
+
+ Result<void> SendMessage(uint32_t command, bool response, void* message, size_t message_size);
+};
+
+} // namespace secure_env
+} // namespace cuttlefish \ No newline at end of file
diff --git a/common/libs/security/oemlock.h b/common/libs/security/oemlock.h
new file mode 100644
index 000000000..ab980a90e
--- /dev/null
+++ b/common/libs/security/oemlock.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 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 <memory>
+
+namespace cuttlefish {
+namespace secure_env {
+
+enum class OemLockField : uint32_t {
+ ALLOWED_BY_CARRIER = 0,
+ ALLOWED_BY_DEVICE = 1,
+};
+
+} // namespace secure_env
+} // namespace cuttlefish \ No newline at end of file
diff --git a/guest/hals/keymint/rust/src/keymint_hal_main.rs b/guest/hals/keymint/rust/src/keymint_hal_main.rs
index 08709b7ae..ff4df214b 100644
--- a/guest/hals/keymint/rust/src/keymint_hal_main.rs
+++ b/guest/hals/keymint/rust/src/keymint_hal_main.rs
@@ -23,7 +23,7 @@ use std::panic;
use std::sync::{Arc, Mutex};
/// Device file used to communicate with the KeyMint TA.
-static DEVICE_FILE_NAME: &str = "/dev/hvc3";
+static DEVICE_FILE_NAME: &str = "/dev/hvc11";
/// Name of KeyMint binder device instance.
static SERVICE_INSTANCE: &str = "default";
diff --git a/guest/hals/oemlock/remote/Android.bp b/guest/hals/oemlock/remote/Android.bp
new file mode 100644
index 000000000..6c2f3b98f
--- /dev/null
+++ b/guest/hals/oemlock/remote/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2023 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.
+//
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.oemlock-service.remote",
+ defaults: ["cuttlefish_guest_only"],
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.oemlock-service.remote.rc"],
+
+ srcs: [
+ "remote_oemlock.cpp",
+ "service.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.oemlock-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libcuttlefish_fs",
+ "libcuttlefish_security",
+ ],
+
+ vintf_fragments: ["android.hardware.oemlock-service.remote.xml"],
+}
diff --git a/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.rc b/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.rc
new file mode 100644
index 000000000..15963aaa5
--- /dev/null
+++ b/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.rc
@@ -0,0 +1,4 @@
+service vendor.oemlock_default /vendor/bin/hw/android.hardware.oemlock-service.remote /dev/hvc10
+ class hal
+ user hsm
+ group hsm
diff --git a/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.xml b/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.xml
new file mode 100644
index 000000000..d5905d838
--- /dev/null
+++ b/guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.oemlock</name>
+ <version>1</version>
+ <interface>
+ <name>IOemLock</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/guest/hals/oemlock/remote/remote_oemlock.cpp b/guest/hals/oemlock/remote/remote_oemlock.cpp
new file mode 100644
index 000000000..f427ec028
--- /dev/null
+++ b/guest/hals/oemlock/remote/remote_oemlock.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 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 "guest/hals/oemlock/remote/remote_oemlock.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace oemlock {
+namespace {
+
+enum {
+ CUSTOM_ERROR_TRANSPORT_IS_FAILED = 0,
+};
+
+::ndk::ScopedAStatus resultToStatus(Result<void> r) {
+ if (r.ok())
+ return ::ndk::ScopedAStatus::ok();
+ else
+ return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ CUSTOM_ERROR_TRANSPORT_IS_FAILED, r.error().Message().c_str());
+}
+
+}
+
+OemLock::OemLock(secure_env::Channel& channel) : channel_(channel) {}
+
+::ndk::ScopedAStatus OemLock::getName(std::string *out_name) {
+ *out_name = "CF Remote Implementation";
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByCarrier(bool in_allowed,
+ const std::vector<uint8_t> &,
+ OemLockSecureStatus *_aidl_return) {
+ *_aidl_return = OemLockSecureStatus::OK;
+ return resultToStatus(setValue(secure_env::OemLockField::ALLOWED_BY_CARRIER, in_allowed));
+}
+
+::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByCarrier(bool *out_allowed) {
+ return resultToStatus(requestValue(secure_env::OemLockField::ALLOWED_BY_CARRIER, out_allowed));
+}
+
+::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByDevice(bool in_allowed) {
+ return resultToStatus(setValue(secure_env::OemLockField::ALLOWED_BY_DEVICE, in_allowed));
+}
+
+::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByDevice(bool *out_allowed) {
+ return resultToStatus(requestValue(secure_env::OemLockField::ALLOWED_BY_DEVICE, out_allowed));
+}
+
+Result<void> OemLock::requestValue(secure_env::OemLockField field, bool *out) {
+ CF_EXPECT(channel_.SendRequest(static_cast<uint32_t>(field), nullptr, 0),
+ "Can't send get value request for field: " << static_cast<uint32_t>(field));
+ auto response = CF_EXPECT(channel_.ReceiveMessage(),
+ "Haven't received an answer for getting the field: " <<
+ static_cast<uint32_t>(field));
+ *out = *reinterpret_cast<bool*>(response->payload);
+ return {};
+}
+
+Result<void> OemLock::setValue(secure_env::OemLockField field, bool value) {
+ CF_EXPECT(channel_.SendRequest(static_cast<uint32_t>(field), &value, sizeof(bool)),
+ "Can't send set value request for field: " << static_cast<uint32_t>(field));
+ auto response = CF_EXPECT(channel_.ReceiveMessage(),
+ "Haven't received an answer for setting the field: " <<
+ static_cast<uint32_t>(field));
+ auto updated_value = *reinterpret_cast<bool*>(response->payload);
+ CF_EXPECT(value == updated_value,
+ "Updated value for the field " << static_cast<uint32_t>(field) <<
+ " is different from what we wated to set");
+ return {};
+}
+
+} // namespace oemlock
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/guest/hals/oemlock/remote/remote_oemlock.h b/guest/hals/oemlock/remote/remote_oemlock.h
new file mode 100644
index 000000000..c2aa5cbc0
--- /dev/null
+++ b/guest/hals/oemlock/remote/remote_oemlock.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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 <aidl/android/hardware/oemlock/BnOemLock.h>
+
+#include "common/libs/security/channel.h"
+#include "common/libs/security/oemlock.h"
+#include "common/libs/utils/result.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace oemlock {
+
+using namespace cuttlefish;
+
+struct OemLock : public BnOemLock {
+public:
+ OemLock(secure_env::Channel& channel);
+
+ // Methods from ::android::hardware::oemlock::IOemLock follow.
+ ::ndk::ScopedAStatus getName(std::string* out_name) override;
+ ::ndk::ScopedAStatus isOemUnlockAllowedByCarrier(bool* out_allowed) override;
+ ::ndk::ScopedAStatus isOemUnlockAllowedByDevice(bool* out_allowed) override;
+ ::ndk::ScopedAStatus setOemUnlockAllowedByCarrier(bool in_allowed,
+ const std::vector<uint8_t>&,
+ OemLockSecureStatus* _aidl_return) override;
+ ::ndk::ScopedAStatus setOemUnlockAllowedByDevice(bool in_allowed) override;
+
+private:
+ secure_env::Channel& channel_;
+
+ Result<void> requestValue(secure_env::OemLockField field, bool *out);
+ Result<void> setValue(secure_env::OemLockField field, bool value);
+};
+
+} // namespace oemlock
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/guest/hals/oemlock/remote/service.cpp b/guest/hals/oemlock/remote/service.cpp
new file mode 100644
index 000000000..d1eefefd2
--- /dev/null
+++ b/guest/hals/oemlock/remote/service.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/security/channel_sharedfd.h"
+#include "guest/hals/oemlock/remote/remote_oemlock.h"
+
+using ::aidl::android::hardware::oemlock::OemLock;
+
+int main(int argc, char *argv[]) {
+ ::android::base::InitLogging(argv, ::android::base::KernelLogger);
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ if (argc != 2) {
+ LOG(FATAL) << "Cuttlefish OemLock HAL requires to have hvc path as a first argument";
+ }
+ const auto fd = cuttlefish::SharedFD::Open(argv[1], O_RDWR);
+ if (!fd->IsOpen()) {
+ LOG(FATAL) << "Could not connect to oemlock: " << fd->StrError();
+ }
+ if (fd->SetTerminalRaw() < 0) {
+ LOG(FATAL) << "Could not make " << argv[1] << " a raw terminal: " << fd->StrError();
+ }
+
+ cuttlefish::secure_env::SharedFdChannel channel(fd, fd);
+ std::shared_ptr<OemLock> oemlock = ndk::SharedRefBase::make<OemLock>(channel);
+
+ const std::string instance = std::string() + OemLock::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(oemlock->asBinder().get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return -1; // Should never be reached
+}
diff --git a/host/commands/run_cvd/Android.bp b/host/commands/run_cvd/Android.bp
index 6f871141a..335a51f34 100644
--- a/host/commands/run_cvd/Android.bp
+++ b/host/commands/run_cvd/Android.bp
@@ -17,34 +17,6 @@ package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
-// Allow the KeyMint reference implementation to be selected at build time.
-soong_config_module_type {
- name: "keymint_impl_defaults",
- module_type: "cc_defaults",
- config_namespace: "secure_env",
- variables: ["keymint_impl"],
- properties: ["cflags"],
-}
-
-soong_config_string_variable {
- name: "keymint_impl",
- values: ["rust", "cpp"],
-}
-
-keymint_impl_defaults {
- name: "secure_env_keymint_impl_defaults",
- soong_config_variables: {
- keymint_impl: {
- rust: {
- cflags: ["-DCUTTLEFISH_KEYMINT_RUST",],
- },
- cpp: {},
- conditions_default: {},
- },
- },
-}
-
-
cc_binary {
name: "run_cvd",
srcs: [
@@ -100,6 +72,5 @@ cc_binary {
"cuttlefish_host",
"cuttlefish_libicuuc",
"cvd_cc_defaults",
- "secure_env_keymint_impl_defaults",
],
}
diff --git a/host/commands/run_cvd/launch/secure_env.cpp b/host/commands/run_cvd/launch/secure_env.cpp
index b5e0cf89d..a70fc1445 100644
--- a/host/commands/run_cvd/launch/secure_env.cpp
+++ b/host/commands/run_cvd/launch/secure_env.cpp
@@ -46,18 +46,22 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer {
command.AddParameter("-keymaster_fd_in=", fifos_[1]);
command.AddParameter("-gatekeeper_fd_out=", fifos_[2]);
command.AddParameter("-gatekeeper_fd_in=", fifos_[3]);
+ command.AddParameter("-oemlock_fd_out=", fifos_[4]);
+ command.AddParameter("-oemlock_fd_in=", fifos_[5]);
+ command.AddParameter("-keymint_fd_out=", fifos_[6]);
+ command.AddParameter("-keymint_fd_in=", fifos_[7]);
const auto& secure_hals = config_.secure_hals();
bool secure_keymint = secure_hals.count(SecureHal::Keymint) > 0;
-#ifdef CUTTLEFISH_KEYMINT_RUST
- command.AddParameter("-keymint_impl=",
- secure_keymint ? "rust-tpm" : "rust-software");
-#else
command.AddParameter("-keymint_impl=", secure_keymint ? "tpm" : "software");
-#endif
bool secure_gatekeeper = secure_hals.count(SecureHal::Gatekeeper) > 0;
auto gatekeeper_impl = secure_gatekeeper ? "tpm" : "software";
command.AddParameter("-gatekeeper_impl=", gatekeeper_impl);
+
+ bool secure_oemlock = secure_hals.count(SecureHal::Oemlock) > 0;
+ auto oemlock_impl = secure_oemlock ? "tpm" : "software";
+ command.AddParameter("-oemlock_impl=", oemlock_impl);
+
command.AddParameter("-kernel_events_fd=", kernel_log_pipe_);
std::vector<MonitorCommand> commands;
@@ -79,6 +83,10 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer {
instance_.PerInstanceInternalPath("keymaster_fifo_vm.out"),
instance_.PerInstanceInternalPath("gatekeeper_fifo_vm.in"),
instance_.PerInstanceInternalPath("gatekeeper_fifo_vm.out"),
+ instance_.PerInstanceInternalPath("oemlock_fifo_vm.in"),
+ instance_.PerInstanceInternalPath("oemlock_fifo_vm.out"),
+ instance_.PerInstanceInternalPath("keymint_fifo_vm.in"),
+ instance_.PerInstanceInternalPath("keymint_fifo_vm.out"),
};
std::vector<SharedFD> fifos;
for (const auto& path : fifo_paths) {
diff --git a/host/commands/run_cvd/server_loop.cpp b/host/commands/run_cvd/server_loop.cpp
index 634767045..b716e3358 100644
--- a/host/commands/run_cvd/server_loop.cpp
+++ b/host/commands/run_cvd/server_loop.cpp
@@ -211,8 +211,12 @@ class ServerLoopImpl : public ServerLoop,
instance_.logcat_pipe_name(),
instance_.PerInstanceInternalPath("keymaster_fifo_vm.in"),
instance_.PerInstanceInternalPath("keymaster_fifo_vm.out"),
+ instance_.PerInstanceInternalPath("keymint_fifo_vm.in"),
+ instance_.PerInstanceInternalPath("keymint_fifo_vm.out"),
instance_.PerInstanceInternalPath("gatekeeper_fifo_vm.in"),
instance_.PerInstanceInternalPath("gatekeeper_fifo_vm.out"),
+ instance_.PerInstanceInternalPath("oemlock_fifo_vm.in"),
+ instance_.PerInstanceInternalPath("oemlock_fifo_vm.out"),
instance_.PerInstanceInternalPath("bt_fifo_vm.in"),
instance_.PerInstanceInternalPath("bt_fifo_vm.out"),
instance_.PerInstanceInternalPath("uwb_fifo_vm.in"),
diff --git a/host/commands/secure_env/Android.bp b/host/commands/secure_env/Android.bp
index 94728747e..73d443b17 100644
--- a/host/commands/secure_env/Android.bp
+++ b/host/commands/secure_env/Android.bp
@@ -77,6 +77,7 @@ common_libsecure_srcs = [
"insecure_fallback_storage.cpp",
"json_serializable.cpp",
"keymaster_responder.cpp",
+ "oemlock_responder.cpp",
"primary_key_builder.cpp",
"tpm_attestation_record.cpp",
"tpm_auth.cpp",
diff --git a/host/commands/secure_env/doc/linkage.dot b/host/commands/secure_env/doc/linkage.dot
index 069ff82cb..9c9378cbb 100644
--- a/host/commands/secure_env/doc/linkage.dot
+++ b/host/commands/secure_env/doc/linkage.dot
@@ -9,12 +9,14 @@ digraph {
subgraph fifos {
rank = same;
- host_keymint_in [color = "blue", label = "internal/keymaster_fifo_vm.in", shape = "rectangle"]
- host_keymint_out [color = "blue", label = "internal/keymaster_fifo_vm.out", shape = "rectangle"]
+ host_keymaster_in [color = "blue", label = "internal/keymaster_fifo_vm.in", shape = "rectangle"]
+ host_keymaster_out [color = "blue", label = "internal/keymaster_fifo_vm.out", shape = "rectangle"]
host_gatekeeper_in [color = "green", label = "internal/gatekeeper_fifo_vm.in", shape = "rectangle"]
host_gatekeeper_out [color = "green", label = "internal/gatekeeper_fifo_vm.out", shape = "rectangle"]
host_confirmationui_in [color = "red", label = "internal/confui_fifo_vm.in", shape = "rectangle"]
host_confirmationui_out [color = "red", label = "internal/confui_fifo_vm.out", shape = "rectangle"]
+ host_keymint_in [color = "blue", label = "internal/keymint_fifo_vm.in", shape = "rectangle"]
+ host_keymint_out [color = "blue", label = "internal/keymint_fifo_vm.out", shape = "rectangle"]
}
subgraph cluster_android {
@@ -22,13 +24,19 @@ digraph {
u_boot [label = "u-boot"]
confirmationui [color = "red", label = "ConfirmationUI HAL"]
gatekeeper [color = "green", label = "Gatekeeper HAL"]
- keymint [color = "blue", label = "Keymint HAL"]
+ subgraph cluster_keymint {
+ graph[style=dotted]
+ label = "One of:"
+ keymaster [color = "blue", label = "KeyMint (C++) HAL"]
+ keymint [color = "blue", label = "KeyMint (Rust) HAL"]
+ }
subgraph consoles {
- rank = same;
+ rank = same;
confirmationui_console [color = "red", label = "/dev/hvc8", shape = "rectangle"]
gatekeeper_console [color = "green", label = "/dev/hvc4", shape = "rectangle"]
- keymint_console [color = "blue", label = "/dev/hvc3", shape = "rectangle"]
+ keymaster_console [color = "blue", label = "/dev/hvc3", shape = "rectangle"]
+ keymint_console [color = "blue", label = "/dev/hvc11", shape = "rectangle"]
}
}
@@ -44,9 +52,13 @@ digraph {
secure_env -> host_gatekeeper_in -> vmm [color = "green"]
vmm -> gatekeeper_console -> gatekeeper [color = "green", dir = "both"]
+ secure_env -> host_keymaster_out -> vmm [color = "blue", dir = "back"]
+ secure_env -> host_keymaster_in -> vmm [color = "blue"]
+ vmm -> keymaster_console -> keymaster [color = "blue", dir = "both"]
+ keymaster_console -> u_boot [color = "blue", dir = "both"]
+
secure_env -> host_keymint_out -> vmm [color = "blue", dir = "back"]
secure_env -> host_keymint_in -> vmm [color = "blue"]
vmm -> keymint_console -> keymint [color = "blue", dir = "both"]
- keymint_console -> u_boot [color = "blue", dir = "both"]
}
diff --git a/host/commands/secure_env/doc/linkage.png b/host/commands/secure_env/doc/linkage.png
index 254956909..10fba9a44 100644
--- a/host/commands/secure_env/doc/linkage.png
+++ b/host/commands/secure_env/doc/linkage.png
Binary files differ
diff --git a/host/commands/secure_env/doc/linkage.svg b/host/commands/secure_env/doc/linkage.svg
index 6bb643f20..f0ab64040 100644
--- a/host/commands/secure_env/doc/linkage.svg
+++ b/host/commands/secure_env/doc/linkage.svg
@@ -4,278 +4,345 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: %3 Pages: 1 -->
-<svg width="1180pt" height="423pt"
- viewBox="0.00 0.00 1179.50 423.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 419)">
+<svg width="1567pt" height="434pt"
+ viewBox="0.00 0.00 1566.50 434.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 430)">
<title>%3</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-419 1175.5,-419 1175.5,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-430 1562.5,-430 1562.5,4 -4,4"/>
<g id="clust2" class="cluster">
<title>cluster_android</title>
-<polygon fill="none" stroke="black" points="297.5,-8 297.5,-155 879.5,-155 879.5,-8 297.5,-8"/>
-<text text-anchor="middle" x="588.5" y="-139.8" font-family="Times,serif" font-size="14.00">Android VM</text>
+<polygon fill="none" stroke="black" points="319.5,-8 319.5,-166 1154.5,-166 1154.5,-8 319.5,-8"/>
+<text text-anchor="middle" x="737" y="-150.8" font-family="Times,serif" font-size="14.00">Android VM</text>
+</g>
+<g id="clust3" class="cluster">
+<title>cluster_keymint</title>
+<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="327.5,-16 327.5,-91 713.5,-91 713.5,-16 327.5,-16"/>
+<text text-anchor="middle" x="520.5" y="-75.8" font-family="Times,serif" font-size="14.00">One of:</text>
</g>
<!-- browser -->
<g id="node1" class="node">
<title>browser</title>
-<ellipse fill="none" stroke="black" cx="904.5" cy="-397" rx="40.09" ry="18"/>
-<text text-anchor="middle" x="904.5" y="-393.3" font-family="Times,serif" font-size="14.00">Browser</text>
+<ellipse fill="none" stroke="black" cx="1291.5" cy="-408" rx="40.09" ry="18"/>
+<text text-anchor="middle" x="1291.5" y="-404.3" font-family="Times,serif" font-size="14.00">Browser</text>
</g>
<!-- webRTC -->
<g id="node6" class="node">
<title>webRTC</title>
-<ellipse fill="none" stroke="black" cx="904.5" cy="-325" rx="42.49" ry="18"/>
-<text text-anchor="middle" x="904.5" y="-321.3" font-family="Times,serif" font-size="14.00">webRTC</text>
+<ellipse fill="none" stroke="black" cx="1291.5" cy="-336" rx="42.49" ry="18"/>
+<text text-anchor="middle" x="1291.5" y="-332.3" font-family="Times,serif" font-size="14.00">webRTC</text>
</g>
<!-- browser&#45;&gt;webRTC -->
<g id="edge1" class="edge">
<title>browser&#45;&gt;webRTC</title>
-<path fill="none" stroke="black" d="M904.5,-378.7C904.5,-370.98 904.5,-361.71 904.5,-353.11"/>
-<polygon fill="black" stroke="black" points="908,-353.1 904.5,-343.1 901,-353.1 908,-353.1"/>
+<path fill="none" stroke="black" d="M1291.5,-389.7C1291.5,-381.98 1291.5,-372.71 1291.5,-364.11"/>
+<polygon fill="black" stroke="black" points="1295,-364.1 1291.5,-354.1 1288,-364.1 1295,-364.1"/>
</g>
<!-- confirmationui_sign -->
<g id="node2" class="node">
<title>confirmationui_sign</title>
-<polygon fill="none" stroke="red" points="788.5,-343 634.5,-343 634.5,-307 788.5,-307 788.5,-343"/>
-<text text-anchor="middle" x="711.5" y="-321.3" font-family="Times,serif" font-size="14.00">internal/confui_sign.sock</text>
+<polygon fill="none" stroke="red" points="1085.5,-354 931.5,-354 931.5,-318 1085.5,-318 1085.5,-354"/>
+<text text-anchor="middle" x="1008.5" y="-332.3" font-family="Times,serif" font-size="14.00">internal/confui_sign.sock</text>
</g>
<!-- confirmationui_sign&#45;&gt;webRTC -->
<g id="edge10" class="edge">
<title>confirmationui_sign&#45;&gt;webRTC</title>
-<path fill="none" stroke="red" d="M798.79,-325C816.4,-325 834.02,-325 851.64,-325"/>
-<polygon fill="red" stroke="red" points="798.78,-321.5 788.78,-325 798.78,-328.5 798.78,-321.5"/>
-<polygon fill="red" stroke="red" points="852.01,-328.5 862.01,-325 852.01,-321.5 852.01,-328.5"/>
+<path fill="none" stroke="red" d="M1095.81,-336C1143.44,-336 1191.08,-336 1238.71,-336"/>
+<polygon fill="red" stroke="red" points="1095.61,-332.5 1085.61,-336 1095.61,-339.5 1095.61,-332.5"/>
+<polygon fill="red" stroke="red" points="1238.87,-339.5 1248.87,-336 1238.87,-332.5 1238.87,-339.5"/>
</g>
<!-- run_cvd -->
<g id="node3" class="node">
<title>run_cvd</title>
-<ellipse fill="none" stroke="black" cx="502.5" cy="-397" rx="39.79" ry="18"/>
-<text text-anchor="middle" x="502.5" y="-393.3" font-family="Times,serif" font-size="14.00">run_cvd</text>
+<ellipse fill="none" stroke="black" cx="709.5" cy="-408" rx="39.79" ry="18"/>
+<text text-anchor="middle" x="709.5" y="-404.3" font-family="Times,serif" font-size="14.00">run_cvd</text>
</g>
<!-- secure_env -->
<g id="node4" class="node">
<title>secure_env</title>
-<ellipse fill="none" stroke="black" stroke-width="2" cx="502.5" cy="-325" rx="57.39" ry="18"/>
-<text text-anchor="start" x="466.5" y="-322.3" font-family="Times,serif" font-size="14.00"> </text>
-<text text-anchor="start" x="470.5" y="-322.3" font-family="Times,serif" font-weight="bold" font-size="14.00">secure_env</text>
-<text text-anchor="start" x="534.5" y="-322.3" font-family="Times,serif" font-size="14.00"> </text>
+<ellipse fill="none" stroke="black" stroke-width="2" cx="709.5" cy="-336" rx="57.39" ry="18"/>
+<text text-anchor="start" x="673.5" y="-333.3" font-family="Times,serif" font-size="14.00"> </text>
+<text text-anchor="start" x="677.5" y="-333.3" font-family="Times,serif" font-weight="bold" font-size="14.00">secure_env</text>
+<text text-anchor="start" x="741.5" y="-333.3" font-family="Times,serif" font-size="14.00"> </text>
</g>
<!-- run_cvd&#45;&gt;secure_env -->
<g id="edge2" class="edge">
<title>run_cvd&#45;&gt;secure_env</title>
-<path fill="none" stroke="black" d="M502.5,-378.7C502.5,-370.98 502.5,-361.71 502.5,-353.11"/>
-<polygon fill="black" stroke="black" points="506,-353.1 502.5,-343.1 499,-353.1 506,-353.1"/>
+<path fill="none" stroke="black" d="M709.5,-389.7C709.5,-381.98 709.5,-372.71 709.5,-364.11"/>
+<polygon fill="black" stroke="black" points="713,-364.1 709.5,-354.1 706,-364.1 713,-364.1"/>
</g>
<!-- secure_env&#45;&gt;confirmationui_sign -->
<g id="edge9" class="edge">
<title>secure_env&#45;&gt;confirmationui_sign</title>
-<path fill="none" stroke="red" d="M570.21,-325C588.23,-325 606.26,-325 624.28,-325"/>
-<polygon fill="red" stroke="red" points="570.06,-321.5 560.06,-325 570.06,-328.5 570.06,-321.5"/>
-<polygon fill="red" stroke="red" points="624.3,-328.5 634.3,-325 624.3,-321.5 624.3,-328.5"/>
+<path fill="none" stroke="red" d="M777,-336C824.94,-336 872.89,-336 920.83,-336"/>
+<polygon fill="red" stroke="red" points="776.73,-332.5 766.73,-336 776.73,-339.5 776.73,-332.5"/>
+<polygon fill="red" stroke="red" points="921.06,-339.5 931.06,-336 921.06,-332.5 921.06,-339.5"/>
</g>
-<!-- host_keymint_in -->
+<!-- host_keymaster_in -->
<g id="node7" class="node">
-<title>host_keymint_in</title>
-<polygon fill="none" stroke="blue" points="183,-271 0,-271 0,-235 183,-235 183,-271"/>
-<text text-anchor="middle" x="91.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/keymaster_fifo_vm.in</text>
+<title>host_keymaster_in</title>
+<polygon fill="none" stroke="blue" points="183,-282 0,-282 0,-246 183,-246 183,-282"/>
+<text text-anchor="middle" x="91.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/keymaster_fifo_vm.in</text>
</g>
-<!-- secure_env&#45;&gt;host_keymint_in -->
+<!-- secure_env&#45;&gt;host_keymaster_in -->
<g id="edge19" class="edge">
-<title>secure_env&#45;&gt;host_keymint_in</title>
-<path fill="none" stroke="blue" d="M453.33,-315.63C389.35,-304.73 275.95,-285.41 193.11,-271.31"/>
-<polygon fill="blue" stroke="blue" points="193.61,-267.84 183.17,-269.61 192.44,-274.74 193.61,-267.84"/>
+<title>secure_env&#45;&gt;host_keymaster_in</title>
+<path fill="none" stroke="blue" d="M654.65,-330.55C561.89,-322.77 367.94,-305.39 193.27,-282.05"/>
+<polygon fill="blue" stroke="blue" points="193.5,-278.55 183.12,-280.69 192.56,-285.49 193.5,-278.55"/>
</g>
-<!-- host_keymint_out -->
+<!-- host_keymaster_out -->
<g id="node8" class="node">
-<title>host_keymint_out</title>
-<polygon fill="none" stroke="blue" points="391.5,-271 201.5,-271 201.5,-235 391.5,-235 391.5,-271"/>
-<text text-anchor="middle" x="296.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/keymaster_fifo_vm.out</text>
+<title>host_keymaster_out</title>
+<polygon fill="none" stroke="blue" points="391.5,-282 201.5,-282 201.5,-246 391.5,-246 391.5,-282"/>
+<text text-anchor="middle" x="296.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/keymaster_fifo_vm.out</text>
</g>
-<!-- secure_env&#45;&gt;host_keymint_out -->
+<!-- secure_env&#45;&gt;host_keymaster_out -->
<g id="edge17" class="edge">
-<title>secure_env&#45;&gt;host_keymint_out</title>
-<path fill="none" stroke="blue" d="M455.48,-308.02C423,-296.99 379.85,-282.32 346.71,-271.06"/>
-<polygon fill="blue" stroke="blue" points="454.6,-311.42 465.19,-311.32 456.85,-304.79 454.6,-311.42"/>
+<title>secure_env&#45;&gt;host_keymaster_out</title>
+<path fill="none" stroke="blue" d="M650.46,-324.99C582.95,-313.55 471.47,-294.66 391.65,-281.13"/>
+<polygon fill="blue" stroke="blue" points="650.06,-328.47 660.5,-326.7 651.23,-321.57 650.06,-328.47"/>
</g>
<!-- host_gatekeeper_in -->
<g id="node9" class="node">
<title>host_gatekeeper_in</title>
-<polygon fill="none" stroke="green" points="595,-271 410,-271 410,-235 595,-235 595,-271"/>
-<text text-anchor="middle" x="502.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/gatekeeper_fifo_vm.in</text>
+<polygon fill="none" stroke="green" points="595,-282 410,-282 410,-246 595,-246 595,-282"/>
+<text text-anchor="middle" x="502.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/gatekeeper_fifo_vm.in</text>
</g>
<!-- secure_env&#45;&gt;host_gatekeeper_in -->
<g id="edge13" class="edge">
<title>secure_env&#45;&gt;host_gatekeeper_in</title>
-<path fill="none" stroke="green" d="M502.5,-306.7C502.5,-298.98 502.5,-289.71 502.5,-281.11"/>
-<polygon fill="green" stroke="green" points="506,-281.1 502.5,-271.1 499,-281.1 506,-281.1"/>
+<path fill="none" stroke="green" d="M672.01,-322.32C641.56,-312.02 598.01,-297.3 562.68,-285.35"/>
+<polygon fill="green" stroke="green" points="563.54,-281.95 552.95,-282.06 561.3,-288.58 563.54,-281.95"/>
</g>
<!-- host_gatekeeper_out -->
<g id="node10" class="node">
<title>host_gatekeeper_out</title>
-<polygon fill="none" stroke="green" points="805.5,-271 613.5,-271 613.5,-235 805.5,-235 805.5,-271"/>
-<text text-anchor="middle" x="709.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/gatekeeper_fifo_vm.out</text>
+<polygon fill="none" stroke="green" points="805.5,-282 613.5,-282 613.5,-246 805.5,-246 805.5,-282"/>
+<text text-anchor="middle" x="709.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/gatekeeper_fifo_vm.out</text>
</g>
<!-- secure_env&#45;&gt;host_gatekeeper_out -->
<g id="edge11" class="edge">
<title>secure_env&#45;&gt;host_gatekeeper_out</title>
-<path fill="none" stroke="green" d="M549.75,-308.02C582.38,-296.99 625.74,-282.32 659.05,-271.06"/>
-<polygon fill="green" stroke="green" points="548.34,-304.8 539.99,-311.32 550.58,-311.44 548.34,-304.8"/>
+<path fill="none" stroke="green" d="M709.5,-307.67C709.5,-299.05 709.5,-289.79 709.5,-282.1"/>
+<polygon fill="green" stroke="green" points="706,-307.7 709.5,-317.7 713,-307.7 706,-307.7"/>
+</g>
+<!-- host_keymint_in -->
+<g id="node13" class="node">
+<title>host_keymint_in</title>
+<polygon fill="none" stroke="blue" points="995.5,-282 823.5,-282 823.5,-246 995.5,-246 995.5,-282"/>
+<text text-anchor="middle" x="909.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/keymint_fifo_vm.in</text>
+</g>
+<!-- secure_env&#45;&gt;host_keymint_in -->
+<g id="edge26" class="edge">
+<title>secure_env&#45;&gt;host_keymint_in</title>
+<path fill="none" stroke="blue" d="M746.18,-322.16C775.44,-311.92 816.97,-297.39 850.83,-285.54"/>
+<polygon fill="blue" stroke="blue" points="852.33,-288.72 860.61,-282.11 850.02,-282.11 852.33,-288.72"/>
+</g>
+<!-- host_keymint_out -->
+<g id="node14" class="node">
+<title>host_keymint_out</title>
+<polygon fill="none" stroke="blue" points="1193,-282 1014,-282 1014,-246 1193,-246 1193,-282"/>
+<text text-anchor="middle" x="1103.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/keymint_fifo_vm.out</text>
+</g>
+<!-- secure_env&#45;&gt;host_keymint_out -->
+<g id="edge24" class="edge">
+<title>secure_env&#45;&gt;host_keymint_out</title>
+<path fill="none" stroke="blue" d="M768.27,-324.56C833.18,-313.03 938.45,-294.32 1013.71,-280.95"/>
+<polygon fill="blue" stroke="blue" points="767.44,-321.15 758.21,-326.35 768.67,-328.04 767.44,-321.15"/>
</g>
<!-- vmm -->
<g id="node5" class="node">
<title>vmm</title>
-<ellipse fill="none" stroke="black" cx="605.5" cy="-181" rx="64.19" ry="18"/>
-<text text-anchor="middle" x="605.5" y="-177.3" font-family="Times,serif" font-size="14.00">crosvm / qemu</text>
+<ellipse fill="none" stroke="black" cx="809.5" cy="-192" rx="64.19" ry="18"/>
+<text text-anchor="middle" x="809.5" y="-188.3" font-family="Times,serif" font-size="14.00">crosvm / qemu</text>
</g>
<!-- confirmationui_console -->
-<g id="node17" class="node">
+<g id="node20" class="node">
<title>confirmationui_console</title>
-<polygon fill="none" stroke="red" points="773.5,-124 703.5,-124 703.5,-88 773.5,-88 773.5,-124"/>
-<text text-anchor="middle" x="738.5" y="-102.3" font-family="Times,serif" font-size="14.00">/dev/hvc8</text>
+<polygon fill="none" stroke="red" points="1039.5,-135 969.5,-135 969.5,-99 1039.5,-99 1039.5,-135"/>
+<text text-anchor="middle" x="1004.5" y="-113.3" font-family="Times,serif" font-size="14.00">/dev/hvc8</text>
</g>
<!-- vmm&#45;&gt;confirmationui_console -->
<g id="edge7" class="edge">
<title>vmm&#45;&gt;confirmationui_console</title>
-<path fill="none" stroke="red" d="M642.4,-159.74C659.81,-150.19 680.61,-138.77 698.4,-129.01"/>
-<polygon fill="red" stroke="red" points="640.46,-156.82 633.38,-164.7 643.83,-162.95 640.46,-156.82"/>
-<polygon fill="red" stroke="red" points="700.32,-131.95 707.4,-124.07 696.95,-125.81 700.32,-131.95"/>
+<path fill="none" stroke="red" d="M868.88,-177.74C881.45,-174.36 894.53,-170.42 906.5,-166 926.14,-158.74 947.09,-148.81 964.56,-139.85"/>
+<polygon fill="red" stroke="red" points="867.74,-174.42 858.95,-180.32 869.5,-181.19 867.74,-174.42"/>
+<polygon fill="red" stroke="red" points="966.62,-142.73 973.87,-135.01 963.39,-136.52 966.62,-142.73"/>
</g>
<!-- gatekeeper_console -->
-<g id="node18" class="node">
+<g id="node21" class="node">
<title>gatekeeper_console</title>
-<polygon fill="none" stroke="green" points="640.5,-124 570.5,-124 570.5,-88 640.5,-88 640.5,-124"/>
-<text text-anchor="middle" x="605.5" y="-102.3" font-family="Times,serif" font-size="14.00">/dev/hvc4</text>
+<polygon fill="none" stroke="green" points="897.5,-135 827.5,-135 827.5,-99 897.5,-99 897.5,-135"/>
+<text text-anchor="middle" x="862.5" y="-113.3" font-family="Times,serif" font-size="14.00">/dev/hvc4</text>
</g>
<!-- vmm&#45;&gt;gatekeeper_console -->
<g id="edge15" class="edge">
<title>vmm&#45;&gt;gatekeeper_console</title>
-<path fill="none" stroke="green" d="M605.5,-152.49C605.5,-146.55 605.5,-140.27 605.5,-134.33"/>
-<polygon fill="green" stroke="green" points="602,-152.7 605.5,-162.7 609,-152.7 602,-152.7"/>
-<polygon fill="green" stroke="green" points="609,-134.18 605.5,-124.18 602,-134.18 609,-134.18"/>
+<path fill="none" stroke="green" d="M827.71,-165.92C833.02,-158.61 838.82,-150.62 844.13,-143.3"/>
+<polygon fill="green" stroke="green" points="824.84,-163.92 821.79,-174.07 830.5,-168.03 824.84,-163.92"/>
+<polygon fill="green" stroke="green" points="847.05,-145.24 850.09,-135.09 841.38,-141.13 847.05,-145.24"/>
+</g>
+<!-- keymaster_console -->
+<g id="node22" class="node">
+<title>keymaster_console</title>
+<polygon fill="none" stroke="blue" points="792.5,-135 722.5,-135 722.5,-99 792.5,-99 792.5,-135"/>
+<text text-anchor="middle" x="757.5" y="-113.3" font-family="Times,serif" font-size="14.00">/dev/hvc3</text>
+</g>
+<!-- vmm&#45;&gt;keymaster_console -->
+<g id="edge21" class="edge">
+<title>vmm&#45;&gt;keymaster_console</title>
+<path fill="none" stroke="blue" d="M791.63,-165.92C786.43,-158.61 780.74,-150.62 775.52,-143.3"/>
+<polygon fill="blue" stroke="blue" points="788.79,-167.95 797.44,-174.07 794.49,-163.89 788.79,-167.95"/>
+<polygon fill="blue" stroke="blue" points="778.33,-141.21 769.68,-135.09 772.63,-145.27 778.33,-141.21"/>
</g>
<!-- keymint_console -->
-<g id="node19" class="node">
+<g id="node23" class="node">
<title>keymint_console</title>
-<polygon fill="none" stroke="blue" points="488.5,-124 418.5,-124 418.5,-88 488.5,-88 488.5,-124"/>
-<text text-anchor="middle" x="453.5" y="-102.3" font-family="Times,serif" font-size="14.00">/dev/hvc3</text>
+<polygon fill="none" stroke="blue" points="583,-135 506,-135 506,-99 583,-99 583,-135"/>
+<text text-anchor="middle" x="544.5" y="-113.3" font-family="Times,serif" font-size="14.00">/dev/hvc11</text>
</g>
<!-- vmm&#45;&gt;keymint_console -->
-<g id="edge21" class="edge">
+<g id="edge28" class="edge">
<title>vmm&#45;&gt;keymint_console</title>
-<path fill="none" stroke="blue" d="M565.23,-160.66C544.45,-150.68 519.06,-138.49 497.74,-128.25"/>
-<polygon fill="blue" stroke="blue" points="563.84,-163.88 574.37,-165.05 566.87,-157.57 563.84,-163.88"/>
-<polygon fill="blue" stroke="blue" points="499.1,-125.02 488.57,-123.84 496.07,-131.33 499.1,-125.02"/>
+<path fill="none" stroke="blue" d="M753.65,-176.68C740.47,-173.24 726.48,-169.53 713.5,-166 672.65,-154.88 626.42,-141.71 592.65,-131.98"/>
+<polygon fill="blue" stroke="blue" points="752.99,-180.12 763.54,-179.25 754.75,-173.35 752.99,-180.12"/>
+<polygon fill="blue" stroke="blue" points="593.61,-128.61 583.03,-129.2 591.67,-135.34 593.61,-128.61"/>
</g>
<!-- host_confirmationui_in -->
<g id="node11" class="node">
<title>host_confirmationui_in</title>
-<polygon fill="none" stroke="red" points="985,-271 824,-271 824,-235 985,-235 985,-271"/>
-<text text-anchor="middle" x="904.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/confui_fifo_vm.in</text>
+<polygon fill="none" stroke="red" points="1372,-282 1211,-282 1211,-246 1372,-246 1372,-282"/>
+<text text-anchor="middle" x="1291.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/confui_fifo_vm.in</text>
</g>
<!-- webRTC&#45;&gt;host_confirmationui_in -->
<g id="edge5" class="edge">
<title>webRTC&#45;&gt;host_confirmationui_in</title>
-<path fill="none" stroke="red" d="M904.5,-306.7C904.5,-298.98 904.5,-289.71 904.5,-281.11"/>
-<polygon fill="red" stroke="red" points="908,-281.1 904.5,-271.1 901,-281.1 908,-281.1"/>
+<path fill="none" stroke="red" d="M1291.5,-317.7C1291.5,-309.98 1291.5,-300.71 1291.5,-292.11"/>
+<polygon fill="red" stroke="red" points="1295,-292.1 1291.5,-282.1 1288,-292.1 1295,-292.1"/>
</g>
<!-- host_confirmationui_out -->
<g id="node12" class="node">
<title>host_confirmationui_out</title>
-<polygon fill="none" stroke="red" points="1171.5,-271 1003.5,-271 1003.5,-235 1171.5,-235 1171.5,-271"/>
-<text text-anchor="middle" x="1087.5" y="-249.3" font-family="Times,serif" font-size="14.00">internal/confui_fifo_vm.out</text>
+<polygon fill="none" stroke="red" points="1558.5,-282 1390.5,-282 1390.5,-246 1558.5,-246 1558.5,-282"/>
+<text text-anchor="middle" x="1474.5" y="-260.3" font-family="Times,serif" font-size="14.00">internal/confui_fifo_vm.out</text>
</g>
<!-- webRTC&#45;&gt;host_confirmationui_out -->
<g id="edge3" class="edge">
<title>webRTC&#45;&gt;host_confirmationui_out</title>
-<path fill="none" stroke="red" d="M944.57,-308.67C973.65,-297.55 1013,-282.5 1043.05,-271"/>
-<polygon fill="red" stroke="red" points="943.22,-305.44 935.13,-312.28 945.72,-311.98 943.22,-305.44"/>
+<path fill="none" stroke="red" d="M1331.57,-319.67C1360.65,-308.55 1400,-293.5 1430.05,-282"/>
+<polygon fill="red" stroke="red" points="1330.22,-316.44 1322.13,-323.28 1332.72,-322.98 1330.22,-316.44"/>
</g>
-<!-- host_keymint_in&#45;&gt;vmm -->
+<!-- host_keymaster_in&#45;&gt;vmm -->
<g id="edge20" class="edge">
-<title>host_keymint_in&#45;&gt;vmm</title>
-<path fill="none" stroke="blue" d="M183.13,-236.42C186.29,-235.93 189.42,-235.46 192.5,-235 313.66,-217.04 455.35,-199.63 537.32,-189.92"/>
-<polygon fill="blue" stroke="blue" points="537.74,-193.4 547.26,-188.75 536.92,-186.44 537.74,-193.4"/>
+<title>host_keymaster_in&#45;&gt;vmm</title>
+<path fill="none" stroke="blue" d="M183.11,-247.25C186.28,-246.81 189.41,-246.39 192.5,-246 388.69,-221.1 621.5,-204.62 737.01,-197.32"/>
+<polygon fill="blue" stroke="blue" points="737.38,-200.8 747.14,-196.68 736.94,-193.81 737.38,-200.8"/>
</g>
-<!-- host_keymint_out&#45;&gt;vmm -->
+<!-- host_keymaster_out&#45;&gt;vmm -->
<g id="edge18" class="edge">
-<title>host_keymint_out&#45;&gt;vmm</title>
-<path fill="none" stroke="blue" d="M381.69,-232.7C438.14,-219.91 510.16,-203.6 557.03,-192.98"/>
-<polygon fill="blue" stroke="blue" points="380.67,-229.34 371.69,-234.97 382.22,-236.17 380.67,-229.34"/>
+<title>host_keymaster_out&#45;&gt;vmm</title>
+<path fill="none" stroke="blue" d="M402.02,-245.95C533.47,-226.91 674.52,-209.31 751.65,-199.94"/>
+<polygon fill="blue" stroke="blue" points="401.16,-242.54 391.77,-247.44 402.17,-249.47 401.16,-242.54"/>
</g>
<!-- host_gatekeeper_in&#45;&gt;vmm -->
<g id="edge14" class="edge">
<title>host_gatekeeper_in&#45;&gt;vmm</title>
-<path fill="none" stroke="green" d="M527.7,-234.88C541.54,-225.47 558.84,-213.71 573.62,-203.67"/>
-<polygon fill="green" stroke="green" points="575.67,-206.5 581.98,-197.99 571.74,-200.71 575.67,-206.5"/>
+<path fill="none" stroke="green" d="M577.21,-245.97C630.84,-233.74 702.08,-217.49 751.46,-206.23"/>
+<polygon fill="green" stroke="green" points="752.37,-209.62 761.34,-203.98 750.82,-202.79 752.37,-209.62"/>
</g>
<!-- host_gatekeeper_out&#45;&gt;vmm -->
<g id="edge12" class="edge">
<title>host_gatekeeper_out&#45;&gt;vmm</title>
-<path fill="none" stroke="green" d="M675.47,-229.1C660.36,-218.92 642.93,-207.2 629.25,-197.99"/>
-<polygon fill="green" stroke="green" points="673.81,-232.2 684.06,-234.88 677.72,-226.39 673.81,-232.2"/>
+<path fill="none" stroke="green" d="M742.22,-240.1C756.75,-229.92 773.51,-218.2 786.66,-208.99"/>
+<polygon fill="green" stroke="green" points="740.15,-237.27 733.96,-245.88 744.16,-243.01 740.15,-237.27"/>
</g>
<!-- host_confirmationui_in&#45;&gt;vmm -->
<g id="edge6" class="edge">
<title>host_confirmationui_in&#45;&gt;vmm</title>
-<path fill="none" stroke="red" d="M831.74,-234.97C779.94,-222.84 711.27,-206.76 663.22,-195.51"/>
-<polygon fill="red" stroke="red" points="663.83,-192.06 653.3,-193.19 662.24,-198.88 663.83,-192.06"/>
+<path fill="none" stroke="red" d="M1210.53,-247.34C1207.82,-246.88 1205.14,-246.43 1202.5,-246 1089.02,-227.52 956.35,-210.6 877.82,-201.06"/>
+<polygon fill="red" stroke="red" points="877.93,-197.55 867.58,-199.82 877.09,-204.5 877.93,-197.55"/>
</g>
<!-- host_confirmationui_out&#45;&gt;vmm -->
<g id="edge4" class="edge">
<title>host_confirmationui_out&#45;&gt;vmm</title>
-<path fill="none" stroke="red" d="M993.38,-234.86C869.99,-215.37 737.36,-198.25 663.29,-189.04"/>
-<polygon fill="red" stroke="red" points="992.95,-238.33 1003.38,-236.45 994.05,-231.42 992.95,-238.33"/>
+<path fill="none" stroke="red" d="M1380.45,-245.92C1189.25,-220.04 974.89,-203.91 871.5,-196.94"/>
+<polygon fill="red" stroke="red" points="1380.02,-249.4 1390.4,-247.28 1380.97,-242.46 1380.02,-249.4"/>
+</g>
+<!-- host_keymint_in&#45;&gt;vmm -->
+<g id="edge27" class="edge">
+<title>host_keymint_in&#45;&gt;vmm</title>
+<path fill="none" stroke="blue" d="M885.04,-245.88C871.73,-236.56 855.11,-224.93 840.86,-214.95"/>
+<polygon fill="blue" stroke="blue" points="842.54,-211.85 832.34,-208.99 838.52,-217.59 842.54,-211.85"/>
+</g>
+<!-- host_keymint_out&#45;&gt;vmm -->
+<g id="edge25" class="edge">
+<title>host_keymint_out&#45;&gt;vmm</title>
+<path fill="none" stroke="blue" d="M1022.21,-243.64C969.06,-230.99 901.49,-214.9 856.94,-204.3"/>
+<polygon fill="blue" stroke="blue" points="1021.42,-247.05 1031.96,-245.97 1023.04,-240.24 1021.42,-247.05"/>
</g>
<!-- u_boot -->
-<g id="node13" class="node">
+<g id="node15" class="node">
<title>u_boot</title>
-<ellipse fill="none" stroke="black" cx="339.5" cy="-34" rx="33.6" ry="18"/>
-<text text-anchor="middle" x="339.5" y="-30.3" font-family="Times,serif" font-size="14.00">u&#45;boot</text>
+<ellipse fill="none" stroke="black" cx="757.5" cy="-42" rx="33.6" ry="18"/>
+<text text-anchor="middle" x="757.5" y="-38.3" font-family="Times,serif" font-size="14.00">u&#45;boot</text>
</g>
<!-- confirmationui -->
-<g id="node14" class="node">
+<g id="node16" class="node">
<title>confirmationui</title>
-<ellipse fill="none" stroke="red" cx="783.5" cy="-34" rx="88.28" ry="18"/>
-<text text-anchor="middle" x="783.5" y="-30.3" font-family="Times,serif" font-size="14.00">ConfirmationUI HAL</text>
+<ellipse fill="none" stroke="red" cx="1058.5" cy="-42" rx="88.28" ry="18"/>
+<text text-anchor="middle" x="1058.5" y="-38.3" font-family="Times,serif" font-size="14.00">ConfirmationUI HAL</text>
</g>
<!-- gatekeeper -->
-<g id="node15" class="node">
+<g id="node17" class="node">
<title>gatekeeper</title>
-<ellipse fill="none" stroke="green" cx="605.5" cy="-34" rx="71.49" ry="18"/>
-<text text-anchor="middle" x="605.5" y="-30.3" font-family="Times,serif" font-size="14.00">Gatekeeper HAL</text>
+<ellipse fill="none" stroke="green" cx="880.5" cy="-42" rx="71.49" ry="18"/>
+<text text-anchor="middle" x="880.5" y="-38.3" font-family="Times,serif" font-size="14.00">Gatekeeper HAL</text>
+</g>
+<!-- keymaster -->
+<g id="node18" class="node">
+<title>keymaster</title>
+<ellipse fill="none" stroke="blue" cx="617.5" cy="-42" rx="88.28" ry="18"/>
+<text text-anchor="middle" x="617.5" y="-38.3" font-family="Times,serif" font-size="14.00">KeyMint (C++) HAL</text>
</g>
<!-- keymint -->
-<g id="node16" class="node">
+<g id="node19" class="node">
<title>keymint</title>
-<ellipse fill="none" stroke="blue" cx="453.5" cy="-34" rx="62.29" ry="18"/>
-<text text-anchor="middle" x="453.5" y="-30.3" font-family="Times,serif" font-size="14.00">Keymint HAL</text>
+<ellipse fill="none" stroke="blue" cx="423.5" cy="-42" rx="87.99" ry="18"/>
+<text text-anchor="middle" x="423.5" y="-38.3" font-family="Times,serif" font-size="14.00">KeyMint (Rust) HAL</text>
</g>
<!-- confirmationui_console&#45;&gt;confirmationui -->
<g id="edge8" class="edge">
<title>confirmationui_console&#45;&gt;confirmationui</title>
-<path fill="none" stroke="red" d="M755.16,-79.08C759.05,-73.03 763.19,-66.59 767.07,-60.56"/>
-<polygon fill="red" stroke="red" points="752.09,-77.39 749.62,-87.7 757.98,-81.18 752.09,-77.39"/>
-<polygon fill="red" stroke="red" points="770.04,-62.41 772.5,-52.1 764.15,-58.62 770.04,-62.41"/>
+<path fill="none" stroke="red" d="M1023.32,-90.56C1028.71,-83.27 1034.58,-75.33 1039.96,-68.06"/>
+<polygon fill="red" stroke="red" points="1020.43,-88.58 1017.3,-98.7 1026.06,-92.74 1020.43,-88.58"/>
+<polygon fill="red" stroke="red" points="1042.85,-70.04 1045.98,-59.92 1037.22,-65.88 1042.85,-70.04"/>
</g>
<!-- gatekeeper_console&#45;&gt;gatekeeper -->
<g id="edge16" class="edge">
<title>gatekeeper_console&#45;&gt;gatekeeper</title>
-<path fill="none" stroke="green" d="M605.5,-77.67C605.5,-72.69 605.5,-67.49 605.5,-62.51"/>
-<polygon fill="green" stroke="green" points="602,-77.7 605.5,-87.7 609,-77.7 602,-77.7"/>
-<polygon fill="green" stroke="green" points="609,-62.1 605.5,-52.1 602,-62.1 609,-62.1"/>
+<path fill="none" stroke="green" d="M869.21,-88.79C870.72,-82.65 872.33,-76.13 873.84,-70"/>
+<polygon fill="green" stroke="green" points="865.76,-88.15 866.77,-98.7 872.56,-89.83 865.76,-88.15"/>
+<polygon fill="green" stroke="green" points="877.27,-70.72 876.26,-60.18 870.47,-69.05 877.27,-70.72"/>
</g>
-<!-- keymint_console&#45;&gt;u_boot -->
+<!-- keymaster_console&#45;&gt;u_boot -->
<g id="edge23" class="edge">
-<title>keymint_console&#45;&gt;u_boot</title>
-<path fill="none" stroke="blue" d="M416.87,-82.51C401.61,-73.14 384.11,-62.39 369.62,-53.49"/>
-<polygon fill="blue" stroke="blue" points="415.26,-85.63 425.61,-87.88 418.92,-79.66 415.26,-85.63"/>
-<polygon fill="blue" stroke="blue" points="371.38,-50.47 361.03,-48.22 367.72,-56.44 371.38,-50.47"/>
+<title>keymaster_console&#45;&gt;u_boot</title>
+<path fill="none" stroke="blue" d="M757.5,-88.49C757.5,-82.55 757.5,-76.27 757.5,-70.33"/>
+<polygon fill="blue" stroke="blue" points="754,-88.7 757.5,-98.7 761,-88.7 754,-88.7"/>
+<polygon fill="blue" stroke="blue" points="761,-70.18 757.5,-60.18 754,-70.18 761,-70.18"/>
</g>
-<!-- keymint_console&#45;&gt;keymint -->
+<!-- keymaster_console&#45;&gt;keymaster -->
<g id="edge22" class="edge">
+<title>keymaster_console&#45;&gt;keymaster</title>
+<path fill="none" stroke="blue" d="M715.61,-94.18C713.54,-93.11 711.5,-92.04 709.5,-91 692.41,-82.09 673.53,-72.24 657.35,-63.8"/>
+<polygon fill="blue" stroke="blue" points="714.22,-97.41 724.71,-98.92 717.46,-91.2 714.22,-97.41"/>
+<polygon fill="blue" stroke="blue" points="658.65,-60.53 648.16,-59.01 655.41,-66.73 658.65,-60.53"/>
+</g>
+<!-- keymint_console&#45;&gt;keymint -->
+<g id="edge29" class="edge">
<title>keymint_console&#45;&gt;keymint</title>
-<path fill="none" stroke="blue" d="M453.5,-77.67C453.5,-72.69 453.5,-67.49 453.5,-62.51"/>
-<polygon fill="blue" stroke="blue" points="450,-77.7 453.5,-87.7 457,-77.7 450,-77.7"/>
-<polygon fill="blue" stroke="blue" points="457,-62.1 453.5,-52.1 450,-62.1 457,-62.1"/>
+<path fill="none" stroke="blue" d="M507.41,-93.63C492.04,-84.35 474.28,-73.64 459.07,-64.46"/>
+<polygon fill="blue" stroke="blue" points="505.76,-96.72 516.13,-98.88 509.38,-90.72 505.76,-96.72"/>
+<polygon fill="blue" stroke="blue" points="460.82,-61.43 450.45,-59.26 457.2,-67.42 460.82,-61.43"/>
</g>
</g>
</svg>
diff --git a/host/commands/secure_env/oemlock.h b/host/commands/secure_env/oemlock.h
new file mode 100644
index 000000000..8ac29ffb2
--- /dev/null
+++ b/host/commands/secure_env/oemlock.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 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
+
+namespace cuttlefish {
+namespace oemlock {
+
+/**
+ * OEMLock TPM server interface
+ *
+ * Inspired by OemLock HAL interface:
+ * https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/oemlock/aidl/default/Android.bp
+*/
+class OemLock {
+ public:
+ virtual bool IsOemUnlockAllowedByCarrier() const = 0;
+ virtual bool IsOemUnlockAllowedByDevice() const = 0;
+ virtual void SetOemUnlockAllowedByCarrier(bool allowed) = 0;
+ virtual void SetOemUnlockAllowedByDevice(bool allowed) = 0;
+};
+
+} // namespace oemlock
+} // namespace cuttlefish \ No newline at end of file
diff --git a/host/commands/secure_env/oemlock_responder.cpp b/host/commands/secure_env/oemlock_responder.cpp
new file mode 100644
index 000000000..3f9ad50c0
--- /dev/null
+++ b/host/commands/secure_env/oemlock_responder.cpp
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2023 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 "host/commands/secure_env/oemlock_responder.h"
+
+#include <android-base/logging.h>
+
+#include "common/libs/security/oemlock.h"
+
+namespace cuttlefish {
+namespace oemlock {
+
+OemLockResponder::OemLockResponder(secure_env::Channel& channel,
+ OemLock& oemlock)
+ : channel_(channel), oemlock_(oemlock) {}
+
+Result<void> OemLockResponder::ProcessMessage() {
+ auto request = CF_EXPECT(channel_.ReceiveMessage(), "Could not receive message");
+
+ bool allowed = false;
+ switch(secure_env::OemLockField(request->command)) {
+ case secure_env::OemLockField::ALLOWED_BY_CARRIER: {
+ if (request->payload_size == 0) {
+ allowed = oemlock_.IsOemUnlockAllowedByCarrier();
+ } else if (request->payload_size == sizeof(bool)) {
+ allowed = *reinterpret_cast<bool*>(request->payload);
+ oemlock_.SetOemUnlockAllowedByCarrier(allowed);
+ }
+ break;
+ }
+
+ case secure_env::OemLockField::ALLOWED_BY_DEVICE: {
+ if (request->payload_size == 0) {
+ allowed = oemlock_.IsOemUnlockAllowedByDevice();
+ } else if (request->payload_size == sizeof(bool)) {
+ allowed = *reinterpret_cast<bool*>(request->payload);
+ oemlock_.SetOemUnlockAllowedByDevice(allowed);
+ }
+ break;
+ }
+
+ default:
+ return CF_ERR("Unrecognized message id " << reinterpret_cast<uint32_t>(request->command));
+ }
+
+ CF_EXPECT(channel_.SendResponse(request->command, &allowed, sizeof(bool)),
+ "Could not answer to " << reinterpret_cast<uint32_t>(request->command) << " request");
+
+ return {};
+}
+
+} // namespace oemlock
+} // namespace cuttlefish
diff --git a/host/commands/secure_env/oemlock_responder.h b/host/commands/secure_env/oemlock_responder.h
new file mode 100644
index 000000000..3b02472a4
--- /dev/null
+++ b/host/commands/secure_env/oemlock_responder.h
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2023 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 "common/libs/security/channel.h"
+#include "common/libs/utils/result.h"
+#include "host/commands/secure_env/oemlock.h"
+
+namespace cuttlefish {
+namespace oemlock {
+
+class OemLockResponder {
+ public:
+ OemLockResponder(secure_env::Channel& channel,
+ OemLock& oemlock);
+
+ Result<void> ProcessMessage();
+
+ private:
+ secure_env::Channel& channel_;
+ OemLock& oemlock_;
+};
+
+} // namespace oemlock
+} // namespace cuttlefish
diff --git a/host/commands/secure_env/rust/lib.rs b/host/commands/secure_env/rust/lib.rs
index 4d4e2f42b..71f028982 100644
--- a/host/commands/secure_env/rust/lib.rs
+++ b/host/commands/secure_env/rust/lib.rs
@@ -46,7 +46,7 @@ pub fn ta_main(fd_in: c_int, fd_out: c_int, security_level: SecurityLevel, trm:
log::set_logger(&AndroidCppLogger).unwrap();
log::set_max_level(log::LevelFilter::Debug); // Filtering happens elsewhere
info!(
- "KeyMint TA running with fd_in={}, fd_out={}, security_level={:?}",
+ "KeyMint Rust TA running with fd_in={}, fd_out={}, security_level={:?}",
fd_in, fd_out, security_level,
);
diff --git a/host/commands/secure_env/secure_env_linux_main.cpp b/host/commands/secure_env/secure_env_linux_main.cpp
index ade41d36c..56428c901 100644
--- a/host/commands/secure_env/secure_env_linux_main.cpp
+++ b/host/commands/secure_env/secure_env_linux_main.cpp
@@ -26,6 +26,7 @@
#include <tss2/tss2_rc.h>
#include "common/libs/fs/shared_fd.h"
+#include "common/libs/security/channel_sharedfd.h"
#include "common/libs/security/confui_sign.h"
#include "common/libs/security/gatekeeper_channel_sharedfd.h"
#include "common/libs/security/keymaster_channel_sharedfd.h"
@@ -38,9 +39,12 @@
#include "host/commands/secure_env/in_process_tpm.h"
#include "host/commands/secure_env/insecure_fallback_storage.h"
#include "host/commands/secure_env/keymaster_responder.h"
+#include "host/commands/secure_env/oemlock_responder.h"
+#include "host/commands/secure_env/oemlock.h"
#include "host/commands/secure_env/proxy_keymaster_context.h"
#include "host/commands/secure_env/rust/kmr_ta.h"
#include "host/commands/secure_env/soft_gatekeeper.h"
+#include "host/commands/secure_env/soft_oemlock.h"
#include "host/commands/secure_env/tpm_gatekeeper.h"
#include "host/commands/secure_env/tpm_keymaster_context.h"
#include "host/commands/secure_env/tpm_keymaster_enforcement.h"
@@ -50,8 +54,12 @@
DEFINE_int32(confui_server_fd, -1, "A named socket to serve confirmation UI");
DEFINE_int32(keymaster_fd_in, -1, "A pipe for keymaster communication");
DEFINE_int32(keymaster_fd_out, -1, "A pipe for keymaster communication");
+DEFINE_int32(keymint_fd_in, -1, "A pipe for keymint communication");
+DEFINE_int32(keymint_fd_out, -1, "A pipe for keymint communication");
DEFINE_int32(gatekeeper_fd_in, -1, "A pipe for gatekeeper communication");
DEFINE_int32(gatekeeper_fd_out, -1, "A pipe for gatekeeper communication");
+DEFINE_int32(oemlock_fd_in, -1, "A pipe for oemlock communication");
+DEFINE_int32(oemlock_fd_out, -1, "A pipe for oemlock communication");
DEFINE_int32(kernel_events_fd, -1,
"A pipe for monitoring events based on "
"messages written to the kernel log. This "
@@ -62,12 +70,14 @@ DEFINE_string(tpm_impl, "in_memory",
"The TPM implementation. \"in_memory\" or \"host_device\"");
DEFINE_string(keymint_impl, "tpm",
- "The KeyMint implementation. \"tpm\", \"software\", \"rust-tpm\" "
- "or \"rust-software\"");
+ "The KeyMint implementation. \"tpm\" or \"software\"");
DEFINE_string(gatekeeper_impl, "tpm",
"The gatekeeper implementation. \"tpm\" or \"software\"");
+DEFINE_string(oemlock_impl, "software",
+ "The oemlock implementation. \"tpm\" or \"software\"");
+
namespace cuttlefish {
namespace {
@@ -140,8 +150,22 @@ ChooseGatekeeperComponent() {
}
}
+fruit::Component<oemlock::OemLock> ChooseOemlockComponent() {
+ if (FLAGS_oemlock_impl == "software") {
+ return fruit::createComponent()
+ .bind<oemlock::OemLock, oemlock::SoftOemLock>();
+ } else if (FLAGS_oemlock_impl == "tpm") {
+ LOG(FATAL) << "Oemlock doesn't support TPM implementation";
+ abort();
+ } else {
+ LOG(FATAL) << "Invalid oemlock implementation: "
+ << FLAGS_oemlock_impl;
+ abort();
+ }
+}
+
fruit::Component<TpmResourceManager, gatekeeper::GateKeeper,
- keymaster::KeymasterEnforcement>
+ oemlock::OemLock, keymaster::KeymasterEnforcement>
SecureEnvComponent() {
return fruit::createComponent()
.registerProvider([]() -> Tpm* { // fruit will take ownership
@@ -188,7 +212,8 @@ SecureEnvComponent() {
insecure_storage);
})
.registerProvider([]() { return new gatekeeper::SoftGateKeeper(); })
- .install(ChooseGatekeeperComponent);
+ .install(ChooseGatekeeperComponent)
+ .install(ChooseOemlockComponent);
}
} // namespace
@@ -199,10 +224,11 @@ int SecureEnvMain(int argc, char** argv) {
keymaster::SoftKeymasterLogger km_logger;
fruit::Injector<TpmResourceManager, gatekeeper::GateKeeper,
- keymaster::KeymasterEnforcement>
+ oemlock::OemLock, keymaster::KeymasterEnforcement>
injector(SecureEnvComponent);
TpmResourceManager* resource_manager = injector.get<TpmResourceManager*>();
gatekeeper::GateKeeper* gatekeeper = injector.get<gatekeeper::GateKeeper*>();
+ oemlock::OemLock* oemlock = injector.get<oemlock::OemLock*>();
keymaster::KeymasterEnforcement* keymaster_enforcement =
injector.get<keymaster::KeymasterEnforcement*>();
std::unique_ptr<keymaster::KeymasterContext> keymaster_context;
@@ -210,61 +236,67 @@ int SecureEnvMain(int argc, char** argv) {
std::vector<std::thread> threads;
- if (android::base::StartsWith(FLAGS_keymint_impl, "rust-")) {
- // Use the Rust reference implementation of KeyMint.
- LOG(DEBUG) << "starting Rust KeyMint implementation";
- int security_level;
- if (FLAGS_keymint_impl == "rust-software") {
- security_level = KM_SECURITY_LEVEL_SOFTWARE;
- } else if (FLAGS_keymint_impl == "rust-tpm") {
- security_level = KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT;
- } else {
- LOG(FATAL) << "Unknown keymaster implementation " << FLAGS_keymint_impl;
- return -1;
- }
+ int security_level;
+ if (FLAGS_keymint_impl == "software") {
+ security_level = KM_SECURITY_LEVEL_SOFTWARE;
+ } else if (FLAGS_keymint_impl == "tpm") {
+ security_level = KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT;
+ } else {
+ LOG(FATAL) << "Unknown keymint implementation " << FLAGS_keymint_impl;
+ return -1;
+ }
- int keymaster_in = FLAGS_keymaster_fd_in;
- int keymaster_out = FLAGS_keymaster_fd_out;
- TpmResourceManager* rm = resource_manager;
- threads.emplace_back([rm, keymaster_in, keymaster_out, security_level]() {
- kmr_ta_main(keymaster_in, keymaster_out, security_level, rm);
- });
+ // The guest image may have either the C++ implementation of
+ // KeyMint/Keymaster, xor the Rust implementation of KeyMint. Those different
+ // implementations each need to have a matching TA implementation in
+ // secure_env, but they use distincts ports (/dev/hvc3 for C++, /dev/hvc11 for
+ // Rust) so start threads for *both* TA implementations -- only one of them
+ // will receive any traffic from the guest.
+
+ // Start the Rust reference implementation of KeyMint.
+ LOG(INFO) << "starting Rust KeyMint TA implementation in a thread";
+
+ int keymint_in = FLAGS_keymint_fd_in;
+ int keymint_out = FLAGS_keymint_fd_out;
+ TpmResourceManager* rm = resource_manager;
+ threads.emplace_back([rm, keymint_in, keymint_out, security_level]() {
+ kmr_ta_main(keymint_in, keymint_out, security_level, rm);
+ });
+ // Start the C++ reference implementation of KeyMint.
+ LOG(INFO) << "starting C++ KeyMint implementation in a thread with FDs in="
+ << FLAGS_keymaster_fd_in << ", out=" << FLAGS_keymaster_fd_out;
+ if (security_level == KM_SECURITY_LEVEL_SOFTWARE) {
+ keymaster_context.reset(new keymaster::PureSoftKeymasterContext(
+ keymaster::KmVersion::KEYMINT_3, KM_SECURITY_LEVEL_SOFTWARE));
+ } else if (security_level == KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT) {
+ keymaster_context.reset(
+ new TpmKeymasterContext(*resource_manager, *keymaster_enforcement));
} else {
- // Use the C++ reference implementation of KeyMint.
- LOG(DEBUG) << "starting C++ KeyMint implementation";
- if (FLAGS_keymint_impl == "software") {
- // TODO: See if this is the right KM version.
- keymaster_context.reset(new keymaster::PureSoftKeymasterContext(
- keymaster::KmVersion::KEYMINT_3, KM_SECURITY_LEVEL_SOFTWARE));
- } else if (FLAGS_keymint_impl == "tpm") {
- keymaster_context.reset(
- new TpmKeymasterContext(*resource_manager, *keymaster_enforcement));
- } else {
- LOG(FATAL) << "Unknown keymaster implementation " << FLAGS_keymint_impl;
- return -1;
- }
- // keymaster::AndroidKeymaster puts the context pointer into a UniquePtr,
- // taking ownership.
- keymaster.reset(new keymaster::AndroidKeymaster(
- new ProxyKeymasterContext(*keymaster_context), kOperationTableSize,
- keymaster::MessageVersion(keymaster::KmVersion::KEYMINT_3,
- 0 /* km_date */)));
-
- auto keymaster_in = DupFdFlag(FLAGS_keymaster_fd_in);
- auto keymaster_out = DupFdFlag(FLAGS_keymaster_fd_out);
- keymaster::AndroidKeymaster* borrowed_km = keymaster.get();
- threads.emplace_back([keymaster_in, keymaster_out, borrowed_km]() {
- while (true) {
- SharedFdKeymasterChannel keymaster_channel(keymaster_in, keymaster_out);
-
- KeymasterResponder keymaster_responder(keymaster_channel, *borrowed_km);
-
- while (keymaster_responder.ProcessMessage()) {
- }
- }
- });
+ LOG(FATAL) << "Unknown keymaster security level " << security_level
+ << " for " << FLAGS_keymint_impl;
+ return -1;
}
+ // keymaster::AndroidKeymaster puts the context pointer into a UniquePtr,
+ // taking ownership.
+ keymaster.reset(new keymaster::AndroidKeymaster(
+ new ProxyKeymasterContext(*keymaster_context), kOperationTableSize,
+ keymaster::MessageVersion(keymaster::KmVersion::KEYMINT_3,
+ 0 /* km_date */)));
+
+ auto keymaster_in = DupFdFlag(FLAGS_keymaster_fd_in);
+ auto keymaster_out = DupFdFlag(FLAGS_keymaster_fd_out);
+ keymaster::AndroidKeymaster* borrowed_km = keymaster.get();
+ threads.emplace_back([keymaster_in, keymaster_out, borrowed_km]() {
+ while (true) {
+ SharedFdKeymasterChannel keymaster_channel(keymaster_in, keymaster_out);
+
+ KeymasterResponder keymaster_responder(keymaster_channel, *borrowed_km);
+
+ while (keymaster_responder.ProcessMessage()) {
+ }
+ }
+ });
auto gatekeeper_in = DupFdFlag(FLAGS_gatekeeper_fd_in);
auto gatekeeper_out = DupFdFlag(FLAGS_gatekeeper_fd_out);
@@ -280,6 +312,17 @@ int SecureEnvMain(int argc, char** argv) {
}
});
+ auto oemlock_in = DupFdFlag(FLAGS_oemlock_fd_in);
+ auto oemlock_out = DupFdFlag(FLAGS_oemlock_fd_out);
+ threads.emplace_back([oemlock_in, oemlock_out, &oemlock]() {
+ while (true) {
+ secure_env::SharedFdChannel channel(oemlock_in, oemlock_out);
+ oemlock::OemLockResponder responder(channel, *oemlock);
+ while (responder.ProcessMessage().ok()) {
+ }
+ }
+ });
+
auto confui_server_fd = DupFdFlag(FLAGS_confui_server_fd);
threads.emplace_back([confui_server_fd, resource_manager]() {
ConfUiSignServer confui_sign_server(*resource_manager, confui_server_fd);
diff --git a/host/commands/secure_env/soft_oemlock.h b/host/commands/secure_env/soft_oemlock.h
new file mode 100644
index 000000000..b731ee982
--- /dev/null
+++ b/host/commands/secure_env/soft_oemlock.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 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 <fruit/fruit.h>
+
+#include "host/commands/secure_env/oemlock.h"
+
+namespace cuttlefish {
+namespace oemlock {
+
+class SoftOemLock : public OemLock {
+ public:
+ INJECT(SoftOemLock()) : is_allowed_by_carrier_(true), is_allowed_by_device_(false) {}
+
+ bool IsOemUnlockAllowedByCarrier() const override {
+ return is_allowed_by_carrier_;
+ }
+
+ bool IsOemUnlockAllowedByDevice() const override {
+ return is_allowed_by_device_;
+ }
+
+ void SetOemUnlockAllowedByCarrier(bool allowed) override {
+ is_allowed_by_carrier_ = allowed;
+ }
+
+ void SetOemUnlockAllowedByDevice(bool allowed) override {
+ is_allowed_by_device_ = allowed;
+ }
+
+ private:
+ bool is_allowed_by_carrier_;
+ bool is_allowed_by_device_;
+};
+
+} // namespace oemlock
+} // namespace cuttlefish \ No newline at end of file
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 1b9e07baa..5c9e8dc36 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -149,6 +149,8 @@ static SecureHal StringToSecureHal(std::string mode) {
return SecureHal::Keymint;
} else if (mode == "gatekeeper") {
return SecureHal::Gatekeeper;
+ } else if (mode == "oemlock") {
+ return SecureHal::Oemlock;
} else {
return SecureHal::Unknown;
}
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 16151b329..9a2af86cd 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -71,6 +71,7 @@ enum class SecureHal {
Unknown,
Keymint,
Gatekeeper,
+ Oemlock,
};
// Holds the configuration of the cuttlefish instances.
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index bfa1c98ad..100b71e56 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -316,6 +316,7 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
crosvm_cmd.Cmd().AddParameter("--cid=", instance.vsock_guest_cid());
}
+ // /dev/hvc0 = kernel console
// If kernel log is enabled, the virtio-console port will be specified as
// a true console for Linux, and kernel messages will be printed there.
// Otherwise, the port will still be set up for bootloader and userspace
@@ -326,6 +327,7 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
crosvm_cmd.AddHvcReadOnly(instance.kernel_log_pipe_name(),
instance.enable_kernel_log());
+ // /dev/hvc1 = serial console
if (instance.console()) {
// stdin is the only currently supported way to write data to a serial port
// in crosvm. A file (named pipe) is used here instead of stdout to ensure
@@ -383,16 +385,20 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
return StopperResult::kStopSuccess;
});
+ // /dev/hvc2 = serial logging
// Serial port for logcat, redirected to a pipe
crosvm_cmd.AddHvcReadOnly(instance.logcat_pipe_name());
+ // /dev/hvc3 = keymaster (C++ implementation)
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("keymaster_fifo_vm.out"),
instance.PerInstanceInternalPath("keymaster_fifo_vm.in"));
+ // /dev/hvc4 = gatekeeper
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("gatekeeper_fifo_vm.out"),
instance.PerInstanceInternalPath("gatekeeper_fifo_vm.in"));
+ // /dev/hvc5 = bt
if (config.enable_host_bluetooth()) {
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("bt_fifo_vm.out"),
@@ -400,6 +406,9 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
} else {
crosvm_cmd.AddHvcSink();
}
+
+ // /dev/hvc6 = gnss
+ // /dev/hvc7 = location
if (instance.enable_gnss_grpc_proxy()) {
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("gnsshvc_fifo_vm.out"),
@@ -413,10 +422,12 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
}
}
+ // /dev/hvc8 = confirmationui
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("confui_fifo_vm.out"),
instance.PerInstanceInternalPath("confui_fifo_vm.in"));
+ // /dev/hvc9 = uwb
if (config.enable_host_uwb()) {
crosvm_cmd.AddHvcReadWrite(
instance.PerInstanceInternalPath("uwb_fifo_vm.out"),
@@ -425,6 +436,16 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands(
crosvm_cmd.AddHvcSink();
}
+ // /dev/hvc10 = oemlock
+ crosvm_cmd.AddHvcReadWrite(
+ instance.PerInstanceInternalPath("oemlock_fifo_vm.out"),
+ instance.PerInstanceInternalPath("oemlock_fifo_vm.in"));
+
+ // /dev/hvc11 = keymint (Rust implementation)
+ crosvm_cmd.AddHvcReadWrite(
+ instance.PerInstanceInternalPath("keymint_fifo_vm.out"),
+ instance.PerInstanceInternalPath("keymint_fifo_vm.in"));
+
for (auto i = 0; i < VmManager::kMaxDisks - disk_num; i++) {
crosvm_cmd.AddHvcSink();
}
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 27a3ddf0b..a2744a35d 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -457,6 +457,7 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands(
}
}
+ // /dev/hvc0 = kernel console
// If kernel log is enabled, the virtio-console port will be specified as
// a true console for Linux, and kernel messages will be printed there.
// Otherwise, the port will still be set up for bootloader and userspace
@@ -469,6 +470,7 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands(
// actually managed by the kernel as a console is handled elsewhere.)
add_hvc_ro(instance.kernel_log_pipe_name());
+ // /dev/hvc1 = serial console
if (instance.console()) {
if (instance.kgdb() || instance.use_bootloader()) {
add_serial_console(instance.console_pipe_prefix());
@@ -495,17 +497,23 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands(
add_hvc_sink();
}
+ // /dev/hvc2 = serial logging
// Serial port for logcat, redirected to a pipe
add_hvc_ro(instance.logcat_pipe_name());
+ // /dev/hvc3 = keymaster (C++ implementation)
add_hvc(instance.PerInstanceInternalPath("keymaster_fifo_vm"));
+ // /dev/hvc4 = gatekeeper
add_hvc(instance.PerInstanceInternalPath("gatekeeper_fifo_vm"));
+ // /dev/hvc5 = bt
if (config.enable_host_bluetooth()) {
add_hvc(instance.PerInstanceInternalPath("bt_fifo_vm"));
} else {
add_hvc_sink();
}
+ // /dev/hvc6 = gnss
+ // /dev/hvc7 = location
if (instance.enable_gnss_grpc_proxy()) {
add_hvc(instance.PerInstanceInternalPath("gnsshvc_fifo_vm"));
add_hvc(instance.PerInstanceInternalPath("locationhvc_fifo_vm"));
@@ -526,14 +534,22 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands(
* confui_fifo_vm.{in/out} are created along with the streamer process,
* which is not created w/ QEMU.
*/
+ // /dev/hvc8 = confirmationui
add_hvc_sink();
+ // /dev/hvc9 = uwb
if (config.enable_host_uwb()) {
add_hvc("uwb_fifo_vm");
} else {
add_hvc_sink();
}
+ // /dev/hvc10 = oemlock
+ add_hvc(instance.PerInstanceInternalPath("oemlock_fifo_vm"));
+
+ // /dev/hvc11 = keymint (Rust implementation)
+ add_hvc(instance.PerInstanceInternalPath("keymint_fifo_vm"));
+
auto disk_num = instance.virtual_disk_paths().size();
for (auto i = 0; i < VmManager::kMaxDisks - disk_num; i++) {
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index 739e0dbc2..4b116bfd9 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -41,8 +41,20 @@ class VmManager {
// so even if they are disabled and the guest isn't using them, they don't
// need to consume host resources, except for the PCI ID. Use this trick to
// keep the number of PCI IDs assigned constant for all flags/vm manager
- // combinations
- static const int kDefaultNumHvcs = 10;
+ // combinations.
+ // - /dev/hvc0 = kernel console
+ // - /dev/hvc1 = serial console
+ // - /dev/hvc2 = serial logging
+ // - /dev/hvc3 = keymaster
+ // - /dev/hvc4 = gatekeeper
+ // - /dev/hvc5 = bt
+ // - /dev/hvc6 = gnss
+ // - /dev/hvc7 = location
+ // - /dev/hvc8 = confirmationui
+ // - /dev/hvc9 = uwb
+ // - /dev/hvc10 = oemlock
+ // - /dev/hvc11 = keymint
+ static const int kDefaultNumHvcs = 12;
// This is the number of virtual disks (block devices) that should be
// configured by the VmManager. Related to the description above regarding
diff --git a/shared/config/ueventd.rc b/shared/config/ueventd.rc
index 4e80bda03..c604e3d23 100644
--- a/shared/config/ueventd.rc
+++ b/shared/config/ueventd.rc
@@ -15,7 +15,7 @@
# seriallogging
/dev/hvc2 0660 system logd
-# keymaster
+# keymaster / C++
/dev/hvc3 0666 system system
# gatekeeper
@@ -38,5 +38,11 @@
# uwb
/dev/hvc9 0660 uwb uwb
+# oemlock
+/dev/hvc10 0660 hsm hsm
+
+# keymint / Rust
+/dev/hvc11 0666 system system
+
# Factory Reset Protection
/dev/block/by-name/frp 0660 system system
diff --git a/shared/device.mk b/shared/device.mk
index 483913f2c..ab8f3aa6c 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -304,13 +304,6 @@ PRODUCT_PACKAGES += \
android.hardware.ir-service.example \
consumerir.default
-
-#
-# OemLock aidl HAL
-#
-PRODUCT_PACKAGES += \
- android.hardware.oemlock-service.example
-
#
# Authsecret AIDL HAL
#
@@ -442,12 +435,23 @@ PRODUCT_PACKAGES += $(LOCAL_DUMPSTATE_PRODUCT_PACKAGE)
# Gatekeeper
#
ifeq ($(LOCAL_GATEKEEPER_PRODUCT_PACKAGE),)
- LOCAL_GATEKEEPER_PRODUCT_PACKAGE := android.hardware.gatekeeper-service.remote
+ LOCAL_GATEKEEPER_PRODUCT_PACKAGE := android.hardware.gatekeeper-service.remote
endif
PRODUCT_PACKAGES += \
$(LOCAL_GATEKEEPER_PRODUCT_PACKAGE)
#
+# Oemlock
+#
+ifeq ($(LOCAL_OEMLOCK_PRODUCT_PACKAGE),)
+ LOCAL_OEMLOCK_PRODUCT_PACKAGE := android.hardware.oemlock-service.remote
+endif
+PRODUCT_PACKAGES += \
+ $(LOCAL_OEMLOCK_PRODUCT_PACKAGE)
+
+PRODUCT_VENDOR_PROPERTIES += ro.oem_unlock_supported=1
+
+#
# GPS
#
LOCAL_GNSS_PRODUCT_PACKAGE ?= \
@@ -505,12 +509,6 @@ ifeq ($(LOCAL_KEYMINT_PRODUCT_PACKAGE),)
LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.rust
endif
-ifeq ($(LOCAL_KEYMINT_PRODUCT_PACKAGE),android.hardware.security.keymint-service.rust)
- # KeyMint HAL has been overridden to force use of the Rust reference implementation.
- # Set the build config for secure_env to match.
- $(call soong_config_set,secure_env,keymint_impl,rust)
-endif
-
PRODUCT_PACKAGES += \
$(LOCAL_KEYMINT_PRODUCT_PACKAGE) \
diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts
index 0d9468773..4805bb1a5 100644
--- a/shared/sepolicy/vendor/file_contexts
+++ b/shared/sepolicy/vendor/file_contexts
@@ -38,6 +38,12 @@
# hvc9 for uwb
/dev/hvc9 u:object_r:uwb_device:s0
+# hvc10 for oemlock
+/dev/hvc10 u:object_r:oemlock_device:s0
+
+# hvc11 for keymint / Rust
+/dev/hvc11 u:object_r:keymint_device:s0
+
# ARM serial console device
/dev/ttyAMA[0-9]* u:object_r:serial_device:s0
@@ -94,11 +100,11 @@
/vendor/bin/hw/android\.hardware\.thermal@2\.0-service\.mock u:object_r:hal_thermal_default_exec:s0
/vendor/bin/hw/android\.hardware\.identity-service\.remote u:object_r:hal_identity_remote_exec:s0
/vendor/bin/hw/android\.hardware\.security\.keymint-service\.remote u:object_r:hal_keymint_remote_exec:s0
-/vendor/bin/hw/android\.hardware\.security\.keymint-service\.rust u:object_r:hal_keymint_remote_exec:s0
+/vendor/bin/hw/android\.hardware\.security\.keymint-service\.rust u:object_r:hal_keymint_rust_exec:s0
/vendor/bin/hw/android\.hardware\.keymaster@4\.1-service.remote u:object_r:hal_keymaster_remote_exec:s0
/vendor/bin/hw/android\.hardware\.gatekeeper-service.remote u:object_r:hal_gatekeeper_remote_exec:s0
/vendor/bin/hw/android\.hardware\.confirmationui-service.cuttlefish u:object_r:hal_confirmationui_cuttlefish_exec:s0
-/vendor/bin/hw/android\.hardware\.oemlock-service.example u:object_r:hal_oemlock_default_exec:s0
+/vendor/bin/hw/android\.hardware\.oemlock-service.remote u:object_r:hal_oemlock_remote_exec:s0
/vendor/bin/hw/android\.hardware\.weaver-service.example u:object_r:hal_weaver_default_exec:s0
/vendor/bin/hw/android\.hardware\.authsecret@1\.0-service u:object_r:hal_authsecret_default_exec:s0
/vendor/bin/hw/android\.hardware\.authsecret-service.example u:object_r:hal_authsecret_default_exec:s0
diff --git a/shared/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts
index 758fb54e9..ce1044560 100644
--- a/shared/sepolicy/vendor/genfs_contexts
+++ b/shared/sepolicy/vendor/genfs_contexts
@@ -30,7 +30,7 @@ genfscon sysfs $1/rtc/rtc$2/alarmtimer.0.auto/wakeup u:object_r:sysfs_wakeup:s0
dnl')dnl
dnl
# crosvm (x86)
-cf_pci_block_device(/devices/pci0000:00, 0xc, 11)
+cf_pci_block_device(/devices/pci0000:00, 0xe, 13)
cf_pci_gpu_device(/devices/pci0000:00, 0x2)
## find /sys/devices/platform/* -type d -name 'rtc[0-9]' | sed 's,/rtc[0-9],,'
genfscon sysfs /devices/platform/rtc_cmos/rtc u:object_r:sysfs_rtc:s0
@@ -69,6 +69,8 @@ genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1b/wakeup u:ob
genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/wakeup u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1d/wakeup u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1e/wakeup u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1f/wakeup u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:20/wakeup u:object_r:sysfs_wakeup:s0
## find /sys/devices/platform/* -type d -name 'wakeup[0-9]*'
genfscon sysfs /devices/platform/rtc_cmos/rtc/rtc0/wakeup3 u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/platform/rtc_cmos/rtc/rtc0/wakeup4 u:object_r:sysfs_wakeup:s0
@@ -82,7 +84,7 @@ genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim0/net u:object_r:sysfs_net:s
genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim1/net u:object_r:sysfs_net:s0
# crosvm (arm64)
-cf_pci_block_device(/devices/platform/10000.pci/pci0000:00, 0xd, 12)
+cf_pci_block_device(/devices/platform/10000.pci/pci0000:00, 0xf, 14)
cf_pci_gpu_device(/devices/platform/10000.pci/pci0000:00, 0x2)
## find /sys/devices/platform/* -type d -name 'rtc[0-9]' | sed 's,/rtc[0-9],,'
genfscon sysfs /devices/platform/2000.rtc/rtc u:object_r:sysfs_rtc:s0
@@ -90,7 +92,7 @@ genfscon sysfs /devices/platform/2000.rtc/rtc u:object_r:sysfs_rtc:s0
## arm64 2000.rtc on crosvm does not currently expose a wakeup node
# qemu (x86)
-cf_pci_block_device(/devices/pci0000:00, 0xd, 11)
+cf_pci_block_device(/devices/pci0000:00, 0xf, 13)
#cf_pci_gpu_device(/devices/pci0000:00, 0x2) - duplicated with crosvm(x86)
## find /sys/devices/platform/* -type d -name 'rtc[0-9]' | sed 's,/rtc[0-9],,'
genfscon sysfs /devices/pnp0/00:04/rtc u:object_r:sysfs_rtc:s0
@@ -98,7 +100,7 @@ genfscon sysfs /devices/pnp0/00:04/rtc u:object_r:sysfs_rtc:s0
cf_rtc_wakeup_alarmtimer(/devices/pnp0/00:04, 0, 19)
# qemu (arm64)
-cf_pci_block_device(/devices/platform/4010000000.pcie/pci0000:00, 0xc, 11)
+cf_pci_block_device(/devices/platform/4010000000.pcie/pci0000:00, 0xe, 13)
cf_pci_gpu_device(/devices/platform/4010000000.pcie/pci0000:00, 0x1)
## find /sys/devices/platform/* -type d -name 'rtc[0-9]' | sed 's,/rtc[0-9],,'
genfscon sysfs /devices/platform/9010000.pl031/rtc u:object_r:sysfs_rtc:s0
@@ -106,13 +108,13 @@ genfscon sysfs /devices/platform/9010000.pl031/rtc u:object_r:sysfs_rtc:s0
cf_rtc_wakeup_alarmtimer(/devices/platform/9010000.pl031, 0, 0)
# qemu (arm)
-cf_pci_block_device(/devices/platform/3f000000.pcie/pci0000:00, 0xc, 11)
+cf_pci_block_device(/devices/platform/3f000000.pcie/pci0000:00, 0xe, 13)
cf_pci_gpu_device(/devices/platform/3f000000.pcie/pci0000:00, 0x1)
genfscon sysfs /devices/platform/rtc-test.1/wakeup/wakeup2 u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/platform/rtc-test.2/wakeup/wakeup3 u:object_r:sysfs_wakeup:s0
# qemu (riscv64)
-cf_pci_block_device(/devices/platform/soc/30000000.pci/pci0000:00, 0xd, 12)
+cf_pci_block_device(/devices/platform/soc/30000000.pci/pci0000:00, 0xf, 14)
cf_pci_gpu_device(/devices/platform/soc/30000000.pci/pci0000:00, 0x1)
# common on all platforms / vm managers
diff --git a/shared/sepolicy/vendor/hal_keymint_rust.te b/shared/sepolicy/vendor/hal_keymint_rust.te
new file mode 100644
index 000000000..f1adb4dbe
--- /dev/null
+++ b/shared/sepolicy/vendor/hal_keymint_rust.te
@@ -0,0 +1,18 @@
+type hal_keymint_rust, domain;
+hal_server_domain(hal_keymint_rust, hal_keymint)
+
+type hal_keymint_rust_exec, exec_type, vendor_file_type, file_type;
+init_daemon_domain(hal_keymint_rust)
+
+type keymint_device, file_type;
+
+allow hal_keymint_rust device:dir r_dir_perms;
+allow hal_keymint_rust keymint_device:chr_file rw_file_perms;
+
+# Write to kernel log (/dev/kmsg)
+allow hal_keymint_rust kmsg_device:chr_file w_file_perms;
+allow hal_keymint_rust kmsg_device:chr_file getattr;
+
+get_prop(hal_keymint_rust, vendor_security_patch_level_prop)
+get_prop(hal_keymint_rust, vendor_boot_security_patch_level_prop)
+get_prop(hal_keymint_rust, serialno_prop)
diff --git a/shared/sepolicy/vendor/hal_oemlock_remote.te b/shared/sepolicy/vendor/hal_oemlock_remote.te
new file mode 100644
index 000000000..f775b6bec
--- /dev/null
+++ b/shared/sepolicy/vendor/hal_oemlock_remote.te
@@ -0,0 +1,14 @@
+type hal_oemlock_remote, domain;
+hal_server_domain(hal_oemlock_remote, hal_oemlock)
+
+type hal_oemlock_remote_exec, exec_type, vendor_file_type, file_type;
+init_daemon_domain(hal_oemlock_remote)
+
+type oemlock_device, file_type;
+
+allow hal_oemlock_remote device:dir r_dir_perms;
+allow hal_oemlock_remote oemlock_device:chr_file rw_file_perms;
+
+# Write to kernel log (/dev/kmsg)
+allow hal_oemlock_remote kmsg_device:chr_file w_file_perms;
+allow hal_oemlock_remote kmsg_device:chr_file getattr;
diff --git a/shared/sepolicy/vendor/init.te b/shared/sepolicy/vendor/init.te
index 22a67583a..c8002d055 100644
--- a/shared/sepolicy/vendor/init.te
+++ b/shared/sepolicy/vendor/init.te
@@ -31,5 +31,7 @@ allow init gatekeeper_device:chr_file rw_file_perms;
allow init confirmationui_device:chr_file rw_file_perms;
allow init bt_device:chr_file rw_file_perms;
allow init uwb_device:chr_file rw_file_perms;
+allow init oemlock_device:chr_file rw_file_perms;
+allow init keymint_device:chr_file rw_file_perms;
allow init frp_block_device:blk_file setattr;
diff --git a/shared/sepolicy/vendor/ueventd.te b/shared/sepolicy/vendor/ueventd.te
index 6bea10450..5376cee57 100644
--- a/shared/sepolicy/vendor/ueventd.te
+++ b/shared/sepolicy/vendor/ueventd.te
@@ -4,3 +4,5 @@ allow ueventd keymaster_device:chr_file { rw_file_perms create setattr };
allow ueventd gatekeeper_device:chr_file { rw_file_perms create setattr };
allow ueventd confirmationui_device:chr_file { rw_file_perms create setattr };
allow ueventd metrics_helper_device:chr_file { rw_file_perms create setattr };
+allow ueventd oemlock_device:chr_file { rw_file_perms create setattr };
+allow ueventd keymint_device:chr_file { rw_file_perms create setattr };
diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp
index ccfe154d1..ff39669b8 100644
--- a/tests/hal/hal_implementation_test.cpp
+++ b/tests/hal/hal_implementation_test.cpp
@@ -98,7 +98,7 @@ static const std::set<std::string> kKnownMissingHidl = {
"android.hardware.memtrack@1.0",
"android.hardware.neuralnetworks@1.3", // converted to AIDL, see b/161428342
"android.hardware.nfc@1.2",
- "android.hardware.oemlock@1.0",
+ "android.hardware.oemlock@1.0", // converted to AIDL, see b/176107318 b/282160400
"android.hardware.power@1.3",
"android.hardware.power.stats@1.0",
"android.hardware.radio@1.6", // converted to AIDL