mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-06-05 21:15:09 +00:00
Merge pull request #265 from gilles-peskine-arm/crypto_knowledge-psa_spec_1.4-no_pake
Crypto knowledge: up to PSA Crypto 1.4, XOF test driver
This commit is contained in:
@@ -48,6 +48,7 @@ my @types = qw(unsigned-int int size_t
|
||||
psa_key_derivation_operation_t
|
||||
psa_sign_hash_interruptible_operation_t
|
||||
psa_verify_hash_interruptible_operation_t
|
||||
psa_xof_operation_t
|
||||
mbedtls_svc_key_id_t
|
||||
psa_key_agreement_iop_t
|
||||
psa_generate_key_iop_t
|
||||
@@ -62,11 +63,30 @@ my %isa = (
|
||||
"psa_key_derivation_step_t" => "uint16_t",
|
||||
);
|
||||
|
||||
# Compile-time guards for some types: the type $type is defined only
|
||||
# if the preprocessor conditional $type_guards{$type} is true.
|
||||
# If a type has no guard, assume that it's always defined.
|
||||
# The guard must be a preprocessor expression with no newline or comment.
|
||||
my %type_guards = (
|
||||
psa_xof_operation_t => "defined(PSA_ALG_CATEGORY_XOF)",
|
||||
);
|
||||
|
||||
sub type_guard {
|
||||
my ($type, $start) = @_;
|
||||
return unless exists $type_guards{$type};
|
||||
if ($start) {
|
||||
print "\n#if $type_guards{$type}";
|
||||
} else {
|
||||
print "#endif /* $type_guards{$type} */\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($which eq "h") {
|
||||
|
||||
print h_header();
|
||||
|
||||
for my $type (@types) {
|
||||
type_guard($type, 1);
|
||||
if ($type eq "buffer") {
|
||||
print declare_buffer_functions();
|
||||
} else {
|
||||
@@ -80,6 +100,7 @@ if ($which eq "h") {
|
||||
print declare_deserialise($type, "server_");
|
||||
}
|
||||
}
|
||||
type_guard($type, 0);
|
||||
}
|
||||
|
||||
} elsif ($which eq "c") {
|
||||
@@ -91,12 +112,15 @@ if ($which eq "h") {
|
||||
|
||||
for my $type (@types) {
|
||||
next unless $type =~ /^psa_(\w+)_operation_t$/;
|
||||
type_guard($type, 1);
|
||||
print define_operation_type_data_and_functions($1);
|
||||
type_guard($type, 0);
|
||||
}
|
||||
|
||||
print c_define_begins();
|
||||
|
||||
for my $type (@types) {
|
||||
type_guard($type, 1);
|
||||
if ($type eq "buffer") {
|
||||
print define_buffer_functions();
|
||||
} elsif (exists($isa{$type})) {
|
||||
@@ -114,6 +138,7 @@ if ($which eq "h") {
|
||||
print define_server_deserialise($type);
|
||||
}
|
||||
}
|
||||
type_guard($type, 0);
|
||||
}
|
||||
|
||||
print define_server_serialize_reset(@types);
|
||||
@@ -982,12 +1007,18 @@ EOF
|
||||
|
||||
my $what = $1; # e.g. "hash_operation"
|
||||
|
||||
if (exists $type_guards{$type}) {
|
||||
$code .= "#if $type_guards{$type}\n";
|
||||
}
|
||||
$code .= <<EOF;
|
||||
memset(${what}_handles, 0,
|
||||
sizeof(${what}_handles));
|
||||
memset(${what}s, 0,
|
||||
sizeof(${what}s));
|
||||
EOF
|
||||
if (exists $type_guards{$type}) {
|
||||
$code .= "#endif /* $type_guards{$type} */\n";
|
||||
}
|
||||
}
|
||||
|
||||
$code .= <<EOF;
|
||||
|
||||
@@ -341,23 +341,31 @@ class OpFail:
|
||||
def test_cases_for_algorithm(
|
||||
self,
|
||||
alg: crypto_knowledge.Algorithm,
|
||||
categories: Iterable[crypto_knowledge.AlgorithmCategory]
|
||||
) -> Iterator[test_case.TestCase]:
|
||||
"""Generate operation failure test cases for the specified algorithm."""
|
||||
for category in crypto_knowledge.AlgorithmCategory:
|
||||
if category == crypto_knowledge.AlgorithmCategory.PAKE:
|
||||
# PAKE operations are not implemented yet
|
||||
pass
|
||||
elif category.requires_key():
|
||||
for category in categories:
|
||||
if category.requires_key():
|
||||
yield from self.one_key_test_cases(alg, category)
|
||||
else:
|
||||
yield from self.no_key_test_cases(alg, category)
|
||||
|
||||
def all_test_cases(self) -> Iterator[test_case.TestCase]:
|
||||
"""Generate all test cases for operations that must fail."""
|
||||
algorithms = sorted(self.constructors.algorithms)
|
||||
for expr in self.constructors.generate_expressions(algorithms):
|
||||
alg = crypto_knowledge.Algorithm(expr)
|
||||
yield from self.test_cases_for_algorithm(alg)
|
||||
algorithm_constructors = sorted(self.constructors.algorithms)
|
||||
algorithms = [crypto_knowledge.Algorithm(alg)
|
||||
for alg in self.constructors.generate_expressions(
|
||||
algorithm_constructors)]
|
||||
supported_categories = set()
|
||||
for alg in algorithms:
|
||||
supported_categories.add(alg.category)
|
||||
# We don't have a pake_fail test function yet.
|
||||
# https://github.com/Mbed-TLS/mbedtls-framework/issues/263
|
||||
supported_categories.remove(crypto_knowledge.AlgorithmCategory.PAKE)
|
||||
categories = sorted(supported_categories, key=lambda cat: cat.value)
|
||||
assert categories # sanity check: at least one category detected
|
||||
for alg in algorithms:
|
||||
yield from self.test_cases_for_algorithm(alg, categories)
|
||||
|
||||
|
||||
class StorageKey(psa_storage.Key):
|
||||
|
||||
@@ -15,6 +15,7 @@ from mbedtls_framework import build_tree
|
||||
BYTES_PER_LINE = 16
|
||||
|
||||
def c_byte_array_literal_content(array_name: str, key_data: bytes) -> Iterator[str]:
|
||||
"""Return C code that defines array_name as a byte array with the given content."""
|
||||
yield 'static const unsigned char '
|
||||
yield array_name
|
||||
yield '[] = {'
|
||||
@@ -27,16 +28,23 @@ def c_byte_array_literal_content(array_name: str, key_data: bytes) -> Iterator[s
|
||||
def convert_der_to_c(array_name: str, key_data: bytes) -> str:
|
||||
return ''.join(c_byte_array_literal_content(array_name, key_data))
|
||||
|
||||
def get_key_type(key: str) -> str:
|
||||
if re.match('PSA_KEY_TYPE_RSA_.*', key):
|
||||
return "rsa"
|
||||
elif re.match('PSA_KEY_TYPE_ECC_.*', key):
|
||||
def get_key_type(key_type: str) -> str:
|
||||
"""Short name for a PSA key type."""
|
||||
if key_type.startswith('PSA_KEY_TYPE_ECC_'):
|
||||
return "ec"
|
||||
elif key_type.startswith('PSA_KEY_TYPE_ML_DSA_'):
|
||||
return "mldsa"
|
||||
elif key_type.startswith('PSA_KEY_TYPE_ML_KEM_'):
|
||||
return "mlkem"
|
||||
elif key_type.startswith('PSA_KEY_TYPE_RSA_'):
|
||||
return "rsa"
|
||||
elif key_type.startswith('PSA_KEY_TYPE_SLH_DSA_'):
|
||||
return "slhdsa"
|
||||
else:
|
||||
print("Unhandled key type {}".format(key))
|
||||
return "unknown"
|
||||
raise Exception(f"Unhandled key type {key_type}")
|
||||
|
||||
def get_ec_key_family(key: str) -> str:
|
||||
"""Extract "PSA_ECC_xxx" from "PSA_KEY_TYPE_ECC_ttt(PSA_ECC_xxx)"."""
|
||||
match = re.search(r'.*\((.*)\)', key)
|
||||
if match is None:
|
||||
raise Exception("Unable to get EC family from {}".format(key))
|
||||
@@ -70,6 +78,7 @@ EC_NAME_CONVERSION = {
|
||||
}
|
||||
|
||||
def get_ec_curve_name(priv_key: str, bits: int) -> str:
|
||||
"""Short name for an elliptic curve key type."""
|
||||
ec_family = get_ec_key_family(priv_key)
|
||||
try:
|
||||
prefix = EC_NAME_CONVERSION[ec_family][bits][0]
|
||||
@@ -78,8 +87,15 @@ def get_ec_curve_name(priv_key: str, bits: int) -> str:
|
||||
return ""
|
||||
return prefix + str(bits) + suffix
|
||||
|
||||
def get_slh_dsa_family(key_type: str) -> str:
|
||||
"""Short name from an SLH-DSA family."""
|
||||
m = re.search(r'PSA_SLH_FAMILY_(\w+)', key_type)
|
||||
assert m
|
||||
return m.group(1).replace('_', '').lower()
|
||||
|
||||
def get_look_up_table_entry(key_type: str, group_id_or_keybits: str,
|
||||
priv_array_name: str, pub_array_name: str) -> Iterator[str]:
|
||||
"""Yield C code lines for the definition of a key pair and its matching public key."""
|
||||
if key_type == "ec":
|
||||
yield " {{ {}, 0,\n".format(group_id_or_keybits)
|
||||
else:
|
||||
@@ -147,10 +163,6 @@ def collect_keys() -> Tuple[str, str]:
|
||||
|
||||
for priv_key in priv_keys:
|
||||
key_type = get_key_type(priv_key)
|
||||
# Ignore keys which are not EC or RSA
|
||||
if key_type == "unknown":
|
||||
continue
|
||||
|
||||
pub_key = re.sub('_KEY_PAIR', '_PUBLIC_KEY', priv_key)
|
||||
|
||||
for bits in ASYMMETRIC_KEY_DATA[priv_key]:
|
||||
@@ -160,10 +172,13 @@ def collect_keys() -> Tuple[str, str]:
|
||||
if curve == "":
|
||||
continue
|
||||
# Create output array name
|
||||
if key_type == "rsa":
|
||||
array_name_base = "_".join(["test", key_type, str(bits)])
|
||||
else:
|
||||
if key_type == "ec":
|
||||
array_name_base = "_".join(["test", key_type, curve])
|
||||
elif key_type == "slhdsa":
|
||||
family = get_slh_dsa_family(priv_key)
|
||||
array_name_base = "_".join(["test", key_type, family, str(bits)])
|
||||
else:
|
||||
array_name_base = "_".join(["test", key_type, str(bits)])
|
||||
array_name_priv = array_name_base + "_priv"
|
||||
array_name_pub = array_name_base + "_pub"
|
||||
# Convert bytearray to C array
|
||||
@@ -182,6 +197,7 @@ def collect_keys() -> Tuple[str, str]:
|
||||
return ''.join(arrays), '\n'.join(look_up_table)
|
||||
|
||||
def main() -> None:
|
||||
"""Command line entry point."""
|
||||
default_output_path = build_tree.guess_project_root() + "/tests/include/test/test_keys.h"
|
||||
|
||||
argparser = argparse.ArgumentParser()
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,13 +36,14 @@ class HashPSALowLevel:
|
||||
# hashlib might not have everything, depending on the Python version and
|
||||
# the underlying OpenSSL. On Ubuntu 16.04, truncated sha512 and sha3/shake
|
||||
# are not available. On Ubuntu 22.04, md2, md4 and ripemd160 are not
|
||||
# available.
|
||||
# available. As of Python 3.14, Ascon is not available.
|
||||
CALCULATE = {
|
||||
'PSA_ALG_MD5': lambda data: hashlib.md5(data).hexdigest(),
|
||||
'PSA_ALG_RIPEMD160': None, #lambda data: hashlib.new('ripdemd160').hexdigest()
|
||||
'PSA_ALG_SHA_1': lambda data: hashlib.sha1(data).hexdigest(),
|
||||
'PSA_ALG_SHA_224': lambda data: hashlib.sha224(data).hexdigest(),
|
||||
'PSA_ALG_SHA_256': lambda data: hashlib.sha256(data).hexdigest(),
|
||||
'PSA_ALG_SHA_256_192': None, #lambda data: hashlib.new('sha256').hexdigest()[:48]
|
||||
'PSA_ALG_SHA_384': lambda data: hashlib.sha384(data).hexdigest(),
|
||||
'PSA_ALG_SHA_512': lambda data: hashlib.sha512(data).hexdigest(),
|
||||
'PSA_ALG_SHA_512_224': None, #lambda data: hashlib.new('sha512_224').hexdigest()
|
||||
@@ -51,7 +52,11 @@ class HashPSALowLevel:
|
||||
'PSA_ALG_SHA3_256': None, #lambda data: hashlib.sha3_256(data).hexdigest(),
|
||||
'PSA_ALG_SHA3_384': None, #lambda data: hashlib.sha3_384(data).hexdigest(),
|
||||
'PSA_ALG_SHA3_512': None, #lambda data: hashlib.sha3_512(data).hexdigest(),
|
||||
'PSA_ALG_SHAKE128_192': None, #lambda data: hashlib.shake_128(data).hexdigest(24),
|
||||
'PSA_ALG_SHAKE128_256': None, #lambda data: hashlib.shake_128(data).hexdigest(32),
|
||||
'PSA_ALG_SHAKE256_256': None, #lambda data: hashlib.shake_256(data).hexdigest(32),
|
||||
'PSA_ALG_SHAKE256_512': None, #lambda data: hashlib.shake_256(data).hexdigest(64),
|
||||
'PSA_ALG_ASCON_HASH256': None, #lambda data: ascon.ascon_hash(data),
|
||||
} #type: Dict[str, Optional[Callable[[bytes], str]]]
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -128,6 +128,7 @@ class KeyType:
|
||||
return self.name.endswith('_PUBLIC_KEY')
|
||||
|
||||
DH_KEY_SIZES = {
|
||||
'PSA_DH_FAMILY_RFC3526': (1536, 2048, 3072, 4096, 6144, 8192),
|
||||
'PSA_DH_FAMILY_RFC7919': (2048, 3072, 4096, 6144, 8192),
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
ECC_KEY_SIZES = {
|
||||
@@ -138,12 +139,15 @@ class KeyType:
|
||||
'PSA_ECC_FAMILY_SECT_R1': (163, 233, 283, 409, 571),
|
||||
'PSA_ECC_FAMILY_SECT_R2': (163,),
|
||||
'PSA_ECC_FAMILY_BRAINPOOL_P_R1': (160, 192, 224, 256, 320, 384, 512),
|
||||
'PSA_ECC_FAMILY_FRP': (256,),
|
||||
'PSA_ECC_FAMILY_MONTGOMERY': (255, 448),
|
||||
'PSA_ECC_FAMILY_TWISTED_EDWARDS': (255, 448),
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
KEY_TYPE_SIZES = {
|
||||
'PSA_KEY_TYPE_AES': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_ARC4': (8, 128, 2048), # extremes + sensible
|
||||
'PSA_KEY_TYPE_ARIA': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_ASCON': (128, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_CAMELLIA': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_CHACHA20': (256,), # exhaustive
|
||||
'PSA_KEY_TYPE_DERIVE': (120, 128), # sample
|
||||
@@ -154,6 +158,8 @@ class KeyType:
|
||||
'PSA_KEY_TYPE_PEPPER': (128, 256), # sample
|
||||
'PSA_KEY_TYPE_RAW_DATA': (8, 40, 128), # sample
|
||||
'PSA_KEY_TYPE_RSA_KEY_PAIR': (1024, 1536), # small sample
|
||||
'PSA_KEY_TYPE_SM4': (128,), # exhaustive
|
||||
'PSA_KEY_TYPE_XCHACHA20': (256,), # exhaustive
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
def sizes_to_test(self) -> Tuple[int, ...]:
|
||||
"""Return a tuple of key sizes to test.
|
||||
@@ -266,7 +272,7 @@ class KeyType:
|
||||
class AlgorithmCategory(enum.Enum):
|
||||
"""PSA algorithm categories."""
|
||||
# The numbers are aligned with the category bits in numerical values of
|
||||
# algorithms.
|
||||
# algorithms. The names match the `PSA_ALG_IS_xxx` macros.
|
||||
HASH = 2
|
||||
MAC = 3
|
||||
CIPHER = 4
|
||||
@@ -276,17 +282,25 @@ class AlgorithmCategory(enum.Enum):
|
||||
KEY_DERIVATION = 8
|
||||
KEY_AGREEMENT = 9
|
||||
PAKE = 10
|
||||
KEY_WRAP = 11
|
||||
KEY_ENCAPSULATION = 12
|
||||
XOF = 13
|
||||
|
||||
def requires_key(self) -> bool:
|
||||
"""Whether operations in this category are set up with a key."""
|
||||
return self not in {self.HASH, self.KEY_DERIVATION}
|
||||
return self not in {
|
||||
self.HASH,
|
||||
self.XOF,
|
||||
self.KEY_DERIVATION, # key passed separately from setup
|
||||
}
|
||||
|
||||
def is_asymmetric(self) -> bool:
|
||||
"""Whether operations in this category involve asymmetric keys."""
|
||||
return self in {
|
||||
self.SIGN,
|
||||
self.ASYMMETRIC_ENCRYPTION,
|
||||
self.KEY_AGREEMENT
|
||||
self.KEY_AGREEMENT,
|
||||
self.KEY_ENCAPSULATION,
|
||||
}
|
||||
|
||||
|
||||
@@ -337,20 +351,33 @@ class Algorithm:
|
||||
return head
|
||||
|
||||
CATEGORY_FROM_HEAD = {
|
||||
'AES_MMO_ZIGBEE': AlgorithmCategory.HASH,
|
||||
'ASCON_HASH': AlgorithmCategory.HASH,
|
||||
'SHA': AlgorithmCategory.HASH,
|
||||
'SHAKE256_512': AlgorithmCategory.HASH,
|
||||
'MD': AlgorithmCategory.HASH,
|
||||
'RIPEMD': AlgorithmCategory.HASH,
|
||||
'SM3': AlgorithmCategory.HASH,
|
||||
'ANY_HASH': AlgorithmCategory.HASH,
|
||||
'HMAC': AlgorithmCategory.MAC,
|
||||
'STREAM_CIPHER': AlgorithmCategory.CIPHER,
|
||||
'ASCON_AEAD': AlgorithmCategory.AEAD,
|
||||
'CHACHA20_POLY1305': AlgorithmCategory.AEAD,
|
||||
'XCHACHA20_POLY1305': AlgorithmCategory.AEAD,
|
||||
'DSA': AlgorithmCategory.SIGN,
|
||||
'ECDSA': AlgorithmCategory.SIGN,
|
||||
'EDDSA': AlgorithmCategory.SIGN,
|
||||
'HASH_ML_DSA': AlgorithmCategory.SIGN,
|
||||
'HASH_SLH_DSA': AlgorithmCategory.SIGN,
|
||||
'HSS': AlgorithmCategory.SIGN,
|
||||
'LMS': AlgorithmCategory.SIGN,
|
||||
'ML_DSA': AlgorithmCategory.SIGN,
|
||||
'PURE_EDDSA': AlgorithmCategory.SIGN,
|
||||
'SLH_DSA': AlgorithmCategory.SIGN,
|
||||
'RSA_PSS': AlgorithmCategory.SIGN,
|
||||
'RSA_PKCS1V15_SIGN': AlgorithmCategory.SIGN,
|
||||
'XMMS': AlgorithmCategory.SIGN,
|
||||
'XMMS_MT': AlgorithmCategory.SIGN,
|
||||
'RSA_PKCS1V15_CRYPT': AlgorithmCategory.ASYMMETRIC_ENCRYPTION,
|
||||
'RSA_OAEP': AlgorithmCategory.ASYMMETRIC_ENCRYPTION,
|
||||
'HKDF': AlgorithmCategory.KEY_DERIVATION,
|
||||
@@ -365,6 +392,13 @@ class Algorithm:
|
||||
'KEY_AGREEMENT': AlgorithmCategory.KEY_DERIVATION,
|
||||
'JPAKE': AlgorithmCategory.PAKE,
|
||||
'SPAKE2P': AlgorithmCategory.PAKE,
|
||||
'KW': AlgorithmCategory.KEY_WRAP,
|
||||
'KWP': AlgorithmCategory.KEY_WRAP,
|
||||
'ECIES_SEC1': AlgorithmCategory.KEY_ENCAPSULATION,
|
||||
'ML_KEM': AlgorithmCategory.KEY_ENCAPSULATION,
|
||||
'ASCON_CXOF': AlgorithmCategory.XOF,
|
||||
'ASCON_XOF': AlgorithmCategory.XOF,
|
||||
'SHAKE': AlgorithmCategory.XOF,
|
||||
}
|
||||
for x in BLOCK_MAC_MODES:
|
||||
CATEGORY_FROM_HEAD[x] = AlgorithmCategory.MAC
|
||||
@@ -455,16 +489,20 @@ class Algorithm:
|
||||
"""
|
||||
return short_expression(self.expression, level=level)
|
||||
|
||||
HASH_LENGTH = {
|
||||
HASH_LENGTH_BYTES = {
|
||||
'PSA_ALG_AES_MMO_ZIGBEE': 16,
|
||||
'PSA_ALG_MD2': 16,
|
||||
'PSA_ALG_MD4': 16,
|
||||
'PSA_ALG_MD5': 16,
|
||||
'PSA_ALG_SHA_1': 20,
|
||||
'PSA_ALG_SM3': 32,
|
||||
}
|
||||
HASH_LENGTH_BITS_RE = re.compile(r'([0-9]+)\Z')
|
||||
@classmethod
|
||||
def hash_length(cls, alg: str) -> int:
|
||||
"""The length of the given hash algorithm, in bytes."""
|
||||
if alg in cls.HASH_LENGTH:
|
||||
return cls.HASH_LENGTH[alg]
|
||||
if alg in cls.HASH_LENGTH_BYTES:
|
||||
return cls.HASH_LENGTH_BYTES[alg]
|
||||
m = cls.HASH_LENGTH_BITS_RE.search(alg)
|
||||
if m:
|
||||
return int(m.group(1)) // 8
|
||||
|
||||
@@ -89,8 +89,8 @@ class PSAMacroEnumerator:
|
||||
self.key_usage_flags = set() #type: Set[str]
|
||||
self.hash_algorithms = set() #type: Set[str]
|
||||
self.mac_algorithms = set() #type: Set[str]
|
||||
self.ka_algorithms = set() #type: Set[str]
|
||||
self.kdf_algorithms = set() #type: Set[str]
|
||||
self.key_agreement_algorithms = set() #type: Set[str]
|
||||
self.key_derivation_algorithms = set() #type: Set[str]
|
||||
self.pake_algorithms = set() #type: Set[str]
|
||||
self.aead_algorithms = set() #type: Set[str]
|
||||
self.sign_algorithms = set() #type: Set[str]
|
||||
@@ -108,6 +108,8 @@ class PSAMacroEnumerator:
|
||||
# type. See `is_internal_name`.
|
||||
# Always false in this class, may be set to true in derived classes.
|
||||
self.include_intermediate = False
|
||||
# Deprecated backward compatibility alias for generate_psa_constants.py.
|
||||
self.ka_algorithms = self.key_agreement_algorithms
|
||||
|
||||
def is_internal_name(self, name: str) -> bool:
|
||||
"""Whether this is an internal macro. Internal macros will be skipped."""
|
||||
@@ -125,8 +127,8 @@ class PSAMacroEnumerator:
|
||||
"""
|
||||
self.arguments_for['hash_alg'] = sorted(self.hash_algorithms)
|
||||
self.arguments_for['mac_alg'] = sorted(self.mac_algorithms)
|
||||
self.arguments_for['ka_alg'] = sorted(self.ka_algorithms)
|
||||
self.arguments_for['kdf_alg'] = sorted(self.kdf_algorithms)
|
||||
self.arguments_for['ka_alg'] = sorted(self.key_agreement_algorithms)
|
||||
self.arguments_for['kdf_alg'] = sorted(self.key_derivation_algorithms)
|
||||
self.arguments_for['aead_alg'] = sorted(self.aead_algorithms)
|
||||
self.arguments_for['sign_alg'] = sorted(self.sign_algorithms)
|
||||
self.arguments_for['curve'] = sorted(self.ecc_curves)
|
||||
@@ -258,7 +260,7 @@ class PSAMacroCollector(PSAMacroEnumerator):
|
||||
if re.match(r'MAC(?:_|\Z)', name):
|
||||
self.mac_algorithms.add(name)
|
||||
elif re.match(r'KDF(?:_|\Z)', name):
|
||||
self.kdf_algorithms.add(name)
|
||||
self.key_derivation_algorithms.add(name)
|
||||
elif re.search(r'0x020000[0-9A-Fa-f]{2}', expansion):
|
||||
self.hash_algorithms.add(name)
|
||||
elif re.search(r'0x03[0-9A-Fa-f]{6}', expansion):
|
||||
@@ -266,9 +268,9 @@ class PSAMacroCollector(PSAMacroEnumerator):
|
||||
elif re.search(r'0x05[0-9A-Fa-f]{6}', expansion):
|
||||
self.aead_algorithms.add(name)
|
||||
elif re.search(r'0x09[0-9A-Fa-f]{2}0000', expansion):
|
||||
self.ka_algorithms.add(name)
|
||||
self.key_agreement_algorithms.add(name)
|
||||
elif re.search(r'0x08[0-9A-Fa-f]{6}', expansion):
|
||||
self.kdf_algorithms.add(name)
|
||||
self.key_derivation_algorithms.add(name)
|
||||
|
||||
# "#define" followed by a macro name with either no parameters
|
||||
# or a single parameter and a non-empty expansion.
|
||||
@@ -281,7 +283,11 @@ class PSAMacroCollector(PSAMacroEnumerator):
|
||||
|
||||
# Macro that is a destructor, not a constructor (i.e. takes a thing as
|
||||
# an argument and analyzes it, rather than constructing a thing).
|
||||
_destructor_name_re = re.compile(r'.*(_GET_|_HAS_|_IS_)|.*_LENGTH\Z')
|
||||
_destructor_name_re = re.compile('|'.join([
|
||||
r'.*(?:_GET_|_HAS_|_IS_)',
|
||||
r'.*_LENGTH\Z',
|
||||
r'PSA_ALG_SIGN_SUPPORTS_CONTEXT\Z',
|
||||
]))
|
||||
|
||||
# Macro that converts between things, rather than building a thing from
|
||||
# scratch.
|
||||
@@ -405,12 +411,15 @@ enumerate
|
||||
'cipher_algorithm': [],
|
||||
'hmac_algorithm': [self.mac_algorithms, self.sign_algorithms],
|
||||
'aead_algorithm': [self.aead_algorithms],
|
||||
'key_derivation_algorithm': [self.kdf_algorithms],
|
||||
'key_agreement_algorithm': [self.ka_algorithms],
|
||||
'key_derivation_algorithm': [self.key_derivation_algorithms],
|
||||
'key_agreement_algorithm': [self.key_agreement_algorithms],
|
||||
'asymmetric_signature_algorithm': [self.sign_algorithms],
|
||||
'asymmetric_signature_wildcard': [self.algorithms],
|
||||
'asymmetric_encryption_algorithm': [],
|
||||
'pake_algorithm': [self.pake_algorithms],
|
||||
'key_wrap_algorithm': [],
|
||||
'key_encapsulation_algorithm': [],
|
||||
'xof_algorithm': [],
|
||||
'other_algorithm': [],
|
||||
'lifetime': [self.lifetimes],
|
||||
} #type: Dict[str, List[Set[str]]]
|
||||
@@ -451,8 +460,8 @@ enumerate
|
||||
# not likely to be assigned in the near future.
|
||||
self.hash_algorithms.add('0x020000fe') # 0x020000ff is PSA_ALG_ANY_HASH
|
||||
self.mac_algorithms.add('0x03007fff')
|
||||
self.ka_algorithms.add('0x09fc0000')
|
||||
self.kdf_algorithms.add('0x080000ff')
|
||||
self.key_agreement_algorithms.add('0x09fc0000')
|
||||
self.key_derivation_algorithms.add('0x080000ff')
|
||||
self.pake_algorithms.add('0x0a0000ff')
|
||||
# For AEAD algorithms, the only variability is over the tag length,
|
||||
# and this only applies to known algorithms, so don't test an
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "test/drivers/asymmetric_encryption.h"
|
||||
#include "test/drivers/key_agreement.h"
|
||||
#include "test/drivers/pake.h"
|
||||
#include "test/drivers/xof.h"
|
||||
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
#endif /* PSA_CRYPTO_TEST_DRIVER_H */
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Test driver for xof driver entry points.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_TEST_DRIVERS_XOF_H
|
||||
#define PSA_CRYPTO_TEST_DRIVERS_XOF_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
#include "test_driver_common.h"
|
||||
|
||||
#include <psa/crypto_driver_common.h>
|
||||
|
||||
/* The type mbedtls_transparent_test_driver_xof_operation_t is only
|
||||
* defined since XOF support was added in TF-PSA-Crypto 1.1.0. */
|
||||
#if defined(PSA_ALG_CATEGORY_XOF)
|
||||
|
||||
typedef struct {
|
||||
/* If not PSA_SUCCESS, return this error code instead of processing the
|
||||
* function call. */
|
||||
psa_status_t forced_status;
|
||||
/* Count the amount of times xof driver entry points are called. */
|
||||
unsigned long hits;
|
||||
/* Status returned by the last xof driver entry point call. */
|
||||
psa_status_t driver_status;
|
||||
} mbedtls_test_driver_xof_hooks_t;
|
||||
|
||||
#define MBEDTLS_TEST_DRIVER_XOF_INIT { 0, 0, 0 }
|
||||
static inline mbedtls_test_driver_xof_hooks_t
|
||||
mbedtls_test_driver_xof_hooks_init(void)
|
||||
{
|
||||
const mbedtls_test_driver_xof_hooks_t v = MBEDTLS_TEST_DRIVER_XOF_INIT;
|
||||
return v;
|
||||
}
|
||||
|
||||
extern mbedtls_test_driver_xof_hooks_t mbedtls_test_driver_xof_hooks;
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_setup(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_set_context(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
const uint8_t *context, size_t context_length);
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_update(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
const uint8_t *input, size_t input_length);
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_output(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
uint8_t *output, size_t output_length);
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_abort(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation);
|
||||
|
||||
#endif /* PSA_ALG_CATEGORY_XOF */
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
#endif /* PSA_CRYPTO_TEST_DRIVERS_XOF_H */
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Test driver for xof entry points.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <test/helpers.h>
|
||||
|
||||
#if defined(PSA_ALG_CATEGORY_XOF) && defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
|
||||
#include "psa_crypto_xof.h"
|
||||
|
||||
#include "test/drivers/xof.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1)
|
||||
#include LIBTESTDRIVER1_PSA_DRIVER_INTERNAL_HEADER(psa_crypto_xof.h)
|
||||
#endif
|
||||
|
||||
mbedtls_test_driver_xof_hooks_t
|
||||
mbedtls_test_driver_xof_hooks = MBEDTLS_TEST_DRIVER_XOF_INIT;
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_setup(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
mbedtls_test_driver_xof_hooks.hits++;
|
||||
|
||||
if (mbedtls_test_driver_xof_hooks.forced_status != PSA_SUCCESS) {
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_test_driver_xof_hooks.forced_status;
|
||||
} else {
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
|
||||
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
libtestdriver1_mbedtls_psa_xof_setup(operation, alg);
|
||||
#elif defined(MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_psa_xof_setup(operation, alg);
|
||||
#else
|
||||
(void) operation;
|
||||
(void) alg;
|
||||
mbedtls_test_driver_xof_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mbedtls_test_driver_xof_hooks.driver_status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_set_context(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
const uint8_t *context, size_t context_length)
|
||||
{
|
||||
mbedtls_test_driver_xof_hooks.hits++;
|
||||
|
||||
if (mbedtls_test_driver_xof_hooks.forced_status != PSA_SUCCESS) {
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_test_driver_xof_hooks.forced_status;
|
||||
} else {
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
|
||||
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
libtestdriver1_mbedtls_psa_xof_set_context(
|
||||
operation, context, context_length);
|
||||
#elif defined(MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_psa_xof_set_context(operation, context, context_length);
|
||||
#else
|
||||
(void) operation;
|
||||
(void) context;
|
||||
(void) context_length;
|
||||
mbedtls_test_driver_xof_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mbedtls_test_driver_xof_hooks.driver_status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_update(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
mbedtls_test_driver_xof_hooks.hits++;
|
||||
|
||||
if (mbedtls_test_driver_xof_hooks.forced_status != PSA_SUCCESS) {
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_test_driver_xof_hooks.forced_status;
|
||||
} else {
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
|
||||
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
libtestdriver1_mbedtls_psa_xof_update(
|
||||
operation, input, input_length);
|
||||
#elif defined(MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_psa_xof_update(operation, input, input_length);
|
||||
#else
|
||||
(void) operation;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
mbedtls_test_driver_xof_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mbedtls_test_driver_xof_hooks.driver_status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_output(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation,
|
||||
uint8_t *output, size_t output_length)
|
||||
{
|
||||
mbedtls_test_driver_xof_hooks.hits++;
|
||||
|
||||
if (mbedtls_test_driver_xof_hooks.forced_status != PSA_SUCCESS) {
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_test_driver_xof_hooks.forced_status;
|
||||
} else {
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
|
||||
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
libtestdriver1_mbedtls_psa_xof_output(
|
||||
operation, output, output_length);
|
||||
#elif defined(MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_psa_xof_output(operation, output, output_length);
|
||||
#else
|
||||
(void) operation;
|
||||
(void) output;
|
||||
(void) output_length;
|
||||
mbedtls_test_driver_xof_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mbedtls_test_driver_xof_hooks.driver_status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_test_transparent_xof_abort(
|
||||
mbedtls_transparent_test_driver_xof_operation_t *operation)
|
||||
{
|
||||
mbedtls_test_driver_xof_hooks.hits++;
|
||||
|
||||
if (mbedtls_test_driver_xof_hooks.forced_status != PSA_SUCCESS) {
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_test_driver_xof_hooks.forced_status;
|
||||
} else {
|
||||
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
|
||||
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
libtestdriver1_mbedtls_psa_xof_abort(operation);
|
||||
#elif defined(MBEDTLS_PSA_BUILTIN_XOF)
|
||||
mbedtls_test_driver_xof_hooks.driver_status =
|
||||
mbedtls_psa_xof_abort(operation);
|
||||
#else
|
||||
(void) operation;
|
||||
mbedtls_test_driver_xof_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mbedtls_test_driver_xof_hooks.driver_status;
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST && defined(PSA_ALG_CATEGORY_XOF) */
|
||||
Reference in New Issue
Block a user