Merge pull request #9292 from gabor-mezei-arm/9140_depends-py_use_psa

Support the crypto_config.h usage in depends.py
This commit is contained in:
Ronald Cron 2024-10-22 11:44:44 +00:00 committed by GitHub
commit 7917074649
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 178 additions and 128 deletions

@ -1 +1 @@
Subproject commit 3eafac12ae1ddc68cc1f0aefdff540d6d3d5a2fb Subproject commit d68446c9da02e536279a7aaa5a3c9850742ba30c

View File

@ -93,10 +93,6 @@ class CoverageTask(outcome_analysis.CoverageTask):
'Opaque key for server authentication: invalid key: ecdh with RSA key, no async', 'Opaque key for server authentication: invalid key: ecdh with RSA key, no async',
], ],
'test_suite_config.mbedtls_boolean': [ 'test_suite_config.mbedtls_boolean': [
# We never test with CBC/PKCS5/PKCS12 enabled but
# PKCS7 padding disabled.
# https://github.com/Mbed-TLS/mbedtls/issues/9580
'Config: !MBEDTLS_CIPHER_PADDING_PKCS7',
# https://github.com/Mbed-TLS/mbedtls/issues/9583 # https://github.com/Mbed-TLS/mbedtls/issues/9583
'Config: !MBEDTLS_ECP_NIST_OPTIM', 'Config: !MBEDTLS_ECP_NIST_OPTIM',
# We never test without the PSA client code. Should we? # We never test without the PSA client code. Should we?
@ -260,10 +256,6 @@ class CoverageTask(outcome_analysis.CoverageTask):
# "PSA test case generation: dependency inference class: operation fail" # "PSA test case generation: dependency inference class: operation fail"
# from https://github.com/Mbed-TLS/mbedtls/pull/9025 . # from https://github.com/Mbed-TLS/mbedtls/pull/9025 .
re.compile(r'.* with (?:DH|ECC)_(?:KEY_PAIR|PUBLIC_KEY)\(.*'), re.compile(r'.* with (?:DH|ECC)_(?:KEY_PAIR|PUBLIC_KEY)\(.*'),
# PBKDF2_HMAC is not in the default configuration, so we don't
# enable it in depends.py where we remove hashes.
# https://github.com/Mbed-TLS/mbedtls/issues/9576
re.compile(r'PSA key_derivation PBKDF2_HMAC\(\w+\): !(?!PBKDF2_HMAC\Z).*'),
# We never test with TLS12_PRF or TLS12_PSK_TO_MS disabled # We never test with TLS12_PRF or TLS12_PSK_TO_MS disabled
# but certain other things enabled. # but certain other things enabled.
# https://github.com/Mbed-TLS/mbedtls/issues/9577 # https://github.com/Mbed-TLS/mbedtls/issues/9577
@ -277,10 +269,6 @@ class CoverageTask(outcome_analysis.CoverageTask):
# key type disabled. Those dependencies don't really make sense. # key type disabled. Those dependencies don't really make sense.
# https://github.com/Mbed-TLS/mbedtls/issues/9573 # https://github.com/Mbed-TLS/mbedtls/issues/9573
re.compile(r'.* !HMAC with HMAC'), re.compile(r'.* !HMAC with HMAC'),
# There's something wrong with PSA_WANT_ALG_RSA_PSS_ANY_SALT
# differing from PSA_WANT_ALG_RSA_PSS.
# https://github.com/Mbed-TLS/mbedtls/issues/9578
re.compile(r'PSA sign RSA_PSS_ANY_SALT.*!(?:MD|RIPEMD|SHA).*'),
], ],
'test_suite_psa_crypto_storage_format.current': [ 'test_suite_psa_crypto_storage_format.current': [
PSA_MECHANISM_NOT_IMPLEMENTED_SEARCH_RE, PSA_MECHANISM_NOT_IMPLEMENTED_SEARCH_RE,

View File

@ -545,62 +545,31 @@ support_build_crypto_baremetal () {
# depends.py family of tests # depends.py family of tests
component_test_depends_py_cipher_id () { component_test_depends_py_cipher_id () {
msg "test/build: depends.py cipher_id (gcc)" msg "test/build: depends.py cipher_id (gcc)"
tests/scripts/depends.py cipher_id --unset-use-psa tests/scripts/depends.py cipher_id
} }
component_test_depends_py_cipher_chaining () { component_test_depends_py_cipher_chaining () {
msg "test/build: depends.py cipher_chaining (gcc)" msg "test/build: depends.py cipher_chaining (gcc)"
tests/scripts/depends.py cipher_chaining --unset-use-psa tests/scripts/depends.py cipher_chaining
} }
component_test_depends_py_cipher_padding () { component_test_depends_py_cipher_padding () {
msg "test/build: depends.py cipher_padding (gcc)" msg "test/build: depends.py cipher_padding (gcc)"
tests/scripts/depends.py cipher_padding --unset-use-psa tests/scripts/depends.py cipher_padding
} }
component_test_depends_py_curves () { component_test_depends_py_curves () {
msg "test/build: depends.py curves (gcc)" msg "test/build: depends.py curves (gcc)"
tests/scripts/depends.py curves --unset-use-psa tests/scripts/depends.py curves
} }
component_test_depends_py_hashes () { component_test_depends_py_hashes () {
msg "test/build: depends.py hashes (gcc)" msg "test/build: depends.py hashes (gcc)"
tests/scripts/depends.py hashes --unset-use-psa tests/scripts/depends.py hashes
} }
component_test_depends_py_pkalgs () { component_test_depends_py_pkalgs () {
msg "test/build: depends.py pkalgs (gcc)" msg "test/build: depends.py pkalgs (gcc)"
tests/scripts/depends.py pkalgs --unset-use-psa
}
# PSA equivalents of the depends.py tests
component_test_depends_py_cipher_id_psa () {
msg "test/build: depends.py cipher_id (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py cipher_id
}
component_test_depends_py_cipher_chaining_psa () {
msg "test/build: depends.py cipher_chaining (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py cipher_chaining
}
component_test_depends_py_cipher_padding_psa () {
msg "test/build: depends.py cipher_padding (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py cipher_padding
}
component_test_depends_py_curves_psa () {
msg "test/build: depends.py curves (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py curves
}
component_test_depends_py_hashes_psa () {
msg "test/build: depends.py hashes (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py hashes
}
component_test_depends_py_pkalgs_psa () {
msg "test/build: depends.py pkalgs (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py pkalgs tests/scripts/depends.py pkalgs
} }

View File

@ -721,11 +721,6 @@ component_test_full_minus_session_tickets () {
component_test_depends_py_kex () { component_test_depends_py_kex () {
msg "test/build: depends.py kex (gcc)" msg "test/build: depends.py kex (gcc)"
tests/scripts/depends.py kex --unset-use-psa
}
component_test_depends_py_kex_psa () {
msg "test/build: depends.py kex (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
tests/scripts/depends.py kex tests/scripts/depends.py kex
} }

View File

@ -47,7 +47,6 @@ a full config without a couple of slowing down or unnecessary options
import argparse import argparse
import os import os
import re import re
import shutil
import subprocess import subprocess
import sys import sys
import traceback import traceback
@ -56,6 +55,7 @@ from typing import Union
# Add the Mbed TLS Python library directory to the module search path # Add the Mbed TLS Python library directory to the module search path
import scripts_path # pylint: disable=unused-import import scripts_path # pylint: disable=unused-import
import config import config
from mbedtls_framework import c_build_helper
class Colors: # pylint: disable=too-few-public-methods class Colors: # pylint: disable=too-few-public-methods
"""Minimalistic support for colored output. """Minimalistic support for colored output.
@ -99,24 +99,6 @@ def log_command(cmd):
cmd is a list of strings: a command name and its arguments.""" cmd is a list of strings: a command name and its arguments."""
log_line(' '.join(cmd), prefix='+') log_line(' '.join(cmd), prefix='+')
def backup_config(options):
"""Back up the library configuration file (mbedtls_config.h).
If the backup file already exists, it is presumed to be the desired backup,
so don't make another backup."""
if os.path.exists(options.config_backup):
options.own_backup = False
else:
options.own_backup = True
shutil.copy(options.config, options.config_backup)
def restore_config(options):
"""Restore the library configuration file (mbedtls_config.h).
Remove the backup file if it was saved earlier."""
if options.own_backup:
shutil.move(options.config_backup, options.config)
else:
shutil.copy(options.config_backup, options.config)
def option_exists(conf, option): def option_exists(conf, option):
return option in conf.settings return option in conf.settings
@ -139,7 +121,7 @@ which will make a symbol defined with a certain value."""
conf.set(option, value) conf.set(option, value)
return True return True
def set_reference_config(conf, options, colors): def set_reference_config(conf, colors):
"""Change the library configuration file (mbedtls_config.h) to the reference state. """Change the library configuration file (mbedtls_config.h) to the reference state.
The reference state is the one from which the tested configurations are The reference state is the one from which the tested configurations are
derived.""" derived."""
@ -147,9 +129,6 @@ derived."""
log_command(['config.py', 'full']) log_command(['config.py', 'full'])
conf.adapt(config.full_adapter) conf.adapt(config.full_adapter)
set_config_option_value(conf, 'MBEDTLS_TEST_HOOKS', colors, False) set_config_option_value(conf, 'MBEDTLS_TEST_HOOKS', colors, False)
set_config_option_value(conf, 'MBEDTLS_PSA_CRYPTO_CONFIG', colors, False)
if options.unset_use_psa:
set_config_option_value(conf, 'MBEDTLS_USE_PSA_CRYPTO', colors, False)
class Job: class Job:
"""A job builds the library in a specific configuration and runs some tests.""" """A job builds the library in a specific configuration and runs some tests."""
@ -179,15 +158,57 @@ If what is False, announce that the job has failed.'''
else: else:
log_line('starting ' + self.name, color=colors.cyan) log_line('starting ' + self.name, color=colors.cyan)
def configure(self, conf, options, colors): def configure(self, conf, colors):
'''Set library configuration options as required for the job.''' '''Set library configuration options as required for the job.'''
set_reference_config(conf, options, colors) set_reference_config(conf, colors)
for key, value in sorted(self.config_settings.items()): for key, value in sorted(self.config_settings.items()):
ret = set_config_option_value(conf, key, colors, value) ret = set_config_option_value(conf, key, colors, value)
if ret is False: if ret is False:
return False return False
return True return True
def _consistency_check(self):
'''Check if the testable option is consistent with the goal.
The purpose of this function to ensure that every option is set or unset according to
the settings.
'''
log_command(['consistency check'])
c_name = None
exe_name = None
header = '#include "mbedtls/build_info.h"\n'
# Generate a C error directive for each setting to test if it is active
for option, value in sorted(self.config_settings.items()):
header += '#if '
if value:
header += '!'
header += f'defined({option})\n'
header += f'#error "{option}"\n'
header += '#endif\n'
include_path = ['include', 'tf-psa-crypto/include',
'tf-psa-crypto/drivers/builtin/include']
try:
# Generate a C file, build and run it
c_file, c_name, exe_name = c_build_helper.create_c_file(self.name)
c_build_helper.generate_c_file(c_file, 'depends.py', header, lambda x: '')
c_file.close()
c_build_helper.compile_c_file(c_name, exe_name, include_path)
return True
except c_build_helper.CompileError as e:
# Read the command line output to find out which setting has been failed
failed = {m.group(1) for m in re.finditer('.*#error "(.*)"', e.message) if m}
log_line('Inconsistent config option(s):')
for option in sorted(failed):
log_line(' ' + option)
return False
finally:
c_build_helper.remove_file_if_exists(c_name)
c_build_helper.remove_file_if_exists(exe_name)
def test(self, options): def test(self, options):
'''Run the job's build and test commands. '''Run the job's build and test commands.
Return True if all the commands succeed and False otherwise. Return True if all the commands succeed and False otherwise.
@ -195,6 +216,8 @@ If options.keep_going is false, stop as soon as one command fails. Otherwise
run all the commands, except that if the first command fails, none of the run all the commands, except that if the first command fails, none of the
other commands are run (typically, the first command is a build command other commands are run (typically, the first command is a build command
and subsequent commands are tests that cannot run if the build failed).''' and subsequent commands are tests that cannot run if the build failed).'''
if not self._consistency_check():
return False
built = False built = False
success = True success = True
for command in self.commands: for command in self.commands:
@ -214,54 +237,118 @@ and subsequent commands are tests that cannot run if the build failed).'''
# If the configuration option A requires B, make sure that # If the configuration option A requires B, make sure that
# B in REVERSE_DEPENDENCIES[A]. # B in REVERSE_DEPENDENCIES[A].
# All the information here should be contained in check_config.h. This # All the information here should be contained in check_config.h or check_crypto_config.h.
# file includes a copy because it changes rarely and it would be a pain # This file includes a copy because it changes rarely and it would be a pain
# to extract automatically. # to extract automatically.
REVERSE_DEPENDENCIES = { REVERSE_DEPENDENCIES = {
'MBEDTLS_AES_C': ['MBEDTLS_CTR_DRBG_C', 'MBEDTLS_AES_C': ['MBEDTLS_CTR_DRBG_C',
'MBEDTLS_NIST_KW_C'], 'MBEDTLS_NIST_KW_C',
'MBEDTLS_CHACHA20_C': ['MBEDTLS_CHACHAPOLY_C'], 'PSA_WANT_KEY_TYPE_AES',
'PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128'],
'MBEDTLS_ARIA_C': ['PSA_WANT_KEY_TYPE_ARIA'],
'MBEDTLS_CAMELLIA_C': ['PSA_WANT_KEY_TYPE_CAMELLIA'],
'MBEDTLS_CCM_C': ['PSA_WANT_ALG_CCM',
'PSA_WANT_ALG_CCM_STAR_NO_TAG'],
'MBEDTLS_CHACHA20_C': ['MBEDTLS_CHACHAPOLY_C',
'PSA_WANT_KEY_TYPE_CHACHA20',
'PSA_WANT_ALG_CHACHA20_POLY1305',
'PSA_WANT_ALG_STREAM_CIPHER'],
'MBEDTLS_CMAC_C': ['PSA_WANT_ALG_CMAC',
'PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128'],
'MBEDTLS_DES_C': ['PSA_WANT_KEY_TYPE_DES'],
'MBEDTLS_GCM_C': ['PSA_WANT_ALG_GCM'],
'MBEDTLS_CIPHER_MODE_CBC': ['PSA_WANT_ALG_CBC_PKCS7',
'PSA_WANT_ALG_CBC_NO_PADDING'],
'MBEDTLS_CIPHER_MODE_CFB': ['PSA_WANT_ALG_CFB'],
'MBEDTLS_CIPHER_MODE_CTR': ['PSA_WANT_ALG_CTR'],
'MBEDTLS_CIPHER_MODE_OFB': ['PSA_WANT_ALG_OFB'],
'MBEDTLS_CIPHER_PADDING_PKCS7': ['MBEDTLS_PKCS5_C',
'MBEDTLS_PKCS12_C',
'PSA_WANT_ALG_CBC_PKCS7'],
'MBEDTLS_ECP_DP_BP256R1_ENABLED': ['PSA_WANT_ECC_BRAINPOOL_P_R1_256'],
'MBEDTLS_ECP_DP_BP384R1_ENABLED': ['PSA_WANT_ECC_BRAINPOOL_P_R1_384'],
'MBEDTLS_ECP_DP_BP512R1_ENABLED': ['PSA_WANT_ECC_BRAINPOOL_P_R1_512'],
'MBEDTLS_ECP_DP_CURVE25519_ENABLED': ['PSA_WANT_ECC_MONTGOMERY_255'],
'MBEDTLS_ECP_DP_CURVE448_ENABLED': ['PSA_WANT_ECC_MONTGOMERY_448'],
'MBEDTLS_ECP_DP_SECP192R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_192'],
'MBEDTLS_ECP_DP_SECP224R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_224'],
'MBEDTLS_ECP_DP_SECP256R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_256',
'PSA_WANT_ALG_JPAKE',
'MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'],
'MBEDTLS_ECP_DP_SECP384R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_384'],
'MBEDTLS_ECP_DP_SECP512R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_512'],
'MBEDTLS_ECP_DP_SECP521R1_ENABLED': ['PSA_WANT_ECC_SECP_R1_521'],
'MBEDTLS_ECP_DP_SECP192K1_ENABLED': ['PSA_WANT_ECC_SECP_K1_192'],
'MBEDTLS_ECP_DP_SECP256K1_ENABLED': ['PSA_WANT_ECC_SECP_K1_256'],
'MBEDTLS_ECDSA_C': ['MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED', 'MBEDTLS_ECDSA_C': ['MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED'], 'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
'PSA_WANT_ALG_ECDSA',
'PSA_WANT_ALG_DETERMINISTIC_ECDSA'],
'MBEDTLS_ECP_C': ['MBEDTLS_ECDSA_C', 'MBEDTLS_ECP_C': ['MBEDTLS_ECDSA_C',
'MBEDTLS_ECDH_C', 'MBEDTLS_ECDH_C', 'PSA_WANT_ALG_ECDH',
'MBEDTLS_ECJPAKE_C', 'MBEDTLS_ECJPAKE_C',
'MBEDTLS_ECP_RESTARTABLE', 'MBEDTLS_ECP_RESTARTABLE',
'MBEDTLS_PK_PARSE_EC_EXTENDED', 'MBEDTLS_PK_PARSE_EC_EXTENDED',
'MBEDTLS_PK_PARSE_EC_COMPRESSED', 'MBEDTLS_PK_PARSE_EC_COMPRESSED',
'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED', 'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED', 'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED', 'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED',
'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED', 'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED',
'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED'], 'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED',
'MBEDTLS_ECP_DP_SECP256R1_ENABLED': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'], 'PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY',
'MBEDTLS_PKCS1_V21': ['MBEDTLS_X509_RSASSA_PSS_SUPPORT'], 'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC',
'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT',
'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT',
'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE',
'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE'],
'MBEDTLS_ECJPAKE_C': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED',
'PSA_WANT_ALG_JPAKE'],
'MBEDTLS_PKCS1_V21': ['MBEDTLS_X509_RSASSA_PSS_SUPPORT',
'PSA_WANT_ALG_RSA_OAEP',
'PSA_WANT_ALG_RSA_PSS'],
'MBEDTLS_PKCS1_V15': ['MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED', 'MBEDTLS_PKCS1_V15': ['MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED'],
'MBEDTLS_RSA_C': ['MBEDTLS_X509_RSASSA_PSS_SUPPORT',
'MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED', 'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED', 'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED', 'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED'], 'PSA_WANT_ALG_RSA_PKCS1V15_CRYPT',
'PSA_WANT_ALG_RSA_PKCS1V15_SIGN'],
'MBEDTLS_RSA_C': ['MBEDTLS_PKCS1_V15',
'MBEDTLS_PKCS1_V21',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
'PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY',
'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC',
'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT',
'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT',
'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE'],
'MBEDTLS_MD5_C' : ['PSA_WANT_ALG_MD5'],
'MBEDTLS_RIPEMD160_C' : ['PSA_WANT_ALG_RIPEMD160'],
'MBEDTLS_SHA1_C' : ['PSA_WANT_ALG_SHA_1'],
'MBEDTLS_SHA224_C': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED',
'MBEDTLS_ENTROPY_FORCE_SHA256',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY',
'PSA_WANT_ALG_SHA_224'],
'MBEDTLS_SHA256_C': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED', 'MBEDTLS_SHA256_C': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED',
'MBEDTLS_ENTROPY_FORCE_SHA256', 'MBEDTLS_ENTROPY_FORCE_SHA256',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT', 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY',
'MBEDTLS_LMS_C', 'MBEDTLS_LMS_C',
'MBEDTLS_LMS_PRIVATE'], 'MBEDTLS_LMS_PRIVATE',
'PSA_WANT_ALG_SHA_256',
'PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS'],
'MBEDTLS_SHA384_C' : ['PSA_WANT_ALG_SHA_384'],
'MBEDTLS_SHA512_C': ['MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT', 'MBEDTLS_SHA512_C': ['MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT',
'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY'], 'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY',
'MBEDTLS_SHA224_C': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED', 'PSA_WANT_ALG_SHA_512'],
'MBEDTLS_ENTROPY_FORCE_SHA256', 'MBEDTLS_SHA3_C' : ['PSA_WANT_ALG_SHA3_224',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT', 'PSA_WANT_ALG_SHA3_256',
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY'], 'PSA_WANT_ALG_SHA3_384',
'MBEDTLS_X509_RSASSA_PSS_SUPPORT': [] 'PSA_WANT_ALG_SHA3_512'],
} }
# If an option is tested in an exclusive test, alter the following defines. # If an option is tested in an exclusive test, alter the following defines.
@ -272,19 +359,20 @@ EXCLUSIVE_GROUPS = {
'-MBEDTLS_SSL_TLS_C'], '-MBEDTLS_SSL_TLS_C'],
'MBEDTLS_ECP_DP_CURVE448_ENABLED': ['-MBEDTLS_ECDSA_C', 'MBEDTLS_ECP_DP_CURVE448_ENABLED': ['-MBEDTLS_ECDSA_C',
'-MBEDTLS_ECDSA_DETERMINISTIC', '-MBEDTLS_ECDSA_DETERMINISTIC',
'-MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED', '-MBEDTLS_ECJPAKE_C',],
'-MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
'-MBEDTLS_ECJPAKE_C',
'-MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'],
'MBEDTLS_ECP_DP_CURVE25519_ENABLED': ['-MBEDTLS_ECDSA_C', 'MBEDTLS_ECP_DP_CURVE25519_ENABLED': ['-MBEDTLS_ECDSA_C',
'-MBEDTLS_ECDSA_DETERMINISTIC', '-MBEDTLS_ECDSA_DETERMINISTIC',
'-MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED', '-MBEDTLS_ECJPAKE_C'],
'-MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED', 'MBEDTLS_ARIA_C': ['-MBEDTLS_CMAC_C',
'-MBEDTLS_ECJPAKE_C', '-MBEDTLS_CCM_C',
'-MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'], '-MBEDTLS_GCM_C',
'MBEDTLS_ARIA_C': ['-MBEDTLS_CMAC_C'], '-MBEDTLS_SSL_TICKET_C',
'-MBEDTLS_SSL_CONTEXT_SERIALIZATION'],
'MBEDTLS_CAMELLIA_C': ['-MBEDTLS_CMAC_C'], 'MBEDTLS_CAMELLIA_C': ['-MBEDTLS_CMAC_C'],
'MBEDTLS_CHACHA20_C': ['-MBEDTLS_CMAC_C', '-MBEDTLS_CCM_C', '-MBEDTLS_GCM_C'], 'MBEDTLS_CHACHA20_C': ['-MBEDTLS_CMAC_C',
'-MBEDTLS_CCM_C',
'-MBEDTLS_GCM_C',
'-PSA_WANT_ALG_ECB_NO_PADDING'],
'MBEDTLS_DES_C': ['-MBEDTLS_CCM_C', 'MBEDTLS_DES_C': ['-MBEDTLS_CCM_C',
'-MBEDTLS_GCM_C', '-MBEDTLS_GCM_C',
'-MBEDTLS_SSL_TICKET_C', '-MBEDTLS_SSL_TICKET_C',
@ -300,12 +388,23 @@ defines to be altered. """
def turn_off_dependencies(config_settings): def turn_off_dependencies(config_settings):
"""For every option turned off config_settings, also turn off what depends on it. """For every option turned off config_settings, also turn off what depends on it.
An option O is turned off if config_settings[O] is False."""
An option O is turned off if config_settings[O] is False.
Handle the dependencies recursively.
"""
for key, value in sorted(config_settings.items()): for key, value in sorted(config_settings.items()):
if value is not False: if value is not False:
continue continue
for dep in REVERSE_DEPENDENCIES.get(key, []):
# Save the processed settings to handle cross referencies
revdep = set(REVERSE_DEPENDENCIES.get(key, []))
history = set()
while revdep:
dep = revdep.pop()
history.add(dep)
config_settings[dep] = False config_settings[dep] = False
# Do not add symbols which are already processed
revdep.update(set(REVERSE_DEPENDENCIES.get(dep, [])) - history)
class BaseDomain: # pylint: disable=too-few-public-methods, unused-argument class BaseDomain: # pylint: disable=too-few-public-methods, unused-argument
"""A base class for all domains.""" """A base class for all domains."""
@ -451,7 +550,7 @@ def run(options, job, conf, colors=NO_COLORS):
"""Run the specified job (a Job instance).""" """Run the specified job (a Job instance)."""
subprocess.check_call([options.make_command, 'clean']) subprocess.check_call([options.make_command, 'clean'])
job.announce(colors, None) job.announce(colors, None)
if not job.configure(conf, options, colors): if not job.configure(conf, colors):
job.announce(colors, False) job.announce(colors, False)
return False return False
conf.write() conf.write()
@ -464,15 +563,13 @@ def run_tests(options, domain_data, conf):
domain_data should be a DomainData instance that describes the available domain_data should be a DomainData instance that describes the available
domains and jobs. domains and jobs.
Run the jobs listed in options.tasks.""" Run the jobs listed in options.tasks."""
if not hasattr(options, 'config_backup'):
options.config_backup = options.config + '.bak'
colors = Colors(options) colors = Colors(options)
jobs = [] jobs = []
failures = [] failures = []
successes = [] successes = []
for name in options.tasks: for name in options.tasks:
jobs += domain_data.get_jobs(name) jobs += domain_data.get_jobs(name)
backup_config(options) conf.backup()
try: try:
for job in jobs: for job in jobs:
success = run(options, job, conf, colors=colors) success = run(options, job, conf, colors=colors)
@ -483,13 +580,13 @@ Run the jobs listed in options.tasks."""
return False return False
else: else:
successes.append(job.name) successes.append(job.name)
restore_config(options) conf.restore()
except: except:
# Restore the configuration, except in stop-on-error mode if there # Restore the configuration, except in stop-on-error mode if there
# was an error, where we leave the failing configuration up for # was an error, where we leave the failing configuration up for
# developer convenience. # developer convenience.
if options.keep_going: if options.keep_going:
restore_config(options) conf.restore()
raise raise
if successes: if successes:
log_line('{} passed'.format(' '.join(successes)), color=colors.bold_green) log_line('{} passed'.format(' '.join(successes)), color=colors.bold_green)
@ -514,7 +611,10 @@ def main():
choices=['always', 'auto', 'never'], default='auto') choices=['always', 'auto', 'never'], default='auto')
parser.add_argument('-c', '--config', metavar='FILE', parser.add_argument('-c', '--config', metavar='FILE',
help='Configuration file to modify', help='Configuration file to modify',
default='include/mbedtls/mbedtls_config.h') default=config.MbedTLSConfigFile.default_path[0])
parser.add_argument('-r', '--crypto-config', metavar='FILE',
help='Crypto configuration file to modify',
default=config.CryptoConfigFile.default_path[0])
parser.add_argument('-C', '--directory', metavar='DIR', parser.add_argument('-C', '--directory', metavar='DIR',
help='Change to this directory before anything else', help='Change to this directory before anything else',
default='.') default='.')
@ -533,15 +633,13 @@ def main():
parser.add_argument('--make-command', metavar='CMD', parser.add_argument('--make-command', metavar='CMD',
help='Command to run instead of make (e.g. gmake)', help='Command to run instead of make (e.g. gmake)',
action='store', default='make') action='store', default='make')
parser.add_argument('--unset-use-psa',
help='Unset MBEDTLS_USE_PSA_CRYPTO before any test',
action='store_true', dest='unset_use_psa')
parser.add_argument('tasks', metavar='TASKS', nargs='*', parser.add_argument('tasks', metavar='TASKS', nargs='*',
help='The domain(s) or job(s) to test (default: all).', help='The domain(s) or job(s) to test (default: all).',
default=True) default=True)
options = parser.parse_args() options = parser.parse_args()
os.chdir(options.directory) os.chdir(options.directory)
conf = config.MbedTLSConfig(options.config) conf = config.CombinedConfig(config.MbedTLSConfigFile(options.config),
config.CryptoConfigFile(options.crypto_config))
domain_data = DomainData(options, conf) domain_data = DomainData(options, conf)
if options.tasks is True: if options.tasks is True: