#!/usr/bin/env python3

# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

"""
Test Mbed TLS with a subset of algorithms.

This script can be divided into several steps:

First, include/mbedtls/mbedtls_config.h or a different config file passed
in the arguments is parsed to extract any configuration options (using config.py).

Then, test domains (groups of jobs, tests) are built based on predefined data
collected in the DomainData class. Here, each domain has five major traits:
- domain name, can be used to run only specific tests via command-line;
- configuration building method, described in detail below;
- list of symbols passed to the configuration building method;
- commands to be run on each job (only build, build and test, or any other custom);
- optional list of symbols to be excluded from testing.

The configuration building method can be one of the three following:

- ComplementaryDomain - build a job for each passed symbol by disabling a single
  symbol and its reverse dependencies (defined in REVERSE_DEPENDENCIES);

- ExclusiveDomain - build a job where, for each passed symbol, only this particular
  one is defined and other symbols from the list are unset. For each job look for
  any non-standard symbols to set/unset in EXCLUSIVE_GROUPS. These are usually not
  direct dependencies, but rather non-trivial results of other configs missing. Then
  look for any unset symbols and handle their reverse dependencies.
  Examples of EXCLUSIVE_GROUPS usage:
  - MBEDTLS_SHA512_C job turns off all hashes except SHA512. MBEDTLS_SSL_COOKIE_C
    requires either SHA256 or SHA384 to work, so it also has to be disabled.
    This is not a dependency on SHA512_C, but a result of an exclusive domain
    config building method. Relevant field:
    'MBEDTLS_SHA512_C': ['-MBEDTLS_SSL_COOKIE_C'],

- DualDomain - combination of the two above - both complementary and exclusive domain
  job generation code will be run. Currently only used for hashes.

Lastly, the collected jobs are executed and (optionally) tested, with
error reporting and coloring as configured in options. Each test starts with
a full config without a couple of slowing down or unnecessary options
(see set_reference_config), then the specific job config is derived.
"""
import argparse
import os
import re
import subprocess
import sys
import traceback
from typing import Union

# 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
from mbedtls_framework import crypto_knowledge
from mbedtls_framework import psa_information

class Colors: # pylint: disable=too-few-public-methods
    """Minimalistic support for colored output.
Each field of an object of this class is either None if colored output
is not possible or not desired, or a pair of strings (start, stop) such
that outputting start switches the text color to the desired color and
stop switches the text color back to the default."""
    red = None
    green = None
    cyan = None
    bold_red = None
    bold_green = None
    def __init__(self, options=None):
        """Initialize color profile according to passed options."""
        if not options or options.color in ['no', 'never']:
            want_color = False
        elif options.color in ['yes', 'always']:
            want_color = True
        else:
            want_color = sys.stderr.isatty()
        if want_color:
            # Assume ANSI compatible terminal
            normal = '\033[0m'
            self.red = ('\033[31m', normal)
            self.green = ('\033[32m', normal)
            self.cyan = ('\033[36m', normal)
            self.bold_red = ('\033[1;31m', normal)
            self.bold_green = ('\033[1;32m', normal)
NO_COLORS = Colors(None)

def log_line(text, prefix='depends.py:', suffix='', color=None):
    """Print a status message."""
    if color is not None:
        prefix = color[0] + prefix
        suffix = suffix + color[1]
    sys.stderr.write(prefix + ' ' + text + suffix + '\n')
    sys.stderr.flush()

def log_command(cmd):
    """Print a trace of the specified command.
cmd is a list of strings: a command name and its arguments."""
    log_line(' '.join(cmd), prefix='+')

def option_exists(conf, option):
    return option in conf.settings

def set_config_option_value(conf, option, colors, value: Union[bool, str]):
    """Set/unset a configuration option, optionally specifying a value.
value can be either True/False (set/unset config option), or a string,
which will make a symbol defined with a certain value."""
    if not option_exists(conf, option):
        log_line('Symbol {} was not found in {}'.format(option, conf.filename), color=colors.red)
        return False

    if value is False:
        log_command(['config.py', 'unset', option])
        conf.unset(option)
    elif value is True:
        log_command(['config.py', 'set', option])
        conf.set(option)
    else:
        log_command(['config.py', 'set', option, value])
        conf.set(option, value)
    return True

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."""
    # Turn off options that are not relevant to the tests and slow them down.
    log_command(['config.py', 'full'])
    conf.adapt(config.full_adapter)
    set_config_option_value(conf, 'MBEDTLS_TEST_HOOKS', colors, False)

class Job:
    """A job builds the library in a specific configuration and runs some tests."""
    def __init__(self, name, config_settings, commands):
        """Build a job object.
The job uses the configuration described by config_settings. This is a
dictionary where the keys are preprocessor symbols and the values are
booleans or strings. A boolean indicates whether or not to #define the
symbol. With a string, the symbol is #define'd to that value.
After setting the configuration, the job runs the programs specified by
commands. This is a list of lists of strings; each list of string is a
command name and its arguments and is passed to subprocess.call with
shell=False."""
        self.name = name
        self.config_settings = config_settings
        self.commands = commands

    def announce(self, colors, what):
        '''Announce the start or completion of a job.
If what is None, announce the start of the job.
If what is True, announce that the job has passed.
If what is False, announce that the job has failed.'''
        if what is True:
            log_line(self.name + ' PASSED', color=colors.green)
        elif what is False:
            log_line(self.name + ' FAILED', color=colors.red)
        else:
            log_line('starting ' + self.name, color=colors.cyan)

    def configure(self, conf, colors):
        '''Set library configuration options as required for the job.'''
        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.
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
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:
            log_command(command)
            env = os.environ.copy()
            if 'MBEDTLS_TEST_CONFIGURATION' in env:
                env['MBEDTLS_TEST_CONFIGURATION'] += '-' + self.name
            ret = subprocess.call(command, env=env)
            if ret != 0:
                if command[0] not in ['make', options.make_command]:
                    log_line('*** [{}] Error {}'.format(' '.join(command), ret))
                if not options.keep_going or not built:
                    return False
                success = False
            built = True
        return success

# 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 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 = {
    'PSA_WANT_KEY_TYPE_AES': ['PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128',
                              'MBEDTLS_CTR_DRBG_C',
                              'MBEDTLS_NIST_KW_C',
                              'MBEDTLS_AES_C'],
    'PSA_WANT_KEY_TYPE_ARIA': ['MBEDTLS_ARIA_C'],
    'PSA_WANT_KEY_TYPE_CAMELLIA': ['MBEDTLS_CAMELLIA_C'],
    'PSA_WANT_KEY_TYPE_CHACHA20': ['PSA_WANT_ALG_CHACHA20_POLY1305',
                                   'PSA_WANT_ALG_STREAM_CIPHER',
                                   'MBEDTLS_CHACHA20_C',
                                   'MBEDTLS_CHACHAPOLY_C'],
    'PSA_WANT_KEY_TYPE_DES': ['MBEDTLS_DES_C'],
    'PSA_WANT_ALG_CCM': ['PSA_WANT_ALG_CCM_STAR_NO_TAG',
                         'MBEDTLS_CCM_C'],
    'PSA_WANT_ALG_CMAC': ['PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128',
                          'MBEDTLS_CMAC_C'],
    'PSA_WANT_ALG_GCM': ['MBEDTLS_GCM_C'],

    'PSA_WANT_ALG_CBC_NO_PADDING': ['MBEDTLS_CIPHER_MODE_CBC'],
    'PSA_WANT_ALG_CBC_PKCS7': ['MBEDTLS_CIPHER_MODE_CBC'],
    'PSA_WANT_ALG_CFB': ['MBEDTLS_CIPHER_MODE_CFB'],
    'PSA_WANT_ALG_CTR': ['MBEDTLS_CIPHER_MODE_CTR'],
    'PSA_WANT_ALG_OFB': ['MBEDTLS_CIPHER_MODE_OFB'],
    'PSA_WANT_ALG_XTS': ['MBEDTLS_CIPHER_MODE_XTS'],

    'MBEDTLS_CIPHER_PADDING_PKCS7': ['MBEDTLS_PKCS5_C',
                                     'MBEDTLS_PKCS12_C',
                                     'PSA_WANT_ALG_CBC_PKCS7'],
    'MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS': ['MBEDTLS_CIPHER_MODE_CBC'],
    'MBEDTLS_CIPHER_PADDING_ZEROS': ['MBEDTLS_CIPHER_MODE_CBC'],
    'MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN': ['MBEDTLS_CIPHER_MODE_CBC'],

    'PSA_WANT_ECC_BRAINPOOL_P_R1_256': ['MBEDTLS_ECP_DP_BP256R1_ENABLED'],
    'PSA_WANT_ECC_BRAINPOOL_P_R1_384': ['MBEDTLS_ECP_DP_BP384R1_ENABLED'],
    'PSA_WANT_ECC_BRAINPOOL_P_R1_512': ['MBEDTLS_ECP_DP_BP512R1_ENABLED'],
    'PSA_WANT_ECC_MONTGOMERY_255': ['MBEDTLS_ECP_DP_CURVE25519_ENABLED'],
    'PSA_WANT_ECC_MONTGOMERY_448': ['MBEDTLS_ECP_DP_CURVE448_ENABLED'],
    'PSA_WANT_ECC_SECP_R1_192': ['MBEDTLS_ECP_DP_SECP192R1_ENABLED'],
    'PSA_WANT_ECC_SECP_R1_224': ['MBEDTLS_ECP_DP_SECP224R1_ENABLED'],
    'PSA_WANT_ECC_SECP_R1_256': ['MBEDTLS_ECJPAKE_C',
                                 'MBEDTLS_ECP_DP_SECP256R1_ENABLED'],
    'PSA_WANT_ECC_SECP_R1_384': ['MBEDTLS_ECP_DP_SECP384R1_ENABLED'],
    'PSA_WANT_ECC_SECP_R1_521': ['MBEDTLS_ECP_DP_SECP521R1_ENABLED'],
    'PSA_WANT_ECC_SECP_K1_192': ['MBEDTLS_ECP_DP_SECP192K1_ENABLED'],
    'PSA_WANT_ECC_SECP_K1_256': ['MBEDTLS_ECP_DP_SECP256K1_ENABLED'],

    'MBEDTLS_ECDSA_C': ['MBEDTLS_KEY_EXCHANGE_ECDHE_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', 'PSA_WANT_ALG_ECDH',
                      'MBEDTLS_ECJPAKE_C',
                      'MBEDTLS_ECP_RESTARTABLE',
                      'MBEDTLS_PK_PARSE_EC_EXTENDED',
                      'MBEDTLS_PK_PARSE_EC_COMPRESSED',
                      'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
                      'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED',
                      'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
                      'MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED',
                      '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_ECDHE_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',
                         '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',
                         '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.
# These are not necessarily dependencies, but just minimal required changes
# if a given define is the only one enabled from an exclusive group.
EXCLUSIVE_GROUPS = {
    'MBEDTLS_SHA512_C': ['-MBEDTLS_SSL_COOKIE_C',
                         '-MBEDTLS_SSL_TLS_C'],
    'PSA_WANT_ECC_MONTGOMERY_448': ['-MBEDTLS_ECDSA_C',
                                    '-MBEDTLS_ECDSA_DETERMINISTIC',
                                    '-MBEDTLS_ECJPAKE_C',],
    'PSA_WANT_ECC_MONTGOMERY_255': ['-MBEDTLS_ECDSA_C',
                                    '-MBEDTLS_ECDSA_DETERMINISTIC',
                                    '-MBEDTLS_ECJPAKE_C'],
    'PSA_WANT_KEY_TYPE_ARIA': ['-PSA_WANT_ALG_CMAC',
                               '-PSA_WANT_ALG_CCM',
                               '-PSA_WANT_ALG_GCM',
                               '-MBEDTLS_SSL_TICKET_C',
                               '-MBEDTLS_SSL_CONTEXT_SERIALIZATION'],
    'PSA_WANT_KEY_TYPE_CAMELLIA': ['-PSA_WANT_ALG_CMAC'],
    'PSA_WANT_KEY_TYPE_CHACHA20': ['-PSA_WANT_ALG_CMAC',
                                   '-PSA_WANT_ALG_CCM',
                                   '-PSA_WANT_ALG_GCM',
                                   '-PSA_WANT_ALG_ECB_NO_PADDING'],
    'PSA_WANT_KEY_TYPE_DES': ['-PSA_WANT_ALG_CCM',
                              '-PSA_WANT_ALG_GCM',
                              '-MBEDTLS_SSL_TICKET_C',
                              '-MBEDTLS_SSL_CONTEXT_SERIALIZATION'],
}
def handle_exclusive_groups(config_settings, symbol):
    """For every symbol tested in an exclusive group check if there are other
