blob: b426440ff00deb7c0cd7ad83eb711c264470061e [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 Moore613a1fd2023-01-11 10:42:26 -080017use crate::error::{map_binder_status_code, Error, ErrorCode};
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::{
23 IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::IGetKeyCallback,
24 IGetRegistrationCallback::BnGetRegistrationCallback,
25 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};
33use futures::channel::oneshot;
34use futures::executor::block_on;
35use std::sync::Mutex;
36
Seth Moorea882c962023-01-09 16:55:10 -080037/// Thread-safe channel for sending a value once and only once. If a value has
38/// already been send, subsequent calls to send will noop.
39struct SafeSender<T> {
40 inner: Mutex<Option<oneshot::Sender<T>>>,
41}
42
43impl<T> SafeSender<T> {
44 fn new(sender: oneshot::Sender<T>) -> Self {
45 Self { inner: Mutex::new(Some(sender)) }
46 }
47
48 fn send(&self, value: T) {
49 if let Some(inner) = self.inner.lock().unwrap().take() {
50 // assert instead of unwrap, because on failure send returns Err(value)
51 assert!(inner.send(value).is_ok(), "thread state is terminally broken");
52 }
53 }
54}
Tri Voe8f04442022-12-21 08:53:56 -080055
56struct GetRegistrationCallback {
Seth Moorea882c962023-01-09 16:55:10 -080057 registration_tx: SafeSender<Result<binder::Strong<dyn IRegistration>>>,
Tri Voe8f04442022-12-21 08:53:56 -080058}
59
60impl GetRegistrationCallback {
61 pub fn new_native_binder(
Seth Moorea882c962023-01-09 16:55:10 -080062 registration_tx: oneshot::Sender<Result<binder::Strong<dyn IRegistration>>>,
Seth Moore613a1fd2023-01-11 10:42:26 -080063 ) -> Strong<dyn IGetRegistrationCallback> {
Tri Voe8f04442022-12-21 08:53:56 -080064 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080065 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -080066 BnGetRegistrationCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -080067 }
68}
69
70impl Interface for GetRegistrationCallback {}
71
72impl IGetRegistrationCallback for GetRegistrationCallback {
73 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
74 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080075 self.registration_tx.send(Ok(registration.clone()));
76 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080077 }
78 fn onCancel(&self) -> binder::Result<()> {
79 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080080 log::warn!("IGetRegistrationCallback cancelled");
81 self.registration_tx.send(
82 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
83 .context(ks_err!("GetRegistrationCallback cancelled.")),
84 );
85 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080086 }
87 fn onError(&self, error: &str) -> binder::Result<()> {
88 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -080089 log::error!("IGetRegistrationCallback failed: '{error}'");
90 self.registration_tx.send(
91 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
92 .context(ks_err!("GetRegistrationCallback failed: {:?}", error)),
93 );
94 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -080095 }
96}
97
98/// Make a new connection to a IRegistration service.
99async fn get_rkpd_registration(
100 security_level: &SecurityLevel,
101) -> Result<binder::Strong<dyn IRegistration>> {
102 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
103 map_binder_status_code(binder::get_interface("remote_provisioning"))
104 .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
105
106 let rpc_name = get_remotely_provisioned_component_name(security_level)
107 .context(ks_err!("Trying to get IRPC name."))?;
108
109 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800110 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800111
112 remote_provisioning
113 .getRegistration(&rpc_name, &cb)
114 .context(ks_err!("Trying to get registration."))?;
115
116 rx.await.unwrap()
117}
118
Tri Voe8f04442022-12-21 08:53:56 -0800119struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800120 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800121}
122
123impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800124 pub fn new_native_binder(
125 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800126 ) -> Strong<dyn IGetKeyCallback> {
Seth Moorea882c962023-01-09 16:55:10 -0800127 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800128 BnGetKeyCallback::new_binder(result, BinderFeatures::default())
Tri Voe8f04442022-12-21 08:53:56 -0800129 }
130}
131
132impl Interface for GetKeyCallback {}
133
134impl IGetKeyCallback for GetKeyCallback {
135 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
136 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800137 self.key_tx.send(Ok(RemotelyProvisionedKey {
138 keyBlob: key.keyBlob.clone(),
139 encodedCertChain: key.encodedCertChain.clone(),
140 }));
141 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800142 }
143 fn onCancel(&self) -> binder::Result<()> {
144 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800145 log::warn!("IGetKeyCallback cancelled");
146 self.key_tx.send(
147 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
148 .context(ks_err!("GetKeyCallback cancelled.")),
149 );
150 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800151 }
152 fn onError(&self, error: &str) -> binder::Result<()> {
153 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800154 log::error!("IGetKeyCallback failed: {error}");
155 self.key_tx.send(
156 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
157 .context(ks_err!("GetKeyCallback failed: {:?}", error)),
158 );
159 Ok(())
Tri Voe8f04442022-12-21 08:53:56 -0800160 }
161}
162
163async fn get_rkpd_attestation_key_async(
164 security_level: &SecurityLevel,
165 caller_uid: u32,
166) -> Result<RemotelyProvisionedKey> {
167 let registration = get_rkpd_registration(security_level)
168 .await
169 .context(ks_err!("Trying to get to IRegistration service."))?;
170
171 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800172 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800173
174 registration
175 .getKey(caller_uid.try_into().unwrap(), &cb)
176 .context(ks_err!("Trying to get key."))?;
177
178 rx.await.unwrap()
179}
180
Seth Moorea55428e2023-01-10 13:07:31 -0800181struct StoreUpgradedKeyCallback {
182 completer: SafeSender<Result<()>>,
183}
184
185impl StoreUpgradedKeyCallback {
186 pub fn new_native_binder(
187 completer: oneshot::Sender<Result<()>>,
Seth Moore613a1fd2023-01-11 10:42:26 -0800188 ) -> Strong<dyn IStoreUpgradedKeyCallback> {
Seth Moorea55428e2023-01-10 13:07:31 -0800189 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
Seth Moore613a1fd2023-01-11 10:42:26 -0800190 BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default())
Seth Moorea55428e2023-01-10 13:07:31 -0800191 }
192}
193
194impl Interface for StoreUpgradedKeyCallback {}
195
196impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
197 fn onSuccess(&self) -> binder::Result<()> {
198 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800199 self.completer.send(Ok(()));
200 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800201 }
202
203 fn onError(&self, error: &str) -> binder::Result<()> {
204 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
Seth Moore613a1fd2023-01-11 10:42:26 -0800205 log::error!("IGetRegistrationCallback failed: {error}");
206 self.completer.send(
207 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
208 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
209 );
210 Ok(())
Seth Moorea55428e2023-01-10 13:07:31 -0800211 }
212}
213
Tri Voe8f04442022-12-21 08:53:56 -0800214async fn store_rkpd_attestation_key_async(
215 security_level: &SecurityLevel,
216 key_blob: &[u8],
217 upgraded_blob: &[u8],
218) -> Result<()> {
219 let registration = get_rkpd_registration(security_level)
220 .await
221 .context(ks_err!("Trying to get to IRegistration service."))?;
222
Seth Moorea55428e2023-01-10 13:07:31 -0800223 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800224 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800225
Tri Voe8f04442022-12-21 08:53:56 -0800226 registration
Seth Moorea55428e2023-01-10 13:07:31 -0800227 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
Tri Voe8f04442022-12-21 08:53:56 -0800228 .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
Seth Moorea55428e2023-01-10 13:07:31 -0800229
230 rx.await.unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800231}
232
233/// Get attestation key from RKPD.
234pub fn get_rkpd_attestation_key(
235 security_level: &SecurityLevel,
236 caller_uid: u32,
237) -> Result<RemotelyProvisionedKey> {
238 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
239 block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
240}
241
242/// Store attestation key in RKPD.
243pub fn store_rkpd_attestation_key(
244 security_level: &SecurityLevel,
245 key_blob: &[u8],
246 upgraded_blob: &[u8],
247) -> Result<()> {
248 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
249 block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
250}
251
252#[cfg(test)]
253mod tests {
254 use super::*;
255 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
256 use std::sync::Arc;
257
258 #[derive(Default)]
259 struct MockRegistrationValues {
260 _key: RemotelyProvisionedKey,
261 }
262
263 #[derive(Default)]
264 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
265
266 impl MockRegistration {
267 pub fn new_native_binder() -> Strong<dyn IRegistration> {
268 let result: Self = Default::default();
269 BnRegistration::new_binder(result, BinderFeatures::default())
270 }
271 }
272
273 impl Interface for MockRegistration {}
274
275 impl IRegistration for MockRegistration {
276 fn getKey(&self, _: i32, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
277 todo!()
278 }
279
280 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
281 todo!()
282 }
283
Seth Moorea55428e2023-01-10 13:07:31 -0800284 fn storeUpgradedKeyAsync(
285 &self,
286 _: &[u8],
287 _: &[u8],
288 _: &Strong<dyn IStoreUpgradedKeyCallback>,
289 ) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800290 todo!()
291 }
292 }
293
294 fn get_mock_registration() -> Result<binder::Strong<dyn IRegistration>> {
295 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800296 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800297 let mock_registration = MockRegistration::new_native_binder();
298
299 assert!(cb.onSuccess(&mock_registration).is_ok());
300 block_on(rx).unwrap()
301 }
302
303 #[test]
304 fn test_get_registration_cb_success() {
305 let registration = get_mock_registration();
306 assert!(registration.is_ok());
307 }
308
309 #[test]
310 fn test_get_registration_cb_cancel() {
311 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800312 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800313 assert!(cb.onCancel().is_ok());
314
315 let result = block_on(rx).unwrap();
316 assert_eq!(
317 result.unwrap_err().downcast::<Error>().unwrap(),
318 Error::Km(ErrorCode::OPERATION_CANCELLED)
319 );
320 }
321
322 #[test]
323 fn test_get_registration_cb_error() {
324 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800325 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800326 assert!(cb.onError("error").is_ok());
327
328 let result = block_on(rx).unwrap();
329 assert_eq!(
330 result.unwrap_err().downcast::<Error>().unwrap(),
331 Error::Km(ErrorCode::UNKNOWN_ERROR)
332 );
333 }
334
335 #[test]
336 fn test_get_key_cb_success() {
337 let mock_key =
338 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
339 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800340 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800341 assert!(cb.onSuccess(&mock_key).is_ok());
342
343 let key = block_on(rx).unwrap().unwrap();
344 assert_eq!(key, mock_key);
345 }
346
347 #[test]
348 fn test_get_key_cb_cancel() {
349 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800350 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800351 assert!(cb.onCancel().is_ok());
352
353 let result = block_on(rx).unwrap();
354 assert_eq!(
355 result.unwrap_err().downcast::<Error>().unwrap(),
356 Error::Km(ErrorCode::OPERATION_CANCELLED)
357 );
358 }
359
360 #[test]
361 fn test_get_key_cb_error() {
362 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800363 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800364 assert!(cb.onError("error").is_ok());
365
366 let result = block_on(rx).unwrap();
367 assert_eq!(
368 result.unwrap_err().downcast::<Error>().unwrap(),
369 Error::Km(ErrorCode::UNKNOWN_ERROR)
370 );
371 }
372
373 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800374 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800375 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800376 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800377 assert!(cb.onSuccess().is_ok());
378
379 block_on(rx).unwrap().unwrap();
380 }
381
382 #[test]
383 fn test_store_upgraded_key_cb_error() {
384 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800385 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800386 assert!(cb.onError("oh no! it failed").is_ok());
387
388 let result = block_on(rx).unwrap();
389 assert_eq!(
390 result.unwrap_err().downcast::<Error>().unwrap(),
391 Error::Km(ErrorCode::UNKNOWN_ERROR)
392 );
393 }
394
395 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800396 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800397 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800398 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
399 assert!(!key.keyBlob.is_empty());
400 assert!(!key.encodedCertChain.is_empty());
401 }
402
403 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800404 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800405 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800406 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
407 let caller_uid = 0;
408
409 // Multiple calls should return the same key.
410 let first_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
411 let second_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
412
413 assert_eq!(first_key.keyBlob, second_key.keyBlob);
414 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
415 }
416
417 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800418 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800419 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800420 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
421
422 // Different callers should be getting different keys.
423 let first_key = get_rkpd_attestation_key(&sec_level, 1).unwrap();
424 let second_key = get_rkpd_attestation_key(&sec_level, 2).unwrap();
425
426 assert_ne!(first_key.keyBlob, second_key.keyBlob);
427 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
428 }
429
430 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800431 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800432 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800433 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
434 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
435
436 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &key.keyBlob).is_ok());
437 }
438}