From 2799513c2b7461608e3b855d437dbca405b7856d Mon Sep 17 00:00:00 2001 From: Wei-chung Hsu Date: Fri, 8 Sep 2023 16:38:47 -0700 Subject: Backport prebuilt cvd binary file to solve group_id and version issues. ARM64 cvd BID is 10769592, x86_64 cvd BID is 10763722. Merged-In: Ic1120e710126ab85224184754fedad4301c1f6d1 Bug: b/293603107, b/293301482 Change-Id: I72de34a239d5577ec8376750fa908cad2c94599a --- host/commands/cvd/Android.bp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/host/commands/cvd/Android.bp b/host/commands/cvd/Android.bp index 6ec05351d..a6d6ec434 100644 --- a/host/commands/cvd/Android.bp +++ b/host/commands/cvd/Android.bp @@ -141,24 +141,3 @@ cc_library_host_static { ], defaults: ["cvd_and_fetch_cvd_defaults"], } - -// These are set up as two separate executables rather than a symlink so that -// either can be downloaded as a standalone statically linked executable from -// the build system. - -cc_binary_host { - name: "cvd", - symlinks: ["acloud"], - static_libs: [ - "cvd_and_fetch_cvd", - ], - defaults: ["cvd_and_fetch_cvd_defaults"], -} - -cc_binary_host { - name: "fetch_cvd", - static_libs: [ - "cvd_and_fetch_cvd", - ], - defaults: ["cvd_and_fetch_cvd_defaults"], -} -- cgit v1.2.3 From 51cce311823e6a1943a8e7c4dac7ad139a3f142d Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 24 May 2023 18:02:39 +0100 Subject: Introduce secure_env common RPC entities Currently all secure_env apps reimplement their own RPC basic architecture. Introduce a common one to reuse across them. Bug: 282160400 Bug: 304347870 Test: local changes with oemlock HAL use it successfully Change-Id: Ie04418d9b6bb3901e41342e1ea21d0fb76f65abe Merged-In: Ie04418d9b6bb3901e41342e1ea21d0fb76f65abe Signed-off-by: Dmitrii Merkurev --- common/libs/security/Android.bp | 2 + common/libs/security/channel.cpp | 32 ++++++++++++ common/libs/security/channel.h | 68 +++++++++++++++++++++++++ common/libs/security/channel_sharedfd.cpp | 85 +++++++++++++++++++++++++++++++ common/libs/security/channel_sharedfd.h | 40 +++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 common/libs/security/channel.cpp create mode 100644 common/libs/security/channel.h create mode 100644 common/libs/security/channel_sharedfd.cpp create mode 100644 common/libs/security/channel_sharedfd.h 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 + +#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; + +/* + * Interface for communication channels that synchronously communicate + * HAL IPC/RPC calls. + */ +class Channel { + public: + virtual Result SendRequest(uint32_t command, void* message, size_t message_size) = 0; + virtual Result SendResponse(uint32_t command, void* message, size_t message_size) = 0; + virtual Result 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 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(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 SharedFdChannel::SendRequest(uint32_t command, void* message, size_t message_size) { + return SendMessage(command, false, message, message_size); +} + +Result SharedFdChannel::SendResponse(uint32_t command, void* message, size_t message_size) { + return SendMessage(command, true, message, message_size); +} + +Result 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(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 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(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 SendRequest(uint32_t command, void* message, size_t message_size) override; + Result SendResponse(uint32_t command, void* message, size_t message_size) override; + Result ReceiveMessage() override; + + private: + SharedFD input_; + SharedFD output_; + + Result SendMessage(uint32_t command, bool response, void* message, size_t message_size); +}; + +} // namespace secure_env +} // namespace cuttlefish \ No newline at end of file -- cgit v1.2.3 From c8c1a65472cf7ee312f5ac82e5b3048161ca6483 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 24 May 2023 18:14:45 +0100 Subject: Add oemlock secure_env interface and software mock implementation Test: local changes with oemlock HAL use it successfully Bug: 282160400 Bug: 304347870 Change-Id: I35bddcac672302e4551be2fbf124ce1d589299b8 Merged-In: I35bddcac672302e4551be2fbf124ce1d589299b8 Signed-off-by: Dmitrii Merkurev --- host/commands/secure_env/oemlock.h | 38 +++++++++++++++++++++++ host/commands/secure_env/soft_oemlock.h | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 host/commands/secure_env/oemlock.h create mode 100644 host/commands/secure_env/soft_oemlock.h 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/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 + +#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 -- cgit v1.2.3 From 31f74366199ed3406e87a9754fd27f0f20f65874 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 24 May 2023 23:39:10 +0100 Subject: Add oemlock TPM transport Use new-introduced secure_env common transport to implement back-end part of oemlock TPM application Test: oemlock guest HAL use it successfully on crosvm/qemu Bug: 282160400 Bug: 304347870 Change-Id: I39981417331eba7b5db78f2c3bbe5da882e2ed88 Merged-In: I39981417331eba7b5db78f2c3bbe5da882e2ed88 Signed-off-by: Dmitrii Merkurev --- common/libs/security/oemlock.h | 30 ++++++++++ host/commands/run_cvd/launch/secure_env.cpp | 9 +++ host/commands/run_cvd/server_loop.cpp | 2 + host/commands/secure_env/Android.bp | 1 + host/commands/secure_env/oemlock_responder.cpp | 65 ++++++++++++++++++++++ host/commands/secure_env/oemlock_responder.h | 38 +++++++++++++ host/commands/secure_env/secure_env_linux_main.cpp | 42 +++++++++++++- host/libs/config/cuttlefish_config.cpp | 2 + host/libs/config/cuttlefish_config.h | 1 + host/libs/vm_manager/crosvm_manager.cpp | 4 ++ host/libs/vm_manager/qemu_manager.cpp | 2 + host/libs/vm_manager/vm_manager.h | 2 +- shared/sepolicy/vendor/genfs_contexts | 12 ++-- tests/hal/hal_implementation_test.cpp | 2 +- 14 files changed, 201 insertions(+), 11 deletions(-) create mode 100644 common/libs/security/oemlock.h create mode 100644 host/commands/secure_env/oemlock_responder.cpp create mode 100644 host/commands/secure_env/oemlock_responder.h 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 + +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/host/commands/run_cvd/launch/secure_env.cpp b/host/commands/run_cvd/launch/secure_env.cpp index b5e0cf89d..eab6e48fe 100644 --- a/host/commands/run_cvd/launch/secure_env.cpp +++ b/host/commands/run_cvd/launch/secure_env.cpp @@ -46,6 +46,8 @@ 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]); const auto& secure_hals = config_.secure_hals(); bool secure_keymint = secure_hals.count(SecureHal::Keymint) > 0; @@ -58,6 +60,11 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer { 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 commands; @@ -79,6 +86,8 @@ 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"), }; std::vector 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..72ed14c1a 100644 --- a/host/commands/run_cvd/server_loop.cpp +++ b/host/commands/run_cvd/server_loop.cpp @@ -213,6 +213,8 @@ class ServerLoopImpl : public ServerLoop, 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("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/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 + +#include "common/libs/security/oemlock.h" + +namespace cuttlefish { +namespace oemlock { + +OemLockResponder::OemLockResponder(secure_env::Channel& channel, + OemLock& oemlock) + : channel_(channel), oemlock_(oemlock) {} + +Result 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(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(request->payload); + oemlock_.SetOemUnlockAllowedByDevice(allowed); + } + break; + } + + default: + return CF_ERR("Unrecognized message id " << reinterpret_cast(request->command)); + } + + CF_EXPECT(channel_.SendResponse(request->command, &allowed, sizeof(bool)), + "Could not answer to " << reinterpret_cast(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 ProcessMessage(); + + private: + secure_env::Channel& channel_; + OemLock& oemlock_; +}; + +} // namespace oemlock +} // namespace cuttlefish diff --git a/host/commands/secure_env/secure_env_linux_main.cpp b/host/commands/secure_env/secure_env_linux_main.cpp index ade41d36c..901ecec36 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 #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" @@ -52,6 +56,8 @@ DEFINE_int32(keymaster_fd_in, -1, "A pipe for keymaster communication"); DEFINE_int32(keymaster_fd_out, -1, "A pipe for keymaster 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 " @@ -68,6 +74,9 @@ DEFINE_string(keymint_impl, "tpm", 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 +149,22 @@ ChooseGatekeeperComponent() { } } +fruit::Component ChooseOemlockComponent() { + if (FLAGS_oemlock_impl == "software") { + return fruit::createComponent() + .bind(); + } 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 + oemlock::OemLock, keymaster::KeymasterEnforcement> SecureEnvComponent() { return fruit::createComponent() .registerProvider([]() -> Tpm* { // fruit will take ownership @@ -188,7 +211,8 @@ SecureEnvComponent() { insecure_storage); }) .registerProvider([]() { return new gatekeeper::SoftGateKeeper(); }) - .install(ChooseGatekeeperComponent); + .install(ChooseGatekeeperComponent) + .install(ChooseOemlockComponent); } } // namespace @@ -199,10 +223,11 @@ int SecureEnvMain(int argc, char** argv) { keymaster::SoftKeymasterLogger km_logger; fruit::Injector + oemlock::OemLock, keymaster::KeymasterEnforcement> injector(SecureEnvComponent); TpmResourceManager* resource_manager = injector.get(); gatekeeper::GateKeeper* gatekeeper = injector.get(); + oemlock::OemLock* oemlock = injector.get(); keymaster::KeymasterEnforcement* keymaster_enforcement = injector.get(); std::unique_ptr keymaster_context; @@ -280,6 +305,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/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..b195cb774 100644 --- a/host/libs/vm_manager/crosvm_manager.cpp +++ b/host/libs/vm_manager/crosvm_manager.cpp @@ -425,6 +425,10 @@ Result> CrosvmManager::StartCommands( crosvm_cmd.AddHvcSink(); } + crosvm_cmd.AddHvcReadWrite( + instance.PerInstanceInternalPath("oemlock_fifo_vm.out"), + instance.PerInstanceInternalPath("oemlock_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..0db1f96d7 100644 --- a/host/libs/vm_manager/qemu_manager.cpp +++ b/host/libs/vm_manager/qemu_manager.cpp @@ -534,6 +534,8 @@ Result> QemuManager::StartCommands( add_hvc_sink(); } + add_hvc(instance.PerInstanceInternalPath("oemlock_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..560f8d2c1 100644 --- a/host/libs/vm_manager/vm_manager.h +++ b/host/libs/vm_manager/vm_manager.h @@ -42,7 +42,7 @@ class VmManager { // 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; + static const int kDefaultNumHvcs = 11; // 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/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts index 758fb54e9..2dd57e7e0 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, 0xd, 12) 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 @@ -82,7 +82,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, 0xe, 13) 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 +90,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, 0xe, 12) #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 +98,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, 0xd, 12) 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 +106,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, 0xd, 12) 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, 0xe, 13) cf_pci_gpu_device(/devices/platform/soc/30000000.pci/pci0000:00, 0x1) # common on all platforms / vm managers diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp index 55926c65f..eb2001c10 100644 --- a/tests/hal/hal_implementation_test.cpp +++ b/tests/hal/hal_implementation_test.cpp @@ -98,7 +98,7 @@ static const std::set 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 -- cgit v1.2.3 From 091861a6cdd85f27dc4866b501a1ae32eecf8320 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 24 May 2023 19:31:24 +0100 Subject: Add oemlock remote hal Utilize introduced oemlock TPM application to implement guest HAL Test: verified oemlock changes works from settings Bug: 282160780 Bug: 304347870 Change-Id: I35466a29e6854a86beee6c3b8acf51384e7a49c0 Merged-In: I35466a29e6854a86beee6c3b8acf51384e7a49c0 Signed-off-by: Dmitrii Merkurev --- guest/hals/oemlock/remote/Android.bp | 42 ++++++++++ .../android.hardware.oemlock-service.remote.rc | 4 + .../android.hardware.oemlock-service.remote.xml | 10 +++ guest/hals/oemlock/remote/remote_oemlock.cpp | 93 ++++++++++++++++++++++ guest/hals/oemlock/remote/remote_oemlock.h | 55 +++++++++++++ guest/hals/oemlock/remote/service.cpp | 51 ++++++++++++ shared/config/ueventd.rc | 3 + shared/device.mk | 20 +++-- shared/sepolicy/vendor/file_contexts | 5 +- shared/sepolicy/vendor/hal_oemlock_remote.te | 14 ++++ shared/sepolicy/vendor/init.te | 1 + shared/sepolicy/vendor/ueventd.te | 1 + 12 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 guest/hals/oemlock/remote/Android.bp create mode 100644 guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.rc create mode 100644 guest/hals/oemlock/remote/android.hardware.oemlock-service.remote.xml create mode 100644 guest/hals/oemlock/remote/remote_oemlock.cpp create mode 100644 guest/hals/oemlock/remote/remote_oemlock.h create mode 100644 guest/hals/oemlock/remote/service.cpp create mode 100644 shared/sepolicy/vendor/hal_oemlock_remote.te 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 @@ + + + android.hardware.oemlock + 1 + + IOemLock + default + + + 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 + +namespace aidl { +namespace android { +namespace hardware { +namespace oemlock { +namespace { + +enum { + CUSTOM_ERROR_TRANSPORT_IS_FAILED = 0, +}; + +::ndk::ScopedAStatus resultToStatus(Result 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 &, + 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 OemLock::requestValue(secure_env::OemLockField field, bool *out) { + CF_EXPECT(channel_.SendRequest(static_cast(field), nullptr, 0), + "Can't send get value request for field: " << static_cast(field)); + auto response = CF_EXPECT(channel_.ReceiveMessage(), + "Haven't received an answer for getting the field: " << + static_cast(field)); + *out = *reinterpret_cast(response->payload); + return {}; +} + +Result OemLock::setValue(secure_env::OemLockField field, bool value) { + CF_EXPECT(channel_.SendRequest(static_cast(field), &value, sizeof(bool)), + "Can't send set value request for field: " << static_cast(field)); + auto response = CF_EXPECT(channel_.ReceiveMessage(), + "Haven't received an answer for setting the field: " << + static_cast(field)); + auto updated_value = *reinterpret_cast(response->payload); + CF_EXPECT(value == updated_value, + "Updated value for the field " << static_cast(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 + +#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&, + OemLockSecureStatus* _aidl_return) override; + ::ndk::ScopedAStatus setOemUnlockAllowedByDevice(bool in_allowed) override; + +private: + secure_env::Channel& channel_; + + Result requestValue(secure_env::OemLockField field, bool *out); + Result 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 +#include +#include + +#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 = ndk::SharedRefBase::make(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/shared/config/ueventd.rc b/shared/config/ueventd.rc index 4e80bda03..ecb4177f9 100644 --- a/shared/config/ueventd.rc +++ b/shared/config/ueventd.rc @@ -38,5 +38,8 @@ # uwb /dev/hvc9 0660 uwb uwb +# oemlock +/dev/hvc10 0660 hsm hsm + # Factory Reset Protection /dev/block/by-name/frp 0660 system system diff --git a/shared/device.mk b/shared/device.mk index d860dda51..7c8a05470 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,11 +435,22 @@ 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 # diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts index 0d9468773..2f6c31a64 100644 --- a/shared/sepolicy/vendor/file_contexts +++ b/shared/sepolicy/vendor/file_contexts @@ -38,6 +38,9 @@ # hvc9 for uwb /dev/hvc9 u:object_r:uwb_device:s0 +# hvc10 for oemlock +/dev/hvc10 u:object_r:oemlock_device:s0 + # ARM serial console device /dev/ttyAMA[0-9]* u:object_r:serial_device:s0 @@ -98,7 +101,7 @@ /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/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..91f7ed40b 100644 --- a/shared/sepolicy/vendor/init.te +++ b/shared/sepolicy/vendor/init.te @@ -31,5 +31,6 @@ 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 frp_block_device:blk_file setattr; diff --git a/shared/sepolicy/vendor/ueventd.te b/shared/sepolicy/vendor/ueventd.te index 6bea10450..e77caf7c5 100644 --- a/shared/sepolicy/vendor/ueventd.te +++ b/shared/sepolicy/vendor/ueventd.te @@ -4,3 +4,4 @@ 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 }; -- cgit v1.2.3 From 9a9281eded3532fbb17033274a7056eb0909983e Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Mon, 29 May 2023 14:30:26 +0100 Subject: Tag device:1f as sysfs_wakeup From boot log: android.system.suspend-service: Error opening kernel wakelock stats for: wakeup25 (../../device:1f/wakeup/wakeup25): Permission denied Bug: 284475099 Bug: 304347870 Test: boot cf, no denials Change-Id: I9810a11d7ef9739158b16d5a95025576774677f3 Merged-In: I9810a11d7ef9739158b16d5a95025576774677f3 Signed-off-by: Dmitrii Merkurev --- shared/sepolicy/vendor/genfs_contexts | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts index 2dd57e7e0..af8ead446 100644 --- a/shared/sepolicy/vendor/genfs_contexts +++ b/shared/sepolicy/vendor/genfs_contexts @@ -69,6 +69,7 @@ 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 ## 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 -- cgit v1.2.3 From 5204f119d859d3ae5f1a2ee1c6a05ee68d6a28ed Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 24 May 2023 12:27:05 +0100 Subject: Use separate /dev/hvc11 for KeyMint/Rust Run the Rust implementation of KeyMint on Cuttlefish over a distinct port than the one used for C++ KeyMint/Keymaster. - Add a new /dev/hvc11 that is intended for use by the Rust KeyMint implementation, instead of re-using /dev/hvc3 (which was used by the C++ KeyMint/Keymaster implementation). - Set up all the SELinux policies for this extra port. Bug: 284005273 Bug: 304347870 Test: build, run, VtsAidlKeyMintTargetTest Change-Id: I3c71d17e6fa99e243c0acfd19697fa42288d8f96 Merged-In: I3c71d17e6fa99e243c0acfd19697fa42288d8f96 --- guest/hals/keymint/rust/src/keymint_hal_main.rs | 2 +- host/commands/run_cvd/launch/secure_env.cpp | 4 + host/commands/run_cvd/server_loop.cpp | 2 + host/commands/secure_env/doc/linkage.dot | 24 +- host/commands/secure_env/doc/linkage.png | Bin 80403 -> 100802 bytes host/commands/secure_env/doc/linkage.svg | 315 +++++++++++++-------- host/commands/secure_env/secure_env_linux_main.cpp | 10 +- host/libs/vm_manager/crosvm_manager.cpp | 17 ++ host/libs/vm_manager/qemu_manager.cpp | 14 + host/libs/vm_manager/vm_manager.h | 16 +- shared/config/ueventd.rc | 5 +- shared/sepolicy/vendor/file_contexts | 5 +- shared/sepolicy/vendor/genfs_contexts | 13 +- shared/sepolicy/vendor/hal_keymint_rust.te | 18 ++ shared/sepolicy/vendor/init.te | 1 + shared/sepolicy/vendor/ueventd.te | 1 + 16 files changed, 302 insertions(+), 145 deletions(-) create mode 100644 shared/sepolicy/vendor/hal_keymint_rust.te 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/host/commands/run_cvd/launch/secure_env.cpp b/host/commands/run_cvd/launch/secure_env.cpp index eab6e48fe..b047ae1b4 100644 --- a/host/commands/run_cvd/launch/secure_env.cpp +++ b/host/commands/run_cvd/launch/secure_env.cpp @@ -48,6 +48,8 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer { 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; @@ -88,6 +90,8 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer { 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 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 72ed14c1a..b716e3358 100644 --- a/host/commands/run_cvd/server_loop.cpp +++ b/host/commands/run_cvd/server_loop.cpp @@ -211,6 +211,8 @@ 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"), 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 Binary files a/host/commands/secure_env/doc/linkage.png and b/host/commands/secure_env/doc/linkage.png 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 @@ - - + + %3 - + cluster_android - -Android VM + +Android VM + + +cluster_keymint + +One of: browser - -Browser + +Browser webRTC - -webRTC + +webRTC browser->webRTC - - + + confirmationui_sign - -internal/confui_sign.sock + +internal/confui_sign.sock confirmationui_sign->webRTC - - - + + + run_cvd - -run_cvd + +run_cvd secure_env - - -secure_env - + + +secure_env + run_cvd->secure_env - - + + secure_env->confirmationui_sign - - - + + + - + -host_keymint_in - -internal/keymaster_fifo_vm.in +host_keymaster_in + +internal/keymaster_fifo_vm.in - + -secure_env->host_keymint_in - - +secure_env->host_keymaster_in + + - + -host_keymint_out - -internal/keymaster_fifo_vm.out +host_keymaster_out + +internal/keymaster_fifo_vm.out - + -secure_env->host_keymint_out - - +secure_env->host_keymaster_out + + host_gatekeeper_in - -internal/gatekeeper_fifo_vm.in + +internal/gatekeeper_fifo_vm.in secure_env->host_gatekeeper_in - - + + host_gatekeeper_out - -internal/gatekeeper_fifo_vm.out + +internal/gatekeeper_fifo_vm.out secure_env->host_gatekeeper_out - - + + + + + +host_keymint_in + +internal/keymint_fifo_vm.in + + + +secure_env->host_keymint_in + + + + + +host_keymint_out + +internal/keymint_fifo_vm.out + + + +secure_env->host_keymint_out + + vmm - -crosvm / qemu + +crosvm / qemu - + confirmationui_console - -/dev/hvc8 + +/dev/hvc8 vmm->confirmationui_console - - - + + + - + gatekeeper_console - -/dev/hvc4 + +/dev/hvc4 vmm->gatekeeper_console - - - + + + + + + +keymaster_console + +/dev/hvc3 + + + +vmm->keymaster_console + + + - + keymint_console - -/dev/hvc3 + +/dev/hvc11 - + vmm->keymint_console - - - + + + host_confirmationui_in - -internal/confui_fifo_vm.in + +internal/confui_fifo_vm.in webRTC->host_confirmationui_in - - + + host_confirmationui_out - -internal/confui_fifo_vm.out + +internal/confui_fifo_vm.out webRTC->host_confirmationui_out - - + + - + -host_keymint_in->vmm - - +host_keymaster_in->vmm + + - + -host_keymint_out->vmm - - +host_keymaster_out->vmm + + host_gatekeeper_in->vmm - - + + host_gatekeeper_out->vmm - - + + host_confirmationui_in->vmm - - + + host_confirmationui_out->vmm - - + + + + + +host_keymint_in->vmm + + + + + +host_keymint_out->vmm + + - + u_boot - -u-boot + +u-boot - + confirmationui - -ConfirmationUI HAL + +ConfirmationUI HAL - + gatekeeper - -Gatekeeper HAL + +Gatekeeper HAL + + + +keymaster + +KeyMint (C++) HAL - + keymint - -Keymint HAL + +KeyMint (Rust) HAL confirmationui_console->confirmationui - - - + + + gatekeeper_console->gatekeeper - - - + + + - + -keymint_console->u_boot - - - +keymaster_console->u_boot + + + - + +keymaster_console->keymaster + + + + + + keymint_console->keymint - - - + + + diff --git a/host/commands/secure_env/secure_env_linux_main.cpp b/host/commands/secure_env/secure_env_linux_main.cpp index 901ecec36..610b52787 100644 --- a/host/commands/secure_env/secure_env_linux_main.cpp +++ b/host/commands/secure_env/secure_env_linux_main.cpp @@ -54,6 +54,8 @@ 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"); @@ -248,11 +250,11 @@ int SecureEnvMain(int argc, char** argv) { return -1; } - int keymaster_in = FLAGS_keymaster_fd_in; - int keymaster_out = FLAGS_keymaster_fd_out; + int keymint_in = FLAGS_keymint_fd_in; + int keymint_out = FLAGS_keymint_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); + threads.emplace_back([rm, keymint_in, keymint_out, security_level]() { + kmr_ta_main(keymint_in, keymint_out, security_level, rm); }); } else { diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp index b195cb774..100b71e56 100644 --- a/host/libs/vm_manager/crosvm_manager.cpp +++ b/host/libs/vm_manager/crosvm_manager.cpp @@ -316,6 +316,7 @@ Result> 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> 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> 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> 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> 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,10 +436,16 @@ Result> 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 0db1f96d7..a2744a35d 100644 --- a/host/libs/vm_manager/qemu_manager.cpp +++ b/host/libs/vm_manager/qemu_manager.cpp @@ -457,6 +457,7 @@ Result> 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> 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> 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,16 +534,22 @@ Result> 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 560f8d2c1..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 = 11; + // 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 ecb4177f9..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 @@ -41,5 +41,8 @@ # 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/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts index 2f6c31a64..4805bb1a5 100644 --- a/shared/sepolicy/vendor/file_contexts +++ b/shared/sepolicy/vendor/file_contexts @@ -41,6 +41,9 @@ # 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 @@ -97,7 +100,7 @@ /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 diff --git a/shared/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts index af8ead446..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, 0xd, 12) +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 @@ -70,6 +70,7 @@ genfscon sysfs /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/wakeup u:ob 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 @@ -83,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, 0xe, 13) +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 @@ -91,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, 0xe, 12) +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 @@ -99,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, 0xd, 12) +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 @@ -107,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, 0xd, 12) +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, 0xe, 13) +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/init.te b/shared/sepolicy/vendor/init.te index 91f7ed40b..c8002d055 100644 --- a/shared/sepolicy/vendor/init.te +++ b/shared/sepolicy/vendor/init.te @@ -32,5 +32,6 @@ 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 e77caf7c5..5376cee57 100644 --- a/shared/sepolicy/vendor/ueventd.te +++ b/shared/sepolicy/vendor/ueventd.te @@ -5,3 +5,4 @@ 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 }; -- cgit v1.2.3 From 27b7db3e0bb17bf8341cd3125e4ebe5295109ebf Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 24 May 2023 13:49:32 +0100 Subject: Run both C++ and Rust KeyMint TAs The guest being run may be configured with either the C++ or the Rust KeyMint HAL service, and each of those needs to match up to a corresponding TA implementation in secure_env. To allow for this, run both the C++ and the Rust KeyMint TAs at the same time, on different threads and using distinct ports. Only one of them will get traffic and be active; the other will sit quiescent. Having both implementations available in secure_env also means that the build flags to allow switching between the implementations are no longer necessary. Test: build, boot, VtsAidlKeyMintTargetTest Bug: 284005273 Bug: 304347870 Change-Id: Ib7f69f7e7fc734695fd1cff86191bb0759974d22 Merged-In: Ib7f69f7e7fc734695fd1cff86191bb0759974d22 --- host/commands/run_cvd/Android.bp | 29 ------ host/commands/run_cvd/launch/secure_env.cpp | 5 - host/commands/secure_env/rust/lib.rs | 2 +- host/commands/secure_env/secure_env_linux_main.cpp | 111 +++++++++++---------- shared/device.mk | 6 -- 5 files changed, 59 insertions(+), 94 deletions(-) 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 b047ae1b4..a70fc1445 100644 --- a/host/commands/run_cvd/launch/secure_env.cpp +++ b/host/commands/run_cvd/launch/secure_env.cpp @@ -53,12 +53,7 @@ class SecureEnvironment : public CommandSource, public KernelLogPipeConsumer { 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); 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 610b52787..56428c901 100644 --- a/host/commands/secure_env/secure_env_linux_main.cpp +++ b/host/commands/secure_env/secure_env_linux_main.cpp @@ -70,8 +70,7 @@ 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\""); @@ -237,61 +236,67 @@ int SecureEnvMain(int argc, char** argv) { std::vector 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 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); - }); + // 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); diff --git a/shared/device.mk b/shared/device.mk index 7c8a05470..59338edb7 100644 --- a/shared/device.mk +++ b/shared/device.mk @@ -509,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) \ -- cgit v1.2.3 From ff3f449e1d4188a59888d20c875c36d0154c3c9d Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 31 May 2023 20:03:58 +0100 Subject: Fix misc and metadata images caching Recreating of metadata and misc leads to CVD wipe Bug: 285167626 Bug: 265068221 Bug: 307584049 Signed-off-by: Dmitrii Merkurev (cherry picked from https://android-review.googlesource.com/q/commit:d3b21b11d73b818b0f5ea77f8bff3c4740e7f0ba) Merged-In: I046da502f1f92a8905ef45b8e42891f3a618e3b1 Change-Id: I046da502f1f92a8905ef45b8e42891f3a618e3b1 --- host/commands/assemble_cvd/disk_flags.cc | 4 ++-- host/libs/config/data_image.cpp | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc index dc6e4f2f2..beae35e48 100644 --- a/host/commands/assemble_cvd/disk_flags.cc +++ b/host/commands/assemble_cvd/disk_flags.cc @@ -901,8 +901,8 @@ class InitializeMetadataImage : public SetupFeature { private: std::unordered_set Dependencies() const override { return {}; } Result ResultSetup() override { - if (FileExists(instance_.metadata_image()) && - FileSize(instance_.metadata_image()) == instance_.blank_metadata_image_mb() << 20) { + if (FileExists(instance_.new_metadata_image()) && + FileSize(instance_.new_metadata_image()) == instance_.blank_metadata_image_mb() << 20) { return {}; } diff --git a/host/libs/config/data_image.cpp b/host/libs/config/data_image.cpp index 45dbad845..e3a6fe48d 100644 --- a/host/libs/config/data_image.cpp +++ b/host/libs/config/data_image.cpp @@ -307,16 +307,13 @@ class InitializeMiscImageImpl : public InitializeMiscImage { private: std::unordered_set Dependencies() const override { return {}; } bool Setup() override { - bool misc_exists = FileHasContent(instance_.misc_image()); - - if (misc_exists) { - LOG(DEBUG) << "misc partition image: use existing at \"" - << instance_.misc_image() << "\""; + if (FileHasContent(instance_.new_misc_image())) { + LOG(DEBUG) << "misc partition image already exists"; return true; } LOG(DEBUG) << "misc partition image: creating empty at \"" - << instance_.misc_image() << "\""; + << instance_.new_misc_image() << "\""; if (!CreateBlankImage(instance_.new_misc_image(), 1 /* mb */, "none")) { LOG(ERROR) << "Failed to create misc image"; return false; -- cgit v1.2.3 From 93f6c89738887809fa1a576edb080a58b13b4cfd Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Wed, 31 May 2023 20:13:00 +0100 Subject: Avoid redundant deletion of misc and metadata partitions They're backing the overlay, any deletion of them triggers device wipe, so preserving them alongside with other similar images. Bug: 285167626 Bug: 265068221 Bug: 307584049 Signed-off-by: Dmitrii Merkurev (cherry picked from https://android-review.googlesource.com/q/commit:aeee1f6356ed6893c1343193320218e9e8f82925) Merged-In: I66b6fc94834f3a57bf5fb076049a09221eafa95f Change-Id: I66b6fc94834f3a57bf5fb076049a09221eafa95f --- host/commands/assemble_cvd/assemble_cvd.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc index 9d285ecab..cfaac2991 100644 --- a/host/commands/assemble_cvd/assemble_cvd.cc +++ b/host/commands/assemble_cvd/assemble_cvd.cc @@ -254,6 +254,8 @@ Result InitFilesystemAndCreateConfig( preserving.insert("persistent_composite.img"); preserving.insert("uboot_env.img"); preserving.insert("factory_reset_protected.img"); + preserving.insert("misc.img"); + preserving.insert("metadata.img"); std::stringstream ss; for (int i = 0; i < modem_simulator_count; i++) { ss.clear(); -- cgit v1.2.3 From 1ec6fb25e34c708d89f00d7cb8e193824d2f8a7b Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Thu, 8 Jun 2023 19:10:13 +0100 Subject: Use ManagedMessage in channel signatures This helps to avoid redundant copy for more complicated messages then primitive types. Particularly it allowes us to form full message using CreateMessage + GateKeeperMessage:: Serialize(message->payload) without serializing it to an intermidiate argument Test: atest VtsHalOemLockTargetTest Bug: 282160400 Bug: 307584049 Signed-off-by: Dmitrii Merkurev (cherry picked from https://android-review.googlesource.com/q/commit:a9866877ba8a36935eef480baab32a4ed2540c9c) Merged-In: I48d5447ecc716b8e60f08ed9d6b3e947dde5bc36 Change-Id: I48d5447ecc716b8e60f08ed9d6b3e947dde5bc36 --- common/libs/security/channel.cpp | 20 +++++++++++++ common/libs/security/channel.h | 11 +++++-- common/libs/security/channel_sharedfd.cpp | 41 +++++++------------------- common/libs/security/channel_sharedfd.h | 6 ++-- guest/hals/oemlock/remote/remote_oemlock.cpp | 11 +++++-- host/commands/secure_env/oemlock_responder.cpp | 5 +++- 6 files changed, 55 insertions(+), 39 deletions(-) diff --git a/common/libs/security/channel.cpp b/common/libs/security/channel.cpp index 009617da1..e2891aa2f 100644 --- a/common/libs/security/channel.cpp +++ b/common/libs/security/channel.cpp @@ -28,5 +28,25 @@ void MessageDestroyer::operator()(RawMessage* ptr) { std::free(ptr); } +/** + * Allocates memory for a RawMessage carrying a message of size + * `payload_size`. + */ +Result 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(memory); + message->command = command; + message->is_response = is_response; + message->payload_size = payload_size; + return ManagedMessage(message); +} + +Result CreateMessage(uint32_t command, size_t payload_size) { + return CreateMessage(command, false, payload_size); +} + } // 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 index bbfb86779..eb415e2a0 100644 --- a/common/libs/security/channel.h +++ b/common/libs/security/channel.h @@ -52,14 +52,21 @@ class MessageDestroyer { /** An owning pointer for a RawMessage instance. */ using ManagedMessage = std::unique_ptr; +/** + * Allocates memory for a RawMessage carrying a message of size + * `payload_size`. + */ +Result CreateMessage(uint32_t command, bool is_response, size_t payload_size); +Result CreateMessage(uint32_t command, size_t payload_size); + /* * Interface for communication channels that synchronously communicate * HAL IPC/RPC calls. */ class Channel { public: - virtual Result SendRequest(uint32_t command, void* message, size_t message_size) = 0; - virtual Result SendResponse(uint32_t command, void* message, size_t message_size) = 0; + virtual Result SendRequest(RawMessage& message) = 0; + virtual Result SendResponse(RawMessage& message) = 0; virtual Result ReceiveMessage() = 0; virtual ~Channel() {} }; diff --git a/common/libs/security/channel_sharedfd.cpp b/common/libs/security/channel_sharedfd.cpp index c07d876b0..a152cf32b 100644 --- a/common/libs/security/channel_sharedfd.cpp +++ b/common/libs/security/channel_sharedfd.cpp @@ -20,35 +20,16 @@ namespace cuttlefish { namespace secure_env { -namespace { - -/** - * Allocates memory for a RawMessage carrying a message of size - * `payload_size`. - */ -Result 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(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 SharedFdChannel::SendRequest(uint32_t command, void* message, size_t message_size) { - return SendMessage(command, false, message, message_size); +Result SharedFdChannel::SendRequest(RawMessage& message) { + return SendMessage(message, false); } -Result SharedFdChannel::SendResponse(uint32_t command, void* message, size_t message_size) { - return SendMessage(command, true, message, message_size); +Result SharedFdChannel::SendResponse(RawMessage& message) { + return SendMessage(message, true); } Result SharedFdChannel::ReceiveMessage() { @@ -69,14 +50,12 @@ Result SharedFdChannel::ReceiveMessage() { return message; } -Result 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(to_send.get()); - auto written = WriteAll(output_, to_send_bytes, write_size); - CF_EXPECT(written != -1, +Result SharedFdChannel::SendMessage(RawMessage& message, bool response) { + message.is_response = response; + auto write_size = sizeof(RawMessage) + message.payload_size; + auto message_bytes = reinterpret_cast(&message); + auto written = WriteAll(output_, message_bytes, write_size); + CF_EXPECT(written == write_size, "Could not write message: " << output_->StrError()); return {}; } diff --git a/common/libs/security/channel_sharedfd.h b/common/libs/security/channel_sharedfd.h index 3d0fdbcda..39f27490d 100644 --- a/common/libs/security/channel_sharedfd.h +++ b/common/libs/security/channel_sharedfd.h @@ -25,15 +25,15 @@ namespace secure_env { class SharedFdChannel : public Channel { public: SharedFdChannel(SharedFD input, SharedFD output); - Result SendRequest(uint32_t command, void* message, size_t message_size) override; - Result SendResponse(uint32_t command, void* message, size_t message_size) override; + Result SendRequest(RawMessage& message) override; + Result SendResponse(RawMessage& message) override; Result ReceiveMessage() override; private: SharedFD input_; SharedFD output_; - Result SendMessage(uint32_t command, bool response, void* message, size_t message_size); + Result SendMessage(RawMessage& message, bool response); }; } // namespace secure_env diff --git a/guest/hals/oemlock/remote/remote_oemlock.cpp b/guest/hals/oemlock/remote/remote_oemlock.cpp index f427ec028..46727be62 100644 --- a/guest/hals/oemlock/remote/remote_oemlock.cpp +++ b/guest/hals/oemlock/remote/remote_oemlock.cpp @@ -65,7 +65,10 @@ OemLock::OemLock(secure_env::Channel& channel) : channel_(channel) {} } Result OemLock::requestValue(secure_env::OemLockField field, bool *out) { - CF_EXPECT(channel_.SendRequest(static_cast(field), nullptr, 0), + auto message = CF_EXPECT(secure_env::CreateMessage(static_cast(field), 0), + "Cannot allocate message for oemlock request: " << + static_cast(field)); + CF_EXPECT(channel_.SendRequest(*message), "Can't send get value request for field: " << static_cast(field)); auto response = CF_EXPECT(channel_.ReceiveMessage(), "Haven't received an answer for getting the field: " << @@ -75,7 +78,11 @@ Result OemLock::requestValue(secure_env::OemLockField field, bool *out) { } Result OemLock::setValue(secure_env::OemLockField field, bool value) { - CF_EXPECT(channel_.SendRequest(static_cast(field), &value, sizeof(bool)), + auto message = CF_EXPECT(secure_env::CreateMessage(static_cast(field), sizeof(bool)), + "Cannot allocate message for oemlock request: " << + static_cast(field)); + memcpy(message->payload, &value, sizeof(bool)); + CF_EXPECT(channel_.SendRequest(*message), "Can't send set value request for field: " << static_cast(field)); auto response = CF_EXPECT(channel_.ReceiveMessage(), "Haven't received an answer for setting the field: " << diff --git a/host/commands/secure_env/oemlock_responder.cpp b/host/commands/secure_env/oemlock_responder.cpp index 3f9ad50c0..698be32ff 100644 --- a/host/commands/secure_env/oemlock_responder.cpp +++ b/host/commands/secure_env/oemlock_responder.cpp @@ -55,7 +55,10 @@ Result OemLockResponder::ProcessMessage() { return CF_ERR("Unrecognized message id " << reinterpret_cast(request->command)); } - CF_EXPECT(channel_.SendResponse(request->command, &allowed, sizeof(bool)), + auto message = CF_EXPECT(secure_env::CreateMessage(request->command, sizeof(bool)), + "Failed to allocate message for oemlock response"); + memcpy(message->payload, &allowed, sizeof(bool)); + CF_EXPECT(channel_.SendResponse(*message), "Could not answer to " << reinterpret_cast(request->command) << " request"); return {}; -- cgit v1.2.3 From 61677e8fa3b63657881876a577dd3e5a282b5475 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Sun, 11 Jun 2023 19:03:30 +0100 Subject: Introduce key(string):value(binary) storage This is needed to reuse existing gatekeeper TPM NV storage logic in oemlock. Also introduced insecure json implementation for software oemlock implementation (in case TPM isn't available) Bug: 282160400 Bug: 307584049 Test: atest VtsHalOemLockTargetTest with other local changes Signed-off-by: Dmitrii Merkurev (cherry picked from https://android-review.googlesource.com/q/commit:ec2fc895b6d3d656d2a1d67b1bce86cfd8bc9253) Merged-In: I843c5937b48a06d763f7cee46fd4bfb10f31aeaa Change-Id: I843c5937b48a06d763f7cee46fd4bfb10f31aeaa --- host/commands/secure_env/Android.bp | 6 ++ .../secure_env/storage/insecure_json_storage.cpp | 88 ++++++++++++++++++++++ .../secure_env/storage/insecure_json_storage.h | 37 +++++++++ host/commands/secure_env/storage/storage.cpp | 48 ++++++++++++ host/commands/secure_env/storage/storage.h | 69 +++++++++++++++++ 5 files changed, 248 insertions(+) create mode 100644 host/commands/secure_env/storage/insecure_json_storage.cpp create mode 100644 host/commands/secure_env/storage/insecure_json_storage.h create mode 100644 host/commands/secure_env/storage/storage.cpp create mode 100644 host/commands/secure_env/storage/storage.h diff --git a/host/commands/secure_env/Android.bp b/host/commands/secure_env/Android.bp index 73d443b17..0bd3690b7 100644 --- a/host/commands/secure_env/Android.bp +++ b/host/commands/secure_env/Android.bp @@ -79,6 +79,7 @@ common_libsecure_srcs = [ "keymaster_responder.cpp", "oemlock_responder.cpp", "primary_key_builder.cpp", + "storage/storage.cpp", "tpm_attestation_record.cpp", "tpm_auth.cpp", "tpm_commands.cpp", @@ -95,11 +96,16 @@ common_libsecure_srcs = [ "tpm_serialize.cpp", ] +// Things blocking us to use oemlock on windows: +// 1. Missing transport implementation +// 2. Missing file utils +// 3. Base64 isn't supported (need for software oemlock implementation) cc_library_host_static { name: "libsecure_env_linux", srcs: common_libsecure_srcs + [ "confui_sign_server.cpp", "device_tpm.cpp", + "storage/insecure_json_storage.cpp", ], defaults: ["cuttlefish_buildhost_only", "secure_env_defaults"], } diff --git a/host/commands/secure_env/storage/insecure_json_storage.cpp b/host/commands/secure_env/storage/insecure_json_storage.cpp new file mode 100644 index 000000000..a85e7e427 --- /dev/null +++ b/host/commands/secure_env/storage/insecure_json_storage.cpp @@ -0,0 +1,88 @@ +// +// 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/storage/insecure_json_storage.h" + +#include + +#include +#include + +#include "common/libs/utils/base64.h" +#include "common/libs/utils/files.h" +#include "common/libs/utils/json.h" + +namespace cuttlefish { +namespace secure_env { +namespace { + +Result ReadJson(const std::string& path) { + std::string json; + CF_EXPECT(android::base::ReadFileToString(path, &json)); + return CF_EXPECT(ParseJson(json)); +} + +Result WriteJson(const std::string& path, const Json::Value& root) { + Json::StreamWriterBuilder builder; + auto json = Json::writeString(builder, root); + CF_EXPECT(android::base::WriteStringToFile(json, path)); + return {}; +} + +} // namespace + +InsecureJsonStorage::InsecureJsonStorage(std::string path) : path_(std::move(path)) {} + +bool InsecureJsonStorage::Exists() const { + return ReadJson(path_).ok(); +} + +Result InsecureJsonStorage::HasKey(const std::string& key) const { + if (!FileHasContent(path_)) { + return false; + } + return CF_EXPECT(ReadJson(path_)).isMember(key); +} + +Result InsecureJsonStorage::Read(const std::string& key) const { + auto root = CF_EXPECT(ReadJson(path_)); + CF_EXPECT(root.isMember(key), "Key: " << key << " not found in " << path_); + + std::vector base64_buffer; + CF_EXPECT(DecodeBase64(root[key].asString(), &base64_buffer), + "Failed to decode base64 to read key: " << key); + auto storage_data = CF_EXPECT(CreateStorageData(base64_buffer.size())); + std::memcpy(storage_data->payload, reinterpret_cast(base64_buffer.data()), + base64_buffer.size()); + return storage_data; +} + +Result InsecureJsonStorage::Write(const std::string& key, const StorageData& data) { + Json::Value root; + if (FileHasContent(path_)) { + root = CF_EXPECT(ReadJson(path_)); + } + + std::string value_base64; + CF_EXPECT(EncodeBase64(data.payload, data.size, &value_base64), + "Failed to encode base64 to write key: " << key); + root[key] = value_base64; + + CF_EXPECT(WriteJson(path_, root)); + return {}; +} + +} // namespace oemlock +} // namespace cuttlefish diff --git a/host/commands/secure_env/storage/insecure_json_storage.h b/host/commands/secure_env/storage/insecure_json_storage.h new file mode 100644 index 000000000..f811774cd --- /dev/null +++ b/host/commands/secure_env/storage/insecure_json_storage.h @@ -0,0 +1,37 @@ +// +// 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 "host/commands/secure_env/storage/storage.h" + +namespace cuttlefish { +namespace secure_env { + +class InsecureJsonStorage : public secure_env::Storage { + public: + InsecureJsonStorage(std::string path); + + Result HasKey(const std::string& key) const override; + Result Read(const std::string& key) const override; + Result Write(const std::string& key, const StorageData& data) override; + bool Exists() const override; + + private: + std::string path_; +}; + +} // namespace secure_env +} // namespace cuttlefish diff --git a/host/commands/secure_env/storage/storage.cpp b/host/commands/secure_env/storage/storage.cpp new file mode 100644 index 000000000..5c7cb2f11 --- /dev/null +++ b/host/commands/secure_env/storage/storage.cpp @@ -0,0 +1,48 @@ +/* + * 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 "host/commands/secure_env/storage/storage.h" + +#include "keymaster/android_keymaster_utils.h" + +namespace cuttlefish { +namespace secure_env { + +void StorageDataDestroyer::operator()(StorageData* ptr) { + { + keymaster::Eraser(ptr, sizeof(StorageData) + ptr->size); + } + std::free(ptr); +} + +Result CreateStorageData(size_t size) { + const auto bytes_to_allocate = sizeof(StorageData) + size; + auto memory = std::malloc(bytes_to_allocate); + CF_EXPECT(memory != nullptr, + "Cannot allocate " << bytes_to_allocate << " bytes for storage data"); + auto data = reinterpret_cast(memory); + data->size = size; + return ManagedStorageData(data); +} + +Result CreateStorageData(const void* data, size_t size) { + auto managed_data = CF_EXPECT(CreateStorageData(size)); + std::memcpy(managed_data->payload, data, size); + return managed_data; +} + +} // namespace secure_env +} // namespace cuttlefish diff --git a/host/commands/secure_env/storage/storage.h b/host/commands/secure_env/storage/storage.h new file mode 100644 index 000000000..6815c3476 --- /dev/null +++ b/host/commands/secure_env/storage/storage.h @@ -0,0 +1,69 @@ +// +// 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 +#include + +#include "common/libs/utils/result.h" + +namespace cuttlefish { +namespace secure_env { + +struct StorageData { + uint32_t size; + uint8_t payload[0]; + + Result asUint8() { + CF_EXPECT(size == sizeof(uint8_t), "Size of payload is not matched with uint8 size"); + return *reinterpret_cast(payload); + } +}; + +/** + * A destroyer for StorageData instances created with + * CreateStorageData. Wipes memory from the StorageData instances. + */ +class StorageDataDestroyer { + public: + void operator()(StorageData* ptr); +}; + +/** An owning pointer for a StorageData instance. */ +using ManagedStorageData = std::unique_ptr; + +/** + * Allocates memory for a StorageData carrying a message of size + * `size`. + */ +Result CreateStorageData(size_t size); +Result CreateStorageData(const void* data, size_t size); + +/** + * Storage abstraction to store binary blobs associated with string key +*/ +class Storage { + public: + virtual Result HasKey(const std::string& key) const = 0; + virtual Result Read(const std::string& key) const = 0; + virtual Result Write(const std::string& key, const StorageData& data) = 0; + virtual bool Exists() const = 0; + + virtual ~Storage() = default; +}; + +} // namespace secure_env +} // namespace cuttlefish -- cgit v1.2.3 From 129eecf8e64117e4f77931207d0a39e1a7c60e48 Mon Sep 17 00:00:00 2001 From: Dmitrii Merkurev Date: Tue, 13 Jun 2023 14:56:59 +0100 Subject: Use introduced json binary storage to store oemlock state Alongside with that introduce LOCKED/UNLOCKED state and single RPC to check unlock is allowed to reduce amount of calls we need to execute on bootloader side Bug: 282160400 Bug: 307584049 Test: Test: atest VtsHalOemLockTargetTest Signed-off-by: Dmitrii Merkurev (cherry picked from https://android-review.googlesource.com/q/commit:dbcf615d82d79ff6a686c9a8f4abbb084a9c2960) Merged-In: Ia554a16eede741c7e6c4253d0aa4a5dc3674e405 Change-Id: Ia554a16eede741c7e6c4253d0aa4a5dc3674e405 --- common/libs/security/oemlock.h | 4 +- host/commands/assemble_cvd/assemble_cvd.cc | 1 + host/commands/secure_env/Android.bp | 3 +- host/commands/secure_env/oemlock.h | 38 -------- host/commands/secure_env/oemlock/oemlock.cpp | 102 +++++++++++++++++++++ host/commands/secure_env/oemlock/oemlock.h | 51 +++++++++++ .../secure_env/oemlock/oemlock_responder.cpp | 83 +++++++++++++++++ .../secure_env/oemlock/oemlock_responder.h | 38 ++++++++ host/commands/secure_env/oemlock_responder.cpp | 68 -------------- host/commands/secure_env/oemlock_responder.h | 38 -------- host/commands/secure_env/secure_env_linux_main.cpp | 40 ++++---- 11 files changed, 303 insertions(+), 163 deletions(-) delete mode 100644 host/commands/secure_env/oemlock.h create mode 100644 host/commands/secure_env/oemlock/oemlock.cpp create mode 100644 host/commands/secure_env/oemlock/oemlock.h create mode 100644 host/commands/secure_env/oemlock/oemlock_responder.cpp create mode 100644 host/commands/secure_env/oemlock/oemlock_responder.h delete mode 100644 host/commands/secure_env/oemlock_responder.cpp delete mode 100644 host/commands/secure_env/oemlock_responder.h diff --git a/common/libs/security/oemlock.h b/common/libs/security/oemlock.h index ab980a90e..d5fb62d06 100644 --- a/common/libs/security/oemlock.h +++ b/common/libs/security/oemlock.h @@ -23,7 +23,9 @@ namespace secure_env { enum class OemLockField : uint32_t { ALLOWED_BY_CARRIER = 0, - ALLOWED_BY_DEVICE = 1, + ALLOWED_BY_DEVICE, + ALLOWED, + LOCKED, }; } // namespace secure_env diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc index cfaac2991..266547ae2 100644 --- a/host/commands/assemble_cvd/assemble_cvd.cc +++ b/host/commands/assemble_cvd/assemble_cvd.cc @@ -256,6 +256,7 @@ Result InitFilesystemAndCreateConfig( preserving.insert("factory_reset_protected.img"); preserving.insert("misc.img"); preserving.insert("metadata.img"); + preserving.insert("oemlock_insecure"); std::stringstream ss; for (int i = 0; i < modem_simulator_count; i++) { ss.clear(); diff --git a/host/commands/secure_env/Android.bp b/host/commands/secure_env/Android.bp index 0bd3690b7..a18ab2679 100644 --- a/host/commands/secure_env/Android.bp +++ b/host/commands/secure_env/Android.bp @@ -77,7 +77,6 @@ common_libsecure_srcs = [ "insecure_fallback_storage.cpp", "json_serializable.cpp", "keymaster_responder.cpp", - "oemlock_responder.cpp", "primary_key_builder.cpp", "storage/storage.cpp", "tpm_attestation_record.cpp", @@ -105,6 +104,8 @@ cc_library_host_static { srcs: common_libsecure_srcs + [ "confui_sign_server.cpp", "device_tpm.cpp", + "oemlock/oemlock.cpp", + "oemlock/oemlock_responder.cpp", "storage/insecure_json_storage.cpp", ], defaults: ["cuttlefish_buildhost_only", "secure_env_defaults"], diff --git a/host/commands/secure_env/oemlock.h b/host/commands/secure_env/oemlock.h deleted file mode 100644 index 8ac29ffb2..000000000 --- a/host/commands/secure_env/oemlock.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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/oemlock.cpp b/host/commands/secure_env/oemlock/oemlock.cpp new file mode 100644 index 000000000..05709f6f7 --- /dev/null +++ b/host/commands/secure_env/oemlock/oemlock.cpp @@ -0,0 +1,102 @@ +/* + * 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 "host/commands/secure_env/oemlock/oemlock.h" + +namespace cuttlefish { +namespace oemlock { +namespace { + +constexpr char kStateKey[] = "oemlock_state"; +constexpr int kAllowedByCarrierBit = 0; +constexpr int kAllowedByDeviceBit = 1; +constexpr int kOemLockedBit = 2; + +// Default state is allowed_by_carrier = true +// allowed_by_device = false +// locked = true +constexpr uint8_t kDefaultState = 0 | (1 << kAllowedByCarrierBit) | (1 << kOemLockedBit); + +Result InitializeDefaultState(secure_env::Storage& storage) { + if (storage.Exists()) { return {}; }; + auto data = CF_EXPECT(secure_env::CreateStorageData(&kDefaultState, sizeof(kDefaultState))); + CF_EXPECT(storage.Write(kStateKey, *data)); + return {}; +} + +Result ReadFlag(secure_env::Storage& storage, int bit) { + auto data = CF_EXPECT(storage.Read(kStateKey)); + auto state = CF_EXPECT(data->asUint8()); + return (state >> bit) & 1; +} + +Result WriteFlag(secure_env::Storage& storage, int bit, bool value) { + auto data = CF_EXPECT(storage.Read(kStateKey)); + auto state = CF_EXPECT(data->asUint8()); + value ? state |= (1 << bit) : state &= ~(1 << bit); + auto data_to_write = CF_EXPECT(secure_env::CreateStorageData(&state, sizeof(state))); + CF_EXPECT(storage.Write(kStateKey, *data_to_write)); + return {}; +} + +} // namespace + +OemLock::OemLock(secure_env::Storage& storage) : storage_(storage) { + auto result = InitializeDefaultState(storage_); + if (!result.ok()) { + LOG(FATAL) << "Failed to initialize default state for OemLock TEE storage: " + << result.error().Message(); + } +} + +Result OemLock::IsOemUnlockAllowedByCarrier() const { + return CF_EXPECT(ReadFlag(storage_, kAllowedByCarrierBit)); +} + +Result OemLock::IsOemUnlockAllowedByDevice() const { + return CF_EXPECT(ReadFlag(storage_, kAllowedByDeviceBit)); +} + +Result OemLock::IsOemUnlockAllowed() const { + auto data = CF_EXPECT(storage_.Read(kStateKey)); + auto state = CF_EXPECT(data->asUint8()); + const bool allowed_by_device = (state >> kAllowedByDeviceBit) & 1; + const bool allowed_by_carrier = (state >> kAllowedByCarrierBit) & 1; + return allowed_by_device && allowed_by_carrier; +} + +Result OemLock::IsOemLocked() const { + return CF_EXPECT(ReadFlag(storage_, kOemLockedBit)); +} + +Result OemLock::SetOemUnlockAllowedByCarrier(bool allowed) { + CF_EXPECT(WriteFlag(storage_, kAllowedByCarrierBit, allowed)); + return {}; +} + +Result OemLock::SetOemUnlockAllowedByDevice(bool allowed) { + CF_EXPECT(WriteFlag(storage_, kAllowedByDeviceBit, allowed)); + return {}; +} + +Result OemLock::SetOemLocked(bool locked) { + CF_EXPECT(WriteFlag(storage_, kOemLockedBit, locked)); + return {}; +} + +} // namespace oemlock +} // namespace cuttlefish \ No newline at end of file diff --git a/host/commands/secure_env/oemlock/oemlock.h b/host/commands/secure_env/oemlock/oemlock.h new file mode 100644 index 000000000..306ec78e4 --- /dev/null +++ b/host/commands/secure_env/oemlock/oemlock.h @@ -0,0 +1,51 @@ +/* + * 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/utils/result.h" + +#include "host/commands/secure_env/storage/storage.h" + +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: + OemLock(secure_env::Storage& storage); + + Result IsOemUnlockAllowedByCarrier() const; + Result IsOemUnlockAllowedByDevice() const; + Result IsOemUnlockAllowed() const; + Result IsOemLocked() const; + Result SetOemUnlockAllowedByCarrier(bool allowed); + Result SetOemUnlockAllowedByDevice(bool allowed); + // TODO(b/286558252): add ConfirmationUI token to the signature + Result SetOemLocked(bool locked); + + private: + secure_env::Storage& storage_; +}; + +} // namespace oemlock +} // namespace cuttlefish diff --git a/host/commands/secure_env/oemlock/oemlock_responder.cpp b/host/commands/secure_env/oemlock/oemlock_responder.cpp new file mode 100644 index 000000000..be434ae3b --- /dev/null +++ b/host/commands/secure_env/oemlock/oemlock_responder.cpp @@ -0,0 +1,83 @@ +// +// 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/oemlock_responder.h" + +#include "common/libs/security/oemlock.h" + +namespace cuttlefish { +namespace oemlock { + +OemLockResponder::OemLockResponder(secure_env::Channel& channel, + OemLock& oemlock) + : channel_(channel), oemlock_(oemlock) {} + +Result OemLockResponder::ProcessMessage() { + auto request = CF_EXPECT(channel_.ReceiveMessage(), "Could not receive message"); + + bool result = false; + switch(secure_env::OemLockField(request->command)) { + case secure_env::OemLockField::ALLOWED_BY_CARRIER: { + if (request->payload_size == 0) { + result = CF_EXPECT(oemlock_.IsOemUnlockAllowedByCarrier()); + } else if (request->payload_size == sizeof(bool)) { + result = *reinterpret_cast(request->payload); + CF_EXPECT(oemlock_.SetOemUnlockAllowedByCarrier(result)); + } + break; + } + + case secure_env::OemLockField::ALLOWED_BY_DEVICE: { + if (request->payload_size == 0) { + result = CF_EXPECT(oemlock_.IsOemUnlockAllowedByDevice()); + } else if (request->payload_size == sizeof(bool)) { + result = *reinterpret_cast(request->payload); + CF_EXPECT(oemlock_.SetOemUnlockAllowedByDevice(result)); + } + break; + } + + case secure_env::OemLockField::ALLOWED: { + if (request->payload_size == 0) { + result = CF_EXPECT(oemlock_.IsOemUnlockAllowed()); + } + break; + } + + case secure_env::OemLockField::LOCKED: { + if (request->payload_size == 0) { + result = CF_EXPECT(oemlock_.IsOemLocked()); + } else if (request->payload_size == sizeof(bool)) { + result = *reinterpret_cast(request->payload); + CF_EXPECT(oemlock_.SetOemLocked(result)); + } + break; + } + + default: + return CF_ERR("Unrecognized message id " << reinterpret_cast(request->command)); + } + + auto message = CF_EXPECT(secure_env::CreateMessage(request->command, sizeof(bool)), + "Failed to allocate message for oemlock response"); + memcpy(message->payload, &result, sizeof(bool)); + CF_EXPECT(channel_.SendResponse(*message), + "Could not answer to " << reinterpret_cast(request->command) << " request"); + + return {}; +} + +} // namespace oemlock +} // namespace cuttlefish diff --git a/host/commands/secure_env/oemlock/oemlock_responder.h b/host/commands/secure_env/oemlock/oemlock_responder.h new file mode 100644 index 000000000..0b5fadbf2 --- /dev/null +++ b/host/commands/secure_env/oemlock/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/oemlock.h" + +namespace cuttlefish { +namespace oemlock { + +class OemLockResponder { + public: + OemLockResponder(secure_env::Channel& channel, + OemLock& oemlock); + + Result ProcessMessage(); + + private: + secure_env::Channel& channel_; + OemLock& oemlock_; +}; + +} // namespace oemlock +} // namespace cuttlefish diff --git a/host/commands/secure_env/oemlock_responder.cpp b/host/commands/secure_env/oemlock_responder.cpp deleted file mode 100644 index 698be32ff..000000000 --- a/host/commands/secure_env/oemlock_responder.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// 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 - -#include "common/libs/security/oemlock.h" - -namespace cuttlefish { -namespace oemlock { - -OemLockResponder::OemLockResponder(secure_env::Channel& channel, - OemLock& oemlock) - : channel_(channel), oemlock_(oemlock) {} - -Result 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(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(request->payload); - oemlock_.SetOemUnlockAllowedByDevice(allowed); - } - break; - } - - default: - return CF_ERR("Unrecognized message id " << reinterpret_cast(request->command)); - } - - auto message = CF_EXPECT(secure_env::CreateMessage(request->command, sizeof(bool)), - "Failed to allocate message for oemlock response"); - memcpy(message->payload, &allowed, sizeof(bool)); - CF_EXPECT(channel_.SendResponse(*message), - "Could not answer to " << reinterpret_cast(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 deleted file mode 100644 index 3b02472a4..000000000 --- a/host/commands/secure_env/oemlock_responder.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// 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 ProcessMessage(); - - private: - secure_env::Channel& channel_; - OemLock& oemlock_; -}; - -} // namespace oemlock -} // namespace cuttlefish diff --git a/host/commands/secure_env/secure_env_linux_main.cpp b/host/commands/secure_env/secure_env_linux_main.cpp index 56428c901..1164ef2d8 100644 --- a/host/commands/secure_env/secure_env_linux_main.cpp +++ b/host/commands/secure_env/secure_env_linux_main.cpp @@ -39,12 +39,13 @@ #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/oemlock/oemlock_responder.h" +#include "host/commands/secure_env/oemlock/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/storage/insecure_json_storage.h" +#include "host/commands/secure_env/storage/storage.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" @@ -150,22 +151,27 @@ ChooseGatekeeperComponent() { } } -fruit::Component ChooseOemlockComponent() { - if (FLAGS_oemlock_impl == "software") { - return fruit::createComponent() - .bind(); - } 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 ChooseOemlockComponent() { + return fruit::createComponent() + .registerProvider([]() -> secure_env::Storage* { + if (FLAGS_oemlock_impl == "software") { + return new secure_env::InsecureJsonStorage("oemlock_insecure"); + } 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(); + } + }) + .registerProvider([](secure_env::Storage& storage) -> oemlock::OemLock* { + return new oemlock::OemLock(storage); + });; } fruit::Component + secure_env::Storage, oemlock::OemLock, keymaster::KeymasterEnforcement> SecureEnvComponent() { return fruit::createComponent() .registerProvider([]() -> Tpm* { // fruit will take ownership @@ -224,7 +230,7 @@ int SecureEnvMain(int argc, char** argv) { keymaster::SoftKeymasterLogger km_logger; fruit::Injector + secure_env::Storage, oemlock::OemLock, keymaster::KeymasterEnforcement> injector(SecureEnvComponent); TpmResourceManager* resource_manager = injector.get(); gatekeeper::GateKeeper* gatekeeper = injector.get(); -- cgit v1.2.3 From f68166f56f022d2813af1ee082ba9f59ac7abb56 Mon Sep 17 00:00:00 2001 From: alukin Date: Thu, 2 Nov 2023 14:28:20 +0000 Subject: Add new modules to TEST_MAPPING Adding new modules to TEST_MAPPING after splitting CtsScopedStorageDeviceOnlyTest Bug: 294741813 Test: atest Change-Id: I30fd7c0e4f95cc2832272194da89da2ec866540c --- TEST_MAPPING | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TEST_MAPPING b/TEST_MAPPING index f711b636d..fadf79d77 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -28,6 +28,15 @@ }, { "name": "CtsScopedStorageDeviceOnlyTest" + }, + { + "name": "CtsScopedStorageBypassDatabaseOperationsTest" + }, + { + "name": "CtsScopedStorageGeneralTest" + }, + { + "name": "CtsScopedStorageRedactUriTest" } ], "auto-presubmit": [ -- cgit v1.2.3 From d24eb75beb4c1ab42c03cb1e7ab3b0cf66322095 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Sat, 11 Nov 2023 06:56:53 -0800 Subject: Adding multiconfig support in android-info To enable android-info.txt to have multiple guest config options, remove the requirement that config be at the front of android_info. Bug: 310326103 Test: local boot of tablet and other targets Change-Id: Ic9714f3038a5737277cea41589ad350efff9b0b4 Merged-In: Ic9714f3038a5737277cea41589ad350efff9b0b4 --- host/libs/config/config_flag.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/host/libs/config/config_flag.cpp b/host/libs/config/config_flag.cpp index d4d515766..63afd2315 100644 --- a/host/libs/config/config_flag.cpp +++ b/host/libs/config/config_flag.cpp @@ -16,6 +16,7 @@ #include "host/libs/config/config_flag.h" +#include #include #include #include @@ -34,6 +35,8 @@ DEFINE_string(system_image_dir, CF_DEFAULTS_SYSTEM_IMAGE_DIR, ""); using gflags::FlagSettingMode::SET_FLAGS_DEFAULT; +using android::base::ReadFileToString; +using android::base::Split; namespace cuttlefish { @@ -192,22 +195,36 @@ class ConfigFlagImpl : public ConfigFlag { if (!FileExists(info_path)) { return {}; } - std::ifstream ifs{info_path}; - if (!ifs.is_open()) { + std::string android_info; + if(!ReadFileToString(info_path, &android_info)) { return {}; } - std::string android_info; - ifs >> android_info; - std::string_view local_android_info(android_info); - if (!android::base::ConsumePrefix(&local_android_info, "config=")) { + // grab the last value of config in android-info.txt, + // it's the setting that's respected. + // TODO (rammuthiah) Replace this logic with ParseMiscInfo + // from host/commands/assemble_cvd/misc_info.h + // Currently blocked on linking error for misc_info which is part of + // assemble_cvd and this bit of code which is in run_cvd. + size_t config_idx = android_info.rfind("config="); + if (config_idx == std::string::npos) { + return {}; + } + std::string config_value = android_info.substr(config_idx); + std::string_view local_config_value(config_value); + if (!android::base::ConsumePrefix(&local_config_value, "config=")) { + return {}; + } + auto split_config = Split(std::string{local_config_value},"\n"); + if (split_config.empty()) { return {}; } - if (!config_reader_.HasConfig(std::string{local_android_info})) { + config_value = split_config[0]; + if (!config_reader_.HasConfig(config_value)) { LOG(WARNING) << info_path << " contains invalid config preset: '" - << local_android_info << "'."; + << config_value << "'."; return {}; } - return std::string{local_android_info}; + return config_value; } ConfigReader& config_reader_; -- cgit v1.2.3 From f84bc3dba0ee211fac047b8d149e4f63d37c51e2 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Mon, 13 Nov 2023 16:12:51 -0800 Subject: Add gfxstream to android-info indicate to main launcher it's supported Bug: 310326103 Change-Id: I9d5ec1f663b151c2ccf8da2ae700943f929102a1 Merged-In: I9d5ec1f663b151c2ccf8da2ae700943f929102a1 --- shared/auto/android-info.txt | 1 + shared/auto_md/android-info.txt | 1 + shared/auto_portrait/android-info.txt | 1 + shared/foldable/android-info.txt | 1 + shared/go/android-info.txt | 1 + shared/minidroid/android-info.txt | 1 + shared/phone/android-info.txt | 1 + shared/slim/android-info.txt | 1 + shared/tv/android-info.txt | 1 + shared/wear/android-info.txt | 1 + 10 files changed, 10 insertions(+) diff --git a/shared/auto/android-info.txt b/shared/auto/android-info.txt index cc15c01a7..74c0e2ebc 100644 --- a/shared/auto/android-info.txt +++ b/shared/auto/android-info.txt @@ -1 +1,2 @@ config=auto +gfxstream=supported diff --git a/shared/auto_md/android-info.txt b/shared/auto_md/android-info.txt index ac7c0e796..1a130ffe4 100644 --- a/shared/auto_md/android-info.txt +++ b/shared/auto_md/android-info.txt @@ -1 +1,2 @@ config=auto_md +gfxstream=supported diff --git a/shared/auto_portrait/android-info.txt b/shared/auto_portrait/android-info.txt index 60b759e8c..ea15130d8 100644 --- a/shared/auto_portrait/android-info.txt +++ b/shared/auto_portrait/android-info.txt @@ -1 +1,2 @@ config=auto_portrait +gfxstream=supported diff --git a/shared/foldable/android-info.txt b/shared/foldable/android-info.txt index 855268558..53cfa1129 100644 --- a/shared/foldable/android-info.txt +++ b/shared/foldable/android-info.txt @@ -1 +1,2 @@ config=foldable +gfxstream=supported diff --git a/shared/go/android-info.txt b/shared/go/android-info.txt index 68f482634..ae9578c4e 100644 --- a/shared/go/android-info.txt +++ b/shared/go/android-info.txt @@ -1 +1,2 @@ config=go +gfxstream=supported diff --git a/shared/minidroid/android-info.txt b/shared/minidroid/android-info.txt index fc7981352..50453d60c 100644 --- a/shared/minidroid/android-info.txt +++ b/shared/minidroid/android-info.txt @@ -1 +1,2 @@ config=minidroid +gfxstream=supported diff --git a/shared/phone/android-info.txt b/shared/phone/android-info.txt index 2286c3d30..169f04d21 100644 --- a/shared/phone/android-info.txt +++ b/shared/phone/android-info.txt @@ -1 +1,2 @@ config=phone +gfxstream=supported diff --git a/shared/slim/android-info.txt b/shared/slim/android-info.txt index b0bf39b52..e7e5bf0ce 100644 --- a/shared/slim/android-info.txt +++ b/shared/slim/android-info.txt @@ -1 +1,2 @@ config=slim +gfxstream=supported diff --git a/shared/tv/android-info.txt b/shared/tv/android-info.txt index 8eae9029d..c4386094f 100644 --- a/shared/tv/android-info.txt +++ b/shared/tv/android-info.txt @@ -1 +1,2 @@ config=tv +gfxstream=supported diff --git a/shared/wear/android-info.txt b/shared/wear/android-info.txt index 22a5b5e7d..02e029bdc 100644 --- a/shared/wear/android-info.txt +++ b/shared/wear/android-info.txt @@ -1 +1,2 @@ config=wear +gfxstream=supported -- cgit v1.2.3