defines to be altered. """
    for dep in EXCLUSIVE_GROUPS.get(symbol, []):
        unset = dep.startswith('-')
        dep = dep[1:]
        config_settings[dep] = not unset

def turn_off_dependencies(config_settings, exclude=None):
    """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.
    Handle the dependencies recursively.

    If 'exclude' is a symbol, ensure its dependencies are not turned off while dependencies
    of other settings are turned off.
    """

    # Determine recursively the settings that should not be turned off for the sake of 'exclude'.
    excludes = set()
    if exclude:
        revdep = set(REVERSE_DEPENDENCIES.get(exclude, []))
        while revdep:
            dep = revdep.pop()
            excludes.add(dep)
            revdep.update(set(REVERSE_DEPENDENCIES.get(dep, [])) - excludes)

    for key, value in sorted(config_settings.items()):
        if value is not False:
            continue

        # Save the processed settings to handle cross referencies.
        # Start with set of settings that we do not want to turn off.
        history = excludes.copy()
        revdep = set(REVERSE_DEPENDENCIES.get(key, [])) - excludes
        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."""
    def __init__(self, symbols, commands, exclude):
        """Initialize the jobs container"""
        self.jobs = []

class ExclusiveDomain(BaseDomain): # pylint: disable=too-few-public-methods
    """A domain consisting of a set of conceptually-equivalent settings.
Establish a list of configuration symbols. For each symbol, run a test job
with this symbol set and the others unset."""
    def __init__(self, symbols, commands, exclude=None):
        """Build a domain for the specified list of configuration symbols.
The domain contains a set of jobs that enable one of the elements
of symbols and disable the others.
Each job runs the specified commands.
If exclude is a regular expression, skip generated jobs whose description
would match this regular expression."""
        super().__init__(symbols, commands, exclude)
        base_config_settings = {}
        for symbol in symbols:
            base_config_settings[symbol] = False
        for symbol in symbols:
            description = symbol
            if exclude and re.match(exclude, description):
                continue
            config_settings = base_config_settings.copy()
            config_settings[symbol] = True
            handle_exclusive_groups(config_settings, symbol)
            turn_off_dependencies(config_settings, symbol)
            job = Job(description, config_settings, commands)
            self.jobs.append(job)

