Merge pull request #9341 from gilles-peskine-arm/psa_cipher_decrypt-ccm_star-iv_length_enforcement-3.6
Backport 3.6: psa_cipher_decrypt CCM*: fix rejection of messages shorter than 3 bytes
diff --git a/framework b/framework
index 0484721..29e8dce 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 04847216ab964b9bdce41f1e61ccc6d8f5d2a139
+Subproject commit 29e8dce54a1041e22489f713cc8c44f700fafcec
diff --git a/library/cipher.c b/library/cipher.c
index 0683677..7f4c121 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -849,6 +849,9 @@
}
padding_len = input[input_len - 1];
+ if (padding_len == 0 || padding_len > input_len) {
+ return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
+ }
*data_len = input_len - padding_len;
mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
diff --git a/scripts/config.py b/scripts/config.py
index c53f9e7..8704bdb 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -396,6 +396,7 @@
self.default_path)
super().__init__()
self.filename = filename
+ self.inclusion_guard = None
self.current_section = 'header'
with open(filename, 'r', encoding='utf-8') as file:
self.templates = [self._parse_line(line) for line in file]
@@ -413,9 +414,11 @@
r'(?P<arguments>(?:\((?:\w|\s|,)*\))?)' +
r'(?P<separator>\s*)' +
r'(?P<value>.*)')
+ _ifndef_line_regexp = r'#ifndef (?P<inclusion_guard>\w+)'
_section_line_regexp = (r'\s*/?\*+\s*[\\@]name\s+SECTION:\s*' +
r'(?P<section>.*)[ */]*')
_config_line_regexp = re.compile(r'|'.join([_define_line_regexp,
+ _ifndef_line_regexp,
_section_line_regexp]))
def _parse_line(self, line):
"""Parse a line in mbedtls_config.h and return the corresponding template."""
@@ -426,10 +429,16 @@
elif m.group('section'):
self.current_section = m.group('section')
return line
+ elif m.group('inclusion_guard') and self.inclusion_guard is None:
+ self.inclusion_guard = m.group('inclusion_guard')
+ return line
else:
active = not m.group('commented_out')
name = m.group('name')
value = m.group('value')
+ if name == self.inclusion_guard and value == '':
+ # The file double-inclusion guard is not an option.
+ return line
template = (name,
m.group('indentation'),
m.group('define') + name +
diff --git a/scripts/make_generated_files.bat b/scripts/make_generated_files.bat
index f04f6b7..b03bce2 100644
--- a/scripts/make_generated_files.bat
+++ b/scripts/make_generated_files.bat
@@ -11,6 +11,7 @@
perl scripts\generate_visualc_files.pl || exit /b 1
python scripts\generate_psa_constants.py || exit /b 1
python framework\scripts\generate_bignum_tests.py || exit /b 1
+python framework\scripts\generate_config_tests.py || exit /b 1
python framework\scripts\generate_ecp_tests.py || exit /b 1
python framework\scripts\generate_psa_tests.py || exit /b 1
python framework\scripts\generate_test_keys.py --output tests\src\test_keys.h || exit /b 1
diff --git a/tests/.gitignore b/tests/.gitignore
index 838ea69..870fa79 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -3,22 +3,24 @@
*.log
/test_suite*
-data_files/mpi_write
-data_files/hmac_drbg_seed
-data_files/ctr_drbg_seed
-data_files/entropy_seed
+/data_files/mpi_write
+/data_files/hmac_drbg_seed
+/data_files/ctr_drbg_seed
+/data_files/entropy_seed
-include/alt-extra/psa/crypto_platform_alt.h
-include/alt-extra/psa/crypto_struct_alt.h
-include/test/instrument_record_status.h
+/include/alt-extra/psa/crypto_platform_alt.h
+/include/alt-extra/psa/crypto_struct_alt.h
+/include/test/instrument_record_status.h
-src/libmbed*
+/src/libmbed*
-libtestdriver1/*
+/libtestdriver1/*
###START_GENERATED_FILES###
# Generated source files
/suites/*.generated.data
+/suites/test_suite_config.mbedtls_boolean.data
+/suites/test_suite_config.psa_boolean.data
/suites/test_suite_psa_crypto_storage_format.v[0-9]*.data
/suites/test_suite_psa_crypto_storage_format.current.data
/src/test_keys.h
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 5bc38b4..37fe465 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -33,6 +33,18 @@
execute_process(
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_config_tests.py
+ --list-for-cmake
+ WORKING_DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ OUTPUT_VARIABLE
+ base_config_generated_data_files)
+string(REGEX REPLACE "[^;]*/" ""
+ base_config_generated_data_files "${base_config_generated_data_files}")
+
+execute_process(
+ COMMAND
+ ${MBEDTLS_PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_ecp_tests.py
--list-for-cmake
WORKING_DIRECTORY
@@ -61,11 +73,15 @@
string(REGEX REPLACE "([^;]+)" "suites/\\1"
all_generated_data_files "${base_generated_data_files}")
set(bignum_generated_data_files "")
+set(config_generated_data_files "")
set(ecp_generated_data_files "")
set(psa_generated_data_files "")
foreach(file ${base_bignum_generated_data_files})
list(APPEND bignum_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
+foreach(file ${base_config_generated_data_files})
+ list(APPEND config_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
+endforeach()
foreach(file ${base_ecp_generated_data_files})
list(APPEND ecp_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
@@ -94,6 +110,21 @@
)
add_custom_command(
OUTPUT
+ ${config_generated_data_files}
+ WORKING_DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ COMMAND
+ ${MBEDTLS_PYTHON_EXECUTABLE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_config_tests.py
+ --directory ${CMAKE_CURRENT_BINARY_DIR}/suites
+ DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_config_tests.py
+ # Do not declare the configuration files as dependencies: they
+ # change too often in ways that don't affect the result
+ # ((un)commenting some options).
+ )
+ add_custom_command(
+ OUTPUT
${ecp_generated_data_files}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}/..
@@ -142,6 +173,7 @@
# With this line, only 4 sub-makefiles include the above command, that reduces
# the risk of a race.
add_custom_target(test_suite_bignum_generated_data DEPENDS ${bignum_generated_data_files})
+add_custom_target(test_suite_config_generated_data DEPENDS ${config_generated_data_files})
add_custom_target(test_suite_ecp_generated_data DEPENDS ${ecp_generated_data_files})
add_custom_target(test_suite_psa_generated_data DEPENDS ${psa_generated_data_files})
# If SKIP_TEST_SUITES is not defined with -D, get it from the environment.
@@ -199,6 +231,10 @@
set(data_file
${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
set(dependency test_suite_bignum_generated_data)
+ elseif(";${config_generated_data_names};" MATCHES ";${data_name};")
+ set(data_file
+ ${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
+ set(dependency test_suite_bignum_generated_data)
elseif(";${ecp_generated_data_names};" MATCHES ";${data_name};")
set(data_file
${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
@@ -210,7 +246,11 @@
else()
set(data_file
${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data)
- set(dependency test_suite_bignum_generated_data test_suite_ecp_generated_data test_suite_psa_generated_data)
+ set(dependency
+ test_suite_bignum_generated_data
+ test_suite_config_generated_data
+ test_suite_ecp_generated_data
+ test_suite_psa_generated_data)
endif()
add_custom_command(
diff --git a/tests/Makefile b/tests/Makefile
index d71c2e3..af26965 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -16,7 +16,6 @@
LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG
endif
-.PHONY: generated_files
GENERATED_BIGNUM_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) ../framework/scripts/generate_bignum_tests.py --list || \
echo FAILED \
@@ -24,6 +23,17 @@
ifeq ($(GENERATED_BIGNUM_DATA_FILES),FAILED)
$(error "$(PYTHON) ../framework/scripts/generate_bignum_tests.py --list" failed)
endif
+GENERATED_DATA_FILES += $(GENERATED_BIGNUM_DATA_FILES)
+
+GENERATED_CONFIG_DATA_FILES := $(patsubst tests/%,%,$(shell \
+ $(PYTHON) ../framework/scripts/generate_config_tests.py --list || \
+ echo FAILED \
+))
+ifeq ($(GENERATED_CONFIG_DATA_FILES),FAILED)
+$(error "$(PYTHON) ../framework/scripts/generate_config_tests.py --list" failed)
+endif
+GENERATED_DATA_FILES += $(GENERATED_CONFIG_DATA_FILES)
+
GENERATED_ECP_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) ../framework/scripts/generate_ecp_tests.py --list || \
echo FAILED \
@@ -31,6 +41,8 @@
ifeq ($(GENERATED_ECP_DATA_FILES),FAILED)
$(error "$(PYTHON) ../framework/scripts/generate_ecp_tests.py --list" failed)
endif
+GENERATED_DATA_FILES += $(GENERATED_ECP_DATA_FILES)
+
GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) ../framework/scripts/generate_psa_tests.py --list || \
echo FAILED \
@@ -38,8 +50,13 @@
ifeq ($(GENERATED_PSA_DATA_FILES),FAILED)
$(error "$(PYTHON) ../framework/scripts/generate_psa_tests.py --list" failed)
endif
-GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_ECP_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES)
-generated_files: $(GENERATED_FILES) src/test_keys.h src/test_certs.h
+GENERATED_DATA_FILES += $(GENERATED_PSA_DATA_FILES)
+
+GENERATED_FILES = $(GENERATED_DATA_FILES)
+GENERATED_FILES += src/test_keys.h src/test_certs.h
+
+.PHONY: generated_files
+generated_files: $(GENERATED_FILES)
# generate_bignum_tests.py and generate_psa_tests.py spend more time analyzing
# inputs than generating outputs. Its inputs are the same no matter which files
@@ -47,7 +64,6 @@
# It's rare not to want all the outputs. So always generate all of its outputs.
# Use an intermediate phony dependency so that parallel builds don't run
# a separate instance of the recipe for each output file.
-.SECONDARY: generated_bignum_test_data generated_ecp_test_data generated_psa_test_data
$(GENERATED_BIGNUM_DATA_FILES): $(gen_file_dep) generated_bignum_test_data
generated_bignum_test_data: ../framework/scripts/generate_bignum_tests.py
generated_bignum_test_data: ../framework/scripts/mbedtls_framework/bignum_common.py
@@ -59,6 +75,23 @@
generated_bignum_test_data:
echo " Gen $(GENERATED_BIGNUM_DATA_FILES)"
$(PYTHON) ../framework/scripts/generate_bignum_tests.py
+.SECONDARY: generated_bignum_test_data
+
+# We deliberately omit the configuration files (mbedtls_config.h,
+# crypto_config.h) from the depenency list because during development
+# and on the CI, we often edit those in a way that doesn't change the
+# output, to comment out certain options, or even to remove certain
+# lines which do affect the output negatively (it will miss the
+# corresponding test cases).
+$(GENERATED_CONFIG_DATA_FILES): $(gen_file_dep) generated_config_test_data
+generated_config_test_data: ../framework/scripts/generate_config_tests.py
+generated_config_test_data: ../scripts/config.py
+generated_config_test_data: ../framework/scripts/mbedtls_framework/test_case.py
+generated_config_test_data: ../framework/scripts/mbedtls_framework/test_data_generation.py
+generated_config_test_data:
+ echo " Gen $(GENERATED_CONFIG_DATA_FILES)"
+ $(PYTHON) ../framework/scripts/generate_config_tests.py
+.SECONDARY: generated_config_test_data
$(GENERATED_ECP_DATA_FILES): $(gen_file_dep) generated_ecp_test_data
generated_ecp_test_data: ../framework/scripts/generate_ecp_tests.py
@@ -69,6 +102,7 @@
generated_ecp_test_data:
echo " Gen $(GENERATED_ECP_DATA_FILES)"
$(PYTHON) ../framework/scripts/generate_ecp_tests.py
+.SECONDARY: generated_ecp_test_data
$(GENERATED_PSA_DATA_FILES): $(gen_file_dep) generated_psa_test_data
generated_psa_test_data: ../framework/scripts/generate_psa_tests.py
@@ -91,6 +125,7 @@
generated_psa_test_data:
echo " Gen $(GENERATED_PSA_DATA_FILES) ..."
$(PYTHON) ../framework/scripts/generate_psa_tests.py
+.SECONDARY: generated_psa_test_data
# A test application is built for each suites/test_suite_*.data file.
# Application name is same as .data file's base name and can be
@@ -98,7 +133,7 @@
DATA_FILES := $(wildcard suites/test_suite_*.data)
# Make sure that generated data files are included even if they don't
# exist yet when the makefile is parsed.
-DATA_FILES += $(filter-out $(DATA_FILES),$(GENERATED_FILES))
+DATA_FILES += $(filter-out $(DATA_FILES),$(GENERATED_DATA_FILES))
APPS = $(basename $(subst suites/,,$(DATA_FILES)))
# Construct executable name by adding OS specific suffix $(EXEXT).
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index eb24694..f8147d1 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -160,10 +160,10 @@
# don't issue an error if they're skipped with drivers,
# but issue an error if they're not (means we have a bad entry).
ignored = False
- if full_test_suite in ignored_tests:
- for str_or_re in ignored_tests[full_test_suite]:
- if name_matches_pattern(test_string, str_or_re):
- ignored = True
+ for str_or_re in (ignored_tests.get(full_test_suite, []) +
+ ignored_tests.get(test_suite, [])):
+ if name_matches_pattern(test_string, str_or_re):
+ ignored = True
if not ignored and not suite_case in driver_outcomes.successes:
results.error("PASS -> SKIP/FAIL: {}", suite_case)
@@ -242,6 +242,9 @@
'psa_crypto_low_hash.generated', # testing the builtins
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(MD5|RIPEMD160|SHA[0-9]+)_.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -265,6 +268,10 @@
'psa_crypto_low_hash.generated',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(MD5|RIPEMD160|SHA[0-9]+)_.*'),
+ re.compile(r'.*\bMBEDTLS_MD_C\b')
+ ],
'test_suite_md': [
# Builtin HMAC is not supported in the accelerate component.
re.compile('.*HMAC.*'),
@@ -304,6 +311,12 @@
'cipher',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(AES|ARIA|CAMELLIA|CHACHA20|DES)_.*'),
+ re.compile(r'.*\bMBEDTLS_(CCM|CHACHAPOLY|CMAC|GCM)_.*'),
+ re.compile(r'.*\bMBEDTLS_AES(\w+)_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_CIPHER_.*'),
+ ],
# PEM decryption is not supported so far.
# The rest of PEM (write, unencrypted read) works though.
'test_suite_pem': [
@@ -357,6 +370,9 @@
'ecdsa', 'ecdh', 'ecjpake',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(ECDH|ECDSA|ECJPAKE|ECP)_.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -397,6 +413,10 @@
'ecp', 'ecdsa', 'ecdh', 'ecjpake',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(ECDH|ECDSA|ECJPAKE|ECP)_.*'),
+ re.compile(r'.*\bMBEDTLS_PK_PARSE_EC_COMPRESSED\b.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -436,6 +456,11 @@
'bignum.generated', 'bignum.misc',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_BIGNUM_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_(ECDH|ECDSA|ECJPAKE|ECP)_.*'),
+ re.compile(r'.*\bMBEDTLS_PK_PARSE_EC_COMPRESSED\b.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -485,6 +510,13 @@
# provide), even with MBEDTLS_USE_PSA_CRYPTO.
re.compile(r'PSK callback:.*\bdhe-psk\b.*'),
],
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_BIGNUM_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_DHM_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_(ECDH|ECDSA|ECJPAKE|ECP)_.*'),
+ re.compile(r'.*\bMBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED\b.*'),
+ re.compile(r'.*\bMBEDTLS_PK_PARSE_EC_COMPRESSED\b.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -523,6 +555,9 @@
'component_driver': 'test_psa_crypto_config_accel_ffdh',
'ignored_suites': ['dhm'],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_DHM_C\b.*'),
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -545,6 +580,15 @@
'bignum.generated', 'bignum.misc',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_BIGNUM_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_(ASN1\w+)_C\b.*'),
+ re.compile(r'.*\bMBEDTLS_(ECDH|ECDSA|ECP)_.*'),
+ re.compile(r'.*\bMBEDTLS_PSA_P256M_DRIVER_ENABLED\b.*')
+ ],
+ 'test_suite_config.crypto_combinations': [
+ 'Config: ECC: Weierstrass curves only',
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -570,6 +614,10 @@
'pk', 'pkwrite', 'pkparse'
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(PKCS1|RSA)_.*'),
+ re.compile(r'.*\bMBEDTLS_GENPRIME\b.*')
+ ],
'test_suite_platform': [
# Incompatible with sanitizers (e.g. ASan). If the driver
# component uses a sanitizer but the reference component
@@ -611,6 +659,10 @@
'cipher.camellia',
],
'ignored_tests': {
+ 'test_suite_config': [
+ re.compile(r'.*\bMBEDTLS_(AES|ARIA|CAMELLIA)_.*'),
+ re.compile(r'.*\bMBEDTLS_AES(\w+)_C\b.*'),
+ ],
'test_suite_cmac': [
# Following tests require AES_C/ARIA_C/CAMELLIA_C to be enabled,
# but these are not available in the accelerated component.
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index e740f33..09c850a 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -129,6 +129,7 @@
# These checks are common to Mbed TLS and TF-PSA-Crypto
check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generated.c
check framework/scripts/generate_bignum_tests.py $(framework/scripts/generate_bignum_tests.py --list)
+check framework/scripts/generate_config_tests.py $(framework/scripts/generate_config_tests.py --list)
check framework/scripts/generate_ecp_tests.py $(framework/scripts/generate_ecp_tests.py --list)
check framework/scripts/generate_psa_tests.py $(framework/scripts/generate_psa_tests.py --list)
check framework/scripts/generate_test_keys.py tests/src/test_keys.h
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index aca4150..8e49d2d 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -549,6 +549,10 @@
/* encode length number of bytes from inbuf */
TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, inbuf, length, encbuf, &outlen));
TEST_ASSERT(ret == mbedtls_cipher_finish(&ctx, encbuf + outlen, &outlen));
+ if (0 != ret) {
+ /* Check output parameter is set to the least-harmful value on error */
+ TEST_ASSERT(0 == outlen);
+ }
/* done */
exit:
@@ -826,6 +830,10 @@
total_len += outlen;
TEST_ASSERT(finish_result == mbedtls_cipher_finish(&ctx, output + outlen,
&outlen));
+ if (0 != finish_result) {
+ /* Check output parameter is set to the least-harmful value on error */
+ TEST_ASSERT(0 == outlen);
+ }
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
diff --git a/tests/suites/test_suite_config.crypto_combinations.data b/tests/suites/test_suite_config.crypto_combinations.data
new file mode 100644
index 0000000..d3287d2
--- /dev/null
+++ b/tests/suites/test_suite_config.crypto_combinations.data
@@ -0,0 +1,9 @@
+# Interesting combinations of low-level crypto options
+
+Config: ECC: Weierstrass curves only
+depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:!MBEDTLS_ECP_MONTGOMERY_ENABLED
+pass:
+
+Config: ECC: Montgomery curves only
+depends_on:!MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:MBEDTLS_ECP_MONTGOMERY_ENABLED
+pass:
diff --git a/tests/suites/test_suite_config.function b/tests/suites/test_suite_config.function
new file mode 100644
index 0000000..9e9dd01
--- /dev/null
+++ b/tests/suites/test_suite_config.function
@@ -0,0 +1,14 @@
+/* BEGIN_HEADER */
+
+/* END_HEADER */
+
+/* BEGIN_CASE */
+/* This test case always passes. It is intended solely for configuration
+ * reporting in the outcome file. Write test cases using this function
+ * with dependencies to record in which configurations the dependencies
+ * are met. */
+void pass()
+{
+ goto exit;
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_config.psa_combinations.data b/tests/suites/test_suite_config.psa_combinations.data
new file mode 100644
index 0000000..1035af2
--- /dev/null
+++ b/tests/suites/test_suite_config.psa_combinations.data
@@ -0,0 +1,9 @@
+# Interesting combinations of PSA options
+
+Config: PSA_WANT_ALG_ECDSA without PSA_WANT_ALG_DETERMINISTIC_ECDSA
+depends_on:PSA_WANT_ALG_ECDSA:!PSA_WANT_ALG_DETERMINISTIC_ECDSA
+pass:
+
+Config: PSA_WANT_ALG_DETERMINSTIC_ECDSA without PSA_WANT_ALG_ECDSA
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:!PSA_WANT_ALG_ECDSA
+pass:
diff --git a/tests/suites/test_suite_config.tls_combinations.data b/tests/suites/test_suite_config.tls_combinations.data
new file mode 100644
index 0000000..cbc57d6
--- /dev/null
+++ b/tests/suites/test_suite_config.tls_combinations.data
@@ -0,0 +1,9 @@
+# Interesting combinations of TLS options
+
+Config: TLS 1.2 without TLS 1.3
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:!MBEDTLS_SSL_PROTO_TLS1_3
+pass:
+
+Config: TLS 1.3 without TLS 1.2
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:!MBEDTLS_SSL_PROTO_TLS1_2
+pass: