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