class ComplementaryDomain(BaseDomain): # pylint: disable=too-few-public-methods
    """A domain consisting of a set of loosely-related settings.
Establish a list of configuration symbols. For each symbol, run a test job
with this symbol unset.
If exclude is a regular expression, skip generated jobs whose description
would match this regular expression."""
    def __init__(self, symbols, commands, exclude=None):
        """Build a domain for the specified list of configuration symbols.
Each job in the domain disables one of the specified symbols.
Each job runs the specified commands."""
        super().__init__(symbols, commands, exclude)
        for symbol in symbols:
            description = '!' + symbol
            if exclude and re.match(exclude, description):
                continue
            config_settings = {symbol: False}
            turn_off_dependencies(config_settings)
            job = Job(description, config_settings, commands)
            self.jobs.append(job)

class DualDomain(ExclusiveDomain, ComplementaryDomain): # pylint: disable=too-few-public-methods
    """A domain that contains both the ExclusiveDomain and BaseDomain tests.
Both parent class __init__ calls are performed in any order and
each call adds respective jobs. The job array initialization is done once in
BaseDomain, before the parent __init__ calls."""

class DomainData:
    """A container for domains and jobs, used to structurize testing."""
    def config_symbols_matching(self, regexp):
        """List the mbedtls_config.h settings matching regexp."""
        return [symbol for symbol in self.all_config_symbols
                if re.match(regexp, symbol)]

    # pylint: disable=too-many-locals
    def __init__(self, options, conf):
        """Gather data about the library and establish a list of domains to test."""
        build_command = [options.make_command, 'CFLAGS=-Werror -O2']
        build_and_test = [build_command, [options.make_command, 'test']]
        self.all_config_symbols = set(conf.settings.keys())
        psa_info = psa_information.Information().constructors
        algs = {crypto_knowledge.Algorithm(alg): symbol
                for alg, symbol in ((alg, psa_information.psa_want_symbol(alg))
                                    for alg in psa_info.algorithms)
                if symbol in self.all_config_symbols}
        cipher_algs = {alg
                       for alg in algs
                       if alg.can_do(crypto_knowledge.AlgorithmCategory.CIPHER)}
        key_types = {crypto_knowledge.KeyType(expr): symbol
                     for key_type in psa_info.key_types
                     for expr, symbol in ((expr, psa_information.psa_want_symbol(key_type))
                                          for expr in psa_info.generate_expressions([key_type]))
                     if symbol in self.all_config_symbols}

        # Find hash modules by name.
        hash_symbols = self.config_symbols_matching(r'MBEDTLS_(MD|RIPEMD|SHA)[0-9]+_C\Z')

        # Find elliptic curve enabling macros
        # MBEDTLS_ECP_DP_SECP224K1_ENABLED added to disable it for all curves
        curve_symbols = self.config_symbols_matching(r'PSA_WANT_ECC_\w+\Z|'
                                                     r'MBEDTLS_ECP_DP_SECP224K1_ENABLED')

        # Find key exchange enabling macros by name.
        key_exchange_symbols = self.config_symbols_matching(r'MBEDTLS_KEY_EXCHANGE_\w+_ENABLED\Z')

        # Find cipher key types
        cipher_key_types = {symbol
                            for key_type, symbol in key_types.items()
                            for alg in cipher_algs
                            if key_type.can_do(alg)}

        # Get cipher modes
        cipher_chaining_symbols = {algs[cipher_alg] for cipher_alg in cipher_algs}

        # Find block padding mode enabling macros by name.
        cipher_padding_symbols = self.config_symbols_matching(r'MBEDTLS_CIPHER_PADDING_\w+\Z')

        self.domains = {
            # Cipher key types
            'cipher_id': ExclusiveDomain(cipher_key_types, build_and_test),

            # XTS is not yet supported via the PSA API.
            # See https://github.com/Mbed-TLS/mbedtls/issues/6384
            'cipher_chaining': ExclusiveDomain(cipher_chaining_symbols,
                                               build_and_test,
                                               exclude=r'PSA_WANT_ALG_XTS'),

            'cipher_padding': ExclusiveDomain(cipher_padding_symbols,
                                              build_and_test),

            # Elliptic curves. Run the test suites.
            'curves': ExclusiveDomain(curve_symbols, build_and_test,
                                      exclude=r'MBEDTLS_ECP_DP_SECP224K1_ENABLED'),

            # Hash algorithms. Excluding exclusive domains of MD, RIPEMD, SHA1,
            # SHA224 and SHA384 because MBEDTLS_ENTROPY_C is extensively used
            # across various modules, but it depends on either SHA256 or SHA512.
            # As a consequence an "exclusive" test of anything other than SHA256
            # or SHA512 with MBEDTLS_ENTROPY_C enabled is not possible.
            'hashes': DualDomain(hash_symbols, build_and_test,
                                 exclude=r'MBEDTLS_(MD|RIPEMD|SHA1_)' \
                                          '|MBEDTLS_SHA224_' \
                                          '|MBEDTLS_SHA384_' \
                                          '|MBEDTLS_SHA3_'),
            # Key exchange types.
            'kex': ExclusiveDomain(key_exchange_symbols, build_and_test),
            'pkalgs': ComplementaryDomain(['MBEDTLS_ECDSA_C',
                                           'MBEDTLS_ECP_C',
                                           'MBEDTLS_PKCS1_V21',
                                           'MBEDTLS_PKCS1_V15',
                                           'MBEDTLS_RSA_C',
                                           'MBEDTLS_X509_RSASSA_PSS_SUPPORT'],
                                          build_and_test),
        }
        self.jobs = {}
        for domain in self.domains.values():
            for job in domain.jobs:
                self.jobs[job.name] = job

    def get_jobs(self, name):
        """Return the list of jobs identified by the given name.
A name can either be the name of a domain or the name of one specific job."""
        if name in self.domains:
            return sorted(self.domains[name].jobs, key=lambda job: job.name)
        else:
            return [self.jobs[name]]

