From e6b85b4d427f3605e676d18d81297920bef96cff Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 18 Mar 2022 09:58:09 +0100 Subject: [PATCH] Storage format tests: exercise operations with keys In key read tests, add usage flags that are suitable for the key type and algorithm. This way, the call to exercise_key() in the test not only checks that exporting the key is possible, but also that operations on the key are possible. This triggers a number of failures in edge cases where the generator generates combinations that are not valid, which will be fixed in subsequent commits. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/crypto_knowledge.py | 30 ++++++++++++++++++++++++- tests/scripts/generate_psa_tests.py | 5 ++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py index 434ecf33e8..6f499403a0 100644 --- a/scripts/mbedtls_dev/crypto_knowledge.py +++ b/scripts/mbedtls_dev/crypto_knowledge.py @@ -20,7 +20,7 @@ This module is entirely based on the PSA API. import enum import re -from typing import Iterable, Optional, Tuple +from typing import Iterable, List, Optional, Tuple from mbedtls_dev.asymmetric_key_data import ASYMMETRIC_KEY_DATA @@ -422,3 +422,31 @@ class Algorithm: self.is_key_agreement_with_derivation(): return True return False + + def usage_flags(self, public: bool = False) -> List[str]: + """The list of usage flags describing operations that can perform this algorithm. + + If public is true, only return public-key operations, not private-key operations. + """ + if self.category == AlgorithmCategory.HASH: + flags = [] + elif self.category == AlgorithmCategory.MAC: + flags = ['SIGN_HASH', 'SIGN_MESSAGE', + 'VERIFY_HASH', 'VERIFY_MESSAGE'] + elif self.category == AlgorithmCategory.CIPHER or \ + self.category == AlgorithmCategory.AEAD: + flags = ['DECRYPT', 'ENCRYPT'] + elif self.category == AlgorithmCategory.SIGN: + flags = ['VERIFY_HASH', 'VERIFY_MESSAGE'] + if not public: + flags += ['SIGN_HASH', 'SIGN_MESSAGE'] + elif self.category == AlgorithmCategory.ASYMMETRIC_ENCRYPTION: + flags = ['ENCRYPT'] + if not public: + flags += ['DECRYPT'] + elif self.category == AlgorithmCategory.KEY_DERIVATION or \ + self.category == AlgorithmCategory.KEY_AGREEMENT: + flags = ['DERIVE'] + else: + raise AlgorithmNotRecognized(self.expression) + return ['PSA_KEY_USAGE_' + flag for flag in flags] diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py index 2a70147055..27ee52d6bb 100755 --- a/tests/scripts/generate_psa_tests.py +++ b/tests/scripts/generate_psa_tests.py @@ -645,8 +645,11 @@ class StorageFormat: If alg is not None, this key allows it. """ usage_flags = ['PSA_KEY_USAGE_EXPORT'] - alg1 = 0 if alg is None else alg.expression #type: psa_storage.Exprable + alg1 = 0 #type: psa_storage.Exprable alg2 = 0 + if alg is not None: + alg1 = alg.expression + usage_flags += alg.usage_flags(public=kt.is_public()) key_material = kt.key_material(bits) description = 'type: {} {}-bit'.format(kt.short_expression(1), bits) if alg is not None: