blob: 5eb16beaeed8a428f1783fbcad124d509a836d89 [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
17use crate::error::{map_binder_status_code, map_or_log_err, Error, ErrorCode};
18use 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>>>,
Tri Voe8f04442022-12-21 08:53:56 -080063 ) -> Result<Strong<dyn IGetRegistrationCallback>> {
64 let result: Self =
Seth Moorea882c962023-01-09 16:55:10 -080065 GetRegistrationCallback { registration_tx: SafeSender::new(registration_tx) };
Tri Voe8f04442022-12-21 08:53:56 -080066 Ok(BnGetRegistrationCallback::new_binder(result, BinderFeatures::default()))
67 }
68 fn on_success(&self, registration: &binder::Strong<dyn IRegistration>) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080069 self.registration_tx.send(Ok(registration.clone()));
Tri Voe8f04442022-12-21 08:53:56 -080070 Ok(())
71 }
72 fn on_cancel(&self) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080073 self.registration_tx.send(
74 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
75 .context(ks_err!("GetRegistrationCallback cancelled.")),
76 );
Tri Voe8f04442022-12-21 08:53:56 -080077 Ok(())
78 }
79 fn on_error(&self, error: &str) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -080080 self.registration_tx.send(
81 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
82 .context(ks_err!("GetRegistrationCallback failed: {:?}", error)),
83 );
Tri Voe8f04442022-12-21 08:53:56 -080084 Ok(())
85 }
86}
87
88impl Interface for GetRegistrationCallback {}
89
90impl IGetRegistrationCallback for GetRegistrationCallback {
91 fn onSuccess(&self, registration: &Strong<dyn IRegistration>) -> binder::Result<()> {
92 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
93 map_or_log_err(self.on_success(registration), Ok)
94 }
95 fn onCancel(&self) -> binder::Result<()> {
96 let _wp = wd::watch_millis("IGetRegistrationCallback::onCancel", 500);
97 map_or_log_err(self.on_cancel(), Ok)
98 }
99 fn onError(&self, error: &str) -> binder::Result<()> {
100 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
101 map_or_log_err(self.on_error(error), Ok)
102 }
103}
104
105/// Make a new connection to a IRegistration service.
106async fn get_rkpd_registration(
107 security_level: &SecurityLevel,
108) -> Result<binder::Strong<dyn IRegistration>> {
109 let remote_provisioning: Strong<dyn IRemoteProvisioning> =
110 map_binder_status_code(binder::get_interface("remote_provisioning"))
111 .context(ks_err!("Trying to connect to IRemoteProvisioning service."))?;
112
113 let rpc_name = get_remotely_provisioned_component_name(security_level)
114 .context(ks_err!("Trying to get IRPC name."))?;
115
116 let (tx, rx) = oneshot::channel();
117 let cb = GetRegistrationCallback::new_native_binder(tx)
118 .context(ks_err!("Trying to create a IGetRegistrationCallback."))?;
119
120 remote_provisioning
121 .getRegistration(&rpc_name, &cb)
122 .context(ks_err!("Trying to get registration."))?;
123
124 rx.await.unwrap()
125}
126
Tri Voe8f04442022-12-21 08:53:56 -0800127struct GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800128 key_tx: SafeSender<Result<RemotelyProvisionedKey>>,
Tri Voe8f04442022-12-21 08:53:56 -0800129}
130
131impl GetKeyCallback {
Seth Moorea882c962023-01-09 16:55:10 -0800132 pub fn new_native_binder(
133 key_tx: oneshot::Sender<Result<RemotelyProvisionedKey>>,
134 ) -> Result<Strong<dyn IGetKeyCallback>> {
135 let result: Self = GetKeyCallback { key_tx: SafeSender::new(key_tx) };
Tri Voe8f04442022-12-21 08:53:56 -0800136 Ok(BnGetKeyCallback::new_binder(result, BinderFeatures::default()))
137 }
138 fn on_success(&self, key: &RemotelyProvisionedKey) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800139 self.key_tx.send(Ok(RemotelyProvisionedKey {
140 keyBlob: key.keyBlob.clone(),
141 encodedCertChain: key.encodedCertChain.clone(),
142 }));
Tri Voe8f04442022-12-21 08:53:56 -0800143 Ok(())
144 }
145 fn on_cancel(&self) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800146 self.key_tx.send(
147 Err(Error::Km(ErrorCode::OPERATION_CANCELLED))
148 .context(ks_err!("GetKeyCallback cancelled.")),
149 );
Tri Voe8f04442022-12-21 08:53:56 -0800150 Ok(())
151 }
152 fn on_error(&self, error: &str) -> Result<()> {
Seth Moorea882c962023-01-09 16:55:10 -0800153 self.key_tx.send(
154 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
155 .context(ks_err!("GetKeyCallback failed: {:?}", error)),
156 );
Tri Voe8f04442022-12-21 08:53:56 -0800157 Ok(())
158 }
159}
160
161impl Interface for GetKeyCallback {}
162
163impl IGetKeyCallback for GetKeyCallback {
164 fn onSuccess(&self, key: &RemotelyProvisionedKey) -> binder::Result<()> {
165 let _wp = wd::watch_millis("IGetKeyCallback::onSuccess", 500);
166 map_or_log_err(self.on_success(key), Ok)
167 }
168 fn onCancel(&self) -> binder::Result<()> {
169 let _wp = wd::watch_millis("IGetKeyCallback::onCancel", 500);
170 map_or_log_err(self.on_cancel(), Ok)
171 }
172 fn onError(&self, error: &str) -> binder::Result<()> {
173 let _wp = wd::watch_millis("IGetKeyCallback::onError", 500);
174 map_or_log_err(self.on_error(error), Ok)
175 }
176}
177
178async fn get_rkpd_attestation_key_async(
179 security_level: &SecurityLevel,
180 caller_uid: u32,
181) -> Result<RemotelyProvisionedKey> {
182 let registration = get_rkpd_registration(security_level)
183 .await
184 .context(ks_err!("Trying to get to IRegistration service."))?;
185
186 let (tx, rx) = oneshot::channel();
187 let cb = GetKeyCallback::new_native_binder(tx)
188 .context(ks_err!("Trying to create a IGetKeyCallback."))?;
189
190 registration
191 .getKey(caller_uid.try_into().unwrap(), &cb)
192 .context(ks_err!("Trying to get key."))?;
193
194 rx.await.unwrap()
195}
196
Seth Moorea55428e2023-01-10 13:07:31 -0800197struct StoreUpgradedKeyCallback {
198 completer: SafeSender<Result<()>>,
199}
200
201impl StoreUpgradedKeyCallback {
202 pub fn new_native_binder(
203 completer: oneshot::Sender<Result<()>>,
204 ) -> Result<Strong<dyn IStoreUpgradedKeyCallback>> {
205 let result: Self = StoreUpgradedKeyCallback { completer: SafeSender::new(completer) };
206 Ok(BnStoreUpgradedKeyCallback::new_binder(result, BinderFeatures::default()))
207 }
208
209 fn on_success(&self) -> Result<()> {
210 self.completer.send(Ok(()));
211 Ok(())
212 }
213
214 fn on_error(&self, error: &str) -> Result<()> {
215 self.completer.send(
216 Err(Error::Km(ErrorCode::UNKNOWN_ERROR))
217 .context(ks_err!("Failed to store upgraded key: {:?}", error)),
218 );
219 Ok(())
220 }
221}
222
223impl Interface for StoreUpgradedKeyCallback {}
224
225impl IStoreUpgradedKeyCallback for StoreUpgradedKeyCallback {
226 fn onSuccess(&self) -> binder::Result<()> {
227 let _wp = wd::watch_millis("IGetRegistrationCallback::onSuccess", 500);
228 map_or_log_err(self.on_success(), Ok)
229 }
230
231 fn onError(&self, error: &str) -> binder::Result<()> {
232 let _wp = wd::watch_millis("IGetRegistrationCallback::onError", 500);
233 map_or_log_err(self.on_error(error), Ok)
234 }
235}
236
Tri Voe8f04442022-12-21 08:53:56 -0800237async fn store_rkpd_attestation_key_async(
238 security_level: &SecurityLevel,
239 key_blob: &[u8],
240 upgraded_blob: &[u8],
241) -> Result<()> {
242 let registration = get_rkpd_registration(security_level)
243 .await
244 .context(ks_err!("Trying to get to IRegistration service."))?;
245
Seth Moorea55428e2023-01-10 13:07:31 -0800246 let (tx, rx) = oneshot::channel();
247 let cb = StoreUpgradedKeyCallback::new_native_binder(tx)
248 .context(ks_err!("Trying to create a StoreUpgradedKeyCallback."))?;
249
Tri Voe8f04442022-12-21 08:53:56 -0800250 registration
Seth Moorea55428e2023-01-10 13:07:31 -0800251 .storeUpgradedKeyAsync(key_blob, upgraded_blob, &cb)
Tri Voe8f04442022-12-21 08:53:56 -0800252 .context(ks_err!("Failed to store upgraded blob with RKPD."))?;
Seth Moorea55428e2023-01-10 13:07:31 -0800253
254 rx.await.unwrap()
Tri Voe8f04442022-12-21 08:53:56 -0800255}
256
257/// Get attestation key from RKPD.
258pub fn get_rkpd_attestation_key(
259 security_level: &SecurityLevel,
260 caller_uid: u32,
261) -> Result<RemotelyProvisionedKey> {
262 let _wp = wd::watch_millis("Calling get_rkpd_attestation_key()", 500);
263 block_on(get_rkpd_attestation_key_async(security_level, caller_uid))
264}
265
266/// Store attestation key in RKPD.
267pub fn store_rkpd_attestation_key(
268 security_level: &SecurityLevel,
269 key_blob: &[u8],
270 upgraded_blob: &[u8],
271) -> Result<()> {
272 let _wp = wd::watch_millis("Calling store_rkpd_attestation_key()", 500);
273 block_on(store_rkpd_attestation_key_async(security_level, key_blob, upgraded_blob))
274}
275
276#[cfg(test)]
277mod tests {
278 use super::*;
279 use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
280 use std::sync::Arc;
281
282 #[derive(Default)]
283 struct MockRegistrationValues {
284 _key: RemotelyProvisionedKey,
285 }
286
287 #[derive(Default)]
288 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
289
290 impl MockRegistration {
291 pub fn new_native_binder() -> Strong<dyn IRegistration> {
292 let result: Self = Default::default();
293 BnRegistration::new_binder(result, BinderFeatures::default())
294 }
295 }
296
297 impl Interface for MockRegistration {}
298
299 impl IRegistration for MockRegistration {
300 fn getKey(&self, _: i32, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
301 todo!()
302 }
303
304 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
305 todo!()
306 }
307
Seth Moorea55428e2023-01-10 13:07:31 -0800308 fn storeUpgradedKeyAsync(
309 &self,
310 _: &[u8],
311 _: &[u8],
312 _: &Strong<dyn IStoreUpgradedKeyCallback>,
313 ) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800314 todo!()
315 }
316 }
317
318 fn get_mock_registration() -> Result<binder::Strong<dyn IRegistration>> {
319 let (tx, rx) = oneshot::channel();
320 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
321 let mock_registration = MockRegistration::new_native_binder();
322
323 assert!(cb.onSuccess(&mock_registration).is_ok());
324 block_on(rx).unwrap()
325 }
326
327 #[test]
328 fn test_get_registration_cb_success() {
329 let registration = get_mock_registration();
330 assert!(registration.is_ok());
331 }
332
333 #[test]
334 fn test_get_registration_cb_cancel() {
335 let (tx, rx) = oneshot::channel();
336 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
337 assert!(cb.onCancel().is_ok());
338
339 let result = block_on(rx).unwrap();
340 assert_eq!(
341 result.unwrap_err().downcast::<Error>().unwrap(),
342 Error::Km(ErrorCode::OPERATION_CANCELLED)
343 );
344 }
345
346 #[test]
347 fn test_get_registration_cb_error() {
348 let (tx, rx) = oneshot::channel();
349 let cb = GetRegistrationCallback::new_native_binder(tx).unwrap();
350 assert!(cb.onError("error").is_ok());
351
352 let result = block_on(rx).unwrap();
353 assert_eq!(
354 result.unwrap_err().downcast::<Error>().unwrap(),
355 Error::Km(ErrorCode::UNKNOWN_ERROR)
356 );
357 }
358
359 #[test]
360 fn test_get_key_cb_success() {
361 let mock_key =
362 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
363 let (tx, rx) = oneshot::channel();
364 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
365 assert!(cb.onSuccess(&mock_key).is_ok());
366
367 let key = block_on(rx).unwrap().unwrap();
368 assert_eq!(key, mock_key);
369 }
370
371 #[test]
372 fn test_get_key_cb_cancel() {
373 let (tx, rx) = oneshot::channel();
374 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
375 assert!(cb.onCancel().is_ok());
376
377 let result = block_on(rx).unwrap();
378 assert_eq!(
379 result.unwrap_err().downcast::<Error>().unwrap(),
380 Error::Km(ErrorCode::OPERATION_CANCELLED)
381 );
382 }
383
384 #[test]
385 fn test_get_key_cb_error() {
386 let (tx, rx) = oneshot::channel();
387 let cb = GetKeyCallback::new_native_binder(tx).unwrap();
388 assert!(cb.onError("error").is_ok());
389
390 let result = block_on(rx).unwrap();
391 assert_eq!(
392 result.unwrap_err().downcast::<Error>().unwrap(),
393 Error::Km(ErrorCode::UNKNOWN_ERROR)
394 );
395 }
396
397 #[test]
Seth Moorea55428e2023-01-10 13:07:31 -0800398 fn test_store_upgraded_key_cb_success() {
399 let (tx, rx) = oneshot::channel();
400 let cb = StoreUpgradedKeyCallback::new_native_binder(tx).unwrap();
401 assert!(cb.onSuccess().is_ok());
402
403 block_on(rx).unwrap().unwrap();
404 }
405
406 #[test]
407 fn test_store_upgraded_key_cb_error() {
408 let (tx, rx) = oneshot::channel();
409 let cb = StoreUpgradedKeyCallback::new_native_binder(tx).unwrap();
410 assert!(cb.onError("oh no! it failed").is_ok());
411
412 let result = block_on(rx).unwrap();
413 assert_eq!(
414 result.unwrap_err().downcast::<Error>().unwrap(),
415 Error::Km(ErrorCode::UNKNOWN_ERROR)
416 );
417 }
418
419 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800420 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800421 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800422 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
423 assert!(!key.keyBlob.is_empty());
424 assert!(!key.encodedCertChain.is_empty());
425 }
426
427 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800428 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800429 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800430 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
431 let caller_uid = 0;
432
433 // Multiple calls should return the same key.
434 let first_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
435 let second_key = get_rkpd_attestation_key(&sec_level, caller_uid).unwrap();
436
437 assert_eq!(first_key.keyBlob, second_key.keyBlob);
438 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
439 }
440
441 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800442 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800443 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800444 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
445
446 // Different callers should be getting different keys.
447 let first_key = get_rkpd_attestation_key(&sec_level, 1).unwrap();
448 let second_key = get_rkpd_attestation_key(&sec_level, 2).unwrap();
449
450 assert_ne!(first_key.keyBlob, second_key.keyBlob);
451 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
452 }
453
454 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800455 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800456 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800457 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
458 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
459
460 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &key.keyBlob).is_ok());
461 }
462}