Super encrypted keys
This CL implements super encryption of auth bound keys.
Bug: 173545997
Test: TBD
Change-Id: I71ca59803797d819a717dbd080550a61d88fe1c3
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index c2170b6..23a3c35 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -31,9 +31,11 @@
KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
};
-use crate::globals::ENFORCEMENTS;
+use crate::database::{CertificateInfo, KeyIdGuard};
+use crate::globals::{DB, ENFORCEMENTS, SUPER_KEY};
use crate::key_parameter::KeyParameter as KsKeyParam;
use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
+use crate::super_key::{KeyBlob, SuperKeyManager};
use crate::utils::{check_key_permission, uid_to_android_user, Asp};
use crate::{
database::{
@@ -45,10 +47,6 @@
permission::KeyPerm,
};
use crate::{
- database::{CertificateInfo, KeyIdGuard},
- globals::DB,
-};
-use crate::{
error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
utils::key_characteristics_to_internal,
};
@@ -98,6 +96,7 @@
key: KeyDescriptor,
creation_result: KeyCreationResult,
user_id: u32,
+ flags: Option<i32>,
) -> Result<KeyMetadata> {
let KeyCreationResult {
keyBlob: key_blob,
@@ -130,6 +129,20 @@
SecurityLevel::SOFTWARE,
));
+ let (key_blob, mut blob_metadata) = DB
+ .with(|db| {
+ SuperKeyManager::handle_super_encryption_on_key_init(
+ &mut db.borrow_mut(),
+ &SUPER_KEY,
+ &(key.domain),
+ &key_parameters,
+ flags,
+ user_id,
+ &key_blob,
+ )
+ })
+ .context("In store_new_key. Failed to handle super encryption.")?;
+
let creation_date = DateTime::now().context("Trying to make creation time.")?;
let key = match key.domain {
@@ -140,7 +153,6 @@
.with::<_, Result<KeyDescriptor>>(|db| {
let mut key_metadata = KeyMetaData::new();
key_metadata.add(KeyMetaEntry::CreationDate(creation_date));
- let mut blob_metadata = BlobMetaData::new();
blob_metadata.add(BlobMetaEntry::KmUuid(self.km_uuid));
let mut db = db.borrow_mut();
@@ -200,7 +212,7 @@
},
None,
None,
- None,
+ BlobMetaData::new(),
)
}
_ => {
@@ -227,7 +239,7 @@
&scoping_blob,
Some((key_id_guard.id(), key_entry.into_key_parameters())),
Some(key_id_guard),
- Some(blob_metadata),
+ blob_metadata,
)
}
};
@@ -256,6 +268,12 @@
let immediate_hat = immediate_hat.unwrap_or_default();
+ let user_id = uid_to_android_user(caller_uid);
+
+ let km_blob = SUPER_KEY
+ .unwrap_key_if_required(&blob_metadata, km_blob)
+ .context("In create_operation. Failed to handle super encryption.")?;
+
let km_dev: Strong<dyn IKeyMintDevice> = self
.keymint
.get_interface()
@@ -265,7 +283,7 @@
.upgrade_keyblob_if_required_with(
&*km_dev,
key_id_guard,
- &(km_blob, blob_metadata.as_ref()),
+ &(&km_blob, &blob_metadata),
&operation_parameters,
|blob| loop {
match map_km_error(km_dev.begin(
@@ -393,7 +411,7 @@
.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.")
+ self.store_new_key(key, creation_result, user_id, Some(flags)).context("In generate_key.")
}
fn import_key(
@@ -448,7 +466,7 @@
.context("In import_key: Trying to call importKey")?;
let user_id = uid_to_android_user(caller_uid);
- self.store_new_key(key, creation_result, user_id).context("In import_key.")
+ self.store_new_key(key, creation_result, user_id, Some(flags)).context("In import_key.")
}
fn import_wrapped_key(
@@ -482,6 +500,8 @@
}
let caller_uid = ThreadState::get_calling_uid();
+ let user_id = uid_to_android_user(caller_uid);
+
let key = match key.domain {
Domain::APP => KeyDescriptor {
domain: key.domain,
@@ -501,7 +521,7 @@
// Import_wrapped_key requires the rebind permission for the new key.
check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
- let (wrapping_key_id_guard, wrapping_key_entry) = DB
+ let (wrapping_key_id_guard, mut wrapping_key_entry) = DB
.with(|db| {
db.borrow_mut().load_key_entry(
&wrapping_key,
@@ -512,15 +532,16 @@
)
})
.context("Failed to load wrapping key.")?;
- let (wrapping_key_blob, wrapping_blob_metadata) = match wrapping_key_entry.key_blob_info() {
- Some((blob, metadata)) => (blob, metadata),
- None => {
- return Err(error::Error::sys()).context(concat!(
- "No km_blob after successfully loading key.",
- " This should never happen."
- ))
- }
- };
+
+ let (wrapping_key_blob, wrapping_blob_metadata) = wrapping_key_entry
+ .take_key_blob_info()
+ .ok_or_else(error::Error::sys)
+ .context("No km_blob after successfully loading key. This should never happen.")?;
+
+ let wrapping_key_blob =
+ SUPER_KEY.unwrap_key_if_required(&wrapping_blob_metadata, &wrapping_key_blob).context(
+ "In import_wrapped_key. Failed to handle super encryption for wrapping key.",
+ )?;
// km_dev.importWrappedKey does not return a certificate chain.
// TODO Do we assume that all wrapped keys are symmetric?
@@ -549,7 +570,7 @@
.upgrade_keyblob_if_required_with(
&*km_dev,
Some(wrapping_key_id_guard),
- &(&wrapping_key_blob, Some(&wrapping_blob_metadata)),
+ &(&wrapping_key_blob, &wrapping_blob_metadata),
&[],
|wrapping_blob| {
let creation_result = map_km_error(km_dev.importWrappedKey(
@@ -565,8 +586,7 @@
)
.context("In import_wrapped_key.")?;
- let user_id = uid_to_android_user(caller_uid);
- self.store_new_key(key, creation_result, user_id)
+ self.store_new_key(key, creation_result, user_id, None)
.context("In import_wrapped_key: Trying to store the new key.")
}
@@ -574,7 +594,7 @@
&self,
km_dev: &dyn IKeyMintDevice,
key_id_guard: Option<KeyIdGuard>,
- blob_info: &(&[u8], Option<&BlobMetaData>),
+ blob_info: &(&KeyBlob, &BlobMetaData),
params: &[KeyParameter],
f: F,
) -> Result<(T, Option<Vec<u8>>)>
@@ -585,13 +605,26 @@
Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
let upgraded_blob = map_km_error(km_dev.upgradeKey(blob_info.0, params))
.context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
+
+ let (upgraded_blob_to_be_stored, blob_metadata) =
+ SuperKeyManager::reencrypt_on_upgrade_if_required(blob_info.0, &upgraded_blob)
+ .context(
+ "In upgrade_keyblob_if_required_with: Failed to handle super encryption.",
+ )?;
+
+ let mut blob_metadata = blob_metadata.unwrap_or_else(BlobMetaData::new);
+ if let Some(uuid) = blob_info.1.km_uuid() {
+ blob_metadata.add(BlobMetaEntry::KmUuid(*uuid));
+ }
+
key_id_guard.map_or(Ok(()), |key_id_guard| {
DB.with(|db| {
- db.borrow_mut().set_blob(
+ let mut db = db.borrow_mut();
+ db.set_blob(
&key_id_guard,
SubComponentType::KEY_BLOB,
- Some(&upgraded_blob),
- blob_info.1,
+ Some(&upgraded_blob_to_be_stored),
+ Some(&blob_metadata),
)
})
.context(concat!(