Feature/mbedtls (#84)

* try to import mbedtls and build it

* add stubs socket class

* some boilterplate, read and write function implemented

* more boilterplate / current error in handshake because no CA cert is setup

* add something so skip ca verification, can ws curl https://google.com !

* cleanup / close implemented

* tweak CMakefiles

* typo in include

* update readme

* disable unittests
This commit is contained in:
Benjamin Sergeant
2019-06-01 17:41:48 -07:00
committed by GitHub
parent ba4a9e1586
commit 06cbebe22e
1614 changed files with 441051 additions and 13 deletions

1333
third_party/mbedtls/tests/scripts/all.sh vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,225 @@
#!/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
if [ ! -f "seedfile" ]; then
dd if=/dev/urandom of="seedfile" bs=32 count=1
fi
# 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

View File

@ -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__

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

67
third_party/mbedtls/tests/scripts/curves.pl vendored Executable file
View File

@ -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( "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;

View File

@ -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;

View File

@ -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;

29
third_party/mbedtls/tests/scripts/doxygen.sh vendored Executable file
View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,38 @@
#!/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_ret=
CFLAGS=-fno-asynchronous-unwind-tables make clean lib \
>list-symbols.make.log 2>&1 ||
{
make_ret=$?
echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make clean 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

View File

@ -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()

View File

@ -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;

View File

@ -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:../crypto/library';
$ENV{'DYLD_LIBRARY_PATH'} = '../library:../crypto/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 );

View File

@ -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);

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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
# "unnecessary" 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

View File

@ -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