Implement ATTEST_KEY support.
Test: atest CtsKeyStoreTestCases:AttestKeyTest
Change-Id: Ib2a8b0cb21b418b9d36df58836290c2e3e94cfa7
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index b96aea8..37e43c6 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -18,8 +18,9 @@
use crate::globals::get_keymint_device;
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
- Algorithm::Algorithm, HardwareAuthenticatorType::HardwareAuthenticatorType,
- IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
+ Algorithm::Algorithm, AttestationKey::AttestationKey,
+ HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
+ KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
KeyMintHardwareInfo::KeyMintHardwareInfo, KeyParameter::KeyParameter,
KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
};
@@ -54,6 +55,7 @@
};
use anyhow::{anyhow, Context, Result};
use binder::{IBinder, Strong, ThreadState};
+use keystore2_crypto::parse_issuer_subject_from_certificate;
/// Implementation of the IKeystoreSecurityLevel Interface.
pub struct KeystoreSecurityLevel {
@@ -359,7 +361,7 @@
fn generate_key(
&self,
key: &KeyDescriptor,
- attestation_key: Option<&KeyDescriptor>,
+ attest_key_descriptor: Option<&KeyDescriptor>,
params: &[KeyParameter],
flags: i32,
entropy: &[u8],
@@ -383,19 +385,78 @@
// generate_key requires the rebind permission.
check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
+ let attest_key = match attest_key_descriptor {
+ None => None,
+ Some(key) => Some(
+ self.get_attest_key(key, caller_uid)
+ .context("In generate_key: Trying to load attest key")?,
+ ),
+ };
+
let params = Self::add_certificate_parameters(caller_uid, params, &key)
.context("In generate_key: Trying to get aaid.")?;
let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
map_km_error(km_dev.addRngEntropy(entropy))
.context("In generate_key: Trying to add entropy.")?;
- let creation_result = map_km_error(km_dev.generateKey(¶ms, None /* attestKey */))
+ let creation_result = map_km_error(km_dev.generateKey(¶ms, attest_key.as_ref()))
.context("In generate_key: While generating Key")?;
let user_id = uid_to_android_user(caller_uid);
self.store_new_key(key, creation_result, user_id).context("In generate_key.")
}
+ fn get_attest_key(&self, key: &KeyDescriptor, caller_uid: u32) -> Result<AttestationKey> {
+ let (km_blob, cert) = self
+ .load_attest_key_blob_and_cert(&key, caller_uid)
+ .context("In get_attest_key: Failed to load blob and cert")?;
+
+ let issuer_subject: Vec<u8> = parse_issuer_subject_from_certificate(&cert)
+ .context("In get_attest_key: Failed to parse subject from certificate.")?;
+
+ Ok(AttestationKey {
+ keyBlob: km_blob.to_vec(),
+ attestKeyParams: [].to_vec(),
+ issuerSubjectName: issuer_subject,
+ })
+ }
+
+ fn load_attest_key_blob_and_cert(
+ &self,
+ key: &KeyDescriptor,
+ caller_uid: u32,
+ ) -> Result<(Vec<u8>, Vec<u8>)> {
+ match key.domain {
+ Domain::BLOB => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
+ "In load_attest_key_blob_and_cert: Domain::BLOB attestation keys not supported",
+ ),
+ _ => {
+ let (key_id_guard, mut key_entry) = DB
+ .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
+ db.borrow_mut().load_key_entry(
+ &key,
+ KeyType::Client,
+ KeyEntryLoadBits::BOTH,
+ caller_uid,
+ |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+ )
+ })
+ .context("In load_attest_key_blob_and_cert: Failed to load key.")?;
+
+ let (blob, _) =
+ key_entry.take_key_blob_info().ok_or_else(Error::sys).context(concat!(
+ "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
+ " but KM blob was missing."
+ ))?;
+ let cert = key_entry.take_cert().ok_or_else(Error::sys).context(concat!(
+ "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
+ " but cert was missing."
+ ))?;
+ Ok((blob, cert))
+ }
+ }
+ }
+
fn import_key(
&self,
key: &KeyDescriptor,