summaryrefslogtreecommitdiff
path: root/keystore2
diff options
context:
space:
mode:
Diffstat (limited to 'keystore2')
-rw-r--r--keystore2/Android.bp1
-rw-r--r--keystore2/src/database.rs2
-rw-r--r--keystore2/src/super_key.rs92
-rw-r--r--keystore2/src/utils.rs2
4 files changed, 57 insertions, 40 deletions
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 03dfd458..e59b6f24 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -42,6 +42,7 @@ rust_defaults {
"android.security.metrics-rust",
"android.security.rkp_aidl-rust",
"libaconfig_android_hardware_biometrics_rust",
+ "libandroid_security_flags_rust",
"libanyhow",
"libbinder_rs",
"libkeystore2_aaid-rust",
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 9d2da8cf..83963f9d 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -4890,11 +4890,13 @@ pub mod tests {
let key_name_enc = SuperKeyType {
alias: "test_super_key_1",
algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+ name: "test_super_key_1",
};
let key_name_nonenc = SuperKeyType {
alias: "test_super_key_2",
algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+ name: "test_super_key_2",
};
// Install two super keys.
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index 128cf4ca..898a8c2c 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -78,26 +78,35 @@ pub struct SuperKeyType<'a> {
pub alias: &'a str,
/// Encryption algorithm
pub algorithm: SuperEncryptionAlgorithm,
+ /// What to call this key in log messages. Not used for anything else.
+ pub name: &'a str,
}
/// The user's AfterFirstUnlock super key. This super key is loaded into memory when the user first
/// unlocks the device, and it remains in memory until the device reboots. This is used to encrypt
/// keys that require user authentication but not an unlocked device.
-pub const USER_AFTER_FIRST_UNLOCK_SUPER_KEY: SuperKeyType =
- SuperKeyType { alias: "USER_SUPER_KEY", algorithm: SuperEncryptionAlgorithm::Aes256Gcm };
+pub const USER_AFTER_FIRST_UNLOCK_SUPER_KEY: SuperKeyType = SuperKeyType {
+ alias: "USER_SUPER_KEY",
+ algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+ name: "AfterFirstUnlock super key",
+};
+
/// The user's UnlockedDeviceRequired symmetric super key. This super key is loaded into memory each
/// time the user unlocks the device, and it is cleared from memory each time the user locks the
/// device. This is used to encrypt keys that use the UnlockedDeviceRequired key parameter.
pub const USER_UNLOCKED_DEVICE_REQUIRED_SYMMETRIC_SUPER_KEY: SuperKeyType = SuperKeyType {
alias: "USER_SCREEN_LOCK_BOUND_KEY",
algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+ name: "UnlockedDeviceRequired symmetric super key",
};
+
/// The user's UnlockedDeviceRequired asymmetric super key. This is used to allow, while the device
/// is locked, the creation of keys that use the UnlockedDeviceRequired key parameter. The private
/// part of this key is loaded and cleared when the symmetric key is loaded and cleared.
pub const USER_UNLOCKED_DEVICE_REQUIRED_P521_SUPER_KEY: SuperKeyType = SuperKeyType {
alias: "USER_SCREEN_LOCK_BOUND_P521_KEY",
algorithm: SuperEncryptionAlgorithm::EcdhP521,
+ name: "UnlockedDeviceRequired asymmetric super key",
};
/// Superencryption to apply to a new key.
@@ -717,6 +726,47 @@ impl SuperKeyManager {
}
}
+ fn create_super_key(
+ &mut self,
+ db: &mut KeystoreDB,
+ user_id: UserId,
+ key_type: &SuperKeyType,
+ password: &Password,
+ reencrypt_with: Option<Arc<SuperKey>>,
+ ) -> Result<Arc<SuperKey>> {
+ log::info!("Creating {} for user {}", key_type.name, user_id);
+ let (super_key, public_key) = match key_type.algorithm {
+ SuperEncryptionAlgorithm::Aes256Gcm => {
+ (generate_aes256_key().context(ks_err!("Failed to generate AES-256 key."))?, None)
+ }
+ SuperEncryptionAlgorithm::EcdhP521 => {
+ let key =
+ ECDHPrivateKey::generate().context(ks_err!("Failed to generate ECDH key"))?;
+ (
+ key.private_key().context(ks_err!("private_key failed"))?,
+ Some(key.public_key().context(ks_err!("public_key failed"))?),
+ )
+ }
+ };
+ // Derive an AES-256 key from the password and re-encrypt the super key before we insert it
+ // in the database.
+ let (encrypted_super_key, blob_metadata) =
+ Self::encrypt_with_password(&super_key, password).context(ks_err!())?;
+ let mut key_metadata = KeyMetaData::new();
+ if let Some(pk) = public_key {
+ key_metadata.add(KeyMetaEntry::Sec1PublicKey(pk));
+ }
+ let key_entry = db
+ .store_super_key(user_id, key_type, &encrypted_super_key, &blob_metadata, &key_metadata)
+ .context(ks_err!("Failed to store super key."))?;
+ Ok(Arc::new(SuperKey {
+ algorithm: key_type.algorithm,
+ key: super_key,
+ id: SuperKeyIdentifier::DatabaseId(key_entry.id()),
+ reencrypt_with,
+ }))
+ }
+
/// Fetch a superencryption key from the database, or create it if it doesn't already exist.
/// When this is called, the caller must hold the lock on the SuperKeyManager.
/// So it's OK that the check and creation are different DB transactions.
@@ -737,43 +787,7 @@ impl SuperKeyManager {
reencrypt_with,
)?)
} else {
- let (super_key, public_key) = match key_type.algorithm {
- SuperEncryptionAlgorithm::Aes256Gcm => (
- generate_aes256_key().context(ks_err!("Failed to generate AES 256 key."))?,
- None,
- ),
- SuperEncryptionAlgorithm::EcdhP521 => {
- let key = ECDHPrivateKey::generate()
- .context(ks_err!("Failed to generate ECDH key"))?;
- (
- key.private_key().context(ks_err!("private_key failed"))?,
- Some(key.public_key().context(ks_err!("public_key failed"))?),
- )
- }
- };
- // Derive an AES256 key from the password and re-encrypt the super key
- // before we insert it in the database.
- let (encrypted_super_key, blob_metadata) =
- Self::encrypt_with_password(&super_key, password).context(ks_err!())?;
- let mut key_metadata = KeyMetaData::new();
- if let Some(pk) = public_key {
- key_metadata.add(KeyMetaEntry::Sec1PublicKey(pk));
- }
- let key_entry = db
- .store_super_key(
- user_id,
- key_type,
- &encrypted_super_key,
- &blob_metadata,
- &key_metadata,
- )
- .context(ks_err!("Failed to store super key."))?;
- Ok(Arc::new(SuperKey {
- algorithm: key_type.algorithm,
- key: super_key,
- id: SuperKeyIdentifier::DatabaseId(key_entry.id()),
- reencrypt_with,
- }))
+ self.create_super_key(db, user_id, key_type, password, reencrypt_with)
}
}
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index f028491a..4fd9c8dd 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -269,7 +269,7 @@ pub fn get_current_time_in_milliseconds() -> i64 {
let mut current_time = libc::timespec { tv_sec: 0, tv_nsec: 0 };
// SAFETY: The pointer is valid because it comes from a reference, and clock_gettime doesn't
// retain it beyond the call.
- unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_RAW, &mut current_time) };
+ unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut current_time) };
current_time.tv_sec as i64 * 1000 + (current_time.tv_nsec as i64 / 1_000_000)
}