blob: f1e8e115c4fbbabcf1984b9c4e17feaf6a64f815 [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
Seth Moore484010a2023-01-31 11:22:26 -080017use crate::error::{map_binder_status_code, Error, ResponseCode};
Tri Voe8f04442022-12-21 08:53:56 -080018use 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::{
Seth Moore484010a2023-01-31 11:22:26 -080023 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
24 IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
Tri Voe8f04442022-12-21 08:53:56 -080025 IGetRegistrationCallback::IGetRegistrationCallback, IRegistration::IRegistration,
Seth Moorea55428e2023-01-10 13:07:31 -080026 IRemoteProvisioning::IRemoteProvisioning,
27 IStoreUpgradedKeyCallback::BnStoreUpgradedKeyCallback,
28 IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
29 RemotelyProvisionedKey::RemotelyProvisionedKey,
Tri Voe8f04442022-12-21 08:53:56 -080030};
31use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
32use anyhow::{Context, Result};
Tri Voe8f04442022-12-21 08:53:56 -080033use std::sync::Mutex;
Tri Vo437d0142023-01-18 16:43:49 -080034use std::time::Duration;
35use tokio::sync::oneshot;
36use 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.
41static RKPD_TIMEOUT: Duration = Duration::from_secs(10);
42
43fn tokio_rt() -> tokio::runtime::Runtime {
44 tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
45}
Tri Voe8f04442022-12-21 08:53:56 -080046
Seth Moorea882c962023-01-09 16:55:10 -080047/// 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.
49struct SafeSender<T> {
50 inner: Mutex<Option<oneshot::Sender<T>>>,
51}
52
53impl<T> SafeSender<T> {
54 fn new(sender: oneshot::Sender<T>) -> Self {
55 Self { inner: Mutex::new(Some(sender)) }
56 }
57
58 fn send(&self, value: T) {
59 if let Some(inner) = self.inner.lock().unwrap().take() {
60 // assert instead of unwrap, because on failure send returns Err(value)
61 assert!(inner.send(value).is_ok(), "thread state is terminally broken");
62 }
63 }
64}
Tri Voe8f04442022-12-21 08:53:56 -080065
66struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080067 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080068}
69
70impl GetRegistrationCallback {
71 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080072 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -080073 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -080074 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080075 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -080076 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -080077 }
78}
79
80impl Interface for GetRegistrationCallback {}
81
82impl IGetRegistrationCallback for GetRegistrationCallback {
83 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
84 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080085 self.registration_tx.send(Ok(registration.clone()));
86 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080087 }
88 fn onCancel(&self) -> binder::Result<()> {
89 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080090 log::warn!("IGetRegistrationCallback cancelled");
91 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -080092 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Seth Moore613a1fd2023-01-11 10:42:26 -080093 .context(ks_err!("GetRegistrationCallback cancelled.")),
94 );
95 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080096 }
Seth Moore484010a2023-01-31 11:22:26 -080097 fn onError(&self, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -080098 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -080099 log::error!("IGetRegistrationCallback failed: '{description}'");
Seth Moore613a1fd2023-01-11 10:42:26 -0800100 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800101 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
102 .context(ks_err!("GetRegistrationCallback failed: {:?}", description)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800103 );
104 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800105 }
106}
107
108/// Make a new connection to a IRegistration service.
109async fn get_rkpd_registration(
110 security_level: &SecurityLevel,
111) -> Result<binder::Strong<dyn IRegistration>> {
112 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
113 map_binder_status_code(binder::get_interface("remote_provisioning"))
114 .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
115
116 let rpc_name = get_remotely_provisioned_component_name(security_level)
117 .context(ks_err!("Trying to get IRPC name."))?;
118
119 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800120 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800121
122 remote_provisioning
123 .getRegistration(&rpc_name, &cb)
124 .context(ks_err!("Trying to get registration."))?;
125
Tri Vo437d0142023-01-18 16:43:49 -0800126 match timeout(RKPD_TIMEOUT, rx).await {
127 Err(e) => {
128 Err(Error::Rc(ResponseCode::SYSTEM_ERROR)).context(ks_err!("Waiting for RKPD: {:?}", e))
129 }
130 Ok(v) => v.unwrap(),
131 }
Tri Voe8f04442022-12-21 08:53:56 -0800132}
133
Tri Voe8f04442022-12-21 08:53:56 -0800134struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800135 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800136}
137
138impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800139 pub fn new_native_binder(
140 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800141 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800142 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800143 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800144 }
145}
146
147impl Interface for GetKeyCallback {}
148
149impl IGetKeyCallback for GetKeyCallback {
150 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
151 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800152 self.key_tx.send(Ok(RemotelyProvisionedKey {
153 keyBlob: key.keyBlob.clone(),
154 encodedCertChain: key.encodedCertChain.clone(),
155 }));
156 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800157 }
158 fn onCancel(&self) -> binder::Result<()> {
159 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800160 log::warn!("IGetKeyCallback cancelled");
161 self.key_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800162 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
163 .context(ks_err!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800164 );
165 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800166 }
Seth Moore484010a2023-01-31 11:22:26 -0800167 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800168 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800169 log::error!("IGetKeyCallback failed: {description}");
170 let rc = match error {
171 GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
172 GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
173 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
174 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
175 }
176 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
177 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
178 }
179 _ => {
180 log::error!("Unexpected error from rkpd: {error:?}");
181 ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
182 }
183 };
184 self.key_tx.send(Err(Error::Rc(rc)).context(ks_err!(
185 "GetKeyCallback failed: {:?} {:?}",
186 error,
187 description
188 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800189 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800190 }
191}
192
Tri Vo437d0142023-01-18 16:43:49 -0800193async fn get_rkpd_attestation_key_from_registration_async(
194 registration: &Strong<dyn IRegistration>,
195 caller_uid: u32,
196) -> Result<RemotelyProvisionedKey> {
197 let (tx, rx) = oneshot::channel();
198 let cb = GetKeyCallback::new_native_binder(tx);
199
200 registration
201 .getKey(caller_uid.try_into().unwrap(), &cb)
202 .context(ks_err!("Trying to get key."))?;
203
204 match timeout(RKPD_TIMEOUT, rx).await {
Seth Moore484010a2023-01-31 11:22:26 -0800205 Err(e) => Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Tri Vo437d0142023-01-18 16:43:49 -0800206 .context(ks_err!("Waiting for RKPD key timed out: {:?}", e)),
207 Ok(v) => v.unwrap(),
208 }
209}
210
Tri Voe8f04442022-12-21 08:53:56 -0800211async fn get_rkpd_attestation_key_async(
212 security_level: &SecurityLevel,
213 caller_uid: u32,
214) -> Result<RemotelyProvisionedKey> {
215 let registration = get_rkpd_registration(security_level)
216 .await
217 .context(ks_err!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800218 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800219}
220
Seth Moorea55428e2023-01-10 13:07:31 -0800221struct StoreUpgradedKeyCallback {
222 completer: SafeSender<Result<()>>,
223}
224
225impl StoreUpgradedKeyCallback {
226 pub fn new_native_binder(
227 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800228 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800229 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800230 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800231 }
232}
233
234impl Interface for StoreUpgradedKeyCallback {}
235
236impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
237 fn onSuccess(&self) -> binder::Result<()> {
238 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800239 self.completer.send(Ok(()));
240 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800241 }
242
243 fn onError(&self, error: &str) -> binder::Result<()> {
244 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800245 log::error!("IGetRegistrationCallback failed: {error}");
246 self.completer.send(
Tri Vo437d0142023-01-18 16:43:49 -0800247 Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Seth Moore613a1fd2023-01-11 10:42:26 -0800248 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
249 );
250 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800251 }
252}
253
Tri Vo437d0142023-01-18 16:43:49 -0800254async fn store_rkpd_attestation_key_with_registration_async(
255 registration: &Strong<dyn IRegistration>,
256 key_blob: &[u8],
257 upgraded_blob: &[u8],
258) -> Result<()> {
259 let (tx, rx) = oneshot::channel();
260 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
261
262 registration
263 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
264 .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
265
266 match timeout(RKPD_TIMEOUT, rx).await {
267 Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
268 .context(ks_err!("Waiting for RKPD to complete storing key: {:?}", e)),
269 Ok(v) => v.unwrap(),
270 }
271}
272
Tri Voe8f04442022-12-21 08:53:56 -0800273async fn store_rkpd_attestation_key_async(
274 security_level: &SecurityLevel,
275 key_blob: &[u8],
276 upgraded_blob: &[u8],
277) -> Result<()> {
278 let registration = get_rkpd_registration(security_level)
279 .await
280 .context(ks_err!("Trying to get to IRegistration service."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800281 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800282}
283
284/// Get attestation key from RKPD.
285pub fn get_rkpd_attestation_key(
286 security_level: &SecurityLevel,
287 caller_uid: u32,
288) -> Result<RemotelyProvisionedKey> {
289 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
Tri Vo437d0142023-01-18 16:43:49 -0800290 tokio_rt().block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800291}
292
293/// Store attestation key in RKPD.
294pub fn store_rkpd_attestation_key(
295 security_level: &SecurityLevel,
296 key_blob: &[u8],
297 upgraded_blob: &[u8],
298) -> Result<()> {
299 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
Tri Vo437d0142023-01-18 16:43:49 -0800300 tokio_rt().block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800301}
302
303#[cfg(test)]
304mod tests {
305 use super::*;
Tri Vo30268da2023-01-24 15:35:45 -0800306 use crate::error::map_km_error;
307 use crate::globals::get_keymint_device;
308 use crate::utils::upgrade_keyblob_if_required_with;
309 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
310 Algorithm::Algorithm, AttestationKey::AttestationKey, KeyParameter::KeyParameter,
311 KeyParameterValue::KeyParameterValue, Tag::Tag,
312 };
Tri Voe8f04442022-12-21 08:53:56 -0800313 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Tri Vo30268da2023-01-24 15:35:45 -0800314 use keystore2_crypto::parse_subject_from_certificate;
Seth Moore484010a2023-01-31 11:22:26 -0800315 use std::collections::HashMap;
Tri Vo4b1cd822023-01-23 13:05:35 -0800316 use std::sync::atomic::{AtomicU32, Ordering};
Tri Voe8f04442022-12-21 08:53:56 -0800317
318 #[derive(Default)]
Tri Vo437d0142023-01-18 16:43:49 -0800319 struct MockRegistration {
320 key: RemotelyProvisionedKey,
321 latency: Option<Duration>,
Tri Voe8f04442022-12-21 08:53:56 -0800322 }
323
Tri Voe8f04442022-12-21 08:53:56 -0800324 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800325 pub fn new_native_binder(
326 key: &RemotelyProvisionedKey,
327 latency: Option<Duration>,
328 ) -> Strong<dyn IRegistration> {
329 let result = Self {
330 key: RemotelyProvisionedKey {
331 keyBlob: key.keyBlob.clone(),
332 encodedCertChain: key.encodedCertChain.clone(),
333 },
334 latency,
335 };
Tri Voe8f04442022-12-21 08:53:56 -0800336 BnRegistration::new_binder(result, BinderFeatures::default())
337 }
338 }
339
340 impl Interface for MockRegistration {}
341
342 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800343 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
344 let key = RemotelyProvisionedKey {
345 keyBlob: self.key.keyBlob.clone(),
346 encodedCertChain: self.key.encodedCertChain.clone(),
347 };
348 let latency = self.latency;
349 let get_key_cb = cb.clone();
350
351 // Need a separate thread to trigger timeout in the caller.
352 std::thread::spawn(move || {
353 if let Some(duration) = latency {
354 std::thread::sleep(duration);
355 }
356 get_key_cb.onSuccess(&key).unwrap();
357 });
358 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800359 }
360
361 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
362 todo!()
363 }
364
Seth Moorea55428e2023-01-10 13:07:31 -0800365 fn storeUpgradedKeyAsync(
366 &self,
367 _: &[u8],
368 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800369 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800370 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800371 // We are primarily concerned with timing out correctly. Storing the key in this mock
372 // registration isn't particularly interesting, so skip that part.
373 let store_cb = cb.clone();
374 let latency = self.latency;
375
376 std::thread::spawn(move || {
377 if let Some(duration) = latency {
378 std::thread::sleep(duration);
379 }
380 store_cb.onSuccess().unwrap();
381 });
382 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800383 }
384 }
385
Tri Vo437d0142023-01-18 16:43:49 -0800386 fn get_mock_registration(
387 key: &RemotelyProvisionedKey,
388 latency: Option<Duration>,
389 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800390 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800391 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800392 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800393
394 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800395 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800396 }
397
Tri Vo4b1cd822023-01-23 13:05:35 -0800398 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
399 // different test cases.
400 fn get_next_key_id() -> u32 {
401 static ID: AtomicU32 = AtomicU32::new(0);
402 ID.fetch_add(1, Ordering::Relaxed)
403 }
404
Tri Voe8f04442022-12-21 08:53:56 -0800405 #[test]
406 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800407 let key: RemotelyProvisionedKey = Default::default();
408 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800409 assert!(registration.is_ok());
410 }
411
412 #[test]
413 fn test_get_registration_cb_cancel() {
414 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800415 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800416 assert!(cb.onCancel().is_ok());
417
Tri Vo437d0142023-01-18 16:43:49 -0800418 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800419 assert_eq!(
420 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800421 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800422 );
423 }
424
425 #[test]
426 fn test_get_registration_cb_error() {
427 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800428 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800429 assert!(cb.onError("error").is_ok());
430
Tri Vo437d0142023-01-18 16:43:49 -0800431 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800432 assert_eq!(
433 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800434 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800435 );
436 }
437
438 #[test]
439 fn test_get_key_cb_success() {
440 let mock_key =
441 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
442 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800443 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800444 assert!(cb.onSuccess(&mock_key).is_ok());
445
Tri Vo437d0142023-01-18 16:43:49 -0800446 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800447 assert_eq!(key, mock_key);
448 }
449
450 #[test]
451 fn test_get_key_cb_cancel() {
452 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800453 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800454 assert!(cb.onCancel().is_ok());
455
Tri Vo437d0142023-01-18 16:43:49 -0800456 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800457 assert_eq!(
458 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800459 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800460 );
461 }
462
463 #[test]
464 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800465 let error_mapping = HashMap::from([
466 (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
467 (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
468 (
469 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
470 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
471 ),
472 (
473 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
474 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
475 ),
476 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800477
Seth Moore484010a2023-01-31 11:22:26 -0800478 // Loop over the generated list of enum values to better ensure this test stays in
479 // sync with the AIDL.
480 for get_key_error in GetKeyErrorCode::enum_values() {
481 let (tx, rx) = oneshot::channel();
482 let cb = GetKeyCallback::new_native_binder(tx);
483 assert!(cb.onError(get_key_error, "error").is_ok());
484
485 let result = tokio_rt().block_on(rx).unwrap();
486 assert_eq!(
487 result.unwrap_err().downcast::<Error>().unwrap(),
488 Error::Rc(error_mapping[&get_key_error]),
489 );
490 }
Tri Voe8f04442022-12-21 08:53:56 -0800491 }
492
493 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800494 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800495 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800496 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800497 assert!(cb.onSuccess().is_ok());
498
Tri Vo437d0142023-01-18 16:43:49 -0800499 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800500 }
501
502 #[test]
503 fn test_store_upgraded_key_cb_error() {
504 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800505 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800506 assert!(cb.onError("oh no! it failed").is_ok());
507
Tri Vo437d0142023-01-18 16:43:49 -0800508 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800509 assert_eq!(
510 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800511 Error::Rc(ResponseCode::SYSTEM_ERROR)
512 );
513 }
514
515 #[test]
516 fn test_get_mock_key_success() {
517 let mock_key =
518 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
519 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
520
521 let key = tokio_rt()
522 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
523 .unwrap();
524 assert_eq!(key, mock_key);
525 }
526
527 #[test]
528 fn test_get_mock_key_timeout() {
529 let mock_key =
530 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
531 let latency = RKPD_TIMEOUT + Duration::from_secs(10);
532 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
533
534 let result =
535 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
536 assert_eq!(
537 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800538 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800539 );
540 }
541
542 #[test]
543 fn test_store_mock_key_success() {
544 let mock_key =
545 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
546 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
547 tokio_rt()
548 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
549 .unwrap();
550 }
551
552 #[test]
553 fn test_store_mock_key_timeout() {
554 let mock_key =
555 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
556 let latency = RKPD_TIMEOUT + Duration::from_secs(10);
557 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
558
559 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
560 &registration,
561 &[],
562 &[],
563 ));
564 assert_eq!(
565 result.unwrap_err().downcast::<Error>().unwrap(),
566 Error::Rc(ResponseCode::SYSTEM_ERROR)
Seth Moorea55428e2023-01-10 13:07:31 -0800567 );
568 }
569
570 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800571 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800572 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800573 let key_id = get_next_key_id();
574 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800575 assert!(!key.keyBlob.is_empty());
576 assert!(!key.encodedCertChain.is_empty());
577 }
578
579 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800580 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800581 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800582 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800583 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800584
585 // Multiple calls should return the same key.
Tri Vo4b1cd822023-01-23 13:05:35 -0800586 let first_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
587 let second_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800588
589 assert_eq!(first_key.keyBlob, second_key.keyBlob);
590 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
591 }
592
593 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800594 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800595 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800596 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800597 let first_key_id = get_next_key_id();
598 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800599
600 // Different callers should be getting different keys.
Tri Vo4b1cd822023-01-23 13:05:35 -0800601 let first_key = get_rkpd_attestation_key(&sec_level, first_key_id).unwrap();
602 let second_key = get_rkpd_attestation_key(&sec_level, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800603
604 assert_ne!(first_key.keyBlob, second_key.keyBlob);
605 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
606 }
607
608 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800609 // Couple of things to note:
610 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
611 // keystore.
612 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
613 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800614 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800615 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800616 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800617 let key_id = get_next_key_id();
618 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800619 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800620
Tri Vobac3b522023-01-23 13:10:24 -0800621 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &new_blob).is_ok());
622
623 let new_key =
624 get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800625
626 // Restore original key so that we don't leave RKPD with invalid blobs.
627 assert!(store_rkpd_attestation_key(&sec_level, &new_blob, &key.keyBlob).is_ok());
Tri Vobac3b522023-01-23 13:10:24 -0800628 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800629 }
Tri Vo30268da2023-01-24 15:35:45 -0800630
631 #[test]
632 // This is a helper for a manual test. We want to check that after a system upgrade RKPD
633 // attestation keys can also be upgraded and stored again with RKPD. The steps are:
634 // 1. Run this test and check in stdout that no key upgrade happened.
635 // 2. Perform a system upgrade.
636 // 3. Run this test and check in stdout that key upgrade did happen.
637 //
638 // Note that this test must be run with that same UID every time. Running as root, i.e. UID 0,
639 // should do the trick. Also, use "--nocapture" flag to get stdout.
640 fn test_rkpd_attestation_key_upgrade() {
641 binder::ProcessState::start_thread_pool();
642 let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
643 let (keymint, _, _) = get_keymint_device(&security_level).unwrap();
644 let key_id = get_next_key_id();
645 let mut key_upgraded = false;
646
647 let key = get_rkpd_attestation_key(&security_level, key_id).unwrap();
648 assert!(!key.keyBlob.is_empty());
649 assert!(!key.encodedCertChain.is_empty());
650
651 upgrade_keyblob_if_required_with(
652 &*keymint,
653 &key.keyBlob,
654 /*upgrade_params=*/ &[],
655 /*km_op=*/
656 |blob| {
657 let params = vec![
658 KeyParameter {
659 tag: Tag::ALGORITHM,
660 value: KeyParameterValue::Algorithm(Algorithm::AES),
661 },
662 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
663 ];
664 let attestation_key = AttestationKey {
665 keyBlob: blob.to_vec(),
666 attestKeyParams: vec![],
667 issuerSubjectName: parse_subject_from_certificate(&key.encodedCertChain)
668 .unwrap(),
669 };
670
671 map_km_error(keymint.generateKey(&params, Some(&attestation_key)))
672 },
673 /*new_blob_handler=*/
674 |new_blob| {
675 // This handler is only executed if a key upgrade was performed.
676 key_upgraded = true;
677 store_rkpd_attestation_key(&security_level, &key.keyBlob, new_blob).unwrap();
678 Ok(())
679 },
680 )
681 .unwrap();
682
683 if key_upgraded {
684 println!("RKPD key was upgraded and stored with RKPD.");
685 } else {
686 println!("RKPD key was NOT upgraded.");
687 }
688 }
Tri Vo02f0fa42023-01-24 12:32:08 -0800689
690 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800691 fn test_stress_get_rkpd_attestation_key() {
692 binder::ProcessState::start_thread_pool();
693 let key_id = get_next_key_id();
694 let mut threads = vec![];
695 const NTHREADS: u32 = 10;
696 const NCALLS: u32 = 1000;
697
698 for _ in 0..NTHREADS {
699 threads.push(std::thread::spawn(move || {
700 for _ in 0..NCALLS {
701 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id)
702 .unwrap();
703 assert!(!key.keyBlob.is_empty());
704 assert!(!key.encodedCertChain.is_empty());
705 }
706 }));
707 }
708
709 for t in threads {
710 assert!(t.join().is_ok());
711 }
712 }
Tri Voe8f04442022-12-21 08:53:56 -0800713}