summaryrefslogtreecommitdiff
path: root/keystore2/test_utils
diff options
context:
space:
mode:
authorRajesh Nyamagoud <nyamagoud@google.com>2023-05-11 00:31:40 +0000
committerRajesh Nyamagoud <nyamagoud@google.com>2023-10-09 21:10:00 +0000
commit75dfa0c2ec8c93cc5b064838401fef32a07147ab (patch)
treec2ee5c30676ba43f9aa0269e21964623081230d8 /keystore2/test_utils
parent3363996eafe6f49817a6f7bed409e37c735021bb (diff)
downloadsecurity-75dfa0c2ec8c93cc5b064838401fef32a07147ab.tar.gz
Adding tests using tags ACTIVE_DATETIME, ORIGINATION_EXPIRE_DATETIME,
USAGE_EXPIRE_DATETIME. 1. Tests will generate a key with current date and time set to active-datetime and verify the key characteristics. Test will use this key to create a sign operation successfully. 2. Test will generate a key with future date set to active-datetime and verify the key characteristics. Test will fail with error code `KEY_NOT_YET_VALID` while creating an operation using generated key. 3. Tests will generate a key with future date and time set to origination-expire-datetime and verify the key characteristics. Test will use this key to create a sign operation successfully. 4. Test will generate a key with current date and time set to origination-expire-datetime and verify the key characteristics. Test will fail with error code `KEY_EXPIRED` while creating an operation using generated key. 5. Tests will generate a key with future date and time set to usage-expire-datetime and verify the key characteristics. Test will use this key to successfully verify the signature created using this key. 6. Tests will generate a key with current date and time set to usage-expire-datetime and verify the key characteristics. Test will fail with error code `KEY_EXPIRED` while verifying the signature created using this key. 7. Test will generate a AES key with future date and time set to usage-expire-datetime and verify the key characteristics. Test will perform encrypt and decrypt operations using this generated key successfully. 8. Test will generate a AES key with current date and time set to usage-expire-datetime and verify the key characteristics. Test will fail with error code `KEY_EXPIRED` while creating Decrypt operation using generated key. Bug: 279721870 Test: atest keystore2_client_tests Change-Id: I8a0865a6256a6da133e95d0ee8250ba67359a2a2
Diffstat (limited to 'keystore2/test_utils')
-rw-r--r--keystore2/test_utils/Android.bp2
-rw-r--r--keystore2/test_utils/authorizations.rs27
-rw-r--r--keystore2/test_utils/ffi_test_utils.cpp13
-rw-r--r--keystore2/test_utils/ffi_test_utils.hpp3
-rw-r--r--keystore2/test_utils/ffi_test_utils.rs18
-rw-r--r--keystore2/test_utils/key_generations.rs150
6 files changed, 196 insertions, 17 deletions
diff --git a/keystore2/test_utils/Android.bp b/keystore2/test_utils/Android.bp
index 9f3a4e90..a3c40cb4 100644
--- a/keystore2/test_utils/Android.bp
+++ b/keystore2/test_utils/Android.bp
@@ -35,6 +35,7 @@ rust_defaults {
"liblog_rust",
"libnix",
"librand",
+ "librustutils",
"libserde",
"libserde_cbor",
"libthiserror",
@@ -82,7 +83,6 @@ cc_library_static {
shared_libs: [
"libbase",
"libcrypto",
- "libcppbor_external",
"libkeymaster_portable",
"libkeystore-engine",
"libkeymint_support",
diff --git a/keystore2/test_utils/authorizations.rs b/keystore2/test_utils/authorizations.rs
index 514cbd3b..aa75982c 100644
--- a/keystore2/test_utils/authorizations.rs
+++ b/keystore2/test_utils/authorizations.rs
@@ -242,6 +242,33 @@ impl AuthSetBuilder {
});
self
}
+
+ /// Set active date-time.
+ pub fn active_date_time(mut self, date: i64) -> Self {
+ self.0.push(KeyParameter {
+ tag: Tag::ACTIVE_DATETIME,
+ value: KeyParameterValue::DateTime(date),
+ });
+ self
+ }
+
+ /// Set origination expire date-time.
+ pub fn origination_expire_date_time(mut self, date: i64) -> Self {
+ self.0.push(KeyParameter {
+ tag: Tag::ORIGINATION_EXPIRE_DATETIME,
+ value: KeyParameterValue::DateTime(date),
+ });
+ self
+ }
+
+ /// Set usage expire date-time.
+ pub fn usage_expire_date_time(mut self, date: i64) -> Self {
+ self.0.push(KeyParameter {
+ tag: Tag::USAGE_EXPIRE_DATETIME,
+ value: KeyParameterValue::DateTime(date),
+ });
+ self
+ }
}
impl Deref for AuthSetBuilder {
diff --git a/keystore2/test_utils/ffi_test_utils.cpp b/keystore2/test_utils/ffi_test_utils.cpp
index 1853c079..07408044 100644
--- a/keystore2/test_utils/ffi_test_utils.cpp
+++ b/keystore2/test_utils/ffi_test_utils.cpp
@@ -8,6 +8,7 @@
#include <keymaster/km_openssl/openssl_err.h>
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymint_support/attestation_record.h>
+#include <keymint_support/keymint_utils.h>
#include <openssl/mem.h>
using keymaster::ASN1_OBJECT_Ptr;
@@ -696,3 +697,15 @@ CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag) {
std::move(val.begin(), val.end(), std::back_inserter(cxx_result.data));
return cxx_result;
}
+
+uint32_t getOsVersion() {
+ return aidl::android::hardware::security::keymint::getOsVersion();
+}
+
+uint32_t getOsPatchlevel() {
+ return aidl::android::hardware::security::keymint::getOsPatchlevel();
+}
+
+uint32_t getVendorPatchlevel() {
+ return aidl::android::hardware::security::keymint::getVendorPatchlevel();
+}
diff --git a/keystore2/test_utils/ffi_test_utils.hpp b/keystore2/test_utils/ffi_test_utils.hpp
index 3ed7edc1..69f558a0 100644
--- a/keystore2/test_utils/ffi_test_utils.hpp
+++ b/keystore2/test_utils/ffi_test_utils.hpp
@@ -11,3 +11,6 @@ CxxResult createWrappedKey(rust::Vec<rust::u8> encrypted_secure_key,
CxxResult buildAsn1DerEncodedWrappedKeyDescription();
bool performCryptoOpUsingKeystoreEngine(int64_t grant_id);
CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag);
+uint32_t getOsVersion();
+uint32_t getOsPatchlevel();
+uint32_t getVendorPatchlevel();
diff --git a/keystore2/test_utils/ffi_test_utils.rs b/keystore2/test_utils/ffi_test_utils.rs
index 95e3160b..04d82f11 100644
--- a/keystore2/test_utils/ffi_test_utils.rs
+++ b/keystore2/test_utils/ffi_test_utils.rs
@@ -36,6 +36,9 @@ mod ffi {
fn buildAsn1DerEncodedWrappedKeyDescription() -> CxxResult;
fn performCryptoOpUsingKeystoreEngine(grant_id: i64) -> bool;
fn getValueFromAttestRecord(cert_buf: Vec<u8>, tag: i32) -> CxxResult;
+ fn getOsVersion() -> u32;
+ fn getOsPatchlevel() -> u32;
+ fn getVendorPatchlevel() -> u32;
}
}
@@ -102,3 +105,18 @@ pub fn get_value_from_attest_record(cert_buf: &[u8], tag: Tag) -> Result<Vec<u8>
}
Err(Error::AttestRecordGetValueFailed)
}
+
+/// Get OS Version
+pub fn get_os_version() -> u32 {
+ ffi::getOsVersion()
+}
+
+/// Get OS Patch Level
+pub fn get_os_patchlevel() -> u32 {
+ ffi::getOsPatchlevel()
+}
+
+/// Get vendor Patch Level
+pub fn get_vendor_patchlevel() -> u32 {
+ ffi::getVendorPatchlevel()
+}
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index 0f9ecbe0..24ce6e19 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -15,11 +15,13 @@
//! This module implements test utils to generate various types of keys.
use anyhow::Result;
-
use core::ops::Range;
+use nix::unistd::getuid;
use std::collections::HashSet;
use std::fmt::Write;
+use binder::ThreadState;
+
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
ErrorCode::ErrorCode, HardwareAuthenticatorType::HardwareAuthenticatorType,
@@ -27,7 +29,8 @@ use android_hardware_security_keymint::aidl::android::hardware::security::keymin
KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, Tag::Tag,
};
use android_system_keystore2::aidl::android::system::keystore2::{
- AuthenticatorSpec::AuthenticatorSpec, Authorization::Authorization, Domain::Domain,
+ AuthenticatorSpec::AuthenticatorSpec, Authorization::Authorization,
+ CreateOperationResponse::CreateOperationResponse, Domain::Domain,
IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
};
@@ -35,6 +38,8 @@ use android_system_keystore2::aidl::android::system::keystore2::{
use crate::authorizations::AuthSetBuilder;
use android_system_keystore2::binder::{ExceptionCode, Result as BinderResult};
+use crate::ffi_test_utils::{get_os_patchlevel, get_os_version, get_vendor_patchlevel};
+
/// Shell namespace.
pub const SELINUX_SHELL_NAMESPACE: i64 = 1;
/// Vold namespace.
@@ -388,7 +393,12 @@ pub fn check_key_param(authorizations: &[Authorization], key_param: &KeyParamete
authorizations.iter().any(|auth| &auth.keyParameter == key_param)
}
-fn check_key_authorizations(authorizations: &[Authorization], expected_params: &[KeyParameter]) {
+/// Verify the given key authorizations with the expected authorizations.
+pub fn check_key_authorizations(
+ authorizations: &[Authorization],
+ expected_params: &[KeyParameter],
+ expected_key_origin: KeyOrigin,
+) {
// Make sure key authorizations contains only `ALLOWED_TAGS_IN_KEY_AUTHS`
authorizations.iter().all(|auth| {
assert!(
@@ -410,6 +420,54 @@ fn check_key_authorizations(authorizations: &[Authorization], expected_params: &
}
true
});
+
+ check_common_auths(authorizations, expected_key_origin);
+}
+
+/// Verify common key authorizations.
+fn check_common_auths(authorizations: &[Authorization], expected_key_origin: KeyOrigin) {
+ assert!(check_key_param(
+ authorizations,
+ &KeyParameter {
+ tag: Tag::OS_VERSION,
+ value: KeyParameterValue::Integer(get_os_version().try_into().unwrap())
+ }
+ ));
+ assert!(check_key_param(
+ authorizations,
+ &KeyParameter {
+ tag: Tag::OS_PATCHLEVEL,
+ value: KeyParameterValue::Integer(get_os_patchlevel().try_into().unwrap())
+ }
+ ));
+
+ // Access denied for finding vendor-patch-level ("ro.vendor.build.security_patch") property
+ // in a test running with `untrusted_app` context. Keeping this check to verify
+ // vendor-patch-level in tests running with `su` context.
+ if getuid().is_root() {
+ assert!(check_key_param(
+ authorizations,
+ &KeyParameter {
+ tag: Tag::VENDOR_PATCHLEVEL,
+ value: KeyParameterValue::Integer(get_vendor_patchlevel().try_into().unwrap())
+ }
+ ));
+ }
+ assert!(check_key_param(
+ authorizations,
+ &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(expected_key_origin) }
+ ));
+ assert!(check_key_param(
+ authorizations,
+ &KeyParameter {
+ tag: Tag::USER_ID,
+ value: KeyParameterValue::Integer(
+ rustutils::users::multiuser_get_user_id(ThreadState::get_calling_uid())
+ .try_into()
+ .unwrap()
+ )
+ }
+ ));
}
/// Generate EC Key using given security level and domain with below key parameters and
@@ -455,7 +513,11 @@ pub fn generate_ec_p256_signing_key(
assert!(key_metadata.key.blob.is_some());
}
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(
+ &key_metadata.authorizations,
+ &gen_params,
+ KeyOrigin::GENERATED,
+ );
Ok(key_metadata)
}
Err(e) => Err(e),
@@ -498,7 +560,7 @@ pub fn generate_ec_key(
} else {
assert!(key_metadata.key.blob.is_none());
}
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(&key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
Ok(key_metadata)
}
@@ -560,7 +622,7 @@ pub fn generate_rsa_key(
|| key_metadata.key.blob.is_none()
);
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(&key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
// If `RSA_OAEP_MGF_DIGEST` tag is not mentioned explicitly while generating/importing a key,
// then make sure `RSA_OAEP_MGF_DIGEST` tag with default value (SHA1) must not be included in
// key authorization list.
@@ -617,7 +679,7 @@ pub fn generate_sym_key(
// Should not have an attestation record.
assert!(key_metadata.certificateChain.is_none());
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(&key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
Ok(key_metadata)
}
@@ -657,7 +719,7 @@ pub fn generate_hmac_key(
// Should not have an attestation record.
assert!(key_metadata.certificateChain.is_none());
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(&key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
Ok(key_metadata)
}
@@ -742,7 +804,11 @@ pub fn generate_ec_attestation_key(
// Should have an attestation record.
assert!(attestation_key_metadata.certificateChain.is_some());
- check_key_authorizations(&attestation_key_metadata.authorizations, &gen_params);
+ check_key_authorizations(
+ &attestation_key_metadata.authorizations,
+ &gen_params,
+ KeyOrigin::GENERATED,
+ );
Ok(attestation_key_metadata)
}
@@ -777,7 +843,7 @@ pub fn generate_ec_256_attested_key(
// Shouldn't have an attestation record.
assert!(ec_key_metadata.certificateChain.is_none());
- check_key_authorizations(&ec_key_metadata.authorizations, &ec_gen_params);
+ check_key_authorizations(&ec_key_metadata.authorizations, &ec_gen_params, KeyOrigin::GENERATED);
Ok(ec_key_metadata)
}
@@ -802,7 +868,7 @@ pub fn import_rsa_2048_key(
assert!(key_metadata.certificate.is_some());
assert!(key_metadata.certificateChain.is_none());
- check_key_authorizations(&key_metadata.authorizations, &import_params);
+ check_key_authorizations(&key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
// Check below auths explicitly, they might not be addd in import parameters.
assert!(check_key_param(
@@ -865,7 +931,7 @@ pub fn import_ec_p_256_key(
assert!(key_metadata.certificate.is_some());
assert!(key_metadata.certificateChain.is_none());
- check_key_authorizations(&key_metadata.authorizations, &import_params);
+ check_key_authorizations(&key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
// Check below auths explicitly, they might not be addd in import parameters.
assert!(check_key_param(
@@ -917,7 +983,7 @@ pub fn import_aes_key(
AES_KEY,
)?;
- check_key_authorizations(&key_metadata.authorizations, &import_params);
+ check_key_authorizations(&key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
// Check below auths explicitly, they might not be addd in import parameters.
assert!(check_key_param(
@@ -976,7 +1042,7 @@ pub fn import_3des_key(
TRIPLE_DES_KEY,
)?;
- check_key_authorizations(&key_metadata.authorizations, &import_params);
+ check_key_authorizations(&key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
// Check below auths explicitly, they might not be addd in import parameters.
assert!(check_key_param(
@@ -1036,7 +1102,7 @@ pub fn import_hmac_key(
HMAC_KEY,
)?;
- check_key_authorizations(&key_metadata.authorizations, &import_params);
+ check_key_authorizations(&key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
// Check below auths explicitly, they might not be addd in import parameters.
assert!(check_key_param(
@@ -1188,7 +1254,11 @@ pub fn generate_ec_agree_key(
assert!(key_metadata.key.blob.is_some());
}
- check_key_authorizations(&key_metadata.authorizations, &gen_params);
+ check_key_authorizations(
+ &key_metadata.authorizations,
+ &gen_params,
+ KeyOrigin::GENERATED,
+ );
Ok(key_metadata)
}
Err(e) => Err(e),
@@ -1288,3 +1358,51 @@ pub fn generate_key_with_attest_id(
b"entropy",
)
}
+
+/// Generate Key and validate key characteristics.
+pub fn generate_key(
+ sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+ gen_params: &AuthSetBuilder,
+ alias: &str,
+) -> binder::Result<KeyMetadata> {
+ let key_metadata = sec_level.generateKey(
+ &KeyDescriptor {
+ domain: Domain::APP,
+ nspace: -1,
+ alias: Some(alias.to_string()),
+ blob: None,
+ },
+ None,
+ gen_params,
+ 0,
+ b"entropy",
+ )?;
+
+ if gen_params.iter().any(|kp| {
+ matches!(
+ kp.value,
+ KeyParameterValue::Algorithm(Algorithm::RSA)
+ | KeyParameterValue::Algorithm(Algorithm::EC)
+ )
+ }) {
+ assert!(key_metadata.certificate.is_some());
+ if gen_params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
+ assert!(key_metadata.certificateChain.is_some());
+ }
+ }
+ check_key_authorizations(&key_metadata.authorizations, gen_params, KeyOrigin::GENERATED);
+
+ Ok(key_metadata)
+}
+
+/// Generate a key using given authorizations and create an operation using the generated key.
+pub fn create_key_and_operation(
+ sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+ gen_params: &AuthSetBuilder,
+ op_params: &AuthSetBuilder,
+ alias: &str,
+) -> binder::Result<CreateOperationResponse> {
+ let key_metadata = generate_key(sec_level, gen_params, alias)?;
+
+ sec_level.createOperation(&key_metadata.key, op_params, false)
+}