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

Support the crypto_config.h usage in depends.py
diff --git a/framework b/framework
index 3eafac1..d68446c 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 3eafac12ae1ddc68cc1f0aefdff540d6d3d5a2fb
+Subproject commit d68446c9da02e536279a7aaa5a3c9850742ba30c
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 2acf77a..43982ce 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -93,10 +93,6 @@
             'Opaque key for server authentication: invalid key: ecdh with RSA key, no async',
         ],
         '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
             'Config: !MBEDTLS_ECP_NIST_OPTIM',
             # We never test without the PSA client code. Should we?
@@ -260,10 +256,6 @@
             # "PSA test case generation: dependency inference class: operation fail"
             # from https://github.com/Mbed-TLS/mbedtls/pull/9025 .
             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
             # but certain other things enabled.
             # https://github.com/Mbed-TLS/mbedtls/issues/9577
@@ -277,10 +269,6 @@
             # key type disabled. Those dependencies don't really make sense.
             # https://github.com/Mbed-TLS/mbedtls/issues/9573
             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': [
             PSA_MECHANISM_NOT_IMPLEMENTED_SEARCH_RE,
diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh
index de8ab2d..9cbcddb 100644
--- a/tests/scripts/components-configuration-crypto.sh
+++ b/tests/scripts/components-configuration-crypto.sh
@@ -545,62 +545,31 @@
 # depends.py family of tests
 component_test_depends_py_cipher_id () {
     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 () {
     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 () {
     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 () {
     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 () {
     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 () {
     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
 }
 
diff --git a/tests/scripts/components-configuration-tls.sh b/tests/scripts/components-configuration-tls.sh
index e1d33ad..b8834d6 100644
--- a/tests/scripts/components-configuration-tls.sh
+++ b/tests/scripts/components-configuration-tls.sh
@@ -721,11 +721,6 @@
 
 component_test_depends_py_kex () {
     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
 }
 
diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py
index 5098099..5eddaae 100755
--- a/tests/scripts/depends.py
+++ b/tests/scripts/depends.py
@@ -47,7 +47,6 @@
 import argparse
 import os
 import re
-import shutil
 import subprocess
 import sys
 import traceback
@@ -56,6 +55,7 @@
 # Add the Mbed TLS Python library directory to the module search path
 import scripts_path # pylint: disable=unused-import
 import config
+from mbedtls_framework import c_build_helper
 
 class Colors: # pylint: disable=too-few-public-methods
     """Minimalistic support for colored output.
@@ -99,24 +99,6 @@
 cmd is a list of strings: a command name and its arguments."""
     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):
     return option in conf.settings
 
@@ -139,7 +121,7 @@
         conf.set(option, value)
     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.
 The reference state is the one from which the tested configurations are
 derived."""
@@ -147,9 +129,6 @@
     log_command(['config.py', 'full'])
     conf.adapt(config.full_adapter)
     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:
     """A job builds the library in a specific configuration and runs some tests."""
@@ -179,15 +158,57 @@
         else:
             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_reference_config(conf, options, colors)
+        set_reference_config(conf, colors)
         for key, value in sorted(self.config_settings.items()):
             ret = set_config_option_value(conf, key, colors, value)
             if ret is False:
                 return False
         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):
         '''Run the job's build and test commands.
 Return True if all the commands succeed and False otherwise.
@@ -195,6 +216,8 @@
 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
 and subsequent commands are tests that cannot run if the build failed).'''
+        if not self._consistency_check():
+            return False
         built = False
         success = True
         for command in self.commands:
@@ -214,54 +237,118 @@
 
 # If the configuration option A requires B, make sure that
 # B in REVERSE_DEPENDENCIES[A].
-# All the information here should be contained in check_config.h. This
-# file includes a copy because it changes rarely and it would be a pain
+# All the information here should be contained in check_config.h or check_crypto_config.h.
+# This file includes a copy because it changes rarely and it would be a pain
 # to extract automatically.
 REVERSE_DEPENDENCIES = {
     'MBEDTLS_AES_C': ['MBEDTLS_CTR_DRBG_C',
-                      'MBEDTLS_NIST_KW_C'],
-    'MBEDTLS_CHACHA20_C': ['MBEDTLS_CHACHAPOLY_C'],
+                      'MBEDTLS_NIST_KW_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_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_ECDH_C',
+                      'MBEDTLS_ECDH_C', 'PSA_WANT_ALG_ECDH',
                       'MBEDTLS_ECJPAKE_C',
                       'MBEDTLS_ECP_RESTARTABLE',
                       'MBEDTLS_PK_PARSE_EC_EXTENDED',
                       'MBEDTLS_PK_PARSE_EC_COMPRESSED',
-                      'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
                       'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
                       'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_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_PSK_EPHEMERAL_ENABLED'],
-    'MBEDTLS_ECP_DP_SECP256R1_ENABLED': ['MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'],
-    'MBEDTLS_PKCS1_V21': ['MBEDTLS_X509_RSASSA_PSS_SUPPORT'],
+                      'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED',
+                      'PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY',
+                      '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_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_RSA_PSK_ENABLED',
-                      'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
-                      'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED'],
+                          'MBEDTLS_KEY_EXCHANGE_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_ENTROPY_FORCE_SHA256',
                          'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT',
                          'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY',
                          '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_USE_A64_CRYPTO_ONLY'],
-    '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'],
-    'MBEDTLS_X509_RSASSA_PSS_SUPPORT': []
+                         'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY',
+                         'PSA_WANT_ALG_SHA_512'],
+    'MBEDTLS_SHA3_C' : ['PSA_WANT_ALG_SHA3_224',
+                        'PSA_WANT_ALG_SHA3_256',
+                        'PSA_WANT_ALG_SHA3_384',
+                        'PSA_WANT_ALG_SHA3_512'],
 }
 
 # If an option is tested in an exclusive test, alter the following defines.
@@ -272,19 +359,20 @@
                          '-MBEDTLS_SSL_TLS_C'],
     'MBEDTLS_ECP_DP_CURVE448_ENABLED': ['-MBEDTLS_ECDSA_C',
                                         '-MBEDTLS_ECDSA_DETERMINISTIC',
-                                        '-MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',
-                                        '-MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
-                                        '-MBEDTLS_ECJPAKE_C',
-                                        '-MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'],
+                                        '-MBEDTLS_ECJPAKE_C',],
     'MBEDTLS_ECP_DP_CURVE25519_ENABLED': ['-MBEDTLS_ECDSA_C',
                                           '-MBEDTLS_ECDSA_DETERMINISTIC',
-                                          '-MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',
-                                          '-MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
-                                          '-MBEDTLS_ECJPAKE_C',
-                                          '-MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED'],
-    'MBEDTLS_ARIA_C': ['-MBEDTLS_CMAC_C'],
+                                          '-MBEDTLS_ECJPAKE_C'],
+    'MBEDTLS_ARIA_C': ['-MBEDTLS_CMAC_C',
+                       '-MBEDTLS_CCM_C',
+                       '-MBEDTLS_GCM_C',
+                       '-MBEDTLS_SSL_TICKET_C',
+                       '-MBEDTLS_SSL_CONTEXT_SERIALIZATION'],
     '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_GCM_C',
                       '-MBEDTLS_SSL_TICKET_C',
@@ -300,12 +388,23 @@
 
 def turn_off_dependencies(config_settings):
     """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()):
         if value is not False:
             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
+            # 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
     """A base class for all domains."""
@@ -451,7 +550,7 @@
     """Run the specified job (a Job instance)."""
     subprocess.check_call([options.make_command, 'clean'])
     job.announce(colors, None)
-    if not job.configure(conf, options, colors):
+    if not job.configure(conf, colors):
         job.announce(colors, False)
         return False
     conf.write()
@@ -464,15 +563,13 @@
 domain_data should be a DomainData instance that describes the available
 domains and jobs.
 Run the jobs listed in options.tasks."""
-    if not hasattr(options, 'config_backup'):
-        options.config_backup = options.config + '.bak'
     colors = Colors(options)
     jobs = []
     failures = []
     successes = []
     for name in options.tasks:
         jobs += domain_data.get_jobs(name)
-    backup_config(options)
+    conf.backup()
     try:
         for job in jobs:
             success = run(options, job, conf, colors=colors)
@@ -483,13 +580,13 @@
                     return False
             else:
                 successes.append(job.name)
-        restore_config(options)
+        conf.restore()
     except:
         # Restore the configuration, except in stop-on-error mode if there
         # was an error, where we leave the failing configuration up for
         # developer convenience.
         if options.keep_going:
-            restore_config(options)
+            conf.restore()
         raise
     if successes:
         log_line('{} passed'.format(' '.join(successes)), color=colors.bold_green)
@@ -514,7 +611,10 @@
                             choices=['always', 'auto', 'never'], default='auto')
         parser.add_argument('-c', '--config', metavar='FILE',
                             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',
                             help='Change to this directory before anything else',
                             default='.')
@@ -533,15 +633,13 @@
         parser.add_argument('--make-command', metavar='CMD',
                             help='Command to run instead of make (e.g. gmake)',
                             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='*',
                             help='The domain(s) or job(s) to test (default: all).',
                             default=True)
         options = parser.parse_args()
         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)
 
         if options.tasks is True: