1 // Copyright 2020, 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 //! This crate implements the IKeystoreSecurityLevel interface.
16 
17 use crate::attestation_key_utils::{get_attest_key_info, AttestationKeyInfo};
18 use crate::audit_log::{
19     log_key_deleted, log_key_generated, log_key_imported, log_key_integrity_violation,
20 };
21 use crate::database::{BlobInfo, CertificateInfo, KeyIdGuard};
22 use crate::error::{
23     self, into_logged_binder, map_km_error, wrapped_rkpd_error_to_ks_error, Error, ErrorCode,
24 };
25 use crate::globals::{
26     get_remotely_provisioned_component_name, DB, ENFORCEMENTS, LEGACY_IMPORTER, SUPER_KEY,
27 };
28 use crate::key_parameter::KeyParameter as KsKeyParam;
29 use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
30 use crate::ks_err;
31 use crate::metrics_store::log_key_creation_event_stats;
32 use crate::remote_provisioning::RemProvState;
33 use crate::super_key::{KeyBlob, SuperKeyManager};
34 use crate::utils::{
35     check_device_attestation_permissions, check_key_permission,
36     check_unique_id_attestation_permissions, is_device_id_attestation_tag,
37     key_characteristics_to_internal, uid_to_android_user, watchdog as wd, UNDEFINED_NOT_AFTER,
38 };
39 use crate::{
40     database::{
41         BlobMetaData, BlobMetaEntry, DateTime, KeyEntry, KeyEntryLoadBits, KeyMetaData,
42         KeyMetaEntry, KeyType, SubComponentType, Uuid,
43     },
44     operation::KeystoreOperation,
45     operation::LoggingInfo,
46     operation::OperationDb,
47     permission::KeyPerm,
48 };
49 use crate::{globals::get_keymint_device, id_rotation::IdRotationState};
50 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
51     Algorithm::Algorithm, AttestationKey::AttestationKey,
52     HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
53     KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
54     KeyMintHardwareInfo::KeyMintHardwareInfo, KeyParameter::KeyParameter,
55     KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
56 };
57 use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
58 use android_system_keystore2::aidl::android::system::keystore2::{
59     AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
60     Domain::Domain, EphemeralStorageKeyResponse::EphemeralStorageKeyResponse,
61     IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
62     IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
63     KeyMetadata::KeyMetadata, KeyParameters::KeyParameters, ResponseCode::ResponseCode,
64 };
65 use anyhow::{anyhow, Context, Result};
66 use rkpd_client::store_rkpd_attestation_key;
67 use std::convert::TryInto;
68 use std::time::SystemTime;
69 
70 /// Implementation of the IKeystoreSecurityLevel Interface.
71 pub struct KeystoreSecurityLevel {
72     security_level: SecurityLevel,
73     keymint: Strong<dyn IKeyMintDevice>,
74     hw_info: KeyMintHardwareInfo,
75     km_uuid: Uuid,
76     operation_db: OperationDb,
77     rem_prov_state: RemProvState,
78     id_rotation_state: IdRotationState,
79 }
80 
81 // Blob of 32 zeroes used as empty masking key.
82 static ZERO_BLOB_32: &[u8] = &[0; 32];
83 
84 impl KeystoreSecurityLevel {
85     /// Creates a new security level instance wrapped in a
86     /// BnKeystoreSecurityLevel proxy object. It also enables
87     /// `BinderFeatures::set_requesting_sid` on the new interface, because
88     /// we need it for checking keystore permissions.
new_native_binder( security_level: SecurityLevel, id_rotation_state: IdRotationState, ) -> Result<(Strong<dyn IKeystoreSecurityLevel>, Uuid)>89     pub fn new_native_binder(
90         security_level: SecurityLevel,
91         id_rotation_state: IdRotationState,
92     ) -> Result<(Strong<dyn IKeystoreSecurityLevel>, Uuid)> {
93         let (dev, hw_info, km_uuid) = get_keymint_device(&security_level)
94             .context(ks_err!("KeystoreSecurityLevel::new_native_binder."))?;
95         let result = BnKeystoreSecurityLevel::new_binder(
96             Self {
97                 security_level,
98                 keymint: dev,
99                 hw_info,
100                 km_uuid,
101                 operation_db: OperationDb::new(),
102                 rem_prov_state: RemProvState::new(security_level),
103                 id_rotation_state,
104             },
105             BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
106         );
107         Ok((result, km_uuid))
108     }
109 
watch_millis(&self, id: &'static str, millis: u64) -> Option<wd::WatchPoint>110     fn watch_millis(&self, id: &'static str, millis: u64) -> Option<wd::WatchPoint> {
111         let sec_level = self.security_level;
112         wd::watch_millis_with(id, millis, move || format!("SecurityLevel {:?}", sec_level))
113     }
114 
watch(&self, id: &'static str) -> Option<wd::WatchPoint>115     fn watch(&self, id: &'static str) -> Option<wd::WatchPoint> {
116         let sec_level = self.security_level;
117         wd::watch_millis_with(id, wd::DEFAULT_TIMEOUT_MS, move || {
118             format!("SecurityLevel {:?}", sec_level)
119         })
120     }
121 
store_new_key( &self, key: KeyDescriptor, creation_result: KeyCreationResult, user_id: u32, flags: Option<i32>, ) -> Result<KeyMetadata>122     fn store_new_key(
123         &self,
124         key: KeyDescriptor,
125         creation_result: KeyCreationResult,
126         user_id: u32,
127         flags: Option<i32>,
128     ) -> Result<KeyMetadata> {
129         let KeyCreationResult {
130             keyBlob: key_blob,
131             keyCharacteristics: key_characteristics,
132             certificateChain: mut certificate_chain,
133         } = creation_result;
134 
135         let mut cert_info: CertificateInfo = CertificateInfo::new(
136             match certificate_chain.len() {
137                 0 => None,
138                 _ => Some(certificate_chain.remove(0).encodedCertificate),
139             },
140             match certificate_chain.len() {
141                 0 => None,
142                 _ => Some(
143                     certificate_chain
144                         .iter()
145                         .flat_map(|c| c.encodedCertificate.iter())
146                         .copied()
147                         .collect(),
148                 ),
149             },
150         );
151 
152         let mut key_parameters = key_characteristics_to_internal(key_characteristics);
153 
154         key_parameters.push(KsKeyParam::new(
155             KsKeyParamValue::UserID(user_id as i32),
156             SecurityLevel::SOFTWARE,
157         ));
158 
159         let creation_date = DateTime::now().context(ks_err!("Trying to make creation time."))?;
160 
161         let key = match key.domain {
162             Domain::BLOB => KeyDescriptor {
163                 domain: Domain::BLOB,
164                 blob: Some(key_blob.to_vec()),
165                 ..Default::default()
166             },
167             _ => DB
168                 .with::<_, Result<KeyDescriptor>>(|db| {
169                     let mut db = db.borrow_mut();
170 
171                     let (key_blob, mut blob_metadata) = SUPER_KEY
172                         .read()
173                         .unwrap()
174                         .handle_super_encryption_on_key_init(
175                             &mut db,
176                             &LEGACY_IMPORTER,
177                             &(key.domain),
178                             &key_parameters,
179                             flags,
180                             user_id,
181                             &key_blob,
182                         )
183                         .context(ks_err!("Failed to handle super encryption."))?;
184 
185                     let mut key_metadata = KeyMetaData::new();
186                     key_metadata.add(KeyMetaEntry::CreationDate(creation_date));
187                     blob_metadata.add(BlobMetaEntry::KmUuid(self.km_uuid));
188 
189                     let key_id = db
190                         .store_new_key(
191                             &key,
192                             KeyType::Client,
193                             &key_parameters,
194                             &BlobInfo::new(&key_blob, &blob_metadata),
195                             &cert_info,
196                             &key_metadata,
197                             &self.km_uuid,
198                         )
199                         .context(ks_err!())?;
200                     Ok(KeyDescriptor {
201                         domain: Domain::KEY_ID,
202                         nspace: key_id.id(),
203                         ..Default::default()
204                     })
205                 })
206                 .context(ks_err!())?,
207         };
208 
209         Ok(KeyMetadata {
210             key,
211             keySecurityLevel: self.security_level,
212             certificate: cert_info.take_cert(),
213             certificateChain: cert_info.take_cert_chain(),
214             authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
215             modificationTimeMs: creation_date.to_millis_epoch(),
216         })
217     }
218 
create_operation( &self, key: &KeyDescriptor, operation_parameters: &[KeyParameter], forced: bool, ) -> Result<CreateOperationResponse>219     fn create_operation(
220         &self,
221         key: &KeyDescriptor,
222         operation_parameters: &[KeyParameter],
223         forced: bool,
224     ) -> Result<CreateOperationResponse> {
225         let caller_uid = ThreadState::get_calling_uid();
226         // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
227         // so that we can use it by reference like the blob provided by the key descriptor.
228         // Otherwise, we would have to clone the blob from the key descriptor.
229         let scoping_blob: Vec<u8>;
230         let (km_blob, key_properties, key_id_guard, blob_metadata) = match key.domain {
231             Domain::BLOB => {
232                 check_key_permission(KeyPerm::Use, key, &None)
233                     .context(ks_err!("checking use permission for Domain::BLOB."))?;
234                 if forced {
235                     check_key_permission(KeyPerm::ReqForcedOp, key, &None)
236                         .context(ks_err!("checking forced permission for Domain::BLOB."))?;
237                 }
238                 (
239                     match &key.blob {
240                         Some(blob) => blob,
241                         None => {
242                             return Err(Error::sys()).context(ks_err!(
243                                 "Key blob must be specified when \
244                                 using Domain::BLOB."
245                             ));
246                         }
247                     },
248                     None,
249                     None,
250                     BlobMetaData::new(),
251                 )
252             }
253             _ => {
254                 let super_key = SUPER_KEY
255                     .read()
256                     .unwrap()
257                     .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
258                 let (key_id_guard, mut key_entry) = DB
259                     .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
260                         LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
261                             db.borrow_mut().load_key_entry(
262                                 key,
263                                 KeyType::Client,
264                                 KeyEntryLoadBits::KM,
265                                 caller_uid,
266                                 |k, av| {
267                                     check_key_permission(KeyPerm::Use, k, &av)?;
268                                     if forced {
269                                         check_key_permission(KeyPerm::ReqForcedOp, k, &av)?;
270                                     }
271                                     Ok(())
272                                 },
273                             )
274                         })
275                     })
276                     .context(ks_err!("Failed to load key blob."))?;
277 
278                 let (blob, blob_metadata) =
279                     key_entry.take_key_blob_info().ok_or_else(Error::sys).context(ks_err!(
280                         "Successfully loaded key entry, \
281                         but KM blob was missing."
282                     ))?;
283                 scoping_blob = blob;
284 
285                 (
286                     &scoping_blob,
287                     Some((key_id_guard.id(), key_entry.into_key_parameters())),
288                     Some(key_id_guard),
289                     blob_metadata,
290                 )
291             }
292         };
293 
294         let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
295             Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
296                 .context(ks_err!("No operation purpose specified.")),
297             |kp| match kp.value {
298                 KeyParameterValue::KeyPurpose(p) => Ok(p),
299                 _ => Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
300                     .context(ks_err!("Malformed KeyParameter.")),
301             },
302         )?;
303 
304         // Remove Tag::PURPOSE from the operation_parameters, since some keymaster devices return
305         // an error on begin() if Tag::PURPOSE is in the operation_parameters.
306         let op_params: Vec<KeyParameter> =
307             operation_parameters.iter().filter(|p| p.tag != Tag::PURPOSE).cloned().collect();
308         let operation_parameters = op_params.as_slice();
309 
310         let (immediate_hat, mut auth_info) = ENFORCEMENTS
311             .authorize_create(
312                 purpose,
313                 key_properties.as_ref(),
314                 operation_parameters.as_ref(),
315                 self.hw_info.timestampTokenRequired,
316             )
317             .context(ks_err!())?;
318 
319         let km_blob = SUPER_KEY
320             .read()
321             .unwrap()
322             .unwrap_key_if_required(&blob_metadata, km_blob)
323             .context(ks_err!("Failed to handle super encryption."))?;
324 
325         let (begin_result, upgraded_blob) = self
326             .upgrade_keyblob_if_required_with(
327                 key_id_guard,
328                 &km_blob,
329                 blob_metadata.km_uuid().copied(),
330                 operation_parameters,
331                 |blob| loop {
332                     match map_km_error({
333                         let _wp =
334                             self.watch("In KeystoreSecurityLevel::create_operation: calling begin");
335                         self.keymint.begin(
336                             purpose,
337                             blob,
338                             operation_parameters,
339                             immediate_hat.as_ref(),
340                         )
341                     }) {
342                         Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
343                             self.operation_db.prune(caller_uid, forced)?;
344                             continue;
345                         }
346                         v @ Err(Error::Km(ErrorCode::INVALID_KEY_BLOB)) => {
347                             if let Some((key_id, _)) = key_properties {
348                                 if let Ok(Some(key)) =
349                                     DB.with(|db| db.borrow_mut().load_key_descriptor(key_id))
350                                 {
351                                     log_key_integrity_violation(&key);
352                                 } else {
353                                     log::error!("Failed to load key descriptor for audit log");
354                                 }
355                             }
356                             return v;
357                         }
358                         v => return v,
359                     }
360                 },
361             )
362             .context(ks_err!("Failed to begin operation."))?;
363 
364         let operation_challenge = auth_info.finalize_create_authorization(begin_result.challenge);
365 
366         let op_params: Vec<KeyParameter> = operation_parameters.to_vec();
367 
368         let operation = match begin_result.operation {
369             Some(km_op) => self.operation_db.create_operation(
370                 km_op,
371                 caller_uid,
372                 auth_info,
373                 forced,
374                 LoggingInfo::new(self.security_level, purpose, op_params, upgraded_blob.is_some()),
375             ),
376             None => {
377                 return Err(Error::sys()).context(ks_err!(
378                     "Begin operation returned successfully, \
379                     but did not return a valid operation."
380                 ));
381             }
382         };
383 
384         let op_binder: binder::Strong<dyn IKeystoreOperation> =
385             KeystoreOperation::new_native_binder(operation)
386                 .as_binder()
387                 .into_interface()
388                 .context(ks_err!("Failed to create IKeystoreOperation."))?;
389 
390         Ok(CreateOperationResponse {
391             iOperation: Some(op_binder),
392             operationChallenge: operation_challenge,
393             parameters: match begin_result.params.len() {
394                 0 => None,
395                 _ => Some(KeyParameters { keyParameter: begin_result.params }),
396             },
397             // An upgraded blob should only be returned if the caller has permission
398             // to use Domain::BLOB keys. If we got to this point, we already checked
399             // that the caller had that permission.
400             upgradedBlob: if key.domain == Domain::BLOB { upgraded_blob } else { None },
401         })
402     }
403 
add_required_parameters( &self, uid: u32, params: &[KeyParameter], key: &KeyDescriptor, ) -> Result<Vec<KeyParameter>>404     fn add_required_parameters(
405         &self,
406         uid: u32,
407         params: &[KeyParameter],
408         key: &KeyDescriptor,
409     ) -> Result<Vec<KeyParameter>> {
410         let mut result = params.to_vec();
411 
412         // Prevent callers from specifying the CREATION_DATETIME tag.
413         if params.iter().any(|kp| kp.tag == Tag::CREATION_DATETIME) {
414             return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!(
415                 "KeystoreSecurityLevel::add_required_parameters: \
416                 Specifying Tag::CREATION_DATETIME is not allowed."
417             ));
418         }
419 
420         // Use this variable to refer to notion of "now". This eliminates discrepancies from
421         // quering the clock multiple times.
422         let creation_datetime = SystemTime::now();
423 
424         // Add CREATION_DATETIME only if the backend version Keymint V1 (100) or newer.
425         if self.hw_info.versionNumber >= 100 {
426             result.push(KeyParameter {
427                 tag: Tag::CREATION_DATETIME,
428                 value: KeyParameterValue::DateTime(
429                     creation_datetime
430                         .duration_since(SystemTime::UNIX_EPOCH)
431                         .context(ks_err!(
432                             "KeystoreSecurityLevel::add_required_parameters: \
433                                 Failed to get epoch time."
434                         ))?
435                         .as_millis()
436                         .try_into()
437                         .context(ks_err!(
438                             "KeystoreSecurityLevel::add_required_parameters: \
439                                 Failed to convert epoch time."
440                         ))?,
441                 ),
442             });
443         }
444 
445         // If there is an attestation challenge we need to get an application id.
446         if params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
447             let aaid = {
448                 let _wp = self
449                     .watch("In KeystoreSecurityLevel::add_required_parameters calling: get_aaid");
450                 keystore2_aaid::get_aaid(uid)
451                     .map_err(|e| anyhow!(ks_err!("get_aaid returned status {}.", e)))
452             }?;
453 
454             result.push(KeyParameter {
455                 tag: Tag::ATTESTATION_APPLICATION_ID,
456                 value: KeyParameterValue::Blob(aaid),
457             });
458         }
459 
460         if params.iter().any(|kp| kp.tag == Tag::INCLUDE_UNIQUE_ID) {
461             if check_key_permission(KeyPerm::GenUniqueId, key, &None).is_err()
462                 && check_unique_id_attestation_permissions().is_err()
463             {
464                 return Err(Error::perm()).context(ks_err!(
465                     "Caller does not have the permission to generate a unique ID"
466                 ));
467             }
468             if self
469                 .id_rotation_state
470                 .had_factory_reset_since_id_rotation(&creation_datetime)
471                 .context(ks_err!("Call to had_factory_reset_since_id_rotation failed."))?
472             {
473                 result.push(KeyParameter {
474                     tag: Tag::RESET_SINCE_ID_ROTATION,
475                     value: KeyParameterValue::BoolValue(true),
476                 })
477             }
478         }
479 
480         // If the caller requests any device identifier attestation tag, check that they hold the
481         // correct Android permission.
482         if params.iter().any(|kp| is_device_id_attestation_tag(kp.tag)) {
483             check_device_attestation_permissions().context(ks_err!(
484                 "Caller does not have the permission to attest device identifiers."
485             ))?;
486         }
487 
488         // If we are generating/importing an asymmetric key, we need to make sure
489         // that NOT_BEFORE and NOT_AFTER are present.
490         match params.iter().find(|kp| kp.tag == Tag::ALGORITHM) {
491             Some(KeyParameter { tag: _, value: KeyParameterValue::Algorithm(Algorithm::RSA) })
492             | Some(KeyParameter { tag: _, value: KeyParameterValue::Algorithm(Algorithm::EC) }) => {
493                 if !params.iter().any(|kp| kp.tag == Tag::CERTIFICATE_NOT_BEFORE) {
494                     result.push(KeyParameter {
495                         tag: Tag::CERTIFICATE_NOT_BEFORE,
496                         value: KeyParameterValue::DateTime(0),
497                     })
498                 }
499                 if !params.iter().any(|kp| kp.tag == Tag::CERTIFICATE_NOT_AFTER) {
500                     result.push(KeyParameter {
501                         tag: Tag::CERTIFICATE_NOT_AFTER,
502                         value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
503                     })
504                 }
505             }
506             _ => {}
507         }
508         Ok(result)
509     }
510 
generate_key( &self, key: &KeyDescriptor, attest_key_descriptor: Option<&KeyDescriptor>, params: &[KeyParameter], flags: i32, _entropy: &[u8], ) -> Result<KeyMetadata>511     fn generate_key(
512         &self,
513         key: &KeyDescriptor,
514         attest_key_descriptor: Option<&KeyDescriptor>,
515         params: &[KeyParameter],
516         flags: i32,
517         _entropy: &[u8],
518     ) -> Result<KeyMetadata> {
519         if key.domain != Domain::BLOB && key.alias.is_none() {
520             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
521                 .context(ks_err!("Alias must be specified"));
522         }
523         let caller_uid = ThreadState::get_calling_uid();
524 
525         let key = match key.domain {
526             Domain::APP => KeyDescriptor {
527                 domain: key.domain,
528                 nspace: caller_uid as i64,
529                 alias: key.alias.clone(),
530                 blob: None,
531             },
532             _ => key.clone(),
533         };
534 
535         // generate_key requires the rebind permission.
536         // Must return on error for security reasons.
537         check_key_permission(KeyPerm::Rebind, &key, &None).context(ks_err!())?;
538 
539         let attestation_key_info = match (key.domain, attest_key_descriptor) {
540             (Domain::BLOB, _) => None,
541             _ => DB
542                 .with(|db| {
543                     get_attest_key_info(
544                         &key,
545                         caller_uid,
546                         attest_key_descriptor,
547                         params,
548                         &self.rem_prov_state,
549                         &mut db.borrow_mut(),
550                     )
551                 })
552                 .context(ks_err!("Trying to get an attestation key"))?,
553         };
554         let params = self
555             .add_required_parameters(caller_uid, params, &key)
556             .context(ks_err!("Trying to get aaid."))?;
557 
558         let creation_result = match attestation_key_info {
559             Some(AttestationKeyInfo::UserGenerated {
560                 key_id_guard,
561                 blob,
562                 blob_metadata,
563                 issuer_subject,
564             }) => self
565                 .upgrade_keyblob_if_required_with(
566                     Some(key_id_guard),
567                     &KeyBlob::Ref(&blob),
568                     blob_metadata.km_uuid().copied(),
569                     &params,
570                     |blob| {
571                         let attest_key = Some(AttestationKey {
572                             keyBlob: blob.to_vec(),
573                             attestKeyParams: vec![],
574                             issuerSubjectName: issuer_subject.clone(),
575                         });
576                         map_km_error({
577                             let _wp = self.watch_millis(
578                                 concat!(
579                                     "In KeystoreSecurityLevel::generate_key (UserGenerated): ",
580                                     "calling generate_key."
581                                 ),
582                                 5000, // Generate can take a little longer.
583                             );
584                             self.keymint.generateKey(&params, attest_key.as_ref())
585                         })
586                     },
587                 )
588                 .context(ks_err!("Using user generated attestation key."))
589                 .map(|(result, _)| result),
590             Some(AttestationKeyInfo::RkpdProvisioned { attestation_key, attestation_certs }) => {
591                 self.upgrade_rkpd_keyblob_if_required_with(&attestation_key.keyBlob, &[], |blob| {
592                     map_km_error({
593                         let _wp = self.watch_millis(
594                             concat!(
595                                 "In KeystoreSecurityLevel::generate_key (RkpdProvisioned): ",
596                                 "calling generate_key.",
597                             ),
598                             5000, // Generate can take a little longer.
599                         );
600                         let dynamic_attest_key = Some(AttestationKey {
601                             keyBlob: blob.to_vec(),
602                             attestKeyParams: vec![],
603                             issuerSubjectName: attestation_key.issuerSubjectName.clone(),
604                         });
605                         self.keymint.generateKey(&params, dynamic_attest_key.as_ref())
606                     })
607                 })
608                 .context(ks_err!("While generating Key with remote provisioned attestation key."))
609                 .map(|(mut result, _)| {
610                     result.certificateChain.push(attestation_certs);
611                     result
612                 })
613             }
614             None => map_km_error({
615                 let _wp = self.watch_millis(
616                     concat!(
617                         "In KeystoreSecurityLevel::generate_key (No attestation): ",
618                         "calling generate_key.",
619                     ),
620                     5000, // Generate can take a little longer.
621                 );
622                 self.keymint.generateKey(&params, None)
623             })
624             .context(ks_err!("While generating Key without explicit attestation key.")),
625         }
626         .context(ks_err!())?;
627 
628         let user_id = uid_to_android_user(caller_uid);
629         self.store_new_key(key, creation_result, user_id, Some(flags)).context(ks_err!())
630     }
631 
import_key( &self, key: &KeyDescriptor, _attestation_key: Option<&KeyDescriptor>, params: &[KeyParameter], flags: i32, key_data: &[u8], ) -> Result<KeyMetadata>632     fn import_key(
633         &self,
634         key: &KeyDescriptor,
635         _attestation_key: Option<&KeyDescriptor>,
636         params: &[KeyParameter],
637         flags: i32,
638         key_data: &[u8],
639     ) -> Result<KeyMetadata> {
640         if key.domain != Domain::BLOB && key.alias.is_none() {
641             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
642                 .context(ks_err!("Alias must be specified"));
643         }
644         let caller_uid = ThreadState::get_calling_uid();
645 
646         let key = match key.domain {
647             Domain::APP => KeyDescriptor {
648                 domain: key.domain,
649                 nspace: caller_uid as i64,
650                 alias: key.alias.clone(),
651                 blob: None,
652             },
653             _ => key.clone(),
654         };
655 
656         // import_key requires the rebind permission.
657         check_key_permission(KeyPerm::Rebind, &key, &None).context(ks_err!("In import_key."))?;
658 
659         let params = self
660             .add_required_parameters(caller_uid, params, &key)
661             .context(ks_err!("Trying to get aaid."))?;
662 
663         let format = params
664             .iter()
665             .find(|p| p.tag == Tag::ALGORITHM)
666             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
667             .context(ks_err!("No KeyParameter 'Algorithm'."))
668             .and_then(|p| match &p.value {
669                 KeyParameterValue::Algorithm(Algorithm::AES)
670                 | KeyParameterValue::Algorithm(Algorithm::HMAC)
671                 | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES) => Ok(KeyFormat::RAW),
672                 KeyParameterValue::Algorithm(Algorithm::RSA)
673                 | KeyParameterValue::Algorithm(Algorithm::EC) => Ok(KeyFormat::PKCS8),
674                 v => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
675                     .context(ks_err!("Unknown Algorithm {:?}.", v)),
676             })
677             .context(ks_err!())?;
678 
679         let km_dev = &self.keymint;
680         let creation_result = map_km_error({
681             let _wp = self.watch("In KeystoreSecurityLevel::import_key: calling importKey.");
682             km_dev.importKey(&params, format, key_data, None /* attestKey */)
683         })
684         .context(ks_err!("Trying to call importKey"))?;
685 
686         let user_id = uid_to_android_user(caller_uid);
687         self.store_new_key(key, creation_result, user_id, Some(flags)).context(ks_err!())
688     }
689 
import_wrapped_key( &self, key: &KeyDescriptor, wrapping_key: &KeyDescriptor, masking_key: Option<&[u8]>, params: &[KeyParameter], authenticators: &[AuthenticatorSpec], ) -> Result<KeyMetadata>690     fn import_wrapped_key(
691         &self,
692         key: &KeyDescriptor,
693         wrapping_key: &KeyDescriptor,
694         masking_key: Option<&[u8]>,
695         params: &[KeyParameter],
696         authenticators: &[AuthenticatorSpec],
697     ) -> Result<KeyMetadata> {
698         let wrapped_data: &[u8] = match key {
699             KeyDescriptor { domain: Domain::APP, blob: Some(ref blob), alias: Some(_), .. }
700             | KeyDescriptor {
701                 domain: Domain::SELINUX, blob: Some(ref blob), alias: Some(_), ..
702             } => blob,
703             _ => {
704                 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(ks_err!(
705                     "Alias and blob must be specified and domain must be APP or SELINUX. {:?}",
706                     key
707                 ));
708             }
709         };
710 
711         if wrapping_key.domain == Domain::BLOB {
712             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
713                 .context(ks_err!("Import wrapped key not supported for self managed blobs."));
714         }
715 
716         let caller_uid = ThreadState::get_calling_uid();
717         let user_id = uid_to_android_user(caller_uid);
718 
719         let key = match key.domain {
720             Domain::APP => KeyDescriptor {
721                 domain: key.domain,
722                 nspace: caller_uid as i64,
723                 alias: key.alias.clone(),
724                 blob: None,
725             },
726             Domain::SELINUX => KeyDescriptor {
727                 domain: Domain::SELINUX,
728                 nspace: key.nspace,
729                 alias: key.alias.clone(),
730                 blob: None,
731             },
732             _ => panic!("Unreachable."),
733         };
734 
735         // Import_wrapped_key requires the rebind permission for the new key.
736         check_key_permission(KeyPerm::Rebind, &key, &None).context(ks_err!())?;
737 
738         let super_key = SUPER_KEY.read().unwrap().get_after_first_unlock_key_by_user_id(user_id);
739 
740         let (wrapping_key_id_guard, mut wrapping_key_entry) = DB
741             .with(|db| {
742                 LEGACY_IMPORTER.with_try_import(&key, caller_uid, super_key, || {
743                     db.borrow_mut().load_key_entry(
744                         wrapping_key,
745                         KeyType::Client,
746                         KeyEntryLoadBits::KM,
747                         caller_uid,
748                         |k, av| check_key_permission(KeyPerm::Use, k, &av),
749                     )
750                 })
751             })
752             .context(ks_err!("Failed to load wrapping key."))?;
753 
754         let (wrapping_key_blob, wrapping_blob_metadata) =
755             wrapping_key_entry.take_key_blob_info().ok_or_else(error::Error::sys).context(
756                 ks_err!("No km_blob after successfully loading key. This should never happen."),
757             )?;
758 
759         let wrapping_key_blob = SUPER_KEY
760             .read()
761             .unwrap()
762             .unwrap_key_if_required(&wrapping_blob_metadata, &wrapping_key_blob)
763             .context(ks_err!("Failed to handle super encryption for wrapping key."))?;
764 
765         // km_dev.importWrappedKey does not return a certificate chain.
766         // TODO Do we assume that all wrapped keys are symmetric?
767         // let certificate_chain: Vec<KmCertificate> = Default::default();
768 
769         let pw_sid = authenticators
770             .iter()
771             .find_map(|a| match a.authenticatorType {
772                 HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
773                 _ => None,
774             })
775             .unwrap_or(-1);
776 
777         let fp_sid = authenticators
778             .iter()
779             .find_map(|a| match a.authenticatorType {
780                 HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
781                 _ => None,
782             })
783             .unwrap_or(-1);
784 
785         let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
786 
787         let (creation_result, _) = self
788             .upgrade_keyblob_if_required_with(
789                 Some(wrapping_key_id_guard),
790                 &wrapping_key_blob,
791                 wrapping_blob_metadata.km_uuid().copied(),
792                 &[],
793                 |wrapping_blob| {
794                     let _wp = self.watch(
795                         "In KeystoreSecurityLevel::import_wrapped_key: calling importWrappedKey.",
796                     );
797                     let creation_result = map_km_error(self.keymint.importWrappedKey(
798                         wrapped_data,
799                         wrapping_blob,
800                         masking_key,
801                         params,
802                         pw_sid,
803                         fp_sid,
804                     ))?;
805                     Ok(creation_result)
806                 },
807             )
808             .context(ks_err!())?;
809 
810         self.store_new_key(key, creation_result, user_id, None)
811             .context(ks_err!("Trying to store the new key."))
812     }
813 
store_upgraded_keyblob( key_id_guard: KeyIdGuard, km_uuid: Option<Uuid>, key_blob: &KeyBlob, upgraded_blob: &[u8], ) -> Result<()>814     fn store_upgraded_keyblob(
815         key_id_guard: KeyIdGuard,
816         km_uuid: Option<Uuid>,
817         key_blob: &KeyBlob,
818         upgraded_blob: &[u8],
819     ) -> Result<()> {
820         let (upgraded_blob_to_be_stored, new_blob_metadata) =
821             SuperKeyManager::reencrypt_if_required(key_blob, upgraded_blob)
822                 .context(ks_err!("Failed to handle super encryption."))?;
823 
824         let mut new_blob_metadata = new_blob_metadata.unwrap_or_default();
825         if let Some(uuid) = km_uuid {
826             new_blob_metadata.add(BlobMetaEntry::KmUuid(uuid));
827         }
828 
829         DB.with(|db| {
830             let mut db = db.borrow_mut();
831             db.set_blob(
832                 &key_id_guard,
833                 SubComponentType::KEY_BLOB,
834                 Some(&upgraded_blob_to_be_stored),
835                 Some(&new_blob_metadata),
836             )
837         })
838         .context(ks_err!("Failed to insert upgraded blob into the database."))
839     }
840 
upgrade_keyblob_if_required_with<T, F>( &self, mut key_id_guard: Option<KeyIdGuard>, key_blob: &KeyBlob, km_uuid: Option<Uuid>, params: &[KeyParameter], f: F, ) -> Result<(T, Option<Vec<u8>>)> where F: Fn(&[u8]) -> Result<T, Error>,841     fn upgrade_keyblob_if_required_with<T, F>(
842         &self,
843         mut key_id_guard: Option<KeyIdGuard>,
844         key_blob: &KeyBlob,
845         km_uuid: Option<Uuid>,
846         params: &[KeyParameter],
847         f: F,
848     ) -> Result<(T, Option<Vec<u8>>)>
849     where
850         F: Fn(&[u8]) -> Result<T, Error>,
851     {
852         let (v, upgraded_blob) = crate::utils::upgrade_keyblob_if_required_with(
853             &*self.keymint,
854             self.hw_info.versionNumber,
855             key_blob,
856             params,
857             f,
858             |upgraded_blob| {
859                 if key_id_guard.is_some() {
860                     // Unwrap cannot panic, because the is_some was true.
861                     let kid = key_id_guard.take().unwrap();
862                     Self::store_upgraded_keyblob(kid, km_uuid, key_blob, upgraded_blob)
863                         .context(ks_err!("store_upgraded_keyblob failed"))
864                 } else {
865                     Ok(())
866                 }
867             },
868         )
869         .context(ks_err!())?;
870 
871         // If no upgrade was needed, use the opportunity to reencrypt the blob if required
872         // and if the a key_id_guard is held. Note: key_id_guard can only be Some if no
873         // upgrade was performed above and if one was given in the first place.
874         if key_blob.force_reencrypt() {
875             if let Some(kid) = key_id_guard {
876                 Self::store_upgraded_keyblob(kid, km_uuid, key_blob, key_blob)
877                     .context(ks_err!("store_upgraded_keyblob failed in forced reencrypt"))?;
878             }
879         }
880         Ok((v, upgraded_blob))
881     }
882 
upgrade_rkpd_keyblob_if_required_with<T, F>( &self, key_blob: &[u8], params: &[KeyParameter], f: F, ) -> Result<(T, Option<Vec<u8>>)> where F: Fn(&[u8]) -> Result<T, Error>,883     fn upgrade_rkpd_keyblob_if_required_with<T, F>(
884         &self,
885         key_blob: &[u8],
886         params: &[KeyParameter],
887         f: F,
888     ) -> Result<(T, Option<Vec<u8>>)>
889     where
890         F: Fn(&[u8]) -> Result<T, Error>,
891     {
892         let rpc_name = get_remotely_provisioned_component_name(&self.security_level)
893             .context(ks_err!("Trying to get IRPC name."))?;
894         crate::utils::upgrade_keyblob_if_required_with(
895             &*self.keymint,
896             self.hw_info.versionNumber,
897             key_blob,
898             params,
899             f,
900             |upgraded_blob| {
901                 let _wp = wd::watch("Calling store_rkpd_attestation_key()");
902                 if let Err(e) = store_rkpd_attestation_key(&rpc_name, key_blob, upgraded_blob) {
903                     Err(wrapped_rkpd_error_to_ks_error(&e)).context(format!("{e:?}"))
904                 } else {
905                     Ok(())
906                 }
907             },
908         )
909         .context(ks_err!())
910     }
911 
convert_storage_key_to_ephemeral( &self, storage_key: &KeyDescriptor, ) -> Result<EphemeralStorageKeyResponse>912     fn convert_storage_key_to_ephemeral(
913         &self,
914         storage_key: &KeyDescriptor,
915     ) -> Result<EphemeralStorageKeyResponse> {
916         if storage_key.domain != Domain::BLOB {
917             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
918                 .context(ks_err!("Key must be of Domain::BLOB"));
919         }
920         let key_blob = storage_key
921             .blob
922             .as_ref()
923             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
924             .context(ks_err!("No key blob specified"))?;
925 
926         // convert_storage_key_to_ephemeral requires the associated permission
927         check_key_permission(KeyPerm::ConvertStorageKeyToEphemeral, storage_key, &None)
928             .context(ks_err!("Check permission"))?;
929 
930         let km_dev = &self.keymint;
931         let res = {
932             let _wp = self.watch(concat!(
933                 "In IKeystoreSecurityLevel::convert_storage_key_to_ephemeral: ",
934                 "calling convertStorageKeyToEphemeral (1)"
935             ));
936             map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
937         };
938         match res {
939             Ok(result) => {
940                 Ok(EphemeralStorageKeyResponse { ephemeralKey: result, upgradedBlob: None })
941             }
942             Err(error::Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
943                 let upgraded_blob = {
944                     let _wp = self.watch("In convert_storage_key_to_ephemeral: calling upgradeKey");
945                     map_km_error(km_dev.upgradeKey(key_blob, &[]))
946                 }
947                 .context(ks_err!("Failed to upgrade key blob."))?;
948                 let ephemeral_key = {
949                     let _wp = self.watch(
950                         "In convert_storage_key_to_ephemeral: calling convertStorageKeyToEphemeral (2)",
951                     );
952                     map_km_error(km_dev.convertStorageKeyToEphemeral(&upgraded_blob))
953                 }
954                     .context(ks_err!(
955                         "Failed to retrieve ephemeral key (after upgrade)."
956                     ))?;
957                 Ok(EphemeralStorageKeyResponse {
958                     ephemeralKey: ephemeral_key,
959                     upgradedBlob: Some(upgraded_blob),
960                 })
961             }
962             Err(e) => Err(e).context(ks_err!("Failed to retrieve ephemeral key.")),
963         }
964     }
965 
delete_key(&self, key: &KeyDescriptor) -> Result<()>966     fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
967         if key.domain != Domain::BLOB {
968             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
969                 .context(ks_err!("delete_key: Key must be of Domain::BLOB"));
970         }
971 
972         let key_blob = key
973             .blob
974             .as_ref()
975             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
976             .context(ks_err!("delete_key: No key blob specified"))?;
977 
978         check_key_permission(KeyPerm::Delete, key, &None)
979             .context(ks_err!("delete_key: Checking delete permissions"))?;
980 
981         let km_dev = &self.keymint;
982         {
983             let _wp = self.watch("In KeystoreSecuritylevel::delete_key: calling deleteKey");
984             map_km_error(km_dev.deleteKey(key_blob)).context(ks_err!("keymint device deleteKey"))
985         }
986     }
987 }
988 
989 impl binder::Interface for KeystoreSecurityLevel {}
990 
991 impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
createOperation( &self, key: &KeyDescriptor, operation_parameters: &[KeyParameter], forced: bool, ) -> binder::Result<CreateOperationResponse>992     fn createOperation(
993         &self,
994         key: &KeyDescriptor,
995         operation_parameters: &[KeyParameter],
996         forced: bool,
997     ) -> binder::Result<CreateOperationResponse> {
998         let _wp = self.watch("IKeystoreSecurityLevel::createOperation");
999         self.create_operation(key, operation_parameters, forced).map_err(into_logged_binder)
1000     }
generateKey( &self, key: &KeyDescriptor, attestation_key: Option<&KeyDescriptor>, params: &[KeyParameter], flags: i32, entropy: &[u8], ) -> binder::Result<KeyMetadata>1001     fn generateKey(
1002         &self,
1003         key: &KeyDescriptor,
1004         attestation_key: Option<&KeyDescriptor>,
1005         params: &[KeyParameter],
1006         flags: i32,
1007         entropy: &[u8],
1008     ) -> binder::Result<KeyMetadata> {
1009         // Duration is set to 5 seconds, because generateKey - especially for RSA keys, takes more
1010         // time than other operations
1011         let _wp = self.watch_millis("IKeystoreSecurityLevel::generateKey", 5000);
1012         let result = self.generate_key(key, attestation_key, params, flags, entropy);
1013         log_key_creation_event_stats(self.security_level, params, &result);
1014         log_key_generated(key, ThreadState::get_calling_uid(), result.is_ok());
1015         result.map_err(into_logged_binder)
1016     }
importKey( &self, key: &KeyDescriptor, attestation_key: Option<&KeyDescriptor>, params: &[KeyParameter], flags: i32, key_data: &[u8], ) -> binder::Result<KeyMetadata>1017     fn importKey(
1018         &self,
1019         key: &KeyDescriptor,
1020         attestation_key: Option<&KeyDescriptor>,
1021         params: &[KeyParameter],
1022         flags: i32,
1023         key_data: &[u8],
1024     ) -> binder::Result<KeyMetadata> {
1025         let _wp = self.watch("IKeystoreSecurityLevel::importKey");
1026         let result = self.import_key(key, attestation_key, params, flags, key_data);
1027         log_key_creation_event_stats(self.security_level, params, &result);
1028         log_key_imported(key, ThreadState::get_calling_uid(), result.is_ok());
1029         result.map_err(into_logged_binder)
1030     }
importWrappedKey( &self, key: &KeyDescriptor, wrapping_key: &KeyDescriptor, masking_key: Option<&[u8]>, params: &[KeyParameter], authenticators: &[AuthenticatorSpec], ) -> binder::Result<KeyMetadata>1031     fn importWrappedKey(
1032         &self,
1033         key: &KeyDescriptor,
1034         wrapping_key: &KeyDescriptor,
1035         masking_key: Option<&[u8]>,
1036         params: &[KeyParameter],
1037         authenticators: &[AuthenticatorSpec],
1038     ) -> binder::Result<KeyMetadata> {
1039         let _wp = self.watch("IKeystoreSecurityLevel::importWrappedKey");
1040         let result =
1041             self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators);
1042         log_key_creation_event_stats(self.security_level, params, &result);
1043         log_key_imported(key, ThreadState::get_calling_uid(), result.is_ok());
1044         result.map_err(into_logged_binder)
1045     }
convertStorageKeyToEphemeral( &self, storage_key: &KeyDescriptor, ) -> binder::Result<EphemeralStorageKeyResponse>1046     fn convertStorageKeyToEphemeral(
1047         &self,
1048         storage_key: &KeyDescriptor,
1049     ) -> binder::Result<EphemeralStorageKeyResponse> {
1050         let _wp = self.watch("IKeystoreSecurityLevel::convertStorageKeyToEphemeral");
1051         self.convert_storage_key_to_ephemeral(storage_key).map_err(into_logged_binder)
1052     }
deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()>1053     fn deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()> {
1054         let _wp = self.watch("IKeystoreSecurityLevel::deleteKey");
1055         let result = self.delete_key(key);
1056         log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
1057         result.map_err(into_logged_binder)
1058     }
1059 }
1060 
1061 #[cfg(test)]
1062 mod tests {
1063     use super::*;
1064     use crate::error::map_km_error;
1065     use crate::globals::get_keymint_device;
1066     use crate::utils::upgrade_keyblob_if_required_with;
1067     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
1068         Algorithm::Algorithm, AttestationKey::AttestationKey, KeyParameter::KeyParameter,
1069         KeyParameterValue::KeyParameterValue, Tag::Tag,
1070     };
1071     use keystore2_crypto::parse_subject_from_certificate;
1072     use rkpd_client::get_rkpd_attestation_key;
1073 
1074     #[test]
1075     // This is a helper for a manual test. We want to check that after a system upgrade RKPD
1076     // attestation keys can also be upgraded and stored again with RKPD. The steps are:
1077     // 1. Run this test and check in stdout that no key upgrade happened.
1078     // 2. Perform a system upgrade.
1079     // 3. Run this test and check in stdout that key upgrade did happen.
1080     //
1081     // Note that this test must be run with that same UID every time. Running as root, i.e. UID 0,
1082     // should do the trick. Also, use "--nocapture" flag to get stdout.
test_rkpd_attestation_key_upgrade()1083     fn test_rkpd_attestation_key_upgrade() {
1084         binder::ProcessState::start_thread_pool();
1085         let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
1086         let (keymint, info, _) = get_keymint_device(&security_level).unwrap();
1087         let key_id = 0;
1088         let mut key_upgraded = false;
1089 
1090         let rpc_name = get_remotely_provisioned_component_name(&security_level).unwrap();
1091         let key = get_rkpd_attestation_key(&rpc_name, key_id).unwrap();
1092         assert!(!key.keyBlob.is_empty());
1093         assert!(!key.encodedCertChain.is_empty());
1094 
1095         upgrade_keyblob_if_required_with(
1096             &*keymint,
1097             info.versionNumber,
1098             &key.keyBlob,
1099             /*upgrade_params=*/ &[],
1100             /*km_op=*/
1101             |blob| {
1102                 let params = vec![
1103                     KeyParameter {
1104                         tag: Tag::ALGORITHM,
1105                         value: KeyParameterValue::Algorithm(Algorithm::AES),
1106                     },
1107                     KeyParameter {
1108                         tag: Tag::ATTESTATION_CHALLENGE,
1109                         value: KeyParameterValue::Blob(vec![0; 16]),
1110                     },
1111                     KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
1112                 ];
1113                 let attestation_key = AttestationKey {
1114                     keyBlob: blob.to_vec(),
1115                     attestKeyParams: vec![],
1116                     issuerSubjectName: parse_subject_from_certificate(&key.encodedCertChain)
1117                         .unwrap(),
1118                 };
1119 
1120                 map_km_error(keymint.generateKey(&params, Some(&attestation_key)))
1121             },
1122             /*new_blob_handler=*/
1123             |new_blob| {
1124                 // This handler is only executed if a key upgrade was performed.
1125                 key_upgraded = true;
1126                 let _wp = wd::watch("Calling store_rkpd_attestation_key()");
1127                 store_rkpd_attestation_key(&rpc_name, &key.keyBlob, new_blob).unwrap();
1128                 Ok(())
1129             },
1130         )
1131         .unwrap();
1132 
1133         if key_upgraded {
1134             println!("RKPD key was upgraded and stored with RKPD.");
1135         } else {
1136             println!("RKPD key was NOT upgraded.");
1137         }
1138     }
1139 }
1140