Snap for 11330025 from 46589b8c19
to 24Q2-release
Change-Id: I31a8f0e375064084373611aff0b23541935fffcd
This commit is contained in:
commit
077f47cc4a
17 changed files with 114 additions and 101 deletions
|
@ -49,9 +49,9 @@ rust_defaults {
|
|||
"libkeystore2_apc_compat-rust",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_flags_rust",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"libkeystore2_km_compat",
|
||||
"libkeystore2_selinux",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"liblazy_static",
|
||||
"liblibc",
|
||||
"liblog_event_list",
|
||||
|
@ -90,9 +90,9 @@ rust_library {
|
|||
"keystore2_blob_test_utils",
|
||||
],
|
||||
rustlibs: [
|
||||
"libkeystore2_test_utils",
|
||||
"liblibsqlite3_sys",
|
||||
"librusqlite",
|
||||
"libkeystore2_test_utils",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -107,15 +107,15 @@ rust_test {
|
|||
"libandroid_logger",
|
||||
"libhex",
|
||||
"libkeystore2_test_utils",
|
||||
"libkeystore2_with_test_utils",
|
||||
"liblibsqlite3_sys",
|
||||
"libnix",
|
||||
"librusqlite",
|
||||
"libkeystore2_with_test_utils",
|
||||
],
|
||||
// The test should always include watchdog.
|
||||
features: [
|
||||
"watchdog",
|
||||
"keystore2_blob_test_utils",
|
||||
"watchdog",
|
||||
],
|
||||
require_root: true,
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ cc_library {
|
|||
"aaid.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libkeystore-attestation-application-id"
|
||||
"libkeystore-attestation-application-id",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ cc_library {
|
|||
"apc_compat.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder_ndk",
|
||||
"android.hardware.confirmationui@1.0",
|
||||
"android.hardware.confirmationui-V1-ndk",
|
||||
"android.hardware.confirmationui@1.0",
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
],
|
||||
|
@ -43,12 +43,12 @@ rust_bindgen {
|
|||
source_stem: "bindings",
|
||||
|
||||
bindgen_flags: [
|
||||
"--allowlist-function=tryGetUserConfirmationService",
|
||||
"--allowlist-function=promptUserConfirmation",
|
||||
"--allowlist-function=abortUserConfirmation",
|
||||
"--allowlist-function=closeUserConfirmationService",
|
||||
"--allowlist-var=INVALID_SERVICE_HANDLE",
|
||||
"--allowlist-function=promptUserConfirmation",
|
||||
"--allowlist-function=tryGetUserConfirmationService",
|
||||
"--allowlist-var=APC_COMPAT_.*",
|
||||
"--allowlist-var=INVALID_SERVICE_HANDLE",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ rust_defaults {
|
|||
"libanyhow",
|
||||
"libbinder_rs",
|
||||
"libkeystore2_flags_rust",
|
||||
"liblog_rust",
|
||||
"libkeystore2_flags_rust",
|
||||
"liblog_rust",
|
||||
"librusqlite",
|
||||
"librustutils",
|
||||
"libthiserror",
|
||||
|
@ -62,8 +62,8 @@ rust_test {
|
|||
"libbinder_rs",
|
||||
"libkeystore2",
|
||||
"libkeystore2_flags_rust",
|
||||
"libkeystore2_test_utils",
|
||||
"libkeystore2_flags_rust",
|
||||
"libkeystore2_test_utils",
|
||||
"liblog_rust",
|
||||
"librusqlite",
|
||||
"librustutils",
|
||||
|
|
|
@ -32,8 +32,8 @@ rust_library {
|
|||
"libthiserror",
|
||||
],
|
||||
shared_libs: [
|
||||
"libkeystore2_crypto",
|
||||
"libcrypto",
|
||||
"libkeystore2_crypto",
|
||||
],
|
||||
vendor_available: true,
|
||||
apex_available: [
|
||||
|
@ -45,8 +45,8 @@ rust_library {
|
|||
cc_library {
|
||||
name: "libkeystore2_crypto",
|
||||
srcs: [
|
||||
"crypto.cpp",
|
||||
"certificate_utils.cpp",
|
||||
"crypto.cpp",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
|
@ -69,28 +69,28 @@ rust_bindgen {
|
|||
vendor_available: true,
|
||||
shared_libs: ["libcrypto"],
|
||||
bindgen_flags: [
|
||||
"--allowlist-function", "hmacSha256",
|
||||
"--allowlist-function", "randomBytes",
|
||||
"--allowlist-function", "AES_gcm_encrypt",
|
||||
"--allowlist-function", "AES_gcm_decrypt",
|
||||
"--allowlist-function", "CreateKeyId",
|
||||
"--allowlist-function", "generateKeyFromPassword",
|
||||
"--allowlist-function", "HKDFExtract",
|
||||
"--allowlist-function", "HKDFExpand",
|
||||
"--allowlist-function", "ECDHComputeKey",
|
||||
"--allowlist-function", "ECKEYGenerateKey",
|
||||
"--allowlist-function", "ECKEYMarshalPrivateKey",
|
||||
"--allowlist-function", "ECKEYParsePrivateKey",
|
||||
"--allowlist-function", "EC_KEY_get0_public_key",
|
||||
"--allowlist-function", "ECPOINTPoint2Oct",
|
||||
"--allowlist-function", "ECPOINTOct2Point",
|
||||
"--allowlist-function", "EC_KEY_free",
|
||||
"--allowlist-function", "EC_POINT_free",
|
||||
"--allowlist-function", "extractSubjectFromCertificate",
|
||||
"--allowlist-type", "EC_KEY",
|
||||
"--allowlist-type", "EC_POINT",
|
||||
"--allowlist-var", "EC_MAX_BYTES",
|
||||
"--allowlist-var", "EVP_MAX_MD_SIZE",
|
||||
"--allowlist-function=AES_gcm_decrypt",
|
||||
"--allowlist-function=AES_gcm_encrypt",
|
||||
"--allowlist-function=CreateKeyId",
|
||||
"--allowlist-function=ECDHComputeKey",
|
||||
"--allowlist-function=ECKEYGenerateKey",
|
||||
"--allowlist-function=ECKEYMarshalPrivateKey",
|
||||
"--allowlist-function=ECKEYParsePrivateKey",
|
||||
"--allowlist-function=ECPOINTOct2Point",
|
||||
"--allowlist-function=ECPOINTPoint2Oct",
|
||||
"--allowlist-function=EC_KEY_free",
|
||||
"--allowlist-function=EC_KEY_get0_public_key",
|
||||
"--allowlist-function=EC_POINT_free",
|
||||
"--allowlist-function=HKDFExpand",
|
||||
"--allowlist-function=HKDFExtract",
|
||||
"--allowlist-function=PBKDF2",
|
||||
"--allowlist-function=extractSubjectFromCertificate",
|
||||
"--allowlist-function=hmacSha256",
|
||||
"--allowlist-function=randomBytes",
|
||||
"--allowlist-type=EC_KEY",
|
||||
"--allowlist-type=EC_POINT",
|
||||
"--allowlist-var=EC_MAX_BYTES",
|
||||
"--allowlist-var=EVP_MAX_MD_SIZE",
|
||||
],
|
||||
cflags: ["-DBORINGSSL_NO_CXX"],
|
||||
apex_available: [
|
||||
|
|
|
@ -141,7 +141,8 @@ bool AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t*
|
|||
EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
|
||||
out_pos += out_len;
|
||||
if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
|
||||
ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
|
||||
// No error log here; this is expected when trying two different keys to see which one
|
||||
// works. The callers handle the error appropriately.
|
||||
return false;
|
||||
}
|
||||
out_pos += out_len;
|
||||
|
@ -191,8 +192,7 @@ static constexpr size_t SALT_SIZE = 16;
|
|||
|
||||
// Copied from system/security/keystore/user_state.cpp.
|
||||
|
||||
void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw, size_t pw_len,
|
||||
const uint8_t* salt) {
|
||||
void PBKDF2(uint8_t* key, size_t key_len, const char* pw, size_t pw_len, const uint8_t* salt) {
|
||||
const EVP_MD* digest = EVP_sha256();
|
||||
|
||||
// SHA1 was used prior to increasing the key size
|
||||
|
|
|
@ -37,8 +37,7 @@ extern "C" {
|
|||
bool CreateKeyId(const uint8_t* key_blob, size_t len, km_id_t* out_id);
|
||||
|
||||
// The salt parameter must be non-nullptr and point to 16 bytes of data.
|
||||
void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw,
|
||||
size_t pw_len, const uint8_t* salt);
|
||||
void PBKDF2(uint8_t* key, size_t key_len, const char* pw, size_t pw_len, const uint8_t* salt);
|
||||
|
||||
#include "openssl/digest.h"
|
||||
#include "openssl/ec_key.h"
|
||||
|
|
|
@ -19,10 +19,10 @@ mod error;
|
|||
pub mod zvec;
|
||||
pub use error::Error;
|
||||
use keystore2_crypto_bindgen::{
|
||||
extractSubjectFromCertificate, generateKeyFromPassword, hmacSha256, randomBytes,
|
||||
AES_gcm_decrypt, AES_gcm_encrypt, ECDHComputeKey, ECKEYGenerateKey, ECKEYMarshalPrivateKey,
|
||||
ECKEYParsePrivateKey, ECPOINTOct2Point, ECPOINTPoint2Oct, EC_KEY_free, EC_KEY_get0_public_key,
|
||||
EC_POINT_free, HKDFExpand, HKDFExtract, EC_KEY, EC_MAX_BYTES, EC_POINT, EVP_MAX_MD_SIZE,
|
||||
extractSubjectFromCertificate, hmacSha256, randomBytes, AES_gcm_decrypt, AES_gcm_encrypt,
|
||||
ECDHComputeKey, ECKEYGenerateKey, ECKEYMarshalPrivateKey, ECKEYParsePrivateKey,
|
||||
ECPOINTOct2Point, ECPOINTPoint2Oct, EC_KEY_free, EC_KEY_get0_public_key, EC_POINT_free,
|
||||
HKDFExpand, HKDFExtract, EC_KEY, EC_MAX_BYTES, EC_POINT, EVP_MAX_MD_SIZE, PBKDF2,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
|
@ -172,7 +172,7 @@ pub fn aes_gcm_encrypt(plaintext: &[u8], key: &[u8]) -> Result<(Vec<u8>, Vec<u8>
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents a "password" that can be used to key the PBKDF2 algorithm.
|
||||
/// A high-entropy synthetic password from which an AES key may be derived.
|
||||
pub enum Password<'a> {
|
||||
/// Borrow an existing byte array
|
||||
Ref(&'a [u8]),
|
||||
|
@ -194,25 +194,28 @@ impl<'a> Password<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generate a key from the given password and salt.
|
||||
/// The salt must be exactly 16 bytes long.
|
||||
/// Two key sizes are accepted: 16 and 32 bytes.
|
||||
pub fn derive_key(&self, salt: &[u8], key_length: usize) -> Result<ZVec, Error> {
|
||||
/// Derives a key from the given password and salt, using PBKDF2 with 8192 iterations.
|
||||
///
|
||||
/// The salt length must be 16 bytes, and the output key length must be 16 or 32 bytes.
|
||||
///
|
||||
/// This function exists only for backwards compatibility reasons. Keystore now receives only
|
||||
/// high-entropy synthetic passwords, which do not require key stretching.
|
||||
pub fn derive_key_pbkdf2(&self, salt: &[u8], out_len: usize) -> Result<ZVec, Error> {
|
||||
if salt.len() != SALT_LENGTH {
|
||||
return Err(Error::InvalidSaltLength);
|
||||
}
|
||||
match key_length {
|
||||
match out_len {
|
||||
AES_128_KEY_LENGTH | AES_256_KEY_LENGTH => {}
|
||||
_ => return Err(Error::InvalidKeyLength),
|
||||
}
|
||||
|
||||
let pw = self.get_key();
|
||||
let mut result = ZVec::new(key_length)?;
|
||||
let mut result = ZVec::new(out_len)?;
|
||||
|
||||
// Safety: We checked that the salt is exactly 16 bytes long. The other pointers are valid,
|
||||
// and have matching lengths.
|
||||
unsafe {
|
||||
generateKeyFromPassword(
|
||||
PBKDF2(
|
||||
result.as_mut_ptr(),
|
||||
result.len(),
|
||||
pw.as_ptr() as *const std::os::raw::c_char,
|
||||
|
@ -224,6 +227,13 @@ impl<'a> Password<'a> {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
/// Derives a key from the given high-entropy synthetic password and salt, using HKDF.
|
||||
pub fn derive_key_hkdf(&self, salt: &[u8], out_len: usize) -> Result<ZVec, Error> {
|
||||
let prk = hkdf_extract(self.get_key(), salt)?;
|
||||
let info = [];
|
||||
hkdf_expand(out_len, &prk, &info)
|
||||
}
|
||||
|
||||
/// Try to make another Password object with the same data.
|
||||
pub fn try_clone(&self) -> Result<Password<'static>, Error> {
|
||||
Ok(Password::Owned(ZVec::try_from(self.get_key())?))
|
||||
|
@ -471,9 +481,7 @@ pub fn parse_subject_from_certificate(cert_buf: &[u8]) -> Result<Vec<u8>, Error>
|
|||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use keystore2_crypto_bindgen::{
|
||||
generateKeyFromPassword, AES_gcm_decrypt, AES_gcm_encrypt, CreateKeyId,
|
||||
};
|
||||
use keystore2_crypto_bindgen::{AES_gcm_decrypt, AES_gcm_encrypt, CreateKeyId, PBKDF2};
|
||||
|
||||
#[test]
|
||||
fn test_wrapper_roundtrip() {
|
||||
|
@ -535,21 +543,15 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_key_from_password() {
|
||||
fn test_pbkdf2() {
|
||||
let mut key = vec![0; 16];
|
||||
let pw = [0; 16];
|
||||
let salt = [0; 16];
|
||||
// SAFETY: The pointers are obtained from references so they are valid, the salt is the
|
||||
// expected length, the other lengths match the lengths of the arrays, and
|
||||
// `generateKeyFromPassword` doesn't access them after it returns.
|
||||
// expected length, the other lengths match the lengths of the arrays, and `PBKDF2` doesn't
|
||||
// access them after it returns.
|
||||
unsafe {
|
||||
generateKeyFromPassword(
|
||||
key.as_mut_ptr(),
|
||||
key.len(),
|
||||
pw.as_ptr(),
|
||||
pw.len(),
|
||||
salt.as_ptr(),
|
||||
);
|
||||
PBKDF2(key.as_mut_ptr(), key.len(), pw.as_ptr(), pw.len(), salt.as_ptr());
|
||||
}
|
||||
assert_ne!(key, vec![0; 16]);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ rust_fuzz {
|
|||
name: "keystore2_unsafe_fuzzer",
|
||||
srcs: ["keystore2_unsafe_fuzzer.rs"],
|
||||
rustlibs: [
|
||||
"libarbitrary",
|
||||
"libkeystore2",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"libkeystore2_aaid-rust",
|
||||
"libkeystore2_apc_compat-rust",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"libkeystore2_selinux",
|
||||
"libarbitrary",
|
||||
],
|
||||
fuzz_config: {
|
||||
fuzz_on_haiku_device: true,
|
||||
|
@ -38,19 +38,18 @@ rust_fuzz {
|
|||
},
|
||||
}
|
||||
|
||||
|
||||
rust_fuzz {
|
||||
name: "authorization_service_fuzzer",
|
||||
srcs: ["aidl-fuzzers/authorization_service_fuzzer.rs"],
|
||||
rustlibs: [
|
||||
"libbinder_random_parcel_rs",
|
||||
"libbinder_rs",
|
||||
"libkeystore2",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"libkeystore2_aaid-rust",
|
||||
"libkeystore2_apc_compat-rust",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_hal_names_rust",
|
||||
"libkeystore2_selinux",
|
||||
"libbinder_rs",
|
||||
"libbinder_random_parcel_rs",
|
||||
],
|
||||
fuzz_config: {
|
||||
fuzz_on_haiku_device: true,
|
||||
|
@ -58,7 +57,7 @@ rust_fuzz {
|
|||
cc: [
|
||||
"android-media-fuzzing-reports@google.com",
|
||||
"smoreland@google.com",
|
||||
"waghpawan@google.com"
|
||||
"waghpawan@google.com",
|
||||
],
|
||||
// Adds bugs to hotlist "AIDL fuzzers bugs" on buganizer
|
||||
hotlists: ["4637097"],
|
||||
|
|
|
@ -144,7 +144,8 @@ fuzz_target!(|commands: Vec<FuzzCommand>| {
|
|||
let _res = aes_gcm_encrypt(plaintext, key_aes_encrypt);
|
||||
}
|
||||
FuzzCommand::Password { pw, salt, key_length } => {
|
||||
let _res = Password::from(pw).derive_key(salt, key_length % MAX_SIZE_MODIFIER);
|
||||
let _res =
|
||||
Password::from(pw).derive_key_pbkdf2(salt, key_length % MAX_SIZE_MODIFIER);
|
||||
}
|
||||
FuzzCommand::HkdfExtract { hkdf_secret, hkdf_salt } => {
|
||||
let _res = hkdf_extract(hkdf_secret, hkdf_salt);
|
||||
|
|
|
@ -33,7 +33,7 @@ rust_library {
|
|||
],
|
||||
shared_libs: [
|
||||
"libkm_compat_service",
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
rust_test {
|
||||
|
@ -91,9 +91,9 @@ cc_library {
|
|||
"android.security.compat-ndk",
|
||||
"libbinder_ndk",
|
||||
"libcrypto",
|
||||
"libkm_compat",
|
||||
"libkeymaster4_1support",
|
||||
"libkeystore2_crypto",
|
||||
"libkm_compat",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -1313,7 +1313,7 @@ impl LegacyBlobLoader {
|
|||
Blob { flags, value: BlobValue::PwEncrypted { iv, tag, data, salt, key_size } } => {
|
||||
if (flags & flags::ENCRYPTED) != 0 {
|
||||
let key = pw
|
||||
.derive_key(&salt, key_size)
|
||||
.derive_key_pbkdf2(&salt, key_size)
|
||||
.context(ks_err!("Failed to derive key from password."))?;
|
||||
let blob = aes_gcm_decrypt(&data, &iv, &tag, &key)
|
||||
.context(ks_err!("while trying to decrypt legacy super key blob."))?;
|
||||
|
@ -1953,7 +1953,7 @@ mod test {
|
|||
std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
|
||||
|
||||
let pw: Password = PASSWORD.into();
|
||||
let pw_key = TestKey(pw.derive_key(SUPERKEY_SALT, 32).unwrap());
|
||||
let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
|
||||
let super_key =
|
||||
Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
|
||||
|
||||
|
@ -2040,7 +2040,7 @@ mod test {
|
|||
std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
|
||||
|
||||
let pw: Password = PASSWORD.into();
|
||||
let pw_key = TestKey(pw.derive_key(SUPERKEY_SALT, 32).unwrap());
|
||||
let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
|
||||
let super_key =
|
||||
Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
|
||||
|
||||
|
@ -2128,7 +2128,7 @@ mod test {
|
|||
std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
|
||||
|
||||
let pw: Password = PASSWORD.into();
|
||||
let pw_key = TestKey(pw.derive_key(SUPERKEY_SALT, 32).unwrap());
|
||||
let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
|
||||
let super_key =
|
||||
Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
|
||||
|
||||
|
|
|
@ -532,11 +532,17 @@ impl SuperKeyManager {
|
|||
(Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
|
||||
// Note that password encryption is AES no matter the value of algorithm.
|
||||
let key = pw
|
||||
.derive_key(salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to generate key from password."))?;
|
||||
.derive_key_hkdf(salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to derive key from password."))?;
|
||||
|
||||
aes_gcm_decrypt(blob, iv, tag, &key)
|
||||
.context(ks_err!("Failed to decrypt key blob."))?
|
||||
aes_gcm_decrypt(blob, iv, tag, &key).or_else(|_e| {
|
||||
// Handle old key stored before the switch to HKDF.
|
||||
let key = pw
|
||||
.derive_key_pbkdf2(salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to derive key from password (PBKDF2)."))?;
|
||||
aes_gcm_decrypt(blob, iv, tag, &key)
|
||||
.context(ks_err!("Failed to decrypt key blob."))
|
||||
})?
|
||||
}
|
||||
(enc_by, salt, iv, tag) => {
|
||||
return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(ks_err!(
|
||||
|
@ -563,14 +569,20 @@ impl SuperKeyManager {
|
|||
}
|
||||
|
||||
/// Encrypts the super key from a key derived from the password, before storing in the database.
|
||||
/// This does not stretch the password; i.e., it assumes that the password is a high-entropy
|
||||
/// synthetic password, not a low-entropy user provided password.
|
||||
pub fn encrypt_with_password(
|
||||
super_key: &[u8],
|
||||
pw: &Password,
|
||||
) -> Result<(Vec<u8>, BlobMetaData)> {
|
||||
let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
|
||||
let derived_key = pw
|
||||
.derive_key(&salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to derive password."))?;
|
||||
let derived_key = if android_security_flags::fix_unlocked_device_required_keys_v2() {
|
||||
pw.derive_key_hkdf(&salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to derive key from password."))?
|
||||
} else {
|
||||
pw.derive_key_pbkdf2(&salt, AES_256_KEY_LENGTH)
|
||||
.context(ks_err!("Failed to derive password."))?
|
||||
};
|
||||
let mut metadata = BlobMetaData::new();
|
||||
metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
|
||||
metadata.add(BlobMetaEntry::Salt(salt));
|
||||
|
|
|
@ -28,6 +28,7 @@ rust_defaults {
|
|||
"keystore2_use_latest_aidl_rust",
|
||||
],
|
||||
rustlibs: [
|
||||
"android.security.authorization-rust",
|
||||
"libanyhow",
|
||||
"libbinder_rs",
|
||||
"libcxx",
|
||||
|
@ -39,11 +40,10 @@ rust_defaults {
|
|||
"libserde",
|
||||
"libserde_cbor",
|
||||
"libthiserror",
|
||||
"android.security.authorization-rust",
|
||||
],
|
||||
static_libs: [
|
||||
"libkeystore2_ffi_test_utils",
|
||||
"libkeystore-engine",
|
||||
"libkeystore2_ffi_test_utils",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.system.keystore2-V4-ndk",
|
||||
|
|
|
@ -31,17 +31,17 @@ rust_test {
|
|||
test_config: "AndroidTest.xml",
|
||||
|
||||
rustlibs: [
|
||||
"libkeystore2_with_test_utils",
|
||||
"libkeystore2_crypto_rust",
|
||||
"android.security.maintenance-rust",
|
||||
"android.security.authorization-rust",
|
||||
"librustutils",
|
||||
"libkeystore2_test_utils",
|
||||
"libnix",
|
||||
"android.security.maintenance-rust",
|
||||
"libanyhow",
|
||||
"libbinder_rs",
|
||||
"libkeystore2_crypto_rust",
|
||||
"libkeystore2_test_utils",
|
||||
"libkeystore2_with_test_utils",
|
||||
"liblazy_static",
|
||||
"liblibc",
|
||||
"libnix",
|
||||
"librustutils",
|
||||
"libserde",
|
||||
"libthiserror",
|
||||
],
|
||||
|
|
|
@ -174,7 +174,7 @@ fn keystore2_encrypted_characteristics() -> anyhow::Result<()> {
|
|||
|
||||
// Create keystore file layout for user_99.
|
||||
let pw: Password = PASSWORD.into();
|
||||
let pw_key = TestKey(pw.derive_key(SUPERKEY_SALT, 32).unwrap());
|
||||
let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
|
||||
let super_key =
|
||||
TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
|
||||
|
||||
|
@ -427,7 +427,7 @@ fn keystore2_encrypted_certificates() -> anyhow::Result<()> {
|
|||
|
||||
// Create keystore file layout for user_98.
|
||||
let pw: Password = PASSWORD.into();
|
||||
let pw_key = TestKey(pw.derive_key(SUPERKEY_SALT, 32).unwrap());
|
||||
let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
|
||||
let super_key =
|
||||
TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ rust_defaults {
|
|||
srcs: ["src/lib.rs"],
|
||||
rustlibs: [
|
||||
"liblog_rust",
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
rust_library {
|
||||
|
@ -45,5 +45,5 @@ rust_test {
|
|||
test_suites: ["general-tests"],
|
||||
rustlibs: [
|
||||
"libandroid_logger",
|
||||
]
|
||||
],
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue