Merge pull request #8373 from sergio-nsk/sergio-nsk/8372/1
Backport 2.28: Fix compiling AESNI in Mbed-TLS with clang on Windows
diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt
index 18945e5..37480f2 100644
--- a/3rdparty/CMakeLists.txt
+++ b/3rdparty/CMakeLists.txt
@@ -4,11 +4,7 @@
list (APPEND thirdparty_inc)
list (APPEND thirdparty_def)
-execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
-
-if(${result} EQUAL 0)
- add_subdirectory(everest)
-endif()
+add_subdirectory(everest)
set(thirdparty_src ${thirdparty_src} PARENT_SCOPE)
set(thirdparty_lib ${thirdparty_lib} PARENT_SCOPE)
diff --git a/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt b/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt
new file mode 100644
index 0000000..c52aa3d
--- /dev/null
+++ b/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix the build with CMake when Everest is enabled through
+ a user configuration file or the compiler command line. Fixes #8165.
diff --git a/ChangeLog.d/fix-mingw32-build.txt b/ChangeLog.d/fix-mingw32-build.txt
new file mode 100644
index 0000000..feef0a2
--- /dev/null
+++ b/ChangeLog.d/fix-mingw32-build.txt
@@ -0,0 +1,4 @@
+Bugfix
+ * Fix an inconsistency between implementations and usages of `__cpuid`,
+ which mainly causes failures when building Windows target using
+ mingw or clang. Fixes #8334 & #8332.
diff --git a/ChangeLog.d/pkwrite-pem-use-heap.txt b/ChangeLog.d/pkwrite-pem-use-heap.txt
new file mode 100644
index 0000000..11db7b6
--- /dev/null
+++ b/ChangeLog.d/pkwrite-pem-use-heap.txt
@@ -0,0 +1,4 @@
+Changes
+ * Use heap memory to allocate DER encoded public/private key.
+ This reduces stack usage significantly for writing a public/private
+ key to a PEM string.
diff --git a/library/aes.c b/library/aes.c
index d2a3c89..683480a 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -334,7 +334,7 @@
/*
* Round constants
*/
-static const uint32_t RCON[10] =
+static const uint32_t round_constants[10] =
{
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
@@ -381,7 +381,7 @@
/*
* Round constants
*/
-static uint32_t RCON[10];
+static uint32_t round_constants[10];
/*
* Tables generation code
@@ -411,7 +411,7 @@
* calculate the round constants
*/
for (i = 0, x = 1; i < 10; i++) {
- RCON[i] = (uint32_t) x;
+ round_constants[i] = (uint32_t) x;
x = MBEDTLS_BYTE_0(XTIME(x));
}
@@ -637,7 +637,7 @@
case 10:
for (i = 0; i < 10; i++, RK += 4) {
- RK[4] = RK[0] ^ RCON[i] ^
+ RK[4] = RK[0] ^ round_constants[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
@@ -652,7 +652,7 @@
case 12:
for (i = 0; i < 8; i++, RK += 6) {
- RK[6] = RK[0] ^ RCON[i] ^
+ RK[6] = RK[0] ^ round_constants[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
@@ -669,7 +669,7 @@
case 14:
for (i = 0; i < 7; i++, RK += 8) {
- RK[8] = RK[0] ^ RCON[i] ^
+ RK[8] = RK[0] ^ round_constants[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
diff --git a/library/aesni.c b/library/aesni.c
index 8bc74f1..3f62a2e 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -39,10 +39,12 @@
#if defined(MBEDTLS_AESNI_HAVE_CODE)
#if MBEDTLS_AESNI_HAVE_CODE == 2
-#if !defined(_WIN32)
+#if defined(__GNUC__)
#include <cpuid.h>
-#else
+#elif defined(_MSC_VER)
#include <intrin.h>
+#else
+#error "`__cpuid` required by MBEDTLS_AESNI_C is not supported by the compiler"
#endif
#include <immintrin.h>
#endif
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 89fda10..76aad9e 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -256,21 +256,22 @@
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- /* PKCS12 uses CBC with PKCS7 padding */
-
- mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
+ {
+ /* PKCS12 uses CBC with PKCS7 padding */
+ mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- /* For historical reasons, when decrypting, this function works when
- * decrypting even when support for PKCS7 padding is disabled. In this
- * case, it ignores the padding, and so will never report a
- * password mismatch.
- */
- if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
- padding = MBEDTLS_PADDING_NONE;
- }
+ /* For historical reasons, when decrypting, this function works when
+ * decrypting even when support for PKCS7 padding is disabled. In this
+ * case, it ignores the padding, and so will never report a
+ * password mismatch.
+ */
+ if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
+ padding = MBEDTLS_PADDING_NONE;
+ }
#endif
- if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
- goto exit;
+ if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
+ goto exit;
+ }
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
diff --git a/library/pkcs5.c b/library/pkcs5.c
index ebf391a..4dc5fd7 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -251,23 +251,25 @@
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- /* PKCS5 uses CBC with PKCS7 padding (which is the same as
- * "PKCS5 padding" except that it's typically only called PKCS5
- * with 64-bit-block ciphers).
- */
- mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
+ {
+ /* PKCS5 uses CBC with PKCS7 padding (which is the same as
+ * "PKCS5 padding" except that it's typically only called PKCS5
+ * with 64-bit-block ciphers).
+ */
+ mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- /* For historical reasons, when decrypting, this function works when
- * decrypting even when support for PKCS7 padding is disabled. In this
- * case, it ignores the padding, and so will never report a
- * password mismatch.
- */
- if (mode == MBEDTLS_DECRYPT) {
- padding = MBEDTLS_PADDING_NONE;
- }
+ /* For historical reasons, when decrypting, this function works when
+ * decrypting even when support for PKCS7 padding is disabled. In this
+ * case, it ignores the padding, and so will never report a
+ * password mismatch.
+ */
+ if (mode == MBEDTLS_DECRYPT) {
+ padding = MBEDTLS_PADDING_NONE;
+ }
#endif
- if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
- goto exit;
+ if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
+ goto exit;
+ }
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
if ((ret = mbedtls_cipher_crypt(&cipher_ctx, iv, enc_scheme_params.len,
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 88e6855..5e3fcc9 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -571,38 +571,49 @@
int mbedtls_pk_write_pubkey_pem(mbedtls_pk_context *key, unsigned char *buf, size_t size)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- unsigned char output_buf[PUB_DER_MAX_BYTES];
+ unsigned char *output_buf = NULL;
+ output_buf = mbedtls_calloc(1, PUB_DER_MAX_BYTES);
+ if (output_buf == NULL) {
+ return MBEDTLS_ERR_PK_ALLOC_FAILED;
+ }
size_t olen = 0;
PK_VALIDATE_RET(key != NULL);
PK_VALIDATE_RET(buf != NULL || size == 0);
if ((ret = mbedtls_pk_write_pubkey_der(key, output_buf,
- sizeof(output_buf))) < 0) {
- return ret;
+ PUB_DER_MAX_BYTES)) < 0) {
+ goto cleanup;
}
if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
- output_buf + sizeof(output_buf) - ret,
+ output_buf + PUB_DER_MAX_BYTES - ret,
ret, buf, size, &olen)) != 0) {
- return ret;
+ goto cleanup;
}
- return 0;
+ ret = 0;
+cleanup:
+ mbedtls_free(output_buf);
+ return ret;
}
int mbedtls_pk_write_key_pem(mbedtls_pk_context *key, unsigned char *buf, size_t size)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- unsigned char output_buf[PRV_DER_MAX_BYTES];
+ unsigned char *output_buf = NULL;
+ output_buf = mbedtls_calloc(1, PRV_DER_MAX_BYTES);
+ if (output_buf == NULL) {
+ return MBEDTLS_ERR_PK_ALLOC_FAILED;
+ }
const char *begin, *end;
size_t olen = 0;
PK_VALIDATE_RET(key != NULL);
PK_VALIDATE_RET(buf != NULL || size == 0);
- if ((ret = mbedtls_pk_write_key_der(key, output_buf, sizeof(output_buf))) < 0) {
- return ret;
+ if ((ret = mbedtls_pk_write_key_der(key, output_buf, PRV_DER_MAX_BYTES)) < 0) {
+ goto cleanup;
}
#if defined(MBEDTLS_RSA_C)
@@ -617,15 +628,22 @@
end = PEM_END_PRIVATE_KEY_EC;
} else
#endif
- return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
-
- if ((ret = mbedtls_pem_write_buffer(begin, end,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen)) != 0) {
- return ret;
+ {
+ ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+ goto cleanup;
}
- return 0;
+ if ((ret = mbedtls_pem_write_buffer(begin, end,
+ output_buf + PRV_DER_MAX_BYTES - ret,
+ ret, buf, size, &olen)) != 0) {
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ mbedtls_platform_zeroize(output_buf, PRV_DER_MAX_BYTES);
+ mbedtls_free(output_buf);
+ return ret;
}
#endif /* MBEDTLS_PEM_WRITE_C */
diff --git a/programs/demo_common.sh b/programs/demo_common.sh
new file mode 100644
index 0000000..d8fcda5
--- /dev/null
+++ b/programs/demo_common.sh
@@ -0,0 +1,137 @@
+## Common shell functions used by demo scripts programs/*/*.sh.
+
+## How to write a demo script
+## ==========================
+##
+## Include this file near the top of each demo script:
+## . "${0%/*}/../demo_common.sh"
+##
+## Start with a "msg" call that explains the purpose of the script.
+## Then call the "depends_on" function to ensure that all config
+## dependencies are met.
+##
+## As the last thing in the script, call the cleanup function.
+##
+## You can use the functions and variables described below.
+
+set -e -u
+
+## $root_dir is the root directory of the Mbed TLS source tree.
+root_dir="${0%/*}"
+# Find a nice path to the root directory, avoiding unnecessary "../".
+# The code supports demo scripts nested up to 4 levels deep.
+# The code works no matter where the demo script is relative to the current
+# directory, even if it is called with a relative path.
+n=4 # limit the search depth
+while ! [ -d "$root_dir/programs" ] || ! [ -d "$root_dir/library" ]; do
+ if [ $n -eq 0 ]; then
+ echo >&2 "This doesn't seem to be an Mbed TLS source tree."
+ exit 125
+ fi
+ n=$((n - 1))
+ case $root_dir in
+ .) root_dir="..";;
+ ..|?*/..) root_dir="$root_dir/..";;
+ ?*/*) root_dir="${root_dir%/*}";;
+ /*) root_dir="/";;
+ *) root_dir=".";;
+ esac
+done
+
+## $programs_dir is the directory containing the sample programs.
+# Assume an in-tree build.
+programs_dir="$root_dir/programs"
+
+## msg LINE...
+## msg <TEXT_ORIGIN
+## Display an informational message.
+msg () {
+ if [ $# -eq 0 ]; then
+ sed 's/^/# /'
+ else
+ for x in "$@"; do
+ echo "# $x"
+ done
+ fi
+}
+
+## run "Message" COMMAND ARGUMENT...
+## Display the message, then run COMMAND with the specified arguments.
+run () {
+ echo
+ echo "# $1"
+ shift
+ echo "+ $*"
+ "$@"
+}
+
+## Like '!', but stop on failure with 'set -e'
+not () {
+ if "$@"; then false; fi
+}
+
+## run_bad "Message" COMMAND ARGUMENT...
+## Like run, but the command is expected to fail.
+run_bad () {
+ echo
+ echo "$1 This must fail."
+ shift
+ echo "+ ! $*"
+ not "$@"
+}
+
+## config_has SYMBOL...
+## Succeeds if the library configuration has all SYMBOLs set.
+config_has () {
+ for x in "$@"; do
+ "$programs_dir/test/query_compile_time_config" "$x"
+ done
+}
+
+## depends_on SYMBOL...
+## Exit if the library configuration does not have all SYMBOLs set.
+depends_on () {
+ m=
+ for x in "$@"; do
+ if ! config_has "$x"; then
+ m="$m $x"
+ fi
+ done
+ if [ -n "$m" ]; then
+ cat >&2 <<EOF
+$0: this demo requires the following
+configuration options to be enabled at compile time:
+ $m
+EOF
+ # Exit with a success status so that this counts as a pass for run_demos.py.
+ exit
+ fi
+}
+
+## Add the names of files to clean up to this whitespace-separated variable.
+## The file names must not contain whitespace characters.
+files_to_clean=
+
+## Call this function at the end of each script.
+## It is called automatically if the script is killed by a signal.
+cleanup () {
+ rm -f -- $files_to_clean
+}
+
+
+
+################################################################
+## End of the public interfaces. Code beyond this point is not
+## meant to be called directly from a demo script.
+
+trap 'cleanup; trap - HUP; kill -HUP $$' HUP
+trap 'cleanup; trap - INT; kill -INT $$' INT
+trap 'cleanup; trap - TERM; kill -TERM $$' TERM
+
+if config_has MBEDTLS_ENTROPY_NV_SEED; then
+ # Create a seedfile that's sufficiently long in all library configurations.
+ # This is necessary for programs that use randomness.
+ # Assume that the name of the seedfile is the default name.
+ files_to_clean="$files_to_clean seedfile"
+ dd if=/dev/urandom of=seedfile ibs=64 obs=64 count=1
+fi
diff --git a/programs/psa/key_ladder_demo.sh b/programs/psa/key_ladder_demo.sh
index e21d1ab..bb4a24f 100755
--- a/programs/psa/key_ladder_demo.sh
+++ b/programs/psa/key_ladder_demo.sh
@@ -15,36 +15,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -e -u
+. "${0%/*}/../demo_common.sh"
-program_name="key_ladder_demo"
-program="${0%/*}/$program_name"
-files_to_clean=
+msg <<'EOF'
+This script demonstrates the use of the PSA cryptography interface to
+create a master key, derive a key from it and use that derived key to
+wrap some data using an AEAD algorithm.
+EOF
-if [ ! -e "$program" ]; then
- # Look for programs in the current directory and the directories above it
- for dir in "." ".." "../.."; do
- program="$dir/programs/psa/$program_name"
- if [ -e "$program" ]; then
- break
- fi
- done
- if [ ! -e "$program" ]; then
- echo "Could not find $program_name executable"
+depends_on MBEDTLS_SHA256_C MBEDTLS_MD_C MBEDTLS_AES_C MBEDTLS_CCM_C MBEDTLS_PSA_CRYPTO_C MBEDTLS_FS_IO
- echo "If building out-of-tree, this script must be run" \
- "from the project build directory."
- exit 1
- fi
-fi
-
-run () {
- echo
- echo "# $1"
- shift
- echo "+ $*"
- "$@"
-}
+program="${0%/*}"/key_ladder_demo
if [ -e master.key ]; then
echo "# Reusing the existing master.key file."
@@ -68,7 +49,7 @@
cmp input.txt hello_world.txt
files_to_clean="$files_to_clean hellow_orld.txt"
-! run "Derive a different key and attempt to unwrap the data. This must fail." \
+run_bad "Derive a different key and attempt to unwrap the data." \
"$program" unwrap master=master.key input=hello_world.wrap output=hellow_orld.txt label=hellow label=orld
files_to_clean="$files_to_clean hello.key"
@@ -79,5 +60,4 @@
"$program" unwrap master=hello.key label=world \
input=hello_world.wrap output=hello_world.txt
-# Cleanup
-rm -f $files_to_clean
+cleanup
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index ca74c00..f5223fb 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -438,7 +438,7 @@
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
- " acceptable ciphersuite names:\n"
+ "\n"
#define ALPN_LIST_SIZE 10
#define CURVE_LIST_SIZE 20
@@ -767,31 +767,6 @@
mbedtls_test_enable_insecure_external_rng();
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
- if (argc < 2) {
-usage:
- if (ret == 0) {
- ret = 1;
- }
-
- mbedtls_printf(USAGE1);
- mbedtls_printf(USAGE2);
- mbedtls_printf(USAGE3);
- mbedtls_printf(USAGE4);
-
- list = mbedtls_ssl_list_ciphersuites();
- while (*list) {
- mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name(*list));
- list++;
- if (!*list) {
- break;
- }
- mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name(*list));
- list++;
- }
- mbedtls_printf("\n");
- goto exit;
- }
-
opt.server_name = DFL_SERVER_NAME;
opt.server_addr = DFL_SERVER_ADDR;
opt.server_port = DFL_SERVER_PORT;
@@ -864,9 +839,54 @@
opt.force_srtp_profile = DFL_SRTP_FORCE_PROFILE;
opt.mki = DFL_SRTP_MKI;
+ p = q = NULL;
+ if (argc < 1) {
+usage:
+ if (p != NULL && q != NULL) {
+ printf("unrecognized value for '%s': '%s'\n", p, q);
+ } else if (p != NULL && q == NULL) {
+ printf("unrecognized param: '%s'\n", p);
+ }
+
+ mbedtls_printf("usage: ssl_client2 [param=value] [...]\n");
+ mbedtls_printf(" ssl_client2 help[_theme]\n");
+ mbedtls_printf("'help' lists acceptable 'param' and 'value'\n");
+ mbedtls_printf("'help_ciphersuites' lists available ciphersuites\n");
+ mbedtls_printf("\n");
+
+ if (ret == 0) {
+ ret = 1;
+ }
+ goto exit;
+ }
+
for (i = 1; i < argc; i++) {
p = argv[i];
+
+ if (strcmp(p, "help") == 0) {
+ mbedtls_printf(USAGE1);
+ mbedtls_printf(USAGE2);
+ mbedtls_printf(USAGE3);
+ mbedtls_printf(USAGE4);
+
+ ret = 0;
+ goto exit;
+ }
+ if (strcmp(p, "help_ciphersuites") == 0) {
+ mbedtls_printf(" acceptable ciphersuite names:\n");
+ for (list = mbedtls_ssl_list_ciphersuites();
+ *list != 0;
+ list++) {
+ mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name(*list));
+ }
+
+ ret = 0;
+ goto exit;
+ }
+
if ((q = strchr(p, '=')) == NULL) {
+ mbedtls_printf("param requires a value: '%s'\n", p);
+ p = NULL; // avoid "unrecnognized param" message
goto usage;
}
*q++ = '\0';
@@ -1226,9 +1246,13 @@
} else if (strcmp(p, "mki") == 0) {
opt.mki = q;
} else {
+ /* This signals that the problem is with p not q */
+ q = NULL;
goto usage;
}
}
+ /* This signals that any further errors are not with a single option */
+ p = q = NULL;
if (opt.nss_keylog != 0 && opt.eap_tls != 0) {
mbedtls_printf("Error: eap_tls and nss_keylog options cannot be used together.\n");
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index ebdef4f..41b12e9 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -1,5 +1,5 @@
/*
- * MbedTLS SSL context deserializer from base64 code
+ * Mbed TLS SSL context deserializer from base64 code
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index c3c5149..dcd5eca 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -535,7 +535,7 @@
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
- " acceptable ciphersuite names:\n"
+ "\n"
#define ALPN_LIST_SIZE 10
#define CURVE_LIST_SIZE 20
@@ -1449,31 +1449,6 @@
signal(SIGINT, term_handler);
#endif
- if (argc < 2) {
-usage:
- if (ret == 0) {
- ret = 1;
- }
-
- mbedtls_printf(USAGE1);
- mbedtls_printf(USAGE2);
- mbedtls_printf(USAGE3);
- mbedtls_printf(USAGE4);
-
- list = mbedtls_ssl_list_ciphersuites();
- while (*list) {
- mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name(*list));
- list++;
- if (!*list) {
- break;
- }
- mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name(*list));
- list++;
- }
- mbedtls_printf("\n");
- goto exit;
- }
-
opt.buffer_size = DFL_IO_BUF_LEN;
opt.server_addr = DFL_SERVER_ADDR;
opt.server_port = DFL_SERVER_PORT;
@@ -1557,9 +1532,54 @@
opt.force_srtp_profile = DFL_SRTP_FORCE_PROFILE;
opt.support_mki = DFL_SRTP_SUPPORT_MKI;
+ p = q = NULL;
+ if (argc < 1) {
+usage:
+ if (p != NULL && q != NULL) {
+ printf("unrecognized value for '%s': '%s'\n", p, q);
+ } else if (p != NULL && q == NULL) {
+ printf("unrecognized param: '%s'\n", p);
+ }
+
+ mbedtls_printf("usage: ssl_client2 [param=value] [...]\n");
+ mbedtls_printf(" ssl_client2 help[_theme]\n");
+ mbedtls_printf("'help' lists acceptable 'param' and 'value'\n");
+ mbedtls_printf("'help_ciphersuites' lists available ciphersuites\n");
+ mbedtls_printf("\n");
+
+ if (ret == 0) {
+ ret = 1;
+ }
+ goto exit;
+ }
+
for (i = 1; i < argc; i++) {
p = argv[i];
+
+ if (strcmp(p, "help") == 0) {
+ mbedtls_printf(USAGE1);
+ mbedtls_printf(USAGE2);
+ mbedtls_printf(USAGE3);
+ mbedtls_printf(USAGE4);
+
+ ret = 0;
+ goto exit;
+ }
+ if (strcmp(p, "help_ciphersuites") == 0) {
+ mbedtls_printf(" acceptable ciphersuite names:\n");
+ for (list = mbedtls_ssl_list_ciphersuites();
+ *list != 0;
+ list++) {
+ mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name(*list));
+ }
+
+ ret = 0;
+ goto exit;
+ }
+
if ((q = strchr(p, '=')) == NULL) {
+ mbedtls_printf("param requires a value: '%s'\n", p);
+ p = NULL; // avoid "unrecnognized param" message
goto usage;
}
*q++ = '\0';
@@ -1949,9 +1969,13 @@
} else if (strcmp(p, "support_mki") == 0) {
opt.support_mki = atoi(q);
} else {
+ /* This signals that the problem is with p not q */
+ q = NULL;
goto usage;
}
}
+ /* This signals that any further erorrs are not with a single option */
+ p = q = NULL;
if (opt.nss_keylog != 0 && opt.eap_tls != 0) {
mbedtls_printf("Error: eap_tls and nss_keylog options cannot be used together.\n");
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index bbb7046..cf92e95 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -89,12 +89,12 @@
#define HEADER_FORMAT " %-24s : "
#define TITLE_LEN 25
-#define OPTIONS \
- "md4, md5, ripemd160, sha1, sha256, sha512,\n" \
- "arc4, des3, des, camellia, blowfish, chacha20,\n" \
- "aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,\n" \
- "aes_cmac, des3_cmac, poly1305\n" \
- "havege, ctr_drbg, hmac_drbg\n" \
+#define OPTIONS \
+ "md4, md5, ripemd160, sha1, sha256, sha512,\n" \
+ "arc4, des3, des, camellia, blowfish, chacha20,\n" \
+ "aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly,\n" \
+ "aes_cmac, des3_cmac, poly1305\n" \
+ "havege, ctr_drbg, hmac_drbg\n" \
"rsa, dhm, ecdsa, ecdh.\n"
#if defined(MBEDTLS_ERROR_C)
@@ -280,7 +280,7 @@
typedef struct {
char md4, md5, ripemd160, sha1, sha256, sha512,
arc4, des3, des,
- aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,
+ aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly,
aes_cmac, des3_cmac,
aria, camellia, blowfish, chacha20,
poly1305,
@@ -336,6 +336,10 @@
todo.des = 1;
} else if (strcmp(argv[i], "aes_cbc") == 0) {
todo.aes_cbc = 1;
+ } else if (strcmp(argv[i], "aes_cfb128") == 0) {
+ todo.aes_cfb128 = 1;
+ } else if (strcmp(argv[i], "aes_cfb8") == 0) {
+ todo.aes_cfb8 = 1;
} else if (strcmp(argv[i], "aes_xts") == 0) {
todo.aes_xts = 1;
} else if (strcmp(argv[i], "aes_gcm") == 0) {
@@ -432,6 +436,7 @@
#if defined(MBEDTLS_ARC4_C)
if (todo.arc4) {
mbedtls_arc4_context arc4;
+
mbedtls_arc4_init(&arc4);
mbedtls_arc4_setup(&arc4, tmp, 32);
TIME_AND_TSC("ARC4", mbedtls_arc4_crypt(&arc4, BUFSIZE, buf, buf));
@@ -443,6 +448,7 @@
#if defined(MBEDTLS_CIPHER_MODE_CBC)
if (todo.des3) {
mbedtls_des3_context des3;
+
mbedtls_des3_init(&des3);
if (mbedtls_des3_set3key_enc(&des3, tmp) != 0) {
mbedtls_exit(1);
@@ -454,6 +460,7 @@
if (todo.des) {
mbedtls_des_context des;
+
mbedtls_des_init(&des);
if (mbedtls_des_setkey_enc(&des, tmp) != 0) {
mbedtls_exit(1);
@@ -486,6 +493,7 @@
if (todo.aes_cbc) {
int keysize;
mbedtls_aes_context aes;
+
mbedtls_aes_init(&aes);
for (keysize = 128; keysize <= 256; keysize += 64) {
mbedtls_snprintf(title, sizeof(title), "AES-CBC-%d", keysize);
@@ -500,6 +508,44 @@
mbedtls_aes_free(&aes);
}
#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ if (todo.aes_cfb128) {
+ int keysize;
+ size_t iv_off = 0;
+ mbedtls_aes_context aes;
+
+ mbedtls_aes_init(&aes);
+ for (keysize = 128; keysize <= 256; keysize += 64) {
+ mbedtls_snprintf(title, sizeof(title), "AES-CFB128-%d", keysize);
+
+ memset(buf, 0, sizeof(buf));
+ memset(tmp, 0, sizeof(tmp));
+ CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
+
+ TIME_AND_TSC(title,
+ mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE,
+ &iv_off, tmp, buf, buf));
+ }
+ mbedtls_aes_free(&aes);
+ }
+ if (todo.aes_cfb8) {
+ int keysize;
+ mbedtls_aes_context aes;
+
+ mbedtls_aes_init(&aes);
+ for (keysize = 128; keysize <= 256; keysize += 64) {
+ mbedtls_snprintf(title, sizeof(title), "AES-CFB8-%d", keysize);
+
+ memset(buf, 0, sizeof(buf));
+ memset(tmp, 0, sizeof(tmp));
+ CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
+
+ TIME_AND_TSC(title,
+ mbedtls_aes_crypt_cfb8(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf));
+ }
+ mbedtls_aes_free(&aes);
+ }
+#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
if (todo.aes_xts) {
int keysize;
@@ -617,6 +663,7 @@
if (todo.aria) {
int keysize;
mbedtls_aria_context aria;
+
mbedtls_aria_init(&aria);
for (keysize = 128; keysize <= 256; keysize += 64) {
mbedtls_snprintf(title, sizeof(title), "ARIA-CBC-%d", keysize);
@@ -637,6 +684,7 @@
if (todo.camellia) {
int keysize;
mbedtls_camellia_context camellia;
+
mbedtls_camellia_init(&camellia);
for (keysize = 128; keysize <= 256; keysize += 64) {
mbedtls_snprintf(title, sizeof(title), "CAMELLIA-CBC-%d", keysize);
@@ -669,6 +717,7 @@
if (todo.blowfish) {
int keysize;
mbedtls_blowfish_context blowfish;
+
mbedtls_blowfish_init(&blowfish);
for (keysize = 128; keysize <= 256; keysize += 64) {
@@ -690,6 +739,7 @@
#if defined(MBEDTLS_HAVEGE_C)
if (todo.havege) {
mbedtls_havege_state hs;
+
mbedtls_havege_init(&hs);
TIME_AND_TSC("HAVEGE", mbedtls_havege_random(&hs, buf, BUFSIZE));
mbedtls_havege_free(&hs);
@@ -774,6 +824,7 @@
if (todo.rsa) {
int keysize;
mbedtls_rsa_context rsa;
+
for (keysize = 2048; keysize <= 4096; keysize *= 2) {
mbedtls_snprintf(title, sizeof(title), "RSA-%d", keysize);
@@ -815,6 +866,7 @@
mbedtls_dhm_context dhm;
size_t olen;
+
for (i = 0; (size_t) i < sizeof(dhm_sizes) / sizeof(dhm_sizes[0]); i++) {
mbedtls_dhm_init(&dhm);
@@ -928,6 +980,7 @@
if (curve_list == (const mbedtls_ecp_curve_info *) &single_curve) {
mbedtls_ecp_group grp;
+
mbedtls_ecp_group_init(&grp);
if (mbedtls_ecp_group_load(&grp, curve_list->grp_id) != 0) {
mbedtls_exit(1);
diff --git a/programs/test/dlopen_demo.sh b/programs/test/dlopen_demo.sh
index a6a9022..b162d7b 100755
--- a/programs/test/dlopen_demo.sh
+++ b/programs/test/dlopen_demo.sh
@@ -18,34 +18,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -e -u
+. "${0%/*}/../demo_common.sh"
-program_name="dlopen"
-program_dir="${0%/*}"
-program="$program_dir/$program_name"
+msg "Test the dynamic loading of libmbed*"
+program="$programs_dir/test/dlopen"
+library_dir="$root_dir/library"
+
+# Skip this test if we don't have a shared library build. Detect this
+# through the absence of the demo program.
if [ ! -e "$program" ]; then
- # Look for programs in the current directory and the directories above it
- for dir in "." ".." "../.."; do
- program_dir="$dir/programs/test"
- program="$program_dir/$program_name"
- if [ -e "$program" ]; then
- break
- fi
- done
- if [ ! -e "$program" ]; then
- echo "Could not find $program_name program"
-
- echo "Make sure that Mbed TLS is built as a shared library." \
- "If building out-of-tree, this script must be run" \
- "from the project build directory."
- exit 1
- fi
+ msg "$0: this demo requires a shared library build."
+ # Exit with a success status so that this counts as a pass for run_demos.py.
+ exit
fi
-top_dir="$program_dir/../.."
-library_dir="$top_dir/library"
-
# ELF-based Unix-like (Linux, *BSD, Solaris, ...)
if [ -n "${LD_LIBRARY_PATH-}" ]; then
LD_LIBRARY_PATH="$library_dir:$LD_LIBRARY_PATH"
@@ -62,6 +49,6 @@
fi
export DYLD_LIBRARY_PATH
-echo "Running dynamic loading test program: $program"
-echo "Loading libraries from: $library_dir"
+msg "Running dynamic loading test program: $program"
+msg "Loading libraries from: $library_dir"
"$program"
diff --git a/scripts/assemble_changelog.py b/scripts/assemble_changelog.py
index d27cc47..d44678b 100755
--- a/scripts/assemble_changelog.py
+++ b/scripts/assemble_changelog.py
@@ -60,6 +60,11 @@
message = ('Lost content from {}: "{}"'.format(filename, line))
super().__init__(message)
+class FilePathError(Exception):
+ def __init__(self, filenames):
+ message = ('Changelog filenames do not end with .txt: {}'.format(", ".join(filenames)))
+ super().__init__(message)
+
# The category names we use in the changelog.
# If you edit this, update ChangeLog.d/README.md.
STANDARD_CATEGORIES = (
@@ -445,8 +450,21 @@
"""List the entry files to merge, oldest first.
"Oldest" is defined by `EntryFileSortKey`.
+
+ Also check for required .txt extension
"""
- files_to_merge = glob.glob(os.path.join(options.dir, '*.txt'))
+ files_to_merge = glob.glob(os.path.join(options.dir, '*'))
+
+ # Ignore 00README.md
+ readme = os.path.join(options.dir, "00README.md")
+ if readme in files_to_merge:
+ files_to_merge.remove(readme)
+
+ # Identify files without the required .txt extension
+ bad_files = [x for x in files_to_merge if not x.endswith(".txt")]
+ if bad_files:
+ raise FilePathError(bad_files)
+
files_to_merge.sort(key=EntryFileSortKey)
return files_to_merge
@@ -454,6 +472,7 @@
"""Merge changelog entries into the changelog file.
Read the changelog file from options.input.
+ Check that all entries have a .txt extension
Read entries to merge from the directory options.dir.
Write the new changelog to options.output.
Remove the merged entries if options.keep_entries is false.
diff --git a/scripts/output_env.sh b/scripts/output_env.sh
index 5356132..63628e7 100755
--- a/scripts/output_env.sh
+++ b/scripts/output_env.sh
@@ -192,20 +192,6 @@
print_version "$GNUTLS_SERV" "--version" "default" "head -n 1"
echo
-if [ -n "${GNUTLS_LEGACY_CLI+set}" ]; then
- print_version "$GNUTLS_LEGACY_CLI" "--version" "legacy" "head -n 1"
-else
- echo " * gnutls-cli (legacy): Not configured."
-fi
-echo
-
-if [ -n "${GNUTLS_LEGACY_SERV+set}" ]; then
- print_version "$GNUTLS_LEGACY_SERV" "--version" "legacy" "head -n 1"
-else
- echo " * gnutls-serv (legacy): Not configured."
-fi
-echo
-
echo " * Installed asan versions:"
if type dpkg-query >/dev/null 2>/dev/null; then
if ! dpkg-query -f '${Status} ${Package}: ${Version}\n' -W 'libasan*' |
diff --git a/tests/compat.sh b/tests/compat.sh
index ba8465b..de9dc40 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -110,6 +110,7 @@
EXCLUDE='NULL\|DES\|RC4\|ARCFOUR\|ARIA\|CHACHA20-POLY1305'
VERBOSE=""
MEMCHECK=0
+PRESERVE_LOGS=0
PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
# hidden option: skip DTLS with OpenSSL
@@ -131,6 +132,7 @@
printf " --list-test-case\tList all potential test cases (No Execution)\n"
printf " --outcome-file\tFile where test outcomes are written\n"
printf " \t(default: \$MBEDTLS_TEST_OUTCOME_FILE, none if empty)\n"
+ printf " --preserve-logs\tPreserve logs of successful tests as well\n"
}
# print_test_case <CLIENT> <SERVER> <STANDARD_CIPHER_SUITE>
@@ -198,6 +200,9 @@
--outcome-file)
shift; MBEDTLS_TEST_OUTCOME_FILE=$1
;;
+ --preserve-logs)
+ PRESERVE_LOGS=1
+ ;;
-h|--help)
print_usage
exit 0
@@ -648,7 +653,16 @@
;;
"RSA")
- if [ `minor_ver "$MODE"` -gt 0 ]
+ # TLS-RSA-WITH-NULL-SHA256 is a (D)TLS 1.2-only cipher suite,
+ # like all SHA256 cipher suites. But Mbed TLS supports it with
+ # (D)TLS 1.0 and 1.1 as well. So do ancient versions of GnuTLS,
+ # but this was considered a bug which was fixed in GnuTLS 3.4.7.
+ # Check the GnuTLS support list to see what the protocol version
+ # requirement is for that cipher suite.
+ if [ `minor_ver "$MODE"` -ge 3 ] || {
+ [ `minor_ver "$MODE"` -gt 0 ] &&
+ $GNUTLS_CLI --list | grep -q '^TLS_RSA_NULL_SHA256.*0$'
+ }
then
M_CIPHERS="$M_CIPHERS \
TLS-RSA-WITH-NULL-SHA256 \
@@ -972,7 +986,7 @@
fi
M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
- O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$O_MODE"
+ O_SERVER_ARGS="-accept $PORT -cipher ALL,COMPLEMENTOFALL -$O_MODE"
G_SERVER_ARGS="-p $PORT --http $G_MODE"
G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
@@ -1218,12 +1232,16 @@
fi
}
+save_logs() {
+ cp $SRV_OUT c-srv-${TESTS}.log
+ cp $CLI_OUT c-cli-${TESTS}.log
+}
+
# display additional information if test case fails
report_fail() {
FAIL_PROMPT="outputs saved to c-srv-${TESTS}.log, c-cli-${TESTS}.log"
record_outcome "FAIL" "$FAIL_PROMPT"
- cp $SRV_OUT c-srv-${TESTS}.log
- cp $CLI_OUT c-cli-${TESTS}.log
+ save_logs
echo " ! $FAIL_PROMPT"
if [ "${LOG_FAILURE_ON_STDOUT:-0}" != 0 ]; then
@@ -1349,6 +1367,9 @@
case $RESULT in
"0")
record_outcome "PASS"
+ if [ "$PRESERVE_LOGS" -gt 0 ]; then
+ save_logs
+ fi
;;
"1")
record_outcome "SKIP"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index afb4a9d..d3e9cda 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -50,10 +50,14 @@
# * 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).
+# * OpenSSL and GnuTLS command line tools, in suitable versions for the
+# interoperability tests. The following are the official versions at the
+# time of writing:
+# * GNUTLS_{CLI,SERV} = 3.4.10
+# * GNUTLS_NEXT_{CLI,SERV} = 3.7.2
+# * OPENSSL_LEGACY = 1.0.1j
+# * OPENSSL = 1.0.2g (without Debian/Ubuntu patches)
+# * OPENSSL_NEXT = 1.1.1a
# See the invocation of check_tools below for details.
#
# This script must be invoked from the toplevel directory of a git
@@ -168,8 +172,6 @@
: ${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}
@@ -286,8 +288,6 @@
--gcc-latest=<GCC_latest_path> Latest version of GCC available
--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
@@ -435,8 +435,8 @@
--gcc-earliest) shift; GCC_EARLIEST="$1";;
--gcc-latest) shift; GCC_LATEST="$1";;
--gnutls-cli) shift; GNUTLS_CLI="$1";;
- --gnutls-legacy-cli) shift; GNUTLS_LEGACY_CLI="$1";;
- --gnutls-legacy-serv) shift; GNUTLS_LEGACY_SERV="$1";;
+ --gnutls-legacy-cli) shift;; # ignored for backward compatibility
+ --gnutls-legacy-serv) shift;; # ignored for backward compatibility
--gnutls-serv) shift; GNUTLS_SERV="$1";;
--help|-h) usage; exit;;
--keep-going|-k) KEEP_GOING=1;;
@@ -709,8 +709,6 @@
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"
}
@@ -736,11 +734,8 @@
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"
+ "$GNUTLS_CLI" "$GNUTLS_SERV"
;;
esac
@@ -873,6 +868,9 @@
msg "selftest: make, default config (out-of-box)" # ~10s
programs/test/selftest
+
+ msg "program demos: make, default config (out-of-box)" # ~10s
+ tests/scripts/run_demos.py
}
component_test_default_cmake_gcc_asan () {
@@ -883,6 +881,9 @@
msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
make test
+ msg "program demos (ASan build)" # ~10s
+ tests/scripts/run_demos.py
+
msg "test: selftest (ASan build)" # ~ 10s
programs/test/selftest
@@ -1031,8 +1032,7 @@
make test
msg "build: SSLv3 - compat.sh (ASan build)" # ~ 6 min
- tests/compat.sh -m 'tls1 tls1_1 tls12 dtls1 dtls12'
- env OPENSSL="$OPENSSL_LEGACY" tests/compat.sh -m 'ssl3'
+ tests/compat.sh -m 'ssl3 tls1 tls1_1 tls12 dtls1 dtls12'
msg "build: SSLv3 - ssl-opt.sh (ASan build)" # ~ 6 min
tests/ssl-opt.sh
@@ -1584,14 +1584,20 @@
msg "test: cpp_dummy_build (full config, clang)" # ~ 1s
programs/test/cpp_dummy_build
+ msg "program demos (full config, clang)" # ~10s
+ tests/scripts/run_demos.py
+
msg "test: psa_constant_names (full config, clang)" # ~ 1s
tests/scripts/test_psa_constant_names.py
msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
- msg "test: compat.sh RC4, DES, 3DES & NULL (full config)" # ~ 2 min
- env OPENSSL="$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 RC4, 3DES & NULL (full config)" # ~ 2min
+ tests/compat.sh -e '^$' -f 'NULL\|3DES\|DES-CBC3\|RC4\|ARCFOUR'
+
+ msg "test: compat.sh single-DES (full config)" # ~ 30s
+ env OPENSSL="$OPENSSL_LEGACY" tests/compat.sh -e '3DES\|DES-CBC3' -f 'DES'
msg "test: compat.sh ARIA + ChachaPoly"
env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
@@ -1701,6 +1707,9 @@
msg "test: full config + MBEDTLS_TEST_DEPRECATED" # ~ 30s
make test
+
+ msg "program demos: full config + MBEDTLS_TEST_DEPRECATED" # ~10s
+ tests/scripts/run_demos.py
}
# Check that the specified libraries exist and are empty.
@@ -1881,8 +1890,11 @@
msg "test: compat.sh default (full minus MBEDTLS_USE_PSA_CRYPTO)"
tests/compat.sh
- msg "test: compat.sh RC4, DES & NULL (full minus MBEDTLS_USE_PSA_CRYPTO)"
- env OPENSSL="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
+ msg "test: compat.sh RC4, 3DES & NULL (full minus MBEDTLS_USE_PSA_CRYPTO)"
+ tests/compat.sh -e '^$' -f 'NULL\|3DES\|DES-CBC3\|RC4\|ARCFOUR'
+
+ msg "test: compat.sh single-DES (full minus MBEDTLS_USE_PSA_CRYPTO)"
+ env OPENSSL="$OPENSSL_LEGACY" tests/compat.sh -e '3DES\|DES-CBC3' -f 'DES'
msg "test: compat.sh ARIA + ChachaPoly (full minus MBEDTLS_USE_PSA_CRYPTO)"
env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
@@ -3327,7 +3339,16 @@
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
-}
+
+ msg "build: Windows cross build - mingw64, make (Library only, AESNI intrinsics)" # ~ 30s
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 lib
+ make WINDOWS_BUILD=1 clean
+
+ msg "build: Windows cross build - mingw64, make (Library only, default config without MBEDTLS_AESNI_C)" # ~ 30s
+ ./scripts/config.py unset MBEDTLS_AESNI_C
+ make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib
+ make WINDOWS_BUILD=1 clean
+ }
support_build_mingw() {
case $(i686-w64-mingw32-gcc -dumpversion 2>/dev/null) in
[0-5]*|"") false;;
@@ -3344,6 +3365,9 @@
msg "test: main suites (MSan)" # ~ 10s
make test
+ msg "program demos (MSan)" # ~20s
+ tests/scripts/run_demos.py
+
msg "test: ssl-opt.sh (MSan)" # ~ 1 min
tests/ssl-opt.sh
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index 196ce45..970abfa 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -51,8 +51,6 @@
: ${OPENSSL_LEGACY:="$OPENSSL"}
: ${GNUTLS_CLI:="gnutls-cli"}
: ${GNUTLS_SERV:="gnutls-serv"}
-: ${GNUTLS_LEGACY_CLI:="$GNUTLS_CLI"}
-: ${GNUTLS_LEGACY_SERV:="$GNUTLS_SERV"}
# Used to make ssl-opt.sh deterministic.
#
@@ -81,8 +79,6 @@
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
@@ -120,17 +116,12 @@
# Step 2c - Compatibility tests (keep going even if some tests fail)
echo '################ compat.sh ################'
{
- echo '#### compat.sh: Default versions'
- sh compat.sh -m 'tls1 tls1_1 tls12 dtls1 dtls12'
- echo
-
- echo '#### compat.sh: legacy (SSLv3)'
- OPENSSL="$OPENSSL_LEGACY" sh compat.sh -m 'ssl3'
+ echo '#### compat.sh: Default ciphers'
+ sh compat.sh -m 'ssl3 tls1 tls1_1 tls12 dtls1 dtls12'
echo
echo '#### compat.sh: legacy (null, DES, RC4)'
OPENSSL="$OPENSSL_LEGACY" \
- GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" \
sh compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'
echo
diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py
index 352b55e..238a83f 100755
--- a/tests/scripts/check_files.py
+++ b/tests/scripts/check_files.py
@@ -162,24 +162,6 @@
return ext in ('.bat', '.dsp', '.dsw', '.sln', '.vcxproj')
-class PermissionIssueTracker(FileIssueTracker):
- """Track files with bad permissions.
-
- Files that are not executable scripts must not be executable."""
-
- heading = "Incorrect permissions:"
-
- # .py files can be either full scripts or modules, so they may or may
- # not be executable.
- suffix_exemptions = frozenset({".py"})
-
- def check_file_for_issue(self, filepath):
- is_executable = os.access(filepath, os.X_OK)
- should_be_executable = filepath.endswith((".sh", ".pl"))
- if is_executable != should_be_executable:
- self.files_with_issues[filepath] = None
-
-
class ShebangIssueTracker(FileIssueTracker):
"""Track files with a bad, missing or extraneous shebang line.
@@ -386,7 +368,6 @@
self.logger = None
self.setup_logger(log_file)
self.issues_to_check = [
- PermissionIssueTracker(),
ShebangIssueTracker(),
EndOfFileNewlineIssueTracker(),
Utf8BomIssueTracker(),
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index 8c08e5c..96a1d3c 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -930,7 +930,7 @@
"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.\n\n"
- "Expected to be run from the MbedTLS root directory.")
+ "Expected to be run from the Mbed TLS root directory.")
)
parser.add_argument(
"-v", "--verbose",
diff --git a/tests/scripts/run_demos.py b/tests/scripts/run_demos.py
new file mode 100755
index 0000000..6a63d23
--- /dev/null
+++ b/tests/scripts/run_demos.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+"""Run the Mbed TLS demo scripts.
+"""
+import argparse
+import glob
+import subprocess
+import sys
+
+def run_demo(demo, quiet=False):
+ """Run the specified demo script. Return True if it succeeds."""
+ args = {}
+ if quiet:
+ args['stdout'] = subprocess.DEVNULL
+ args['stderr'] = subprocess.DEVNULL
+ returncode = subprocess.call([demo], **args)
+ return returncode == 0
+
+def run_demos(demos, quiet=False):
+ """Run the specified demos and print summary information about failures.
+
+ Return True if all demos passed and False if a demo fails.
+ """
+ failures = []
+ for demo in demos:
+ if not quiet:
+ print('#### {} ####'.format(demo))
+ success = run_demo(demo, quiet=quiet)
+ if not success:
+ failures.append(demo)
+ if not quiet:
+ print('{}: FAIL'.format(demo))
+ if quiet:
+ print('{}: {}'.format(demo, 'PASS' if success else 'FAIL'))
+ else:
+ print('')
+ successes = len(demos) - len(failures)
+ print('{}/{} demos passed'.format(successes, len(demos)))
+ if failures and not quiet:
+ print('Failures:', *failures)
+ return not failures
+
+def run_all_demos(quiet=False):
+ """Run all the available demos.
+
+ Return True if all demos passed and False if a demo fails.
+ """
+ all_demos = glob.glob('programs/*/*_demo.sh')
+ if not all_demos:
+ # Keep the message on one line. pylint: disable=line-too-long
+ raise Exception('No demos found. run_demos needs to operate from the Mbed TLS toplevel directory.')
+ return run_demos(all_demos, quiet=quiet)
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('--quiet', '-q',
+ action='store_true',
+ help="suppress the output of demos")
+ options = parser.parse_args()
+ success = run_all_demos(quiet=options.quiet)
+ sys.exit(0 if success else 1)
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/src/external_timing/timing_alt.h b/tests/src/external_timing/timing_alt.h
index 82e8c8b..d71ceb9 100644
--- a/tests/src/external_timing/timing_alt.h
+++ b/tests/src/external_timing/timing_alt.h
@@ -1,5 +1,5 @@
/*
- * Copy of the internal MbedTLS timing implementation, to be used in tests.
+ * Copy of the internal Mbed TLS timing implementation, to be used in tests.
*/
/*
* Copyright The Mbed TLS Contributors
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 3a27aac..4b6b695 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -81,14 +81,6 @@
# alternative versions of OpenSSL and GnuTLS (no default path)
-if [ -n "${OPENSSL_LEGACY:-}" ]; then
- O_LEGACY_SRV="$OPENSSL_LEGACY s_server -www -cert data_files/server5.crt -key data_files/server5.key"
- O_LEGACY_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_LEGACY s_client"
-else
- O_LEGACY_SRV=false
- O_LEGACY_CLI=false
-fi
-
if [ -n "${OPENSSL_NEXT:-}" ]; then
O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
@@ -456,20 +448,6 @@
fi
}
-# skip next test if OpenSSL-legacy isn't available
-requires_openssl_legacy() {
- if [ -z "${OPENSSL_LEGACY_AVAILABLE:-}" ]; then
- if which "${OPENSSL_LEGACY:-}" >/dev/null 2>&1; then
- OPENSSL_LEGACY_AVAILABLE="YES"
- else
- OPENSSL_LEGACY_AVAILABLE="NO"
- fi
- fi
- if [ "$OPENSSL_LEGACY_AVAILABLE" = "NO" ]; then
- SKIP_NEXT="YES"
- fi
-}
-
requires_openssl_next() {
if [ -z "${OPENSSL_NEXT_AVAILABLE:-}" ]; then
if which "${OPENSSL_NEXT:-}" >/dev/null 2>&1; then
@@ -1502,11 +1480,6 @@
G_SRV="$G_SRV -p $SRV_PORT"
G_CLI="$G_CLI -p +SRV_PORT"
-if [ -n "${OPENSSL_LEGACY:-}" ]; then
- O_LEGACY_SRV="$O_LEGACY_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
- O_LEGACY_CLI="$O_LEGACY_CLI -connect 127.0.0.1:+SRV_PORT"
-fi
-
# Newer versions of OpenSSL have a syntax to enable all "ciphers", even
# low-security ones. This covers not just cipher suites but also protocol
# versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 06f391f..d8ff49e 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -432,6 +432,50 @@
fflush(outcome_file);
}
+#if defined(__unix__) || \
+ (defined(__APPLE__) && defined(__MACH__))
+#define MBEDTLS_HAVE_CHDIR
+#endif
+
+#if defined(MBEDTLS_HAVE_CHDIR)
+/** Try chdir to the directory containing argv0.
+ *
+ * Failures are silent.
+ */
+static void try_chdir_if_supported(const char *argv0)
+{
+ /* We might want to allow backslash as well, for Windows. But then we also
+ * need to consider chdir() vs _chdir(), and different conventions
+ * regarding paths in argv[0] (naively enabling this code with
+ * backslash support on Windows leads to chdir into the wrong directory
+ * on the CI). */
+ const char *slash = strrchr(argv0, '/');
+ if (slash == NULL) {
+ return;
+ }
+ size_t path_size = slash - argv0 + 1;
+ char *path = mbedtls_calloc(1, path_size);
+ if (path == NULL) {
+ return;
+ }
+ memcpy(path, argv0, path_size - 1);
+ path[path_size - 1] = 0;
+ int ret = chdir(path);
+ if (ret != 0) {
+ mbedtls_fprintf(stderr, "%s: note: chdir(\"%s\") failed.\n",
+ __func__, path);
+ }
+ mbedtls_free(path);
+}
+#else /* MBEDTLS_HAVE_CHDIR */
+/* No chdir() or no support for parsing argv[0] on this platform. */
+static void try_chdir_if_supported(const char *argv0)
+{
+ (void) argv0;
+ return;
+}
+#endif /* MBEDTLS_HAVE_CHDIR */
+
/**
* \brief Desktop implementation of execute_tests().
* Parses command line and executes tests from
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 335ce84..a69442d 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -278,6 +278,21 @@
mbedtls_test_hook_error_add = &mbedtls_test_err_add_check;
#endif
+ /* Try changing to the directory containing the executable, if
+ * using the default data file. This allows running the executable
+ * from another directory (e.g. the project root) and still access
+ * the .datax file as well as data files used by test cases
+ * (typically from tests/data_files).
+ *
+ * Note that we do this before the platform setup (which may access
+ * files such as a random seed). We also do this before accessing
+ * test-specific files such as the outcome file, which is arguably
+ * not desirable and should be fixed later.
+ */
+ if (argc == 1) {
+ try_chdir_if_supported(argv[0]);
+ }
+
int ret = mbedtls_test_platform_setup();
if (ret != 0) {
mbedtls_fprintf(stderr,