blob: 2369d0a9128ced6ed41f49b9591958c31e321d3b [file] [log] [blame]
Tri Voe8f04442022-12-21 08:53:56 -08001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Helper wrapper around RKPD interface.
16
17use crate::error::{map_binder_status_code, map_or_log_err, Error, ErrorCode};
18use crate::globals::get_remotely_provisioned_component_name;
19use crate::ks_err;
20use crate::utils::watchdog as wd;
21use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
22use android_security_rkp_aidl::aidl::android::security::rkp::{
23 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::IGetKeyCallback,
24 IGetRegistrationCallback::BnGetRegistrationCallback,
25 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
26 IRemoteProvisioning::IRemoteProvisioning, RemotelyProvisionedKey::RemotelyProvisionedKey,
27};
28use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
29use anyhow::{Context, Result};
30use futures::channel::oneshot;
31use futures::executor::block_on;
32use std::sync::Mutex;
33
Seth Moorea882c962023-01-09 16:55:10 -080034/// Thread-safe channel for sending a value once and only once. If a value has
35/// already been send, subsequent calls to send will noop.
36struct SafeSender<T> {
37 inner: Mutex<Option<oneshot::Sender<T>>>,
38}
39
40impl<T> SafeSender<T> {
41 fn new(sender: oneshot::Sender<T>) -> Self {
42 Self { inner: Mutex::new(Some(sender)) }
43 }
44
45 fn send(&self, value: T) {
46 if let Some(inner) = self.inner.lock().unwrap().take() {
47 // assert instead of unwrap, because on failure send returns Err(value)
48 assert!(inner.send(value).is_ok(), "thread state is terminally broken");
49 }
50 }
51}
Tri Voe8f04442022-12-21 08:53:56 -080052
53struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080054 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080055}
56
57impl GetRegistrationCallback {
58 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080059 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080060 ) -> Result<Strong<dyn IGetRegistrationCallback>> {
61 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080062 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Tri Voe8f04442022-12-21 08:53:56 -080063 Ok(BnGetRegistrationCallback::new_binder(result, BinderFeatures::default()))
64 }
65 fn on_success(&self, registration: &binder::Strong<dyn IRegistration>) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080066 self.registration_tx.send(Ok(registration.clone()));
Tri Voe8f04442022-12-21 08:53:56 -080067 Ok(())
68 }
69 fn on_cancel(&self) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080070 self.registration_tx.send(
71 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
72 .context(ks_err!("GetRegistrationCallback cancelled.")),
73 );
Tri Voe8f04442022-12-21 08:53:56 -080074 Ok(())
75 }
76 fn on_error(&self, error: &str) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080077 self.registration_tx.send(
78 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
79 .context(ks_err!("GetRegistrationCallback failed: {:?}", error)),
80 );
Tri Voe8f04442022-12-21 08:53:56 -080081 Ok(())
82 }
83}
84
85impl Interface for GetRegistrationCallback {}
86
87impl IGetRegistrationCallback for GetRegistrationCallback {
88 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
89 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
90 map_or_log_err(self.on_success(registration), Ok)
91 }
92 fn onCancel(&self) -> binder::Result<()> {
93 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
94 map_or_log_err(self.on_cancel(), Ok)
95 }
96 fn onError(&self, error: &str) -> binder::Result<()> {
97 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
98 map_or_log_err(self.on_error(error), Ok)
99 }
100}
101
102/// Make a new connection to a IRegistration service.
103async fn get_rkpd_registration(
104 security_level: &SecurityLevel,
105) -> Result<binder::Strong<dyn IRegistration>> {
106 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
107 map_binder_status_code(binder::get_interface("remote_provisioning"))
108 .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
109
110 let rpc_name = get_remotely_provisioned_component_name(security_level)
111 .context(ks_err!("Trying to get IRPC name."))?;
112
113 let (tx, rx) = oneshot::channel();
114 let cb = GetRegistrationCallback::new_native_binder(tx)
115 .context(ks_err!("Trying to create a IGetRegistrationCallback."))?;
116
117 remote_provisioning
118 .getRegistration(&rpc_name, &cb)
119 .context(ks_err!("Trying to get registration."))?;
120
121 rx.await.unwrap()
122}
123
Tri Voe8f04442022-12-21 08:53:56 -0800124struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800125 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800126}
127
128impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800129 pub fn new_native_binder(
130 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
131 ) -> Result<Strong<dyn IGetKeyCallback>> {
132 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Tri Voe8f04442022-12-21 08:53:56 -0800133 Ok(BnGetKeyCallback::new_binder(result, BinderFeatures::default()))
134 }
135 fn on_success(&self, key: &RemotelyProvisionedKey) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800136 self.key_tx.send(Ok(RemotelyProvisionedKey {
137 keyBlob: key.keyBlob.clone(),
138 encodedCertChain: key.encodedCertChain.clone(),
139 }));
Tri Voe8f04442022-12-21 08:53:56 -0800140 Ok(())
141 }
142 fn on_cancel(&self) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800143 self.key_tx.send(
144 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
145 .context(ks_err!("GetKeyCallback cancelled.")),
146 );
Tri Voe8f04442022-12-21 08:53:56 -0800147 Ok(())
148 }
149 fn on_error(&self, error: &str) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800150 self.key_tx.send(
151 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
152 .context(ks_err!("GetKeyCallback failed: {:?}", error)),
153 );
Tri Voe8f04442022-12-21 08:53:56 -0800154 Ok(())
155 }
156}
157
158impl Interface for GetKeyCallback {}
159
160impl IGetKeyCallback for GetKeyCallback {
161 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
162 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
163 map_or_log_err(self.on_success(key), Ok)
164 }
165 fn onCancel(&self) -> binder::Result<()> {
166 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
167 map_or_log_err(self.on_cancel(), Ok)
168 }
169 fn onError(&self, error: &str) -> binder::Result<()> {
170 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
171 map_or_log_err(self.on_error(error), Ok)
172 }
173}
174
175async fn get_rkpd_attestation_key_async(
176 security_level: &SecurityLevel,
177 caller_uid: u32,
178) -> Result<RemotelyProvisionedKey> {
179 let registration = get_rkpd_registration(security_level)
180 .await
181 .context(ks_err!("Trying to get to IRegistration service."))?;
182
183 let (tx, rx) = oneshot::channel();
184 let cb = GetKeyCallback::new_native_binder(tx)
185 .context(ks_err!("Trying to create a IGetKeyCallback."))?;
186
187 registration
188 .getKey(caller_uid.try_into().unwrap(), &cb)
189 .context(ks_err!("Trying to get key."))?;
190
191 rx.await.unwrap()
192}
193
194async fn store_rkpd_attestation_key_async(
195 security_level: &SecurityLevel,
196 key_blob: &[u8],
197 upgraded_blob: &[u8],
198) -> Result<()> {
199 let registration = get_rkpd_registration(security_level)
200 .await
201 .context(ks_err!("Trying to get to IRegistration service."))?;
202
203 registration
204 .storeUpgradedKey(key_blob, upgraded_blob)
205 .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
206 Ok(())
207}
208
209/// Get attestation key from RKPD.
210pub fn get_rkpd_attestation_key(
211 security_level: &SecurityLevel,
212 caller_uid: u32,
213) -> Result<RemotelyProvisionedKey> {
214 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
215 block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
216}
217
218/// Store attestation key in RKPD.
219pub fn store_rkpd_attestation_key(
220 security_level: &SecurityLevel,
221 key_blob: &[u8],
222 upgraded_blob: &[u8],
223) -> Result<()> {
224 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
225 block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
226}
227
228#[cfg(test)]
229mod tests {
230 use super::*;
231 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
232 use std::sync::Arc;
233
234 #[derive(Default)]
235 struct MockRegistrationValues {
236 _key: RemotelyProvisionedKey,
237 }
238
239 #[derive(Default)]
240 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
241
242 impl MockRegistration {
243 pub fn new_native_binder() -> Strong<dyn IRegistration> {
244 let result: Self = Default::default();
245 BnRegistration::new_binder(result, BinderFeatures::default())
246 }
247 }
248
249 impl Interface for MockRegistration {}
250
251 impl IRegistration for MockRegistration {
252 fn getKey(&self, _: i32, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
253 todo!()
254 }
255
256 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
257 todo!()
258 }
259
260 fn storeUpgradedKey(&self, _: &[u8], _: &[u8]) -> binder::Result<()> {
261 todo!()
262 }
263 }
264
265 fn get_mock_registration() -> Result<binder::Strong<dyn IRegistration>> {
266 let (tx, rx) = oneshot::channel();
267 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
268 let mock_registration = MockRegistration::new_native_binder();
269
270 assert!(cb.onSuccess(&mock_registration).is_ok());
271 block_on(rx).unwrap()
272 }
273
274 #[test]
275 fn test_get_registration_cb_success() {
276 let registration = get_mock_registration();
277 assert!(registration.is_ok());
278 }
279
280 #[test]
281 fn test_get_registration_cb_cancel() {
282 let (tx, rx) = oneshot::channel();
283 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
284 assert!(cb.onCancel().is_ok());
285
286 let result = block_on(rx).unwrap();
287 assert_eq!(
288 result.unwrap_err().downcast::<Error>().unwrap(),
289 Error::Km(ErrorCode::OPERATION_CANCELLED)
290 );
291 }
292
293 #[test]
294 fn test_get_registration_cb_error() {
295 let (tx, rx) = oneshot::channel();
296 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
297 assert!(cb.onError("error").is_ok());
298
299 let result = block_on(rx).unwrap();
300 assert_eq!(
301 result.unwrap_err().downcast::<Error>().unwrap(),
302 Error::Km(ErrorCode::UNKNOWN_ERROR)
303 );
304 }
305
306 #[test]
307 fn test_get_key_cb_success() {
308 let mock_key =
309 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
310 let (tx, rx) = oneshot::channel();
311 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
312 assert!(cb.onSuccess(&mock_key).is_ok());
313
314 let key = block_on(rx).unwrap().unwrap();
315 assert_eq!(key, mock_key);
316 }
317
318 #[test]
319 fn test_get_key_cb_cancel() {
320 let (tx, rx) = oneshot::channel();
321 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
322 assert!(cb.onCancel().is_ok());
323
324 let result = block_on(rx).unwrap();
325 assert_eq!(
326 result.unwrap_err().downcast::<Error>().unwrap(),
327 Error::Km(ErrorCode::OPERATION_CANCELLED)
328 );
329 }
330
331 #[test]
332 fn test_get_key_cb_error() {
333 let (tx, rx) = oneshot::channel();
334 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
335 assert!(cb.onError("error").is_ok());
336
337 let result = block_on(rx).unwrap();
338 assert_eq!(
339 result.unwrap_err().downcast::<Error>().unwrap(),
340 Error::Km(ErrorCode::UNKNOWN_ERROR)
341 );
342 }
343
344 #[test]
345 #[ignore]
346 fn test_get_rkpd_attestation_key() {
347 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
348 assert!(!key.keyBlob.is_empty());
349 assert!(!key.encodedCertChain.is_empty());
350 }
351
352 #[test]
353 #[ignore]
354 fn test_get_rkpd_attestation_key_same_caller() {
355 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
356 let caller_uid = 0;
357
358 // Multiple calls should return the same key.
359 let first_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
360 let second_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
361
362 assert_eq!(first_key.keyBlob, second_key.keyBlob);
363 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
364 }
365
366 #[test]
367 #[ignore]
368 fn test_get_rkpd_attestation_key_different_caller() {
369 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
370
371 // Different callers should be getting different keys.
372 let first_key = get_rkpd_attestation_key(&sec_level, 1).unwrap();
373 let second_key = get_rkpd_attestation_key(&sec_level, 2).unwrap();
374
375 assert_ne!(first_key.keyBlob, second_key.keyBlob);
376 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
377 }
378
379 #[test]
380 #[ignore]
381 fn test_store_rkpd_attestation_key() {
382 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
383 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
384
385 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &key.keyBlob).is_ok());
386 }
387}