aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/libstb/crypto/mbedtls/tests/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/libstb/crypto/mbedtls/tests/scripts')
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/all.sh1343
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/basic-build-test.sh222
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-doxy-blocks.pl64
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-files.py280
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-generated-files.sh70
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-names.sh115
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-python-files.sh12
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/curves.pl67
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-hashes.pl77
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-pkalgs.pl91
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/doxygen.sh29
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_ctr_drbg.pl93
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_decrypt.pl98
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_encrypt.pl81
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_pkcs1_v21_sign_verify.pl72
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate-afl-tests.sh68
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate_test_code.py1152
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/key-exchanges.pl62
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-enum-consts.pl35
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-identifiers.sh62
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-macros.sh16
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-symbols.sh39
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/mbedtls_test.py379
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/recursion.pl44
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/run-test-suites.pl152
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/tcp_client.pl86
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/test-ref-configs.pl102
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_generate_test_code.py1755
-rw-r--r--roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_zeroize.gdb71
-rwxr-xr-xroms/skiboot/libstb/crypto/mbedtls/tests/scripts/travis-log-failure.sh36
30 files changed, 6773 insertions, 0 deletions
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/all.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/all.sh
new file mode 100755
index 000000000..7eaefe999
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/all.sh
@@ -0,0 +1,1343 @@
+#! /usr/bin/env sh
+
+# all.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2014-2017, ARM Limited, All Rights Reserved
+
+
+
+################################################################
+#### Documentation
+################################################################
+
+# Purpose
+# -------
+#
+# To run all tests possible or available on the platform.
+#
+# Notes for users
+# ---------------
+#
+# Warning: the test is destructive. It includes various build modes and
+# configurations, and can and will arbitrarily change the current CMake
+# configuration. The following files must be committed into git:
+# * include/mbedtls/config.h
+# * Makefile, library/Makefile, programs/Makefile, tests/Makefile
+# After running this script, the CMake cache will be lost and CMake
+# will no longer be initialised.
+#
+# The script assumes the presence of a number of tools:
+# * Basic Unix tools (Windows users note: a Unix-style find must be before
+# the Windows find in the PATH)
+# * Perl
+# * GNU Make
+# * CMake
+# * GCC and Clang (recent enough for using ASan with gcc and MemSan with clang, or valgrind)
+# * G++
+# * arm-gcc and mingw-gcc
+# * ArmCC 5 and ArmCC 6, unless invoked with --no-armcc
+# * OpenSSL and GnuTLS command line tools, recent enough for the
+# interoperability tests. If they don't support SSLv3 then a legacy
+# version of these tools must be present as well (search for LEGACY
+# below).
+# See the invocation of check_tools below for details.
+#
+# This script must be invoked from the toplevel directory of a git
+# working copy of Mbed TLS.
+#
+# Note that the output is not saved. You may want to run
+# script -c tests/scripts/all.sh
+# or
+# tests/scripts/all.sh >all.log 2>&1
+#
+# Notes for maintainers
+# ---------------------
+#
+# The bulk of the code is organized into functions that follow one of the
+# following naming conventions:
+# * pre_XXX: things to do before running the tests, in order.
+# * component_XXX: independent components. They can be run in any order.
+# * component_check_XXX: quick tests that aren't worth parallelizing.
+# * component_build_XXX: build things but don't run them.
+# * component_test_XXX: build and test.
+# * support_XXX: if support_XXX exists and returns false then
+# component_XXX is not run by default.
+# * post_XXX: things to do after running the tests.
+# * other: miscellaneous support functions.
+#
+# Each component must start by invoking `msg` with a short informative message.
+#
+# The framework performs some cleanup tasks after each component. This
+# means that components can assume that the working directory is in a
+# cleaned-up state, and don't need to perform the cleanup themselves.
+# * Run `make clean`.
+# * Restore `include/mbedtks/config.h` from a backup made before running
+# the component.
+# * Check out `Makefile`, `library/Makefile`, `programs/Makefile` and
+# `tests/Makefile` from git. This cleans up after an in-tree use of
+# CMake.
+#
+# Any command that is expected to fail must be protected so that the
+# script keeps running in --keep-going mode despite `set -e`. In keep-going
+# mode, if a protected command fails, this is logged as a failure and the
+# script will exit with a failure status once it has run all components.
+# Commands can be protected in any of the following ways:
+# * `make` is a function which runs the `make` command with protection.
+# Note that you must write `make VAR=value`, not `VAR=value make`,
+# because the `VAR=value make` syntax doesn't work with functions.
+# * Put `report_status` before the command to protect it.
+# * Put `if_build_successful` before a command. This protects it, and
+# additionally skips it if a prior invocation of `make` in the same
+# component failed.
+#
+# The tests are roughly in order from fastest to slowest. This doesn't
+# have to be exact, but in general you should add slower tests towards
+# the end and fast checks near the beginning.
+
+
+
+################################################################
+#### Initialization and command line parsing
+################################################################
+
+# Abort on errors (and uninitialised variables)
+set -eu
+
+pre_check_environment () {
+ if [ -d library -a -d include -a -d tests ]; then :; else
+ echo "Must be run from mbed TLS root" >&2
+ exit 1
+ fi
+}
+
+pre_initialize_variables () {
+ CONFIG_H='include/mbedtls/config.h'
+ CONFIG_BAK="$CONFIG_H.bak"
+
+ MEMORY=0
+ FORCE=0
+ KEEP_GOING=0
+
+ # Default commands, can be overriden by the environment
+ : ${OPENSSL:="openssl"}
+ : ${OPENSSL_LEGACY:="$OPENSSL"}
+ : ${OPENSSL_NEXT:="$OPENSSL"}
+ : ${GNUTLS_CLI:="gnutls-cli"}
+ : ${GNUTLS_SERV:="gnutls-serv"}
+ : ${GNUTLS_LEGACY_CLI:="$GNUTLS_CLI"}
+ : ${GNUTLS_LEGACY_SERV:="$GNUTLS_SERV"}
+ : ${OUT_OF_SOURCE_DIR:=./mbedtls_out_of_source_build}
+ : ${ARMC5_BIN_DIR:=/usr/bin}
+ : ${ARMC6_BIN_DIR:=/usr/bin}
+
+ # if MAKEFLAGS is not set add the -j option to speed up invocations of make
+ if [ -z "${MAKEFLAGS+set}" ]; then
+ export MAKEFLAGS="-j"
+ fi
+
+ # Gather the list of available components. These are the functions
+ # defined in this script whose name starts with "component_".
+ # Parse the script with sed, because in sh there is no way to list
+ # defined functions.
+ ALL_COMPONENTS=$(sed -n 's/^ *component_\([0-9A-Z_a-z]*\) *().*/\1/p' <"$0")
+
+ # Exclude components that are not supported on this platform.
+ SUPPORTED_COMPONENTS=
+ for component in $ALL_COMPONENTS; do
+ case $(type "support_$component" 2>&1) in
+ *' function'*)
+ if ! support_$component; then continue; fi;;
+ esac
+ SUPPORTED_COMPONENTS="$SUPPORTED_COMPONENTS $component"
+ done
+}
+
+# Test whether the component $1 is included in the command line patterns.
+is_component_included()
+{
+ set -f
+ for pattern in $COMMAND_LINE_COMPONENTS; do
+ set +f
+ case ${1#component_} in $pattern) return 0;; esac
+ done
+ set +f
+ return 1
+}
+
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTION]... [COMPONENT]...
+Run mbedtls release validation tests.
+By default, run all tests. With one or more COMPONENT, run only those.
+COMPONENT can be the name of a component or a shell wildcard pattern.
+
+Examples:
+ $0 "check_*"
+ Run all sanity checks.
+ $0 --no-armcc --except test_memsan
+ Run everything except builds that require armcc and MemSan.
+
+Special options:
+ -h|--help Print this help and exit.
+ --list-all-components List all available test components and exit.
+ --list-components List components supported on this platform and exit.
+
+General options:
+ -f|--force Force the tests to overwrite any modified files.
+ -k|--keep-going Run all tests and report errors at the end.
+ -m|--memory Additional optional memory tests.
+ --armcc Run ARM Compiler builds (on by default).
+ --except Exclude the COMPONENTs listed on the command line,
+ instead of running only those.
+ --no-armcc Skip ARM Compiler builds.
+ --no-force Refuse to overwrite modified files (default).
+ --no-keep-going Stop at the first error (default).
+ --no-memory No additional memory tests (default).
+ --out-of-source-dir=<path> Directory used for CMake out-of-source build tests.
+ --random-seed Use a random seed value for randomized tests (default).
+ -r|--release-test Run this script in release mode. This fixes the seed value to 1.
+ -s|--seed Integer seed value to use for this test run.
+
+Tool path options:
+ --armc5-bin-dir=<ARMC5_bin_dir_path> ARM Compiler 5 bin directory.
+ --armc6-bin-dir=<ARMC6_bin_dir_path> ARM Compiler 6 bin directory.
+ --gnutls-cli=<GnuTLS_cli_path> GnuTLS client executable to use for most tests.
+ --gnutls-serv=<GnuTLS_serv_path> GnuTLS server executable to use for most tests.
+ --gnutls-legacy-cli=<GnuTLS_cli_path> GnuTLS client executable to use for legacy tests.
+ --gnutls-legacy-serv=<GnuTLS_serv_path> GnuTLS server executable to use for legacy tests.
+ --openssl=<OpenSSL_path> OpenSSL executable to use for most tests.
+ --openssl-legacy=<OpenSSL_path> OpenSSL executable to use for legacy tests e.g. SSLv3.
+ --openssl-next=<OpenSSL_path> OpenSSL executable to use for recent things like ARIA
+EOF
+}
+
+# remove built files as well as the cmake cache/config
+cleanup()
+{
+ if [ -n "${MBEDTLS_ROOT_DIR+set}" ]; then
+ cd "$MBEDTLS_ROOT_DIR"
+ fi
+
+ command make clean
+
+ # Remove CMake artefacts
+ find . -name .git -prune \
+ -iname CMakeFiles -exec rm -rf {} \+ -o \
+ \( -iname cmake_install.cmake -o \
+ -iname CTestTestfile.cmake -o \
+ -iname CMakeCache.txt \) -exec rm {} \+
+ # Recover files overwritten by in-tree CMake builds
+ rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
+ git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
+ git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
+
+ if [ -f "$CONFIG_BAK" ]; then
+ mv "$CONFIG_BAK" "$CONFIG_H"
+ fi
+}
+
+# Executed on exit. May be redefined depending on command line options.
+final_report () {
+ :
+}
+
+fatal_signal () {
+ cleanup
+ final_report $1
+ trap - $1
+ kill -$1 $$
+}
+
+trap 'fatal_signal HUP' HUP
+trap 'fatal_signal INT' INT
+trap 'fatal_signal TERM' TERM
+
+msg()
+{
+ if [ -n "${current_component:-}" ]; then
+ current_section="${current_component#component_}: $1"
+ else
+ current_section="$1"
+ fi
+ echo ""
+ echo "******************************************************************"
+ echo "* $current_section "
+ printf "* "; date
+ echo "******************************************************************"
+}
+
+armc6_build_test()
+{
+ FLAGS="$1"
+
+ msg "build: ARM Compiler 6 ($FLAGS), make"
+ ARM_TOOL_VARIANT="ult" CC="$ARMC6_CC" AR="$ARMC6_AR" CFLAGS="$FLAGS" \
+ WARNING_CFLAGS='-xc -std=c99' make lib
+ make clean
+}
+
+err_msg()
+{
+ echo "$1" >&2
+}
+
+check_tools()
+{
+ for TOOL in "$@"; do
+ if ! `type "$TOOL" >/dev/null 2>&1`; then
+ err_msg "$TOOL not found!"
+ exit 1
+ fi
+ done
+}
+
+check_headers_in_cpp () {
+ ls include/mbedtls | grep "\.h$" >headers.txt
+ <programs/test/cpp_dummy_build.cpp sed -n 's/"$//; s!^#include "mbedtls/!!p' |
+ sort |
+ diff headers.txt -
+ rm headers.txt
+}
+
+pre_parse_command_line () {
+ COMMAND_LINE_COMPONENTS=
+ all_except=0
+ no_armcc=
+
+ while [ $# -gt 0 ]; do
+ case "$1" in
+ --armcc) no_armcc=;;
+ --armc5-bin-dir) shift; ARMC5_BIN_DIR="$1";;
+ --armc6-bin-dir) shift; ARMC6_BIN_DIR="$1";;
+ --except) all_except=1;;
+ --force|-f) FORCE=1;;
+ --gnutls-cli) shift; GNUTLS_CLI="$1";;
+ --gnutls-legacy-cli) shift; GNUTLS_LEGACY_CLI="$1";;
+ --gnutls-legacy-serv) shift; GNUTLS_LEGACY_SERV="$1";;
+ --gnutls-serv) shift; GNUTLS_SERV="$1";;
+ --help|-h) usage; exit;;
+ --keep-going|-k) KEEP_GOING=1;;
+ --list-all-components) printf '%s\n' $ALL_COMPONENTS; exit;;
+ --list-components) printf '%s\n' $SUPPORTED_COMPONENTS; exit;;
+ --memory|-m) MEMORY=1;;
+ --no-armcc) no_armcc=1;;
+ --no-force) FORCE=0;;
+ --no-keep-going) KEEP_GOING=0;;
+ --no-memory) MEMORY=0;;
+ --openssl) shift; OPENSSL="$1";;
+ --openssl-legacy) shift; OPENSSL_LEGACY="$1";;
+ --openssl-next) shift; OPENSSL_NEXT="$1";;
+ --out-of-source-dir) shift; OUT_OF_SOURCE_DIR="$1";;
+ --random-seed) unset SEED;;
+ --release-test|-r) SEED=1;;
+ --seed|-s) shift; SEED="$1";;
+ -*)
+ echo >&2 "Unknown option: $1"
+ echo >&2 "Run $0 --help for usage."
+ exit 120
+ ;;
+ *) COMMAND_LINE_COMPONENTS="$COMMAND_LINE_COMPONENTS $1";;
+ esac
+ shift
+ done
+
+ # With no list of components, run everything.
+ if [ -z "$COMMAND_LINE_COMPONENTS" ]; then
+ all_except=1
+ fi
+
+ # --no-armcc is a legacy option. The modern way is --except '*_armcc*'.
+ # Ignore it if components are listed explicitly on the command line.
+ if [ -n "$no_armcc" ] && [ $all_except -eq 1 ]; then
+ COMMAND_LINE_COMPONENTS="$COMMAND_LINE_COMPONENTS *_armcc*"
+ fi
+
+ # Build the list of components to run.
+ RUN_COMPONENTS=
+ for component in $SUPPORTED_COMPONENTS; do
+ if is_component_included "$component"; [ $? -eq $all_except ]; then
+ RUN_COMPONENTS="$RUN_COMPONENTS $component"
+ fi
+ done
+
+ unset all_except
+ unset no_armcc
+}
+
+pre_check_git () {
+ if [ $FORCE -eq 1 ]; then
+ rm -rf "$OUT_OF_SOURCE_DIR"
+ git checkout-index -f -q $CONFIG_H
+ cleanup
+ else
+
+ if [ -d "$OUT_OF_SOURCE_DIR" ]; then
+ echo "Warning - there is an existing directory at '$OUT_OF_SOURCE_DIR'" >&2
+ echo "You can either delete this directory manually, or force the test by rerunning"
+ echo "the script as: $0 --force --out-of-source-dir $OUT_OF_SOURCE_DIR"
+ exit 1
+ fi
+
+ if ! git diff --quiet include/mbedtls/config.h; then
+ err_msg "Warning - the configuration file 'include/mbedtls/config.h' has been edited. "
+ echo "You can either delete or preserve your work, or force the test by rerunning the"
+ echo "script as: $0 --force"
+ exit 1
+ fi
+ fi
+}
+
+pre_setup_keep_going () {
+ failure_summary=
+ failure_count=0
+ start_red=
+ end_color=
+ if [ -t 1 ]; then
+ case "${TERM:-}" in
+ *color*|cygwin|linux|rxvt*|screen|[Eex]term*)
+ start_red=$(printf '\033[31m')
+ end_color=$(printf '\033[0m')
+ ;;
+ esac
+ fi
+ record_status () {
+ if "$@"; then
+ last_status=0
+ else
+ last_status=$?
+ text="$current_section: $* -> $last_status"
+ failure_summary="$failure_summary
+$text"
+ failure_count=$((failure_count + 1))
+ echo "${start_red}^^^^$text^^^^${end_color}"
+ fi
+ }
+ make () {
+ case "$*" in
+ *test|*check)
+ if [ $build_status -eq 0 ]; then
+ record_status command make "$@"
+ else
+ echo "(skipped because the build failed)"
+ fi
+ ;;
+ *)
+ record_status command make "$@"
+ build_status=$last_status
+ ;;
+ esac
+ }
+ final_report () {
+ if [ $failure_count -gt 0 ]; then
+ echo
+ echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+ echo "${start_red}FAILED: $failure_count${end_color}$failure_summary"
+ echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+ exit 1
+ elif [ -z "${1-}" ]; then
+ echo "SUCCESS :)"
+ fi
+ if [ -n "${1-}" ]; then
+ echo "Killed by SIG$1."
+ fi
+ }
+}
+
+if_build_succeeded () {
+ if [ $build_status -eq 0 ]; then
+ record_status "$@"
+ fi
+}
+
+# to be used instead of ! for commands run with
+# record_status or if_build_succeeded
+not() {
+ ! "$@"
+}
+
+pre_print_configuration () {
+ msg "info: $0 configuration"
+ echo "MEMORY: $MEMORY"
+ echo "FORCE: $FORCE"
+ echo "SEED: ${SEED-"UNSET"}"
+ echo "OPENSSL: $OPENSSL"
+ echo "OPENSSL_LEGACY: $OPENSSL_LEGACY"
+ echo "OPENSSL_NEXT: $OPENSSL_NEXT"
+ echo "GNUTLS_CLI: $GNUTLS_CLI"
+ echo "GNUTLS_SERV: $GNUTLS_SERV"
+ echo "GNUTLS_LEGACY_CLI: $GNUTLS_LEGACY_CLI"
+ echo "GNUTLS_LEGACY_SERV: $GNUTLS_LEGACY_SERV"
+ echo "ARMC5_BIN_DIR: $ARMC5_BIN_DIR"
+ echo "ARMC6_BIN_DIR: $ARMC6_BIN_DIR"
+}
+
+# Make sure the tools we need are available.
+pre_check_tools () {
+ # Build the list of variables to pass to output_env.sh.
+ set env
+
+ case " $RUN_COMPONENTS " in
+ # Require OpenSSL and GnuTLS if running any tests (as opposed to
+ # only doing builds). Not all tests run OpenSSL and GnuTLS, but this
+ # is a good enough approximation in practice.
+ *" test_"*)
+ # To avoid setting OpenSSL and GnuTLS for each call to compat.sh
+ # and ssl-opt.sh, we just export the variables they require.
+ export OPENSSL_CMD="$OPENSSL"
+ export GNUTLS_CLI="$GNUTLS_CLI"
+ export GNUTLS_SERV="$GNUTLS_SERV"
+ # Avoid passing --seed flag in every call to ssl-opt.sh
+ if [ -n "${SEED-}" ]; then
+ export SEED
+ fi
+ set "$@" OPENSSL="$OPENSSL" OPENSSL_LEGACY="$OPENSSL_LEGACY"
+ set "$@" GNUTLS_CLI="$GNUTLS_CLI" GNUTLS_SERV="$GNUTLS_SERV"
+ set "$@" GNUTLS_LEGACY_CLI="$GNUTLS_LEGACY_CLI"
+ set "$@" GNUTLS_LEGACY_SERV="$GNUTLS_LEGACY_SERV"
+ check_tools "$OPENSSL" "$OPENSSL_LEGACY" "$OPENSSL_NEXT" \
+ "$GNUTLS_CLI" "$GNUTLS_SERV" \
+ "$GNUTLS_LEGACY_CLI" "$GNUTLS_LEGACY_SERV"
+ ;;
+ esac
+
+ case " $RUN_COMPONENTS " in
+ *_doxygen[_\ ]*) check_tools "doxygen" "dot";;
+ esac
+
+ case " $RUN_COMPONENTS " in
+ *_arm_none_eabi_gcc[_\ ]*) check_tools "arm-none-eabi-gcc";;
+ esac
+
+ case " $RUN_COMPONENTS " in
+ *_mingw[_\ ]*) check_tools "i686-w64-mingw32-gcc";;
+ esac
+
+ case " $RUN_COMPONENTS " in
+ *" test_zeroize "*) check_tools "gdb";;
+ esac
+
+ case " $RUN_COMPONENTS " in
+ *_armcc*)
+ ARMC5_CC="$ARMC5_BIN_DIR/armcc"
+ ARMC5_AR="$ARMC5_BIN_DIR/armar"
+ ARMC6_CC="$ARMC6_BIN_DIR/armclang"
+ ARMC6_AR="$ARMC6_BIN_DIR/armar"
+ check_tools "$ARMC5_CC" "$ARMC5_AR" "$ARMC6_CC" "$ARMC6_AR";;
+ esac
+
+ msg "info: output_env.sh"
+ case $RUN_COMPONENTS in
+ *_armcc*)
+ set "$@" ARMC5_CC="$ARMC5_CC" ARMC6_CC="$ARMC6_CC" RUN_ARMCC=1;;
+ *) set "$@" RUN_ARMCC=0;;
+ esac
+ "$@" scripts/output_env.sh
+}
+
+
+
+################################################################
+#### Basic checks
+################################################################
+
+#
+# Test Suites to be executed
+#
+# The test ordering tries to optimize for the following criteria:
+# 1. Catch possible problems early, by running first tests that run quickly
+# and/or are more likely to fail than others (eg I use Clang most of the
+# time, so start with a GCC build).
+# 2. Minimize total running time, by avoiding useless rebuilds
+#
+# Indicative running times are given for reference.
+
+component_check_recursion () {
+ msg "test: recursion.pl" # < 1s
+ record_status tests/scripts/recursion.pl library/*.c
+}
+
+component_check_generated_files () {
+ msg "test: freshness of generated source files" # < 1s
+ record_status tests/scripts/check-generated-files.sh
+}
+
+component_check_doxy_blocks () {
+ msg "test: doxygen markup outside doxygen blocks" # < 1s
+ record_status tests/scripts/check-doxy-blocks.pl
+}
+
+component_check_files () {
+ msg "test: check-files.py" # < 1s
+ record_status tests/scripts/check-files.py
+}
+
+component_check_names () {
+ msg "test/build: declared and exported names" # < 3s
+ record_status tests/scripts/check-names.sh -v
+}
+
+component_check_doxygen_warnings () {
+ msg "test: doxygen warnings" # ~ 3s
+ record_status tests/scripts/doxygen.sh
+}
+
+
+
+################################################################
+#### Build and test many configurations and targets
+################################################################
+
+component_test_default_out_of_box () {
+ msg "build: make, default config (out-of-box)" # ~1min
+ make
+
+ msg "test: main suites make, default config (out-of-box)" # ~10s
+ make test
+
+ msg "selftest: make, default config (out-of-box)" # ~10s
+ programs/test/selftest
+}
+
+component_test_default_cmake_gcc_asan () {
+ msg "build: cmake, gcc, ASan" # ~ 1 min 50s
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
+ make test
+
+ msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
+ if_build_succeeded tests/ssl-opt.sh
+
+ msg "test: compat.sh (ASan build)" # ~ 6 min
+ if_build_succeeded tests/compat.sh
+}
+
+component_test_ref_configs () {
+ msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ record_status tests/scripts/test-ref-configs.pl
+}
+
+component_test_sslv3 () {
+ msg "build: Default + SSLv3 (ASan build)" # ~ 6 min
+ scripts/config.pl set MBEDTLS_SSL_PROTO_SSL3
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: SSLv3 - main suites (inc. selftests) (ASan build)" # ~ 50s
+ make test
+
+ msg "build: SSLv3 - compat.sh (ASan build)" # ~ 6 min
+ if_build_succeeded tests/compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2'
+ if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" tests/compat.sh -m 'ssl3'
+
+ msg "build: SSLv3 - ssl-opt.sh (ASan build)" # ~ 6 min
+ if_build_succeeded tests/ssl-opt.sh
+}
+
+component_test_no_renegotiation () {
+ msg "build: Default + !MBEDTLS_SSL_RENEGOTIATION (ASan build)" # ~ 6 min
+ scripts/config.pl unset MBEDTLS_SSL_RENEGOTIATION
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: !MBEDTLS_SSL_RENEGOTIATION - main suites (inc. selftests) (ASan build)" # ~ 50s
+ make test
+
+ msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
+ if_build_succeeded tests/ssl-opt.sh
+}
+
+component_test_no_pem_no_fs () {
+ msg "build: Default + !MBEDTLS_PEM_PARSE_C + !MBEDTLS_FS_IO (ASan build)"
+ scripts/config.pl unset MBEDTLS_PEM_PARSE_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - main suites (inc. selftests) (ASan build)" # ~ 50s
+ make test
+
+ msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - ssl-opt.sh (ASan build)" # ~ 6 min
+ if_build_succeeded tests/ssl-opt.sh
+}
+
+component_test_rsa_no_crt () {
+ msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min
+ scripts/config.pl set MBEDTLS_RSA_NO_CRT
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: RSA_NO_CRT - main suites (inc. selftests) (ASan build)" # ~ 50s
+ make test
+
+ msg "test: RSA_NO_CRT - RSA-related part of ssl-opt.sh (ASan build)" # ~ 5s
+ if_build_succeeded tests/ssl-opt.sh -f RSA
+
+ msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
+ if_build_succeeded tests/compat.sh -t RSA
+}
+
+component_test_small_ssl_out_content_len () {
+ msg "build: small SSL_OUT_CONTENT_LEN (ASan build)"
+ scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 16384
+ scripts/config.pl set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: small SSL_OUT_CONTENT_LEN - ssl-opt.sh MFL and large packet tests"
+ if_build_succeeded tests/ssl-opt.sh -f "Max fragment\|Large packet"
+}
+
+component_test_small_ssl_in_content_len () {
+ msg "build: small SSL_IN_CONTENT_LEN (ASan build)"
+ scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 4096
+ scripts/config.pl set MBEDTLS_SSL_OUT_CONTENT_LEN 16384
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: small SSL_IN_CONTENT_LEN - ssl-opt.sh MFL tests"
+ if_build_succeeded tests/ssl-opt.sh -f "Max fragment"
+}
+
+component_test_small_ssl_dtls_max_buffering () {
+ msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0"
+ scripts/config.pl set MBEDTLS_SSL_DTLS_MAX_BUFFERING 1000
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0 - ssl-opt.sh specific reordering test"
+ if_build_succeeded tests/ssl-opt.sh -f "DTLS reordering: Buffer out-of-order hs msg before reassembling next, free buffered msg"
+}
+
+component_test_small_mbedtls_ssl_dtls_max_buffering () {
+ msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1"
+ scripts/config.pl set MBEDTLS_SSL_DTLS_MAX_BUFFERING 240
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1 - ssl-opt.sh specific reordering test"
+ if_build_succeeded tests/ssl-opt.sh -f "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket"
+}
+
+component_test_full_cmake_clang () {
+ msg "build: cmake, full config, clang" # ~ 50s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
+ make
+
+ msg "test: main suites (full config)" # ~ 5s
+ make test
+
+ msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
+ if_build_succeeded tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
+
+ msg "test: compat.sh RC4, DES, 3DES & NULL (full config)" # ~ 2 min
+ if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'
+
+ msg "test: compat.sh ARIA + ChachaPoly"
+ if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+}
+
+component_build_deprecated () {
+ msg "build: make, full config + DEPRECATED_WARNING, gcc -O" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl set MBEDTLS_DEPRECATED_WARNING
+ # Build with -O -Wextra to catch a maximum of issues.
+ make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' lib programs
+ make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
+
+ msg "build: make, full config + DEPRECATED_REMOVED, clang -O" # ~ 30s
+ # No cleanup, just tweak the configuration and rebuild
+ make clean
+ scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING
+ scripts/config.pl set MBEDTLS_DEPRECATED_REMOVED
+ # Build with -O -Wextra to catch a maximum of issues.
+ make CC=clang CFLAGS='-O -Werror -Wall -Wextra' lib programs
+ make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
+}
+
+
+component_test_depends_curves () {
+ msg "test/build: curves.pl (gcc)" # ~ 4 min
+ record_status tests/scripts/curves.pl
+}
+
+component_test_depends_hashes () {
+ msg "test/build: depends-hashes.pl (gcc)" # ~ 2 min
+ record_status tests/scripts/depends-hashes.pl
+}
+
+component_test_depends_pkalgs () {
+ msg "test/build: depends-pkalgs.pl (gcc)" # ~ 2 min
+ record_status tests/scripts/depends-pkalgs.pl
+}
+
+component_build_key_exchanges () {
+ msg "test/build: key-exchanges (gcc)" # ~ 1 min
+ record_status tests/scripts/key-exchanges.pl
+}
+
+component_build_default_make_gcc_and_cxx () {
+ msg "build: Unix make, -Os (gcc)" # ~ 30s
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os'
+
+ msg "test: verify header list in cpp_dummy_build.cpp"
+ record_status check_headers_in_cpp
+
+ msg "build: Unix make, incremental g++"
+ make TEST_CPP=1
+}
+
+component_test_check_params_without_platform () {
+ msg "build+test: MBEDTLS_CHECK_PARAMS without MBEDTLS_PLATFORM_C"
+ scripts/config.pl full # includes CHECK_PARAMS
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_MEMORY
+ scripts/config.pl unset MBEDTLS_PLATFORM_PRINTF_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl unset MBEDTLS_PLATFORM_C
+ make CC=gcc CFLAGS='-Werror -O1' all test
+}
+
+component_test_check_params_silent () {
+ msg "build+test: MBEDTLS_CHECK_PARAMS with alternative MBEDTLS_PARAM_FAILED()"
+ scripts/config.pl full # includes CHECK_PARAMS
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H"
+ make CC=gcc CFLAGS='-Werror -O1' all test
+}
+
+component_test_no_platform () {
+ # Full configuration build, without platform support, file IO and net sockets.
+ # This should catch missing mbedtls_printf definitions, and by disabling file
+ # IO, it should catch missing '#include <stdio.h>'
+ msg "build: full config except platform/fsio/net, make, gcc, C99" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_PLATFORM_C
+ scripts/config.pl unset MBEDTLS_NET_C
+ scripts/config.pl unset MBEDTLS_PLATFORM_MEMORY
+ scripts/config.pl unset MBEDTLS_PLATFORM_PRINTF_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT
+ scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
+ # to re-enable platform integration features otherwise disabled in C99 builds
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' test
+}
+
+component_build_no_std_function () {
+ # catch compile bugs in _uninit functions
+ msg "build: full config with NO_STD_FUNCTION, make, gcc" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+}
+
+component_build_no_ssl_srv () {
+ msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_SSL_SRV_C
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+}
+
+component_build_no_ssl_cli () {
+ msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_SSL_CLI_C
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+}
+
+component_build_no_sockets () {
+ # Note, C99 compliance can also be tested with the sockets support disabled,
+ # as that requires a POSIX platform (which isn't the same as C99).
+ msg "build: full config except net_sockets.c, make, gcc -std=c99 -pedantic" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
+ scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib
+}
+
+component_test_no_max_fragment_length () {
+ # Run max fragment length tests with MFL disabled
+ msg "build: default config except MFL extension (ASan build)" # ~ 30s
+ scripts/config.pl unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: ssl-opt.sh, MFL-related tests"
+ if_build_succeeded tests/ssl-opt.sh -f "Max fragment length"
+}
+
+component_test_no_max_fragment_length_small_ssl_out_content_len () {
+ msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)"
+ scripts/config.pl unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 16384
+ scripts/config.pl set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MFL tests (disabled MFL extension case) & large packet tests"
+ if_build_succeeded tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
+}
+
+component_test_null_entropy () {
+ msg "build: default config with MBEDTLS_TEST_NULL_ENTROPY (ASan build)"
+ scripts/config.pl set MBEDTLS_TEST_NULL_ENTROPY
+ scripts/config.pl set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ scripts/config.pl set MBEDTLS_ENTROPY_C
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl unset MBEDTLS_ENTROPY_HARDWARE_ALT
+ scripts/config.pl unset MBEDTLS_HAVEGE_C
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan -D UNSAFE_BUILD=ON .
+ make
+
+ msg "test: MBEDTLS_TEST_NULL_ENTROPY - main suites (inc. selftests) (ASan build)"
+ make test
+}
+
+component_test_platform_calloc_macro () {
+ msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
+ scripts/config.pl set MBEDTLS_PLATFORM_MEMORY
+ scripts/config.pl set MBEDTLS_PLATFORM_CALLOC_MACRO calloc
+ scripts/config.pl set MBEDTLS_PLATFORM_FREE_MACRO free
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
+ make test
+}
+
+component_test_aes_fewer_tables () {
+ msg "build: default config with AES_FEWER_TABLES enabled"
+ scripts/config.pl set MBEDTLS_AES_FEWER_TABLES
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra'
+
+ msg "test: AES_FEWER_TABLES"
+ make test
+}
+
+component_test_aes_rom_tables () {
+ msg "build: default config with AES_ROM_TABLES enabled"
+ scripts/config.pl set MBEDTLS_AES_ROM_TABLES
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra'
+
+ msg "test: AES_ROM_TABLES"
+ make test
+}
+
+component_test_aes_fewer_tables_and_rom_tables () {
+ msg "build: default config with AES_ROM_TABLES and AES_FEWER_TABLES enabled"
+ scripts/config.pl set MBEDTLS_AES_FEWER_TABLES
+ scripts/config.pl set MBEDTLS_AES_ROM_TABLES
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra'
+
+ msg "test: AES_FEWER_TABLES + AES_ROM_TABLES"
+ make test
+}
+
+component_test_make_shared () {
+ msg "build/test: make shared" # ~ 40s
+ make SHARED=1 all check
+}
+
+component_test_m32_o0 () {
+ # Build once with -O0, to compile out the i386 specific inline assembly
+ msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s
+ scripts/config.pl full
+ make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address'
+
+ msg "test: i386, make, gcc -O0 (ASan build)"
+ make test
+}
+support_test_m32_o0 () {
+ case $(uname -m) in
+ *64*) true;;
+ *) false;;
+ esac
+}
+
+component_test_m32_o1 () {
+ # Build again with -O1, to compile in the i386 specific inline assembly
+ msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ scripts/config.pl unset MBEDTLS_MEMORY_DEBUG
+ make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address'
+
+ msg "test: i386, make, gcc -O1 (ASan build)"
+ make test
+
+ msg "test ssl-opt.sh, i386, make, gcc-O1"
+ if_build_succeeded tests/ssl-opt.sh
+}
+support_test_m32_o1 () {
+ support_test_m32_o0 "$@"
+}
+
+component_test_mx32 () {
+ msg "build: 64-bit ILP32, make, gcc" # ~ 30s
+ scripts/config.pl full
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32'
+
+ msg "test: 64-bit ILP32, make, gcc"
+ make test
+}
+support_test_mx32 () {
+ case $(uname -m) in
+ amd64|x86_64) true;;
+ *) false;;
+ esac
+}
+
+component_test_min_mpi_window_size () {
+ msg "build: Default + MBEDTLS_MPI_WINDOW_SIZE=1 (ASan build)" # ~ 10s
+ scripts/config.pl set MBEDTLS_MPI_WINDOW_SIZE 1
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MBEDTLS_MPI_WINDOW_SIZE=1 - main suites (inc. selftests) (ASan build)" # ~ 10s
+ make test
+}
+
+component_test_have_int32 () {
+ msg "build: gcc, force 32-bit bignum limbs"
+ scripts/config.pl unset MBEDTLS_HAVE_ASM
+ scripts/config.pl unset MBEDTLS_AESNI_C
+ scripts/config.pl unset MBEDTLS_PADLOCK_C
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32'
+
+ msg "test: gcc, force 32-bit bignum limbs"
+ make test
+}
+
+component_test_have_int64 () {
+ msg "build: gcc, force 64-bit bignum limbs"
+ scripts/config.pl unset MBEDTLS_HAVE_ASM
+ scripts/config.pl unset MBEDTLS_AESNI_C
+ scripts/config.pl unset MBEDTLS_PADLOCK_C
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64'
+
+ msg "test: gcc, force 64-bit bignum limbs"
+ make test
+}
+
+component_test_no_udbl_division () {
+ msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION
+ make CFLAGS='-Werror -O1'
+
+ msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
+ make test
+}
+
+component_test_no_64bit_multiplication () {
+ msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION
+ make CFLAGS='-Werror -O1'
+
+ msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
+ make test
+}
+
+component_build_arm_none_eabi_gcc () {
+ msg "build: arm-none-eabi-gcc, make" # ~ 10s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_NET_C
+ scripts/config.pl unset MBEDTLS_TIMING_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
+ # following things are not in the default config
+ scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
+ scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
+ scripts/config.pl unset MBEDTLS_THREADING_C
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+ make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib
+}
+
+component_build_arm_none_eabi_gcc_no_udbl_division () {
+ msg "build: arm-none-eabi-gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_NET_C
+ scripts/config.pl unset MBEDTLS_TIMING_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
+ # following things are not in the default config
+ scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
+ scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
+ scripts/config.pl unset MBEDTLS_THREADING_C
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+ scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION
+ make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib
+ echo "Checking that software 64-bit division is not required"
+ if_build_succeeded not grep __aeabi_uldiv library/*.o
+}
+
+component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
+ msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_NET_C
+ scripts/config.pl unset MBEDTLS_TIMING_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
+ # following things are not in the default config
+ scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
+ scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
+ scripts/config.pl unset MBEDTLS_THREADING_C
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+ scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION
+ make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib
+ echo "Checking that software 64-bit multiplication is not required"
+ if_build_succeeded not grep __aeabi_lmul library/*.o
+}
+
+component_build_armcc () {
+ msg "build: ARM Compiler 5, make"
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_NET_C
+ scripts/config.pl unset MBEDTLS_TIMING_C
+ scripts/config.pl unset MBEDTLS_FS_IO
+ scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+ scripts/config.pl unset MBEDTLS_HAVE_TIME
+ scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE
+ scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
+ # following things are not in the default config
+ scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING
+ scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
+ scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
+ scripts/config.pl unset MBEDTLS_THREADING_C
+ scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+ scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT # depends on MBEDTLS_HAVE_TIME
+
+ make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
+ make clean
+
+ # ARM Compiler 6 - Target ARMv7-A
+ armc6_build_test "--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"
+
+ # ARM Compiler 6 - Target ARMv8-A - AArch32
+ armc6_build_test "--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"
+
+ # ARM Compiler 6 - Target ARMv8-A - AArch64
+ armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a"
+}
+
+component_test_allow_sha1 () {
+ msg "build: allow SHA1 in certificates by default"
+ scripts/config.pl set MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+ make CFLAGS='-Werror -Wall -Wextra'
+ msg "test: allow SHA1 in certificates by default"
+ make test
+ if_build_succeeded tests/ssl-opt.sh -f SHA-1
+}
+
+component_build_mingw () {
+ msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs
+
+ # note Make tests only builds the tests, but doesn't run them
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror' WINDOWS_BUILD=1 tests
+ make WINDOWS_BUILD=1 clean
+
+ msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests
+ make WINDOWS_BUILD=1 clean
+}
+
+component_test_memsan () {
+ msg "build: MSan (clang)" # ~ 1 min 20s
+ scripts/config.pl unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+ CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
+ make
+
+ msg "test: main suites (MSan)" # ~ 10s
+ make test
+
+ msg "test: ssl-opt.sh (MSan)" # ~ 1 min
+ if_build_succeeded tests/ssl-opt.sh
+
+ # Optional part(s)
+
+ if [ "$MEMORY" -gt 0 ]; then
+ msg "test: compat.sh (MSan)" # ~ 6 min 20s
+ if_build_succeeded tests/compat.sh
+ fi
+}
+
+component_test_valgrind () {
+ msg "build: Release (clang)"
+ CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release .
+ make
+
+ msg "test: main suites valgrind (Release)"
+ make memcheck
+
+ # Optional parts (slow; currently broken on OS X because programs don't
+ # seem to receive signals under valgrind on OS X).
+ if [ "$MEMORY" -gt 0 ]; then
+ msg "test: ssl-opt.sh --memcheck (Release)"
+ if_build_succeeded tests/ssl-opt.sh --memcheck
+ fi
+
+ if [ "$MEMORY" -gt 1 ]; then
+ msg "test: compat.sh --memcheck (Release)"
+ if_build_succeeded tests/compat.sh --memcheck
+ fi
+}
+
+component_test_cmake_out_of_source () {
+ msg "build: cmake 'out-of-source' build"
+ MBEDTLS_ROOT_DIR="$PWD"
+ mkdir "$OUT_OF_SOURCE_DIR"
+ cd "$OUT_OF_SOURCE_DIR"
+ cmake "$MBEDTLS_ROOT_DIR"
+ make
+
+ msg "test: cmake 'out-of-source' build"
+ make test
+ # Test an SSL option that requires an auxiliary script in test/scripts/.
+ # 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).
+ if_build_succeeded ./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
+ if [ -s ssl-opt.err ]; then
+ cat ssl-opt.err >&2
+ record_status [ ! -s ssl-opt.err ]
+ rm ssl-opt.err
+ fi
+ cd "$MBEDTLS_ROOT_DIR"
+ rm -rf "$OUT_OF_SOURCE_DIR"
+ unset MBEDTLS_ROOT_DIR
+}
+
+component_test_zeroize () {
+ # Test that the function mbedtls_platform_zeroize() is not optimized away by
+ # different combinations of compilers and optimization flags by using an
+ # auxiliary GDB script. Unfortunately, GDB does not return error values to the
+ # system in all cases that the script fails, so we must manually search the
+ # output to check whether the pass string is present and no failure strings
+ # were printed.
+
+ # Don't try to disable ASLR. We don't care about ASLR here. We do care
+ # about a spurious message if Gdb tries and fails, so suppress that.
+ gdb_disable_aslr=
+ if [ -z "$(gdb -batch -nw -ex 'set disable-randomization off' 2>&1)" ]; then
+ gdb_disable_aslr='set disable-randomization off'
+ fi
+
+ for optimization_flag in -O2 -O3 -Ofast -Os; do
+ for compiler in clang gcc; do
+ msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()"
+ make programs CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag"
+ if_build_succeeded gdb -ex "$gdb_disable_aslr" -x tests/scripts/test_zeroize.gdb -nw -batch -nx 2>&1 | tee test_zeroize.log
+ if_build_succeeded grep "The buffer was correctly zeroized" test_zeroize.log
+ if_build_succeeded not grep -i "error" test_zeroize.log
+ rm -f test_zeroize.log
+ make clean
+ done
+ done
+
+ unset gdb_disable_aslr
+}
+
+support_check_python_files () {
+ type pylint3 >/dev/null 2>/dev/null
+}
+component_check_python_files () {
+ msg "Lint: Python scripts"
+ record_status tests/scripts/check-python-files.sh
+}
+
+component_check_generate_test_code () {
+ msg "uint test: generate_test_code.py"
+ record_status ./tests/scripts/test_generate_test_code.py
+}
+
+################################################################
+#### Termination
+################################################################
+
+post_report () {
+ msg "Done, cleaning up"
+ cleanup
+
+ final_report
+}
+
+
+
+################################################################
+#### Run all the things
+################################################################
+
+# Run one component and clean up afterwards.
+run_component () {
+ # Back up the configuration in case the component modifies it.
+ # The cleanup function will restore it.
+ cp -p "$CONFIG_H" "$CONFIG_BAK"
+ current_component="$1"
+ "$@"
+ cleanup
+}
+
+# Preliminary setup
+pre_check_environment
+pre_initialize_variables
+pre_parse_command_line "$@"
+
+pre_check_git
+build_status=0
+if [ $KEEP_GOING -eq 1 ]; then
+ pre_setup_keep_going
+else
+ record_status () {
+ "$@"
+ }
+fi
+pre_print_configuration
+pre_check_tools
+cleanup
+
+# Run the requested tests.
+for component in $RUN_COMPONENTS; do
+ run_component "component_$component"
+done
+
+# We're done.
+post_report
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/basic-build-test.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/basic-build-test.sh
new file mode 100755
index 000000000..8990dfbea
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/basic-build-test.sh
@@ -0,0 +1,222 @@
+#!/bin/sh
+
+# basic-build-tests.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Executes the basic test suites, captures the results, and generates a simple
+# test report and code coverage report.
+#
+# The tests include:
+# * Unit tests - executed using tests/scripts/run-test-suite.pl
+# * Self-tests - executed using the test suites above
+# * System tests - executed using tests/ssl-opt.sh
+# * Interoperability tests - executed using tests/compat.sh
+#
+# The tests focus on functionality and do not consider performance.
+#
+# Note the tests self-adapt due to configurations in include/mbedtls/config.h
+# which can lead to some tests being skipped, and can cause the number of
+# available tests to fluctuate.
+#
+# This script has been written to be generic and should work on any shell.
+#
+# Usage: basic-build-tests.sh
+#
+
+# Abort on errors (and uninitiliased variables)
+set -eu
+
+if [ -d library -a -d include -a -d tests ]; then :; else
+ echo "Must be run from mbed TLS root" >&2
+ exit 1
+fi
+
+: ${OPENSSL:="openssl"}
+: ${OPENSSL_LEGACY:="$OPENSSL"}
+: ${GNUTLS_CLI:="gnutls-cli"}
+: ${GNUTLS_SERV:="gnutls-serv"}
+: ${GNUTLS_LEGACY_CLI:="$GNUTLS_CLI"}
+: ${GNUTLS_LEGACY_SERV:="$GNUTLS_SERV"}
+
+# To avoid setting OpenSSL and GnuTLS for each call to compat.sh and ssl-opt.sh
+# we just export the variables they require
+export OPENSSL_CMD="$OPENSSL"
+export GNUTLS_CLI="$GNUTLS_CLI"
+export GNUTLS_SERV="$GNUTLS_SERV"
+
+CONFIG_H='include/mbedtls/config.h'
+CONFIG_BAK="$CONFIG_H.bak"
+
+# Step 0 - print build environment info
+OPENSSL="$OPENSSL" \
+ OPENSSL_LEGACY="$OPENSSL_LEGACY" \
+ GNUTLS_CLI="$GNUTLS_CLI" \
+ GNUTLS_SERV="$GNUTLS_SERV" \
+ GNUTLS_LEGACY_CLI="$GNUTLS_LEGACY_CLI" \
+ GNUTLS_LEGACY_SERV="$GNUTLS_LEGACY_SERV" \
+ scripts/output_env.sh
+echo
+
+# Step 1 - Make and instrumented build for code coverage
+export CFLAGS=' --coverage -g3 -O0 '
+make clean
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+make -j
+
+
+# Step 2 - Execute the tests
+TEST_OUTPUT=out_${PPID}
+cd tests
+
+# Step 2a - Unit Tests
+perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT
+echo
+
+# Step 2b - System Tests
+sh ssl-opt.sh |tee sys-test-$TEST_OUTPUT
+echo
+
+# Step 2c - Compatibility tests
+sh compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2' | \
+ tee compat-test-$TEST_OUTPUT
+OPENSSL_CMD="$OPENSSL_LEGACY" \
+ sh compat.sh -m 'ssl3' |tee -a compat-test-$TEST_OUTPUT
+OPENSSL_CMD="$OPENSSL_LEGACY" \
+ GNUTLS_CLI="$GNUTLS_LEGACY_CLI" \
+ GNUTLS_SERV="$GNUTLS_LEGACY_SERV" \
+ sh compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR' | \
+ tee -a compat-test-$TEST_OUTPUT
+OPENSSL_CMD="$OPENSSL_NEXT" \
+ sh compat.sh -e '^$' -f 'ARIA\|CHACHA' | \
+ tee -a compat-test-$TEST_OUTPUT
+echo
+
+# Step 3 - Process the coverage report
+cd ..
+make lcov |tee tests/cov-$TEST_OUTPUT
+
+
+# Step 4 - Summarise the test report
+echo
+echo "========================================================================="
+echo "Test Report Summary"
+echo
+
+cd tests
+
+# Step 4a - Unit tests
+echo "Unit tests - tests/scripts/run-test-suites.pl"
+
+PASSED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/test cases passed :[\t]*\([0-9]*\)/\1/p'| tr -d ' ')
+SKIPPED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/skipped :[ \t]*\([0-9]*\)/\1/p'| tr -d ' ')
+TOTAL_SUITES=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) .*, [0-9]* tests run)/\1/p'| tr -d ' ')
+FAILED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/failed :[\t]*\([0-9]*\)/\1/p' |tr -d ' ')
+
+echo "No test suites : $TOTAL_SUITES"
+echo "Passed : $PASSED_TESTS"
+echo "Failed : $FAILED_TESTS"
+echo "Skipped : $SKIPPED_TESTS"
+echo "Total exec'd tests : $(($PASSED_TESTS + $FAILED_TESTS))"
+echo "Total avail tests : $(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$PASSED_TESTS
+TOTAL_FAIL=$FAILED_TESTS
+TOTAL_SKIP=$SKIPPED_TESTS
+TOTAL_AVAIL=$(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($PASSED_TESTS + $FAILED_TESTS))
+
+# Step 4b - TLS Options tests
+echo "TLS Options tests - tests/ssl-opt.sh"
+
+PASSED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p')
+SKIPPED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p')
+TOTAL_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p')
+FAILED_TESTS=$(($TOTAL_TESTS - $PASSED_TESTS))
+
+echo "Passed : $PASSED_TESTS"
+echo "Failed : $FAILED_TESTS"
+echo "Skipped : $SKIPPED_TESTS"
+echo "Total exec'd tests : $TOTAL_TESTS"
+echo "Total avail tests : $(($TOTAL_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+TOTAL_AVAIL=$(($TOTAL_AVAIL + $TOTAL_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($TOTAL_EXED + $TOTAL_TESTS))
+
+
+# Step 4c - System Compatibility tests
+echo "System/Compatibility tests - tests/compat.sh"
+
+PASSED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+SKIPPED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+EXED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+FAILED_TESTS=$(($EXED_TESTS - $PASSED_TESTS))
+
+echo "Passed : $PASSED_TESTS"
+echo "Failed : $FAILED_TESTS"
+echo "Skipped : $SKIPPED_TESTS"
+echo "Total exec'd tests : $EXED_TESTS"
+echo "Total avail tests : $(($EXED_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+TOTAL_AVAIL=$(($TOTAL_AVAIL + $EXED_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($TOTAL_EXED + $EXED_TESTS))
+
+
+# Step 4d - Grand totals
+echo "-------------------------------------------------------------------------"
+echo "Total tests"
+
+echo "Total Passed : $TOTAL_PASS"
+echo "Total Failed : $TOTAL_FAIL"
+echo "Total Skipped : $TOTAL_SKIP"
+echo "Total exec'd tests : $TOTAL_EXED"
+echo "Total avail tests : $TOTAL_AVAIL"
+echo
+
+
+# Step 4e - Coverage
+echo "Coverage"
+
+LINES_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ lines......: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* lines)/\1/p')
+LINES_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ lines......: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) lines)/\1/p')
+FUNCS_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ functions..: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* functions)$/\1/p')
+FUNCS_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ functions..: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) functions)$/\1/p')
+
+LINES_PERCENT=$((1000*$LINES_TESTED/$LINES_TOTAL))
+LINES_PERCENT="$(($LINES_PERCENT/10)).$(($LINES_PERCENT-($LINES_PERCENT/10)*10))"
+
+FUNCS_PERCENT=$((1000*$FUNCS_TESTED/$FUNCS_TOTAL))
+FUNCS_PERCENT="$(($FUNCS_PERCENT/10)).$(($FUNCS_PERCENT-($FUNCS_PERCENT/10)*10))"
+
+echo "Lines Tested : $LINES_TESTED of $LINES_TOTAL $LINES_PERCENT%"
+echo "Functions Tested : $FUNCS_TESTED of $FUNCS_TOTAL $FUNCS_PERCENT%"
+echo
+
+
+rm unit-test-$TEST_OUTPUT
+rm sys-test-$TEST_OUTPUT
+rm compat-test-$TEST_OUTPUT
+rm cov-$TEST_OUTPUT
+
+cd ..
+
+make clean
+
+if [ -f "$CONFIG_BAK" ]; then
+ mv "$CONFIG_BAK" "$CONFIG_H"
+fi
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-doxy-blocks.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-doxy-blocks.pl
new file mode 100755
index 000000000..496769992
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-doxy-blocks.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+
+# Detect comment blocks that are likely meant to be doxygen blocks but aren't.
+#
+# More precisely, look for normal comment block containing '\'.
+# Of course one could use doxygen warnings, eg with:
+# sed -e '/EXTRACT/s/YES/NO/' doxygen/mbedtls.doxyfile | doxygen -
+# but that would warn about any undocumented item, while our goal is to find
+# items that are documented, but not marked as such by mistake.
+
+use warnings;
+use strict;
+use File::Basename;
+
+# C/header files in the following directories will be checked
+my @directories = qw(include/mbedtls library doxygen/input);
+
+# very naive pattern to find directives:
+# everything with a backslach except '\0' and backslash at EOL
+my $doxy_re = qr/\\(?!0|\n)/;
+
+# Return an error code to the environment if a potential error in the
+# source code is found.
+my $exit_code = 0;
+
+sub check_file {
+ my ($fname) = @_;
+ open my $fh, '<', $fname or die "Failed to open '$fname': $!\n";
+
+ # first line of the last normal comment block,
+ # or 0 if not in a normal comment block
+ my $block_start = 0;
+ while (my $line = <$fh>) {
+ $block_start = $. if $line =~ m/\/\*(?![*!])/;
+ $block_start = 0 if $line =~ m/\*\//;
+ if ($block_start and $line =~ m/$doxy_re/) {
+ print "$fname:$block_start: directive on line $.\n";
+ $block_start = 0; # report only one directive per block
+ $exit_code = 1;
+ }
+ }
+
+ close $fh;
+}
+
+sub check_dir {
+ my ($dirname) = @_;
+ for my $file (<$dirname/*.[ch]>) {
+ check_file($file);
+ }
+}
+
+# Check that the script is being run from the project's root directory.
+for my $dir (@directories) {
+ if (! -d $dir) {
+ die "This script must be run from the mbed TLS root directory";
+ } else {
+ check_dir($dir)
+ }
+}
+
+exit $exit_code;
+
+__END__
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-files.py b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-files.py
new file mode 100755
index 000000000..00fd0edfb
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-files.py
@@ -0,0 +1,280 @@
+#!/usr/bin/env python3
+"""
+This file is part of Mbed TLS (https://tls.mbed.org)
+
+Copyright (c) 2018, Arm Limited, All Rights Reserved
+
+Purpose
+
+This script checks the current state of the source code for minor issues,
+including incorrect file permissions, presence of tabs, non-Unix line endings,
+trailing whitespace, presence of UTF-8 BOM, and TODO comments.
+Note: requires python 3, must be run from Mbed TLS root.
+"""
+
+import os
+import argparse
+import logging
+import codecs
+import sys
+
+
+class FileIssueTracker(object):
+ """Base class for file-wide issue tracking.
+
+ To implement a checker that processes a file as a whole, inherit from
+ this class and implement `check_file_for_issue` and define ``heading``.
+
+ ``files_exemptions``: files whose name ends with a string in this set
+ will not be checked.
+
+ ``heading``: human-readable description of the issue
+ """
+
+ files_exemptions = frozenset()
+ # heading must be defined in derived classes.
+ # pylint: disable=no-member
+
+ def __init__(self):
+ self.files_with_issues = {}
+
+ def should_check_file(self, filepath):
+ for files_exemption in self.files_exemptions:
+ if filepath.endswith(files_exemption):
+ return False
+ return True
+
+ def check_file_for_issue(self, filepath):
+ raise NotImplementedError
+
+ def record_issue(self, filepath, line_number):
+ if filepath not in self.files_with_issues.keys():
+ self.files_with_issues[filepath] = []
+ self.files_with_issues[filepath].append(line_number)
+
+ def output_file_issues(self, logger):
+ if self.files_with_issues.values():
+ logger.info(self.heading)
+ for filename, lines in sorted(self.files_with_issues.items()):
+ if lines:
+ logger.info("{}: {}".format(
+ filename, ", ".join(str(x) for x in lines)
+ ))
+ else:
+ logger.info(filename)
+ logger.info("")
+
+class LineIssueTracker(FileIssueTracker):
+ """Base class for line-by-line issue tracking.
+
+ To implement a checker that processes files line by line, inherit from
+ this class and implement `line_with_issue`.
+ """
+
+ def issue_with_line(self, line, filepath):
+ raise NotImplementedError
+
+ def check_file_line(self, filepath, line, line_number):
+ if self.issue_with_line(line, filepath):
+ self.record_issue(filepath, line_number)
+
+ def check_file_for_issue(self, filepath):
+ with open(filepath, "rb") as f:
+ for i, line in enumerate(iter(f.readline, b"")):
+ self.check_file_line(filepath, line, i + 1)
+
+class PermissionIssueTracker(FileIssueTracker):
+ """Track files with bad permissions.
+
+ Files that are not executable scripts must not be executable."""
+
+ heading = "Incorrect permissions:"
+
+ def check_file_for_issue(self, filepath):
+ is_executable = os.access(filepath, os.X_OK)
+ should_be_executable = filepath.endswith((".sh", ".pl", ".py"))
+ if is_executable != should_be_executable:
+ self.files_with_issues[filepath] = None
+
+
+class EndOfFileNewlineIssueTracker(FileIssueTracker):
+ """Track files that end with an incomplete line
+ (no newline character at the end of the last line)."""
+
+ heading = "Missing newline at end of file:"
+
+ def check_file_for_issue(self, filepath):
+ with open(filepath, "rb") as f:
+ if not f.read().endswith(b"\n"):
+ self.files_with_issues[filepath] = None
+
+
+class Utf8BomIssueTracker(FileIssueTracker):
+ """Track files that start with a UTF-8 BOM.
+ Files should be ASCII or UTF-8. Valid UTF-8 does not start with a BOM."""
+
+ heading = "UTF-8 BOM present:"
+
+ def check_file_for_issue(self, filepath):
+ with open(filepath, "rb") as f:
+ if f.read().startswith(codecs.BOM_UTF8):
+ self.files_with_issues[filepath] = None
+
+
+class LineEndingIssueTracker(LineIssueTracker):
+ """Track files with non-Unix line endings (i.e. files with CR)."""
+
+ heading = "Non Unix line endings:"
+
+ def issue_with_line(self, line, _filepath):
+ return b"\r" in line
+
+
+class TrailingWhitespaceIssueTracker(LineIssueTracker):
+ """Track lines with trailing whitespace."""
+
+ heading = "Trailing whitespace:"
+ files_exemptions = frozenset(".md")
+
+ def issue_with_line(self, line, _filepath):
+ return line.rstrip(b"\r\n") != line.rstrip()
+
+
+class TabIssueTracker(LineIssueTracker):
+ """Track lines with tabs."""
+
+ heading = "Tabs present:"
+ files_exemptions = frozenset([
+ "Makefile",
+ "generate_visualc_files.pl",
+ ])
+
+ def issue_with_line(self, line, _filepath):
+ return b"\t" in line
+
+
+class MergeArtifactIssueTracker(LineIssueTracker):
+ """Track lines with merge artifacts.
+ These are leftovers from a ``git merge`` that wasn't fully edited."""
+
+ heading = "Merge artifact:"
+
+ def issue_with_line(self, line, _filepath):
+ # Detect leftover git conflict markers.
+ if line.startswith(b'<<<<<<< ') or line.startswith(b'>>>>>>> '):
+ return True
+ if line.startswith(b'||||||| '): # from merge.conflictStyle=diff3
+ return True
+ if line.rstrip(b'\r\n') == b'=======' and \
+ not _filepath.endswith('.md'):
+ return True
+ return False
+
+class TodoIssueTracker(LineIssueTracker):
+ """Track lines containing ``TODO``."""
+
+ heading = "TODO present:"
+ files_exemptions = frozenset([
+ os.path.basename(__file__),
+ "benchmark.c",
+ "pull_request_template.md",
+ ])
+
+ def issue_with_line(self, line, _filepath):
+ return b"todo" in line.lower()
+
+
+class IntegrityChecker(object):
+ """Sanity-check files under the current directory."""
+
+ def __init__(self, log_file):
+ """Instantiate the sanity checker.
+ Check files under the current directory.
+ Write a report of issues to log_file."""
+ self.check_repo_path()
+ self.logger = None
+ self.setup_logger(log_file)
+ self.files_to_check = (
+ ".c", ".h", ".sh", ".pl", ".py", ".md", ".function", ".data",
+ "Makefile", "CMakeLists.txt", "ChangeLog"
+ )
+ self.excluded_directories = ['.git', 'mbed-os']
+ self.excluded_paths = list(map(os.path.normpath, [
+ 'cov-int',
+ 'examples',
+ ]))
+ self.issues_to_check = [
+ PermissionIssueTracker(),
+ EndOfFileNewlineIssueTracker(),
+ Utf8BomIssueTracker(),
+ LineEndingIssueTracker(),
+ TrailingWhitespaceIssueTracker(),
+ TabIssueTracker(),
+ MergeArtifactIssueTracker(),
+ TodoIssueTracker(),
+ ]
+
+ @staticmethod
+ def check_repo_path():
+ if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
+ raise Exception("Must be run from Mbed TLS root")
+
+ def setup_logger(self, log_file, level=logging.INFO):
+ self.logger = logging.getLogger()
+ self.logger.setLevel(level)
+ if log_file:
+ handler = logging.FileHandler(log_file)
+ self.logger.addHandler(handler)
+ else:
+ console = logging.StreamHandler()
+ self.logger.addHandler(console)
+
+ def prune_branch(self, root, d):
+ if d in self.excluded_directories:
+ return True
+ if os.path.normpath(os.path.join(root, d)) in self.excluded_paths:
+ return True
+ return False
+
+ def check_files(self):
+ for root, dirs, files in os.walk("."):
+ dirs[:] = sorted(d for d in dirs if not self.prune_branch(root, d))
+ for filename in sorted(files):
+ filepath = os.path.join(root, filename)
+ if not filepath.endswith(self.files_to_check):
+ continue
+ for issue_to_check in self.issues_to_check:
+ if issue_to_check.should_check_file(filepath):
+ issue_to_check.check_file_for_issue(filepath)
+
+ def output_issues(self):
+ integrity_return_code = 0
+ for issue_to_check in self.issues_to_check:
+ if issue_to_check.files_with_issues:
+ integrity_return_code = 1
+ issue_to_check.output_file_issues(self.logger)
+ return integrity_return_code
+
+
+def run_main():
+ parser = argparse.ArgumentParser(
+ description=(
+ "This script checks the current state of the source code for "
+ "minor issues, including incorrect file permissions, "
+ "presence of tabs, non-Unix line endings, trailing whitespace, "
+ "presence of UTF-8 BOM, and TODO comments. "
+ "Note: requires python 3, must be run from Mbed TLS root."
+ )
+ )
+ parser.add_argument(
+ "-l", "--log_file", type=str, help="path to optional output log",
+ )
+ check_args = parser.parse_args()
+ integrity_check = IntegrityChecker(check_args.log_file)
+ integrity_check.check_files()
+ return_code = integrity_check.output_issues()
+ sys.exit(return_code)
+
+
+if __name__ == "__main__":
+ run_main()
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-generated-files.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-generated-files.sh
new file mode 100755
index 000000000..065ea33a2
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-generated-files.sh
@@ -0,0 +1,70 @@
+#! /usr/bin/env sh
+
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2018, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Check if generated files are up-to-date.
+
+set -eu
+
+if [ -d library -a -d include -a -d tests ]; then :; else
+ echo "Must be run from mbed TLS root" >&2
+ exit 1
+fi
+
+check()
+{
+ SCRIPT=$1
+ TO_CHECK=$2
+ PATTERN=""
+ FILES=""
+
+ if [ -d $TO_CHECK ]; then
+ for FILE in $TO_CHECK/*; do
+ FILES="$FILE $FILES"
+ done
+ else
+ FILES=$TO_CHECK
+ fi
+
+ for FILE in $FILES; do
+ cp $FILE $FILE.bak
+ done
+
+ $SCRIPT
+
+ # Compare the script output to the old files and remove backups
+ for FILE in $FILES; do
+ if ! diff $FILE $FILE.bak >/dev/null 2>&1; then
+ echo "'$FILE' was either modified or deleted by '$SCRIPT'"
+ exit 1
+ fi
+ mv $FILE.bak $FILE
+
+ if [ -d $TO_CHECK ]; then
+ # Create a grep regular expression that we can check against the
+ # directory contents to test whether new files have been created
+ if [ -z $PATTERN ]; then
+ PATTERN="$(basename $FILE)"
+ else
+ PATTERN="$PATTERN\|$(basename $FILE)"
+ fi
+ fi
+ done
+
+ if [ -d $TO_CHECK ]; then
+ # Check if there are any new files
+ if ls -1 $TO_CHECK | grep -v "$PATTERN" >/dev/null 2>&1; then
+ echo "Files were created by '$SCRIPT'"
+ exit 1
+ fi
+ fi
+}
+
+check scripts/generate_errors.pl library/error.c
+check scripts/generate_query_config.pl programs/ssl/query_config.c
+check scripts/generate_features.pl library/version_features.c
+check scripts/generate_visualc_files.pl visualc/VS2010
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-names.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-names.sh
new file mode 100755
index 000000000..90ecfd272
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-names.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2019, ARM Limited, All Rights Reserved
+
+set -eu
+
+if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
+ cat <<EOF
+$0 [-v]
+This script confirms that the naming of all symbols and identifiers in mbed
+TLS are consistent with the house style and are also self-consistent.
+
+ -v If the script fails unexpectedly, print a command trace.
+EOF
+ exit
+fi
+
+if grep --version|head -n1|grep GNU >/dev/null; then :; else
+ echo "This script requires GNU grep.">&2
+ exit 1
+fi
+
+trace=
+if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
+ shift
+ trace='-x'
+ exec 2>check-names.err
+ trap 'echo "FAILED UNEXPECTEDLY, status=$?";
+ cat check-names.err' EXIT
+ set -x
+fi
+
+printf "Analysing source code...\n"
+
+sh $trace tests/scripts/list-macros.sh
+tests/scripts/list-enum-consts.pl
+sh $trace tests/scripts/list-identifiers.sh
+sh $trace tests/scripts/list-symbols.sh
+
+FAIL=0
+
+printf "\nExported symbols declared in header: "
+UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' )
+if [ "x$UNDECLARED" = "x" ]; then
+ echo "PASS"
+else
+ echo "FAIL"
+ echo "$UNDECLARED"
+ FAIL=1
+fi
+
+diff macros identifiers | sed -n -e 's/< //p' > actual-macros
+
+for THING in actual-macros enum-consts; do
+ printf "Names of $THING: "
+ test -r $THING
+ BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
+ if [ "x$BAD" = "x" ]; then
+ echo "PASS"
+ else
+ echo "FAIL"
+ echo "$BAD"
+ FAIL=1
+ fi
+done
+
+for THING in identifiers; do
+ printf "Names of $THING: "
+ test -r $THING
+ BAD=$( grep -v '^mbedtls_[0-9a-z_]*[0-9a-z]$' $THING || true )
+ if [ "x$BAD" = "x" ]; then
+ echo "PASS"
+ else
+ echo "FAIL"
+ echo "$BAD"
+ FAIL=1
+ fi
+done
+
+printf "Likely typos: "
+sort -u actual-macros enum-consts > _caps
+HEADERS=$( ls include/mbedtls/*.h | egrep -v 'compat-1\.3\.h' )
+NL='
+'
+sed -n 's/MBED..._[A-Z0-9_]*/\'"$NL"'&\'"$NL"/gp \
+ $HEADERS library/*.c \
+ | grep MBEDTLS | sort -u > _MBEDTLS_XXX
+TYPOS=$( diff _caps _MBEDTLS_XXX | sed -n 's/^> //p' \
+ | egrep -v 'XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$' || true )
+rm _MBEDTLS_XXX _caps
+if [ "x$TYPOS" = "x" ]; then
+ echo "PASS"
+else
+ echo "FAIL"
+ echo "$TYPOS"
+ FAIL=1
+fi
+
+if [ -n "$trace" ]; then
+ set +x
+ trap - EXIT
+ rm check-names.err
+fi
+
+printf "\nOverall: "
+if [ "$FAIL" -eq 0 ]; then
+ rm macros actual-macros enum-consts identifiers exported-symbols
+ echo "PASSED"
+ exit 0
+else
+ echo "FAILED"
+ exit 1
+fi
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-python-files.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-python-files.sh
new file mode 100755
index 000000000..929041822
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/check-python-files.sh
@@ -0,0 +1,12 @@
+#! /usr/bin/env sh
+
+# This file is part of Mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2018, Arm Limited, All Rights Reserved
+#
+# Purpose:
+#
+# Run 'pylint' on Python files for programming errors and helps enforcing
+# PEP8 coding standards.
+
+pylint3 -j 2 scripts/*.py tests/scripts/*.py
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/curves.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/curves.pl
new file mode 100755
index 000000000..ddc90c580
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/curves.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+# curves.pl
+#
+# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To test the code dependencies on individual curves in each test suite. This
+# is a verification step to ensure we don't ship test suites that do not work
+# for some build options.
+#
+# The process is:
+# for each possible curve
+# build the library and test suites with the curve disabled
+# execute the test suites
+#
+# And any test suite with the wrong dependencies will fail.
+#
+# Usage: tests/scripts/curves.pl
+#
+# This script should be executed from the root of the project directory.
+#
+# For best effect, run either with cmake disabled, or cmake enabled in a mode
+# that includes -Werror.
+
+use warnings;
+use strict;
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $sed_cmd = 's/^#define \(MBEDTLS_ECP_DP.*_ENABLED\)/\1/p';
+my $config_h = 'include/mbedtls/config.h';
+my @curves = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
+
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+ system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+ # use an exit code between 1 and 124 for git bisect (die returns 255)
+ warn $_[0];
+ exit 1;
+}
+
+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.pl unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED" );
+
+ print "\n******************************************\n";
+ print "* Testing without curve: $curve\n";
+ print "******************************************\n";
+
+ system( "scripts/config.pl unset $curve" )
+ and abort "Failed to disable $curve\n";
+
+ system( "CFLAGS='-Werror -Wall -Wextra' make lib" )
+ and abort "Failed to build lib: $curve\n";
+ system( "cd tests && make" ) and abort "Failed to build tests: $curve\n";
+ system( "make test" ) and abort "Failed test suite: $curve\n";
+
+}
+
+system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
+system( "make clean" ) and die;
+exit 0;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-hashes.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-hashes.pl
new file mode 100755
index 000000000..f57e7ed88
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-hashes.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/env perl
+
+# depends-hashes.pl
+#
+# Copyright (c) 2017, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To test the code dependencies on individual hashes in each test suite. This
+# is a verification step to ensure we don't ship test suites that do not work
+# for some build options.
+#
+# The process is:
+# for each possible hash
+# build the library and test suites with the hash disabled
+# execute the test suites
+#
+# And any test suite with the wrong dependencies will fail.
+#
+# Usage: tests/scripts/depends-hashes.pl
+#
+# This script should be executed from the root of the project directory.
+#
+# For best effect, run either with cmake disabled, or cmake enabled in a mode
+# that includes -Werror.
+
+use warnings;
+use strict;
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $config_h = 'include/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
+my $ssl_sed_cmd = 's/^#define \(MBEDTLS_SSL.*\)/\1/p';
+my @ssl = split( /\s+/, `sed -n -e '$ssl_sed_cmd' $config_h` );
+
+# for md we want to catch MD5_C but not MD_C, hence the extra dot
+my $mdx_sed_cmd = 's/^#define \(MBEDTLS_MD..*_C\)/\1/p';
+my $sha_sed_cmd = 's/^#define \(MBEDTLS_SHA.*_C\)/\1/p';
+my @hashes = split( /\s+/,
+ `sed -n -e '$mdx_sed_cmd' -e '$sha_sed_cmd' $config_h` );
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+ system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+ # use an exit code between 1 and 124 for git bisect (die returns 255)
+ warn $_[0];
+ exit 1;
+}
+
+for my $hash (@hashes) {
+ system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
+ system( "make clean" ) and die;
+
+ print "\n******************************************\n";
+ print "* Testing without hash: $hash\n";
+ print "******************************************\n";
+
+ system( "scripts/config.pl unset $hash" )
+ and abort "Failed to disable $hash\n";
+
+ for my $opt (@ssl) {
+ system( "scripts/config.pl unset $opt" )
+ and abort "Failed to disable $opt\n";
+ }
+
+ system( "CFLAGS='-Werror -Wall -Wextra' make lib" )
+ and abort "Failed to build lib: $hash\n";
+ system( "cd tests && make" ) and abort "Failed to build tests: $hash\n";
+ system( "make test" ) and abort "Failed test suite: $hash\n";
+}
+
+system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
+system( "make clean" ) and die;
+exit 0;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-pkalgs.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-pkalgs.pl
new file mode 100755
index 000000000..97a43e881
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/depends-pkalgs.pl
@@ -0,0 +1,91 @@
+#!/usr/bin/env perl
+
+# depends-pkalgs.pl
+#
+# Copyright (c) 2017, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To test the code dependencies on individual PK algs (those that can be used
+# from the PK layer, so currently signature and encryption but not key
+# exchange) in each test suite. This is a verification step to ensure we don't
+# ship test suites that do not work for some build options.
+#
+# The process is:
+# for each possible PK alg
+# build the library and test suites with that alg disabled
+# execute the test suites
+#
+# And any test suite with the wrong dependencies will fail.
+#
+# Usage: tests/scripts/depends-pkalgs.pl
+#
+# This script should be executed from the root of the project directory.
+#
+# For best effect, run either with cmake disabled, or cmake enabled in a mode
+# that includes -Werror.
+
+use warnings;
+use strict;
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $config_h = 'include/mbedtls/config.h';
+
+# Some algorithms can't be disabled on their own as others depend on them, so
+# we list those reverse-dependencies here to keep check_config.h happy.
+my %algs = (
+ 'MBEDTLS_ECDSA_C' => ['MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED'],
+ 'MBEDTLS_ECP_C' => ['MBEDTLS_ECDSA_C',
+ 'MBEDTLS_ECDH_C',
+ 'MBEDTLS_ECJPAKE_C',
+ 'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED'],
+ 'MBEDTLS_X509_RSASSA_PSS_SUPPORT' => [],
+ 'MBEDTLS_PKCS1_V21' => ['MBEDTLS_X509_RSASSA_PSS_SUPPORT'],
+ 'MBEDTLS_PKCS1_V15' => ['MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED'],
+ 'MBEDTLS_RSA_C' => ['MBEDTLS_X509_RSASSA_PSS_SUPPORT',
+ 'MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED',
+ 'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED'],
+);
+
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+ system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+ # use an exit code between 1 and 124 for git bisect (die returns 255)
+ warn $_[0];
+ exit 1;
+}
+
+while( my ($alg, $extras) = each %algs ) {
+ system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
+ system( "make clean" ) and die;
+
+ print "\n******************************************\n";
+ print "* Testing without alg: $alg\n";
+ print "******************************************\n";
+
+ system( "scripts/config.pl unset $alg" )
+ and abort "Failed to disable $alg\n";
+ for my $opt (@$extras) {
+ system( "scripts/config.pl unset $opt" )
+ and abort "Failed to disable $opt\n";
+ }
+
+ system( "CFLAGS='-Werror -Wall -Wextra' make lib" )
+ and abort "Failed to build lib: $alg\n";
+ system( "cd tests && make" ) and abort "Failed to build tests: $alg\n";
+ system( "make test" ) and abort "Failed test suite: $alg\n";
+}
+
+system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
+system( "make clean" ) and die;
+exit 0;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/doxygen.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/doxygen.sh
new file mode 100755
index 000000000..e7758c9e8
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/doxygen.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Make sure the doxygen documentation builds without warnings
+
+# Abort on errors (and uninitiliased variables)
+set -eu
+
+if [ -d library -a -d include -a -d tests ]; then :; else
+ echo "Must be run from mbed TLS root" >&2
+ exit 1
+fi
+
+if scripts/apidoc_full.sh > doc.out 2>doc.err; then :; else
+ cat doc.err
+ echo "FAIL" >&2
+ exit 1;
+fi
+
+cat doc.out doc.err | \
+ grep -v "warning: ignoring unsupported tag" \
+ > doc.filtered
+
+if egrep "(warning|error):" doc.filtered; then
+ echo "FAIL" >&2
+ exit 1;
+fi
+
+make apidoc_clean
+rm -f doc.out doc.err doc.filtered
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_ctr_drbg.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_ctr_drbg.pl
new file mode 100755
index 000000000..3c074be19
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_ctr_drbg.pl
@@ -0,0 +1,93 @@
+#!/usr/bin/env perl
+#
+# Based on NIST CTR_DRBG.rsp validation file
+# Only uses AES-256-CTR cases that use a Derivation function
+# and concats nonce and personalization for initialization.
+
+use strict;
+
+my $file = shift;
+
+open(TEST_DATA, "$file") or die "Opening test cases '$file': $!";
+
+sub get_suite_val($)
+{
+ my $name = shift;
+ my $val = "";
+
+ my $line = <TEST_DATA>;
+ ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/);
+
+ return $val;
+}
+
+sub get_val($)
+{
+ my $name = shift;
+ my $val = "";
+ my $line;
+
+ while($line = <TEST_DATA>)
+ {
+ next if($line !~ /=/);
+ last;
+ }
+
+ ($val) = ($line =~ /^$name = (\w+)/);
+
+ return $val;
+}
+
+my $cnt = 1;;
+while (my $line = <TEST_DATA>)
+{
+ next if ($line !~ /^\[AES-256 use df/);
+
+ my $PredictionResistanceStr = get_suite_val("PredictionResistance");
+ my $PredictionResistance = 0;
+ $PredictionResistance = 1 if ($PredictionResistanceStr eq 'True');
+ my $EntropyInputLen = get_suite_val("EntropyInputLen");
+ my $NonceLen = get_suite_val("NonceLen");
+ my $PersonalizationStringLen = get_suite_val("PersonalizationStringLen");
+ my $AdditionalInputLen = get_suite_val("AdditionalInputLen");
+
+ for ($cnt = 0; $cnt < 15; $cnt++)
+ {
+ my $Count = get_val("COUNT");
+ my $EntropyInput = get_val("EntropyInput");
+ my $Nonce = get_val("Nonce");
+ my $PersonalizationString = get_val("PersonalizationString");
+ my $AdditionalInput1 = get_val("AdditionalInput");
+ my $EntropyInputPR1 = get_val("EntropyInputPR") if ($PredictionResistance == 1);
+ my $EntropyInputReseed = get_val("EntropyInputReseed") if ($PredictionResistance == 0);
+ my $AdditionalInputReseed = get_val("AdditionalInputReseed") if ($PredictionResistance == 0);
+ my $AdditionalInput2 = get_val("AdditionalInput");
+ my $EntropyInputPR2 = get_val("EntropyInputPR") if ($PredictionResistance == 1);
+ my $ReturnedBits = get_val("ReturnedBits");
+
+ if ($PredictionResistance == 1)
+ {
+ print("CTR_DRBG NIST Validation (AES-256 use df,$PredictionResistanceStr,$EntropyInputLen,$NonceLen,$PersonalizationStringLen,$AdditionalInputLen) #$Count\n");
+ print("ctr_drbg_validate_pr");
+ print(":\"$Nonce$PersonalizationString\"");
+ print(":\"$EntropyInput$EntropyInputPR1$EntropyInputPR2\"");
+ print(":\"$AdditionalInput1\"");
+ print(":\"$AdditionalInput2\"");
+ print(":\"$ReturnedBits\"");
+ print("\n\n");
+ }
+ else
+ {
+ print("CTR_DRBG NIST Validation (AES-256 use df,$PredictionResistanceStr,$EntropyInputLen,$NonceLen,$PersonalizationStringLen,$AdditionalInputLen) #$Count\n");
+ print("ctr_drbg_validate_nopr");
+ print(":\"$Nonce$PersonalizationString\"");
+ print(":\"$EntropyInput$EntropyInputReseed\"");
+ print(":\"$AdditionalInput1\"");
+ print(":\"$AdditionalInputReseed\"");
+ print(":\"$AdditionalInput2\"");
+ print(":\"$ReturnedBits\"");
+ print("\n\n");
+ }
+ }
+}
+close(TEST_DATA);
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_decrypt.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_decrypt.pl
new file mode 100755
index 000000000..03809cb94
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_decrypt.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/env perl
+#
+# Based on NIST gcmDecryptxxx.rsp validation files
+# Only first 3 of every set used for compile time saving
+
+use strict;
+
+my $file = shift;
+
+open(TEST_DATA, "$file") or die "Opening test cases '$file': $!";
+
+sub get_suite_val($)
+{
+ my $name = shift;
+ my $val = "";
+
+ while(my $line = <TEST_DATA>)
+ {
+ next if ($line !~ /^\[/);
+ ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/);
+ last;
+ }
+
+ return $val;
+}
+
+sub get_val($)
+{
+ my $name = shift;
+ my $val = "";
+ my $line;
+
+ while($line = <TEST_DATA>)
+ {
+ next if($line !~ /=/);
+ last;
+ }
+
+ ($val) = ($line =~ /^$name = (\w+)/);
+
+ return $val;
+}
+
+sub get_val_or_fail($)
+{
+ my $name = shift;
+ my $val = "FAIL";
+ my $line;
+
+ while($line = <TEST_DATA>)
+ {
+ next if($line !~ /=/ && $line !~ /FAIL/);
+ last;
+ }
+
+ ($val) = ($line =~ /^$name = (\w+)/) if ($line =~ /=/);
+
+ return $val;
+}
+
+my $cnt = 1;;
+while (my $line = <TEST_DATA>)
+{
+ my $key_len = get_suite_val("Keylen");
+ next if ($key_len !~ /\d+/);
+ my $iv_len = get_suite_val("IVlen");
+ my $pt_len = get_suite_val("PTlen");
+ my $add_len = get_suite_val("AADlen");
+ my $tag_len = get_suite_val("Taglen");
+
+ for ($cnt = 0; $cnt < 3; $cnt++)
+ {
+ my $Count = get_val("Count");
+ my $key = get_val("Key");
+ my $iv = get_val("IV");
+ my $ct = get_val("CT");
+ my $add = get_val("AAD");
+ my $tag = get_val("Tag");
+ my $pt = get_val_or_fail("PT");
+
+ print("GCM NIST Validation (AES-$key_len,$iv_len,$pt_len,$add_len,$tag_len) #$Count\n");
+ print("gcm_decrypt_and_verify");
+ print(":\"$key\"");
+ print(":\"$ct\"");
+ print(":\"$iv\"");
+ print(":\"$add\"");
+ print(":$tag_len");
+ print(":\"$tag\"");
+ print(":\"$pt\"");
+ print(":0");
+ print("\n\n");
+ }
+}
+
+print("GCM Selftest\n");
+print("gcm_selftest:\n\n");
+
+close(TEST_DATA);
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_encrypt.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_encrypt.pl
new file mode 100755
index 000000000..29ec677da
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_gcm_encrypt.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/env perl
+#
+# Based on NIST gcmEncryptIntIVxxx.rsp validation files
+# Only first 3 of every set used for compile time saving
+
+use strict;
+
+my $file = shift;
+
+open(TEST_DATA, "$file") or die "Opening test cases '$file': $!";
+
+sub get_suite_val($)
+{
+ my $name = shift;
+ my $val = "";
+
+ while(my $line = <TEST_DATA>)
+ {
+ next if ($line !~ /^\[/);
+ ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/);
+ last;
+ }
+
+ return $val;
+}
+
+sub get_val($)
+{
+ my $name = shift;
+ my $val = "";
+ my $line;
+
+ while($line = <TEST_DATA>)
+ {
+ next if($line !~ /=/);
+ last;
+ }
+
+ ($val) = ($line =~ /^$name = (\w+)/);
+
+ return $val;
+}
+
+my $cnt = 1;;
+while (my $line = <TEST_DATA>)
+{
+ my $key_len = get_suite_val("Keylen");
+ next if ($key_len !~ /\d+/);
+ my $iv_len = get_suite_val("IVlen");
+ my $pt_len = get_suite_val("PTlen");
+ my $add_len = get_suite_val("AADlen");
+ my $tag_len = get_suite_val("Taglen");
+
+ for ($cnt = 0; $cnt < 3; $cnt++)
+ {
+ my $Count = get_val("Count");
+ my $key = get_val("Key");
+ my $pt = get_val("PT");
+ my $add = get_val("AAD");
+ my $iv = get_val("IV");
+ my $ct = get_val("CT");
+ my $tag = get_val("Tag");
+
+ print("GCM NIST Validation (AES-$key_len,$iv_len,$pt_len,$add_len,$tag_len) #$Count\n");
+ print("gcm_encrypt_and_tag");
+ print(":\"$key\"");
+ print(":\"$pt\"");
+ print(":\"$iv\"");
+ print(":\"$add\"");
+ print(":\"$ct\"");
+ print(":$tag_len");
+ print(":\"$tag\"");
+ print(":0");
+ print("\n\n");
+ }
+}
+
+print("GCM Selftest\n");
+print("gcm_selftest:\n\n");
+
+close(TEST_DATA);
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_pkcs1_v21_sign_verify.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_pkcs1_v21_sign_verify.pl
new file mode 100755
index 000000000..110cb4b07
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/gen_pkcs1_v21_sign_verify.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+#
+
+use strict;
+
+my $file = shift;
+
+open(TEST_DATA, "$file") or die "Opening test cases '$file': $!";
+
+sub get_val($$)
+{
+ my $str = shift;
+ my $name = shift;
+ my $val = "";
+
+ while(my $line = <TEST_DATA>)
+ {
+ next if($line !~ /^# $str/);
+ last;
+ }
+
+ while(my $line = <TEST_DATA>)
+ {
+ last if($line eq "\r\n");
+ $val .= $line;
+ }
+
+ $val =~ s/[ \r\n]//g;
+
+ return $val;
+}
+
+my $state = 0;
+my $val_n = "";
+my $val_e = "";
+my $val_p = "";
+my $val_q = "";
+my $mod = 0;
+my $cnt = 1;
+while (my $line = <TEST_DATA>)
+{
+ next if ($line !~ /^# Example/);
+
+ ( $mod ) = ($line =~ /A (\d+)/);
+ $val_n = get_val("RSA modulus n", "N");
+ $val_e = get_val("RSA public exponent e", "E");
+ $val_p = get_val("Prime p", "P");
+ $val_q = get_val("Prime q", "Q");
+
+ for(my $i = 1; $i <= 6; $i++)
+ {
+ my $val_m = get_val("Message to be", "M");
+ my $val_salt = get_val("Salt", "Salt");
+ my $val_sig = get_val("Signature", "Sig");
+
+ print("RSASSA-PSS Signature Example ${cnt}_${i}\n");
+ print("pkcs1_rsassa_pss_sign:$mod:16:\"$val_p\":16:\"$val_q\":16:\"$val_n\":16:\"$val_e\":SIG_RSA_SHA1:MBEDTLS_MD_SHA1");
+ print(":\"$val_m\"");
+ print(":\"$val_salt\"");
+ print(":\"$val_sig\":0");
+ print("\n\n");
+
+ print("RSASSA-PSS Signature Example ${cnt}_${i} (verify)\n");
+ print("pkcs1_rsassa_pss_verify:$mod:16:\"$val_n\":16:\"$val_e\":SIG_RSA_SHA1:MBEDTLS_MD_SHA1");
+ print(":\"$val_m\"");
+ print(":\"$val_salt\"");
+ print(":\"$val_sig\":0");
+ print("\n\n");
+ }
+ $cnt++;
+}
+close(TEST_DATA);
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate-afl-tests.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate-afl-tests.sh
new file mode 100755
index 000000000..cbc2f5906
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate-afl-tests.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+# This script splits the data test files containing the test cases into
+# individual files (one test case per file) suitable for use with afl
+# (American Fuzzy Lop). http://lcamtuf.coredump.cx/afl/
+#
+# Usage: generate-afl-tests.sh <test data file path>
+# <test data file path> - should be the path to one of the test suite files
+# such as 'test_suite_mpi.data'
+
+# Abort on errors
+set -e
+
+if [ -z $1 ]
+then
+ echo " [!] No test file specified" >&2
+ echo "Usage: $0 <test data file>" >&2
+ exit 1
+fi
+
+SRC_FILEPATH=$(dirname $1)/$(basename $1)
+TESTSUITE=$(basename $1 .data)
+
+THIS_DIR=$(basename $PWD)
+
+if [ -d ../library -a -d ../include -a -d ../tests -a $THIS_DIR == "tests" ];
+then :;
+else
+ echo " [!] Must be run from mbed TLS tests directory" >&2
+ exit 1
+fi
+
+DEST_TESTCASE_DIR=$TESTSUITE-afl-tests
+DEST_OUTPUT_DIR=$TESTSUITE-afl-out
+
+echo " [+] Creating output directories" >&2
+
+if [ -e $DEST_OUTPUT_DIR/* ];
+then :
+ echo " [!] Test output files already exist." >&2
+ exit 1
+else
+ mkdir -p $DEST_OUTPUT_DIR
+fi
+
+if [ -e $DEST_TESTCASE_DIR/* ];
+then :
+ echo " [!] Test output files already exist." >&2
+else
+ mkdir -p $DEST_TESTCASE_DIR
+fi
+
+echo " [+] Creating test cases" >&2
+cd $DEST_TESTCASE_DIR
+
+split -p '^\s*$' ../$SRC_FILEPATH
+
+for f in *;
+do
+ # Strip out any blank lines (no trim on OS X)
+ sed '/^\s*$/d' $f >testcase_$f
+ rm $f
+done
+
+cd ..
+
+echo " [+] Test cases in $DEST_TESTCASE_DIR" >&2
+
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate_test_code.py b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate_test_code.py
new file mode 100755
index 000000000..1fff09992
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/generate_test_code.py
@@ -0,0 +1,1152 @@
+#!/usr/bin/env python3
+# Test suites code generator.
+#
+# Copyright (C) 2018, Arm Limited, All Rights Reserved
+# 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.
+#
+# This file is part of Mbed TLS (https://tls.mbed.org)
+
+"""
+This script is a key part of Mbed TLS test suites framework. For
+understanding the script it is important to understand the
+framework. This doc string contains a summary of the framework
+and explains the function of this script.
+
+Mbed TLS test suites:
+=====================
+Scope:
+------
+The test suites focus on unit testing the crypto primitives and also
+include x509 parser tests. Tests can be added to test any Mbed TLS
+module. However, the framework is not capable of testing SSL
+protocol, since that requires full stack execution and that is best
+tested as part of the system test.
+
+Test case definition:
+---------------------
+Tests are defined in a test_suite_<module>[.<optional sub module>].data
+file. A test definition contains:
+ test name
+ optional build macro dependencies
+ test function
+ test parameters
+
+Test dependencies are build macros that can be specified to indicate
+the build config in which the test is valid. For example if a test
+depends on a feature that is only enabled by defining a macro. Then
+that macro should be specified as a dependency of the test.
+
+Test function is the function that implements the test steps. This
+function is specified for different tests that perform same steps
+with different parameters.
+
+Test parameters are specified in string form separated by ':'.
+Parameters can be of type string, binary data specified as hex
+string and integer constants specified as integer, macro or
+as an expression. Following is an example test definition:
+
+ AES 128 GCM Encrypt and decrypt 8 bytes
+ depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+ enc_dec_buf:MBEDTLS_CIPHER_AES_128_GCM:"AES-128-GCM":128:8:-1
+
+Test functions:
+---------------
+Test functions are coded in C in test_suite_<module>.function files.
+Functions file is itself not compilable and contains special
+format patterns to specify test suite dependencies, start and end
+of functions and function dependencies. Check any existing functions
+file for example.
+
+Execution:
+----------
+Tests are executed in 3 steps:
+- Generating test_suite_<module>[.<optional sub module>].c file
+ for each corresponding .data file.
+- Building each source file into executables.
+- Running each executable and printing report.
+
+Generating C test source requires more than just the test functions.
+Following extras are required:
+- Process main()
+- Reading .data file and dispatching test cases.
+- Platform specific test case execution
+- Dependency checking
+- Integer expression evaluation
+- Test function dispatch
+
+Build dependencies and integer expressions (in the test parameters)
+are specified as strings in the .data file. Their run time value is
+not known at the generation stage. Hence, they need to be translated
+into run time evaluations. This script generates the run time checks
+for dependencies and integer expressions.
+
+Similarly, function names have to be translated into function calls.
+This script also generates code for function dispatch.
+
+The extra code mentioned here is either generated by this script
+or it comes from the input files: helpers file, platform file and
+the template file.
+
+Helper file:
+------------
+Helpers file contains common helper/utility functions and data.
+
+Platform file:
+--------------
+Platform file contains platform specific setup code and test case
+dispatch code. For example, host_test.function reads test data
+file from host's file system and dispatches tests.
+In case of on-target target_test.function tests are not dispatched
+on target. Target code is kept minimum and only test functions are
+dispatched. Test case dispatch is done on the host using tools like
+Greentea.
+
+Template file:
+---------
+Template file for example main_test.function is a template C file in
+which generated code and code from input files is substituted to
+generate a compilable C file. It also contains skeleton functions for
+dependency checks, expression evaluation and function dispatch. These
+functions are populated with checks and return codes by this script.
+
+Template file contains "replacement" fields that are formatted
+strings processed by Python string.Template.substitute() method.
+
+This script:
+============
+Core function of this script is to fill the template file with
+code that is generated or read from helpers and platform files.
+
+This script replaces following fields in the template and generates
+the test source file:
+
+$test_common_helpers <-- All common code from helpers.function
+ is substituted here.
+$functions_code <-- Test functions are substituted here
+ from the input test_suit_xyz.function
+ file. C preprocessor checks are generated
+ for the build dependencies specified
+ in the input file. This script also
+ generates wrappers for the test
+ functions with code to expand the
+ string parameters read from the data
+ file.
+$expression_code <-- This script enumerates the
+ expressions in the .data file and
+ generates code to handle enumerated
+ expression Ids and return the values.
+$dep_check_code <-- This script enumerates all
+ build dependencies and generate
+ code to handle enumerated build
+ dependency Id and return status: if
+ the dependency is defined or not.
+$dispatch_code <-- This script enumerates the functions
+ specified in the input test data file
+ and generates the initializer for the
+ function table in the template
+ file.
+$platform_code <-- Platform specific setup and test
+ dispatch code.
+
+"""
+
+
+import io
+import os
+import re
+import sys
+import string
+import argparse
+
+
+BEGIN_HEADER_REGEX = r'/\*\s*BEGIN_HEADER\s*\*/'
+END_HEADER_REGEX = r'/\*\s*END_HEADER\s*\*/'
+
+BEGIN_SUITE_HELPERS_REGEX = r'/\*\s*BEGIN_SUITE_HELPERS\s*\*/'
+END_SUITE_HELPERS_REGEX = r'/\*\s*END_SUITE_HELPERS\s*\*/'
+
+BEGIN_DEP_REGEX = r'BEGIN_DEPENDENCIES'
+END_DEP_REGEX = r'END_DEPENDENCIES'
+
+BEGIN_CASE_REGEX = r'/\*\s*BEGIN_CASE\s*(?P<depends_on>.*?)\s*\*/'
+END_CASE_REGEX = r'/\*\s*END_CASE\s*\*/'
+
+DEPENDENCY_REGEX = r'depends_on:(?P<dependencies>.*)'
+C_IDENTIFIER_REGEX = r'!?[a-z_][a-z0-9_]*'
+CONDITION_OPERATOR_REGEX = r'[!=]=|[<>]=?'
+# forbid 0ddd which might be accidentally octal or accidentally decimal
+CONDITION_VALUE_REGEX = r'[-+]?(0x[0-9a-f]+|0|[1-9][0-9]*)'
+CONDITION_REGEX = r'({})(?:\s*({})\s*({}))?$'.format(C_IDENTIFIER_REGEX,
+ CONDITION_OPERATOR_REGEX,
+ CONDITION_VALUE_REGEX)
+TEST_FUNCTION_VALIDATION_REGEX = r'\s*void\s+(?P<func_name>\w+)\s*\('
+INT_CHECK_REGEX = r'int\s+.*'
+CHAR_CHECK_REGEX = r'char\s*\*\s*.*'
+DATA_T_CHECK_REGEX = r'data_t\s*\*\s*.*'
+FUNCTION_ARG_LIST_END_REGEX = r'.*\)'
+EXIT_LABEL_REGEX = r'^exit:'
+
+
+class GeneratorInputError(Exception):
+ """
+ Exception to indicate error in the input files to this script.
+ This includes missing patterns, test function names and other
+ parsing errors.
+ """
+ pass
+
+
+class FileWrapper(io.FileIO, object):
+ """
+ This class extends built-in io.FileIO class with attribute line_no,
+ that indicates line number for the line that is read.
+ """
+
+ def __init__(self, file_name):
+ """
+ Instantiate the base class and initialize the line number to 0.
+
+ :param file_name: File path to open.
+ """
+ super(FileWrapper, self).__init__(file_name, 'r')
+ self._line_no = 0
+
+ def next(self):
+ """
+ Python 2 iterator method. This method overrides base class's
+ next method and extends the next method to count the line
+ numbers as each line is read.
+
+ It works for both Python 2 and Python 3 by checking iterator
+ method name in the base iterator object.
+
+ :return: Line read from file.
+ """
+ parent = super(FileWrapper, self)
+ if hasattr(parent, '__next__'):
+ line = parent.__next__() # Python 3
+ else:
+ line = parent.next() # Python 2 # pylint: disable=no-member
+ if line is not None:
+ self._line_no += 1
+ # Convert byte array to string with correct encoding and
+ # strip any whitespaces added in the decoding process.
+ return line.decode(sys.getdefaultencoding()).rstrip() + '\n'
+ return None
+
+ # Python 3 iterator method
+ __next__ = next
+
+ def get_line_no(self):
+ """
+ Gives current line number.
+ """
+ return self._line_no
+
+ line_no = property(get_line_no)
+
+
+def split_dep(dep):
+ """
+ Split NOT character '!' from dependency. Used by gen_dependencies()
+
+ :param dep: Dependency list
+ :return: string tuple. Ex: ('!', MACRO) for !MACRO and ('', MACRO) for
+ MACRO.
+ """
+ return ('!', dep[1:]) if dep[0] == '!' else ('', dep)
+
+
+def gen_dependencies(dependencies):
+ """
+ Test suite data and functions specifies compile time dependencies.
+ This function generates C preprocessor code from the input
+ dependency list. Caller uses the generated preprocessor code to
+ wrap dependent code.
+ A dependency in the input list can have a leading '!' character
+ to negate a condition. '!' is separated from the dependency using
+ function split_dep() and proper preprocessor check is generated
+ accordingly.
+
+ :param dependencies: List of dependencies.
+ :return: if defined and endif code with macro annotations for
+ readability.
+ """
+ dep_start = ''.join(['#if %sdefined(%s)\n' % (x, y) for x, y in
+ map(split_dep, dependencies)])
+ dep_end = ''.join(['#endif /* %s */\n' %
+ x for x in reversed(dependencies)])
+
+ return dep_start, dep_end
+
+
+def gen_dependencies_one_line(dependencies):
+ """
+ Similar to gen_dependencies() but generates dependency checks in one line.
+ Useful for generating code with #else block.
+
+ :param dependencies: List of dependencies.
+ :return: Preprocessor check code
+ """
+ defines = '#if ' if dependencies else ''
+ defines += ' && '.join(['%sdefined(%s)' % (x, y) for x, y in map(
+ split_dep, dependencies)])
+ return defines
+
+
+def gen_function_wrapper(name, local_vars, args_dispatch):
+ """
+ Creates test function wrapper code. A wrapper has the code to
+ unpack parameters from parameters[] array.
+
+ :param name: Test function name
+ :param local_vars: Local variables declaration code
+ :param args_dispatch: List of dispatch arguments.
+ Ex: ['(char *)params[0]', '*((int *)params[1])']
+ :return: Test function wrapper.
+ """
+ # Then create the wrapper
+ wrapper = '''
+void {name}_wrapper( void ** params )
+{{
+{unused_params}{locals}
+ {name}( {args} );
+}}
+'''.format(name=name,
+ unused_params='' if args_dispatch else ' (void)params;\n',
+ args=', '.join(args_dispatch),
+ locals=local_vars)
+ return wrapper
+
+
+def gen_dispatch(name, dependencies):
+ """
+ Test suite code template main_test.function defines a C function
+ array to contain test case functions. This function generates an
+ initializer entry for a function in that array. The entry is
+ composed of a compile time check for the test function
+ dependencies. At compile time the test function is assigned when
+ dependencies are met, else NULL is assigned.
+
+ :param name: Test function name
+ :param dependencies: List of dependencies
+ :return: Dispatch code.
+ """
+ if dependencies:
+ preprocessor_check = gen_dependencies_one_line(dependencies)
+ dispatch_code = '''
+{preprocessor_check}
+ {name}_wrapper,
+#else
+ NULL,
+#endif
+'''.format(preprocessor_check=preprocessor_check, name=name)
+ else:
+ dispatch_code = '''
+ {name}_wrapper,
+'''.format(name=name)
+
+ return dispatch_code
+
+
+def parse_until_pattern(funcs_f, end_regex):
+ """
+ Matches pattern end_regex to the lines read from the file object.
+ Returns the lines read until end pattern is matched.
+
+ :param funcs_f: file object for .function file
+ :param end_regex: Pattern to stop parsing
+ :return: Lines read before the end pattern
+ """
+ headers = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
+ for line in funcs_f:
+ if re.search(end_regex, line):
+ break
+ headers += line
+ else:
+ raise GeneratorInputError("file: %s - end pattern [%s] not found!" %
+ (funcs_f.name, end_regex))
+
+ return headers
+
+
+def validate_dependency(dependency):
+ """
+ Validates a C macro and raises GeneratorInputError on invalid input.
+ :param dependency: Input macro dependency
+ :return: input dependency stripped of leading & trailing white spaces.
+ """
+ dependency = dependency.strip()
+ if not re.match(CONDITION_REGEX, dependency, re.I):
+ raise GeneratorInputError('Invalid dependency %s' % dependency)
+ return dependency
+
+
+def parse_dependencies(inp_str):
+ """
+ Parses dependencies out of inp_str, validates them and returns a
+ list of macros.
+
+ :param inp_str: Input string with macros delimited by ':'.
+ :return: list of dependencies
+ """
+ dependencies = [dep for dep in map(validate_dependency,
+ inp_str.split(':'))]
+ return dependencies
+
+
+def parse_suite_dependencies(funcs_f):
+ """
+ Parses test suite dependencies specified at the top of a
+ .function file, that starts with pattern BEGIN_DEPENDENCIES
+ and end with END_DEPENDENCIES. Dependencies are specified
+ after pattern 'depends_on:' and are delimited by ':'.
+
+ :param funcs_f: file object for .function file
+ :return: List of test suite dependencies.
+ """
+ dependencies = []
+ for line in funcs_f:
+ match = re.search(DEPENDENCY_REGEX, line.strip())
+ if match:
+ try:
+ dependencies = parse_dependencies(match.group('dependencies'))
+ except GeneratorInputError as error:
+ raise GeneratorInputError(
+ str(error) + " - %s:%d" % (funcs_f.name, funcs_f.line_no))
+ if re.search(END_DEP_REGEX, line):
+ break
+ else:
+ raise GeneratorInputError("file: %s - end dependency pattern [%s]"
+ " not found!" % (funcs_f.name,
+ END_DEP_REGEX))
+
+ return dependencies
+
+
+def parse_function_dependencies(line):
+ """
+ Parses function dependencies, that are in the same line as
+ comment BEGIN_CASE. Dependencies are specified after pattern
+ 'depends_on:' and are delimited by ':'.
+
+ :param line: Line from .function file that has dependencies.
+ :return: List of dependencies.
+ """
+ dependencies = []
+ match = re.search(BEGIN_CASE_REGEX, line)
+ dep_str = match.group('depends_on')
+ if dep_str:
+ match = re.search(DEPENDENCY_REGEX, dep_str)
+ if match:
+ dependencies += parse_dependencies(match.group('dependencies'))
+
+ return dependencies
+
+
+def parse_function_arguments(line):
+ """
+ Parses test function signature for validation and generates
+ a dispatch wrapper function that translates input test vectors
+ read from the data file into test function arguments.
+
+ :param line: Line from .function file that has a function
+ signature.
+ :return: argument list, local variables for
+ wrapper function and argument dispatch code.
+ """
+ args = []
+ local_vars = ''
+ args_dispatch = []
+ arg_idx = 0
+ # Remove characters before arguments
+ line = line[line.find('(') + 1:]
+ # Process arguments, ex: <type> arg1, <type> arg2 )
+ # This script assumes that the argument list is terminated by ')'
+ # i.e. the test functions will not have a function pointer
+ # argument.
+ for arg in line[:line.find(')')].split(','):
+ arg = arg.strip()
+ if arg == '':
+ continue
+ if re.search(INT_CHECK_REGEX, arg.strip()):
+ args.append('int')
+ args_dispatch.append('*( (int *) params[%d] )' % arg_idx)
+ elif re.search(CHAR_CHECK_REGEX, arg.strip()):
+ args.append('char*')
+ args_dispatch.append('(char *) params[%d]' % arg_idx)
+ elif re.search(DATA_T_CHECK_REGEX, arg.strip()):
+ args.append('hex')
+ # create a structure
+ pointer_initializer = '(uint8_t *) params[%d]' % arg_idx
+ len_initializer = '*( (uint32_t *) params[%d] )' % (arg_idx+1)
+ local_vars += """ data_t data%d = {%s, %s};
+""" % (arg_idx, pointer_initializer, len_initializer)
+
+ args_dispatch.append('&data%d' % arg_idx)
+ arg_idx += 1
+ else:
+ raise ValueError("Test function arguments can only be 'int', "
+ "'char *' or 'data_t'\n%s" % line)
+ arg_idx += 1
+
+ return args, local_vars, args_dispatch
+
+
+def generate_function_code(name, code, local_vars, args_dispatch,
+ dependencies):
+ """
+ Generate function code with preprocessor checks and parameter dispatch
+ wrapper.
+
+ :param name: Function name
+ :param code: Function code
+ :param local_vars: Local variables for function wrapper
+ :param args_dispatch: Argument dispatch code
+ :param dependencies: Preprocessor dependencies list
+ :return: Final function code
+ """
+ # Add exit label if not present
+ if code.find('exit:') == -1:
+ split_code = code.rsplit('}', 1)
+ if len(split_code) == 2:
+ code = """exit:
+ ;
+}""".join(split_code)
+
+ code += gen_function_wrapper(name, local_vars, args_dispatch)
+ preprocessor_check_start, preprocessor_check_end = \
+ gen_dependencies(dependencies)
+ return preprocessor_check_start + code + preprocessor_check_end
+
+
+def parse_function_code(funcs_f, dependencies, suite_dependencies):
+ """
+ Parses out a function from function file object and generates
+ function and dispatch code.
+
+ :param funcs_f: file object of the functions file.
+ :param dependencies: List of dependencies
+ :param suite_dependencies: List of test suite dependencies
+ :return: Function name, arguments, function code and dispatch code.
+ """
+ line_directive = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
+ code = ''
+ has_exit_label = False
+ for line in funcs_f:
+ # Check function signature. Function signature may be split
+ # across multiple lines. Here we try to find the start of
+ # arguments list, then remove '\n's and apply the regex to
+ # detect function start.
+ up_to_arg_list_start = code + line[:line.find('(') + 1]
+ match = re.match(TEST_FUNCTION_VALIDATION_REGEX,
+ up_to_arg_list_start.replace('\n', ' '), re.I)
+ if match:
+ # check if we have full signature i.e. split in more lines
+ name = match.group('func_name')
+ if not re.match(FUNCTION_ARG_LIST_END_REGEX, line):
+ for lin in funcs_f:
+ line += lin
+ if re.search(FUNCTION_ARG_LIST_END_REGEX, line):
+ break
+ args, local_vars, args_dispatch = parse_function_arguments(
+ line)
+ code += line
+ break
+ code += line
+ else:
+ raise GeneratorInputError("file: %s - Test functions not found!" %
+ funcs_f.name)
+
+ # Prefix test function name with 'test_'
+ code = code.replace(name, 'test_' + name, 1)
+ name = 'test_' + name
+
+ for line in funcs_f:
+ if re.search(END_CASE_REGEX, line):
+ break
+ if not has_exit_label:
+ has_exit_label = \
+ re.search(EXIT_LABEL_REGEX, line.strip()) is not None
+ code += line
+ else:
+ raise GeneratorInputError("file: %s - end case pattern [%s] not "
+ "found!" % (funcs_f.name, END_CASE_REGEX))
+
+ code = line_directive + code
+ code = generate_function_code(name, code, local_vars, args_dispatch,
+ dependencies)
+ dispatch_code = gen_dispatch(name, suite_dependencies + dependencies)
+ return (name, args, code, dispatch_code)
+
+
+def parse_functions(funcs_f):
+ """
+ Parses a test_suite_xxx.function file and returns information
+ for generating a C source file for the test suite.
+
+ :param funcs_f: file object of the functions file.
+ :return: List of test suite dependencies, test function dispatch
+ code, function code and a dict with function identifiers
+ and arguments info.
+ """
+ suite_helpers = ''
+ suite_dependencies = []
+ suite_functions = ''
+ func_info = {}
+ function_idx = 0
+ dispatch_code = ''
+ for line in funcs_f:
+ if re.search(BEGIN_HEADER_REGEX, line):
+ suite_helpers += parse_until_pattern(funcs_f, END_HEADER_REGEX)
+ elif re.search(BEGIN_SUITE_HELPERS_REGEX, line):
+ suite_helpers += parse_until_pattern(funcs_f,
+ END_SUITE_HELPERS_REGEX)
+ elif re.search(BEGIN_DEP_REGEX, line):
+ suite_dependencies += parse_suite_dependencies(funcs_f)
+ elif re.search(BEGIN_CASE_REGEX, line):
+ try:
+ dependencies = parse_function_dependencies(line)
+ except GeneratorInputError as error:
+ raise GeneratorInputError(
+ "%s:%d: %s" % (funcs_f.name, funcs_f.line_no,
+ str(error)))
+ func_name, args, func_code, func_dispatch =\
+ parse_function_code(funcs_f, dependencies, suite_dependencies)
+ suite_functions += func_code
+ # Generate dispatch code and enumeration info
+ if func_name in func_info:
+ raise GeneratorInputError(
+ "file: %s - function %s re-declared at line %d" %
+ (funcs_f.name, func_name, funcs_f.line_no))
+ func_info[func_name] = (function_idx, args)
+ dispatch_code += '/* Function Id: %d */\n' % function_idx
+ dispatch_code += func_dispatch
+ function_idx += 1
+
+ func_code = (suite_helpers +
+ suite_functions).join(gen_dependencies(suite_dependencies))
+ return suite_dependencies, dispatch_code, func_code, func_info
+
+
+def escaped_split(inp_str, split_char):
+ """
+ Split inp_str on character split_char but ignore if escaped.
+ Since, return value is used to write back to the intermediate
+ data file, any escape characters in the input are retained in the
+ output.
+
+ :param inp_str: String to split
+ :param split_char: Split character
+ :return: List of splits
+ """
+ if len(split_char) > 1:
+ raise ValueError('Expected split character. Found string!')
+ out = re.sub(r'(\\.)|' + split_char,
+ lambda m: m.group(1) or '\n', inp_str,
+ len(inp_str)).split('\n')
+ out = [x for x in out if x]
+ return out
+
+
+def parse_test_data(data_f):
+ """
+ Parses .data file for each test case name, test function name,
+ test dependencies and test arguments. This information is
+ correlated with the test functions file for generating an
+ intermediate data file replacing the strings for test function
+ names, dependencies and integer constant expressions with
+ identifiers. Mainly for optimising space for on-target
+ execution.
+
+ :param data_f: file object of the data file.
+ :return: Generator that yields test name, function name,
+ dependency list and function argument list.
+ """
+ __state_read_name = 0
+ __state_read_args = 1
+ state = __state_read_name
+ dependencies = []
+ name = ''
+ for line in data_f:
+ line = line.strip()
+ # Skip comments
+ if line.startswith('#'):
+ continue
+
+ # Blank line indicates end of test
+ if not line:
+ if state == __state_read_args:
+ raise GeneratorInputError("[%s:%d] Newline before arguments. "
+ "Test function and arguments "
+ "missing for %s" %
+ (data_f.name, data_f.line_no, name))
+ continue
+
+ if state == __state_read_name:
+ # Read test name
+ name = line
+ state = __state_read_args
+ elif state == __state_read_args:
+ # Check dependencies
+ match = re.search(DEPENDENCY_REGEX, line)
+ if match:
+ try:
+ dependencies = parse_dependencies(
+ match.group('dependencies'))
+ except GeneratorInputError as error:
+ raise GeneratorInputError(
+ str(error) + " - %s:%d" %
+ (data_f.name, data_f.line_no))
+ else:
+ # Read test vectors
+ parts = escaped_split(line, ':')
+ test_function = parts[0]
+ args = parts[1:]
+ yield name, test_function, dependencies, args
+ dependencies = []
+ state = __state_read_name
+ if state == __state_read_args:
+ raise GeneratorInputError("[%s:%d] Newline before arguments. "
+ "Test function and arguments missing for "
+ "%s" % (data_f.name, data_f.line_no, name))
+
+
+def gen_dep_check(dep_id, dep):
+ """
+ Generate code for checking dependency with the associated
+ identifier.
+
+ :param dep_id: Dependency identifier
+ :param dep: Dependency macro
+ :return: Dependency check code
+ """
+ if dep_id < 0:
+ raise GeneratorInputError("Dependency Id should be a positive "
+ "integer.")
+ _not, dep = ('!', dep[1:]) if dep[0] == '!' else ('', dep)
+ if not dep:
+ raise GeneratorInputError("Dependency should not be an empty string.")
+
+ dependency = re.match(CONDITION_REGEX, dep, re.I)
+ if not dependency:
+ raise GeneratorInputError('Invalid dependency %s' % dep)
+
+ _defined = '' if dependency.group(2) else 'defined'
+ _cond = dependency.group(2) if dependency.group(2) else ''
+ _value = dependency.group(3) if dependency.group(3) else ''
+
+ dep_check = '''
+ case {id}:
+ {{
+#if {_not}{_defined}({macro}{_cond}{_value})
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }}
+ break;'''.format(_not=_not, _defined=_defined,
+ macro=dependency.group(1), id=dep_id,
+ _cond=_cond, _value=_value)
+ return dep_check
+
+
+def gen_expression_check(exp_id, exp):
+ """
+ Generates code for evaluating an integer expression using
+ associated expression Id.
+
+ :param exp_id: Expression Identifier
+ :param exp: Expression/Macro
+ :return: Expression check code
+ """
+ if exp_id < 0:
+ raise GeneratorInputError("Expression Id should be a positive "
+ "integer.")
+ if not exp:
+ raise GeneratorInputError("Expression should not be an empty string.")
+ exp_code = '''
+ case {exp_id}:
+ {{
+ *out_value = {expression};
+ }}
+ break;'''.format(exp_id=exp_id, expression=exp)
+ return exp_code
+
+
+def write_dependencies(out_data_f, test_dependencies, unique_dependencies):
+ """
+ Write dependencies to intermediate test data file, replacing
+ the string form with identifiers. Also, generates dependency
+ check code.
+
+ :param out_data_f: Output intermediate data file
+ :param test_dependencies: Dependencies
+ :param unique_dependencies: Mutable list to track unique dependencies
+ that are global to this re-entrant function.
+ :return: returns dependency check code.
+ """
+ dep_check_code = ''
+ if test_dependencies:
+ out_data_f.write('depends_on')
+ for dep in test_dependencies:
+ if dep not in unique_dependencies:
+ unique_dependencies.append(dep)
+ dep_id = unique_dependencies.index(dep)
+ dep_check_code += gen_dep_check(dep_id, dep)
+ else:
+ dep_id = unique_dependencies.index(dep)
+ out_data_f.write(':' + str(dep_id))
+ out_data_f.write('\n')
+ return dep_check_code
+
+
+def write_parameters(out_data_f, test_args, func_args, unique_expressions):
+ """
+ Writes test parameters to the intermediate data file, replacing
+ the string form with identifiers. Also, generates expression
+ check code.
+
+ :param out_data_f: Output intermediate data file
+ :param test_args: Test parameters
+ :param func_args: Function arguments
+ :param unique_expressions: Mutable list to track unique
+ expressions that are global to this re-entrant function.
+ :return: Returns expression check code.
+ """
+ expression_code = ''
+ for i, _ in enumerate(test_args):
+ typ = func_args[i]
+ val = test_args[i]
+
+ # check if val is a non literal int val (i.e. an expression)
+ if typ == 'int' and not re.match(r'(\d+|0x[0-9a-f]+)$',
+ val, re.I):
+ typ = 'exp'
+ if val not in unique_expressions:
+ unique_expressions.append(val)
+ # exp_id can be derived from len(). But for
+ # readability and consistency with case of existing
+ # let's use index().
+ exp_id = unique_expressions.index(val)
+ expression_code += gen_expression_check(exp_id, val)
+ val = exp_id
+ else:
+ val = unique_expressions.index(val)
+ out_data_f.write(':' + typ + ':' + str(val))
+ out_data_f.write('\n')
+ return expression_code
+
+
+def gen_suite_dep_checks(suite_dependencies, dep_check_code, expression_code):
+ """
+ Generates preprocessor checks for test suite dependencies.
+
+ :param suite_dependencies: Test suite dependencies read from the
+ .function file.
+ :param dep_check_code: Dependency check code
+ :param expression_code: Expression check code
+ :return: Dependency and expression code guarded by test suite
+ dependencies.
+ """
+ if suite_dependencies:
+ preprocessor_check = gen_dependencies_one_line(suite_dependencies)
+ dep_check_code = '''
+{preprocessor_check}
+{code}
+#endif
+'''.format(preprocessor_check=preprocessor_check, code=dep_check_code)
+ expression_code = '''
+{preprocessor_check}
+{code}
+#endif
+'''.format(preprocessor_check=preprocessor_check, code=expression_code)
+ return dep_check_code, expression_code
+
+
+def gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies):
+ """
+ This function reads test case name, dependencies and test vectors
+ from the .data file. This information is correlated with the test
+ functions file for generating an intermediate data file replacing
+ the strings for test function names, dependencies and integer
+ constant expressions with identifiers. Mainly for optimising
+ space for on-target execution.
+ It also generates test case dependency check code and expression
+ evaluation code.
+
+ :param data_f: Data file object
+ :param out_data_f: Output intermediate data file
+ :param func_info: Dict keyed by function and with function id
+ and arguments info
+ :param suite_dependencies: Test suite dependencies
+ :return: Returns dependency and expression check code
+ """
+ unique_dependencies = []
+ unique_expressions = []
+ dep_check_code = ''
+ expression_code = ''
+ for test_name, function_name, test_dependencies, test_args in \
+ parse_test_data(data_f):
+ out_data_f.write(test_name + '\n')
+
+ # Write dependencies
+ dep_check_code += write_dependencies(out_data_f, test_dependencies,
+ unique_dependencies)
+
+ # Write test function name
+ test_function_name = 'test_' + function_name
+ if test_function_name not in func_info:
+ raise GeneratorInputError("Function %s not found!" %
+ test_function_name)
+ func_id, func_args = func_info[test_function_name]
+ out_data_f.write(str(func_id))
+
+ # Write parameters
+ if len(test_args) != len(func_args):
+ raise GeneratorInputError("Invalid number of arguments in test "
+ "%s. See function %s signature." %
+ (test_name, function_name))
+ expression_code += write_parameters(out_data_f, test_args, func_args,
+ unique_expressions)
+
+ # Write a newline as test case separator
+ out_data_f.write('\n')
+
+ dep_check_code, expression_code = gen_suite_dep_checks(
+ suite_dependencies, dep_check_code, expression_code)
+ return dep_check_code, expression_code
+
+
+def add_input_info(funcs_file, data_file, template_file,
+ c_file, snippets):
+ """
+ Add generator input info in snippets.
+
+ :param funcs_file: Functions file object
+ :param data_file: Data file object
+ :param template_file: Template file object
+ :param c_file: Output C file object
+ :param snippets: Dictionary to contain code pieces to be
+ substituted in the template.
+ :return:
+ """
+ snippets['test_file'] = c_file
+ snippets['test_main_file'] = template_file
+ snippets['test_case_file'] = funcs_file
+ snippets['test_case_data_file'] = data_file
+
+
+def read_code_from_input_files(platform_file, helpers_file,
+ out_data_file, snippets):
+ """
+ Read code from input files and create substitutions for replacement
+ strings in the template file.
+
+ :param platform_file: Platform file object
+ :param helpers_file: Helper functions file object
+ :param out_data_file: Output intermediate data file object
+ :param snippets: Dictionary to contain code pieces to be
+ substituted in the template.
+ :return:
+ """
+ # Read helpers
+ with open(helpers_file, 'r') as help_f, open(platform_file, 'r') as \
+ platform_f:
+ snippets['test_common_helper_file'] = helpers_file
+ snippets['test_common_helpers'] = help_f.read()
+ snippets['test_platform_file'] = platform_file
+ snippets['platform_code'] = platform_f.read().replace(
+ 'DATA_FILE', out_data_file.replace('\\', '\\\\')) # escape '\'
+
+
+def write_test_source_file(template_file, c_file, snippets):
+ """
+ Write output source file with generated source code.
+
+ :param template_file: Template file name
+ :param c_file: Output source file
+ :param snippets: Generated and code snippets
+ :return:
+ """
+ with open(template_file, 'r') as template_f, open(c_file, 'w') as c_f:
+ for line_no, line in enumerate(template_f.readlines(), 1):
+ # Update line number. +1 as #line directive sets next line number
+ snippets['line_no'] = line_no + 1
+ code = string.Template(line).substitute(**snippets)
+ c_f.write(code)
+
+
+def parse_function_file(funcs_file, snippets):
+ """
+ Parse function file and generate function dispatch code.
+
+ :param funcs_file: Functions file name
+ :param snippets: Dictionary to contain code pieces to be
+ substituted in the template.
+ :return:
+ """
+ with FileWrapper(funcs_file) as funcs_f:
+ suite_dependencies, dispatch_code, func_code, func_info = \
+ parse_functions(funcs_f)
+ snippets['functions_code'] = func_code
+ snippets['dispatch_code'] = dispatch_code
+ return suite_dependencies, func_info
+
+
+def generate_intermediate_data_file(data_file, out_data_file,
+ suite_dependencies, func_info, snippets):
+ """
+ Generates intermediate data file from input data file and
+ information read from functions file.
+
+ :param data_file: Data file name
+ :param out_data_file: Output/Intermediate data file
+ :param suite_dependencies: List of suite dependencies.
+ :param func_info: Function info parsed from functions file.
+ :param snippets: Dictionary to contain code pieces to be
+ substituted in the template.
+ :return:
+ """
+ with FileWrapper(data_file) as data_f, \
+ open(out_data_file, 'w') as out_data_f:
+ dep_check_code, expression_code = gen_from_test_data(
+ data_f, out_data_f, func_info, suite_dependencies)
+ snippets['dep_check_code'] = dep_check_code
+ snippets['expression_code'] = expression_code
+
+
+def generate_code(**input_info):
+ """
+ Generates C source code from test suite file, data file, common
+ helpers file and platform file.
+
+ input_info expands to following parameters:
+ funcs_file: Functions file object
+ data_file: Data file object
+ template_file: Template file object
+ platform_file: Platform file object
+ helpers_file: Helper functions file object
+ suites_dir: Test suites dir
+ c_file: Output C file object
+ out_data_file: Output intermediate data file object
+ :return:
+ """
+ funcs_file = input_info['funcs_file']
+ data_file = input_info['data_file']
+ template_file = input_info['template_file']
+ platform_file = input_info['platform_file']
+ helpers_file = input_info['helpers_file']
+ suites_dir = input_info['suites_dir']
+ c_file = input_info['c_file']
+ out_data_file = input_info['out_data_file']
+ for name, path in [('Functions file', funcs_file),
+ ('Data file', data_file),
+ ('Template file', template_file),
+ ('Platform file', platform_file),
+ ('Helpers code file', helpers_file),
+ ('Suites dir', suites_dir)]:
+ if not os.path.exists(path):
+ raise IOError("ERROR: %s [%s] not found!" % (name, path))
+
+ snippets = {'generator_script': os.path.basename(__file__)}
+ read_code_from_input_files(platform_file, helpers_file,
+ out_data_file, snippets)
+ add_input_info(funcs_file, data_file, template_file,
+ c_file, snippets)
+ suite_dependencies, func_info = parse_function_file(funcs_file, snippets)
+ generate_intermediate_data_file(data_file, out_data_file,
+ suite_dependencies, func_info, snippets)
+ write_test_source_file(template_file, c_file, snippets)
+
+
+def main():
+ """
+ Command line parser.
+
+ :return:
+ """
+ parser = argparse.ArgumentParser(
+ description='Dynamically generate test suite code.')
+
+ parser.add_argument("-f", "--functions-file",
+ dest="funcs_file",
+ help="Functions file",
+ metavar="FUNCTIONS_FILE",
+ required=True)
+
+ parser.add_argument("-d", "--data-file",
+ dest="data_file",
+ help="Data file",
+ metavar="DATA_FILE",
+ required=True)
+
+ parser.add_argument("-t", "--template-file",
+ dest="template_file",
+ help="Template file",
+ metavar="TEMPLATE_FILE",
+ required=True)
+
+ parser.add_argument("-s", "--suites-dir",
+ dest="suites_dir",
+ help="Suites dir",
+ metavar="SUITES_DIR",
+ required=True)
+
+ parser.add_argument("--helpers-file",
+ dest="helpers_file",
+ help="Helpers file",
+ metavar="HELPERS_FILE",
+ required=True)
+
+ parser.add_argument("-p", "--platform-file",
+ dest="platform_file",
+ help="Platform code file",
+ metavar="PLATFORM_FILE",
+ required=True)
+
+ parser.add_argument("-o", "--out-dir",
+ dest="out_dir",
+ help="Dir where generated code and scripts are copied",
+ metavar="OUT_DIR",
+ required=True)
+
+ args = parser.parse_args()
+
+ data_file_name = os.path.basename(args.data_file)
+ data_name = os.path.splitext(data_file_name)[0]
+
+ out_c_file = os.path.join(args.out_dir, data_name + '.c')
+ out_data_file = os.path.join(args.out_dir, data_name + '.datax')
+
+ out_c_file_dir = os.path.dirname(out_c_file)
+ out_data_file_dir = os.path.dirname(out_data_file)
+ for directory in [out_c_file_dir, out_data_file_dir]:
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+
+ generate_code(funcs_file=args.funcs_file, data_file=args.data_file,
+ template_file=args.template_file,
+ platform_file=args.platform_file,
+ helpers_file=args.helpers_file, suites_dir=args.suites_dir,
+ c_file=out_c_file, out_data_file=out_data_file)
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except GeneratorInputError as err:
+ sys.exit("%s: input error: %s" %
+ (os.path.basename(sys.argv[0]), str(err)))
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/key-exchanges.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/key-exchanges.pl
new file mode 100755
index 000000000..3bf7ae34f
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/key-exchanges.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+# key-exchanges.pl
+#
+# Copyright (c) 2015-2017, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To test the code dependencies on individual key exchanges in the SSL module.
+# is a verification step to ensure we don't ship SSL code that do not work
+# for some build options.
+#
+# The process is:
+# for each possible key exchange
+# build the library with all but that key exchange disabled
+#
+# Usage: tests/scripts/key-exchanges.pl
+#
+# This script should be executed from the root of the project directory.
+#
+# For best effect, run either with cmake disabled, or cmake enabled in a mode
+# that includes -Werror.
+
+use warnings;
+use strict;
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $sed_cmd = 's/^#define \(MBEDTLS_KEY_EXCHANGE_.*_ENABLED\)/\1/p';
+my $config_h = 'include/mbedtls/config.h';
+my @kexes = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
+
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+ system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+ # use an exit code between 1 and 124 for git bisect (die returns 255)
+ warn $_[0];
+ exit 1;
+}
+
+for my $kex (@kexes) {
+ system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
+ system( "make clean" ) and die;
+
+ print "\n******************************************\n";
+ print "* Testing with key exchange: $kex\n";
+ print "******************************************\n";
+
+ # full config with all key exchanges disabled except one
+ system( "scripts/config.pl full" ) and abort "Failed config full\n";
+ for my $k (@kexes) {
+ next if $k eq $kex;
+ system( "scripts/config.pl unset $k" )
+ and abort "Failed to disable $k\n";
+ }
+
+ system( "make lib CFLAGS='-Os -Werror'" ) and abort "Failed to build lib: $kex\n";
+}
+
+system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
+system( "make clean" ) and die;
+exit 0;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-enum-consts.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-enum-consts.pl
new file mode 100755
index 000000000..21c25b33e
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-enum-consts.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+-d 'include/mbedtls' or die "$0: must be run from root\n";
+
+@ARGV = grep { ! /compat-1\.3\.h/ } <include/mbedtls/*.h>;
+
+my @consts;
+my $state = 'out';
+while (<>)
+{
+ if( $state eq 'out' and /^(typedef )?enum \{/ ) {
+ $state = 'in';
+ } elsif( $state eq 'out' and /^(typedef )?enum/ ) {
+ $state = 'start';
+ } elsif( $state eq 'start' and /{/ ) {
+ $state = 'in';
+ } elsif( $state eq 'in' and /}/ ) {
+ $state = 'out';
+ } elsif( $state eq 'in' ) {
+ s/=.*//; s!/\*.*!!; s/,.*//; s/\s+//g; chomp;
+ push @consts, $_ if $_;
+ }
+}
+
+open my $fh, '>', 'enum-consts' or die;
+print $fh "$_\n" for sort @consts;
+close $fh or die;
+
+printf "%8d enum-consts\n", scalar @consts;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-identifiers.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-identifiers.sh
new file mode 100755
index 000000000..cc9c54fad
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-identifiers.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# Create a file named identifiers containing identifiers from internal header
+# files or all header files, based on --internal flag.
+# Outputs the line count of the file to stdout.
+#
+# Usage: list-identifiers.sh [ -i | --internal ]
+
+set -eu
+
+if [ -d include/mbedtls ]; then :; else
+ echo "$0: must be run from root" >&2
+ exit 1
+fi
+
+INTERNAL=""
+
+until [ -z "${1-}" ]
+do
+ case "$1" in
+ -i|--internal)
+ INTERNAL="1"
+ ;;
+ *)
+ # print error
+ echo "Unknown argument: '$1'"
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+if [ $INTERNAL ]
+then
+ HEADERS=$( ls include/mbedtls/*_internal.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+else
+ HEADERS=$( ls include/mbedtls/*.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+fi
+
+rm -f identifiers
+
+grep '^[^ /#{]' $HEADERS | \
+ sed -e 's/^[^:]*://' | \
+ egrep -v '^(extern "C"|(typedef )?(struct|enum)( {)?$|};?$)' \
+ > _decls
+
+if true; then
+sed -n -e 's/.* \**\([a-zA-Z_][a-zA-Z0-9_]*\)(.*/\1/p' \
+ -e 's/.*(\*\(.*\))(.*/\1/p' _decls
+grep -v '(' _decls | sed -e 's/\([a-zA-Z0-9_]*\)[;[].*/\1/' -e 's/.* \**//'
+fi > _identifiers
+
+if [ $( wc -l < _identifiers ) -eq $( wc -l < _decls ) ]; then
+ rm _decls
+ egrep -v '^(u?int(16|32|64)_t)$' _identifiers | sort > identifiers
+ rm _identifiers
+else
+ echo "$0: oops, lost some identifiers" 2>&1
+ exit 1
+fi
+
+wc -l identifiers
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-macros.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-macros.sh
new file mode 100755
index 000000000..3c84adba6
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-macros.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -eu
+
+if [ -d include/mbedtls ]; then :; else
+ echo "$0: must be run from root" >&2
+ exit 1
+fi
+
+HEADERS=$( ls include/mbedtls/*.h | egrep -v 'compat-1\.3\.h' )
+
+sed -n -e 's/.*#define \([a-zA-Z0-9_]*\).*/\1/p' $HEADERS \
+ | egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_' \
+ | sort -u > macros
+
+wc -l macros
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-symbols.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-symbols.sh
new file mode 100755
index 000000000..930722c1b
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/list-symbols.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+set -eu
+
+if [ -d include/mbedtls ]; then :; else
+ echo "$0: must be run from root" >&2
+ exit 1
+fi
+
+if grep -i cmake Makefile >/dev/null; then
+ echo "$0: not compatible with cmake" >&2
+ exit 1
+fi
+
+cp include/mbedtls/config.h include/mbedtls/config.h.bak
+scripts/config.pl full
+make clean
+make_ret=
+CFLAGS=-fno-asynchronous-unwind-tables make lib \
+ >list-symbols.make.log 2>&1 ||
+ {
+ make_ret=$?
+ echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make lib"
+ cat list-symbols.make.log >&2
+ }
+rm list-symbols.make.log
+mv include/mbedtls/config.h.bak include/mbedtls/config.h
+if [ -n "$make_ret" ]; then
+ exit "$make_ret"
+fi
+
+if uname | grep -F Darwin >/dev/null; then
+ nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p'
+elif uname | grep -F Linux >/dev/null; then
+ nm -og library/libmbed*.a | grep -v '^[^ ]*: *U \|^$\|^[^ ]*:$' | sed 's/^[^ ]* . //'
+fi | sort > exported-symbols
+make clean
+
+wc -l exported-symbols
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/mbedtls_test.py b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/mbedtls_test.py
new file mode 100755
index 000000000..ac2912d4c
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/mbedtls_test.py
@@ -0,0 +1,379 @@
+# Greentea host test script for Mbed TLS on-target test suite testing.
+#
+# Copyright (C) 2018, Arm Limited, All Rights Reserved
+# 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.
+#
+# This file is part of Mbed TLS (https://tls.mbed.org)
+
+
+"""
+Mbed TLS on-target test suite tests are implemented as Greentea
+tests. Greentea tests are implemented in two parts: target test and
+host test. Target test is a C application that is built for the
+target platform and executes on the target. Host test is a Python
+class derived from mbed_host_tests.BaseHostTest. Target communicates
+with the host over serial for the test data and sends back the result.
+
+Python tool mbedgt (Greentea) is responsible for flashing the test
+binary on to the target and dynamically loading this host test module.
+
+Greentea documentation can be found here:
+https://github.com/ARMmbed/greentea
+"""
+
+
+import re
+import os
+import binascii
+
+from mbed_host_tests import BaseHostTest, event_callback # pylint: disable=import-error
+
+
+class TestDataParserError(Exception):
+ """Indicates error in test data, read from .data file."""
+ pass
+
+
+class TestDataParser(object):
+ """
+ Parses test name, dependencies, test function name and test parameters
+ from the data file.
+ """
+
+ def __init__(self):
+ """
+ Constructor
+ """
+ self.tests = []
+
+ def parse(self, data_file):
+ """
+ Data file parser.
+
+ :param data_file: Data file path
+ """
+ with open(data_file, 'r') as data_f:
+ self.__parse(data_f)
+
+ @staticmethod
+ def __escaped_split(inp_str, split_char):
+ """
+ Splits inp_str on split_char except when escaped.
+
+ :param inp_str: String to split
+ :param split_char: Split character
+ :return: List of splits
+ """
+ split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x)
+ if len(split_char) > 1:
+ raise ValueError('Expected split character. Found string!')
+ out = map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str))
+ out = [x for x in out if x]
+ return out
+
+ def __parse(self, data_f):
+ """
+ Parses data file using supplied file object.
+
+ :param data_f: Data file object
+ :return:
+ """
+ for line in data_f:
+ line = line.strip()
+ if not line:
+ continue
+ # Read test name
+ name = line
+
+ # Check dependencies
+ dependencies = []
+ line = data_f.next().strip()
+ match = re.search('depends_on:(.*)', line)
+ if match:
+ dependencies = [int(x) for x in match.group(1).split(':')]
+ line = data_f.next().strip()
+
+ # Read test vectors
+ line = line.replace('\\n', '\n')
+ parts = self.__escaped_split(line, ':')
+ function_name = int(parts[0])
+ args = parts[1:]
+ args_count = len(args)
+ if args_count % 2 != 0:
+ err_str_fmt = "Number of test arguments({}) should be even: {}"
+ raise TestDataParserError(err_str_fmt.format(args_count, line))
+ grouped_args = [(args[i * 2], args[(i * 2) + 1])
+ for i in range(len(args)/2)]
+ self.tests.append((name, function_name, dependencies,
+ grouped_args))
+
+ def get_test_data(self):
+ """
+ Returns test data.
+ """
+ return self.tests
+
+
+class MbedTlsTest(BaseHostTest):
+ """
+ Host test for Mbed TLS unit tests. This script is loaded at
+ run time by Greentea for executing Mbed TLS test suites. Each
+ communication from the target is received in this object as
+ an event, which is then handled by the event handler method
+ decorated by the associated event. Ex: @event_callback('GO').
+
+ Target test sends requests for dispatching next test. It reads
+ tests from the intermediate data file and sends test function
+ identifier, dependency identifiers, expression identifiers and
+ the test data in binary form. Target test checks dependencies
+ , evaluate integer constant expressions and dispatches the test
+ function with received test parameters. After test function is
+ finished, target sends the result. This class handles the result
+ event and prints verdict in the form that Greentea understands.
+
+ """
+ # status/error codes from suites/helpers.function
+ DEPENDENCY_SUPPORTED = 0
+ KEY_VALUE_MAPPING_FOUND = DEPENDENCY_SUPPORTED
+ DISPATCH_TEST_SUCCESS = DEPENDENCY_SUPPORTED
+
+ KEY_VALUE_MAPPING_NOT_FOUND = -1 # Expression Id not found.
+ DEPENDENCY_NOT_SUPPORTED = -2 # Dependency not supported.
+ DISPATCH_TEST_FN_NOT_FOUND = -3 # Test function not found.
+ DISPATCH_INVALID_TEST_DATA = -4 # Invalid parameter type.
+ DISPATCH_UNSUPPORTED_SUITE = -5 # Test suite not supported/enabled.
+
+ def __init__(self):
+ """
+ Constructor initialises test index to 0.
+ """
+ super(MbedTlsTest, self).__init__()
+ self.tests = []
+ self.test_index = -1
+ self.dep_index = 0
+ self.suite_passed = True
+ self.error_str = dict()
+ self.error_str[self.DEPENDENCY_SUPPORTED] = \
+ 'DEPENDENCY_SUPPORTED'
+ self.error_str[self.KEY_VALUE_MAPPING_NOT_FOUND] = \
+ 'KEY_VALUE_MAPPING_NOT_FOUND'
+ self.error_str[self.DEPENDENCY_NOT_SUPPORTED] = \
+ 'DEPENDENCY_NOT_SUPPORTED'
+ self.error_str[self.DISPATCH_TEST_FN_NOT_FOUND] = \
+ 'DISPATCH_TEST_FN_NOT_FOUND'
+ self.error_str[self.DISPATCH_INVALID_TEST_DATA] = \
+ 'DISPATCH_INVALID_TEST_DATA'
+ self.error_str[self.DISPATCH_UNSUPPORTED_SUITE] = \
+ 'DISPATCH_UNSUPPORTED_SUITE'
+
+ def setup(self):
+ """
+ Setup hook implementation. Reads test suite data file and parses out
+ tests.
+ """
+ binary_path = self.get_config_item('image_path')
+ script_dir = os.path.split(os.path.abspath(__file__))[0]
+ suite_name = os.path.splitext(os.path.basename(binary_path))[0]
+ data_file = ".".join((suite_name, 'datax'))
+ data_file = os.path.join(script_dir, '..', 'mbedtls',
+ suite_name, data_file)
+ if os.path.exists(data_file):
+ self.log("Running tests from %s" % data_file)
+ parser = TestDataParser()
+ parser.parse(data_file)
+ self.tests = parser.get_test_data()
+ self.print_test_info()
+ else:
+ self.log("Data file not found: %s" % data_file)
+ self.notify_complete(False)
+
+ def print_test_info(self):
+ """
+ Prints test summary read by Greentea to detect test cases.
+ """
+ self.log('{{__testcase_count;%d}}' % len(self.tests))
+ for name, _, _, _ in self.tests:
+ self.log('{{__testcase_name;%s}}' % name)
+
+ @staticmethod
+ def align_32bit(data_bytes):
+ """
+ 4 byte aligns input byte array.
+
+ :return:
+ """
+ data_bytes += bytearray((4 - (len(data_bytes))) % 4)
+
+ @staticmethod
+ def hex_str_bytes(hex_str):
+ """
+ Converts Hex string representation to byte array
+
+ :param hex_str: Hex in string format.
+ :return: Output Byte array
+ """
+ if hex_str[0] != '"' or hex_str[len(hex_str) - 1] != '"':
+ raise TestDataParserError("HEX test parameter missing '\"':"
+ " %s" % hex_str)
+ hex_str = hex_str.strip('"')
+ if len(hex_str) % 2 != 0:
+ raise TestDataParserError("HEX parameter len should be mod of "
+ "2: %s" % hex_str)
+
+ data_bytes = binascii.unhexlify(hex_str)
+ return data_bytes
+
+ @staticmethod
+ def int32_to_big_endian_bytes(i):
+ """
+ Coverts i to byte array in big endian format.
+
+ :param i: Input integer
+ :return: Output bytes array in big endian or network order
+ """
+ data_bytes = bytearray([((i >> x) & 0xff) for x in [24, 16, 8, 0]])
+ return data_bytes
+
+ def test_vector_to_bytes(self, function_id, dependencies, parameters):
+ """
+ Converts test vector into a byte array that can be sent to the target.
+
+ :param function_id: Test Function Identifier
+ :param dependencies: Dependency list
+ :param parameters: Test function input parameters
+ :return: Byte array and its length
+ """
+ data_bytes = bytearray([len(dependencies)])
+ if dependencies:
+ data_bytes += bytearray(dependencies)
+ data_bytes += bytearray([function_id, len(parameters)])
+ for typ, param in parameters:
+ if typ == 'int' or typ == 'exp':
+ i = int(param)
+ data_bytes += 'I' if typ == 'int' else 'E'
+ self.align_32bit(data_bytes)
+ data_bytes += self.int32_to_big_endian_bytes(i)
+ elif typ == 'char*':
+ param = param.strip('"')
+ i = len(param) + 1 # + 1 for null termination
+ data_bytes += 'S'
+ self.align_32bit(data_bytes)
+ data_bytes += self.int32_to_big_endian_bytes(i)
+ data_bytes += bytearray(list(param))
+ data_bytes += '\0' # Null terminate
+ elif typ == 'hex':
+ binary_data = self.hex_str_bytes(param)
+ data_bytes += 'H'
+ self.align_32bit(data_bytes)
+ i = len(binary_data)
+ data_bytes += self.int32_to_big_endian_bytes(i)
+ data_bytes += binary_data
+ length = self.int32_to_big_endian_bytes(len(data_bytes))
+ return data_bytes, length
+
+ def run_next_test(self):
+ """
+ Fetch next test information and execute the test.
+
+ """
+ self.test_index += 1
+ self.dep_index = 0
+ if self.test_index < len(self.tests):
+ name, function_id, dependencies, args = self.tests[self.test_index]
+ self.run_test(name, function_id, dependencies, args)
+ else:
+ self.notify_complete(self.suite_passed)
+
+ def run_test(self, name, function_id, dependencies, args):
+ """
+ Execute the test on target by sending next test information.
+
+ :param name: Test name
+ :param function_id: function identifier
+ :param dependencies: Dependencies list
+ :param args: test parameters
+ :return:
+ """
+ self.log("Running: %s" % name)
+
+ param_bytes, length = self.test_vector_to_bytes(function_id,
+ dependencies, args)
+ self.send_kv(length, param_bytes)
+
+ @staticmethod
+ def get_result(value):
+ """
+ Converts result from string type to integer
+ :param value: Result code in string
+ :return: Integer result code. Value is from the test status
+ constants defined under the MbedTlsTest class.
+ """
+ try:
+ return int(value)
+ except ValueError:
+ ValueError("Result should return error number. "
+ "Instead received %s" % value)
+
+ @event_callback('GO')
+ def on_go(self, _key, _value, _timestamp):
+ """
+ Sent by the target to start first test.
+
+ :param _key: Event key
+ :param _value: Value. ignored
+ :param _timestamp: Timestamp ignored.
+ :return:
+ """
+ self.run_next_test()
+
+ @event_callback("R")
+ def on_result(self, _key, value, _timestamp):
+ """
+ Handle result. Prints test start, finish required by Greentea
+ to detect test execution.
+
+ :param _key: Event key
+ :param value: Value. ignored
+ :param _timestamp: Timestamp ignored.
+ :return:
+ """
+ int_val = self.get_result(value)
+ name, _, _, _ = self.tests[self.test_index]
+ self.log('{{__testcase_start;%s}}' % name)
+ self.log('{{__testcase_finish;%s;%d;%d}}' % (name, int_val == 0,
+ int_val != 0))
+ if int_val != 0:
+ self.suite_passed = False
+ self.run_next_test()
+
+ @event_callback("F")
+ def on_failure(self, _key, value, _timestamp):
+ """
+ Handles test execution failure. That means dependency not supported or
+ Test function not supported. Hence marking test as skipped.
+
+ :param _key: Event key
+ :param value: Value. ignored
+ :param _timestamp: Timestamp ignored.
+ :return:
+ """
+ int_val = self.get_result(value)
+ if int_val in self.error_str:
+ err = self.error_str[int_val]
+ else:
+ err = 'Unknown error'
+ # For skip status, do not write {{__testcase_finish;...}}
+ self.log("Error: %s" % err)
+ self.run_next_test()
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/recursion.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/recursion.pl
new file mode 100755
index 000000000..431e59211
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/recursion.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/env perl
+
+# Find functions making recursive calls to themselves.
+# (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.
+#
+# Typical usage: scripts/recursion.pl library/*.c
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+# exclude functions that are ok:
+# - mpi_write_hlp: bounded by size of mbedtls_mpi, a compile-time constant
+# - x509_crt_verify_child: bounded by MBEDTLS_X509_MAX_INTERMEDIATE_CA
+my $known_ok = qr/mpi_write_hlp|x509_crt_verify_child/;
+
+my $cur_name;
+my $inside;
+my @funcs;
+
+die "Usage: $0 file.c [...]\n" unless @ARGV;
+
+while (<>)
+{
+ if( /^[^\/#{}\s]/ && ! /\[.*]/ ) {
+ chomp( $cur_name = $_ ) unless $inside;
+ } elsif( /^{/ && $cur_name ) {
+ $inside = 1;
+ $cur_name =~ s/.* ([^ ]*)\(.*/$1/;
+ } elsif( /^}/ && $inside ) {
+ undef $inside;
+ undef $cur_name;
+ } elsif( $inside && /\b\Q$cur_name\E\([^)]/ ) {
+ push @funcs, $cur_name unless /$known_ok/;
+ }
+}
+
+print "$_\n" for @funcs;
+exit @funcs;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/run-test-suites.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/run-test-suites.pl
new file mode 100755
index 000000000..1c9dc1dfc
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/run-test-suites.pl
@@ -0,0 +1,152 @@
+#!/usr/bin/env perl
+
+# run-test-suites.pl
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2018, ARM Limited, All Rights Reserved
+
+=head1 SYNOPSIS
+
+Execute all the test suites and print a summary of the results.
+
+ run-test-suites.pl [[-v|--verbose] [VERBOSITY]] [--skip=SUITE[...]]
+
+Options:
+
+ -v|--verbose Print detailed failure information.
+ -v 2|--verbose=2 Print detailed failure information and summary messages.
+ -v 3|--verbose=3 Print detailed information about every test case.
+ --skip=SUITE[,SUITE...]
+ Skip the specified SUITE(s). This option can be used
+ multiple times.
+
+=cut
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+use Getopt::Long qw(:config auto_help gnu_compat);
+use Pod::Usage;
+
+my $verbose = 0;
+my @skip_patterns = ();
+GetOptions(
+ 'skip=s' => \@skip_patterns,
+ 'verbose|v:1' => \$verbose,
+ ) or die;
+
+# All test suites = executable files, excluding source files, debug
+# and profiling information, etc. We can't just grep {! /\./} because
+# some of our test cases' base names contain a dot.
+my @suites = grep { -x $_ || /\.exe$/ } glob 'test_suite_*';
+@suites = grep { !/\.c$/ && !/\.data$/ && -f } @suites;
+die "$0: no test suite found\n" unless @suites;
+
+# "foo" as a skip pattern skips "test_suite_foo" and "test_suite_foo.bar"
+# but not "test_suite_foobar".
+my $skip_re =
+ ( '\Atest_suite_(' .
+ join('|', map {
+ s/[ ,;]/|/g; # allow any of " ,;|" as separators
+ s/\./\./g; # "." in the input means ".", not "any character"
+ $_
+ } @skip_patterns) .
+ ')(\z|\.)' );
+
+# in case test suites are linked dynamically
+$ENV{'LD_LIBRARY_PATH'} = '../library';
+$ENV{'DYLD_LIBRARY_PATH'} = '../library';
+
+my $prefix = $^O eq "MSWin32" ? '' : './';
+
+my ($failed_suites, $total_tests_run, $failed, $suite_cases_passed,
+ $suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
+ $total_cases_failed, $total_cases_skipped );
+my $suites_skipped = 0;
+
+sub pad_print_center {
+ my( $width, $padchar, $string ) = @_;
+ my $padlen = ( $width - length( $string ) - 2 ) / 2;
+ print $padchar x( $padlen ), " $string ", $padchar x( $padlen ), "\n";
+}
+
+for my $suite (@suites)
+{
+ print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
+ if( $suite =~ /$skip_re/o ) {
+ print "SKIP\n";
+ ++$suites_skipped;
+ next;
+ }
+
+ my $command = "$prefix$suite";
+ if( $verbose ) {
+ $command .= ' -v';
+ }
+ my $result = `$command`;
+
+ $suite_cases_passed = () = $result =~ /.. PASS/g;
+ $suite_cases_failed = () = $result =~ /.. FAILED/g;
+ $suite_cases_skipped = () = $result =~ /.. ----/g;
+
+ if( $result =~ /PASSED/ ) {
+ print "PASS\n";
+ if( $verbose > 2 ) {
+ pad_print_center( 72, '-', "Begin $suite" );
+ print $result;
+ pad_print_center( 72, '-', "End $suite" );
+ }
+ } else {
+ $failed_suites++;
+ print "FAIL\n";
+ if( $verbose ) {
+ pad_print_center( 72, '-', "Begin $suite" );
+ print $result;
+ pad_print_center( 72, '-', "End $suite" );
+ }
+ }
+
+ my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
+ $total_tests_run += $tests - $skipped;
+
+ if( $verbose > 1 ) {
+ print "(test cases passed:", $suite_cases_passed,
+ " failed:", $suite_cases_failed,
+ " skipped:", $suite_cases_skipped,
+ " of total:", ($suite_cases_passed + $suite_cases_failed +
+ $suite_cases_skipped),
+ ")\n"
+ }
+
+ $total_cases_passed += $suite_cases_passed;
+ $total_cases_failed += $suite_cases_failed;
+ $total_cases_skipped += $suite_cases_skipped;
+}
+
+print "-" x 72, "\n";
+print $failed_suites ? "FAILED" : "PASSED";
+printf( " (%d suites, %d tests run%s)\n",
+ scalar(@suites) - $suites_skipped,
+ $total_tests_run,
+ $suites_skipped ? ", $suites_skipped suites skipped" : "" );
+
+if( $verbose > 1 ) {
+ print " test cases passed :", $total_cases_passed, "\n";
+ print " failed :", $total_cases_failed, "\n";
+ print " skipped :", $total_cases_skipped, "\n";
+ print " of tests executed :", ( $total_cases_passed + $total_cases_failed ),
+ "\n";
+ print " of available tests :",
+ ( $total_cases_passed + $total_cases_failed + $total_cases_skipped ),
+ "\n";
+ if( $suites_skipped != 0 ) {
+ print "Note: $suites_skipped suites were skipped.\n";
+ }
+}
+
+exit( $failed_suites ? 1 : 0 );
+
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/tcp_client.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/tcp_client.pl
new file mode 100755
index 000000000..11cbf1b1b
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/tcp_client.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/env perl
+
+# A simple TCP client that sends some data and expects a response.
+# Usage: tcp_client.pl HOSTNAME PORT DATA1 RESPONSE1
+# DATA: hex-encoded data to send to the server
+# RESPONSE: regexp that must match the server's response
+
+use warnings;
+use strict;
+use IO::Socket::INET;
+
+# Pack hex digits into a binary string, ignoring whitespace.
+sub parse_hex {
+ my ($hex) = @_;
+ $hex =~ s/\s+//g;
+ return pack('H*', $hex);
+}
+
+## Open a TCP connection to the specified host and port.
+sub open_connection {
+ my ($host, $port) = @_;
+ my $socket = IO::Socket::INET->new(PeerAddr => $host,
+ PeerPort => $port,
+ Proto => 'tcp',
+ Timeout => 1);
+ die "Cannot connect to $host:$port: $!" unless $socket;
+ return $socket;
+}
+
+## Close the TCP connection.
+sub close_connection {
+ my ($connection) = @_;
+ $connection->shutdown(2);
+ # Ignore shutdown failures (at least for now)
+ return 1;
+}
+
+## Write the given data, expressed as hexadecimal
+sub write_data {
+ my ($connection, $hexdata) = @_;
+ my $data = parse_hex($hexdata);
+ my $total_sent = 0;
+ while ($total_sent < length($data)) {
+ my $sent = $connection->send($data, 0);
+ if (!defined $sent) {
+ die "Unable to send data: $!";
+ }
+ $total_sent += $sent;
+ }
+ return 1;
+}
+
+## Read a response and check it against an expected prefix
+sub read_response {
+ my ($connection, $expected_hex) = @_;
+ my $expected_data = parse_hex($expected_hex);
+ my $start_offset = 0;
+ while ($start_offset < length($expected_data)) {
+ my $actual_data;
+ my $ok = $connection->recv($actual_data, length($expected_data));
+ if (!defined $ok) {
+ die "Unable to receive data: $!";
+ }
+ if (($actual_data ^ substr($expected_data, $start_offset)) =~ /[^\000]/) {
+ printf STDERR ("Received \\x%02x instead of \\x%02x at offset %d\n",
+ ord(substr($actual_data, $-[0], 1)),
+ ord(substr($expected_data, $start_offset + $-[0], 1)),
+ $start_offset + $-[0]);
+ return 0;
+ }
+ $start_offset += length($actual_data);
+ }
+ return 1;
+}
+
+if (@ARGV != 4) {
+ print STDERR "Usage: $0 HOSTNAME PORT DATA1 RESPONSE1\n";
+ exit(3);
+}
+my ($host, $port, $data1, $response1) = @ARGV;
+my $connection = open_connection($host, $port);
+write_data($connection, $data1);
+if (!read_response($connection, $response1)) {
+ exit(1);
+}
+close_connection($connection);
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test-ref-configs.pl b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test-ref-configs.pl
new file mode 100755
index 000000000..80d5f3875
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test-ref-configs.pl
@@ -0,0 +1,102 @@
+#!/usr/bin/env perl
+
+# test-ref-configs.pl
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# For each reference configuration file in the configs directory, build the
+# configuration, run the test suites and compat.sh
+#
+# Usage: tests/scripts/test-ref-configs.pl [config-name [...]]
+
+use warnings;
+use strict;
+
+my %configs = (
+ 'config-mini-tls1_1.h' => {
+ 'compat' => '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'',
+ },
+ 'config-suite-b.h' => {
+ 'compat' => "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
+ },
+ 'config-ccm-psk-tls1_2.h' => {
+ 'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
+ },
+ 'config-thread.h' => {
+ 'opt' => '-f ECJPAKE.*nolog',
+ },
+);
+
+# If no config-name is provided, use all known configs.
+# Otherwise, use the provided names only.
+if ($#ARGV >= 0) {
+ my %configs_ori = ( %configs );
+ %configs = ();
+
+ foreach my $conf_name (@ARGV) {
+ if( ! exists $configs_ori{$conf_name} ) {
+ die "Unknown configuration: $conf_name\n";
+ } else {
+ $configs{$conf_name} = $configs_ori{$conf_name};
+ }
+ }
+}
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $config_h = 'include/mbedtls/config.h';
+
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+ system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+ # use an exit code between 1 and 124 for git bisect (die returns 255)
+ warn $_[0];
+ exit 1;
+}
+
+while( my ($conf, $data) = each %configs ) {
+ system( "cp $config_h.bak $config_h" ) and die;
+ system( "make clean" ) and die;
+
+ print "\n******************************************\n";
+ print "* Testing configuration: $conf\n";
+ print "******************************************\n";
+
+ system( "cp configs/$conf $config_h" )
+ and abort "Failed to activate $conf\n";
+
+ system( "CFLAGS='-Os -Werror -Wall -Wextra' make" ) and abort "Failed to build: $conf\n";
+ system( "make test" ) and abort "Failed test suite: $conf\n";
+
+ my $compat = $data->{'compat'};
+ if( $compat )
+ {
+ print "\nrunning compat.sh $compat\n";
+ system( "tests/compat.sh $compat" )
+ and abort "Failed compat.sh: $conf\n";
+ }
+ else
+ {
+ print "\nskipping compat.sh\n";
+ }
+
+ my $opt = $data->{'opt'};
+ if( $opt )
+ {
+ print "\nrunning ssl-opt.sh $opt\n";
+ system( "tests/ssl-opt.sh $opt" )
+ and abort "Failed ssl-opt.sh: $conf\n";
+ }
+ else
+ {
+ print "\nskipping ssl-opt.sh\n";
+ }
+}
+
+system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+system( "make clean" );
+exit 0;
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_generate_test_code.py b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_generate_test_code.py
new file mode 100755
index 000000000..6d7113e18
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_generate_test_code.py
@@ -0,0 +1,1755 @@
+#!/usr/bin/env python3
+# Unit test for generate_test_code.py
+#
+# Copyright (C) 2018, Arm Limited, All Rights Reserved
+# 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.
+#
+# This file is part of Mbed TLS (https://tls.mbed.org)
+
+"""
+Unit tests for generate_test_code.py
+"""
+
+# pylint: disable=wrong-import-order
+try:
+ # Python 2
+ from StringIO import StringIO
+except ImportError:
+ # Python 3
+ from io import StringIO
+from unittest import TestCase, main as unittest_main
+try:
+ # Python 2
+ from mock import patch
+except ImportError:
+ # Python 3
+ from unittest.mock import patch
+# pylint: enable=wrong-import-order
+from generate_test_code import gen_dependencies, gen_dependencies_one_line
+from generate_test_code import gen_function_wrapper, gen_dispatch
+from generate_test_code import parse_until_pattern, GeneratorInputError
+from generate_test_code import parse_suite_dependencies
+from generate_test_code import parse_function_dependencies
+from generate_test_code import parse_function_arguments, parse_function_code
+from generate_test_code import parse_functions, END_HEADER_REGEX
+from generate_test_code import END_SUITE_HELPERS_REGEX, escaped_split
+from generate_test_code import parse_test_data, gen_dep_check
+from generate_test_code import gen_expression_check, write_dependencies
+from generate_test_code import write_parameters, gen_suite_dep_checks
+from generate_test_code import gen_from_test_data
+
+
+class GenDep(TestCase):
+ """
+ Test suite for function gen_dep()
+ """
+
+ def test_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['DEP1', 'DEP2']
+ dep_start, dep_end = gen_dependencies(dependencies)
+ preprocessor1, preprocessor2 = dep_start.splitlines()
+ endif1, endif2 = dep_end.splitlines()
+ self.assertEqual(preprocessor1, '#if defined(DEP1)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(preprocessor2, '#if defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif1, '#endif /* DEP2 */',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif2, '#endif /* DEP1 */',
+ 'Preprocessor generated incorrectly')
+
+ def test_disabled_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['!DEP1', '!DEP2']
+ dep_start, dep_end = gen_dependencies(dependencies)
+ preprocessor1, preprocessor2 = dep_start.splitlines()
+ endif1, endif2 = dep_end.splitlines()
+ self.assertEqual(preprocessor1, '#if !defined(DEP1)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(preprocessor2, '#if !defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif1, '#endif /* !DEP2 */',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif2, '#endif /* !DEP1 */',
+ 'Preprocessor generated incorrectly')
+
+ def test_mixed_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['!DEP1', 'DEP2']
+ dep_start, dep_end = gen_dependencies(dependencies)
+ preprocessor1, preprocessor2 = dep_start.splitlines()
+ endif1, endif2 = dep_end.splitlines()
+ self.assertEqual(preprocessor1, '#if !defined(DEP1)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(preprocessor2, '#if defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif1, '#endif /* DEP2 */',
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(endif2, '#endif /* !DEP1 */',
+ 'Preprocessor generated incorrectly')
+
+ def test_empty_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = []
+ dep_start, dep_end = gen_dependencies(dependencies)
+ self.assertEqual(dep_start, '', 'Preprocessor generated incorrectly')
+ self.assertEqual(dep_end, '', 'Preprocessor generated incorrectly')
+
+ def test_large_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = []
+ count = 10
+ for i in range(count):
+ dependencies.append('DEP%d' % i)
+ dep_start, dep_end = gen_dependencies(dependencies)
+ self.assertEqual(len(dep_start.splitlines()), count,
+ 'Preprocessor generated incorrectly')
+ self.assertEqual(len(dep_end.splitlines()), count,
+ 'Preprocessor generated incorrectly')
+
+
+class GenDepOneLine(TestCase):
+ """
+ Test Suite for testing gen_dependencies_one_line()
+ """
+
+ def test_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['DEP1', 'DEP2']
+ dep_str = gen_dependencies_one_line(dependencies)
+ self.assertEqual(dep_str, '#if defined(DEP1) && defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+
+ def test_disabled_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['!DEP1', '!DEP2']
+ dep_str = gen_dependencies_one_line(dependencies)
+ self.assertEqual(dep_str, '#if !defined(DEP1) && !defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+
+ def test_mixed_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = ['!DEP1', 'DEP2']
+ dep_str = gen_dependencies_one_line(dependencies)
+ self.assertEqual(dep_str, '#if !defined(DEP1) && defined(DEP2)',
+ 'Preprocessor generated incorrectly')
+
+ def test_empty_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = []
+ dep_str = gen_dependencies_one_line(dependencies)
+ self.assertEqual(dep_str, '', 'Preprocessor generated incorrectly')
+
+ def test_large_dependencies_list(self):
+ """
+ Test that gen_dep() correctly creates dependencies for given
+ dependency list.
+ :return:
+ """
+ dependencies = []
+ count = 10
+ for i in range(count):
+ dependencies.append('DEP%d' % i)
+ dep_str = gen_dependencies_one_line(dependencies)
+ expected = '#if ' + ' && '.join(['defined(%s)' %
+ x for x in dependencies])
+ self.assertEqual(dep_str, expected,
+ 'Preprocessor generated incorrectly')
+
+
+class GenFunctionWrapper(TestCase):
+ """
+ Test Suite for testing gen_function_wrapper()
+ """
+
+ def test_params_unpack(self):
+ """
+ Test that params are properly unpacked in the function call.
+
+ :return:
+ """
+ code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
+ expected = '''
+void test_a_wrapper( void ** params )
+{
+
+ test_a( a, b, c, d );
+}
+'''
+ self.assertEqual(code, expected)
+
+ def test_local(self):
+ """
+ Test that params are properly unpacked in the function call.
+
+ :return:
+ """
+ code = gen_function_wrapper('test_a',
+ 'int x = 1;', ('x', 'b', 'c', 'd'))
+ expected = '''
+void test_a_wrapper( void ** params )
+{
+int x = 1;
+ test_a( x, b, c, d );
+}
+'''
+ self.assertEqual(code, expected)
+
+ def test_empty_params(self):
+ """
+ Test that params are properly unpacked in the function call.
+
+ :return:
+ """
+ code = gen_function_wrapper('test_a', '', ())
+ expected = '''
+void test_a_wrapper( void ** params )
+{
+ (void)params;
+
+ test_a( );
+}
+'''
+ self.assertEqual(code, expected)
+
+
+class GenDispatch(TestCase):
+ """
+ Test suite for testing gen_dispatch()
+ """
+
+ def test_dispatch(self):
+ """
+ Test that dispatch table entry is generated correctly.
+ :return:
+ """
+ code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
+ expected = '''
+#if defined(DEP1) && defined(DEP2)
+ test_a_wrapper,
+#else
+ NULL,
+#endif
+'''
+ self.assertEqual(code, expected)
+
+ def test_empty_dependencies(self):
+ """
+ Test empty dependency list.
+ :return:
+ """
+ code = gen_dispatch('test_a', [])
+ expected = '''
+ test_a_wrapper,
+'''
+ self.assertEqual(code, expected)
+
+
+class StringIOWrapper(StringIO, object):
+ """
+ file like class to mock file object in tests.
+ """
+ def __init__(self, file_name, data, line_no=0):
+ """
+ Init file handle.
+
+ :param file_name:
+ :param data:
+ :param line_no:
+ """
+ super(StringIOWrapper, self).__init__(data)
+ self.line_no = line_no
+ self.name = file_name
+
+ def next(self):
+ """
+ Iterator method. This method overrides base class's
+ next method and extends the next method to count the line
+ numbers as each line is read.
+
+ :return: Line read from file.
+ """
+ parent = super(StringIOWrapper, self)
+ if getattr(parent, 'next', None):
+ # Python 2
+ line = parent.next()
+ else:
+ # Python 3
+ line = parent.__next__()
+ return line
+
+ # Python 3
+ __next__ = next
+
+ def readline(self, length=0):
+ """
+ Wrap the base class readline.
+
+ :param length:
+ :return:
+ """
+ # pylint: disable=unused-argument
+ line = super(StringIOWrapper, self).readline()
+ if line is not None:
+ self.line_no += 1
+ return line
+
+
+class ParseUntilPattern(TestCase):
+ """
+ Test Suite for testing parse_until_pattern().
+ """
+
+ def test_suite_headers(self):
+ """
+ Test that suite headers are parsed correctly.
+
+ :return:
+ """
+ data = '''#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+/* END_HEADER */
+'''
+ expected = '''#line 1 "test_suite_ut.function"
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data, line_no=0)
+ headers = parse_until_pattern(stream, END_HEADER_REGEX)
+ self.assertEqual(headers, expected)
+
+ def test_line_no(self):
+ """
+ Test that #line is set to correct line no. in source .function file.
+
+ :return:
+ """
+ data = '''#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+/* END_HEADER */
+'''
+ offset_line_no = 5
+ expected = '''#line %d "test_suite_ut.function"
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+''' % (offset_line_no + 1)
+ stream = StringIOWrapper('test_suite_ut.function', data,
+ offset_line_no)
+ headers = parse_until_pattern(stream, END_HEADER_REGEX)
+ self.assertEqual(headers, expected)
+
+ def test_no_end_header_comment(self):
+ """
+ Test that InvalidFileFormat is raised when end header comment is
+ missing.
+ :return:
+ """
+ data = '''#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(GeneratorInputError, parse_until_pattern, stream,
+ END_HEADER_REGEX)
+
+
+class ParseSuiteDependencies(TestCase):
+ """
+ Test Suite for testing parse_suite_dependencies().
+ """
+
+ def test_suite_dependencies(self):
+ """
+
+ :return:
+ """
+ data = '''
+ * depends_on:MBEDTLS_ECP_C
+ * END_DEPENDENCIES
+ */
+'''
+ expected = ['MBEDTLS_ECP_C']
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ dependencies = parse_suite_dependencies(stream)
+ self.assertEqual(dependencies, expected)
+
+ def test_no_end_dep_comment(self):
+ """
+ Test that InvalidFileFormat is raised when end dep comment is missing.
+ :return:
+ """
+ data = '''
+* depends_on:MBEDTLS_ECP_C
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(GeneratorInputError, parse_suite_dependencies,
+ stream)
+
+ def test_dependencies_split(self):
+ """
+ Test that InvalidFileFormat is raised when end dep comment is missing.
+ :return:
+ """
+ data = '''
+ * depends_on:MBEDTLS_ECP_C:A:B: C : D :F : G: !H
+ * END_DEPENDENCIES
+ */
+'''
+ expected = ['MBEDTLS_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ dependencies = parse_suite_dependencies(stream)
+ self.assertEqual(dependencies, expected)
+
+
+class ParseFuncDependencies(TestCase):
+ """
+ Test Suite for testing parse_function_dependencies()
+ """
+
+ def test_function_dependencies(self):
+ """
+ Test that parse_function_dependencies() correctly parses function
+ dependencies.
+ :return:
+ """
+ line = '/* BEGIN_CASE ' \
+ 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */'
+ expected = ['MBEDTLS_ENTROPY_NV_SEED', 'MBEDTLS_FS_IO']
+ dependencies = parse_function_dependencies(line)
+ self.assertEqual(dependencies, expected)
+
+ def test_no_dependencies(self):
+ """
+ Test that parse_function_dependencies() correctly parses function
+ dependencies.
+ :return:
+ """
+ line = '/* BEGIN_CASE */'
+ dependencies = parse_function_dependencies(line)
+ self.assertEqual(dependencies, [])
+
+ def test_tolerance(self):
+ """
+ Test that parse_function_dependencies() correctly parses function
+ dependencies.
+ :return:
+ """
+ line = '/* BEGIN_CASE depends_on:MBEDTLS_FS_IO: A : !B:C : F*/'
+ dependencies = parse_function_dependencies(line)
+ self.assertEqual(dependencies, ['MBEDTLS_FS_IO', 'A', '!B', 'C', 'F'])
+
+
+class ParseFuncSignature(TestCase):
+ """
+ Test Suite for parse_function_arguments().
+ """
+
+ def test_int_and_char_params(self):
+ """
+ Test int and char parameters parsing
+ :return:
+ """
+ line = 'void entropy_threshold( char * a, int b, int result )'
+ args, local, arg_dispatch = parse_function_arguments(line)
+ self.assertEqual(args, ['char*', 'int', 'int'])
+ self.assertEqual(local, '')
+ self.assertEqual(arg_dispatch, ['(char *) params[0]',
+ '*( (int *) params[1] )',
+ '*( (int *) params[2] )'])
+
+ def test_hex_params(self):
+ """
+ Test hex parameters parsing
+ :return:
+ """
+ line = 'void entropy_threshold( char * a, data_t * h, int result )'
+ args, local, arg_dispatch = parse_function_arguments(line)
+ self.assertEqual(args, ['char*', 'hex', 'int'])
+ self.assertEqual(local,
+ ' data_t data1 = {(uint8_t *) params[1], '
+ '*( (uint32_t *) params[2] )};\n')
+ self.assertEqual(arg_dispatch, ['(char *) params[0]',
+ '&data1',
+ '*( (int *) params[3] )'])
+
+ def test_unsupported_arg(self):
+ """
+ Test unsupported arguments (not among int, char * and data_t)
+ :return:
+ """
+ line = 'void entropy_threshold( char * a, data_t * h, char result )'
+ self.assertRaises(ValueError, parse_function_arguments, line)
+
+ def test_no_params(self):
+ """
+ Test no parameters.
+ :return:
+ """
+ line = 'void entropy_threshold()'
+ args, local, arg_dispatch = parse_function_arguments(line)
+ self.assertEqual(args, [])
+ self.assertEqual(local, '')
+ self.assertEqual(arg_dispatch, [])
+
+
+class ParseFunctionCode(TestCase):
+ """
+ Test suite for testing parse_function_code()
+ """
+
+ def assert_raises_regex(self, exp, regex, func, *args):
+ """
+ Python 2 & 3 portable wrapper of assertRaisesRegex(p)? function.
+
+ :param exp: Exception type expected to be raised by cb.
+ :param regex: Expected exception message
+ :param func: callable object under test
+ :param args: variable positional arguments
+ """
+ parent = super(ParseFunctionCode, self)
+
+ # Pylint does not appreciate that the super method called
+ # conditionally can be available in other Python version
+ # then that of Pylint.
+ # Workaround is to call the method via getattr.
+ # Pylint ignores that the method got via getattr is
+ # conditionally executed. Method has to be a callable.
+ # Hence, using a dummy callable for getattr default.
+ dummy = lambda *x: None
+ # First Python 3 assertRaisesRegex is checked, since Python 2
+ # assertRaisesRegexp is also available in Python 3 but is
+ # marked deprecated.
+ for name in ('assertRaisesRegex', 'assertRaisesRegexp'):
+ method = getattr(parent, name, dummy)
+ if method is not dummy:
+ method(exp, regex, func, *args)
+ break
+ else:
+ raise AttributeError(" 'ParseFunctionCode' object has no attribute"
+ " 'assertRaisesRegex' or 'assertRaisesRegexp'"
+ )
+
+ def test_no_function(self):
+ """
+ Test no test function found.
+ :return:
+ """
+ data = '''
+No
+test
+function
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ err_msg = 'file: test_suite_ut.function - Test functions not found!'
+ self.assert_raises_regex(GeneratorInputError, err_msg,
+ parse_function_code, stream, [], [])
+
+ def test_no_end_case_comment(self):
+ """
+ Test missing end case.
+ :return:
+ """
+ data = '''
+void test_func()
+{
+}
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ err_msg = r'file: test_suite_ut.function - '\
+ 'end case pattern .*? not found!'
+ self.assert_raises_regex(GeneratorInputError, err_msg,
+ parse_function_code, stream, [], [])
+
+ @patch("generate_test_code.parse_function_arguments")
+ def test_function_called(self,
+ parse_function_arguments_mock):
+ """
+ Test parse_function_code()
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ data = '''
+void test_func()
+{
+}
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(GeneratorInputError, parse_function_code,
+ stream, [], [])
+ self.assertTrue(parse_function_arguments_mock.called)
+ parse_function_arguments_mock.assert_called_with('void test_func()\n')
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_return(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test generated code.
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+void func()
+{
+ ba ba black sheep
+ have you any wool
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ name, arg, code, dispatch_code = parse_function_code(stream, [], [])
+
+ self.assertTrue(parse_function_arguments_mock.called)
+ parse_function_arguments_mock.assert_called_with('void func()\n')
+ gen_function_wrapper_mock.assert_called_with('test_func', '', [])
+ self.assertEqual(name, 'test_func')
+ self.assertEqual(arg, [])
+ expected = '''#line 1 "test_suite_ut.function"
+
+void test_func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ ;
+}
+'''
+ self.assertEqual(code, expected)
+ self.assertEqual(dispatch_code, "\n test_func_wrapper,\n")
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_with_exit_label(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test when exit label is present.
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+void func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+void test_func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
+ def test_non_void_function(self):
+ """
+ Test invalid signature (non void).
+ :return:
+ """
+ data = 'int entropy_threshold( char * a, data_t * h, int result )'
+ err_msg = 'file: test_suite_ut.function - Test functions not found!'
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assert_raises_regex(GeneratorInputError, err_msg,
+ parse_function_code, stream, [], [])
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_functio_name_on_newline(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test when exit label is present.
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+void
+
+
+func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+void
+
+
+test_func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
+
+class ParseFunction(TestCase):
+ """
+ Test Suite for testing parse_functions()
+ """
+
+ @patch("generate_test_code.parse_until_pattern")
+ def test_begin_header(self, parse_until_pattern_mock):
+ """
+ Test that begin header is checked and parse_until_pattern() is called.
+ :return:
+ """
+ def stop(*_unused):
+ """Stop when parse_until_pattern is called."""
+ raise Exception
+ parse_until_pattern_mock.side_effect = stop
+ data = '''/* BEGIN_HEADER */
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+/* END_HEADER */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(Exception, parse_functions, stream)
+ parse_until_pattern_mock.assert_called_with(stream, END_HEADER_REGEX)
+ self.assertEqual(stream.line_no, 1)
+
+ @patch("generate_test_code.parse_until_pattern")
+ def test_begin_helper(self, parse_until_pattern_mock):
+ """
+ Test that begin helper is checked and parse_until_pattern() is called.
+ :return:
+ """
+ def stop(*_unused):
+ """Stop when parse_until_pattern is called."""
+ raise Exception
+ parse_until_pattern_mock.side_effect = stop
+ data = '''/* BEGIN_SUITE_HELPERS */
+void print_hello_world()
+{
+ printf("Hello World!\n");
+}
+/* END_SUITE_HELPERS */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(Exception, parse_functions, stream)
+ parse_until_pattern_mock.assert_called_with(stream,
+ END_SUITE_HELPERS_REGEX)
+ self.assertEqual(stream.line_no, 1)
+
+ @patch("generate_test_code.parse_suite_dependencies")
+ def test_begin_dep(self, parse_suite_dependencies_mock):
+ """
+ Test that begin dep is checked and parse_suite_dependencies() is
+ called.
+ :return:
+ """
+ def stop(*_unused):
+ """Stop when parse_until_pattern is called."""
+ raise Exception
+ parse_suite_dependencies_mock.side_effect = stop
+ data = '''/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_ECP_C
+ * END_DEPENDENCIES
+ */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(Exception, parse_functions, stream)
+ parse_suite_dependencies_mock.assert_called_with(stream)
+ self.assertEqual(stream.line_no, 1)
+
+ @patch("generate_test_code.parse_function_dependencies")
+ def test_begin_function_dep(self, func_mock):
+ """
+ Test that begin dep is checked and parse_function_dependencies() is
+ called.
+ :return:
+ """
+ def stop(*_unused):
+ """Stop when parse_until_pattern is called."""
+ raise Exception
+ func_mock.side_effect = stop
+
+ dependencies_str = '/* BEGIN_CASE ' \
+ 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
+ data = '''%svoid test_func()
+{
+}
+''' % dependencies_str
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(Exception, parse_functions, stream)
+ func_mock.assert_called_with(dependencies_str)
+ self.assertEqual(stream.line_no, 1)
+
+ @patch("generate_test_code.parse_function_code")
+ @patch("generate_test_code.parse_function_dependencies")
+ def test_return(self, func_mock1, func_mock2):
+ """
+ Test that begin case is checked and parse_function_code() is called.
+ :return:
+ """
+ func_mock1.return_value = []
+ in_func_code = '''void test_func()
+{
+}
+'''
+ func_dispatch = '''
+ test_func_wrapper,
+'''
+ func_mock2.return_value = 'test_func', [],\
+ in_func_code, func_dispatch
+ dependencies_str = '/* BEGIN_CASE ' \
+ 'depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */\n'
+ data = '''%svoid test_func()
+{
+}
+''' % dependencies_str
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ suite_dependencies, dispatch_code, func_code, func_info = \
+ parse_functions(stream)
+ func_mock1.assert_called_with(dependencies_str)
+ func_mock2.assert_called_with(stream, [], [])
+ self.assertEqual(stream.line_no, 5)
+ self.assertEqual(suite_dependencies, [])
+ expected_dispatch_code = '''/* Function Id: 0 */
+
+ test_func_wrapper,
+'''
+ self.assertEqual(dispatch_code, expected_dispatch_code)
+ self.assertEqual(func_code, in_func_code)
+ self.assertEqual(func_info, {'test_func': (0, [])})
+
+ def test_parsing(self):
+ """
+ Test case parsing.
+ :return:
+ """
+ data = '''/* BEGIN_HEADER */
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_ECP_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void func1()
+{
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void func2()
+{
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ suite_dependencies, dispatch_code, func_code, func_info = \
+ parse_functions(stream)
+ self.assertEqual(stream.line_no, 23)
+ self.assertEqual(suite_dependencies, ['MBEDTLS_ECP_C'])
+
+ expected_dispatch_code = '''/* Function Id: 0 */
+
+#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
+ test_func1_wrapper,
+#else
+ NULL,
+#endif
+/* Function Id: 1 */
+
+#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_FS_IO)
+ test_func2_wrapper,
+#else
+ NULL,
+#endif
+'''
+ self.assertEqual(dispatch_code, expected_dispatch_code)
+ expected_func_code = '''#if defined(MBEDTLS_ECP_C)
+#line 2 "test_suite_ut.function"
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if defined(MBEDTLS_FS_IO)
+#line 13 "test_suite_ut.function"
+void test_func1()
+{
+exit:
+ ;
+}
+
+void test_func1_wrapper( void ** params )
+{
+ (void)params;
+
+ test_func1( );
+}
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if defined(MBEDTLS_FS_IO)
+#line 19 "test_suite_ut.function"
+void test_func2()
+{
+exit:
+ ;
+}
+
+void test_func2_wrapper( void ** params )
+{
+ (void)params;
+
+ test_func2( );
+}
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+#endif /* MBEDTLS_ECP_C */
+'''
+ self.assertEqual(func_code, expected_func_code)
+ self.assertEqual(func_info, {'test_func1': (0, []),
+ 'test_func2': (1, [])})
+
+ def test_same_function_name(self):
+ """
+ Test name conflict.
+ :return:
+ """
+ data = '''/* BEGIN_HEADER */
+#include "mbedtls/ecp.h"
+
+#define ECP_PF_UNKNOWN -1
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_ECP_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void func()
+{
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void func()
+{
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ self.assertRaises(GeneratorInputError, parse_functions, stream)
+
+
+class EscapedSplit(TestCase):
+ """
+ Test suite for testing escaped_split().
+ Note: Since escaped_split() output is used to write back to the
+ intermediate data file. Any escape characters in the input are
+ retained in the output.
+ """
+
+ def test_invalid_input(self):
+ """
+ Test when input split character is not a character.
+ :return:
+ """
+ self.assertRaises(ValueError, escaped_split, '', 'string')
+
+ def test_empty_string(self):
+ """
+ Test empty string input.
+ :return:
+ """
+ splits = escaped_split('', ':')
+ self.assertEqual(splits, [])
+
+ def test_no_escape(self):
+ """
+ Test with no escape character. The behaviour should be same as
+ str.split()
+ :return:
+ """
+ test_str = 'yahoo:google'
+ splits = escaped_split(test_str, ':')
+ self.assertEqual(splits, test_str.split(':'))
+
+ def test_escaped_input(self):
+ """
+ Test input that has escaped delimiter.
+ :return:
+ """
+ test_str = r'yahoo\:google:facebook'
+ splits = escaped_split(test_str, ':')
+ self.assertEqual(splits, [r'yahoo\:google', 'facebook'])
+
+ def test_escaped_escape(self):
+ """
+ Test input that has escaped delimiter.
+ :return:
+ """
+ test_str = r'yahoo\\:google:facebook'
+ splits = escaped_split(test_str, ':')
+ self.assertEqual(splits, [r'yahoo\\', 'google', 'facebook'])
+
+ def test_all_at_once(self):
+ """
+ Test input that has escaped delimiter.
+ :return:
+ """
+ test_str = r'yahoo\\:google:facebook\:instagram\\:bbc\\:wikipedia'
+ splits = escaped_split(test_str, ':')
+ self.assertEqual(splits, [r'yahoo\\', r'google',
+ r'facebook\:instagram\\',
+ r'bbc\\', r'wikipedia'])
+
+
+class ParseTestData(TestCase):
+ """
+ Test suite for parse test data.
+ """
+
+ def test_parser(self):
+ """
+ Test that tests are parsed correctly from data file.
+ :return:
+ """
+ data = """
+Diffie-Hellman full exchange #1
+dhm_do_dhm:10:"23":10:"5"
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+Diffie-Hellman full exchange #3
+dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
+
+Diffie-Hellman selftest
+dhm_selftest:
+"""
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ tests = [(name, test_function, dependencies, args)
+ for name, test_function, dependencies, args in
+ parse_test_data(stream)]
+ test1, test2, test3, test4 = tests
+ self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
+ self.assertEqual(test1[1], 'dhm_do_dhm')
+ self.assertEqual(test1[2], [])
+ self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
+
+ self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
+ self.assertEqual(test2[1], 'dhm_do_dhm')
+ self.assertEqual(test2[2], [])
+ self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
+ '10', '"9345098304850938450983409622"'])
+
+ self.assertEqual(test3[0], 'Diffie-Hellman full exchange #3')
+ self.assertEqual(test3[1], 'dhm_do_dhm')
+ self.assertEqual(test3[2], [])
+ self.assertEqual(test3[3], ['10',
+ '"9345098382739712938719287391879381271"',
+ '10',
+ '"9345098792137312973297123912791271"'])
+
+ self.assertEqual(test4[0], 'Diffie-Hellman selftest')
+ self.assertEqual(test4[1], 'dhm_selftest')
+ self.assertEqual(test4[2], [])
+ self.assertEqual(test4[3], [])
+
+ def test_with_dependencies(self):
+ """
+ Test that tests with dependencies are parsed.
+ :return:
+ """
+ data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+dhm_do_dhm:10:"23":10:"5"
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+"""
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ tests = [(name, function_name, dependencies, args)
+ for name, function_name, dependencies, args in
+ parse_test_data(stream)]
+ test1, test2 = tests
+ self.assertEqual(test1[0], 'Diffie-Hellman full exchange #1')
+ self.assertEqual(test1[1], 'dhm_do_dhm')
+ self.assertEqual(test1[2], ['YAHOO'])
+ self.assertEqual(test1[3], ['10', '"23"', '10', '"5"'])
+
+ self.assertEqual(test2[0], 'Diffie-Hellman full exchange #2')
+ self.assertEqual(test2[1], 'dhm_do_dhm')
+ self.assertEqual(test2[2], [])
+ self.assertEqual(test2[3], ['10', '"93450983094850938450983409623"',
+ '10', '"9345098304850938450983409622"'])
+
+ def test_no_args(self):
+ """
+ Test GeneratorInputError is raised when test function name and
+ args line is missing.
+ :return:
+ """
+ data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+"""
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ err = None
+ try:
+ for _, _, _, _ in parse_test_data(stream):
+ pass
+ except GeneratorInputError as err:
+ self.assertEqual(type(err), GeneratorInputError)
+
+ def test_incomplete_data(self):
+ """
+ Test GeneratorInputError is raised when test function name
+ and args line is missing.
+ :return:
+ """
+ data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+"""
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ err = None
+ try:
+ for _, _, _, _ in parse_test_data(stream):
+ pass
+ except GeneratorInputError as err:
+ self.assertEqual(type(err), GeneratorInputError)
+
+
+class GenDepCheck(TestCase):
+ """
+ Test suite for gen_dep_check(). It is assumed this function is
+ called with valid inputs.
+ """
+
+ def test_gen_dep_check(self):
+ """
+ Test that dependency check code generated correctly.
+ :return:
+ """
+ expected = """
+ case 5:
+ {
+#if defined(YAHOO)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;"""
+ out = gen_dep_check(5, 'YAHOO')
+ self.assertEqual(out, expected)
+
+ def test_not_defined_dependency(self):
+ """
+ Test dependency with !.
+ :return:
+ """
+ expected = """
+ case 5:
+ {
+#if !defined(YAHOO)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;"""
+ out = gen_dep_check(5, '!YAHOO')
+ self.assertEqual(out, expected)
+
+ def test_empty_dependency(self):
+ """
+ Test invalid dependency input.
+ :return:
+ """
+ self.assertRaises(GeneratorInputError, gen_dep_check, 5, '!')
+
+ def test_negative_dep_id(self):
+ """
+ Test invalid dependency input.
+ :return:
+ """
+ self.assertRaises(GeneratorInputError, gen_dep_check, -1, 'YAHOO')
+
+
+class GenExpCheck(TestCase):
+ """
+ Test suite for gen_expression_check(). It is assumed this function
+ is called with valid inputs.
+ """
+
+ def test_gen_exp_check(self):
+ """
+ Test that expression check code generated correctly.
+ :return:
+ """
+ expected = """
+ case 5:
+ {
+ *out_value = YAHOO;
+ }
+ break;"""
+ out = gen_expression_check(5, 'YAHOO')
+ self.assertEqual(out, expected)
+
+ def test_invalid_expression(self):
+ """
+ Test invalid expression input.
+ :return:
+ """
+ self.assertRaises(GeneratorInputError, gen_expression_check, 5, '')
+
+ def test_negative_exp_id(self):
+ """
+ Test invalid expression id.
+ :return:
+ """
+ self.assertRaises(GeneratorInputError, gen_expression_check,
+ -1, 'YAHOO')
+
+
+class WriteDependencies(TestCase):
+ """
+ Test suite for testing write_dependencies.
+ """
+
+ def test_no_test_dependencies(self):
+ """
+ Test when test dependencies input is empty.
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_dependencies = []
+ dep_check_code = write_dependencies(stream, [], unique_dependencies)
+ self.assertEqual(dep_check_code, '')
+ self.assertEqual(len(unique_dependencies), 0)
+ self.assertEqual(stream.getvalue(), '')
+
+ def test_unique_dep_ids(self):
+ """
+
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_dependencies = []
+ dep_check_code = write_dependencies(stream, ['DEP3', 'DEP2', 'DEP1'],
+ unique_dependencies)
+ expect_dep_check_code = '''
+ case 0:
+ {
+#if defined(DEP3)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;
+ case 1:
+ {
+#if defined(DEP2)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;
+ case 2:
+ {
+#if defined(DEP1)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;'''
+ self.assertEqual(dep_check_code, expect_dep_check_code)
+ self.assertEqual(len(unique_dependencies), 3)
+ self.assertEqual(stream.getvalue(), 'depends_on:0:1:2\n')
+
+ def test_dep_id_repeat(self):
+ """
+
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_dependencies = []
+ dep_check_code = ''
+ dep_check_code += write_dependencies(stream, ['DEP3', 'DEP2'],
+ unique_dependencies)
+ dep_check_code += write_dependencies(stream, ['DEP2', 'DEP1'],
+ unique_dependencies)
+ dep_check_code += write_dependencies(stream, ['DEP1', 'DEP3'],
+ unique_dependencies)
+ expect_dep_check_code = '''
+ case 0:
+ {
+#if defined(DEP3)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;
+ case 1:
+ {
+#if defined(DEP2)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;
+ case 2:
+ {
+#if defined(DEP1)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;'''
+ self.assertEqual(dep_check_code, expect_dep_check_code)
+ self.assertEqual(len(unique_dependencies), 3)
+ self.assertEqual(stream.getvalue(),
+ 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
+
+
+class WriteParams(TestCase):
+ """
+ Test Suite for testing write_parameters().
+ """
+
+ def test_no_params(self):
+ """
+ Test with empty test_args
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_expressions = []
+ expression_code = write_parameters(stream, [], [], unique_expressions)
+ self.assertEqual(len(unique_expressions), 0)
+ self.assertEqual(expression_code, '')
+ self.assertEqual(stream.getvalue(), '\n')
+
+ def test_no_exp_param(self):
+ """
+ Test when there is no macro or expression in the params.
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_expressions = []
+ expression_code = write_parameters(stream, ['"Yahoo"', '"abcdef00"',
+ '0'],
+ ['char*', 'hex', 'int'],
+ unique_expressions)
+ self.assertEqual(len(unique_expressions), 0)
+ self.assertEqual(expression_code, '')
+ self.assertEqual(stream.getvalue(),
+ ':char*:"Yahoo":hex:"abcdef00":int:0\n')
+
+ def test_hex_format_int_param(self):
+ """
+ Test int parameter in hex format.
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_expressions = []
+ expression_code = write_parameters(stream,
+ ['"Yahoo"', '"abcdef00"', '0xAA'],
+ ['char*', 'hex', 'int'],
+ unique_expressions)
+ self.assertEqual(len(unique_expressions), 0)
+ self.assertEqual(expression_code, '')
+ self.assertEqual(stream.getvalue(),
+ ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
+
+ def test_with_exp_param(self):
+ """
+ Test when there is macro or expression in the params.
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_expressions = []
+ expression_code = write_parameters(stream,
+ ['"Yahoo"', '"abcdef00"', '0',
+ 'MACRO1', 'MACRO2', 'MACRO3'],
+ ['char*', 'hex', 'int',
+ 'int', 'int', 'int'],
+ unique_expressions)
+ self.assertEqual(len(unique_expressions), 3)
+ self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
+ expected_expression_code = '''
+ case 0:
+ {
+ *out_value = MACRO1;
+ }
+ break;
+ case 1:
+ {
+ *out_value = MACRO2;
+ }
+ break;
+ case 2:
+ {
+ *out_value = MACRO3;
+ }
+ break;'''
+ self.assertEqual(expression_code, expected_expression_code)
+ self.assertEqual(stream.getvalue(),
+ ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1'
+ ':exp:2\n')
+
+ def test_with_repeat_calls(self):
+ """
+ Test when write_parameter() is called with same macro or expression.
+ :return:
+ """
+ stream = StringIOWrapper('test_suite_ut.data', '')
+ unique_expressions = []
+ expression_code = ''
+ expression_code += write_parameters(stream,
+ ['"Yahoo"', 'MACRO1', 'MACRO2'],
+ ['char*', 'int', 'int'],
+ unique_expressions)
+ expression_code += write_parameters(stream,
+ ['"abcdef00"', 'MACRO2', 'MACRO3'],
+ ['hex', 'int', 'int'],
+ unique_expressions)
+ expression_code += write_parameters(stream,
+ ['0', 'MACRO3', 'MACRO1'],
+ ['int', 'int', 'int'],
+ unique_expressions)
+ self.assertEqual(len(unique_expressions), 3)
+ self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
+ expected_expression_code = '''
+ case 0:
+ {
+ *out_value = MACRO1;
+ }
+ break;
+ case 1:
+ {
+ *out_value = MACRO2;
+ }
+ break;
+ case 2:
+ {
+ *out_value = MACRO3;
+ }
+ break;'''
+ self.assertEqual(expression_code, expected_expression_code)
+ expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
+:hex:"abcdef00":exp:1:exp:2
+:int:0:exp:2:exp:0
+'''
+ self.assertEqual(stream.getvalue(), expected_data_file)
+
+
+class GenTestSuiteDependenciesChecks(TestCase):
+ """
+ Test suite for testing gen_suite_dep_checks()
+ """
+ def test_empty_suite_dependencies(self):
+ """
+ Test with empty suite_dependencies list.
+
+ :return:
+ """
+ dep_check_code, expression_code = \
+ gen_suite_dep_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
+ self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
+ self.assertEqual(expression_code, 'EXPRESSION_CODE')
+
+ def test_suite_dependencies(self):
+ """
+ Test with suite_dependencies list.
+
+ :return:
+ """
+ dep_check_code, expression_code = \
+ gen_suite_dep_checks(['SUITE_DEP'], 'DEP_CHECK_CODE',
+ 'EXPRESSION_CODE')
+ expected_dep_check_code = '''
+#if defined(SUITE_DEP)
+DEP_CHECK_CODE
+#endif
+'''
+ expected_expression_code = '''
+#if defined(SUITE_DEP)
+EXPRESSION_CODE
+#endif
+'''
+ self.assertEqual(dep_check_code, expected_dep_check_code)
+ self.assertEqual(expression_code, expected_expression_code)
+
+ def test_no_dep_no_exp(self):
+ """
+ Test when there are no dependency and expression code.
+ :return:
+ """
+ dep_check_code, expression_code = gen_suite_dep_checks([], '', '')
+ self.assertEqual(dep_check_code, '')
+ self.assertEqual(expression_code, '')
+
+
+class GenFromTestData(TestCase):
+ """
+ Test suite for gen_from_test_data()
+ """
+
+ @staticmethod
+ @patch("generate_test_code.write_dependencies")
+ @patch("generate_test_code.write_parameters")
+ @patch("generate_test_code.gen_suite_dep_checks")
+ def test_intermediate_data_file(func_mock1,
+ write_parameters_mock,
+ write_dependencies_mock):
+ """
+ Test that intermediate data file is written with expected data.
+ :return:
+ """
+ data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+ data_f = StringIOWrapper('test_suite_ut.data', data)
+ out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+ func_info = {'test_func1': (1, ('int',))}
+ suite_dependencies = []
+ write_parameters_mock.side_effect = write_parameters
+ write_dependencies_mock.side_effect = write_dependencies
+ func_mock1.side_effect = gen_suite_dep_checks
+ gen_from_test_data(data_f, out_data_f, func_info, suite_dependencies)
+ write_dependencies_mock.assert_called_with(out_data_f,
+ ['DEP1'], ['DEP1'])
+ write_parameters_mock.assert_called_with(out_data_f, ['0'],
+ ('int',), [])
+ expected_dep_check_code = '''
+ case 0:
+ {
+#if defined(DEP1)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;'''
+ func_mock1.assert_called_with(
+ suite_dependencies, expected_dep_check_code, '')
+
+ def test_function_not_found(self):
+ """
+ Test that AssertError is raised when function info in not found.
+ :return:
+ """
+ data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+ data_f = StringIOWrapper('test_suite_ut.data', data)
+ out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+ func_info = {'test_func2': (1, ('int',))}
+ suite_dependencies = []
+ self.assertRaises(GeneratorInputError, gen_from_test_data,
+ data_f, out_data_f, func_info, suite_dependencies)
+
+ def test_different_func_args(self):
+ """
+ Test that AssertError is raised when no. of parameters and
+ function args differ.
+ :return:
+ """
+ data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+ data_f = StringIOWrapper('test_suite_ut.data', data)
+ out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+ func_info = {'test_func2': (1, ('int', 'hex'))}
+ suite_dependencies = []
+ self.assertRaises(GeneratorInputError, gen_from_test_data, data_f,
+ out_data_f, func_info, suite_dependencies)
+
+ def test_output(self):
+ """
+ Test that intermediate data file is written with expected data.
+ :return:
+ """
+ data = '''
+My test 1
+depends_on:DEP1
+func1:0:0xfa:MACRO1:MACRO2
+
+My test 2
+depends_on:DEP1:DEP2
+func2:"yahoo":88:MACRO1
+'''
+ data_f = StringIOWrapper('test_suite_ut.data', data)
+ out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+ func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')),
+ 'test_func2': (1, ('char*', 'int', 'int'))}
+ suite_dependencies = []
+ dep_check_code, expression_code = \
+ gen_from_test_data(data_f, out_data_f, func_info,
+ suite_dependencies)
+ expected_dep_check_code = '''
+ case 0:
+ {
+#if defined(DEP1)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;
+ case 1:
+ {
+#if defined(DEP2)
+ ret = DEPENDENCY_SUPPORTED;
+#else
+ ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+ }
+ break;'''
+ expected_data = '''My test 1
+depends_on:0
+0:int:0:int:0xfa:exp:0:exp:1
+
+My test 2
+depends_on:0:1
+1:char*:"yahoo":int:88:exp:0
+
+'''
+ expected_expression_code = '''
+ case 0:
+ {
+ *out_value = MACRO1;
+ }
+ break;
+ case 1:
+ {
+ *out_value = MACRO2;
+ }
+ break;'''
+ self.assertEqual(dep_check_code, expected_dep_check_code)
+ self.assertEqual(out_data_f.getvalue(), expected_data)
+ self.assertEqual(expression_code, expected_expression_code)
+
+
+if __name__ == '__main__':
+ unittest_main()
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_zeroize.gdb b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_zeroize.gdb
new file mode 100644
index 000000000..2f995d2a3
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/test_zeroize.gdb
@@ -0,0 +1,71 @@
+# test_zeroize.gdb
+#
+# This file is part of Mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2018, Arm Limited, All Rights Reserved
+#
+# Purpose
+#
+# Run a test using the debugger to check that the mbedtls_platform_zeroize()
+# function in platform_util.h is not being optimized out by the compiler. To do
+# so, the script loads the test program at programs/test/zeroize.c and sets a
+# breakpoint at the last return statement in main(). When the breakpoint is
+# hit, the debugger manually checks the contents to be zeroized and checks that
+# it is actually cleared.
+#
+# The mbedtls_platform_zeroize() test is debugger driven because there does not
+# seem to be a mechanism to reliably check whether the zeroize calls are being
+# eliminated by compiler optimizations from within the compiled program. The
+# problem is that a compiler would typically remove what it considers to be
+# "unecessary" assignments as part of redundant code elimination. To identify
+# such code, the compilar will create some form dependency graph between
+# reads and writes to variables (among other situations). It will then use this
+# data structure to remove redundant code that does not have an impact on the
+# program's observable behavior. In the case of mbedtls_platform_zeroize(), an
+# intelligent compiler could determine that this function clears a block of
+# memory that is not accessed later in the program, so removing the call to
+# mbedtls_platform_zeroize() does not have an observable behavior. However,
+# inserting a test after a call to mbedtls_platform_zeroize() to check whether
+# the block of memory was correctly zeroed would force the compiler to not
+# eliminate the mbedtls_platform_zeroize() call. If this does not occur, then
+# the compiler potentially has a bug.
+#
+# Note: This test requires that the test program is compiled with -g3.
+#
+# WARNING: There does not seem to be a mechanism in GDB scripts to set a
+# breakpoint at the end of a function (probably because there are a lot of
+# complications as function can have multiple exit points, etc). Therefore, it
+# was necessary to hard-code the line number of the breakpoint in the zeroize.c
+# test app. The assumption is that zeroize.c is a simple test app that does not
+# change often (as opposed to the actual library code), so the breakpoint line
+# number does not need to be updated often.
+
+set confirm off
+
+file ./programs/test/zeroize
+break zeroize.c:100
+
+set args ./programs/test/zeroize.c
+run
+
+set $i = 0
+set $len = sizeof(buf)
+set $buf = buf
+
+while $i < $len
+ if $buf[$i++] != 0
+ echo The buffer at was not zeroized\n
+ quit 1
+ end
+end
+
+echo The buffer was correctly zeroized\n
+
+continue
+
+if $_exitcode != 0
+ echo The program did not terminate correctly\n
+ quit 1
+end
+
+quit 0
diff --git a/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/travis-log-failure.sh b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/travis-log-failure.sh
new file mode 100755
index 000000000..9866ca7da
--- /dev/null
+++ b/roms/skiboot/libstb/crypto/mbedtls/tests/scripts/travis-log-failure.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# travis-log-failure.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# List the server and client logs on failed ssl-opt.sh and compat.sh tests.
+# This script is used to make the logs show up in the Travis test results.
+#
+# Some of the logs can be very long: this means usually a couple of megabytes
+# but it can be much more. For example, the client log of test 273 in ssl-opt.sh
+# is more than 630 Megabytes long.
+
+if [ -d include/mbedtls ]; then :; else
+ echo "$0: must be run from root" >&2
+ exit 1
+fi
+
+FILES="o-srv-*.log o-cli-*.log c-srv-*.log c-cli-*.log o-pxy-*.log"
+MAX_LOG_SIZE=1048576
+
+for PATTERN in $FILES; do
+ for LOG in $( ls tests/$PATTERN 2>/dev/null ); do
+ echo
+ echo "****** BEGIN file: $LOG ******"
+ echo
+ tail -c $MAX_LOG_SIZE $LOG
+ echo "****** END file: $LOG ******"
+ echo
+ rm $LOG
+ done
+done