From eb223ba883056588cd2acedaf2d1d835197f1dfe Mon Sep 17 00:00:00 2001 From: Shikha Panwar Date: Thu, 19 Oct 2023 14:54:06 +0000 Subject: [PATCH] Secretkeeper implementation: in-HAL/nonsecure impl Create the default/reference implementation of Secretkeeper HAL. Status quo, this is non-secure implementation. In reality, the HAL should be backed by a privileged component such a trusted app. Bug: 291224769 Test: Topic includes VTS Change-Id: I6a4ad50482d537f5438de6201275f4020cd827df --- .../compatibility_matrix.9.xml | 8 ++ security/secretkeeper/default/Android.bp | 37 ++++++ security/secretkeeper/default/secretkeeper.rc | 5 + .../secretkeeper/default/secretkeeper.xml | 28 ++++ security/secretkeeper/default/src/main.rs | 121 ++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 security/secretkeeper/default/Android.bp create mode 100644 security/secretkeeper/default/secretkeeper.rc create mode 100644 security/secretkeeper/default/secretkeeper.xml create mode 100644 security/secretkeeper/default/src/main.rs diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml index 83d2665cf5..9f6b78b79c 100644 --- a/compatibility_matrices/compatibility_matrix.9.xml +++ b/compatibility_matrices/compatibility_matrix.9.xml @@ -302,6 +302,14 @@ default + + android.hardware.security.secretkeeper + 1 + + ISecretkeeper + nonsecure + + android.hardware.security.keymint 1-3 diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp new file mode 100644 index 0000000000..1c39fa6159 --- /dev/null +++ b/security/secretkeeper/default/Android.bp @@ -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. + */ + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +rust_binary { + name: "android.hardware.security.secretkeeper-service.nonsecure", + relative_install_path: "hw", + vendor: true, + init_rc: ["secretkeeper.rc"], + vintf_fragments: ["secretkeeper.xml"], + rustlibs: [ + "android.hardware.security.secretkeeper-V1-rust", + "libandroid_logger", + "libbinder_rs", + "liblog_rust", + "libsecretkeeper_comm_nostd", + ], + srcs: [ + "src/main.rs", + ], +} diff --git a/security/secretkeeper/default/secretkeeper.rc b/security/secretkeeper/default/secretkeeper.rc new file mode 100644 index 0000000000..f39f9b75c2 --- /dev/null +++ b/security/secretkeeper/default/secretkeeper.rc @@ -0,0 +1,5 @@ +service vendor.secretkeeper /vendor/bin/hw/android.hardware.security.secretkeeper-service.nonsecure + interface aidl android.hardware.security.secretkeeper.ISecretkeeper/nonsecure + class hal + user nobody + group nobody diff --git a/security/secretkeeper/default/secretkeeper.xml b/security/secretkeeper/default/secretkeeper.xml new file mode 100644 index 0000000000..40aebe0a13 --- /dev/null +++ b/security/secretkeeper/default/secretkeeper.xml @@ -0,0 +1,28 @@ + + + + + android.hardware.security.secretkeeper + 1 + + ISecretkeeper + nonsecure + + + diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs new file mode 100644 index 0000000000..2d367c5184 --- /dev/null +++ b/security/secretkeeper/default/src/main.rs @@ -0,0 +1,121 @@ +/* + * 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. + */ + +use binder::{BinderFeatures, Interface}; +use log::{error, info, Level}; +use secretkeeper_comm::data_types::error::SecretkeeperError; +use secretkeeper_comm::data_types::packet::{RequestPacket, ResponsePacket}; +use secretkeeper_comm::data_types::request::Request; +use secretkeeper_comm::data_types::request_response_impl::{ + GetVersionRequest, GetVersionResponse, Opcode, +}; +use secretkeeper_comm::data_types::response::Response; + +use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{ + BnSecretkeeper, BpSecretkeeper, ISecretkeeper, +}; + +const CURRENT_VERSION: u64 = 1; + +#[derive(Debug, Default)] +pub struct NonSecureSecretkeeper; + +impl Interface for NonSecureSecretkeeper {} + +impl ISecretkeeper for NonSecureSecretkeeper { + fn processSecretManagementRequest(&self, request: &[u8]) -> binder::Result> { + Ok(self.process_opaque_request(request)) + } +} + +impl NonSecureSecretkeeper { + // A set of requests to Secretkeeper are 'opaque' - encrypted bytes with inner structure + // described by CDDL. They need to be decrypted, deserialized and processed accordingly. + fn process_opaque_request(&self, request: &[u8]) -> Vec { + // TODO(b/291224769) The request will need to be decrypted & response need to be encrypted + // with key & related artifacts pre-shared via Authgraph Key Exchange HAL. + self.process_opaque_request_unhandled_error(request) + .unwrap_or_else( + // SecretkeeperError is also a valid 'Response', serialize to a response packet. + |sk_err| { + Response::serialize_to_packet(&sk_err) + .into_bytes() + .expect("Panicking due to serialization failing") + }, + ) + } + + fn process_opaque_request_unhandled_error( + &self, + request: &[u8], + ) -> Result, SecretkeeperError> { + let request_packet = RequestPacket::from_bytes(request).map_err(|e| { + error!("Failed to get Request packet from bytes: {:?}", e); + SecretkeeperError::RequestMalformed + })?; + let response_packet = match request_packet + .opcode() + .map_err(|_| SecretkeeperError::RequestMalformed)? + { + Opcode::GetVersion => Self::process_get_version_request(request_packet)?, + _ => todo!("TODO(b/291224769): Unimplemented operations"), + }; + + response_packet + .into_bytes() + .map_err(|_| SecretkeeperError::UnexpectedServerError) + } + + fn process_get_version_request( + request: RequestPacket, + ) -> Result { + // Deserialization really just verifies the structural integrity of the request such + // as args being empty. + let _request = GetVersionRequest::deserialize_from_packet(request) + .map_err(|_| SecretkeeperError::RequestMalformed)?; + let response = GetVersionResponse::new(CURRENT_VERSION); + Ok(response.serialize_to_packet()) + } +} + +fn main() { + // Initialize Android logging. + android_logger::init_once( + android_logger::Config::default() + .with_tag("NonSecureSecretkeeper") + .with_min_level(Level::Info) + .with_log_id(android_logger::LogId::System), + ); + // Redirect panic messages to logcat. + std::panic::set_hook(Box::new(|panic_info| { + error!("{}", panic_info); + })); + + let service = NonSecureSecretkeeper::default(); + let service_binder = BnSecretkeeper::new_binder(service, BinderFeatures::default()); + let service_name = format!( + "{}/nonsecure", + ::get_descriptor() + ); + binder::add_service(&service_name, service_binder.as_binder()).unwrap_or_else(|e| { + panic!( + "Failed to register service {} because of {:?}.", + service_name, e + ); + }); + info!("Registered Binder service, joining threadpool."); + binder::ProcessState::join_thread_pool(); +}