diff --git a/trusty/secretkeeper/Android.bp b/trusty/secretkeeper/Android.bp new file mode 100644 index 000000000..84db8c222 --- /dev/null +++ b/trusty/secretkeeper/Android.bp @@ -0,0 +1,42 @@ +// +// Copyright (C) 2022 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"], +} + +rust_binary { + name: "android.hardware.security.secretkeeper.trusty", + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.security.secretkeeper.trusty.rc"], + vintf_fragments: ["android.hardware.security.secretkeeper.trusty.xml"], + srcs: [ + "src/hal_main.rs", + ], + rustlibs: [ + "libandroid_logger", + "libbinder_rs", + "libauthgraph_hal", + "libtrusty-rs", + "liblibc", + "liblog_rust", + "libsecretkeeper_hal", + ], + defaults: [ + "secretkeeper_use_latest_hal_aidl_rust", + ], + prefer_rlib: true, +} diff --git a/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc new file mode 100644 index 000000000..3be03ad80 --- /dev/null +++ b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc @@ -0,0 +1,4 @@ +service vendor.secretkeeper.trusty /vendor/bin/hw/android.hardware.security.secretkeeper.trusty + class hal + user nobody + group drmrpc \ No newline at end of file diff --git a/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml new file mode 100644 index 000000000..2ac152bf2 --- /dev/null +++ b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml @@ -0,0 +1,7 @@ + + + android.hardware.security.secretkeeper + 1 + ISecretkeeper/default + + diff --git a/trusty/secretkeeper/src/hal_main.rs b/trusty/secretkeeper/src/hal_main.rs new file mode 100644 index 000000000..9439c369b --- /dev/null +++ b/trusty/secretkeeper/src/hal_main.rs @@ -0,0 +1,141 @@ +// +// Copyright (C) 2022 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. + +//! This module implements the HAL service for Secretkeeper in Trusty. +use authgraph_hal::{channel::SerializedChannel}; +use secretkeeper_hal::SecretkeeperService; +use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{ + ISecretkeeper, BpSecretkeeper, +}; +use log::{error, info}; +use std::{ + ffi::CString, + panic, + sync::{Arc, Mutex}, +}; +use trusty::DEFAULT_DEVICE; + +const SK_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper"; +const AG_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper.authgraph"; + +static SERVICE_INSTANCE: &str = "default"; + +/// Local error type for failures in the HAL service. +#[derive(Debug, Clone)] +struct HalServiceError(String); + +#[derive(Debug)] +struct TipcChannel { + channel: Arc>, +} + +impl TipcChannel { + fn new(channel: trusty::TipcChannel) -> Self { + Self { channel: Arc::new(Mutex::new(channel)) } + } +} + +impl SerializedChannel for TipcChannel { + const MAX_SIZE: usize = 4000; + fn execute(&self, req_data: &[u8]) -> binder::Result> { + // Hold lock across both request and response. + let mut channel = self.channel.lock().unwrap(); + channel.send(req_data).map_err(|e| { + binder::Status::new_exception( + binder::ExceptionCode::TRANSACTION_FAILED, + Some( + &CString::new(format!( + "Failed to send the request via tipc channel because of {:?}", + e + )) + .unwrap(), + ), + ) + })?; + // TODO: cope with fragmentation and reassembly + let mut rsp_data = Vec::new(); + channel.recv(&mut rsp_data).map_err(|e| { + binder::Status::new_exception( + binder::ExceptionCode::TRANSACTION_FAILED, + Some( + &CString::new(format!( + "Failed to receive the response via tipc channel because of {:?}", + e + )) + .unwrap(), + ), + ) + })?; + Ok(rsp_data) + } +} + +fn main() { + if let Err(e) = inner_main() { + panic!("HAL service failed: {:?}", e); + } +} + +fn inner_main() -> Result<(), HalServiceError> { + // Initialize Android logging. + android_logger::init_once( + android_logger::Config::default() + .with_tag("secretkeeper-hal-trusty") + .with_min_level(log::Level::Info) + .with_log_id(android_logger::LogId::System), + ); + // Redirect panic messages to logcat. + panic::set_hook(Box::new(|panic_info| { + error!("{}", panic_info); + })); + + info!("Trusty Secretkeeper HAL service is starting."); + + info!("Starting thread pool now."); + binder::ProcessState::start_thread_pool(); + + // Create connections to the TA. + let ag_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, AG_TIPC_SERVICE_PORT) + .map_err(|e| { + HalServiceError(format!( + "Failed to connect to Trusty port {AG_TIPC_SERVICE_PORT} because of {:?}.", + e + )) + })?; + let ag_tipc_channel = TipcChannel::new(ag_connection); + + let sk_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, SK_TIPC_SERVICE_PORT) + .map_err(|e| { + HalServiceError(format!( + "Failed to connect to Trusty port {SK_TIPC_SERVICE_PORT} because of {:?}.", + e + )) + })?; + let sk_tipc_channel = TipcChannel::new(sk_connection); + + // Register the AIDL service + let service = SecretkeeperService::new_as_binder(sk_tipc_channel, ag_tipc_channel); + let service_name = + format!("{}/{}", ::get_descriptor(), SERVICE_INSTANCE); + binder::add_service(&service_name, service.as_binder()).map_err(|e| { + HalServiceError(format!("Failed to register service {} because of {:?}.", service_name, e)) + })?; + + info!("Successfully registered Secretkeeper HAL service."); + info!("Joining thread pool now."); + binder::ProcessState::join_thread_pool(); + info!("Secretkeeper HAL service is terminating."); // should not reach here + Ok(()) +} diff --git a/trusty/trusty-base.mk b/trusty/trusty-base.mk index 1986c73e9..d645c3e40 100644 --- a/trusty/trusty-base.mk +++ b/trusty/trusty-base.mk @@ -35,8 +35,16 @@ else LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.trusty endif +# TODO(b/306364873): move this to be flag-controlled? +ifeq ($(SECRETKEEPER_ENABLED),) + LOCAL_SECRETKEEPER_PRODUCT_PACKAGE := +else + LOCAL_SECRETKEEPER_PRODUCT_PACKAGE := android.hardware.security.secretkeeper.trusty +endif + PRODUCT_PACKAGES += \ $(LOCAL_KEYMINT_PRODUCT_PACKAGE) \ + $(LOCAL_SECRETKEEPER_PRODUCT_PACKAGE) \ android.hardware.gatekeeper-service.trusty \ trusty_apploader \