1 2# To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS 3 4CFLAGS ?= -O2 5WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral 6LDFLAGS ?= 7 8# Set this to -v to see the details of failing test cases 9TEST_FLAGS ?= $(if $(filter-out 0 OFF Off off NO No no FALSE False false N n,$(CTEST_OUTPUT_ON_FAILURE)),-v,) 10 11default: all 12 13# Include public header files from ../include, test-specific header files 14# from ./include, and private header files (used by some invasive tests) 15# from ../library. 16LOCAL_CFLAGS = $(WARNING_CFLAGS) -I./include -I../include -I../library -D_FILE_OFFSET_BITS=64 17LOCAL_LDFLAGS = -L../library \ 18 -lmbedtls$(SHARED_SUFFIX) \ 19 -lmbedx509$(SHARED_SUFFIX) \ 20 -lmbedcrypto$(SHARED_SUFFIX) 21 22include ../3rdparty/Makefile.inc 23LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES) 24 25# Enable definition of various functions used throughout the testsuite 26# (gethostname, strdup, fileno...) even when compiling with -std=c99. Harmless 27# on non-POSIX platforms. 28LOCAL_CFLAGS += -D_POSIX_C_SOURCE=200809L 29 30ifndef SHARED 31MBEDLIBS=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a 32else 33MBEDLIBS=../library/libmbedcrypto.$(DLEXT) ../library/libmbedx509.$(DLEXT) ../library/libmbedtls.$(DLEXT) 34endif 35 36ifdef DEBUG 37LOCAL_CFLAGS += -g3 38endif 39 40ifdef RECORD_PSA_STATUS_COVERAGE_LOG 41LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG 42endif 43 44# if we're running on Windows, build for Windows 45ifdef WINDOWS 46WINDOWS_BUILD=1 47endif 48 49ifdef WINDOWS_BUILD 50DLEXT=dll 51EXEXT=.exe 52LOCAL_LDFLAGS += -lws2_32 -lbcrypt 53ifdef SHARED 54SHARED_SUFFIX=.$(DLEXT) 55endif 56else 57DLEXT ?= so 58EXEXT= 59SHARED_SUFFIX= 60endif 61 62ifdef WINDOWS 63PYTHON ?= python 64else 65PYTHON ?= $(shell if type python3 >/dev/null 2>/dev/null; then echo python3; else echo python; fi) 66endif 67 68# See root Makefile 69GEN_FILES ?= 70ifdef GEN_FILES 71gen_file_dep = 72else 73gen_file_dep = | 74endif 75 76.PHONY: generated_files 77GENERATED_BIGNUM_DATA_FILES := $(patsubst tests/%,%,$(shell \ 78 $(PYTHON) scripts/generate_bignum_tests.py --list || \ 79 echo FAILED \ 80)) 81ifeq ($(GENERATED_BIGNUM_DATA_FILES),FAILED) 82$(error "$(PYTHON) scripts/generate_bignum_tests.py --list" failed) 83endif 84GENERATED_ECP_DATA_FILES := $(patsubst tests/%,%,$(shell \ 85 $(PYTHON) scripts/generate_ecp_tests.py --list || \ 86 echo FAILED \ 87)) 88ifeq ($(GENERATED_ECP_DATA_FILES),FAILED) 89$(error "$(PYTHON) scripts/generate_ecp_tests.py --list" failed) 90endif 91GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \ 92 $(PYTHON) scripts/generate_psa_tests.py --list || \ 93 echo FAILED \ 94)) 95ifeq ($(GENERATED_PSA_DATA_FILES),FAILED) 96$(error "$(PYTHON) scripts/generate_psa_tests.py --list" failed) 97endif 98GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_ECP_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES) 99generated_files: $(GENERATED_FILES) 100 101# generate_bignum_tests.py and generate_psa_tests.py spend more time analyzing 102# inputs than generating outputs. Its inputs are the same no matter which files 103# are being generated. 104# It's rare not to want all the outputs. So always generate all of its outputs. 105# Use an intermediate phony dependency so that parallel builds don't run 106# a separate instance of the recipe for each output file. 107.SECONDARY: generated_bignum_test_data generated_ecp_test_data generated_psa_test_data 108$(GENERATED_BIGNUM_DATA_FILES): $(gen_file_dep) generated_bignum_test_data 109generated_bignum_test_data: scripts/generate_bignum_tests.py 110generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_common.py 111generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_core.py 112generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_mod_raw.py 113generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_mod.py 114generated_bignum_test_data: ../scripts/mbedtls_dev/test_case.py 115generated_bignum_test_data: ../scripts/mbedtls_dev/test_data_generation.py 116generated_bignum_test_data: 117 echo " Gen $(GENERATED_BIGNUM_DATA_FILES)" 118 $(PYTHON) scripts/generate_bignum_tests.py 119 120$(GENERATED_ECP_DATA_FILES): $(gen_file_dep) generated_ecp_test_data 121generated_ecp_test_data: scripts/generate_ecp_tests.py 122generated_ecp_test_data: ../scripts/mbedtls_dev/bignum_common.py 123generated_ecp_test_data: ../scripts/mbedtls_dev/ecp.py 124generated_ecp_test_data: ../scripts/mbedtls_dev/test_case.py 125generated_ecp_test_data: ../scripts/mbedtls_dev/test_data_generation.py 126generated_ecp_test_data: 127 echo " Gen $(GENERATED_ECP_DATA_FILES)" 128 $(PYTHON) scripts/generate_ecp_tests.py 129 130$(GENERATED_PSA_DATA_FILES): $(gen_file_dep) generated_psa_test_data 131generated_psa_test_data: scripts/generate_psa_tests.py 132generated_psa_test_data: ../scripts/mbedtls_dev/crypto_data_tests.py 133generated_psa_test_data: ../scripts/mbedtls_dev/crypto_knowledge.py 134generated_psa_test_data: ../scripts/mbedtls_dev/macro_collector.py 135generated_psa_test_data: ../scripts/mbedtls_dev/psa_information.py 136generated_psa_test_data: ../scripts/mbedtls_dev/psa_storage.py 137generated_psa_test_data: ../scripts/mbedtls_dev/test_case.py 138generated_psa_test_data: ../scripts/mbedtls_dev/test_data_generation.py 139## The generated file only depends on the options that are present in 140## crypto_config.h, not on which options are set. To avoid regenerating this 141## file all the time when switching between configurations, don't declare 142## crypto_config.h as a dependency. Remove this file from your working tree 143## if you've just added or removed an option in crypto_config.h. 144#generated_psa_test_data: ../include/psa/crypto_config.h 145generated_psa_test_data: ../include/psa/crypto_values.h 146generated_psa_test_data: ../include/psa/crypto_extra.h 147generated_psa_test_data: suites/test_suite_psa_crypto_metadata.data 148generated_psa_test_data: 149 echo " Gen $(GENERATED_PSA_DATA_FILES) ..." 150 $(PYTHON) scripts/generate_psa_tests.py 151 152# A test application is built for each suites/test_suite_*.data file. 153# Application name is same as .data file's base name and can be 154# constructed by stripping path 'suites/' and extension .data. 155DATA_FILES := $(wildcard suites/test_suite_*.data) 156# Make sure that generated data files are included even if they don't 157# exist yet when the makefile is parsed. 158DATA_FILES += $(filter-out $(DATA_FILES),$(GENERATED_FILES)) 159APPS = $(basename $(subst suites/,,$(DATA_FILES))) 160 161# Construct executable name by adding OS specific suffix $(EXEXT). 162BINARIES := $(addsuffix $(EXEXT),$(APPS)) 163 164.SILENT: 165 166.PHONY: all check test clean 167 168all: $(BINARIES) 169 170$(MBEDLIBS): 171 $(MAKE) -C ../library 172 173MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/drivers/*.c src/test_helpers/*.c)) 174 175mbedtls_test: $(MBEDTLS_TEST_OBJS) 176 177TEST_OBJS_DEPS = $(wildcard include/test/*.h include/test/*/*.h) 178ifdef RECORD_PSA_STATUS_COVERAGE_LOG 179# Explicitly depend on this header because on a clean copy of the source tree, 180# it doesn't exist yet and must be generated as part of the build, and 181# therefore the wildcard enumeration above doesn't include it. 182TEST_OBJS_DEPS += include/test/instrument_record_status.h 183endif 184 185# Rule to compile common test C files in src folder 186src/%.o : src/%.c $(TEST_OBJS_DEPS) 187 echo " CC $<" 188 $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< 189 190src/drivers/%.o : src/drivers/%.c 191 echo " CC $<" 192 $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< 193 194src/test_helpers/%.o : src/test_helpers/%.c 195 echo " CC $<" 196 $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< 197 198C_FILES := $(addsuffix .c,$(APPS)) 199c: $(C_FILES) 200 201# Wildcard target for test code generation: 202# A .c file is generated for each .data file in the suites/ directory. Each .c 203# file depends on a .data and .function file from suites/ directory. Following 204# nameing convention is followed: 205# 206# C file | Depends on 207#----------------------------------------------------------------------------- 208# foo.c | suites/foo.function suites/foo.data 209# foo.bar.c | suites/foo.function suites/foo.bar.data 210# 211# Note above that .c and .data files have same base name. 212# However, corresponding .function file's base name is the word before first 213# dot in .c file's base name. 214# 215.SECONDEXPANSION: 216%.c: suites/$$(firstword $$(subst ., ,$$*)).function suites/%.data scripts/generate_test_code.py suites/helpers.function suites/main_test.function suites/host_test.function 217 echo " Gen $@" 218 $(PYTHON) scripts/generate_test_code.py -f suites/$(firstword $(subst ., ,$*)).function \ 219 -d suites/$*.data \ 220 -t suites/main_test.function \ 221 -p suites/host_test.function \ 222 -s suites \ 223 --helpers-file suites/helpers.function \ 224 -o . 225 226 227$(BINARIES): %$(EXEXT): %.c $(MBEDLIBS) $(TEST_OBJS_DEPS) $(MBEDTLS_TEST_OBJS) 228 echo " CC $<" 229 $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(MBEDTLS_TEST_OBJS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ 230 231clean: 232ifndef WINDOWS 233 rm -rf $(BINARIES) *.c *.datax 234 rm -f src/*.o src/drivers/*.o src/test_helpers/*.o src/libmbed* 235 rm -f include/test/instrument_record_status.h 236 rm -f include/alt-extra/*/*_alt.h 237 rm -rf libtestdriver1 238 rm -f ../library/libtestdriver1.a 239else 240 if exist *.c del /Q /F *.c 241 if exist *.exe del /Q /F *.exe 242 if exist *.datax del /Q /F *.datax 243 if exist src/*.o del /Q /F src/*.o 244 if exist src/drivers/*.o del /Q /F src/drivers/*.o 245 if exist src/test_helpers/*.o del /Q /F src/test_helpers/*.o 246 if exist src/libmbed* del /Q /F src/libmed* 247 if exist include/test/instrument_record_status.h del /Q /F include/test/instrument_record_status.h 248endif 249 250neat: clean 251ifndef WINDOWS 252 rm -f $(GENERATED_FILES) 253else 254 for %f in ($(subst /,\,$(GENERATED_FILES))) if exist %f del /Q /F %f 255endif 256 257# Test suites caught by SKIP_TEST_SUITES are built but not executed. 258check: $(BINARIES) 259 perl scripts/run-test-suites.pl $(TEST_FLAGS) --skip=$(SKIP_TEST_SUITES) 260 261test: check 262 263# Generate variants of some headers for testing 264include/alt-extra/%_alt.h: ../include/%.h 265 perl -p -e 's/^(# *(define|ifndef) +\w+_)H\b/$${1}ALT_H/' $< >$@ 266 267# Generate test library 268 269# Perl code that is executed to transform each original line from a library 270# source file into the corresponding line in the test driver copy of the 271# library. Add a LIBTESTDRIVER1_/libtestdriver1_ to mbedtls_xxx and psa_xxx 272# symbols. 273define libtestdriver1_rewrite := 274 s!^(\s*#\s*include\s*[\"<])(mbedtls|psa)/!$${1}libtestdriver1/include/$${2}/!; \ 275 next if /^\s*#\s*include/; \ 276 s/\b(?=MBEDTLS_|PSA_)/LIBTESTDRIVER1_/g; \ 277 s/\b(?=mbedtls_|psa_)/libtestdriver1_/g; 278endef 279 280libtestdriver1.a: 281 # Copy the library and fake a 3rdparty Makefile include. 282 rm -Rf ./libtestdriver1 283 mkdir ./libtestdriver1 284 cp -Rf ../library ./libtestdriver1 285 cp -Rf ../include ./libtestdriver1 286 cp -Rf ../scripts ./libtestdriver1 287 mkdir ./libtestdriver1/3rdparty 288 touch ./libtestdriver1/3rdparty/Makefile.inc 289 290 # Set the test driver base (minimal) configuration. 291 cp ./include/test/drivers/config_test_driver.h ./libtestdriver1/include/mbedtls/mbedtls_config.h 292 293 # Set the PSA cryptography configuration for the test library. 294 # It is set from the copied include/psa/crypto_config.h of the Mbed TLS 295 # library the test library is intended to be linked with extended by 296 # ./include/test/drivers/crypto_config_test_driver_extension.h to 297 # mirror the PSA_ACCEL_* macros. 298 mv ./libtestdriver1/include/psa/crypto_config.h ./libtestdriver1/include/psa/crypto_config.h.bak 299 head -n -1 ./libtestdriver1/include/psa/crypto_config.h.bak > ./libtestdriver1/include/psa/crypto_config.h 300 cat ./include/test/drivers/crypto_config_test_driver_extension.h >> ./libtestdriver1/include/psa/crypto_config.h 301 echo "#endif /* PSA_CRYPTO_CONFIG_H */" >> ./libtestdriver1/include/psa/crypto_config.h 302 303 # Prefix MBEDTLS_* PSA_* symbols with LIBTESTDRIVER1_ as well as 304 # mbedtls_* psa_* symbols with libtestdriver1_ to avoid symbol clash 305 # when this test driver library is linked with the Mbed TLS library. 306 perl -pi -e '$(libtestdriver1_rewrite)' ./libtestdriver1/library/*.[ch] 307 perl -pi -e '$(libtestdriver1_rewrite)' ./libtestdriver1/include/*/*.h 308 309 $(MAKE) -C ./libtestdriver1/library CFLAGS="-I../../ $(CFLAGS)" LDFLAGS="$(LDFLAGS)" libmbedcrypto.a 310 cp ./libtestdriver1/library/libmbedcrypto.a ../library/libtestdriver1.a 311 312ifdef RECORD_PSA_STATUS_COVERAGE_LOG 313include/test/instrument_record_status.h: ../include/psa/crypto.h Makefile 314 echo " Gen $@" 315 sed <../include/psa/crypto.h >$@ -n 's/^psa_status_t \([A-Za-z0-9_]*\)(.*/#define \1(...) RECORD_STATUS("\1", \1(__VA_ARGS__))/p' 316endif 317