def run(options, job, conf, colors=NO_COLORS):
    """Run the specified job (a Job instance)."""
    subprocess.check_call([options.make_command, 'clean'])
    job.announce(colors, None)
    if not job.configure(conf, colors):
        job.announce(colors, False)
        return False
    conf.write()
    success = job.test(options)
    job.announce(colors, success)
    return success

def run_tests(options, domain_data, conf):
    """Run the desired jobs.
domain_data should be a DomainData instance that describes the available
domains and jobs.
Run the jobs listed in options.tasks."""
    colors = Colors(options)
    jobs = []
    failures = []
    successes = []
    for name in options.tasks:
        jobs += domain_data.get_jobs(name)
    conf.backup()
    try:
        for job in jobs:
            success = run(options, job, conf, colors=colors)
            if not success:
                if options.keep_going:
                    failures.append(job.name)
                else:
                    return False
            else:
                successes.append(job.name)
        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:
            conf.restore()
        raise
    if successes:
        log_line('{} passed'.format(' '.join(successes)), color=colors.bold_green)
    if failures:
        log_line('{} FAILED'.format(' '.join(failures)), color=colors.bold_red)
        return False
    else:
        return True

def main():
    try:
        parser = argparse.ArgumentParser(
            formatter_class=argparse.RawDescriptionHelpFormatter,
            description=
            "Test Mbed TLS with a subset of algorithms.\n\n"
            "Example usage:\n"
            r"./tests/scripts/depends.py \!MBEDTLS_SHA1_C MBEDTLS_SHA256_C""\n"
            "./tests/scripts/depends.py MBEDTLS_AES_C hashes\n"
            "./tests/scripts/depends.py cipher_id cipher_chaining\n")
        parser.add_argument('--color', metavar='WHEN',
                            help='Colorize the output (always/auto/never)',
                            choices=['always', 'auto', 'never'], default='auto')
        parser.add_argument('-c', '--config', metavar='FILE',
                            help='Configuration file to modify',
                            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='.')
        parser.add_argument('-k', '--keep-going',
                            help='Try all configurations even if some fail (default)',
                            action='store_true', dest='keep_going', default=True)
        parser.add_argument('-e', '--no-keep-going',
                            help='Stop as soon as a configuration fails',
                            action='store_false', dest='keep_going')
        parser.add_argument('--list-jobs',
                            help='List supported jobs and exit',
                            action='append_const', dest='list', const='jobs')
        parser.add_argument('--list-domains',
                            help='List supported domains and exit',
                            action='append_const', dest='list', const='domains')
        parser.add_argument('--make-command', metavar='CMD',
                            help='Command to run instead of make (e.g. gmake)',
                            action='store', default='make')
        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.CombinedConfig(config.MbedTLSConfigFile(options.config),
                                     config.CryptoConfigFile(options.crypto_config))
        domain_data = DomainData(options, conf)

        if options.tasks is True:
            options.tasks = sorted(domain_data.domains.keys())
        if options.list:
            for arg in options.list:
                for domain_name in sorted(getattr(domain_data, arg).keys()):
                    print(domain_name)
            sys.exit(0)
        else:
            sys.exit(0 if run_tests(options, domain_data, conf) else 1)
    except Exception: # pylint: disable=broad-except
        traceback.print_exc()
        sys.exit(3)

if __name__ == '__main__':
    main()
