Add storage tests for lifetimes
Test keys with various persistence levels, enumerated from the
metadata tests.
For read-only keys, do not attempt to create or destroy the key
through the API, only to read a key that has been injected into
storage directly through filesystem access.
Do not test keys with a non-default location, since they require a
driver and we do not yet have a dependency mechanism to require the
presence of a driver for a specific location value.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/scripts/mbedtls_dev/psa_storage.py b/scripts/mbedtls_dev/psa_storage.py
index 3a74007..45f0380 100644
--- a/scripts/mbedtls_dev/psa_storage.py
+++ b/scripts/mbedtls_dev/psa_storage.py
@@ -164,6 +164,10 @@
"""
return self.bytes().hex()
+ def location_value(self) -> int:
+ """The numerical value of the location encoded in the key's lifetime."""
+ return self.lifetime.value() >> 8
+
class TestKey(unittest.TestCase):
# pylint: disable=line-too-long
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 8c53414..9615c29 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -295,6 +295,38 @@
*extra_arguments])
return tc
+ def key_for_lifetime(
+ self,
+ lifetime: str,
+ ) -> StorageKey:
+ """Construct a test key for the given lifetime."""
+ short = lifetime
+ short = re.sub(r'PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION',
+ r'', short)
+ short = re.sub(r'PSA_KEY_[A-Z]+_', r'', short)
+ description = 'lifetime: ' + short
+ key = StorageKey(version=self.version,
+ id=1, lifetime=lifetime,
+ type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+ usage='PSA_KEY_USAGE_EXPORT', alg=0, alg2=0,
+ material=b'L',
+ description=description)
+ return key
+
+ def all_keys_for_lifetimes(self) -> Iterator[StorageKey]:
+ """Generate test keys covering lifetimes."""
+ lifetimes = sorted(self.constructors.lifetimes)
+ expressions = self.constructors.generate_expressions(lifetimes)
+ for lifetime in expressions:
+ # Don't attempt to create or load a volatile key in storage
+ if 'VOLATILE' in lifetime:
+ continue
+ # Don't attempt to create a read-only key in storage,
+ # but do attempt to load one.
+ if 'READ_ONLY' in lifetime and self.forward:
+ continue
+ yield self.key_for_lifetime(lifetime)
+
def key_for_usage_flags(
self,
usage_flags: List[str],
@@ -395,12 +427,17 @@
# one go, which is a significant performance gain as the information
# includes numerical values obtained by compiling a C program.
keys = [] #type: List[StorageKey]
+ keys += self.all_keys_for_lifetimes()
keys += self.all_keys_for_usage_flags()
keys += self.all_keys_for_types()
keys += self.all_keys_for_algorithms()
for key in keys:
+ if key.location_value() != 0:
+ # Skip keys with a non-default location, because they
+ # require a driver and we currently have no mechanism to
+ # determine whether a driver is available.
+ continue
yield self.make_test_case(key)
- # To do: vary id, lifetime
class TestGenerator:
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function
index 34d63a7..003c70b 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.function
+++ b/tests/suites/test_suite_psa_crypto_storage_format.function
@@ -8,6 +8,7 @@
#include <psa_crypto_its.h>
#define TEST_FLAG_EXERCISE 0x00000001
+#define TEST_FLAG_READ_ONLY 0x00000002
/** Write a key with the given attributes and key material to storage.
* Test that it has the expected representation.
@@ -115,10 +116,22 @@
psa_get_key_algorithm( expected_attributes ) ) );
}
- /* Destroy the key. Confirm through direct access to the storage. */
- PSA_ASSERT( psa_destroy_key( key_id ) );
- TEST_EQUAL( PSA_ERROR_DOES_NOT_EXIST,
- psa_its_get_info( uid, &storage_info ) );
+
+ if( flags & TEST_FLAG_READ_ONLY )
+ {
+ /* Read-only keys cannot be removed through the API.
+ * The key will be removed through ITS in the cleanup code below.
+ * Purge the key from memory so that the test framework doesn't
+ * think the test is leaking it. */
+ PSA_ASSERT( psa_purge_key( key_id ) );
+ }
+ else
+ {
+ /* Destroy the key. Confirm through direct access to the storage. */
+ PSA_ASSERT( psa_destroy_key( key_id ) );
+ TEST_EQUAL( PSA_ERROR_DOES_NOT_EXIST,
+ psa_its_get_info( uid, &storage_info ) );
+ }
ok = 1;
@@ -219,7 +232,6 @@
exit:
psa_reset_key_attributes( &attributes );
- psa_destroy_key( key_id );
PSA_DONE( );
}
/* END_CASE */