summaryrefslogtreecommitdiff
path: root/keystore2/test_utils
diff options
context:
space:
mode:
authorRajesh Nyamagoud <nyamagoud@google.com>2023-05-12 01:16:07 +0000
committerRajesh Nyamagoud <nyamagoud@google.com>2023-10-09 21:44:48 +0000
commitf436a9326c19134f6f7e0a06b7221f64915a6b4b (patch)
tree91b2279d3cf13e7a0f57a496c6fc4ead2a3a0ed6 /keystore2/test_utils
parent75dfa0c2ec8c93cc5b064838401fef32a07147ab (diff)
downloadsecurity-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.rs36
-rw-r--r--keystore2/test_utils/ffi_test_utils.cpp35
-rw-r--r--keystore2/test_utils/ffi_test_utils.hpp10
-rw-r--r--keystore2/test_utils/ffi_test_utils.rs18
-rw-r--r--keystore2/test_utils/key_generations.rs12
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 -