1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-28 00:21:48 +03:00

Merge branch 'Mbed-TLS:development' into codegen_1.1

This commit is contained in:
asfand-silabs
2022-09-17 19:54:01 +02:00
committed by GitHub
389 changed files with 50509 additions and 19601 deletions

View File

@ -259,7 +259,7 @@ General options:
--no-force Refuse to overwrite modified files (default).
--no-keep-going Stop at the first error (default).
--no-memory No additional memory tests (default).
--no-quiet Print full ouput from components.
--no-quiet Print full output from components.
--out-of-source-dir=<path> Directory used for CMake out-of-source build tests.
--outcome-file=<path> File where test outcomes are written (not done if
empty; default: \$MBEDTLS_TEST_OUTCOME_FILE).
@ -866,6 +866,12 @@ component_check_test_cases () {
fi
tests/scripts/check_test_cases.py $opt
unset opt
# Check that no tests are explicitely disabled when USE_PSA_CRYPTO is set
# as a matter of policy to ensure there is no missed testing
msg "Check: explicitely disabled test with USE_PSA_CRYPTO" # < 1s
not grep -n 'depends_on:.*!MBEDTLS_USE_PSA_CRYPTO' tests/suites/*.function tests/suites/*.data
not grep -n '^ *requires_config_disabled.*MBEDTLS_USE_PSA_CRYPTO' tests/ssl-opt.sh tests/opt-testcases/*.sh
}
component_check_doxygen_warnings () {
@ -1059,6 +1065,7 @@ component_test_no_ctr_drbg_classic () {
scripts/config.py full
scripts/config.py unset MBEDTLS_CTR_DRBG_C
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
@ -1104,6 +1111,7 @@ component_test_no_hmac_drbg_classic () {
scripts/config.py unset MBEDTLS_HMAC_DRBG_C
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
@ -1156,6 +1164,7 @@ component_test_psa_external_rng_no_drbg_classic () {
msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto in TLS"
scripts/config.py full
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
scripts/config.py unset MBEDTLS_ENTROPY_C
scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
@ -1194,6 +1203,72 @@ component_test_psa_external_rng_no_drbg_use_psa () {
tests/ssl-opt.sh -f 'Default\|opaque'
}
component_test_crypto_full_no_md () {
msg "build: crypto_full minus MD"
scripts/config.py crypto_full
scripts/config.py unset MBEDTLS_MD_C
# Direct dependencies
scripts/config.py unset MBEDTLS_HKDF_C
scripts/config.py unset MBEDTLS_HMAC_DRBG_C
# Indirect dependencies
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
make
msg "test: crypto_full minus MD"
make test
}
component_test_full_no_cipher () {
msg "build: full minus CIPHER"
scripts/config.py full
scripts/config.py unset MBEDTLS_CIPHER_C
# Direct dependencies
scripts/config.py unset MBEDTLS_CCM_C
scripts/config.py unset MBEDTLS_CMAC_C
scripts/config.py unset MBEDTLS_GCM_C
scripts/config.py unset MBEDTLS_NIST_KW_C
scripts/config.py unset MBEDTLS_PKCS12_C
scripts/config.py unset MBEDTLS_PKCS5_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
scripts/config.py unset MBEDTLS_SSL_TLS_C
scripts/config.py unset MBEDTLS_SSL_TICKET_C
# Indirect dependencies
scripts/config.py unset MBEDTLS_SSL_CLI_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
scripts/config.py unset MBEDTLS_SSL_DTLS_ANTI_REPLAY
scripts/config.py unset MBEDTLS_SSL_DTLS_CONNECTION_ID
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_SSL_SRV_C
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
make
msg "test: full minus CIPHER"
make test
}
component_test_crypto_full_no_cipher () {
msg "build: crypto_full minus CIPHER"
scripts/config.py crypto_full
scripts/config.py unset MBEDTLS_CIPHER_C
# Direct dependencies
scripts/config.py unset MBEDTLS_CCM_C
scripts/config.py unset MBEDTLS_CMAC_C
scripts/config.py unset MBEDTLS_GCM_C
scripts/config.py unset MBEDTLS_NIST_KW_C
scripts/config.py unset MBEDTLS_PKCS12_C
scripts/config.py unset MBEDTLS_PKCS5_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
# Indirect dependencies
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
make
msg "test: crypto_full minus CIPHER"
make test
}
component_test_psa_external_rng_use_psa_crypto () {
msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
scripts/config.py full
@ -1223,7 +1298,7 @@ component_test_everest () {
msg "test: Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
# Exclude some symmetric ciphers that are redundant here to gain time.
tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA\|DES'
tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
}
component_test_everest_curve25519_only () {
@ -1311,14 +1386,33 @@ component_test_full_cmake_clang () {
msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
msg "test: compat.sh DES, 3DES & NULL (full config)" # ~ 2 min
env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '^$' -f 'NULL\|DES'
msg "test: compat.sh NULL (full config)" # ~ 2 min
env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '^$' -f 'NULL'
msg "test: compat.sh ARIA + ChachaPoly"
env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
}
component_test_memsan_constant_flow () {
# This tests both (1) accesses to undefined memory, and (2) branches or
# memory access depending on secret values. To distinguish between those:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
# - or alternatively, change the build type to MemSanDbg, which enables
# origin tracking and nicer stack traces (which are useful for debugging
# anyway), and check if the origin was TEST_CF_SECRET() or something else.
msg "build: cmake MSan (clang), full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
scripts/config.py full
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
make
msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, Msan + constant flow)"
make test
}
component_test_memsan_constant_flow_psa () {
# This tests both (1) accesses to undefined memory, and (2) branches or
# memory access depending on secret values. To distinguish between those:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
@ -1337,6 +1431,29 @@ component_test_memsan_constant_flow () {
}
component_test_valgrind_constant_flow () {
# This tests both (1) everything that valgrind's memcheck usually checks
# (heap buffer overflows, use of uninitialized memory, use-after-free,
# etc.) and (2) branches or memory access depending on secret values,
# which will be reported as uninitialized memory. To distinguish between
# secret and actually uninitialized:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
# - or alternatively, build with debug info and manually run the offending
# test suite with valgrind --track-origins=yes, then check if the origin
# was TEST_CF_SECRET() or something else.
msg "build: cmake release GCC, full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
scripts/config.py full
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
cmake -D CMAKE_BUILD_TYPE:String=Release .
make
# this only shows a summary of the results (how many of each type)
# details are left in Testing/<date>/DynamicAnalysis.xml
msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, valgrind + constant flow)"
make memcheck
}
component_test_valgrind_constant_flow_psa () {
# This tests both (1) everything that valgrind's memcheck usually checks
# (heap buffer overflows, use of uninitialized memory, use-after-free,
# etc.) and (2) branches or memory access depending on secret values,
@ -1435,9 +1552,24 @@ component_build_crypto_full () {
component_build_crypto_baremetal () {
msg "build: make, crypto only, baremetal config"
scripts/config.py crypto_baremetal
make CFLAGS='-O1 -Werror'
make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
are_empty_libraries library/libmbedx509.* library/libmbedtls.*
}
support_build_crypto_baremetal () {
support_build_baremetal "$@"
}
component_build_baremetal () {
msg "build: make, baremetal config"
scripts/config.py baremetal
make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
}
support_build_baremetal () {
# Older Glibc versions include time.h from other headers such as stdlib.h,
# which makes the no-time.h-in-baremetal check fail. Ubuntu 16.04 has this
# problem, Ubuntu 18.04 is ok.
! grep -q -F time.h /usr/include/x86_64-linux-gnu/sys/types.h
}
component_test_depends_curves () {
msg "test/build: curves.pl (gcc)" # ~ 4 min
@ -1498,6 +1630,12 @@ component_build_module_alt () {
# The SpecifiedECDomain parsing code accesses mbedtls_ecp_group fields
# directly and assumes the implementation works with partial groups.
scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
# MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_A64_CRYPTO_*
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
# MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
# Enable all MBEDTLS_XXX_ALT for whole modules. Do not enable
# MBEDTLS_XXX_YYY_ALT which are for single functions.
scripts/config.py set-all 'MBEDTLS_([A-Z0-9]*|NIST_KW)_ALT'
@ -1541,8 +1679,8 @@ component_test_no_use_psa_crypto_full_cmake_asan() {
msg "test: compat.sh default (full minus MBEDTLS_USE_PSA_CRYPTO)"
tests/compat.sh
msg "test: compat.sh DES & NULL (full minus MBEDTLS_USE_PSA_CRYPTO)"
env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES'
msg "test: compat.sh NULL (full minus MBEDTLS_USE_PSA_CRYPTO)"
env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -f 'NULL'
msg "test: compat.sh ARIA + ChachaPoly (full minus MBEDTLS_USE_PSA_CRYPTO)"
env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
@ -1571,6 +1709,7 @@ component_test_psa_crypto_config_accel_ecdsa () {
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_ECDSA_C
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
@ -1617,6 +1756,8 @@ component_test_psa_crypto_config_accel_rsa_signature () {
scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA1_C
scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C
# We need to define either MD_C or all of the PSA_WANT_ALG_SHAxxx.
scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_MD_C
# We need PEM parsing in the test library as well to support the import
# of PEM encoded RSA keys.
scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_PEM_PARSE_C
@ -1629,6 +1770,7 @@ component_test_psa_crypto_config_accel_rsa_signature () {
# Restore test driver base configuration
scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA1_C
scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA512_C
scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_MD_C
scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_PEM_PARSE_C
scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_BASE64_C
@ -1684,12 +1826,6 @@ component_test_psa_crypto_config_accel_hash () {
# Don't unset MBEDTLS_SHA256_C as it is needed by PSA crypto core.
scripts/config.py unset MBEDTLS_SHA384_C
scripts/config.py unset MBEDTLS_SHA512_C
# Unset MBEDTLS_SSL_PROTO_SSL3, MBEDTLS_SSL_PROTO_TLS1 and MBEDTLS_SSL_PROTO_TLS1_1 as they depend on MBEDTLS_SHA1_C
scripts/config.py unset MBEDTLS_SSL_PROTO_SSL3
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_1
# Unset MBEDTLS_SSL_CBC_RECORD_SPLITTING as it depends on MBEDTLS_SSL_PROTO_TLS1 in the default configuration.
scripts/config.py unset MBEDTLS_SSL_CBC_RECORD_SPLITTING
loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS"
@ -1700,6 +1836,67 @@ component_test_psa_crypto_config_accel_hash () {
make test
}
component_test_psa_crypto_config_accel_hash_use_psa () {
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
# Disable ALG_STREAM_CIPHER and ALG_ECB_NO_PADDING to avoid having
# partial support for cipher operations in the driver test library.
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512"
loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_MD5_C
scripts/config.py unset MBEDTLS_RIPEMD160_C
scripts/config.py unset MBEDTLS_SHA1_C
scripts/config.py unset MBEDTLS_SHA224_C
scripts/config.py unset MBEDTLS_SHA256_C # see external RNG below
scripts/config.py unset MBEDTLS_SHA384_C
scripts/config.py unset MBEDTLS_SHA512_C
# Use an external RNG as currently internal RNGs depend on entropy.c
# which in turn hard-depends on SHA256_C (or SHA512_C).
# See component_test_psa_external_rng_no_drbg_use_psa.
scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
scripts/config.py unset MBEDTLS_ENTROPY_C
# Also unset MD_C and things that depend on it;
# see component_test_crypto_full_no_md.
scripts/config.py unset MBEDTLS_MD_C
scripts/config.py unset MBEDTLS_HKDF_C
scripts/config.py unset MBEDTLS_HMAC_DRBG_C
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
# Enable TLS 1.3: use PSA implementation for hashes
scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py set MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1
loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" all
# There's a risk of something getting re-enabled via config_psa.h;
# make sure it did not happen.
not grep mbedtls_md library/md.o
not grep mbedtls_md5 library/md5.o
not grep mbedtls_sha1 library/sha1.o
not grep mbedtls_sha256 library/sha256.o
not grep mbedtls_sha512 library/sha512.o
not grep mbedtls_ripemd160 library/ripemd160.o
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
make test
msg "test: ssl-opt.sh, MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
tests/ssl-opt.sh
msg "test: compat.sh, MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
tests/compat.sh
}
component_test_psa_crypto_config_accel_cipher () {
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated cipher"
@ -1732,7 +1929,7 @@ component_test_psa_crypto_config_accel_cipher () {
not grep mbedtls_des* library/des.o
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash"
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated cipher"
make test
}
@ -1743,6 +1940,7 @@ component_test_psa_crypto_config_no_driver() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py unset MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
make CC=gcc CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG minus MBEDTLS_PSA_CRYPTO_DRIVERS"
@ -1773,6 +1971,7 @@ component_build_psa_accel_alg_ecdsa() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_ECDSA_C
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
@ -1789,6 +1988,7 @@ component_build_psa_accel_alg_ecdh() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_ECDH_C
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
@ -1807,6 +2007,7 @@ component_build_psa_accel_key_type_ecc_key_pair() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
@ -1821,6 +2022,7 @@ component_build_psa_accel_key_type_ecc_public_key() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
@ -1835,6 +2037,7 @@ component_build_psa_accel_alg_hmac() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HMAC -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
}
@ -1848,6 +2051,7 @@ component_build_psa_accel_alg_hkdf() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py unset MBEDTLS_HKDF_C
# Make sure to unset TLS1_3 since it requires HKDF_C and will not build properly without it.
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
@ -1863,6 +2067,7 @@ component_build_psa_accel_alg_md5() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_224
@ -1881,6 +2086,7 @@ component_build_psa_accel_alg_ripemd160() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_224
@ -1899,6 +2105,7 @@ component_build_psa_accel_alg_sha1() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_224
@ -1917,6 +2124,7 @@ component_build_psa_accel_alg_sha224() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
@ -1934,6 +2142,7 @@ component_build_psa_accel_alg_sha256() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
@ -1952,6 +2161,7 @@ component_build_psa_accel_alg_sha384() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
@ -1969,6 +2179,7 @@ component_build_psa_accel_alg_sha512() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_SHA_1
@ -1987,6 +2198,7 @@ component_build_psa_accel_alg_rsa_pkcs1v15_crypt() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_OAEP
@ -2003,6 +2215,7 @@ component_build_psa_accel_alg_rsa_pkcs1v15_sign() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_OAEP
@ -2019,6 +2232,7 @@ component_build_psa_accel_alg_rsa_oaep() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_OAEP 1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
@ -2035,6 +2249,7 @@ component_build_psa_accel_alg_rsa_pss() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_PSS 1
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
@ -2051,6 +2266,7 @@ component_build_psa_accel_key_type_rsa_key_pair() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_PSS 1
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
@ -2065,6 +2281,7 @@ component_build_psa_accel_key_type_rsa_public_key() {
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_ALG_RSA_PSS 1
scripts/config.py -f include/psa/crypto_config.h set PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
@ -2085,6 +2302,7 @@ component_test_no_platform () {
scripts/config.py unset MBEDTLS_PLATFORM_SNPRINTF_ALT
scripts/config.py unset MBEDTLS_PLATFORM_TIME_ALT
scripts/config.py unset MBEDTLS_PLATFORM_EXIT_ALT
scripts/config.py unset MBEDTLS_PLATFORM_SETBUF_ALT
scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
scripts/config.py unset MBEDTLS_FS_IO
@ -2109,14 +2327,14 @@ component_build_no_std_function () {
}
component_build_no_ssl_srv () {
msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
msg "build: full config except SSL server, make, gcc" # ~ 30s
scripts/config.py full
scripts/config.py unset MBEDTLS_SSL_SRV_C
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
}
component_build_no_ssl_cli () {
msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s
msg "build: full config except SSL client, make, gcc" # ~ 30s
scripts/config.py full
scripts/config.py unset MBEDTLS_SSL_CLI_C
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
@ -2239,18 +2457,6 @@ component_test_variable_ssl_in_out_buffer_len_CID () {
tests/compat.sh
}
component_test_CID_no_debug() {
msg "build: Connection ID enabled, debug disabled"
scripts/config.py unset MBEDTLS_DEBUG_C
scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID
CC=gcc cmake .
make
msg "test: Connection ID enabled, debug disabled"
make test
}
component_test_ssl_alloc_buffer_and_mfl () {
msg "build: default config with memory buffer allocator and MFL extension"
scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
@ -2457,13 +2663,42 @@ component_test_gcc_opt () {
component_build_mbedtls_config_file () {
msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s
# Use the full config so as to catch a maximum of places where
# the check of MBEDTLS_CONFIG_FILE might be missing.
scripts/config.py full
sed 's!"check_config.h"!"mbedtls/check_config.h"!' <"$CONFIG_H" >full_config.h
scripts/config.py -w full_config.h full
echo '#error "MBEDTLS_CONFIG_FILE is not working"' >"$CONFIG_H"
make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"'"
rm -f full_config.h
# Make sure this feature is enabled. We'll disable it in the next phase.
programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
make clean
msg "build: make with MBEDTLS_CONFIG_FILE + MBEDTLS_USER_CONFIG_FILE"
# In the user config, disable one feature (for simplicity, pick a feature
# that nothing else depends on).
echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"' -DMBEDTLS_USER_CONFIG_FILE='\"user_config.h\"'"
not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
rm -f user_config.h full_config.h
}
component_build_psa_config_file () {
msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE" # ~40s
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
cp "$CRYPTO_CONFIG_H" psa_test_config.h
echo '#error "MBEDTLS_PSA_CRYPTO_CONFIG_FILE is not working"' >"$CRYPTO_CONFIG_H"
make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"'"
# Make sure this feature is enabled. We'll disable it in the next phase.
programs/test/query_compile_time_config MBEDTLS_CMAC_C
make clean
msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE + MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE" # ~40s
# In the user config, disable one feature, which will reflect on the
# mbedtls configuration so we can query it with query_compile_time_config.
echo '#undef PSA_WANT_ALG_CMAC' >psa_user_config.h
scripts/config.py unset MBEDTLS_CMAC_C
make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"' -DMBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE='\"psa_user_config.h\"'"
not programs/test/query_compile_time_config MBEDTLS_CMAC_C
rm -f psa_test_config.h psa_user_config.h
}
component_test_m32_o0 () {
@ -2513,7 +2748,7 @@ component_test_m32_everest () {
msg "test: i386, Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
# Exclude some symmetric ciphers that are redundant here to gain time.
tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA\|DES'
tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
}
support_test_m32_everest () {
support_test_m32_o0 "$@"
@ -2615,25 +2850,25 @@ component_test_no_x509_info () {
}
component_build_arm_none_eabi_gcc () {
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1" # ~ 10s
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug" # ~ 10s
scripts/config.py baremetal
make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -O1' lib
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1"
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug"
${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
}
component_build_arm_linux_gnueabi_gcc_arm5vte () {
msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
scripts/config.py baremetal
# Build for a target platform that's close to what Debian uses
# for its "armel" distribution (https://wiki.debian.org/ArmEabiPort).
# See https://github.com/ARMmbed/mbedtls/pull/2169 and comments.
# See https://github.com/Mbed-TLS/mbedtls/pull/2169 and comments.
# Build everything including programs, see for example
# https://github.com/ARMmbed/mbedtls/pull/3449#issuecomment-675313720
# https://github.com/Mbed-TLS/mbedtls/pull/3449#issuecomment-675313720
make CC="${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc" AR="${ARM_LINUX_GNUEABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te'
msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1"
msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
${ARM_LINUX_GNUEABI_GCC_PREFIX}size library/*.o
}
support_build_arm_linux_gnueabi_gcc_arm5vte () {
@ -2641,23 +2876,23 @@ support_build_arm_linux_gnueabi_gcc_arm5vte () {
}
component_build_arm_none_eabi_gcc_arm5vte () {
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
scripts/config.py baremetal
# This is an imperfect substitute for
# component_build_arm_linux_gnueabi_gcc_arm5vte
# in case the gcc-arm-linux-gnueabi toolchain is not available
make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-std=c99 -Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1"
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
}
component_build_arm_none_eabi_gcc_m0plus () {
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus" # ~ 10s
scripts/config.py baremetal
msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus, baremetal_size" # ~ 10s
scripts/config.py baremetal_size
make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -mthumb -mcpu=cortex-m0plus -Os' lib
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus -Os"
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus -Os, baremetal_size"
${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
}
@ -2682,6 +2917,10 @@ component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
component_build_armcc () {
msg "build: ARM Compiler 5"
scripts/config.py baremetal
# armc[56] don't support SHA-512 intrinsics
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py set MBEDTLS_HAVE_ASM
make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
msg "size: ARM Compiler 5"
@ -2689,20 +2928,25 @@ component_build_armcc () {
make clean
# Compile with -O1 since some Arm inline assembly is disabled for -O0.
# ARM Compiler 6 - Target ARMv7-A
armc6_build_test "--target=arm-arm-none-eabi -march=armv7-a"
armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-a"
# ARM Compiler 6 - Target ARMv7-M
armc6_build_test "--target=arm-arm-none-eabi -march=armv7-m"
armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m"
# ARM Compiler 6 - Target ARMv7-M+DSP
armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m+dsp"
# ARM Compiler 6 - Target ARMv8-A - AArch32
armc6_build_test "--target=arm-arm-none-eabi -march=armv8.2-a"
armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8.2-a"
# ARM Compiler 6 - Target ARMv8-M
armc6_build_test "--target=arm-arm-none-eabi -march=armv8-m.main"
armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8-m.main"
# ARM Compiler 6 - Target ARMv8-A - AArch64
armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a"
# ARM Compiler 6 - Target ARMv8.2-A - AArch64
armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
}
component_test_tls13_only () {
@ -2716,6 +2960,18 @@ component_test_tls13_only () {
if_build_succeeded tests/ssl-opt.sh
}
component_test_tls13_only_with_hooks () {
msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3 and MBEDTLS_TEST_HOOKS, without MBEDTLS_SSL_PROTO_TLS1_2"
scripts/config.py set MBEDTLS_TEST_HOOKS
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without MBEDTLS_SSL_PROTO_TLS1_2"
if_build_succeeded make test
msg "ssl-opt.sh (TLS 1.3)"
if_build_succeeded tests/ssl-opt.sh
}
component_test_tls13 () {
msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding"
scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3
@ -2888,16 +3144,17 @@ component_test_cmake_out_of_source () {
msg "test: cmake 'out-of-source' build"
make test
# Test an SSL option that requires an auxiliary script in test/scripts/.
# Check that ssl-opt.sh can find the test programs.
# Also ensure that there are no error messages such as
# "No such file or directory", which would indicate that some required
# file is missing (ssl-opt.sh tolerates the absence of some files so
# may exit with status 0 but emit errors).
./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
./tests/ssl-opt.sh -f 'Default' >ssl-opt.out 2>ssl-opt.err
grep PASS ssl-opt.out
cat ssl-opt.err >&2
# If ssl-opt.err is non-empty, record an error and keep going.
[ ! -s ssl-opt.err ]
rm ssl-opt.err
rm ssl-opt.out ssl-opt.err
cd "$MBEDTLS_ROOT_DIR"
rm -rf "$OUT_OF_SOURCE_DIR"
}
@ -3045,7 +3302,7 @@ run_component () {
local dd_cmd
dd_cmd=(dd if=/dev/urandom of=./tests/seedfile bs=64 count=1)
case $OSTYPE in
linux*|freebsd*|openbsd*|darwin*) dd_cmd+=(status=none)
linux*|freebsd*|openbsd*) dd_cmd+=(status=none)
esac
"${dd_cmd[@]}"

View File

@ -121,13 +121,13 @@ echo
echo '################ compat.sh ################'
{
echo '#### compat.sh: Default versions'
sh compat.sh -m 'tls1_2 dtls1_2'
sh compat.sh
echo
echo '#### compat.sh: legacy (null, DES)'
echo '#### compat.sh: legacy (null)'
OPENSSL_CMD="$OPENSSL_LEGACY" \
GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" \
sh compat.sh -e '^$' -f 'NULL\|DES'
sh compat.sh -e '^$' -f 'NULL'
echo
echo '#### compat.sh: next (ARIA, ChaCha)'

View File

@ -76,7 +76,7 @@ check()
for FILE in "$@"; do
if [ -e "$FILE" ]; then
cp "$FILE" "$FILE.bak"
cp -p "$FILE" "$FILE.bak"
else
rm -f "$FILE.bak"
fi
@ -86,17 +86,18 @@ check()
# Compare the script output to the old files and remove backups
for FILE in "$@"; do
if ! diff "$FILE" "$FILE.bak" >/dev/null 2>&1; then
if diff "$FILE" "$FILE.bak" >/dev/null 2>&1; then
# Move the original file back so that $FILE's timestamp doesn't
# change (avoids spurious rebuilds with make).
mv "$FILE.bak" "$FILE"
else
echo "'$FILE' was either modified or deleted by '$SCRIPT'"
if [ -z "$UPDATE" ]; then
exit 1
else
rm -f "$FILE.bak"
fi
fi
if [ -z "$UPDATE" ]; then
mv "$FILE.bak" "$FILE"
else
rm -f "$FILE.bak"
fi
done
if [ -n "$directory" ]; then
@ -125,4 +126,5 @@ check scripts/generate_ssl_debug_helpers.py library/ssl_debug_helpers_generated.
# the step that creates or updates these files.
check scripts/generate_visualc_files.pl visualc/VS2010
check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generated.c
check tests/scripts/generate_bignum_tests.py $(tests/scripts/generate_bignum_tests.py --list)
check tests/scripts/generate_psa_tests.py $(tests/scripts/generate_psa_tests.py --list)

View File

@ -187,7 +187,7 @@ class ShebangIssueTracker(FileIssueTracker):
# Allow either /bin/sh, /bin/bash, or /usr/bin/env.
# Allow at most one argument (this is a Linux limitation).
# For sh and bash, the argument if present must be options.
# For env, the argument must be the base name of the interpeter.
# For env, the argument must be the base name of the interpreter.
_shebang_re = re.compile(rb'^#! ?(?:/bin/(bash|sh)(?: -[^\n ]*)?'
rb'|/usr/bin/env ([^\n /]+))$')
_extensions = {

View File

@ -58,8 +58,9 @@ import logging
# Naming patterns to check against. These are defined outside the NameCheck
# class for ease of modification.
MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
CONSTANTS_PATTERN = MACRO_PATTERN
PUBLIC_MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
INTERNAL_MACRO_PATTERN = r"^[0-9A-Za-z_]*[0-9A-Z]$"
CONSTANTS_PATTERN = PUBLIC_MACRO_PATTERN
IDENTIFIER_PATTERN = r"^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$"
class Match(): # pylint: disable=too-few-public-methods
@ -249,14 +250,17 @@ class CodeParser():
.format(str(self.excluded_files))
)
all_macros = self.parse_macros([
all_macros = {"public": [], "internal": []}
all_macros["public"] = self.parse_macros([
"include/mbedtls/*.h",
"include/psa/*.h",
"library/*.h",
"tests/include/test/drivers/*.h",
"3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h"
])
all_macros["internal"] = self.parse_macros([
"library/*.h",
"tests/include/test/drivers/*.h",
])
enum_consts = self.parse_enum_consts([
"include/mbedtls/*.h",
"library/*.h",
@ -284,20 +288,25 @@ class CodeParser():
# Remove identifier macros like mbedtls_printf or mbedtls_calloc
identifiers_justname = [x.name for x in identifiers]
actual_macros = []
for macro in all_macros:
if macro.name not in identifiers_justname:
actual_macros.append(macro)
actual_macros = {"public": [], "internal": []}
for scope in actual_macros:
for macro in all_macros[scope]:
if macro.name not in identifiers_justname:
actual_macros[scope].append(macro)
self.log.debug("Found:")
# Aligns the counts on the assumption that none exceeds 4 digits
self.log.debug(" {:4} Total Macros".format(len(all_macros)))
self.log.debug(" {:4} Non-identifier Macros".format(len(actual_macros)))
for scope in actual_macros:
self.log.debug(" {:4} Total {} Macros"
.format(len(all_macros[scope]), scope))
self.log.debug(" {:4} {} Non-identifier Macros"
.format(len(actual_macros[scope]), scope))
self.log.debug(" {:4} Enum Constants".format(len(enum_consts)))
self.log.debug(" {:4} Identifiers".format(len(identifiers)))
self.log.debug(" {:4} Exported Symbols".format(len(symbols)))
return {
"macros": actual_macros,
"public_macros": actual_macros["public"],
"internal_macros": actual_macros["internal"],
"enum_consts": enum_consts,
"identifiers": identifiers,
"symbols": symbols,
@ -741,7 +750,8 @@ class NameChecker():
problems += self.check_symbols_declared_in_header()
pattern_checks = [
("macros", MACRO_PATTERN),
("public_macros", PUBLIC_MACRO_PATTERN),
("internal_macros", INTERNAL_MACRO_PATTERN),
("enum_consts", CONSTANTS_PATTERN),
("identifiers", IDENTIFIER_PATTERN)
]
@ -813,7 +823,7 @@ class NameChecker():
def check_for_typos(self):
"""
Perform a check that all words in the soure code beginning with MBED are
Perform a check that all words in the source code beginning with MBED are
either defined as macros, or as enum constants.
Assumes parse_names_in_source() was called before this.
@ -825,7 +835,10 @@ class NameChecker():
all_caps_names = {
match.name
for match
in self.parse_result["macros"] + self.parse_result["enum_consts"]}
in self.parse_result["public_macros"] +
self.parse_result["internal_macros"] +
self.parse_result["enum_consts"]
}
typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$|"
r"MBEDTLS_TEST_LIBTESTDRIVER*")

View File

@ -20,18 +20,24 @@
# Purpose
#
# The purpose of this test script is to validate that the library works
# with any combination of elliptic curves. To this effect, build the library
# and run the test suite with each tested combination of elliptic curves.
# when only a single curve is enabled. In particular, this validates that
# curve-specific code is guarded by the proper preprocessor conditionals,
# both in the library and in tests.
#
# Testing all 2^n combinations would be too much, so we only test 2*n:
# Since this script only tests builds with a single curve, it can't detect
# bugs that are only triggered when multiple curves are present. We do
# also test in many configurations where all curves are enabled, as well
# as a few configurations in configs/*.h with a restricted subset of curves.
#
# 1. Test with a single curve, for each curve. This validates that the
# library works with any curve, and in particular that curve-specific
# code is guarded by the proper preprocessor conditionals.
# 2. Test with all curves except one, for each curve. This validates that
# the test cases have correct dependencies. Testing with a single curve
# doesn't validate this for tests that require more than one curve.
# Here are some known test gaps that could be addressed by testing all
# 2^n combinations of support for n curves, which is impractical:
# * There could be product bugs when curves A and B are enabled but not C.
# For example, a MAX_SIZE calculation that forgets B, where
# size(A) < size(B) < size(C).
# * For test cases that require three or more curves, validate that they're
# not missing dependencies. This is extremely rare. (For test cases that
# require curves A and B but are missing a dependency on B, this is
# detected in the A-only build.)
# Usage: tests/scripts/curves.pl
#
# This script should be executed from the root of the project directory.
@ -115,31 +121,6 @@ for my $curve (@curves) {
and abort "Failed to disable $curve\n";
}
system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
# Test with $curve disabled but the others enabled, for each $curve.
for my $curve (@curves) {
system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
system( "make clean" ) and die;
# depends on a specific curve. Also, ignore error if it wasn't enabled
system( "scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED" );
print "\n******************************************\n";
print "* Testing without curve: $curve\n";
print "******************************************\n";
$ENV{MBEDTLS_TEST_CONFIGURATION} = "-$curve";
system( "scripts/config.py unset $curve" )
and abort "Failed to disable $curve\n";
system( "CFLAGS='-Werror -Wall -Wextra' make" )
and abort "Failed to build: all but $curve\n";
system( "make test" )
and abort "Failed test suite: all but $curve\n";
}
system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
system( "make clean" ) and die;
exit 0;

View File

@ -46,12 +46,12 @@ my $config_h = 'include/mbedtls/mbedtls_config.h';
# as many SSL options depend on specific hashes,
# and SSL is not in the test suites anyways,
# disable it to avoid dependcies issues
# disable it to avoid dependency issues
my $ssl_sed_cmd = 's/^#define \(MBEDTLS_SSL.*\)/\1/p';
my @ssl = split( /\s+/, `sed -n -e '$ssl_sed_cmd' $config_h` );
# Each element of this array holds list of configuration options that
# should be tested together. Certain options depend on eachother and
# should be tested together. Certain options depend on each other and
# separating them would generate invalid configurations.
my @hash_configs = (
['unset MBEDTLS_MD5_C'],

View File

@ -0,0 +1,238 @@
#!/usr/bin/env python3
"""Generate test data for bignum functions.
With no arguments, generate all test data. With non-option arguments,
generate only the specified files.
Class structure:
Child classes of test_generation.BaseTarget (file targets) represent an output
file. These indicate where test cases will be written to, for all subclasses of
this target. Multiple file targets should not reuse a `target_basename`.
Each subclass derived from a file target can either be:
- A concrete class, representing a test function, which generates test cases.
- An abstract class containing shared methods and attributes, not associated
with a test function. An example is BignumOperation, which provides
common features used for bignum binary operations.
Both concrete and abstract subclasses can be derived from, to implement
additional test cases (see BignumCmp and BignumCmpAbs for examples of deriving
from abstract and concrete classes).
Adding test case generation for a function:
A subclass representing the test function should be added, deriving from a
file target such as BignumTarget. This test class must set/implement the
following:
- test_function: the function name from the associated .function file.
- test_name: a descriptive name or brief summary to refer to the test
function.
- arguments(): a method to generate the list of arguments required for the
test_function.
- generate_function_test(): a method to generate TestCases for the function.
This should create instances of the class with required input data, and
call `.create_test_case()` to yield the TestCase.
Additional details and other attributes/methods are given in the documentation
of BaseTarget in test_generation.py.
"""
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
import sys
import typing
from abc import ABCMeta, abstractmethod
from typing import Iterator, List, Tuple, TypeVar
import scripts_path # pylint: disable=unused-import
from mbedtls_dev import test_case
from mbedtls_dev import test_generation
T = TypeVar('T') #pylint: disable=invalid-name
def hex_to_int(val: str) -> int:
return int(val, 16) if val else 0
def quote_str(val) -> str:
return "\"{}\"".format(val)
def combination_pairs(values: List[T]) -> List[Tuple[T, T]]:
"""Return all pair combinations from input values.
The return value is cast, as older versions of mypy are unable to derive
the specific type returned by itertools.combinations_with_replacement.
"""
return typing.cast(
List[Tuple[T, T]],
list(itertools.combinations_with_replacement(values, 2))
)
class BignumTarget(test_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
"""Target for bignum (mpi) test case generation."""
target_basename = 'test_suite_mpi.generated'
class BignumOperation(BignumTarget, metaclass=ABCMeta):
"""Common features for bignum binary operations.
This adds functionality common in binary operation tests. This includes
generation of case descriptions, using descriptions of values and symbols
to represent the operation or result.
Attributes:
symbol: Symbol used for the operation in case description.
input_values: List of values to use as test case inputs. These are
combined to produce pairs of values.
input_cases: List of tuples containing pairs of test case inputs. This
can be used to implement specific pairs of inputs.
"""
symbol = ""
input_values = [
"", "0", "7b", "-7b",
"0000000000000000123", "-0000000000000000123",
"1230000000000000000", "-1230000000000000000"
] # type: List[str]
input_cases = [] # type: List[Tuple[str, str]]
def __init__(self, val_a: str, val_b: str) -> None:
self.arg_a = val_a
self.arg_b = val_b
self.int_a = hex_to_int(val_a)
self.int_b = hex_to_int(val_b)
def arguments(self) -> List[str]:
return [quote_str(self.arg_a), quote_str(self.arg_b), self.result()]
def description(self) -> str:
"""Generate a description for the test case.
If not set, case_description uses the form A `symbol` B, where symbol
is used to represent the operation. Descriptions of each value are
generated to provide some context to the test case.
"""
if not self.case_description:
self.case_description = "{} {} {}".format(
self.value_description(self.arg_a),
self.symbol,
self.value_description(self.arg_b)
)
return super().description()
@abstractmethod
def result(self) -> str:
"""Get the result of the operation.
This could be calculated during initialization and stored as `_result`
and then returned, or calculated when the method is called.
"""
raise NotImplementedError
@staticmethod
def value_description(val) -> str:
"""Generate a description of the argument val.
This produces a simple description of the value, which is used in test
case naming to add context.
"""
if val == "":
return "0 (null)"
if val == "0":
return "0 (1 limb)"
if val[0] == "-":
tmp = "negative"
val = val[1:]
else:
tmp = "positive"
if val[0] == "0":
tmp += " with leading zero limb"
elif len(val) > 10:
tmp = "large " + tmp
return tmp
@classmethod
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
"""Generator to yield pairs of inputs.
Combinations are first generated from all input values, and then
specific cases provided.
"""
yield from combination_pairs(cls.input_values)
yield from cls.input_cases
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
cur_op = cls(a_value, b_value)
yield cur_op.create_test_case()
class BignumCmp(BignumOperation):
"""Test cases for bignum value comparison."""
count = 0
test_function = "mbedtls_mpi_cmp_mpi"
test_name = "MPI compare"
input_cases = [
("-2", "-3"),
("-2", "-2"),
("2b4", "2b5"),
("2b5", "2b6")
]
def __init__(self, val_a, val_b) -> None:
super().__init__(val_a, val_b)
self._result = int(self.int_a > self.int_b) - int(self.int_a < self.int_b)
self.symbol = ["<", "==", ">"][self._result + 1]
def result(self) -> str:
return str(self._result)
class BignumCmpAbs(BignumCmp):
"""Test cases for absolute bignum value comparison."""
count = 0
test_function = "mbedtls_mpi_cmp_abs"
test_name = "MPI compare (abs)"
def __init__(self, val_a, val_b) -> None:
super().__init__(val_a.strip("-"), val_b.strip("-"))
class BignumAdd(BignumOperation):
"""Test cases for bignum value addition."""
count = 0
symbol = "+"
test_function = "mbedtls_mpi_add_mpi"
test_name = "MPI add"
input_cases = combination_pairs(
[
"1c67967269c6", "9cde3",
"-1c67967269c6", "-9cde3",
]
)
def result(self) -> str:
return quote_str("{:x}".format(self.int_a + self.int_b))
if __name__ == '__main__':
# Use the section of the docstring relevant to the CLI as description
test_generation.main(sys.argv[1:], "\n".join(__doc__.splitlines()[:4]))

View File

@ -20,21 +20,17 @@ generate only the specified files.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
import posixpath
import enum
import re
import sys
from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional, TypeVar
from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional
import scripts_path # pylint: disable=unused-import
from mbedtls_dev import build_tree
from mbedtls_dev import crypto_knowledge
from mbedtls_dev import macro_collector
from mbedtls_dev import psa_storage
from mbedtls_dev import test_case
T = TypeVar('T') #pylint: disable=invalid-name
from mbedtls_dev import test_generation
def psa_want_symbol(name: str) -> str:
@ -144,7 +140,7 @@ def test_case_for_key_type_not_supported(
"""
hack_dependencies_not_implemented(dependencies)
tc = test_case.TestCase()
short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
short_key_type = crypto_knowledge.short_expression(key_type)
adverb = 'not' if dependencies else 'never'
if param_descr:
adverb = param_descr + ' ' + adverb
@ -164,6 +160,7 @@ class NotSupported:
ALWAYS_SUPPORTED = frozenset([
'PSA_KEY_TYPE_DERIVE',
'PSA_KEY_TYPE_RAW_DATA',
'PSA_KEY_TYPE_HMAC'
])
def test_cases_for_key_type_not_supported(
self,
@ -205,7 +202,7 @@ class NotSupported:
continue
# For public key we expect that key generation fails with
# INVALID_ARGUMENT. It is handled by KeyGenerate class.
if not kt.name.endswith('_PUBLIC_KEY'):
if not kt.is_public():
yield test_case_for_key_type_not_supported(
'generate', kt.expression, bits,
finish_family_dependencies(generate_dependencies, bits),
@ -242,7 +239,7 @@ def test_case_for_key_generation(
"""
hack_dependencies_not_implemented(dependencies)
tc = test_case.TestCase()
short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
short_key_type = crypto_knowledge.short_expression(key_type)
tc.set_description('PSA {} {}-bit'
.format(short_key_type, bits))
tc.set_dependencies(dependencies)
@ -305,6 +302,145 @@ class KeyGenerate:
kt = crypto_knowledge.KeyType(constr, [curve_family])
yield from self.test_cases_for_key_type_key_generation(kt)
class OpFail:
"""Generate test cases for operations that must fail."""
#pylint: disable=too-few-public-methods
class Reason(enum.Enum):
NOT_SUPPORTED = 0
INVALID = 1
INCOMPATIBLE = 2
PUBLIC = 3
def __init__(self, info: Information) -> None:
self.constructors = info.constructors
key_type_expressions = self.constructors.generate_expressions(
sorted(self.constructors.key_types)
)
self.key_types = [crypto_knowledge.KeyType(kt_expr)
for kt_expr in key_type_expressions]
def make_test_case(
self,
alg: crypto_knowledge.Algorithm,
category: crypto_knowledge.AlgorithmCategory,
reason: 'Reason',
kt: Optional[crypto_knowledge.KeyType] = None,
not_deps: FrozenSet[str] = frozenset(),
) -> test_case.TestCase:
"""Construct a failure test case for a one-key or keyless operation."""
#pylint: disable=too-many-arguments,too-many-locals
tc = test_case.TestCase()
pretty_alg = alg.short_expression()
if reason == self.Reason.NOT_SUPPORTED:
short_deps = [re.sub(r'PSA_WANT_ALG_', r'', dep)
for dep in not_deps]
pretty_reason = '!' + '&'.join(sorted(short_deps))
else:
pretty_reason = reason.name.lower()
if kt:
key_type = kt.expression
pretty_type = kt.short_expression()
else:
key_type = ''
pretty_type = ''
tc.set_description('PSA {} {}: {}{}'
.format(category.name.lower(),
pretty_alg,
pretty_reason,
' with ' + pretty_type if pretty_type else ''))
dependencies = automatic_dependencies(alg.base_expression, key_type)
for i, dep in enumerate(dependencies):
if dep in not_deps:
dependencies[i] = '!' + dep
tc.set_dependencies(dependencies)
tc.set_function(category.name.lower() + '_fail')
arguments = []
if kt:
key_material = kt.key_material(kt.sizes_to_test()[0])
arguments += [key_type, test_case.hex_string(key_material)]
arguments.append(alg.expression)
if category.is_asymmetric():
arguments.append('1' if reason == self.Reason.PUBLIC else '0')
error = ('NOT_SUPPORTED' if reason == self.Reason.NOT_SUPPORTED else
'INVALID_ARGUMENT')
arguments.append('PSA_ERROR_' + error)
tc.set_arguments(arguments)
return tc
def no_key_test_cases(
self,
alg: crypto_knowledge.Algorithm,
category: crypto_knowledge.AlgorithmCategory,
) -> Iterator[test_case.TestCase]:
"""Generate failure test cases for keyless operations with the specified algorithm."""
if alg.can_do(category):
# Compatible operation, unsupported algorithm
for dep in automatic_dependencies(alg.base_expression):
yield self.make_test_case(alg, category,
self.Reason.NOT_SUPPORTED,
not_deps=frozenset([dep]))
else:
# Incompatible operation, supported algorithm
yield self.make_test_case(alg, category, self.Reason.INVALID)
def one_key_test_cases(
self,
alg: crypto_knowledge.Algorithm,
category: crypto_knowledge.AlgorithmCategory,
) -> Iterator[test_case.TestCase]:
"""Generate failure test cases for one-key operations with the specified algorithm."""
for kt in self.key_types:
key_is_compatible = kt.can_do(alg)
if key_is_compatible and alg.can_do(category):
# Compatible key and operation, unsupported algorithm
for dep in automatic_dependencies(alg.base_expression):
yield self.make_test_case(alg, category,
self.Reason.NOT_SUPPORTED,
kt=kt, not_deps=frozenset([dep]))
# Public key for a private-key operation
if category.is_asymmetric() and kt.is_public():
yield self.make_test_case(alg, category,
self.Reason.PUBLIC,
kt=kt)
elif key_is_compatible:
# Compatible key, incompatible operation, supported algorithm
yield self.make_test_case(alg, category,
self.Reason.INVALID,
kt=kt)
elif alg.can_do(category):
# Incompatible key, compatible operation, supported algorithm
yield self.make_test_case(alg, category,
self.Reason.INCOMPATIBLE,
kt=kt)
else:
# Incompatible key and operation. Don't test cases where
# multiple things are wrong, to keep the number of test
# cases reasonable.
pass
def test_cases_for_algorithm(
self,
alg: crypto_knowledge.Algorithm,
) -> Iterator[test_case.TestCase]:
"""Generate operation failure test cases for the specified algorithm."""
for category in crypto_knowledge.AlgorithmCategory:
if category == crypto_knowledge.AlgorithmCategory.PAKE:
# PAKE operations are not implemented yet
pass
elif category.requires_key():
yield from self.one_key_test_cases(alg, category)
else:
yield from self.no_key_test_cases(alg, category)
def all_test_cases(self) -> Iterator[test_case.TestCase]:
"""Generate all test cases for operations that must fail."""
algorithms = sorted(self.constructors.algorithms)
for expr in self.constructors.generate_expressions(algorithms):
alg = crypto_knowledge.Algorithm(expr)
yield from self.test_cases_for_algorithm(alg)
class StorageKey(psa_storage.Key):
"""Representation of a key for storage format testing."""
@ -316,7 +452,7 @@ class StorageKey(psa_storage.Key):
def __init__(
self,
usage: str,
usage: Iterable[str],
without_implicit_usage: Optional[bool] = False,
**kwargs
) -> None:
@ -325,13 +461,16 @@ class StorageKey(psa_storage.Key):
* `usage` : The usage flags used for the key.
* `without_implicit_usage`: Flag to defide to apply the usage extension
"""
super().__init__(usage=usage, **kwargs)
usage_flags = set(usage)
if not without_implicit_usage:
for flag, implicit in self.IMPLICIT_USAGE_FLAGS.items():
if self.usage.value() & psa_storage.Expr(flag).value() and \
self.usage.value() & psa_storage.Expr(implicit).value() == 0:
self.usage = psa_storage.Expr(self.usage.string + ' | ' + implicit)
for flag in sorted(usage_flags):
if flag in self.IMPLICIT_USAGE_FLAGS:
usage_flags.add(self.IMPLICIT_USAGE_FLAGS[flag])
if usage_flags:
usage_expression = ' | '.join(sorted(usage_flags))
else:
usage_expression = '0'
super().__init__(usage=usage_expression, **kwargs)
class StorageTestData(StorageKey):
"""Representation of test case data for storage format testing."""
@ -339,7 +478,7 @@ class StorageTestData(StorageKey):
def __init__(
self,
description: str,
expected_usage: Optional[str] = None,
expected_usage: Optional[List[str]] = None,
**kwargs
) -> None:
"""Prepare to generate test data
@ -351,7 +490,12 @@ class StorageTestData(StorageKey):
"""
super().__init__(**kwargs)
self.description = description #type: str
self.expected_usage = expected_usage if expected_usage else self.usage.string #type: str
if expected_usage is None:
self.expected_usage = self.usage #type: psa_storage.Expr
elif expected_usage:
self.expected_usage = psa_storage.Expr(' | '.join(expected_usage))
else:
self.expected_usage = psa_storage.Expr(0)
class StorageFormat:
"""Storage format stability test cases."""
@ -370,6 +514,47 @@ class StorageFormat:
self.version = version #type: int
self.forward = forward #type: bool
RSA_OAEP_RE = re.compile(r'PSA_ALG_RSA_OAEP\((.*)\)\Z')
BRAINPOOL_RE = re.compile(r'PSA_KEY_TYPE_\w+\(PSA_ECC_FAMILY_BRAINPOOL_\w+\)\Z')
@classmethod
def exercise_key_with_algorithm(
cls,
key_type: psa_storage.Expr, bits: int,
alg: psa_storage.Expr
) -> bool:
"""Whether to the given key with the given algorithm.
Normally only the type and algorithm matter for compatibility, and
this is handled in crypto_knowledge.KeyType.can_do(). This function
exists to detect exceptional cases. Exceptional cases detected here
are not tested in OpFail and should therefore have manually written
test cases.
"""
# Some test keys have the RAW_DATA type and attributes that don't
# necessarily make sense. We do this to validate numerical
# encodings of the attributes.
# Raw data keys have no useful exercise anyway so there is no
# loss of test coverage.
if key_type.string == 'PSA_KEY_TYPE_RAW_DATA':
return False
# OAEP requires room for two hashes plus wrapping
m = cls.RSA_OAEP_RE.match(alg.string)
if m:
hash_alg = m.group(1)
hash_length = crypto_knowledge.Algorithm.hash_length(hash_alg)
key_length = (bits + 7) // 8
# Leave enough room for at least one byte of plaintext
return key_length > 2 * hash_length + 2
# There's nothing wrong with ECC keys on Brainpool curves,
# but operations with them are very slow. So we only exercise them
# with a single algorithm, not with all possible hashes. We do
# exercise other curves with all algorithms so test coverage is
# perfectly adequate like this.
m = cls.BRAINPOOL_RE.match(key_type.string)
if m and alg.string != 'PSA_ALG_ECDSA_ANY':
return False
return True
def make_test_case(self, key: StorageTestData) -> test_case.TestCase:
"""Construct a storage format test case for the given key.
@ -381,10 +566,10 @@ class StorageFormat:
"""
verb = 'save' if self.forward else 'read'
tc = test_case.TestCase()
tc.set_description('PSA storage {}: {}'.format(verb, key.description))
tc.set_description(verb + ' ' + key.description)
dependencies = automatic_dependencies(
key.lifetime.string, key.type.string,
key.expected_usage, key.alg.string, key.alg2.string,
key.alg.string, key.alg2.string,
)
dependencies = finish_family_dependencies(dependencies, key.bits)
tc.set_dependencies(dependencies)
@ -393,19 +578,15 @@ class StorageFormat:
extra_arguments = []
else:
flags = []
# Some test keys have the RAW_DATA type and attributes that don't
# necessarily make sense. We do this to validate numerical
# encodings of the attributes.
# Raw data keys have no useful exercise anyway so there is no
# loss of test coverage.
if key.type.string != 'PSA_KEY_TYPE_RAW_DATA':
if self.exercise_key_with_algorithm(key.type, key.bits, key.alg):
flags.append('TEST_FLAG_EXERCISE')
if 'READ_ONLY' in key.lifetime.string:
flags.append('TEST_FLAG_READ_ONLY')
extra_arguments = [' | '.join(flags) if flags else '0']
tc.set_arguments([key.lifetime.string,
key.type.string, str(key.bits),
key.expected_usage, key.alg.string, key.alg2.string,
key.expected_usage.string,
key.alg.string, key.alg2.string,
'"' + key.material.hex() + '"',
'"' + key.hex() + '"',
*extra_arguments])
@ -419,12 +600,12 @@ class StorageFormat:
short = lifetime
short = re.sub(r'PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION',
r'', short)
short = re.sub(r'PSA_KEY_[A-Z]+_', r'', short)
short = crypto_knowledge.short_expression(short)
description = 'lifetime: ' + short
key = StorageTestData(version=self.version,
id=1, lifetime=lifetime,
type='PSA_KEY_TYPE_RAW_DATA', bits=8,
usage='PSA_KEY_USAGE_EXPORT', alg=0, alg2=0,
usage=['PSA_KEY_USAGE_EXPORT'], alg=0, alg2=0,
material=b'L',
description=description)
return key
@ -443,99 +624,112 @@ class StorageFormat:
continue
yield self.key_for_lifetime(lifetime)
def keys_for_usage_flags(
def key_for_usage_flags(
self,
usage_flags: List[str],
short: Optional[str] = None,
test_implicit_usage: Optional[bool] = False
) -> Iterator[StorageTestData]:
test_implicit_usage: Optional[bool] = True
) -> StorageTestData:
"""Construct a test key for the given key usage."""
usage = ' | '.join(usage_flags) if usage_flags else '0'
if short is None:
short = re.sub(r'\bPSA_KEY_USAGE_', r'', usage)
extra_desc = ' with implication' if test_implicit_usage else ''
description = 'usage' + extra_desc + ': ' + short
extra_desc = ' without implication' if test_implicit_usage else ''
description = 'usage' + extra_desc + ': '
key1 = StorageTestData(version=self.version,
id=1, lifetime=0x00000001,
type='PSA_KEY_TYPE_RAW_DATA', bits=8,
expected_usage=usage,
usage=usage, alg=0, alg2=0,
expected_usage=usage_flags,
without_implicit_usage=not test_implicit_usage,
usage=usage_flags, alg=0, alg2=0,
material=b'K',
description=description)
yield key1
if test_implicit_usage:
description = 'usage without implication' + ': ' + short
key2 = StorageTestData(version=self.version,
id=1, lifetime=0x00000001,
type='PSA_KEY_TYPE_RAW_DATA', bits=8,
without_implicit_usage=True,
usage=usage, alg=0, alg2=0,
material=b'K',
description=description)
yield key2
if short is None:
usage_expr = key1.expected_usage.string
key1.description += crypto_knowledge.short_expression(usage_expr)
else:
key1.description += short
return key1
def generate_keys_for_usage_flags(self, **kwargs) -> Iterator[StorageTestData]:
"""Generate test keys covering usage flags."""
known_flags = sorted(self.constructors.key_usage_flags)
yield from self.keys_for_usage_flags(['0'], **kwargs)
yield self.key_for_usage_flags(['0'], **kwargs)
for usage_flag in known_flags:
yield from self.keys_for_usage_flags([usage_flag], **kwargs)
yield self.key_for_usage_flags([usage_flag], **kwargs)
for flag1, flag2 in zip(known_flags,
known_flags[1:] + [known_flags[0]]):
yield from self.keys_for_usage_flags([flag1, flag2], **kwargs)
yield self.key_for_usage_flags([flag1, flag2], **kwargs)
def generate_key_for_all_usage_flags(self) -> Iterator[StorageTestData]:
known_flags = sorted(self.constructors.key_usage_flags)
yield from self.keys_for_usage_flags(known_flags, short='all known')
yield self.key_for_usage_flags(known_flags, short='all known')
def all_keys_for_usage_flags(self) -> Iterator[StorageTestData]:
yield from self.generate_keys_for_usage_flags()
yield from self.generate_key_for_all_usage_flags()
def key_for_type_and_alg(
self,
kt: crypto_knowledge.KeyType,
bits: int,
alg: Optional[crypto_knowledge.Algorithm] = None,
) -> StorageTestData:
"""Construct a test key of the given type.
If alg is not None, this key allows it.
"""
usage_flags = ['PSA_KEY_USAGE_EXPORT']
alg1 = 0 #type: psa_storage.Exprable
alg2 = 0
if alg is not None:
alg1 = alg.expression
usage_flags += alg.usage_flags(public=kt.is_public())
key_material = kt.key_material(bits)
description = 'type: {} {}-bit'.format(kt.short_expression(1), bits)
if alg is not None:
description += ', ' + alg.short_expression(1)
key = StorageTestData(version=self.version,
id=1, lifetime=0x00000001,
type=kt.expression, bits=bits,
usage=usage_flags, alg=alg1, alg2=alg2,
material=key_material,
description=description)
return key
def keys_for_type(
self,
key_type: str,
params: Optional[Iterable[str]] = None
all_algorithms: List[crypto_knowledge.Algorithm],
) -> Iterator[StorageTestData]:
"""Generate test keys for the given key type.
For key types that depend on a parameter (e.g. elliptic curve family),
`param` is the parameter to pass to the constructor. Only a single
parameter is supported.
"""
kt = crypto_knowledge.KeyType(key_type, params)
"""Generate test keys for the given key type."""
kt = crypto_knowledge.KeyType(key_type)
for bits in kt.sizes_to_test():
usage_flags = 'PSA_KEY_USAGE_EXPORT'
alg = 0
alg2 = 0
key_material = kt.key_material(bits)
short_expression = re.sub(r'\bPSA_(?:KEY_TYPE|ECC_FAMILY)_',
r'',
kt.expression)
description = 'type: {} {}-bit'.format(short_expression, bits)
key = StorageTestData(version=self.version,
id=1, lifetime=0x00000001,
type=kt.expression, bits=bits,
usage=usage_flags, alg=alg, alg2=alg2,
material=key_material,
description=description)
yield key
# Test a non-exercisable key, as well as exercisable keys for
# each compatible algorithm.
# To do: test reading a key from storage with an incompatible
# or unsupported algorithm.
yield self.key_for_type_and_alg(kt, bits)
compatible_algorithms = [alg for alg in all_algorithms
if kt.can_do(alg)]
for alg in compatible_algorithms:
yield self.key_for_type_and_alg(kt, bits, alg)
def all_keys_for_types(self) -> Iterator[StorageTestData]:
"""Generate test keys covering key types and their representations."""
key_types = sorted(self.constructors.key_types)
all_algorithms = [crypto_knowledge.Algorithm(alg)
for alg in self.constructors.generate_expressions(
sorted(self.constructors.algorithms)
)]
for key_type in self.constructors.generate_expressions(key_types):
yield from self.keys_for_type(key_type)
yield from self.keys_for_type(key_type, all_algorithms)
def keys_for_algorithm(self, alg: str) -> Iterator[StorageTestData]:
"""Generate test keys for the specified algorithm."""
# For now, we don't have information on the compatibility of key
# types and algorithms. So we just test the encoding of algorithms,
# and not that operations can be performed with them.
descr = re.sub(r'PSA_ALG_', r'', alg)
descr = re.sub(r',', r', ', re.sub(r' +', r'', descr))
usage = 'PSA_KEY_USAGE_EXPORT'
"""Generate test keys for the encoding of the specified algorithm."""
# These test cases only validate the encoding of algorithms, not
# whether the key read from storage is suitable for an operation.
# `keys_for_types` generate read tests with an algorithm and a
# compatible key.
descr = crypto_knowledge.short_expression(alg, 1)
usage = ['PSA_KEY_USAGE_EXPORT']
key1 = StorageTestData(version=self.version,
id=1, lifetime=0x00000001,
type='PSA_KEY_TYPE_RAW_DATA', bits=8,
@ -593,8 +787,8 @@ class StorageFormatV0(StorageFormat):
def all_keys_for_usage_flags(self) -> Iterator[StorageTestData]:
"""Generate test keys covering usage flags."""
yield from self.generate_keys_for_usage_flags(test_implicit_usage=True)
yield from self.generate_key_for_all_usage_flags()
yield from super().all_keys_for_usage_flags()
yield from self.generate_keys_for_usage_flags(test_implicit_usage=False)
def keys_for_implicit_usage(
self,
@ -608,17 +802,14 @@ class StorageFormatV0(StorageFormat):
"""
bits = key_type.sizes_to_test()[0]
implicit_usage = StorageKey.IMPLICIT_USAGE_FLAGS[implyer_usage]
usage_flags = 'PSA_KEY_USAGE_EXPORT'
material_usage_flags = usage_flags + ' | ' + implyer_usage
expected_usage_flags = material_usage_flags + ' | ' + implicit_usage
usage_flags = ['PSA_KEY_USAGE_EXPORT']
material_usage_flags = usage_flags + [implyer_usage]
expected_usage_flags = material_usage_flags + [implicit_usage]
alg2 = 0
key_material = key_type.key_material(bits)
usage_expression = re.sub(r'PSA_KEY_USAGE_', r'', implyer_usage)
alg_expression = re.sub(r'PSA_ALG_', r'', alg)
alg_expression = re.sub(r',', r', ', re.sub(r' +', r'', alg_expression))
key_type_expression = re.sub(r'\bPSA_(?:KEY_TYPE|ECC_FAMILY)_',
r'',
key_type.expression)
usage_expression = crypto_knowledge.short_expression(implyer_usage, 1)
alg_expression = crypto_knowledge.short_expression(alg, 1)
key_type_expression = key_type.short_expression(1)
description = 'implied by {}: {} {} {}-bit'.format(
usage_expression, alg_expression, key_type_expression, bits)
key = StorageTestData(version=self.version,
@ -635,7 +826,7 @@ class StorageFormatV0(StorageFormat):
def gather_key_types_for_sign_alg(self) -> Dict[str, List[str]]:
# pylint: disable=too-many-locals
"""Match possible key types for sign algorithms."""
# To create a valid combinaton both the algorithms and key types
# To create a valid combination both the algorithms and key types
# must be filtered. Pair them with keywords created from its names.
incompatible_alg_keyword = frozenset(['RAW', 'ANY', 'PURE'])
incompatible_key_type_keywords = frozenset(['MONTGOMERY'])
@ -659,7 +850,7 @@ class StorageFormatV0(StorageFormat):
if re.match(pattern, keyword):
alg_keywords.remove(keyword)
alg_keywords.add(replace)
# Filter out incompatible algortihms
# Filter out incompatible algorithms
if not alg_keywords.isdisjoint(incompatible_alg_keyword):
continue
@ -667,7 +858,7 @@ class StorageFormatV0(StorageFormat):
# Generate keywords from the of the key type
key_type_keywords = set(key_type.translate(translation_table).split(sep='_')[3:])
# Remove ambigious keywords
# Remove ambiguous keywords
for keyword1, keyword2 in exclusive_keywords.items():
if keyword1 in key_type_keywords:
key_type_keywords.remove(keyword2)
@ -684,7 +875,7 @@ class StorageFormatV0(StorageFormat):
"""Generate test keys for usage flag extensions."""
# Generate a key type and algorithm pair for each extendable usage
# flag to generate a valid key for exercising. The key is generated
# without usage extension to check the extension compatiblity.
# without usage extension to check the extension compatibility.
alg_with_keys = self.gather_key_types_for_sign_alg()
for usage in sorted(StorageKey.IMPLICIT_USAGE_FLAGS, key=str):
@ -692,90 +883,38 @@ class StorageFormatV0(StorageFormat):
for key_type in sorted(alg_with_keys[alg]):
# The key types must be filtered to fit the specific usage flag.
kt = crypto_knowledge.KeyType(key_type)
if kt.is_valid_for_signature(usage):
yield self.keys_for_implicit_usage(usage, alg, kt)
if kt.is_public() and '_SIGN_' in usage:
# Can't sign with a public key
continue
yield self.keys_for_implicit_usage(usage, alg, kt)
def generate_all_keys(self) -> Iterator[StorageTestData]:
yield from super().generate_all_keys()
yield from self.all_keys_for_implicit_usage()
class TestGenerator:
"""Generate test data."""
def __init__(self, options) -> None:
self.test_suite_directory = self.get_option(options, 'directory',
'tests/suites')
self.info = Information()
@staticmethod
def get_option(options, name: str, default: T) -> T:
value = getattr(options, name, None)
return default if value is None else value
def filename_for(self, basename: str) -> str:
"""The location of the data file with the specified base name."""
return posixpath.join(self.test_suite_directory, basename + '.data')
def write_test_data_file(self, basename: str,
test_cases: Iterable[test_case.TestCase]) -> None:
"""Write the test cases to a .data file.
The output file is ``basename + '.data'`` in the test suite directory.
"""
filename = self.filename_for(basename)
test_case.write_data_file(filename, test_cases)
# Note that targets whose name containns 'test_format' have their content
class PSATestGenerator(test_generation.TestGenerator):
"""Test generator subclass including PSA targets and info."""
# Note that targets whose names contain 'test_format' have their content
# validated by `abi_check.py`.
TARGETS = {
targets = {
'test_suite_psa_crypto_generate_key.generated':
lambda info: KeyGenerate(info).test_cases_for_key_generation(),
'test_suite_psa_crypto_not_supported.generated':
lambda info: NotSupported(info).test_cases_for_not_supported(),
'test_suite_psa_crypto_op_fail.generated':
lambda info: OpFail(info).all_test_cases(),
'test_suite_psa_crypto_storage_format.current':
lambda info: StorageFormatForward(info, 0).all_test_cases(),
'test_suite_psa_crypto_storage_format.v0':
lambda info: StorageFormatV0(info).all_test_cases(),
} #type: Dict[str, Callable[[Information], Iterable[test_case.TestCase]]]
def generate_target(self, name: str) -> None:
test_cases = self.TARGETS[name](self.info)
self.write_test_data_file(name, test_cases)
def __init__(self, options):
super().__init__(options)
self.info = Information()
def main(args):
"""Command line entry point."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--list', action='store_true',
help='List available targets and exit')
parser.add_argument('--list-for-cmake', action='store_true',
help='Print \';\'-separated list of available targets and exit')
parser.add_argument('--directory', metavar='DIR',
help='Output directory (default: tests/suites)')
parser.add_argument('targets', nargs='*', metavar='TARGET',
help='Target file to generate (default: all; "-": none)')
options = parser.parse_args(args)
build_tree.chdir_to_root()
generator = TestGenerator(options)
if options.list:
for name in sorted(generator.TARGETS):
print(generator.filename_for(name))
return
# List in a cmake list format (i.e. ';'-separated)
if options.list_for_cmake:
print(';'.join(generator.filename_for(name)
for name in sorted(generator.TARGETS)), end='')
return
if options.targets:
# Allow "-" as a special case so you can run
# ``generate_psa_tests.py - $targets`` and it works uniformly whether
# ``$targets`` is empty or not.
options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target))
for target in options.targets
if target != '-']
else:
options.targets = sorted(generator.TARGETS)
for target in options.targets:
generator.generate_target(target)
def generate_target(self, name: str, *target_args) -> None:
super().generate_target(name, self.info)
if __name__ == '__main__':
main(sys.argv[1:])
test_generation.main(sys.argv[1:], __doc__, PSATestGenerator)

View File

@ -24,11 +24,9 @@ Generate TLSv1.3 Compat test cases
import sys
import os
import abc
import argparse
import itertools
from collections import namedtuple
# pylint: disable=useless-super-delegation
# define certificates configuration entry
Certificate = namedtuple("Certificate", ['cafile', 'certfile', 'keyfile'])
@ -71,18 +69,27 @@ NAMED_GROUP_IANA_VALUE = {
'x448': 0x1e,
}
class TLSProgram(metaclass=abc.ABCMeta):
class TLSProgram:
"""
Base class for generate server/client command.
"""
def __init__(self, ciphersuite, signature_algorithm, named_group, compat_mode=True):
# pylint: disable=too-many-arguments
def __init__(self, ciphersuite=None, signature_algorithm=None, named_group=None,
cert_sig_alg=None, compat_mode=True):
self._ciphers = []
self._sig_algs = []
self._named_groups = []
self.add_ciphersuites(ciphersuite)
self.add_named_groups(named_group)
self.add_signature_algorithms(signature_algorithm)
self._cert_sig_algs = []
if ciphersuite:
self.add_ciphersuites(ciphersuite)
if named_group:
self.add_named_groups(named_group)
if signature_algorithm:
self.add_signature_algorithms(signature_algorithm)
if cert_sig_alg:
self.add_cert_signature_algorithms(cert_sig_alg)
self._compat_mode = compat_mode
# add_ciphersuites should not override by sub class
@ -95,27 +102,42 @@ class TLSProgram(metaclass=abc.ABCMeta):
self._sig_algs.extend(
[sig_alg for sig_alg in signature_algorithms if sig_alg not in self._sig_algs])
# add_signature_algorithms should not override by sub class
# add_named_groups should not override by sub class
def add_named_groups(self, *named_groups):
self._named_groups.extend(
[named_group for named_group in named_groups if named_group not in self._named_groups])
@abc.abstractmethod
# add_cert_signature_algorithms should not override by sub class
def add_cert_signature_algorithms(self, *signature_algorithms):
self._cert_sig_algs.extend(
[sig_alg for sig_alg in signature_algorithms if sig_alg not in self._cert_sig_algs])
# pylint: disable=no-self-use
def pre_checks(self):
return []
@abc.abstractmethod
# pylint: disable=no-self-use
def cmd(self):
pass
if not self._cert_sig_algs:
self._cert_sig_algs = list(CERTIFICATES.keys())
return self.pre_cmd()
@abc.abstractmethod
# pylint: disable=no-self-use
def post_checks(self):
return []
# pylint: disable=no-self-use
def pre_cmd(self):
return ['false']
class OpenSSLServ(TLSProgram):
# pylint: disable=unused-argument,no-self-use
def hrr_post_checks(self, named_group):
return []
class OpenSSLBase(TLSProgram):
"""
Generate test commands for OpenSSL server.
Generate base test commands for OpenSSL.
"""
NAMED_GROUP = {
@ -127,34 +149,66 @@ class OpenSSLServ(TLSProgram):
}
def cmd(self):
ret = ['$O_NEXT_SRV_NO_CERT']
for _, cert, key in map(lambda sig_alg: CERTIFICATES[sig_alg], self._sig_algs):
ret += ['-cert {cert} -key {key}'.format(cert=cert, key=key)]
ret += ['-accept $SRV_PORT']
ciphersuites = ','.join(self._ciphers)
signature_algorithms = ','.join(self._sig_algs)
named_groups = ','.join(
map(lambda named_group: self.NAMED_GROUP[named_group], self._named_groups))
ret += ["-ciphersuites {ciphersuites}".format(ciphersuites=ciphersuites),
"-sigalgs {signature_algorithms}".format(
signature_algorithms=signature_algorithms),
"-groups {named_groups}".format(named_groups=named_groups)]
ret += ['-msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache']
ret = super().cmd()
if self._ciphers:
ciphersuites = ':'.join(self._ciphers)
ret += ["-ciphersuites {ciphersuites}".format(ciphersuites=ciphersuites)]
if self._sig_algs:
signature_algorithms = set(self._sig_algs + self._cert_sig_algs)
signature_algorithms = ':'.join(signature_algorithms)
ret += ["-sigalgs {signature_algorithms}".format(
signature_algorithms=signature_algorithms)]
if self._named_groups:
named_groups = ':'.join(
map(lambda named_group: self.NAMED_GROUP[named_group], self._named_groups))
ret += ["-groups {named_groups}".format(named_groups=named_groups)]
ret += ['-msg -tls1_3']
if not self._compat_mode:
ret += ['-no_middlebox']
return ' '.join(ret)
return ret
def pre_checks(self):
return ["requires_openssl_tls1_3"]
class OpenSSLServ(OpenSSLBase):
"""
Generate test commands for OpenSSL server.
"""
def cmd(self):
ret = super().cmd()
ret += ['-num_tickets 0 -no_resume_ephemeral -no_cache']
return ret
def post_checks(self):
return ['-c "HTTP/1.0 200 ok"']
def pre_cmd(self):
ret = ['$O_NEXT_SRV_NO_CERT']
for _, cert, key in map(lambda sig_alg: CERTIFICATES[sig_alg], self._cert_sig_algs):
ret += ['-cert {cert} -key {key}'.format(cert=cert, key=key)]
return ret
class GnuTLSServ(TLSProgram):
class OpenSSLCli(OpenSSLBase):
"""
Generate test commands for GnuTLS server.
Generate test commands for OpenSSL client.
"""
def pre_cmd(self):
return ['$O_NEXT_CLI_NO_CERT',
'-CAfile {cafile}'.format(cafile=CERTIFICATES[self._cert_sig_algs[0]].cafile)]
class GnuTLSBase(TLSProgram):
"""
Generate base test commands for GnuTLS.
"""
CIPHER_SUITE = {
@ -198,16 +252,8 @@ class GnuTLSServ(TLSProgram):
"requires_gnutls_next_no_ticket",
"requires_gnutls_next_disable_tls13_compat", ]
def post_checks(self):
return ['-c "HTTP/1.0 200 OK"']
def cmd(self):
ret = ['$G_NEXT_SRV_NO_CERT', '--http',
'--disable-client-cert', '--debug=4']
for _, cert, key in map(lambda sig_alg: CERTIFICATES[sig_alg], self._sig_algs):
ret += ['--x509certfile {cert} --x509keyfile {key}'.format(
cert=cert, key=key)]
ret = super().cmd()
priority_string_list = []
@ -216,28 +262,70 @@ class GnuTLSServ(TLSProgram):
for i in map_table[item]:
if i not in priority_string_list:
yield i
priority_string_list.extend(update_priority_string_list(
self._sig_algs, self.SIGNATURE_ALGORITHM))
priority_string_list.extend(
update_priority_string_list(self._ciphers, self.CIPHER_SUITE))
priority_string_list.extend(update_priority_string_list(
self._named_groups, self.NAMED_GROUP))
priority_string_list = ['NONE'] + sorted(priority_string_list) + ['VERS-TLS1.3']
if self._ciphers:
priority_string_list.extend(update_priority_string_list(
self._ciphers, self.CIPHER_SUITE))
else:
priority_string_list.extend(['CIPHER-ALL', 'MAC-ALL'])
if self._sig_algs:
signature_algorithms = set(self._sig_algs + self._cert_sig_algs)
priority_string_list.extend(update_priority_string_list(
signature_algorithms, self.SIGNATURE_ALGORITHM))
else:
priority_string_list.append('SIGN-ALL')
if self._named_groups:
priority_string_list.extend(update_priority_string_list(
self._named_groups, self.NAMED_GROUP))
else:
priority_string_list.append('GROUP-ALL')
priority_string_list = ['NONE'] + \
priority_string_list + ['VERS-TLS1.3']
priority_string = ':+'.join(priority_string_list)
priority_string += ':%NO_TICKETS'
if not self._compat_mode:
priority_string += [':%DISABLE_TLS13_COMPAT_MODE']
ret += ['--priority={priority_string}'.format(
priority_string=priority_string)]
ret = ' '.join(ret)
return ret
class MbedTLSCli(TLSProgram):
class GnuTLSServ(GnuTLSBase):
"""
Generate test commands for mbedTLS client.
Generate test commands for GnuTLS server.
"""
def pre_cmd(self):
ret = ['$G_NEXT_SRV_NO_CERT', '--http', '--disable-client-cert', '--debug=4']
for _, cert, key in map(lambda sig_alg: CERTIFICATES[sig_alg], self._cert_sig_algs):
ret += ['--x509certfile {cert} --x509keyfile {key}'.format(
cert=cert, key=key)]
return ret
def post_checks(self):
return ['-c "HTTP/1.0 200 OK"']
class GnuTLSCli(GnuTLSBase):
"""
Generate test commands for GnuTLS client.
"""
def pre_cmd(self):
return ['$G_NEXT_CLI_NO_CERT', '--debug=4', '--single-key-share',
'--x509cafile {cafile}'.format(cafile=CERTIFICATES[self._cert_sig_algs[0]].cafile)]
class MbedTLSBase(TLSProgram):
"""
Generate base test commands for mbedTLS.
"""
CIPHER_SUITE = {
@ -248,79 +336,181 @@ class MbedTLSCli(TLSProgram):
'TLS_AES_128_CCM_8_SHA256': 'TLS1-3-AES-128-CCM-8-SHA256'}
def cmd(self):
ret = ['$P_CLI']
ret += ['server_addr=127.0.0.1', 'server_port=$SRV_PORT',
'debug_level=4', 'force_version=tls13']
ret += ['ca_file={cafile}'.format(
cafile=CERTIFICATES[self._sig_algs[0]].cafile)]
ret = super().cmd()
ret += ['debug_level=4']
if self._ciphers:
ciphers = ','.join(
map(lambda cipher: self.CIPHER_SUITE[cipher], self._ciphers))
ret += ["force_ciphersuite={ciphers}".format(ciphers=ciphers)]
if self._sig_algs:
if self._sig_algs + self._cert_sig_algs:
ret += ['sig_algs={sig_algs}'.format(
sig_algs=','.join(self._sig_algs))]
for sig_alg in self._sig_algs:
if sig_alg in ('ecdsa_secp256r1_sha256',
'ecdsa_secp384r1_sha384',
'ecdsa_secp521r1_sha512'):
self.add_named_groups(sig_alg.split('_')[1])
sig_algs=','.join(set(self._sig_algs + self._cert_sig_algs)))]
if self._named_groups:
named_groups = ','.join(self._named_groups)
ret += ["curves={named_groups}".format(named_groups=named_groups)]
ret = ' '.join(ret)
ret += ['force_version=tls13']
return ret
def pre_checks(self):
ret = ['requires_config_enabled MBEDTLS_DEBUG_C',
'requires_config_enabled MBEDTLS_SSL_CLI_C',
'requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3']
if self._compat_mode:
ret += ['requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE']
if 'rsa_pss_rsae_sha256' in self._sig_algs:
if 'rsa_pss_rsae_sha256' in self._sig_algs + self._cert_sig_algs:
ret.append(
'requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT')
return ret
class MbedTLSServ(MbedTLSBase):
"""
Generate test commands for mbedTLS server.
"""
def cmd(self):
ret = super().cmd()
ret += ['tls13_kex_modes=ephemeral cookies=0 tickets=0']
return ret
def pre_checks(self):
return ['requires_config_enabled MBEDTLS_SSL_SRV_C'] + super().pre_checks()
def post_checks(self):
check_strings = ["ECDH curve: {group}".format(group=self._named_groups[0]),
"server hello, chosen ciphersuite: ( {:04x} ) - {}".format(
CIPHER_SUITE_IANA_VALUE[self._ciphers[0]],
self.CIPHER_SUITE[self._ciphers[0]]),
"Certificate Verify: Signature algorithm ( {:04x} )".format(
SIG_ALG_IANA_VALUE[self._sig_algs[0]]),
"Verifying peer X.509 certificate... ok", ]
check_strings = ["Protocol is TLSv1.3"]
if self._ciphers:
check_strings.append(
"server hello, chosen ciphersuite: {} ( id={:04d} )".format(
self.CIPHER_SUITE[self._ciphers[0]],
CIPHER_SUITE_IANA_VALUE[self._ciphers[0]]))
if self._sig_algs:
check_strings.append(
"received signature algorithm: 0x{:x}".format(
SIG_ALG_IANA_VALUE[self._sig_algs[0]]))
for named_group in self._named_groups:
check_strings += ['got named group: {named_group}({iana_value:04x})'.format(
named_group=named_group,
iana_value=NAMED_GROUP_IANA_VALUE[named_group])]
check_strings.append("Verifying peer X.509 certificate... ok")
return ['-s "{}"'.format(i) for i in check_strings]
def pre_cmd(self):
ret = ['$P_SRV']
for _, cert, key in map(lambda sig_alg: CERTIFICATES[sig_alg], self._cert_sig_algs):
ret += ['crt_file={cert} key_file={key}'.format(cert=cert, key=key)]
return ret
def hrr_post_checks(self, named_group):
return ['-s "HRR selected_group: {:s}"'.format(named_group)]
class MbedTLSCli(MbedTLSBase):
"""
Generate test commands for mbedTLS client.
"""
def pre_cmd(self):
return ['$P_CLI',
'ca_file={cafile}'.format(cafile=CERTIFICATES[self._cert_sig_algs[0]].cafile)]
def pre_checks(self):
return ['requires_config_enabled MBEDTLS_SSL_CLI_C'] + super().pre_checks()
def hrr_post_checks(self, named_group):
ret = ['-c "received HelloRetryRequest message"']
ret += ['-c "selected_group ( {:d} )"'.format(NAMED_GROUP_IANA_VALUE[named_group])]
return ret
def post_checks(self):
check_strings = ["Protocol is TLSv1.3"]
if self._ciphers:
check_strings.append(
"server hello, chosen ciphersuite: ( {:04x} ) - {}".format(
CIPHER_SUITE_IANA_VALUE[self._ciphers[0]],
self.CIPHER_SUITE[self._ciphers[0]]))
if self._sig_algs:
check_strings.append(
"Certificate Verify: Signature algorithm ( {:04x} )".format(
SIG_ALG_IANA_VALUE[self._sig_algs[0]]))
for named_group in self._named_groups:
check_strings += ['NamedGroup: {named_group} ( {iana_value:x} )'.format(
named_group=named_group,
iana_value=NAMED_GROUP_IANA_VALUE[named_group])]
check_strings.append("Verifying peer X.509 certificate... ok")
return ['-c "{}"'.format(i) for i in check_strings]
SERVER_CLASSES = {'OpenSSL': OpenSSLServ, 'GnuTLS': GnuTLSServ}
CLIENT_CLASSES = {'mbedTLS': MbedTLSCli}
SERVER_CLASSES = {'OpenSSL': OpenSSLServ, 'GnuTLS': GnuTLSServ, 'mbedTLS': MbedTLSServ}
CLIENT_CLASSES = {'OpenSSL': OpenSSLCli, 'GnuTLS': GnuTLSCli, 'mbedTLS': MbedTLSCli}
def generate_compat_test(server=None, client=None, cipher=None, sig_alg=None, named_group=None):
def generate_compat_test(client=None, server=None, cipher=None, named_group=None, sig_alg=None):
"""
Generate test case with `ssl-opt.sh` format.
"""
name = 'TLS 1.3 {client[0]}->{server[0]}: {cipher},{named_group},{sig_alg}'.format(
client=client, server=server, cipher=cipher, sig_alg=sig_alg, named_group=named_group)
server_object = SERVER_CLASSES[server](cipher, sig_alg, named_group)
client_object = CLIENT_CLASSES[client](cipher, sig_alg, named_group)
client=client, server=server, cipher=cipher[4:], sig_alg=sig_alg, named_group=named_group)
cmd = ['run_test "{}"'.format(name), '"{}"'.format(
server_object.cmd()), '"{}"'.format(client_object.cmd()), '0']
server_object = SERVER_CLASSES[server](ciphersuite=cipher,
named_group=named_group,
signature_algorithm=sig_alg,
cert_sig_alg=sig_alg)
client_object = CLIENT_CLASSES[client](ciphersuite=cipher,
named_group=named_group,
signature_algorithm=sig_alg,
cert_sig_alg=sig_alg)
cmd = ['run_test "{}"'.format(name),
'"{}"'.format(' '.join(server_object.cmd())),
'"{}"'.format(' '.join(client_object.cmd())),
'0']
cmd += server_object.post_checks()
cmd += client_object.post_checks()
cmd += ['-C "received HelloRetryRequest message"']
prefix = ' \\\n' + (' '*9)
cmd = prefix.join(cmd)
return '\n'.join(server_object.pre_checks() + client_object.pre_checks() + [cmd])
def generate_hrr_compat_test(client=None, server=None,
client_named_group=None, server_named_group=None,
cert_sig_alg=None):
"""
Generate Hello Retry Request test case with `ssl-opt.sh` format.
"""
name = 'TLS 1.3 {client[0]}->{server[0]}: HRR {c_named_group} -> {s_named_group}'.format(
client=client, server=server, c_named_group=client_named_group,
s_named_group=server_named_group)
server_object = SERVER_CLASSES[server](named_group=server_named_group,
cert_sig_alg=cert_sig_alg)
client_object = CLIENT_CLASSES[client](named_group=client_named_group,
cert_sig_alg=cert_sig_alg)
client_object.add_named_groups(server_named_group)
cmd = ['run_test "{}"'.format(name),
'"{}"'.format(' '.join(server_object.cmd())),
'"{}"'.format(' '.join(client_object.cmd())),
'0']
cmd += server_object.post_checks()
cmd += client_object.post_checks()
cmd += server_object.hrr_post_checks(server_named_group)
cmd += client_object.hrr_post_checks(server_named_group)
prefix = ' \\\n' + (' '*9)
cmd = prefix.join(cmd)
return '\n'.join(server_object.pre_checks() +
client_object.pre_checks() +
[cmd])
SSL_OUTPUT_HEADER = '''#!/bin/sh
# {filename}
@ -343,14 +533,13 @@ SSL_OUTPUT_HEADER = '''#!/bin/sh
# Purpose
#
# List TLS1.3 compat test cases. They are generated by
# `generate_tls13_compat_tests.py -a`.
# `{cmd}`.
#
# PLEASE DO NOT EDIT THIS FILE. IF NEEDED, PLEASE MODIFY `generate_tls13_compat_tests.py`
# AND REGENERATE THIS FILE.
#
'''
def main():
"""
Main function of this program
@ -397,22 +586,42 @@ def main():
args = parser.parse_args()
def get_all_test_cases():
for cipher, sig_alg, named_group, server, client in \
itertools.product(CIPHER_SUITE_IANA_VALUE.keys(), SIG_ALG_IANA_VALUE.keys(),
NAMED_GROUP_IANA_VALUE.keys(), SERVER_CLASSES.keys(),
CLIENT_CLASSES.keys()):
yield generate_compat_test(cipher=cipher, sig_alg=sig_alg, named_group=named_group,
server=server, client=client)
# Generate normal compat test cases
for client, server, cipher, named_group, sig_alg in \
itertools.product(CLIENT_CLASSES.keys(),
SERVER_CLASSES.keys(),
CIPHER_SUITE_IANA_VALUE.keys(),
NAMED_GROUP_IANA_VALUE.keys(),
SIG_ALG_IANA_VALUE.keys()):
if server == 'mbedTLS' or client == 'mbedTLS':
yield generate_compat_test(client=client, server=server,
cipher=cipher, named_group=named_group,
sig_alg=sig_alg)
# Generate Hello Retry Request compat test cases
for client, server, client_named_group, server_named_group in \
itertools.product(CLIENT_CLASSES.keys(),
SERVER_CLASSES.keys(),
NAMED_GROUP_IANA_VALUE.keys(),
NAMED_GROUP_IANA_VALUE.keys()):
if (client == 'mbedTLS' or server == 'mbedTLS') and \
client_named_group != server_named_group:
yield generate_hrr_compat_test(client=client, server=server,
client_named_group=client_named_group,
server_named_group=server_named_group,
cert_sig_alg="ecdsa_secp256r1_sha256")
if args.generate_all_tls13_compat_tests:
if args.output:
with open(args.output, 'w', encoding="utf-8") as f:
f.write(SSL_OUTPUT_HEADER.format(
filename=os.path.basename(args.output)))
filename=os.path.basename(args.output), cmd=' '.join(sys.argv)))
f.write('\n\n'.join(get_all_test_cases()))
f.write('\n')
else:
print('\n'.join(get_all_test_cases()))
print('\n\n'.join(get_all_test_cases()))
return 0
if args.list_ciphers or args.list_sig_algs or args.list_named_groups \

View File

@ -4,7 +4,7 @@
# (Multiple recursion where a() calls b() which calls a() not covered.)
#
# When the recursion depth might depend on data controlled by the attacker in
# an unbounded way, those functions should use interation instead.
# an unbounded way, those functions should use iteration instead.
#
# Typical usage: scripts/recursion.pl library/*.c
#

View File

@ -32,11 +32,19 @@ my %configs = (
'compat' => '-m tls12 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
'test_again_with_use_psa' => 1
},
'config-ccm-psk-dtls1_2.h' => {
'compat' => '-m dtls12 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
'opt' => ' ',
'opt_needs_debug' => 1,
'test_again_with_use_psa' => 1
},
'config-no-entropy.h' => {
},
'config-suite-b.h' => {
'compat' => "-m tls12 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
'test_again_with_use_psa' => 1,
'opt' => ' ',
'opt_needs_debug' => 1,
},
'config-symmetric-only.h' => {
'test_again_with_use_psa' => 0, # Uses PSA by default, no need to test it twice
@ -49,17 +57,14 @@ my %configs = (
# If no config-name is provided, use all known configs.
# Otherwise, use the provided names only.
my @configs_to_test = sort keys %configs;
if ($#ARGV >= 0) {
my %configs_ori = ( %configs );
%configs = ();
foreach my $conf_name (@ARGV) {
if( ! exists $configs_ori{$conf_name} ) {
foreach my $conf_name ( @ARGV ) {
if( ! exists $configs{$conf_name} ) {
die "Unknown configuration: $conf_name\n";
} else {
$configs{$conf_name} = $configs_ori{$conf_name};
}
}
@configs_to_test = @ARGV;
}
-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
@ -84,25 +89,27 @@ if (!-e "tests/seedfile" || -s "tests/seedfile" < 64) {
}
sub perform_test {
my $conf = $_[0];
my $conf_file = $_[0];
my $data = $_[1];
my $test_with_psa = $_[2];
my $conf_name = $conf_file;
if ( $test_with_psa )
{
$conf_name .= "+PSA";
}
system( "cp $config_h.bak $config_h" ) and die;
system( "make clean" ) and die;
print "\n******************************************\n";
print "* Testing configuration: $conf\n";
if ( $test_with_psa )
{
print "* ENABLING MBEDTLS_PSA_CRYPTO_C and MBEDTLS_USE_PSA_CRYPTO \n";
}
print "* Testing configuration: $conf_name\n";
print "******************************************\n";
$ENV{MBEDTLS_TEST_CONFIGURATION} = $conf;
$ENV{MBEDTLS_TEST_CONFIGURATION} = $conf_name;
system( "cp configs/$conf $config_h" )
and abort "Failed to activate $conf\n";
system( "cp configs/$conf_file $config_h" )
and abort "Failed to activate $conf_file\n";
if ( $test_with_psa )
{
@ -110,41 +117,52 @@ sub perform_test {
system( "scripts/config.py set MBEDTLS_USE_PSA_CRYPTO" );
}
system( "CFLAGS='-Os -Werror -Wall -Wextra' make" ) and abort "Failed to build: $conf\n";
system( "make test" ) and abort "Failed test suite: $conf\n";
system( "CFLAGS='-Os -Werror -Wall -Wextra' make" ) and abort "Failed to build: $conf_name\n";
system( "make test" ) and abort "Failed test suite: $conf_name\n";
my $compat = $data->{'compat'};
if( $compat )
{
print "\nrunning compat.sh $compat\n";
print "\nrunning compat.sh $compat ($conf_name)\n";
system( "tests/compat.sh $compat" )
and abort "Failed compat.sh: $conf\n";
and abort "Failed compat.sh: $conf_name\n";
}
else
{
print "\nskipping compat.sh\n";
print "\nskipping compat.sh ($conf_name)\n";
}
my $opt = $data->{'opt'};
if( $opt )
{
print "\nrunning ssl-opt.sh $opt\n";
if( $data->{'opt_needs_debug'} )
{
print "\nrebuilding with debug traces for ssl-opt ($conf_name)\n";
$conf_name .= '+DEBUG';
$ENV{MBEDTLS_TEST_CONFIGURATION} = $conf_name;
system( "make clean" );
system( "scripts/config.py set MBEDTLS_DEBUG_C" );
system( "scripts/config.py set MBEDTLS_ERROR_C" );
system( "CFLAGS='-Os -Werror -Wall -Wextra' make" ) and abort "Failed to build: $conf_name\n";
}
print "\nrunning ssl-opt.sh $opt ($conf_name)\n";
system( "tests/ssl-opt.sh $opt" )
and abort "Failed ssl-opt.sh: $conf\n";
and abort "Failed ssl-opt.sh: $conf_name\n";
}
else
{
print "\nskipping ssl-opt.sh\n";
print "\nskipping ssl-opt.sh ($conf_name)\n";
}
}
while( my ($conf, $data) = each %configs ) {
my $test_with_psa = $data->{'test_again_with_use_psa'};
foreach my $conf ( @configs_to_test ) {
my $test_with_psa = $configs{$conf}{'test_again_with_use_psa'};
if ( $test_with_psa )
{
perform_test( $conf, $data, $test_with_psa );
perform_test( $conf, $configs{$conf}, $test_with_psa );
}
perform_test( $conf, $data, 0 );
perform_test( $conf, $configs{$conf}, 0 );
}
system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Run the PSA Cryto API compliance test suite.
"""Run the PSA Crypto API compliance test suite.
Clone the repo and check out the commit specified by PSA_ARCH_TEST_REPO and PSA_ARCH_TEST_REF,
then complie and run the test suite. The clone is stored at <Mbed TLS root>/psa-arch-tests.
Known defects in either the test suite or mbedtls - identified by their test number - are ignored,
@ -47,7 +47,7 @@ EXPECTED_FAILURES = {
#
# Web URL: https://github.com/bensze01/psa-arch-tests/tree/fixes-for-mbedtls-3
PSA_ARCH_TESTS_REPO = 'https://github.com/bensze01/psa-arch-tests.git'
PSA_ARCH_TESTS_REF = 'fix-pr-5139-3'
PSA_ARCH_TESTS_REF = 'fix-pr-5736'
#pylint: disable=too-many-branches,too-many-statements
def main():

View File

@ -77,6 +77,22 @@ def normalize(expr: str) -> str:
"""
return re.sub(NORMALIZE_STRIP_RE, '', expr)
ALG_TRUNCATED_TO_SELF_RE = \
re.compile(r'PSA_ALG_AEAD_WITH_SHORTENED_TAG\('
r'PSA_ALG_(?:CCM|CHACHA20_POLY1305|GCM)'
r', *16\)\Z')
def is_simplifiable(expr: str) -> bool:
"""Determine whether an expression is simplifiable.
Simplifiable expressions can't be output in their input form, since
the output will be the simple form. Therefore they must be excluded
from testing.
"""
if ALG_TRUNCATED_TO_SELF_RE.match(expr):
return True
return False
def collect_values(inputs: InputsForTest,
type_word: str,
include_path: Optional[str] = None,
@ -87,7 +103,9 @@ def collect_values(inputs: InputsForTest,
value is a string representation of its integer value.
"""
names = inputs.get_names(type_word)
expressions = sorted(inputs.generate_expressions(names))
expressions = sorted(expr
for expr in inputs.generate_expressions(names)
if not is_simplifiable(expr))
values = run_c(type_word, expressions,
include_path=include_path, keep_c=keep_c)
return expressions, values