blob: 500927872b53c423443b360ea9e926b11864a845 [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;
Alice Wang83c6aef2023-11-03 17:17:34 +000020use crate::watchdog_helper::watchdog as wd;
Tri Voe8f04442022-12-21 08:53:56 -080021use 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() {
Tri Vo0e5fe2c2023-02-15 17:02:06 -080060 // 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 }
Seth Moorea882c962023-01-09 16:55:10 -080065 }
66 }
67}
Tri Voe8f04442022-12-21 08:53:56 -080068
69struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080070 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080071}
72
73impl GetRegistrationCallback {
74 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080075 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -080076 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -080077 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080078 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -080079 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -080080 }
81}
82
83impl Interface for GetRegistrationCallback {}
84
85impl IGetRegistrationCallback for GetRegistrationCallback {
86 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
87 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080088 self.registration_tx.send(Ok(registration.clone()));
89 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080090 }
91 fn onCancel(&self) -> binder::Result<()> {
92 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080093 log::warn!("IGetRegistrationCallback cancelled");
94 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -080095 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
Seth Moore613a1fd2023-01-11 10:42:26 -080096 .context(ks_err!("GetRegistrationCallback cancelled.")),
97 );
98 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080099 }
Seth Moore484010a2023-01-31 11:22:26 -0800100 fn onError(&self, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800101 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800102 log::error!("IGetRegistrationCallback failed: '{description}'");
Seth Moore613a1fd2023-01-11 10:42:26 -0800103 self.registration_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800104 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
105 .context(ks_err!("GetRegistrationCallback failed: {:?}", description)),
Seth Moore613a1fd2023-01-11 10:42:26 -0800106 );
107 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800108 }
109}
110
111/// Make a new connection to a IRegistration service.
112async 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();
Seth Moore613a1fd2023-01-11 10:42:26 -0800123 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800124
125 remote_provisioning
126 .getRegistration(&rpc_name, &cb)
127 .context(ks_err!("Trying to get registration."))?;
128
Tri Vo437d0142023-01-18 16:43:49 -0800129 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 }
Tri Voe8f04442022-12-21 08:53:56 -0800135}
136
Tri Voe8f04442022-12-21 08:53:56 -0800137struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800138 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800139}
140
141impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800142 pub fn new_native_binder(
143 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800144 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800145 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800146 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800147 }
148}
149
150impl Interface for GetKeyCallback {}
151
152impl IGetKeyCallback for GetKeyCallback {
153 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
154 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800155 self.key_tx.send(Ok(RemotelyProvisionedKey {
156 keyBlob: key.keyBlob.clone(),
157 encodedCertChain: key.encodedCertChain.clone(),
158 }));
159 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800160 }
161 fn onCancel(&self) -> binder::Result<()> {
162 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800163 log::warn!("IGetKeyCallback cancelled");
164 self.key_tx.send(
Seth Moore484010a2023-01-31 11:22:26 -0800165 Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
166 .context(ks_err!("GetKeyCallback cancelled.")),
Seth Moore613a1fd2023-01-11 10:42:26 -0800167 );
168 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800169 }
Seth Moore484010a2023-01-31 11:22:26 -0800170 fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800171 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
Seth Moore484010a2023-01-31 11:22:26 -0800172 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 )));
Seth Moore613a1fd2023-01-11 10:42:26 -0800192 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800193 }
194}
195
Tri Vo437d0142023-01-18 16:43:49 -0800196async 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 {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800208 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 }
Tri Vo437d0142023-01-18 16:43:49 -0800216 Ok(v) => v.unwrap(),
217 }
218}
219
Tri Voe8f04442022-12-21 08:53:56 -0800220async 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."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800227 get_rkpd_attestation_key_from_registration_async(&registration, caller_uid).await
Tri Voe8f04442022-12-21 08:53:56 -0800228}
229
Seth Moorea55428e2023-01-10 13:07:31 -0800230struct StoreUpgradedKeyCallback {
231 completer: SafeSender<Result<()>>,
232}
233
234impl StoreUpgradedKeyCallback {
235 pub fn new_native_binder(
236 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800237 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800238 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800239 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800240 }
241}
242
243impl Interface for StoreUpgradedKeyCallback {}
244
245impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
246 fn onSuccess(&self) -> binder::Result<()> {
247 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800248 self.completer.send(Ok(()));
249 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800250 }
251
252 fn onError(&self, error: &str) -> binder::Result<()> {
253 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800254 log::error!("IGetRegistrationCallback failed: {error}");
255 self.completer.send(
Tri Vo437d0142023-01-18 16:43:49 -0800256 Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
Seth Moore613a1fd2023-01-11 10:42:26 -0800257 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
258 );
259 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800260 }
261}
262
Tri Vo437d0142023-01-18 16:43:49 -0800263async 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
Tri Voe8f04442022-12-21 08:53:56 -0800282async 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."))?;
Tri Vo437d0142023-01-18 16:43:49 -0800290 store_rkpd_attestation_key_with_registration_async(&registration, key_blob, upgraded_blob).await
Tri Voe8f04442022-12-21 08:53:56 -0800291}
292
293/// Get attestation key from RKPD.
294pub 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);
Tri Vo437d0142023-01-18 16:43:49 -0800299 tokio_rt().block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
Tri Voe8f04442022-12-21 08:53:56 -0800300}
301
302/// Store attestation key in RKPD.
303pub 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);
Tri Vo437d0142023-01-18 16:43:49 -0800309 tokio_rt().block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
Tri Voe8f04442022-12-21 08:53:56 -0800310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
Tri Vo30268da2023-01-24 15:35:45 -0800315 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 };
Tri Voe8f04442022-12-21 08:53:56 -0800322 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
Tri Vo30268da2023-01-24 15:35:45 -0800323 use keystore2_crypto::parse_subject_from_certificate;
Seth Moore484010a2023-01-31 11:22:26 -0800324 use std::collections::HashMap;
Tri Vo4b1cd822023-01-23 13:05:35 -0800325 use std::sync::atomic::{AtomicU32, Ordering};
Tri Vo215f12e2023-02-15 16:23:39 -0800326 use std::sync::{Arc, Mutex};
Tri Voe8f04442022-12-21 08:53:56 -0800327
Tri Vo215f12e2023-02-15 16:23:39 -0800328 struct MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800329 key: RemotelyProvisionedKey,
330 latency: Option<Duration>,
Tri Vo215f12e2023-02-15 16:23:39 -0800331 thread_join_handles: Vec<Option<std::thread::JoinHandle<()>>>,
Tri Voe8f04442022-12-21 08:53:56 -0800332 }
333
Tri Vo215f12e2023-02-15 16:23:39 -0800334 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
335
Tri Voe8f04442022-12-21 08:53:56 -0800336 impl MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800337 pub fn new_native_binder(
338 key: &RemotelyProvisionedKey,
339 latency: Option<Duration>,
340 ) -> Strong<dyn IRegistration> {
Tri Vo215f12e2023-02-15 16:23:39 -0800341 let result = Self(Arc::new(Mutex::new(MockRegistrationValues {
Tri Vo437d0142023-01-18 16:43:49 -0800342 key: RemotelyProvisionedKey {
343 keyBlob: key.keyBlob.clone(),
344 encodedCertChain: key.encodedCertChain.clone(),
345 },
346 latency,
Tri Vo215f12e2023-02-15 16:23:39 -0800347 thread_join_handles: Vec::new(),
348 })));
Tri Voe8f04442022-12-21 08:53:56 -0800349 BnRegistration::new_binder(result, BinderFeatures::default())
350 }
351 }
352
Tri Vo215f12e2023-02-15 16:23:39 -0800353 impl Drop for MockRegistration {
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
Tri Voe8f04442022-12-21 08:53:56 -0800363 impl Interface for MockRegistration {}
364
365 impl IRegistration for MockRegistration {
Tri Vo437d0142023-01-18 16:43:49 -0800366 fn getKey(&self, _: i32, cb: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo215f12e2023-02-15 16:23:39 -0800367 let mut values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800368 let key = RemotelyProvisionedKey {
Tri Vo215f12e2023-02-15 16:23:39 -0800369 keyBlob: values.key.keyBlob.clone(),
370 encodedCertChain: values.key.encodedCertChain.clone(),
Tri Vo437d0142023-01-18 16:43:49 -0800371 };
Tri Vo215f12e2023-02-15 16:23:39 -0800372 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800373 let get_key_cb = cb.clone();
374
375 // Need a separate thread to trigger timeout in the caller.
Tri Vo215f12e2023-02-15 16:23:39 -0800376 let join_handle = std::thread::spawn(move || {
Tri Vo437d0142023-01-18 16:43:49 -0800377 if let Some(duration) = latency {
378 std::thread::sleep(duration);
379 }
380 get_key_cb.onSuccess(&key).unwrap();
381 });
Tri Vo215f12e2023-02-15 16:23:39 -0800382 values.thread_join_handles.push(Some(join_handle));
Tri Vo437d0142023-01-18 16:43:49 -0800383 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800384 }
385
386 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
Tri Vo0e5fe2c2023-02-15 17:02:06 -0800387 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800388 }
389
Seth Moorea55428e2023-01-10 13:07:31 -0800390 fn storeUpgradedKeyAsync(
391 &self,
392 _: &[u8],
393 _: &[u8],
Tri Vo437d0142023-01-18 16:43:49 -0800394 cb: &Strong<dyn IStoreUpgradedKeyCallback>,
Seth Moorea55428e2023-01-10 13:07:31 -0800395 ) -> binder::Result<()> {
Tri Vo437d0142023-01-18 16:43:49 -0800396 // We are primarily concerned with timing out correctly. Storing the key in this mock
397 // registration isn't particularly interesting, so skip that part.
Tri Vo215f12e2023-02-15 16:23:39 -0800398 let values = self.0.lock().unwrap();
Tri Vo437d0142023-01-18 16:43:49 -0800399 let store_cb = cb.clone();
Tri Vo215f12e2023-02-15 16:23:39 -0800400 let latency = values.latency;
Tri Vo437d0142023-01-18 16:43:49 -0800401
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(())
Tri Voe8f04442022-12-21 08:53:56 -0800409 }
410 }
411
Tri Vo437d0142023-01-18 16:43:49 -0800412 fn get_mock_registration(
413 key: &RemotelyProvisionedKey,
414 latency: Option<Duration>,
415 ) -> Result<binder::Strong<dyn IRegistration>> {
Tri Voe8f04442022-12-21 08:53:56 -0800416 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800417 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Vo437d0142023-01-18 16:43:49 -0800418 let mock_registration = MockRegistration::new_native_binder(key, latency);
Tri Voe8f04442022-12-21 08:53:56 -0800419
420 assert!(cb.onSuccess(&mock_registration).is_ok());
Tri Vo437d0142023-01-18 16:43:49 -0800421 tokio_rt().block_on(rx).unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800422 }
423
Tri Vo4b1cd822023-01-23 13:05:35 -0800424 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
425 // different test cases.
426 fn get_next_key_id() -> u32 {
427 static ID: AtomicU32 = AtomicU32::new(0);
428 ID.fetch_add(1, Ordering::Relaxed)
429 }
430
Tri Voe8f04442022-12-21 08:53:56 -0800431 #[test]
432 fn test_get_registration_cb_success() {
Tri Vo437d0142023-01-18 16:43:49 -0800433 let key: RemotelyProvisionedKey = Default::default();
434 let registration = get_mock_registration(&key, /*latency=*/ None);
Tri Voe8f04442022-12-21 08:53:56 -0800435 assert!(registration.is_ok());
436 }
437
438 #[test]
439 fn test_get_registration_cb_cancel() {
440 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800441 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800442 assert!(cb.onCancel().is_ok());
443
Tri Vo437d0142023-01-18 16:43:49 -0800444 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800445 assert_eq!(
446 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800447 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800448 );
449 }
450
451 #[test]
452 fn test_get_registration_cb_error() {
453 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800454 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800455 assert!(cb.onError("error").is_ok());
456
Tri Vo437d0142023-01-18 16:43:49 -0800457 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800458 assert_eq!(
459 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800460 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800461 );
462 }
463
464 #[test]
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();
Seth Moore613a1fd2023-01-11 10:42:26 -0800469 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800470 assert!(cb.onSuccess(&mock_key).is_ok());
471
Tri Vo437d0142023-01-18 16:43:49 -0800472 let key = tokio_rt().block_on(rx).unwrap().unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800473 assert_eq!(key, mock_key);
474 }
475
476 #[test]
477 fn test_get_key_cb_cancel() {
478 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800479 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800480 assert!(cb.onCancel().is_ok());
481
Tri Vo437d0142023-01-18 16:43:49 -0800482 let result = tokio_rt().block_on(rx).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800483 assert_eq!(
484 result.unwrap_err().downcast::<Error>().unwrap(),
Seth Moore484010a2023-01-31 11:22:26 -0800485 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Voe8f04442022-12-21 08:53:56 -0800486 );
487 }
488
489 #[test]
490 fn test_get_key_cb_error() {
Seth Moore484010a2023-01-31 11:22:26 -0800491 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 ]);
Tri Voe8f04442022-12-21 08:53:56 -0800503
Seth Moore484010a2023-01-31 11:22:26 -0800504 // 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 }
Tri Voe8f04442022-12-21 08:53:56 -0800517 }
518
519 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800520 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800521 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.onSuccess().is_ok());
524
Tri Vo437d0142023-01-18 16:43:49 -0800525 tokio_rt().block_on(rx).unwrap().unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800526 }
527
528 #[test]
529 fn test_store_upgraded_key_cb_error() {
530 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800531 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800532 assert!(cb.onError("oh no! it failed").is_ok());
533
Tri Vo437d0142023-01-18 16:43:49 -0800534 let result = tokio_rt().block_on(rx).unwrap();
Seth Moorea55428e2023-01-10 13:07:31 -0800535 assert_eq!(
536 result.unwrap_err().downcast::<Error>().unwrap(),
Tri Vo437d0142023-01-18 16:43:49 -0800537 Error::Rc(ResponseCode::SYSTEM_ERROR)
538 );
539 }
540
541 #[test]
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]
554 fn test_get_mock_key_timeout() {
555 let mock_key =
556 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800557 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800558 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(),
Seth Moore484010a2023-01-31 11:22:26 -0800564 Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
Tri Vo437d0142023-01-18 16:43:49 -0800565 );
566 }
567
568 #[test]
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]
579 fn test_store_mock_key_timeout() {
580 let mock_key =
581 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
Tri Vo215f12e2023-02-15 16:23:39 -0800582 let latency = RKPD_TIMEOUT + Duration::from_secs(1);
Tri Vo437d0142023-01-18 16:43:49 -0800583 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)
Seth Moorea55428e2023-01-10 13:07:31 -0800593 );
594 }
595
596 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800597 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800598 binder::ProcessState::start_thread_pool();
Tri Vo437d0142023-01-18 16:43:49 -0800599 let key_id = get_next_key_id();
600 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800601 assert!(!key.keyBlob.is_empty());
602 assert!(!key.encodedCertChain.is_empty());
603 }
604
605 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800606 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800607 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800608 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800609 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800610
611 // Multiple calls should return the same key.
Tri Vo4b1cd822023-01-23 13:05:35 -0800612 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();
Tri Voe8f04442022-12-21 08:53:56 -0800614
615 assert_eq!(first_key.keyBlob, second_key.keyBlob);
616 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
617 }
618
619 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800620 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800621 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800622 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800623 let first_key_id = get_next_key_id();
624 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800625
626 // Different callers should be getting different keys.
Tri Vo4b1cd822023-01-23 13:05:35 -0800627 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();
Tri Voe8f04442022-12-21 08:53:56 -0800629
630 assert_ne!(first_key.keyBlob, second_key.keyBlob);
631 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
632 }
633
634 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800635 // 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.
Tri Voe8f04442022-12-21 08:53:56 -0800640 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800641 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800642 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800643 let key_id = get_next_key_id();
644 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800645 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800646
Tri Vobac3b522023-01-23 13:10:24 -0800647 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();
Tri Vofc179492023-02-01 14:18:18 -0800651
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());
Tri Vobac3b522023-01-23 13:10:24 -0800654 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800655 }
Tri Vo30268da2023-01-24 15:35:45 -0800656
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.
666 fn test_rkpd_attestation_key_upgrade() {
667 binder::ProcessState::start_thread_pool();
668 let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
David Drysdale5accbaa2023-04-12 18:47:10 +0100669 let (keymint, info, _) = get_keymint_device(&security_level).unwrap();
Tri Vo30268da2023-01-24 15:35:45 -0800670 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,
David Drysdale5accbaa2023-04-12 18:47:10 +0100679 info.versionNumber,
Tri Vo30268da2023-01-24 15:35:45 -0800680 &key.keyBlob,
681 /*upgrade_params=*/ &[],
682 /*km_op=*/
683 |blob| {
684 let params = vec![
685 KeyParameter {
686 tag: Tag::ALGORITHM,
687 value: KeyParameterValue::Algorithm(Algorithm::AES),
688 },
Seth Moore29fd4612023-09-26 10:42:06 -0700689 KeyParameter {
690 tag: Tag::ATTESTATION_CHALLENGE,
691 value: KeyParameterValue::Blob(vec![0; 16]),
692 },
Tri Vo30268da2023-01-24 15:35:45 -0800693 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
694 ];
695 let attestation_key = AttestationKey {
696 keyBlob: blob.to_vec(),
697 attestKeyParams: vec![],
698 issuerSubjectName: parse_subject_from_certificate(&key.encodedCertChain)
699 .unwrap(),
700 };
701
702 map_km_error(keymint.generateKey(&params, Some(&attestation_key)))
703 },
704 /*new_blob_handler=*/
705 |new_blob| {
706 // This handler is only executed if a key upgrade was performed.
707 key_upgraded = true;
708 store_rkpd_attestation_key(&security_level, &key.keyBlob, new_blob).unwrap();
709 Ok(())
710 },
711 )
712 .unwrap();
713
714 if key_upgraded {
715 println!("RKPD key was upgraded and stored with RKPD.");
716 } else {
717 println!("RKPD key was NOT upgraded.");
718 }
719 }
Tri Vo02f0fa42023-01-24 12:32:08 -0800720
721 #[test]
Tri Vo02f0fa42023-01-24 12:32:08 -0800722 fn test_stress_get_rkpd_attestation_key() {
723 binder::ProcessState::start_thread_pool();
724 let key_id = get_next_key_id();
725 let mut threads = vec![];
726 const NTHREADS: u32 = 10;
727 const NCALLS: u32 = 1000;
728
729 for _ in 0..NTHREADS {
730 threads.push(std::thread::spawn(move || {
731 for _ in 0..NCALLS {
732 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id)
733 .unwrap();
734 assert!(!key.keyBlob.is_empty());
735 assert!(!key.encodedCertChain.is_empty());
736 }
737 }));
738 }
739
740 for t in threads {
741 assert!(t.join().is_ok());
742 }
743 }
Tri Voe8f04442022-12-21 08:53:56 -0800744}