blob: 0754a64680fea59039e0dcd96ea1dd1febee3e59 [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 Vo215f12e2023-02-15 16:23:39 -0800317 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800318
Tri Vo215f12e2023-02-15 16:23:39 -0800319 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800320 key: RemotelyProvisionedKey,
321 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800322 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800323 }
324
Tri Vo215f12e2023-02-15 16:23:39 -0800325 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
326
Tri Voe8f04442022-12-21 08:53:56 -0800327 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800328 pub fn new_native_binder(
329 key: &RemotelyProvisionedKey,
330 latency: Option<Duration>,
331 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800332 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800333 key: RemotelyProvisionedKey {
334 keyBlob: key.keyBlob.clone(),
335 encodedCertChain: key.encodedCertChain.clone(),
336 },
337 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800338 thread_join_handles: Vec::new(),
339 })));
Tri Voe8f04442022-12-21 08:53:56 -0800340 BnRegistration::new_binder(result, BinderFeatures::default())
341 }
342 }
343
Tri Vo215f12e2023-02-15 16:23:39 -0800344 impl Drop for MockRegistration {
345 fn drop(&mut self) {
346 let mut values = self.0.lock().unwrap();
347 for handle in values.thread_join_handles.iter_mut() {
348 // These are test threads. So, no need to worry too much about error handling.
349 handle.take().unwrap().join().unwrap();
350 }
351 }
352 }
353
Tri Voe8f04442022-12-21 08:53:56 -0800354 impl Interface for MockRegistration {}
355
356 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800357 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800358 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800359 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800360 keyBlob: values.key.keyBlob.clone(),
361 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800362 };
Tri Vo215f12e2023-02-15 16:23:39 -0800363 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800364 let get_key_cb = cb.clone();
365
366 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800367 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800368 if let Some(duration) = latency {
369 std::thread::sleep(duration);
370 }
371 get_key_cb.onSuccess(&key).unwrap();
372 });
Tri Vo215f12e2023-02-15 16:23:39 -0800373 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800374 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800375 }
376
377 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
378 todo!()
379 }
380
Seth Moorea55428e2023-01-10 13:07:31 -0800381 fn storeUpgradedKeyAsync(
382 &self,
383 _: &[u8],
384 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800385 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800386 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800387 // We are primarily concerned with timing out correctly. Storing the key in this mock
388 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800389 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800390 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800391 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800392
393 std::thread::spawn(move || {
394 if let Some(duration) = latency {
395 std::thread::sleep(duration);
396 }
397 store_cb.onSuccess().unwrap();
398 });
399 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800400 }
401 }
402
Tri Vo437d0142023-01-18 16:43:49 -0800403 fn get_mock_registration(
404 key: &RemotelyProvisionedKey,
405 latency: Option<Duration>,
406 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800407 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800408 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800409 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800410
411 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800412 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800413 }
414
Tri Vo4b1cd822023-01-23 13:05:35 -0800415 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
416 // different test cases.
417 fn get_next_key_id() -> u32 {
418 static ID: AtomicU32 = AtomicU32::new(0);
419 ID.fetch_add(1, Ordering::Relaxed)
420 }
421
Tri Voe8f04442022-12-21 08:53:56 -0800422 #[test]
423 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800424 let key: RemotelyProvisionedKey = Default::default();
425 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800426 assert!(registration.is_ok());
427 }
428
429 #[test]
430 fn test_get_registration_cb_cancel() {
431 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800432 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800433 assert!(cb.onCancel().is_ok());
434
Tri Vo437d0142023-01-18 16:43:49 -0800435 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800436 assert_eq!(
437 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800438 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800439 );
440 }
441
442 #[test]
443 fn test_get_registration_cb_error() {
444 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800445 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800446 assert!(cb.onError("error").is_ok());
447
Tri Vo437d0142023-01-18 16:43:49 -0800448 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800449 assert_eq!(
450 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800451 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800452 );
453 }
454
455 #[test]
456 fn test_get_key_cb_success() {
457 let mock_key =
458 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
459 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800460 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800461 assert!(cb.onSuccess(&mock_key).is_ok());
462
Tri Vo437d0142023-01-18 16:43:49 -0800463 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800464 assert_eq!(key, mock_key);
465 }
466
467 #[test]
468 fn test_get_key_cb_cancel() {
469 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800470 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800471 assert!(cb.onCancel().is_ok());
472
Tri Vo437d0142023-01-18 16:43:49 -0800473 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800474 assert_eq!(
475 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800476 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800477 );
478 }
479
480 #[test]
481 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800482 let error_mapping = HashMap::from([
483 (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
484 (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
485 (
486 GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
487 ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
488 ),
489 (
490 GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
491 ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
492 ),
493 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800494
Seth Moore484010a2023-01-31 11:22:26 -0800495 // Loop over the generated list of enum values to better ensure this test stays in
496 // sync with the AIDL.
497 for get_key_error in GetKeyErrorCode::enum_values() {
498 let (tx, rx) = oneshot::channel();
499 let cb = GetKeyCallback::new_native_binder(tx);
500 assert!(cb.onError(get_key_error, "error").is_ok());
501
502 let result = tokio_rt().block_on(rx).unwrap();
503 assert_eq!(
504 result.unwrap_err().downcast::<Error>().unwrap(),
505 Error::Rc(error_mapping[&get_key_error]),
506 );
507 }
Tri Voe8f04442022-12-21 08:53:56 -0800508 }
509
510 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800511 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800512 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800513 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800514 assert!(cb.onSuccess().is_ok());
515
Tri Vo437d0142023-01-18 16:43:49 -0800516 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800517 }
518
519 #[test]
520 fn test_store_upgraded_key_cb_error() {
521 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800522 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800523 assert!(cb.onError("oh no! it failed").is_ok());
524
Tri Vo437d0142023-01-18 16:43:49 -0800525 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800526 assert_eq!(
527 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800528 Error::Rc(ResponseCode::SYSTEM_ERROR)
529 );
530 }
531
532 #[test]
533 fn test_get_mock_key_success() {
534 let mock_key =
535 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
536 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
537
538 let key = tokio_rt()
539 .block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0))
540 .unwrap();
541 assert_eq!(key, mock_key);
542 }
543
544 #[test]
545 fn test_get_mock_key_timeout() {
546 let mock_key =
547 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800548 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800549 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
550
551 let result =
552 tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
553 assert_eq!(
554 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800555 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800556 );
557 }
558
559 #[test]
560 fn test_store_mock_key_success() {
561 let mock_key =
562 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
563 let registration = get_mock_registration(&mock_key, /*latency=*/ None).unwrap();
564 tokio_rt()
565 .block_on(store_rkpd_attestation_key_with_registration_async(&registration, &[], &[]))
566 .unwrap();
567 }
568
569 #[test]
570 fn test_store_mock_key_timeout() {
571 let mock_key =
572 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800573 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800574 let registration = get_mock_registration(&mock_key, Some(latency)).unwrap();
575
576 let result = tokio_rt().block_on(store_rkpd_attestation_key_with_registration_async(
577 &registration,
578 &[],
579 &[],
580 ));
581 assert_eq!(
582 result.unwrap_err().downcast::<Error>().unwrap(),
583 Error::Rc(ResponseCode::SYSTEM_ERROR)
Seth Moorea55428e2023-01-10 13:07:31 -0800584 );
585 }
586
587 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800588 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800589 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800590 let key_id = get_next_key_id();
591 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800592 assert!(!key.keyBlob.is_empty());
593 assert!(!key.encodedCertChain.is_empty());
594 }
595
596 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800597 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800598 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800599 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800600 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800601
602 // Multiple calls should return the same key.
Tri Vo4b1cd822023-01-23 13:05:35 -0800603 let first_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
604 let second_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800605
606 assert_eq!(first_key.keyBlob, second_key.keyBlob);
607 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
608 }
609
610 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800611 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800612 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800613 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800614 let first_key_id = get_next_key_id();
615 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800616
617 // Different callers should be getting different keys.
Tri Vo4b1cd822023-01-23 13:05:35 -0800618 let first_key = get_rkpd_attestation_key(&sec_level, first_key_id).unwrap();
619 let second_key = get_rkpd_attestation_key(&sec_level, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800620
621 assert_ne!(first_key.keyBlob, second_key.keyBlob);
622 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
623 }
624
625 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800626 // Couple of things to note:
627 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
628 // keystore.
629 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
630 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800631 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800632 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800633 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800634 let key_id = get_next_key_id();
635 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800636 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800637
Tri Vobac3b522023-01-23 13:10:24 -0800638 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &new_blob).is_ok());
639
640 let new_key =
641 get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vofc179492023-02-01 14:18:18 -0800642
643 // Restore original key so that we don't leave RKPD with invalid blobs.
644 assert!(store_rkpd_attestation_key(&sec_level, &new_blob, &key.keyBlob).is_ok());
Tri Vobac3b522023-01-23 13:10:24 -0800645 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800646 }
Tri Vo30268da2023-01-24 15:35:45 -0800647
648 #[test]
649 // This is a helper for a manual test. We want to check that after a system upgrade RKPD
650 // attestation keys can also be upgraded and stored again with RKPD. The steps are:
651 // 1. Run this test and check in stdout that no key upgrade happened.
652 // 2. Perform a system upgrade.
653 // 3. Run this test and check in stdout that key upgrade did happen.
654 //
655 // Note that this test must be run with that same UID every time. Running as root, i.e. UID 0,
656 // should do the trick. Also, use "--nocapture" flag to get stdout.
657 fn test_rkpd_attestation_key_upgrade() {
658 binder::ProcessState::start_thread_pool();
659 let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
660 let (keymint, _, _) = get_keymint_device(&security_level).unwrap();
661 let key_id = get_next_key_id();
662 let mut key_upgraded = false;
663
664 let key = get_rkpd_attestation_key(&security_level, key_id).unwrap();
665 assert!(!key.keyBlob.is_empty());
666 assert!(!key.encodedCertChain.is_empty());
667
668 upgrade_keyblob_if_required_with(
669 &*keymint,
670 &key.keyBlob,
671 /*upgrade_params=*/ &[],
672 /*km_op=*/
673 |blob| {
674 let params = vec![
675 KeyParameter {
676 tag: Tag::ALGORITHM,
677 value: KeyParameterValue::Algorithm(Algorithm::AES),
678 },
679 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
680 ];
681 let attestation_key = AttestationKey {
682 keyBlob: blob.to_vec(),
683 attestKeyParams: vec![],
684 issuerSubjectName: parse_subject_from_certificate(&key.encodedCertChain)
685 .unwrap(),
686 };
687
688 map_km_error(keymint.generateKey(&params, Some(&attestation_key)))
689 },
690 /*new_blob_handler=*/
691 |new_blob| {
692 // This handler is only executed if a key upgrade was performed.
693 key_upgraded = true;
694 store_rkpd_attestation_key(&security_level, &key.keyBlob, new_blob).unwrap();
695 Ok(())
696 },
697 )
698 .unwrap();
699
700 if key_upgraded {
701 println!("RKPD key was upgraded and stored with RKPD.");
702 } else {
703 println!("RKPD key was NOT upgraded.");
704 }
705 }
Tri Vo02f0fa42023-01-24 12:32:08 -0800706
707 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800708 fn test_stress_get_rkpd_attestation_key() {
709 binder::ProcessState::start_thread_pool();
710 let key_id = get_next_key_id();
711 let mut threads = vec![];
712 const NTHREADS: u32 = 10;
713 const NCALLS: u32 = 1000;
714
715 for _ in 0..NTHREADS {
716 threads.push(std::thread::spawn(move || {
717 for _ in 0..NCALLS {
718 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id)
719 .unwrap();
720 assert!(!key.keyBlob.is_empty());
721 assert!(!key.encodedCertChain.is_empty());
722 }
723 }));
724 }
725
726 for t in threads {
727 assert!(t.join().is_ok());
728 }
729 }
Tri Voe8f04442022-12-21 08:53:56 -0800730}