blob: d611678c31f9534112eae02af2aa2734c72fa16d [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;
Tri Vo4b1cd822023-01-23 13:05:35 -0800256 use std::sync::atomic::{AtomicU32, Ordering};
Tri Voe8f04442022-12-21 08:53:56 -0800257 use std::sync::Arc;
258
259 #[derive(Default)]
260 struct MockRegistrationValues {
261 _key: RemotelyProvisionedKey,
262 }
263
264 #[derive(Default)]
265 struct MockRegistration(Arc<Mutex<MockRegistrationValues>>);
266
267 impl MockRegistration {
268 pub fn new_native_binder() -> Strong<dyn IRegistration> {
269 let result: Self = Default::default();
270 BnRegistration::new_binder(result, BinderFeatures::default())
271 }
272 }
273
274 impl Interface for MockRegistration {}
275
276 impl IRegistration for MockRegistration {
277 fn getKey(&self, _: i32, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
278 todo!()
279 }
280
281 fn cancelGetKey(&self, _: &Strong<dyn IGetKeyCallback>) -> binder::Result<()> {
282 todo!()
283 }
284
Seth Moorea55428e2023-01-10 13:07:31 -0800285 fn storeUpgradedKeyAsync(
286 &self,
287 _: &[u8],
288 _: &[u8],
289 _: &Strong<dyn IStoreUpgradedKeyCallback>,
290 ) -> binder::Result<()> {
Tri Voe8f04442022-12-21 08:53:56 -0800291 todo!()
292 }
293 }
294
295 fn get_mock_registration() -> Result<binder::Strong<dyn IRegistration>> {
296 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800297 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800298 let mock_registration = MockRegistration::new_native_binder();
299
300 assert!(cb.onSuccess(&mock_registration).is_ok());
301 block_on(rx).unwrap()
302 }
303
Tri Vo4b1cd822023-01-23 13:05:35 -0800304 // Using the same key ID makes test cases race with each other. So, we use separate key IDs for
305 // different test cases.
306 fn get_next_key_id() -> u32 {
307 static ID: AtomicU32 = AtomicU32::new(0);
308 ID.fetch_add(1, Ordering::Relaxed)
309 }
310
Tri Voe8f04442022-12-21 08:53:56 -0800311 #[test]
312 fn test_get_registration_cb_success() {
313 let registration = get_mock_registration();
314 assert!(registration.is_ok());
315 }
316
317 #[test]
318 fn test_get_registration_cb_cancel() {
319 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800320 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800321 assert!(cb.onCancel().is_ok());
322
323 let result = block_on(rx).unwrap();
324 assert_eq!(
325 result.unwrap_err().downcast::<Error>().unwrap(),
326 Error::Km(ErrorCode::OPERATION_CANCELLED)
327 );
328 }
329
330 #[test]
331 fn test_get_registration_cb_error() {
332 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800333 let cb = GetRegistrationCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800334 assert!(cb.onError("error").is_ok());
335
336 let result = block_on(rx).unwrap();
337 assert_eq!(
338 result.unwrap_err().downcast::<Error>().unwrap(),
339 Error::Km(ErrorCode::UNKNOWN_ERROR)
340 );
341 }
342
343 #[test]
344 fn test_get_key_cb_success() {
345 let mock_key =
346 RemotelyProvisionedKey { keyBlob: vec![1, 2, 3], encodedCertChain: vec![4, 5, 6] };
347 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800348 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800349 assert!(cb.onSuccess(&mock_key).is_ok());
350
351 let key = block_on(rx).unwrap().unwrap();
352 assert_eq!(key, mock_key);
353 }
354
355 #[test]
356 fn test_get_key_cb_cancel() {
357 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800358 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800359 assert!(cb.onCancel().is_ok());
360
361 let result = block_on(rx).unwrap();
362 assert_eq!(
363 result.unwrap_err().downcast::<Error>().unwrap(),
364 Error::Km(ErrorCode::OPERATION_CANCELLED)
365 );
366 }
367
368 #[test]
369 fn test_get_key_cb_error() {
370 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800371 let cb = GetKeyCallback::new_native_binder(tx);
Tri Voe8f04442022-12-21 08:53:56 -0800372 assert!(cb.onError("error").is_ok());
373
374 let result = block_on(rx).unwrap();
375 assert_eq!(
376 result.unwrap_err().downcast::<Error>().unwrap(),
377 Error::Km(ErrorCode::UNKNOWN_ERROR)
378 );
379 }
380
381 #[test]
Seth Moore613a1fd2023-01-11 10:42:26 -0800382 fn test_store_upgraded_cb_success() {
Seth Moorea55428e2023-01-10 13:07:31 -0800383 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800384 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800385 assert!(cb.onSuccess().is_ok());
386
387 block_on(rx).unwrap().unwrap();
388 }
389
390 #[test]
391 fn test_store_upgraded_key_cb_error() {
392 let (tx, rx) = oneshot::channel();
Seth Moore613a1fd2023-01-11 10:42:26 -0800393 let cb = StoreUpgradedKeyCallback::new_native_binder(tx);
Seth Moorea55428e2023-01-10 13:07:31 -0800394 assert!(cb.onError("oh no! it failed").is_ok());
395
396 let result = block_on(rx).unwrap();
397 assert_eq!(
398 result.unwrap_err().downcast::<Error>().unwrap(),
399 Error::Km(ErrorCode::UNKNOWN_ERROR)
400 );
401 }
402
403 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800404 fn test_get_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800405 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800406 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, 0).unwrap();
407 assert!(!key.keyBlob.is_empty());
408 assert!(!key.encodedCertChain.is_empty());
409 }
410
411 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800412 fn test_get_rkpd_attestation_key_same_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800413 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800414 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800415 let key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800416
417 // Multiple calls should return the same key.
Tri Vo4b1cd822023-01-23 13:05:35 -0800418 let first_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
419 let second_key = get_rkpd_attestation_key(&sec_level, key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800420
421 assert_eq!(first_key.keyBlob, second_key.keyBlob);
422 assert_eq!(first_key.encodedCertChain, second_key.encodedCertChain);
423 }
424
425 #[test]
Tri Voe8f04442022-12-21 08:53:56 -0800426 fn test_get_rkpd_attestation_key_different_caller() {
Seth Mooref896d362023-01-11 08:06:17 -0800427 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800428 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800429 let first_key_id = get_next_key_id();
430 let second_key_id = get_next_key_id();
Tri Voe8f04442022-12-21 08:53:56 -0800431
432 // Different callers should be getting different keys.
Tri Vo4b1cd822023-01-23 13:05:35 -0800433 let first_key = get_rkpd_attestation_key(&sec_level, first_key_id).unwrap();
434 let second_key = get_rkpd_attestation_key(&sec_level, second_key_id).unwrap();
Tri Voe8f04442022-12-21 08:53:56 -0800435
436 assert_ne!(first_key.keyBlob, second_key.keyBlob);
437 assert_ne!(first_key.encodedCertChain, second_key.encodedCertChain);
438 }
439
440 #[test]
Tri Vobac3b522023-01-23 13:10:24 -0800441 // Couple of things to note:
442 // 1. This test must never run with UID of keystore. Otherwise, it can mess up keys stored by
443 // keystore.
444 // 2. Storing and reading the stored key is prone to race condition. So, we only do this in one
445 // test case.
Tri Voe8f04442022-12-21 08:53:56 -0800446 fn test_store_rkpd_attestation_key() {
Seth Mooref896d362023-01-11 08:06:17 -0800447 binder::ProcessState::start_thread_pool();
Tri Voe8f04442022-12-21 08:53:56 -0800448 let sec_level = SecurityLevel::TRUSTED_ENVIRONMENT;
Tri Vo4b1cd822023-01-23 13:05:35 -0800449 let key_id = get_next_key_id();
450 let key = get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
Tri Vobac3b522023-01-23 13:10:24 -0800451 let new_blob: [u8; 8] = rand::random();
Tri Voe8f04442022-12-21 08:53:56 -0800452
Tri Vobac3b522023-01-23 13:10:24 -0800453 assert!(store_rkpd_attestation_key(&sec_level, &key.keyBlob, &new_blob).is_ok());
454
455 let new_key =
456 get_rkpd_attestation_key(&SecurityLevel::TRUSTED_ENVIRONMENT, key_id).unwrap();
457 assert_eq!(new_key.keyBlob, new_blob);
Tri Voe8f04442022-12-21 08:53:56 -0800458 }
459}