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 Keymint (Rust) in Trusty.
17 use kmr_hal::{
18 extract_rsp, keymint, rpc, secureclock, send_hal_info, sharedsecret, SerializedChannel,
19 };
20 use log::{error, info};
21 use std::{
22 ffi::CString,
23 ops::DerefMut,
24 panic,
25 sync::{Arc, Mutex},
26 };
27 use trusty::DEFAULT_DEVICE;
28
29 const TRUSTY_KEYMINT_RUST_SERVICE_NAME: &str = "com.android.trusty.keymint";
30
31 static SERVICE_INSTANCE: &str = "default";
32
33 static KM_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
34 static RPC_SERVICE_NAME: &str = "android.hardware.security.keymint.IRemotelyProvisionedComponent";
35 static SECURE_CLOCK_SERVICE_NAME: &str = "android.hardware.security.secureclock.ISecureClock";
36 static SHARED_SECRET_SERVICE_NAME: &str = "android.hardware.security.sharedsecret.ISharedSecret";
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(trusty::TipcChannel);
44
45 impl SerializedChannel for TipcChannel {
46 const MAX_SIZE: usize = 4000;
execute(&mut self, serialized_req: &[u8]) -> binder::Result<Vec<u8>>47 fn execute(&mut self, serialized_req: &[u8]) -> binder::Result<Vec<u8>> {
48 self.0.send(serialized_req).map_err(|e| {
49 binder::Status::new_exception(
50 binder::ExceptionCode::TRANSACTION_FAILED,
51 Some(
52 &CString::new(format!(
53 "Failed to send the request via tipc channel because of {:?}",
54 e
55 ))
56 .unwrap(),
57 ),
58 )
59 })?;
60 let mut expect_more_msgs = true;
61 let mut full_rsp = Vec::new();
62 while expect_more_msgs {
63 let mut recv_buf = Vec::new();
64 self.0.recv(&mut recv_buf).map_err(|e| {
65 binder::Status::new_exception(
66 binder::ExceptionCode::TRANSACTION_FAILED,
67 Some(
68 &CString::new(format!(
69 "Failed to receive the response via tipc channel because of {:?}",
70 e
71 ))
72 .unwrap(),
73 ),
74 )
75 })?;
76 let current_rsp_content;
77 (expect_more_msgs, current_rsp_content) = extract_rsp(&recv_buf)?;
78 full_rsp.extend_from_slice(current_rsp_content);
79 }
80 Ok(full_rsp)
81 }
82 }
83
main()84 fn main() {
85 if let Err(e) = inner_main() {
86 panic!("HAL service failed: {:?}", e);
87 }
88 }
89
inner_main() -> Result<(), HalServiceError>90 fn inner_main() -> Result<(), HalServiceError> {
91 // Initialize Android logging.
92 android_logger::init_once(
93 android_logger::Config::default()
94 .with_tag("keymint-hal-trusty")
95 .with_min_level(log::Level::Info)
96 .with_log_id(android_logger::LogId::System),
97 );
98 // Redirect panic messages to logcat.
99 panic::set_hook(Box::new(|panic_info| {
100 error!("{}", panic_info);
101 }));
102
103 info!("Trusty KM HAL service is starting.");
104
105 info!("Starting thread pool now.");
106 binder::ProcessState::start_thread_pool();
107
108 // Create connection to the TA
109 let connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, TRUSTY_KEYMINT_RUST_SERVICE_NAME)
110 .map_err(|e| {
111 HalServiceError(format!("Failed to connect to Trusty Keymint TA because of {:?}.", e))
112 })?;
113 let tipc_channel = Arc::new(Mutex::new(TipcChannel(connection)));
114
115 // Register the Keymint service
116 let km_service = keymint::Device::new_as_binder(tipc_channel.clone());
117 let km_service_name = format!("{}/{}", KM_SERVICE_NAME, SERVICE_INSTANCE);
118 binder::add_service(&km_service_name, km_service.as_binder()).map_err(|e| {
119 HalServiceError(format!(
120 "Failed to register service {} because of {:?}.",
121 km_service_name, e
122 ))
123 })?;
124
125 // Register the Remotely Provisioned Component service
126 let rpc_service = rpc::Device::new_as_binder(tipc_channel.clone());
127 let rpc_service_name = format!("{}/{}", RPC_SERVICE_NAME, SERVICE_INSTANCE);
128 binder::add_service(&rpc_service_name, rpc_service.as_binder()).map_err(|e| {
129 HalServiceError(format!(
130 "Failed to register service {} because of {:?}.",
131 rpc_service_name, e
132 ))
133 })?;
134
135 // Register the Secure Clock service
136 let sclock_service = secureclock::Device::new_as_binder(tipc_channel.clone());
137 let sclock_service_name = format!("{}/{}", SECURE_CLOCK_SERVICE_NAME, SERVICE_INSTANCE);
138 binder::add_service(&sclock_service_name, sclock_service.as_binder()).map_err(|e| {
139 HalServiceError(format!(
140 "Failed to register service {} because of {:?}.",
141 sclock_service_name, e
142 ))
143 })?;
144
145 // Register the Shared Secret service
146 let ssecret_service = sharedsecret::Device::new_as_binder(tipc_channel.clone());
147 let ssecret_service_name = format!("{}/{}", SHARED_SECRET_SERVICE_NAME, SERVICE_INSTANCE);
148 binder::add_service(&ssecret_service_name, ssecret_service.as_binder()).map_err(|e| {
149 HalServiceError(format!(
150 "Failed to register service {} because of {:?}.",
151 ssecret_service_name, e
152 ))
153 })?;
154
155 // Send the HAL service information to the TA
156 send_hal_info(tipc_channel.lock().unwrap().deref_mut())
157 .map_err(|e| HalServiceError(format!("Failed to populate HAL info: {:?}", e)))?;
158
159 info!("Successfully registered KeyMint HAL services.");
160 info!("Joining thread pool now.");
161 binder::ProcessState::join_thread_pool();
162 info!("KeyMint HAL service is terminating."); // should not reach here
163 Ok(())
164 }
165