Merge branch 'development' into md-light

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
This commit is contained in:
Dave Rodgman 2023-03-03 14:28:13 +00:00 committed by GitHub
commit 45cef61fa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
107 changed files with 6916 additions and 1422 deletions

View file

@ -388,7 +388,7 @@ armc6_build_test()
msg "build: ARM Compiler 6 ($FLAGS)"
ARM_TOOL_VARIANT="ult" CC="$ARMC6_CC" AR="$ARMC6_AR" CFLAGS="$FLAGS" \
WARNING_CFLAGS='-xc -std=c99' make lib
WARNING_CFLAGS='-Werror -xc -std=c99' make lib
msg "size: ARM Compiler 6 ($FLAGS)"
"$ARMC6_FROMELF" -z library/*.o
@ -1978,6 +1978,7 @@ component_build_module_alt () {
# aesni.c and padlock.c reference mbedtls_aes_context fields directly.
scripts/config.py unset MBEDTLS_AESNI_C
scripts/config.py unset MBEDTLS_PADLOCK_C
scripts/config.py unset MBEDTLS_AESCE_C
# MBEDTLS_ECP_RESTARTABLE is documented as incompatible.
scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
# You can only have one threading implementation: alt or pthread, not both.
@ -3263,6 +3264,27 @@ component_build_psa_config_file () {
rm -f psa_test_config.h psa_user_config.h
}
component_build_psa_alt_headers () {
msg "build: make with PSA alt headers" # ~20s
# Generate alternative versions of the substitutable headers with the
# same content except different include guards.
make -C tests include/alt-extra/psa/crypto_platform_alt.h include/alt-extra/psa/crypto_struct_alt.h
# Build the library and some programs.
# Don't build the fuzzers to avoid having to go through hoops to set
# a correct include path for programs/fuzz/Makefile.
make CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'" lib
make -C programs -o fuzz CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'"
# Check that we're getting the alternative include guards and not the
# original include guards.
programs/test/query_included_headers | grep -x PSA_CRYPTO_PLATFORM_ALT_H
programs/test/query_included_headers | grep -x PSA_CRYPTO_STRUCT_ALT_H
programs/test/query_included_headers | not grep -x PSA_CRYPTO_PLATFORM_H
programs/test/query_included_headers | not grep -x PSA_CRYPTO_STRUCT_H
}
component_test_m32_o0 () {
# Build without optimization, so as to use portable C code (in a 32-bit
# build) and not the i386-specific inline assembly.
@ -3346,6 +3368,7 @@ component_test_have_int32 () {
scripts/config.py unset MBEDTLS_HAVE_ASM
scripts/config.py unset MBEDTLS_AESNI_C
scripts/config.py unset MBEDTLS_PADLOCK_C
scripts/config.py unset MBEDTLS_AESCE_C
make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32'
msg "test: gcc, force 32-bit bignum limbs"
@ -3357,6 +3380,7 @@ component_test_have_int64 () {
scripts/config.py unset MBEDTLS_HAVE_ASM
scripts/config.py unset MBEDTLS_AESNI_C
scripts/config.py unset MBEDTLS_PADLOCK_C
scripts/config.py unset MBEDTLS_AESCE_C
make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64'
msg "test: gcc, force 64-bit bignum limbs"
@ -3481,6 +3505,15 @@ component_build_armcc () {
scripts/config.py baremetal
# armc[56] don't support SHA-512 intrinsics
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
# Stop armclang warning about feature detection for A64_CRYPTO.
# With this enabled, the library does build correctly under armclang,
# but in baremetal builds (as tested here), feature detection is
# unavailable, and the user is notified via a #warning. So enabling
# this feature would prevent us from building with -Werror on
# armclang. Tracked in #7198.
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py set MBEDTLS_HAVE_ASM
make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib

View file

@ -23,7 +23,7 @@ Test Mbed TLS with a subset of algorithms.
This script can be divided into several steps:
First, include/mbedtls/mbedtls_config.h or a different config file passed
in the arguments is parsed to extract any configuration options (collect_config_symbols).
in the arguments is parsed to extract any configuration options (using config.py).
Then, test domains (groups of jobs, tests) are built based on predefined data
collected in the DomainData class. Here, each domain has five major traits:
@ -65,6 +65,11 @@ import shutil
import subprocess
import sys
import traceback
from typing import Union
# Add the Mbed TLS Python library directory to the module search path
import scripts_path # pylint: disable=unused-import
import config
class Colors: # pylint: disable=too-few-public-methods
"""Minimalistic support for colored output.
@ -74,6 +79,7 @@ that outputting start switches the text color to the desired color and
stop switches the text color back to the default."""
red = None
green = None
cyan = None
bold_red = None
bold_green = None
def __init__(self, options=None):
@ -89,6 +95,7 @@ stop switches the text color back to the default."""
normal = '\033[0m'
self.red = ('\033[31m', normal)
self.green = ('\033[32m', normal)
self.cyan = ('\033[36m', normal)
self.bold_red = ('\033[1;31m', normal)
self.bold_green = ('\033[1;32m', normal)
NO_COLORS = Colors(None)
@ -124,34 +131,38 @@ Remove the backup file if it was saved earlier."""
else:
shutil.copy(options.config_backup, options.config)
def run_config_py(options, args):
"""Run scripts/config.py with the specified arguments."""
cmd = ['scripts/config.py']
if options.config != 'include/mbedtls/mbedtls_config.h':
cmd += ['--file', options.config]
cmd += args
log_command(cmd)
subprocess.check_call(cmd)
def option_exists(conf, option):
return option in conf.settings
def set_reference_config(options):
def set_config_option_value(conf, option, colors, value: Union[bool, str]):
"""Set/unset a configuration option, optionally specifying a value.
value can be either True/False (set/unset config option), or a string,
which will make a symbol defined with a certain value."""
if not option_exists(conf, option):
log_line('Symbol {} was not found in {}'.format(option, conf.filename), color=colors.red)
return False
if value is False:
log_command(['config.py', 'unset', option])
conf.unset(option)
elif value is True:
log_command(['config.py', 'set', option])
conf.set(option)
else:
log_command(['config.py', 'set', option, value])
conf.set(option, value)
return True
def set_reference_config(conf, options, colors):
"""Change the library configuration file (mbedtls_config.h) to the reference state.
The reference state is the one from which the tested configurations are
derived."""
# Turn off options that are not relevant to the tests and slow them down.
run_config_py(options, ['full'])
run_config_py(options, ['unset', 'MBEDTLS_TEST_HOOKS'])
log_command(['config.py', 'full'])
conf.adapt(config.full_adapter)
set_config_option_value(conf, 'MBEDTLS_TEST_HOOKS', colors, False)
if options.unset_use_psa:
run_config_py(options, ['unset', 'MBEDTLS_USE_PSA_CRYPTO'])
def collect_config_symbols(options):
"""Read the list of settings from mbedtls_config.h.
Return them in a generator."""
with open(options.config, encoding="utf-8") as config_file:
rx = re.compile(r'\s*(?://\s*)?#define\s+(\w+)\s*(?:$|/[/*])')
for line in config_file:
m = re.match(rx, line)
if m:
yield m.group(1)
set_config_option_value(conf, 'MBEDTLS_USE_PSA_CRYPTO', colors, False)
class Job:
"""A job builds the library in a specific configuration and runs some tests."""
@ -179,19 +190,16 @@ If what is False, announce that the job has failed.'''
elif what is False:
log_line(self.name + ' FAILED', color=colors.red)
else:
log_line('starting ' + self.name)
log_line('starting ' + self.name, color=colors.cyan)
def configure(self, options):
def configure(self, conf, options, colors):
'''Set library configuration options as required for the job.'''
set_reference_config(options)
set_reference_config(conf, options, colors)
for key, value in sorted(self.config_settings.items()):
if value is True:
args = ['set', key]
elif value is False:
args = ['unset', key]
else:
args = ['set', key, value]
run_config_py(options, args)
ret = set_config_option_value(conf, key, colors, value)
if ret is False:
return False
return True
def test(self, options):
'''Run the job's build and test commands.
@ -382,11 +390,11 @@ class DomainData:
return [symbol for symbol in self.all_config_symbols
if re.match(regexp, symbol)]
def __init__(self, options):
def __init__(self, options, conf):
"""Gather data about the library and establish a list of domains to test."""
build_command = [options.make_command, 'CFLAGS=-Werror']
build_and_test = [build_command, [options.make_command, 'test']]
self.all_config_symbols = set(collect_config_symbols(options))
self.all_config_symbols = set(conf.settings.keys())
# Find hash modules by name.
hash_symbols = self.config_symbols_matching(r'MBEDTLS_(MD|RIPEMD|SHA)[0-9]+_C\Z')
# Find elliptic curve enabling macros by name.
@ -442,16 +450,19 @@ A name can either be the name of a domain or the name of one specific job."""
else:
return [self.jobs[name]]
def run(options, job, colors=NO_COLORS):
def run(options, job, conf, colors=NO_COLORS):
"""Run the specified job (a Job instance)."""
subprocess.check_call([options.make_command, 'clean'])
job.announce(colors, None)
job.configure(options)
if not job.configure(conf, options, colors):
job.announce(colors, False)
return False
conf.write()
success = job.test(options)
job.announce(colors, success)
return success
def run_tests(options, domain_data):
def run_tests(options, domain_data, conf):
"""Run the desired jobs.
domain_data should be a DomainData instance that describes the available
domains and jobs.
@ -467,7 +478,7 @@ Run the jobs listed in options.tasks."""
backup_config(options)
try:
for job in jobs:
success = run(options, job, colors=colors)
success = run(options, job, conf, colors=colors)
if not success:
if options.keep_going:
failures.append(job.name)
@ -533,7 +544,9 @@ def main():
default=True)
options = parser.parse_args()
os.chdir(options.directory)
domain_data = DomainData(options)
conf = config.ConfigFile(options.config)
domain_data = DomainData(options, conf)
if options.tasks is True:
options.tasks = sorted(domain_data.domains.keys())
if options.list:
@ -542,7 +555,7 @@ def main():
print(domain_name)
sys.exit(0)
else:
sys.exit(0 if run_tests(options, domain_data) else 1)
sys.exit(0 if run_tests(options, domain_data, conf) else 1)
except Exception: # pylint: disable=broad-except
traceback.print_exc()
sys.exit(3)