xref: /aosp_15_r20/system/core/trusty/secretkeeper/src/hal_main.rs (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1 //
2 // Copyright (C) 2022 The Android Open-Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 //! This module implements the HAL service for Secretkeeper in Trusty.
17 use authgraph_hal::channel::SerializedChannel;
18 use authgraph_wire::fragmentation::{Fragmenter, Reassembler};
19 use secretkeeper_hal::SecretkeeperService;
20 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
21     ISecretkeeper, BpSecretkeeper,
22 };
23 use log::{error, info};
24 use std::{
25     ffi::CString,
26     fmt::Debug,
27     panic,
28     sync::{Arc, Mutex},
29 };
30 use trusty::DEFAULT_DEVICE;
31 
32 const SK_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper";
33 const AG_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper.authgraph";
34 const TIPC_MAX_SIZE: usize = 4000;
35 
36 static SERVICE_INSTANCE: &str = "default";
37 
38 /// Local error type for failures in the HAL service.
39 #[derive(Debug, Clone)]
40 struct HalServiceError(String);
41 
42 #[derive(Debug)]
43 struct TipcChannel {
44     channel: Arc<Mutex<trusty::TipcChannel>>,
45 }
46 
47 impl TipcChannel {
new(channel: trusty::TipcChannel) -> Self48     fn new(channel: trusty::TipcChannel) -> Self {
49         Self { channel: Arc::new(Mutex::new(channel)) }
50     }
51 }
52 
binderr<E: Debug>(msg: &str, e: E) -> binder::Status53 fn binderr<E: Debug>(msg: &str, e: E) -> binder::Status {
54     binder::Status::new_exception(
55         binder::ExceptionCode::TRANSACTION_FAILED,
56         Some(&CString::new(format!("Failed to {msg} via tipc channel: {e:?}",)).unwrap()),
57     )
58 }
59 
60 impl SerializedChannel for TipcChannel {
61     // No maximum size for messages passed to `execute()` because it performs fragmentation
62     // and reassembly internally.
63     const MAX_SIZE: usize = usize::MAX;
64 
execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>>65     fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
66         // Hold lock across both request and response.
67         let mut channel = self.channel.lock().unwrap();
68         let mut pending_rsp = Reassembler::default();
69 
70         // Break request message into fragments to send.
71         for req_frag in Fragmenter::new(req_data, TIPC_MAX_SIZE) {
72             channel.send(&req_frag).map_err(|e| binderr("send request", e))?;
73 
74             // Every request gets a response.
75             let mut rsp_frag = Vec::new();
76             channel.recv(&mut rsp_frag).map_err(|e| binderr("receive response", e))?;
77 
78             if let Some(full_rsp) = pending_rsp.accumulate(&rsp_frag) {
79                 return Ok(full_rsp.to_vec());
80             }
81         }
82         // There may be additional response fragments to receive.
83         loop {
84             let mut rsp_frag = Vec::new();
85             channel.recv(&mut rsp_frag).map_err(|e| binderr("receive response", e))?;
86             if let Some(full_rsp) = pending_rsp.accumulate(&rsp_frag) {
87                 return Ok(full_rsp.to_vec());
88             }
89         }
90     }
91 }
92 
main()93 fn main() {
94     if let Err(HalServiceError(e)) = inner_main() {
95         panic!("HAL service failed: {:?}", e);
96     }
97 }
98 
inner_main() -> Result<(), HalServiceError>99 fn inner_main() -> Result<(), HalServiceError> {
100     // Initialize Android logging.
101     android_logger::init_once(
102         android_logger::Config::default()
103             .with_tag("secretkeeper-hal-trusty")
104             .with_max_level(log::LevelFilter::Info)
105             .with_log_buffer(android_logger::LogId::System),
106     );
107     // Redirect panic messages to logcat.
108     panic::set_hook(Box::new(|panic_info| {
109         error!("{}", panic_info);
110     }));
111 
112     info!("Trusty Secretkeeper HAL service is starting.");
113 
114     info!("Starting thread pool now.");
115     binder::ProcessState::start_thread_pool();
116 
117     // Create connections to the TA.
118     let ag_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, AG_TIPC_SERVICE_PORT)
119         .map_err(|e| {
120             HalServiceError(format!(
121                 "Failed to connect to Trusty port {AG_TIPC_SERVICE_PORT} because of {:?}.",
122                 e
123             ))
124         })?;
125     let ag_tipc_channel = TipcChannel::new(ag_connection);
126 
127     let sk_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, SK_TIPC_SERVICE_PORT)
128         .map_err(|e| {
129             HalServiceError(format!(
130                 "Failed to connect to Trusty port {SK_TIPC_SERVICE_PORT} because of {:?}.",
131                 e
132             ))
133         })?;
134     let sk_tipc_channel = TipcChannel::new(sk_connection);
135 
136     // Register the AIDL service
137     let service = SecretkeeperService::new_as_binder(sk_tipc_channel, ag_tipc_channel);
138     let service_name =
139         format!("{}/{}", <BpSecretkeeper as ISecretkeeper>::get_descriptor(), SERVICE_INSTANCE);
140     binder::add_service(&service_name, service.as_binder()).map_err(|e| {
141         HalServiceError(format!("Failed to register service {} because of {:?}.", service_name, e))
142     })?;
143 
144     info!("Successfully registered Secretkeeper HAL service.");
145     info!("Joining thread pool now.");
146     binder::ProcessState::join_thread_pool();
147     info!("Secretkeeper HAL service is terminating."); // should not reach here
148     Ok(())
149 }
150