diff options
author | Janis Danisevskis <jdanis@google.com> | 2021-05-17 17:13:56 -0700 |
---|---|---|
committer | Janis Danisevskis <jdanis@google.com> | 2021-06-01 14:30:27 -0700 |
commit | 5c7482104f61d43b15f8421c3a5c546d16d0cd45 (patch) | |
tree | 33996d0771da7ed25f86b6ddbd5875b65eb13371 /keystore2/src/raw_device.rs | |
parent | 67f30564f44fa0b6c6e4e1b93b89f89b01f2d29e (diff) | |
download | security-5c7482104f61d43b15f8421c3a5c546d16d0cd45.tar.gz |
Keystore 2.0: Use preferred KM instance for level zero key.
Prefer KM4.1 and higher over KM4.0 and lower, but prefer TEE over
Strongbox if TEE meets the minimal requirements.
Ignore-AOSP-First: No automerge path from AOSP.
Bug: 187862706
Test: Manually tested by observing logs during boot.
Merged-In: I1d27c80ef7c869b84b6d0c1a5d8eec287c242f6c
Change-Id: I1d27c80ef7c869b84b6d0c1a5d8eec287c242f6c
Merged-In: I1d27c80ef7c869b84b6d0c1a5d8eec287c242f6c
Diffstat (limited to 'keystore2/src/raw_device.rs')
-rw-r--r-- | keystore2/src/raw_device.rs | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/keystore2/src/raw_device.rs b/keystore2/src/raw_device.rs index 9e6ef410..9cc69ef6 100644 --- a/keystore2/src/raw_device.rs +++ b/keystore2/src/raw_device.rs @@ -19,16 +19,15 @@ use crate::{ BlobMetaData, BlobMetaEntry, CertificateInfo, DateTime, KeyEntry, KeyEntryLoadBits, KeyIdGuard, KeyMetaData, KeyMetaEntry, KeyType, KeystoreDB, SubComponentType, Uuid, }, - error::{map_km_error, Error}, + error::{map_km_error, Error, ErrorCode}, globals::get_keymint_device, super_key::KeyBlob, utils::{key_characteristics_to_internal, watchdog as wd, Asp, AID_KEYSTORE}, }; use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ - BeginResult::BeginResult, ErrorCode::ErrorCode, HardwareAuthToken::HardwareAuthToken, - IKeyMintDevice::IKeyMintDevice, IKeyMintOperation::IKeyMintOperation, - KeyCreationResult::KeyCreationResult, KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, - SecurityLevel::SecurityLevel, + BeginResult::BeginResult, HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice, + IKeyMintOperation::IKeyMintOperation, KeyCreationResult::KeyCreationResult, + KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel, }; use android_system_keystore2::aidl::android::system::keystore2::{ Domain::Domain, KeyDescriptor::KeyDescriptor, ResponseCode::ResponseCode, @@ -48,14 +47,39 @@ use binder::Strong; pub struct KeyMintDevice { asp: Asp, km_uuid: Uuid, + version: i32, } impl KeyMintDevice { + /// Version number of KeyMasterDevice@V4_0 + pub const KEY_MASTER_V4_0: i32 = 40; + /// Version number of KeyMasterDevice@V4_1 + pub const KEY_MASTER_V4_1: i32 = 41; + /// Version number of KeyMintDevice@V1 + pub const KEY_MINT_V1: i32 = 100; + /// Get a [`KeyMintDevice`] for the given [`SecurityLevel`] pub fn get(security_level: SecurityLevel) -> Result<KeyMintDevice> { - let (asp, _hw_info, km_uuid) = get_keymint_device(&security_level) + let (asp, hw_info, km_uuid) = get_keymint_device(&security_level) .context("In KeyMintDevice::get: get_keymint_device failed")?; - Ok(KeyMintDevice { asp, km_uuid }) + + Ok(KeyMintDevice { asp, km_uuid, version: hw_info.versionNumber }) + } + + /// Get a [`KeyMintDevice`] for the given [`SecurityLevel`], return + /// [`None`] if the error `HARDWARE_TYPE_UNAVAILABLE` is returned + pub fn get_or_none(security_level: SecurityLevel) -> Result<Option<KeyMintDevice>> { + KeyMintDevice::get(security_level).map(Some).or_else(|e| { + match e.root_cause().downcast_ref::<Error>() { + Some(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) => Ok(None), + _ => Err(e), + } + }) + } + + /// Returns the version of the underlying KeyMint/KeyMaster device. + pub fn version(&self) -> i32 { + self.version } /// Create a KM key and store in the database. @@ -145,14 +169,24 @@ impl KeyMintDevice { // KeyMint operations let lookup = Self::not_found_is_none(Self::lookup_from_desc(db, key_desc)) .context("In lookup_or_generate_key: first lookup failed")?; - if let Some(result) = lookup { - Ok(result) - } else { - self.create_and_store_key(db, &key_desc, |km_dev| km_dev.generateKey(¶ms, None)) - .context("In lookup_or_generate_key: generate_and_store_key failed")?; - Self::lookup_from_desc(db, key_desc) - .context("In lookup_or_generate_key: second lookup failed") + + if let Some((key_id_guard, key_entry)) = lookup { + // If the key is associated with a different km instance + // or if there is no blob metadata for some reason the key entry + // is considered corrupted and needs to be replaced with a new one. + if key_entry + .key_blob_info() + .as_ref() + .map(|(_, blob_metadata)| Some(&self.km_uuid) == blob_metadata.km_uuid()) + .unwrap_or(false) + { + return Ok((key_id_guard, key_entry)); + } } + self.create_and_store_key(db, &key_desc, |km_dev| km_dev.generateKey(¶ms, None)) + .context("In lookup_or_generate_key: generate_and_store_key failed")?; + Self::lookup_from_desc(db, key_desc) + .context("In lookup_or_generate_key: second lookup failed") } /// Call the passed closure; if it returns `KEY_REQUIRES_UPGRADE`, call upgradeKey, and |