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 ¶ms, 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(¶ms, 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(¶ms) 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(¶ms, 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(¶ms) 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(¶ms, 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(¶ms) 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(¶ms, 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(¶ms, 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