• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
17 use crate::error::{map_binder_status_code, Error, ResponseCode};
18 use crate::globals::get_remotely_provisioned_component_name;
19 use crate::ks_err;
20 use crate::utils::watchdog as wd;
21 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
22 use android_security_rkp_aidl::aidl::android::security::rkp::{
23     IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
24     IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
25     IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
26     IRemoteProvisioning::IRemoteProvisioning,
27     IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
28     IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
29     RemotelyProvisionedKey::RemotelyProvisionedKey,
30 };
31 use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
32 use anyhow::{Context, Result};
33 use std::sync::Mutex;
34 use std::time::Duration;
35 use tokio::sync::oneshot;
36 use tokio::time::timeout;
37 
38 // Normally, we block indefinitely when making calls outside of keystore and rely on watchdog to
39 // report deadlocks. However, RKPD is mainline updatable. Also, calls to RKPD may wait on network
40 // for certificates. So, we err on the side of caution and timeout instead.
41 static RKPD_TIMEOUT: Duration = Duration::from_secs(10);
42 
tokio_rt() -> tokio::runtime::Runtime43 fn tokio_rt() -> tokio::runtime::Runtime {
44     tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
45 }
46 
47 /// Thread-safe channel for sending a value once and only once. If a value has
48 /// already been send, subsequent calls to send will noop.
49 struct SafeSender<T> {
50     inner: Mutex<Option<oneshot::Sender<T>>>,
51 }
52 
53 impl<T> SafeSender<T> {
new(sender: oneshot::Sender<T>) -> Self54     fn new(sender: oneshot::Sender<T>) -> Self {
55         Self { inner: Mutex::new(Some(sender)) }
56     }
57 
send(&self, value: T)58     fn send(&self, value: T) {
59         if let Some(inner) = self.inner.lock().unwrap().take() {
60             // It's possible for the corresponding receiver to time out and be dropped. In this
61             // case send() will fail. This error is not actionable though, so only log the error.
62             if inner.send(value).is_err() {
63                 log::error!("SafeSender::send() failed");
64             }
65         }
66     }
67 }
68 
69 struct GetRegistrationCallback {
70     registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
71 }
72 
73 impl GetRegistrationCallback {
new_native_binder( registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>, ) -> Strong<dyn IGetRegistrationCallback>74     pub fn new_native_binder(
75         registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
76     ) -> Strong<dyn IGetRegistrationCallback> {
77         let result: Self =
78             GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
79         BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
80     }
81 }
82 
83 impl Interface for GetRegistrationCallback {}
84 
85 impl IGetRegistrationCallback for GetRegistrationCallback {
onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()>86     fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
87         let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
88         self.registration_tx.send(Ok(registration.clone()));
89         Ok(())
90     }
onCancel(&self) -> binder::Result<()>91     fn onCancel(&self) -> binder::Result<()> {
92         let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
93         log::warn!("IGetRegistrationCallback cancelled");
94         self.registration_tx.send(
95             Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
96                 .context(ks_err!("GetRegistrationCallback cancelled.")),
97         );
98         Ok(())
99     }
onError(&self, description: &str) -> binder::Result<()>100     fn onError(&self, description: &str) -> binder::Result<()> {
101         let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
102         log::error!("IGetRegistrationCallback failed: '{description}'");
103         self.registration_tx.send(
104             Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
105                 .context(ks_err!("GetRegistrationCallback failed: {:?}", description)),
106         );
107         Ok(())
108     }
109 }
110 
111 /// Make a new connection to a IRegistration service.
get_rkpd_registration( security_level: &SecurityLevel, ) -> Result<binder::Strong<dyn IRegistration>>112 async fn get_rkpd_registration(
113     security_level: &SecurityLevel,
114 ) -> Result<binder::Strong<dyn IRegistration>> {
115     let remote_provisioning: Strong<dyn IRemoteProvisioning> =
116         map_binder_status_code(binder::get_interface("remote_provisioning"))
117             .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
118 
119     let rpc_name = get_remotely_provisioned_component_name(security_level)
120         .context(ks_err!("Trying to get IRPC name."))?;
121 
122     let (tx, rx) = oneshot::channel();
123     let cb = GetRegistrationCallback::new_native_binder(tx);
124 
125     remote_provisioning
126         .getRegistration(&rpc_name, &cb)
127         .context(ks_err!("Trying to get registration."))?;
128 
129     match timeout(RKPD_TIMEOUT, rx).await {
130         Err(e) => {
131             Err(Error::Rc(ResponseCode::SYSTEM_ERROR)).context(ks_err!("Waiting for RKPD: {:?}", e))
132         }
133         Ok(v) => v.unwrap(),
134     }
135 }
136 
137 struct GetKeyCallback {
138     key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
139 }
140 
141 impl GetKeyCallback {
new_native_binder( key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>, ) -> Strong<dyn IGetKeyCallback>142     pub fn new_native_binder(
143         key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
144     ) -> Strong<dyn IGetKeyCallback> {
145         let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
146         BnGetKeyCallback::new_binder(result, BinderFeatures::default())
147     }
148 }
149 
150 impl Interface for GetKeyCallback {}
151 
152 impl IGetKeyCallback for GetKeyCallback {
onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()>153     fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
154         let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
155         self.key_tx.send(Ok(RemotelyProvisionedKey {
156             keyBlob: key.keyBlob.clone(),
157             encodedCertChain: key.encodedCertChain.clone(),
158         }));
159         Ok(())
160     }
onCancel(&self) -> binder::Result<()>161     fn onCancel(&self) -> binder::Result<()> {
162         let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
163         log::warn!("IGetKeyCallback cancelled");
164         self.key_tx.send(
165             Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
166                 .context(ks_err!("GetKeyCallback cancelled.")),
167         );
168         Ok(())
169     }
onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()>170     fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
171         let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
172         log::error!("IGetKeyCallback failed: {description}");
173         let rc = match error {
174             GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
175             GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
176             GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
177                 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
178             }
179             GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
180                 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
181             }
182             _ => {
183                 log::error!("Unexpected error from rkpd: {error:?}");
184                 ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
185             }
186         };
187         self.key_tx.send(Err(Error::Rc(rc)).context(ks_err!(
188             "GetKeyCallback failed: {:?} {:?}",
189             error,
190             description
191         )));
192         Ok(())
193     }
194 }
195 
get_rkpd_attestation_key_from_registration_async( registration: &Strong<dyn IRegistration>, caller_uid: u32, ) -> Result<RemotelyProvisionedKey>196 async fn get_rkpd_attestation_key_from_registration_async(
197     registration: &Strong<dyn IRegistration>,
198     caller_uid: u32,
199 ) -> Result<RemotelyProvisionedKey> {
200     let (tx, rx) = oneshot::channel();
201     let cb = GetKeyCallback::new_native_binder(tx);
202 
203     registration
204         .getKey(caller_uid.try_into().unwrap(), &cb)
205         .context(ks_err!("Trying to get key."))?;
206 
207     match timeout(RKPD_TIMEOUT, rx).await {
208         Err(e) => {
209             // Make a best effort attempt to cancel the timed out request.
210             if let Err(e) = registration.cancelGetKey(&cb) {
211                 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
212             }
213             Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
214                 .context(ks_err!("Waiting for RKPD key timed out: {:?}", e))
215         }
216         Ok(v) => v.unwrap(),
217     }
218 }
219 
get_rkpd_attestation_key_async( security_level: &SecurityLevel, caller_uid: u32, ) -> Result<RemotelyProvisionedKey>220 async fn get_rkpd_attestation_key_async(
221     security_level: &SecurityLevel,
222     caller_uid: u32,
223 ) -> Result<RemotelyProvisionedKey> {
224     let registration = get_rkpd_registration(security_level)
225         .await
226         .context(ks_err!("Trying to get to IRegistration service."))?;
227     get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
228 }
229 
230 struct StoreUpgradedKeyCallback {
231     completer: SafeSender<Result<()>>,
232 }
233 
234 impl StoreUpgradedKeyCallback {
new_native_binder( completer: oneshot::Sender<Result<()>>, ) -> Strong<dyn IStoreUpgradedKeyCallback>235     pub fn new_native_binder(
236         completer: oneshot::Sender<Result<()>>,
237     ) -> Strong<dyn IStoreUpgradedKeyCallback> {
238         let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
239         BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
240     }
241 }
242 
243 impl Interface for StoreUpgradedKeyCallback {}
244 
245 impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
onSuccess(&self) -> binder::Result<()>246     fn onSuccess(&self) -> binder::Result<()> {
247         let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
248         self.completer.send(Ok(()));
249         Ok(())
250     }
251 
onError(&self, error: &str) -> binder::Result<()>252     fn onError(&self, error: &str) -> binder::Result<()> {
253         let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
254         log::error!("IGetRegistrationCallback failed: {error}");
255         self.completer.send(
256             Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
257                 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
258         );
259         Ok(())
260     }
261 }
262 
store_rkpd_attestation_key_with_registration_async( registration: &Strong<dyn IRegistration>, key_blob: &[u8], upgraded_blob: &[u8], ) -> Result<()>263 async fn store_rkpd_attestation_key_with_registration_async(
264     registration: &Strong<dyn IRegistration>,
265     key_blob: &[u8],
266     upgraded_blob: &[u8],
267 ) -> Result<()> {
268     let (tx, rx) = oneshot::channel();
269     let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
270 
271     registration
272         .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
273         .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
274 
275     match timeout(RKPD_TIMEOUT, rx).await {
276         Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
277             .context(ks_err!("Waiting for RKPD to complete storing key: {:?}", e)),
278         Ok(v) => v.unwrap(),
279     }
280 }
281 
store_rkpd_attestation_key_async( security_level: &SecurityLevel, key_blob: &[u8], upgraded_blob: &[u8], ) -> Result<()>282 async fn store_rkpd_attestation_key_async(
283     security_level: &SecurityLevel,
284     key_blob: &[u8],
285     upgraded_blob: &[u8],
286 ) -> Result<()> {
287     let registration = get_rkpd_registration(security_level)
288         .await
289         .context(ks_err!("Trying to get to IRegistration service."))?;
290     store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
291 }
292 
293 /// Get attestation key from RKPD.
get_rkpd_attestation_key( security_level: &SecurityLevel, caller_uid: u32, ) -> Result<RemotelyProvisionedKey>294 pub fn get_rkpd_attestation_key(
295     security_level: &SecurityLevel,
296     caller_uid: u32,
297 ) -> Result<RemotelyProvisionedKey> {
298     let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
299     tokio_rt().block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
300 }
301 
302 /// Store attestation key in RKPD.
store_rkpd_attestation_key( security_level: &SecurityLevel, key_blob: &[u8], upgraded_blob: &[u8], ) -> Result<()>303 pub fn store_rkpd_attestation_key(
304     security_level: &SecurityLevel,
305     key_blob: &[u8],
306     upgraded_blob: &[u8],
307 ) -> Result<()> {
308     let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
309     tokio_rt().block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
310 }
311 
312 #[cfg(test)]
313 mod tests {
314     use super::*;
315     use crate::error::map_km_error;
316     use crate::globals::get_keymint_device;
317     use crate::utils::upgrade_keyblob_if_required_with;
318     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
319         Algorithm::Algorithm, AttestationKey::AttestationKey, KeyParameter::KeyParameter,
320         KeyParameterValue::KeyParameterValue, Tag::Tag,
321     };
322     use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
323     use keystore2_crypto::parse_subject_from_certificate;
324     use std::collections::HashMap;
325     use std::sync::atomic::{AtomicU32, Ordering};
326     use std::sync::{Arc, Mutex};
327 
328     struct MockRegistrationValues {
329         key: RemotelyProvisionedKey,
330         latency: Option<Duration>,
331         thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
332     }
333 
334     struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
335 
336     impl MockRegistration {
new_native_binder( key: &RemotelyProvisionedKey, latency: Option<Duration>, ) -> Strong<dyn IRegistration>337         pub fn new_native_binder(
338             key: &RemotelyProvisionedKey,
339             latency: Option<Duration>,
340         ) -> Strong<dyn IRegistration> {
341             let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
342                 key: RemotelyProvisionedKey {
343                     keyBlob: key.keyBlob.clone(),
344                     encodedCertChain: key.encodedCertChain.clone(),
345                 },
346                 latency,
347                 thread_join_handles: Vec::new(),
348             })));
349             BnRegistration::new_binder(result, BinderFeatures::default())
350         }
351     }
352 
353     impl Drop for MockRegistration {
drop(&mut self)354         fn drop(&mut self) {
355             let mut values = self.0.lock().unwrap();
356             for handle in values.thread_join_handles.iter_mut() {
357                 // These are test threads. So, no need to worry too much about error handling.
358                 handle.take().unwrap().join().unwrap();
359             }
360         }
361     }
362 
363     impl Interface for MockRegistration {}
364 
365     impl IRegistration for MockRegistration {
getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()>366         fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
367             let mut values = self.0.lock().unwrap();
368             let key = RemotelyProvisionedKey {
369                 keyBlob: values.key.keyBlob.clone(),
370                 encodedCertChain: values.key.encodedCertChain.clone(),
371             };
372             let latency = values.latency;
373             let get_key_cb = cb.clone();
374 
375             // Need a separate thread to trigger timeout in the caller.
376             let join_handle = std::thread::spawn(move || {
377                 if let Some(duration) = latency {
378                     std::thread::sleep(duration);
379                 }
380                 get_key_cb.onSuccess(&key).unwrap();
381             });
382             values.thread_join_handles.push(Some(join_handle));
383             Ok(())
384         }
385 
cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()>386         fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
387             Ok(())
388         }
389 
storeUpgradedKeyAsync( &self, _: &[u8], _: &[u8], cb: &Strong<dyn IStoreUpgradedKeyCallback>, ) -> binder::Result<()>390         fn storeUpgradedKeyAsync(
391             &self,
392             _: &[u8],
393             _: &[u8],
394             cb: &Strong<dyn IStoreUpgradedKeyCallback>,
395         ) -> binder::Result<()> {
396             // We are primarily concerned with timing out correctly. Storing the key in this mock
397             // registration isn't particularly interesting, so skip that part.
398             let values = self.0.lock().unwrap();
399             let store_cb = cb.clone();
400             let latency = values.latency;
401 
402             std::thread::spawn(move || {
403                 if let Some(duration) = latency {
404                     std::thread::sleep(duration);
405                 }
406                 store_cb.onSuccess().unwrap();
407             });
408             Ok(())
409         }
410     }
411 
get_mock_registration( key: &RemotelyProvisionedKey, latency: Option<Duration>, ) -> Result<binder::Strong<dyn IRegistration>>412     fn get_mock_registration(
413         key: &RemotelyProvisionedKey,
414         latency: Option<Duration>,
415     ) -> Result<binder::Strong<dyn IRegistration>> {
416         let (tx, rx) = oneshot::channel();
417         let cb = GetRegistrationCallback::new_native_binder(tx);
418         let mock_registration = MockRegistration::new_native_binder(key, latency);
419 
420         assert!(cb.onSuccess(&mock_registration).is_ok());
421         tokio_rt().block_on(rx).unwrap()
422     }
423 
424     // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
425     // different test cases.
get_next_key_id() -> u32426     fn get_next_key_id() -> u32 {
427         static ID: AtomicU32 = AtomicU32::new(0);
428         ID.fetch_add(1, Ordering::Relaxed)
429     }
430 
431     #[test]
test_get_registration_cb_success()432     fn test_get_registration_cb_success() {
433         let key: RemotelyProvisionedKey = Default::default();
434         let registration = get_mock_registration(&key, /*latency=*/ None);
435         assert!(registration.is_ok());
436     }
437 
438     #[test]
test_get_registration_cb_cancel()439     fn test_get_registration_cb_cancel() {
440         let (tx, rx) = oneshot::channel();
441         let cb = GetRegistrationCallback::new_native_binder(tx);
442         assert!(cb.onCancel().is_ok());
443 
444         let result = tokio_rt().block_on(rx).unwrap();
445         assert_eq!(
446             result.unwrap_err().downcast::<Error>().unwrap(),
447             Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
448         );
449     }
450 
451     #[test]
test_get_registration_cb_error()452     fn test_get_registration_cb_error() {
453         let (tx, rx) = oneshot::channel();
454         let cb = GetRegistrationCallback::new_native_binder(tx);
455         assert!(cb.onError("error").is_ok());
456 
457         let result = tokio_rt().block_on(rx).unwrap();
458         assert_eq!(
459             result.unwrap_err().downcast::<Error>().unwrap(),
460             Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
461         );
462     }
463 
464     #[test]
test_get_key_cb_success()465     fn test_get_key_cb_success() {
466         let mock_key =
467             RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
468         let (tx, rx) = oneshot::channel();
469         let cb = GetKeyCallback::new_native_binder(tx);
470         assert!(cb.onSuccess(&mock_key).is_ok());
471 
472         let key = tokio_rt().block_on(rx).unwrap().unwrap();
473         assert_eq!(key, mock_key);
474     }
475 
476     #[test]
test_get_key_cb_cancel()477     fn test_get_key_cb_cancel() {
478         let (tx, rx) = oneshot::channel();
479         let cb = GetKeyCallback::new_native_binder(tx);
480         assert!(cb.onCancel().is_ok());
481 
482         let result = tokio_rt().block_on(rx).unwrap();
483         assert_eq!(
484             result.unwrap_err().downcast::<Error>().unwrap(),
485             Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
486         );
487     }
488 
489     #[test]
test_get_key_cb_error()490     fn test_get_key_cb_error() {
491         let error_mapping = HashMap::from([
492             (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
493             (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
494             (
495                 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
496                 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
497             ),
498             (
499                 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
500                 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
501             ),
502         ]);
503 
504         // Loop over the generated list of enum values to better ensure this test stays in
505         // sync with the AIDL.
506         for get_key_error in GetKeyErrorCode::enum_values() {
507             let (tx, rx) = oneshot::channel();
508             let cb = GetKeyCallback::new_native_binder(tx);
509             assert!(cb.onError(get_key_error, "error").is_ok());
510 
511             let result = tokio_rt().block_on(rx).unwrap();
512             assert_eq!(
513                 result.unwrap_err().downcast::<Error>().unwrap(),
514                 Error::Rc(error_mapping[&get_key_error]),
515             );
516         }
517     }
518 
519     #[test]
test_store_upgraded_cb_success()520     fn test_store_upgraded_cb_success() {
521         let (tx, rx) = oneshot::channel();
522         let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
523         assert!(cb.onSuccess().is_ok());
524 
525         tokio_rt().block_on(rx).unwrap().unwrap();
526     }
527 
528     #[test]
test_store_upgraded_key_cb_error()529     fn test_store_upgraded_key_cb_error() {
530         let (tx, rx) = oneshot::channel();
531         let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
532         assert!(cb.onError("oh no! it failed").is_ok());
533 
534         let result = tokio_rt().block_on(rx).unwrap();
535         assert_eq!(
536             result.unwrap_err().downcast::<Error>().unwrap(),
537             Error::Rc(ResponseCode::SYSTEM_ERROR)
538         );
539     }
540 
541     #[test]
test_get_mock_key_success()542     fn test_get_mock_key_success() {
543         let mock_key =
544             RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
545         let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
546 
547         let key = tokio_rt()
548             .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
549             .unwrap();
550         assert_eq!(key, mock_key);
551     }
552 
553     #[test]
test_get_mock_key_timeout()554     fn test_get_mock_key_timeout() {
555         let mock_key =
556             RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
557         let latency = RKPD_TIMEOUT + Duration::from_secs(1);
558         let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
559 
560         let result =
561             tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
562         assert_eq!(
563             result.unwrap_err().downcast::<Error>().unwrap(),
564             Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
565         );
566     }
567 
568     #[test]
test_store_mock_key_success()569     fn test_store_mock_key_success() {
570         let mock_key =
571             RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
572         let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
573         tokio_rt()
574             .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
575             .unwrap();
576     }
577 
578     #[test]
test_store_mock_key_timeout()579     fn test_store_mock_key_timeout() {
580         let mock_key =
581             RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
582         let latency = RKPD_TIMEOUT + Duration::from_secs(1);
583         let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
584 
585         let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
586             &registration,
587             &[],
588             &[],
589         ));
590         assert_eq!(
591             result.unwrap_err().downcast::<Error>().unwrap(),
592             Error::Rc(ResponseCode::SYSTEM_ERROR)
593         );
594     }
595 
596     #[test]
test_get_rkpd_attestation_key()597     fn test_get_rkpd_attestation_key() {
598         binder::ProcessState::start_thread_pool();
599         let key_id = get_next_key_id();
600         let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
601         assert!(!key.keyBlob.is_empty());
602         assert!(!key.encodedCertChain.is_empty());
603     }
604 
605     #[test]
test_get_rkpd_attestation_key_same_caller()606     fn test_get_rkpd_attestation_key_same_caller() {
607         binder::ProcessState::start_thread_pool();
608         let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
609         let key_id = get_next_key_id();
610 
611         // Multiple calls should return the same key.
612         let first_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
613         let second_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
614 
615         assert_eq!(first_key.keyBlob, second_key.keyBlob);
616         assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
617     }
618 
619     #[test]
test_get_rkpd_attestation_key_different_caller()620     fn test_get_rkpd_attestation_key_different_caller() {
621         binder::ProcessState::start_thread_pool();
622         let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
623         let first_key_id = get_next_key_id();
624         let second_key_id = get_next_key_id();
625 
626         // Different callers should be getting different keys.
627         let first_key = get_rkpd_attestation_key(&sec_level, first_key_id).unwrap();
628         let second_key = get_rkpd_attestation_key(&sec_level, second_key_id).unwrap();
629 
630         assert_ne!(first_key.keyBlob, second_key.keyBlob);
631         assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
632     }
633 
634     #[test]
635     // Couple of things to note:
636     // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
637     //    keystore.
638     // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
639     //    test case.
test_store_rkpd_attestation_key()640     fn test_store_rkpd_attestation_key() {
641         binder::ProcessState::start_thread_pool();
642         let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
643         let key_id = get_next_key_id();
644         let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
645         let new_blob: [u8; 8] = rand::random();
646 
647         assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &new_blob).is_ok());
648 
649         let new_key =
650             get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
651 
652         // Restore original key so that we don't leave RKPD with invalid blobs.
653         assert!(store_rkpd_attestation_key(&sec_level, &new_blob, &key.keyBlob).is_ok());
654         assert_eq!(new_key.keyBlob, new_blob);
655     }
656 
657     #[test]
658     // This is a helper for a manual test. We want to check that after a system upgrade RKPD
659     // attestation keys can also be upgraded and stored again with RKPD. The steps are:
660     // 1. Run this test and check in stdout that no key upgrade happened.
661     // 2. Perform a system upgrade.
662     // 3. Run this test and check in stdout that key upgrade did happen.
663     //
664     // Note that this test must be run with that same UID every time. Running as root, i.e. UID 0,
665     // should do the trick. Also, use "--nocapture" flag to get stdout.
test_rkpd_attestation_key_upgrade()666     fn test_rkpd_attestation_key_upgrade() {
667         binder::ProcessState::start_thread_pool();
668         let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
669         let (keymint, _, _) = get_keymint_device(&security_level).unwrap();
670         let key_id = get_next_key_id();
671         let mut key_upgraded = false;
672 
673         let key = get_rkpd_attestation_key(&security_level, key_id).unwrap();
674         assert!(!key.keyBlob.is_empty());
675         assert!(!key.encodedCertChain.is_empty());
676 
677         upgrade_keyblob_if_required_with(
678             &*keymint,
679             &key.keyBlob,
680             /*upgrade_params=*/ &[],
681             /*km_op=*/
682             |blob| {
683                 let params = vec![
684                     KeyParameter {
685                         tag: Tag::ALGORITHM,
686                         value: KeyParameterValue::Algorithm(Algorithm::AES),
687                     },
688                     KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
689                 ];
690                 let attestation_key = AttestationKey {
691                     keyBlob: blob.to_vec(),
692                     attestKeyParams: vec![],
693                     issuerSubjectName: parse_subject_from_certificate(&key.encodedCertChain)
694                         .unwrap(),
695                 };
696 
697                 map_km_error(keymint.generateKey(&params, Some(&attestation_key)))
698             },
699             /*new_blob_handler=*/
700             |new_blob| {
701                 // This handler is only executed if a key upgrade was performed.
702                 key_upgraded = true;
703                 store_rkpd_attestation_key(&security_level, &key.keyBlob, new_blob).unwrap();
704                 Ok(())
705             },
706         )
707         .unwrap();
708 
709         if key_upgraded {
710             println!("RKPD key was upgraded and stored with RKPD.");
711         } else {
712             println!("RKPD key was NOT upgraded.");
713         }
714     }
715 
716     #[test]
test_stress_get_rkpd_attestation_key()717     fn test_stress_get_rkpd_attestation_key() {
718         binder::ProcessState::start_thread_pool();
719         let key_id = get_next_key_id();
720         let mut threads = vec![];
721         const NTHREADS: u32 = 10;
722         const NCALLS: u32 = 1000;
723 
724         for _ in 0..NTHREADS {
725             threads.push(std::thread::spawn(move || {
726                 for _ in 0..NCALLS {
727                     let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id)
728                         .unwrap();
729                     assert!(!key.keyBlob.is_empty());
730                     assert!(!key.encodedCertChain.is_empty());
731                 }
732             }));
733         }
734 
735         for t in threads {
736             assert!(t.join().is_ok());
737         }
738     }
739 }
740