diff options
author | Rajesh Nyamagoud <nyamagoud@google.com> | 2023-05-12 01:16:07 +0000 |
---|---|---|
committer | Rajesh Nyamagoud <nyamagoud@google.com> | 2023-10-09 21:44:48 +0000 |
commit | f436a9326c19134f6f7e0a06b7221f64915a6b4b (patch) | |
tree | 91b2279d3cf13e7a0f57a496c6fc4ead2a3a0ed6 /keystore2/test_utils | |
parent | 75dfa0c2ec8c93cc5b064838401fef32a07147ab (diff) | |
download | security-f436a9326c19134f6f7e0a06b7221f64915a6b4b.tar.gz |
Adding tests using `MAX_USES_PER_BOOT`, `EARLY_BOOT_ONLY`, `BOOTLOADER_ONLY` and `USAGE_COUNT_LIMIT`
1. Generate a key with `BOOTLOADER_ONLY` tag. Test should successfully
generate a key and verify the key characteristics. Test should fail
with error code `INVALID_KEY_BLOB` during creation of an operation
using this key.
2. Generate a key with `EARLY_BOOT_ONLY` tag. Test should successfully
generate a key and verify the key characteristics. Test should fail
with error code `EARLY_BOOT_ENDED` during creation of an operation
using this key.
3. Generate a key with `MAX_USES_PER_BOOT` tag. Test should successfully
generate a key and verify the key characteristics. Test should be
able to use the key successfully `MAX_USES_COUNT` times. After
exceeding key usage `MAX_USES_COUNT` times subsequent attempts to use
the key in test should fail with error code `MAX_OPS_EXCEEDED`.
4. Generate a key with `USAGE_COUNT_LIMIT` tag. Test should successfully
generate a key and verify the key characteristics. Test should be
able to use the key successfully `MAX_USES_COUNT` times. After
exceeding key usage `MAX_USES_COUNT` times subsequent attempts to use
the key in test should fail with error code `KEY_NOT_FOUND`. Test
should also check attest record for attested keys that
`USAGE_COUNT_LIMIT` is included in attest record.
Bug: 279721870
Test: atest keystore2_client_tests
Change-Id: I205964b571d92dc0fcbd11b1f6d45bc3aea7c050
Diffstat (limited to 'keystore2/test_utils')
-rw-r--r-- | keystore2/test_utils/authorizations.rs | 36 | ||||
-rw-r--r-- | keystore2/test_utils/ffi_test_utils.cpp | 35 | ||||
-rw-r--r-- | keystore2/test_utils/ffi_test_utils.hpp | 10 | ||||
-rw-r--r-- | keystore2/test_utils/ffi_test_utils.rs | 18 | ||||
-rw-r--r-- | keystore2/test_utils/key_generations.rs | 12 |
5 files changed, 101 insertions, 10 deletions
diff --git a/keystore2/test_utils/authorizations.rs b/keystore2/test_utils/authorizations.rs index aa75982c..b73aab51 100644 --- a/keystore2/test_utils/authorizations.rs +++ b/keystore2/test_utils/authorizations.rs @@ -269,6 +269,42 @@ impl AuthSetBuilder { }); self } + + /// Set boot loader only. + pub fn boot_loader_only(mut self) -> Self { + self.0.push(KeyParameter { + tag: Tag::BOOTLOADER_ONLY, + value: KeyParameterValue::BoolValue(true), + }); + self + } + + /// Set early boot only. + pub fn early_boot_only(mut self) -> Self { + self.0.push(KeyParameter { + tag: Tag::EARLY_BOOT_ONLY, + value: KeyParameterValue::BoolValue(true), + }); + self + } + + /// Set max uses per boot. + pub fn max_uses_per_boot(mut self, max_uses: i32) -> Self { + self.0.push(KeyParameter { + tag: Tag::MAX_USES_PER_BOOT, + value: KeyParameterValue::Integer(max_uses), + }); + self + } + + /// Set max usage count. + pub fn usage_count_limit(mut self, usage_count: i32) -> Self { + self.0.push(KeyParameter { + tag: Tag::USAGE_COUNT_LIMIT, + value: KeyParameterValue::Integer(usage_count), + }); + self + } } impl Deref for AuthSetBuilder { diff --git a/keystore2/test_utils/ffi_test_utils.cpp b/keystore2/test_utils/ffi_test_utils.cpp index 07408044..4e781d10 100644 --- a/keystore2/test_utils/ffi_test_utils.cpp +++ b/keystore2/test_utils/ffi_test_utils.cpp @@ -601,7 +601,8 @@ bool performCryptoOpUsingKeystoreEngine(int64_t grant_id) { return result; } -CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag) { +CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag, + int32_t expected_sec_level) { CxxResult cxx_result{}; cxx_result.error = false; @@ -649,6 +650,8 @@ CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag) { aidl::android::hardware::security::keymint::Tag auth_tag = static_cast<aidl::android::hardware::security::keymint::Tag>(tag); + aidl::android::hardware::security::keymint::SecurityLevel tag_security_level = + static_cast<aidl::android::hardware::security::keymint::SecurityLevel>(expected_sec_level); if (auth_tag == aidl::android::hardware::security::keymint::Tag::ATTESTATION_APPLICATION_ID) { int pos = att_sw_enforced.find( @@ -685,6 +688,36 @@ CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag) { return cxx_result; } + if (auth_tag == aidl::android::hardware::security::keymint::Tag::USAGE_COUNT_LIMIT) { + aidl::android::hardware::security::keymint::KeyParameter param; + int pos = att_hw_enforced.find(auth_tag); + if (tag_security_level == + aidl::android::hardware::security::keymint::SecurityLevel::SOFTWARE || + tag_security_level == + aidl::android::hardware::security::keymint::SecurityLevel::KEYSTORE) { + pos = att_sw_enforced.find(auth_tag); + if (pos == -1) { + LOG(ERROR) << "USAGE_COUNT_LIMIT not found in software enforced auth list"; + cxx_result.error = KM_ERROR_INVALID_TAG; + return cxx_result; + } + param = att_sw_enforced[pos]; + } else { + pos = att_hw_enforced.find(auth_tag); + if (pos == -1) { + LOG(ERROR) << "USAGE_COUNT_LIMIT not found in hardware enforced auth list"; + cxx_result.error = KM_ERROR_INVALID_TAG; + return cxx_result; + } + param = att_hw_enforced[pos]; + } + std::string val = std::to_string( + param.value + .get<aidl::android::hardware::security::keymint::KeyParameterValue::integer>()); + std::move(val.begin(), val.end(), std::back_inserter(cxx_result.data)); + return cxx_result; + } + int pos = att_hw_enforced.find(auth_tag); if (pos == -1) { LOG(ERROR) << "getValueFromAttestRecord - unsupported tag."; diff --git a/keystore2/test_utils/ffi_test_utils.hpp b/keystore2/test_utils/ffi_test_utils.hpp index 69f558a0..c4db1ba4 100644 --- a/keystore2/test_utils/ffi_test_utils.hpp +++ b/keystore2/test_utils/ffi_test_utils.hpp @@ -1,16 +1,16 @@ #pragma once -#include "rust/cxx.h" #include "ffi_test_utils.rs.h" +#include "rust/cxx.h" bool validateCertChain(rust::Vec<rust::u8> cert_buf, uint32_t cert_len, bool strict_issuer_check); CxxResult createWrappedKey(rust::Vec<rust::u8> encrypted_secure_key, - rust::Vec<rust::u8> encrypted_transport_key, - rust::Vec<rust::u8> iv, - rust::Vec<rust::u8> tag); + rust::Vec<rust::u8> encrypted_transport_key, rust::Vec<rust::u8> iv, + rust::Vec<rust::u8> tag); CxxResult buildAsn1DerEncodedWrappedKeyDescription(); bool performCryptoOpUsingKeystoreEngine(int64_t grant_id); -CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag); +CxxResult getValueFromAttestRecord(rust::Vec<rust::u8> cert_buf, int32_t tag, + int32_t expected_sec_level); 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 04d82f11..5d6bf46e 100644 --- a/keystore2/test_utils/ffi_test_utils.rs +++ b/keystore2/test_utils/ffi_test_utils.rs @@ -15,7 +15,9 @@ //! This module implements helper methods to access the functionalities implemented in CPP. use crate::key_generations::Error; -use android_hardware_security_keymint::aidl::android::hardware::security::keymint::Tag::Tag; +use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ + SecurityLevel::SecurityLevel, Tag::Tag, +}; #[cxx::bridge] mod ffi { @@ -35,7 +37,11 @@ mod ffi { ) -> CxxResult; fn buildAsn1DerEncodedWrappedKeyDescription() -> CxxResult; fn performCryptoOpUsingKeystoreEngine(grant_id: i64) -> bool; - fn getValueFromAttestRecord(cert_buf: Vec<u8>, tag: i32) -> CxxResult; + fn getValueFromAttestRecord( + cert_buf: Vec<u8>, + tag: i32, + expected_sec_level: i32, + ) -> CxxResult; fn getOsVersion() -> u32; fn getOsPatchlevel() -> u32; fn getVendorPatchlevel() -> u32; @@ -98,8 +104,12 @@ pub fn perform_crypto_op_using_keystore_engine(grant_id: i64) -> Result<bool, Er } /// Get the value of the given `Tag` from attestation record. -pub fn get_value_from_attest_record(cert_buf: &[u8], tag: Tag) -> Result<Vec<u8>, Error> { - let result = ffi::getValueFromAttestRecord(cert_buf.to_vec(), tag.0); +pub fn get_value_from_attest_record( + cert_buf: &[u8], + tag: Tag, + expected_sec_level: SecurityLevel, +) -> Result<Vec<u8>, Error> { + let result = ffi::getValueFromAttestRecord(cert_buf.to_vec(), tag.0, expected_sec_level.0); if !result.error && !result.data.is_empty() { return Ok(result.data); } diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs index 24ce6e19..ccf27bc6 100644 --- a/keystore2/test_utils/key_generations.rs +++ b/keystore2/test_utils/key_generations.rs @@ -470,6 +470,18 @@ fn check_common_auths(authorizations: &[Authorization], expected_key_origin: Key )); } +/// Get the key `Authorization` for the given auth `Tag`. +pub fn get_key_auth(authorizations: &[Authorization], tag: Tag) -> Option<&Authorization> { + let auths: Vec<&Authorization> = + authorizations.iter().filter(|auth| auth.keyParameter.tag == tag).collect(); + + if !auths.is_empty() { + Some(auths[0]) + } else { + None + } +} + /// Generate EC Key using given security level and domain with below key parameters and /// optionally allow the generated key to be attested with factory provisioned attest key using /// given challenge and application id - |