Merge branch 'development' into development-restricted

* development: (22 commits)
  Only pass -Wformat-signedness to versions of GCC that support it.
  Documentation improvements
  Remove redundant assignment
  Add comments explaining include paths
  Library files aren't supposed to be executable
  CMake: Include the library directory for the sake of 3rdparty
  Factor common library properties
  Fix erroneous skip of test cases for disabled ciphersuites
  Include common.h instead of config.h in library source files
  Include the library directory for the sake of 3rdparty
  Fix copypasta in test case descriptions
  Remove metadata tests for features that are not implemented
  Fix dependency in PSA test cases
  Fix dependency in AES GCM test case
  Document the fields of TestCasesOutcomes
  Check test case coverage
  New script for test outcome analysis
  check_test_cases: move some functions into the logical class
  check_test_cases: move "walk" functions into a class
  check_test_cases: parametrize iteration functions by the action
  ...
diff --git a/3rdparty/everest/library/Hacl_Curve25519_joined.c b/3rdparty/everest/library/Hacl_Curve25519_joined.c
index 18b32d2..ee62be1 100644
--- a/3rdparty/everest/library/Hacl_Curve25519_joined.c
+++ b/3rdparty/everest/library/Hacl_Curve25519_joined.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
 
diff --git a/3rdparty/everest/library/everest.c b/3rdparty/everest/library/everest.c
index 2e2422f..82c4e03 100644
--- a/3rdparty/everest/library/everest.c
+++ b/3rdparty/everest/library/everest.c
@@ -19,11 +19,7 @@
  *  This file is part of Mbed TLS (https://tls.mbed.org).
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #include <string.h>
 
diff --git a/3rdparty/everest/library/x25519.c b/3rdparty/everest/library/x25519.c
index 990bb4d..9faa9ab 100644
--- a/3rdparty/everest/library/x25519.c
+++ b/3rdparty/everest/library/x25519.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7e2ed0..f8df140 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -165,7 +165,10 @@
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
     endif()
     if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow -Wformat-signedness")
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
+    endif()
+    if (GCC_VERSION VERSION_GREATER 5.0)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-signedness")
     endif()
     set(CMAKE_C_FLAGS_RELEASE     "-O2")
     set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
diff --git a/ChangeLog.d/cmake-install.txt b/ChangeLog.d/cmake-install.txt
new file mode 100644
index 0000000..1bcec4a
--- /dev/null
+++ b/ChangeLog.d/cmake-install.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Library files installed after a CMake build no longer have execute
+     permission.
diff --git a/ChangeLog.d/format-signedness.txt b/ChangeLog.d/format-signedness.txt
new file mode 100644
index 0000000..ee1ee4b
--- /dev/null
+++ b/ChangeLog.d/format-signedness.txt
@@ -0,0 +1,3 @@
+Changes
+   * Only pass -Wformat-signedness to versions of GCC that support it. Reported
+     in #3478 and fix contributed in #3479 by okhowang.
diff --git a/docs/architecture/testing/test-framework.md b/docs/architecture/testing/test-framework.md
index e0e960f..c4178fa 100644
--- a/docs/architecture/testing/test-framework.md
+++ b/docs/architecture/testing/test-framework.md
@@ -22,7 +22,7 @@
 * Make the description descriptive. “foo: x=2, y=4” is more descriptive than “foo #2”. “foo: 0<x<y, both even” is even better if these inequalities and parities are why this particular test data was chosen.
 * Avoid changing the description of an existing test case without a good reason. This breaks the tracking of failures across CI runs, since this tracking is based on the descriptions.
 
-`tests/scripts/check-test-cases.py` enforces some rules and warns if some guidelines are violated.
+`tests/scripts/check_test_cases.py` enforces some rules and warns if some guidelines are violated.
 
 ## TLS tests
 
@@ -32,7 +32,7 @@
 
 Each test case in `ssl-opt.sh` has a description which succinctly describes for a human audience what the test does. The test description is the first parameter to `run_tests`.
 
-The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, the description must be written on the same line as `run_test`, in double quotes, for the sake of `check-test-cases.py`.
+The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, the description must be written on the same line as `run_test`, in double quotes, for the sake of `check_test_cases.py`.
 
 ## Running tests
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 698c819..1bdc59e 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -148,10 +148,14 @@
     message(FATAL_ERROR "Need to choose static or shared mbedtls build!")
 endif(NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
 
+set(target_libraries "mbedcrypto" "mbedx509" "mbedtls")
+
 if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
     set(mbedtls_static_target "mbedtls_static")
     set(mbedx509_static_target "mbedx509_static")
     set(mbedcrypto_static_target "mbedcrypto_static")
+    list(APPEND target_libraries
+        "mbedcrypto_static" "mbedx509_static" "mbedtls_static")
 elseif(USE_STATIC_MBEDTLS_LIBRARY)
     set(mbedtls_static_target "mbedtls")
     set(mbedx509_static_target "mbedx509")
@@ -162,59 +166,48 @@
     add_library(${mbedcrypto_static_target} STATIC ${src_crypto})
     set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
     target_link_libraries(${mbedcrypto_static_target} ${libs})
-    target_include_directories(${mbedcrypto_static_target}
-        PUBLIC ${MBEDTLS_DIR}/include/
-        PUBLIC ${thirdparty_inc_public}
-        PRIVATE ${thirdparty_inc})
-    target_compile_definitions(${mbedcrypto_static_target}
-        PRIVATE ${thirdparty_def})
 
     add_library(${mbedx509_static_target} STATIC ${src_x509})
     set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
     target_link_libraries(${mbedx509_static_target} ${libs} ${mbedcrypto_static_target})
-    target_include_directories(${mbedx509_static_target}
-        PUBLIC ${MBEDTLS_DIR}/include/)
 
     add_library(${mbedtls_static_target} STATIC ${src_tls})
     set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls)
     target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target})
-    target_include_directories(${mbedtls_static_target}
-        PUBLIC ${MBEDTLS_DIR}/include/)
-
-    install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target} ${mbedcrypto_static_target}
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 endif(USE_STATIC_MBEDTLS_LIBRARY)
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
-
     add_library(mbedcrypto SHARED ${src_crypto})
     set_target_properties(mbedcrypto PROPERTIES VERSION 2.23.0 SOVERSION 5)
     target_link_libraries(mbedcrypto ${libs})
-    target_include_directories(mbedcrypto
-        PUBLIC ${MBEDTLS_DIR}/include/
-        PUBLIC ${thirdparty_inc_public}
-        PRIVATE ${thirdparty_inc})
-    target_compile_definitions(mbedcrypto
-        PRIVATE ${thirdparty_def})
 
     add_library(mbedx509 SHARED ${src_x509})
     set_target_properties(mbedx509 PROPERTIES VERSION 2.23.0 SOVERSION 1)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
-    target_include_directories(mbedx509
-        PUBLIC ${MBEDTLS_DIR}/include/)
 
     add_library(mbedtls SHARED ${src_tls})
     set_target_properties(mbedtls PROPERTIES VERSION 2.23.0 SOVERSION 13)
     target_link_libraries(mbedtls ${libs} mbedx509)
-    target_include_directories(mbedtls
-        PUBLIC ${MBEDTLS_DIR}/include/)
-
-    install(TARGETS mbedtls mbedx509 mbedcrypto
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
+foreach(target IN LISTS target_libraries)
+    # Include public header files from /include and other directories
+    # declared by /3rdparty/**/CMakeLists.txt. Include private header files
+    # from /library and others declared by /3rdparty/**/CMakeLists.txt.
+    # /library needs to be listed explicitly when building .c files outside
+    # of /library (which currently means: under /3rdparty).
+    target_include_directories(${target}
+        PUBLIC ${MBEDTLS_DIR}/include/
+        PUBLIC ${thirdparty_inc_public}
+        PRIVATE ${MBEDTLS_DIR}/library/
+        PRIVATE ${thirdparty_inc})
+    target_compile_definitions(${target}
+        PRIVATE ${thirdparty_def})
+    install(TARGETS ${target}
+            DESTINATION ${LIB_INSTALL_DIR}
+            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+endforeach(target)
+
 add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls)
 if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
     add_dependencies(lib mbedcrypto_static mbedx509_static mbedtls_static)
diff --git a/library/Makefile b/library/Makefile
index 87ea56d..b76a84b 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -5,7 +5,11 @@
 WARNING_CFLAGS ?=  -Wall -Wextra
 LDFLAGS ?=
 
-LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../include -D_FILE_OFFSET_BITS=64
+# Include ../include for public headers and . for private headers.
+# Note that . needs to be included explicitly for the sake of library
+# files that are not in the /library directory (which currently means
+# under /3rdparty).
+LOCAL_CFLAGS = $(WARNING_CFLAGS) -I. -I../include -D_FILE_OFFSET_BITS=64
 LOCAL_LDFLAGS =
 
 ifdef DEBUG
diff --git a/library/aes.c b/library/aes.c
index 962b0b9..80e8134 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -25,11 +25,7 @@
  *  http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_AES_C)
 
diff --git a/library/aesni.c b/library/aesni.c
index 062708b..e0d8a69 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -24,11 +24,7 @@
  * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_AESNI_C)
 
diff --git a/library/arc4.c b/library/arc4.c
index b8998ac..2109bb2 100644
--- a/library/arc4.c
+++ b/library/arc4.c
@@ -24,11 +24,7 @@
  *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ARC4_C)
 
diff --git a/library/aria.c b/library/aria.c
index aff66d6..107be27 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -25,11 +25,7 @@
  * [2] https://tools.ietf.org/html/rfc5794
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ARIA_C)
 
diff --git a/library/asn1parse.c b/library/asn1parse.c
index 34c6607..fe62bc6 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ASN1_PARSE_C)
 
diff --git a/library/asn1write.c b/library/asn1write.c
index 503db93..3c41180 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ASN1_WRITE_C)
 
diff --git a/library/base64.c b/library/base64.c
index f06b57b..3921c46 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_BASE64_C)
 
diff --git a/library/bignum.c b/library/bignum.c
index d9ab6f6..2ab71ca 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -35,11 +35,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_BIGNUM_C)
 
diff --git a/library/blowfish.c b/library/blowfish.c
index cbf9238..7c9b1a6 100644
--- a/library/blowfish.c
+++ b/library/blowfish.c
@@ -25,11 +25,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_BLOWFISH_C)
 
diff --git a/library/camellia.c b/library/camellia.c
index 22262b8..764e4f8 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -25,11 +25,7 @@
  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CAMELLIA_C)
 
diff --git a/library/ccm.c b/library/ccm.c
index eaef106..25a627b 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -28,11 +28,7 @@
  * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CCM_C)
 
diff --git a/library/certs.c b/library/certs.c
index f152c28..fa11d5c 100644
--- a/library/certs.c
+++ b/library/certs.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #include "mbedtls/certs.h"
 
diff --git a/library/chacha20.c b/library/chacha20.c
index 343b216..bda39b2 100644
--- a/library/chacha20.c
+++ b/library/chacha20.c
@@ -23,11 +23,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CHACHA20_C)
 
diff --git a/library/chachapoly.c b/library/chachapoly.c
index f0af5de..d51227a 100644
--- a/library/chachapoly.c
+++ b/library/chachapoly.c
@@ -20,11 +20,7 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CHACHAPOLY_C)
 
diff --git a/library/cipher.c b/library/cipher.c
index 409c3fe..acbda26 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -23,11 +23,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CIPHER_C)
 
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index a813426..e5ee7ff 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -23,11 +23,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CIPHER_C)
 
diff --git a/library/cmac.c b/library/cmac.c
index 2d23be5..3a48a62 100644
--- a/library/cmac.c
+++ b/library/cmac.c
@@ -40,11 +40,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CMAC_C)
 
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 8a2920a..7872e9b 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -24,11 +24,7 @@
  *  http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_CTR_DRBG_C)
 
diff --git a/library/debug.c b/library/debug.c
index 2b25e99..6fb766b 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_DEBUG_C)
 
diff --git a/library/des.c b/library/des.c
index 24e517e..e135219 100644
--- a/library/des.c
+++ b/library/des.c
@@ -25,11 +25,7 @@
  *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_DES_C)
 
diff --git a/library/dhm.c b/library/dhm.c
index 392ed0c..387f5be 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -27,11 +27,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_DHM_C)
 
diff --git a/library/ecdh.c b/library/ecdh.c
index 3cf5333..987a6ce 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -26,11 +26,7 @@
  * RFC 4492
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECDH_C)
 
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 5acd2d0..3183a90 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -25,11 +25,7 @@
  * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECDSA_C)
 
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 79ea3cb..a607851 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -24,11 +24,7 @@
  * available to members of the Thread Group http://threadgroup.org/
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECJPAKE_C)
 
diff --git a/library/ecp.c b/library/ecp.c
index 7b20516..c642037 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -41,11 +41,7 @@
  *     <http://eprint.iacr.org/2004/342.pdf>
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 /**
  * \brief Function level alternative implementation.
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index a24a50c..92bbb89 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ECP_C)
 
diff --git a/library/entropy.c b/library/entropy.c
index 102f9f1..4d4d6ce 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ENTROPY_C)
 
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index dc62183..62fb4af 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -24,11 +24,7 @@
 #define _GNU_SOURCE
 #endif
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #include <string.h>
 
diff --git a/library/error.c b/library/error.c
index 57171b3..68e1f17 100644
--- a/library/error.c
+++ b/library/error.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
 #include <string.h>
diff --git a/library/gcm.c b/library/gcm.c
index e34f1da..eae9eed 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -29,11 +29,7 @@
  * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_GCM_C)
 
diff --git a/library/havege.c b/library/havege.c
index ca7dd17..75e0e84 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -26,11 +26,7 @@
  *  Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_HAVEGE_C)
 
diff --git a/library/hkdf.c b/library/hkdf.c
index 82df597..0e9da59 100644
--- a/library/hkdf.c
+++ b/library/hkdf.c
@@ -18,11 +18,7 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_HKDF_C)
 
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index f811885..b25b683 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -25,11 +25,7 @@
  *  References below are based on rev. 1 (January 2012).
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_HMAC_DRBG_C)
 
diff --git a/library/md.c b/library/md.c
index 30a580b..3eb0fe3 100644
--- a/library/md.c
+++ b/library/md.c
@@ -23,11 +23,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_MD_C)
 
diff --git a/library/md2.c b/library/md2.c
index 82aed8e..afc6539 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -25,11 +25,7 @@
  *  http://www.ietf.org/rfc/rfc1319.txt
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_MD2_C)
 
diff --git a/library/md4.c b/library/md4.c
index 6a658e3..beb42c9 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -25,11 +25,7 @@
  *  http://www.ietf.org/rfc/rfc1320.txt
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_MD4_C)
 
diff --git a/library/md5.c b/library/md5.c
index 2306855..c7b85d1 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -24,11 +24,7 @@
  *  http://www.ietf.org/rfc/rfc1321.txt
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_MD5_C)
 
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 51ea7c4..07bcce0 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
 #include "mbedtls/memory_buffer_alloc.h"
diff --git a/library/net_sockets.c b/library/net_sockets.c
index b26e858..3c6d293 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -25,11 +25,7 @@
 #define _POSIX_C_SOURCE 200112L
 #define _XOPEN_SOURCE 600 /* sockaddr_storage */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_NET_C)
 
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 03e8072..f6ee486 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -29,11 +29,7 @@
  * the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_NIST_KW_C)
 
diff --git a/library/oid.c b/library/oid.c
index e0c0743..29ced43 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -21,11 +21,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_OID_C)
 
diff --git a/library/padlock.c b/library/padlock.c
index b85ff9c..887a386 100644
--- a/library/padlock.c
+++ b/library/padlock.c
@@ -25,11 +25,7 @@
  *  programming_guide.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PADLOCK_C)
 
diff --git a/library/pem.c b/library/pem.c
index 31f4a9a..544f7c4 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
 
diff --git a/library/pk.c b/library/pk.c
index b83ba8e..5858a4e 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PK_C)
 #include "mbedtls/pk.h"
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index f736431..46fd02c 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PK_C)
 #include "mbedtls/pk_internal.h"
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 96c64ad..b26f566 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -25,11 +25,7 @@
  *  ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PKCS12_C)
 
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 8832322..fc52248 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -29,11 +29,7 @@
  * http://tools.ietf.org/html/rfc6070 (Test vectors)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PKCS5_C)
 
diff --git a/library/pkparse.c b/library/pkparse.c
index 1cbb8cc..03d5972 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PK_PARSE_C)
 
diff --git a/library/pkwrite.c b/library/pkwrite.c
index b1b5f46..7ec84f3 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PK_WRITE_C)
 
diff --git a/library/platform.c b/library/platform.c
index 420d09e..cd0e85b 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 
diff --git a/library/platform_util.c b/library/platform_util.c
index b1f7450..f6882e2 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -28,11 +28,7 @@
 #define _POSIX_C_SOURCE 200112L
 #endif
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #include "mbedtls/platform_util.h"
 #include "mbedtls/platform.h"
diff --git a/library/poly1305.c b/library/poly1305.c
index bc1e8a6..069b82d 100644
--- a/library/poly1305.c
+++ b/library/poly1305.c
@@ -20,11 +20,7 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_POLY1305_C)
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 8cd8079..4c3966c 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -20,11 +20,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index 53a2600..61e6c98 100644
--- a/library/psa_crypto_se.c
+++ b/library/psa_crypto_se.c
@@ -20,11 +20,7 @@
  *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 801caf0..5ceac84 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -20,11 +20,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 
diff --git a/library/ripemd160.c b/library/ripemd160.c
index a62f4b8..a2ad32c 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -25,11 +25,7 @@
  *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_RIPEMD160_C)
 
diff --git a/library/rsa.c b/library/rsa.c
index 6c45746..83ed3c9 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -37,11 +37,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_RSA_C)
 
diff --git a/library/rsa_internal.c b/library/rsa_internal.c
index 9a42d47..b4098f4 100644
--- a/library/rsa_internal.c
+++ b/library/rsa_internal.c
@@ -20,11 +20,7 @@
  *
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_RSA_C)
 
diff --git a/library/sha1.c b/library/sha1.c
index 9233943..79bac6b 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -24,11 +24,7 @@
  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SHA1_C)
 
diff --git a/library/sha256.c b/library/sha256.c
index 087a8e3..d8ddda5 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -24,11 +24,7 @@
  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SHA256_C)
 
diff --git a/library/sha512.c b/library/sha512.c
index 30dd719..37fc96d 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -24,11 +24,7 @@
  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SHA512_C)
 
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 62a0a29..3a2df0c 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -23,11 +23,7 @@
  * to store and retrieve the session information.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_CACHE_C)
 
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 5da1294..726912e 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -21,11 +21,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 48ef30d..361e6e6 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_CLI_C)
 
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 323784c..151f0c5 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -23,11 +23,7 @@
  * to store and retrieve the session information.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_COOKIE_C)
 
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 7fc4bf0..d32afac 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -28,11 +28,7 @@
  *  http://www.ietf.org/rfc/rfc4346.txt
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 9bfda16..91bd83a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_SRV_C)
 
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 6b50b55..bfa2546 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_TICKET_C)
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 250ef98..834c632 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -27,11 +27,7 @@
  *  http://www.ietf.org/rfc/rfc4346.txt
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
diff --git a/library/threading.c b/library/threading.c
index 7c90c7c..cb9026d 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -27,11 +27,7 @@
 #define _POSIX_C_SOURCE 200112L
 #endif
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_THREADING_C)
 
diff --git a/library/timing.c b/library/timing.c
index 4a65422..90cfe88 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/library/version.c b/library/version.c
index fd96750..1e17482 100644
--- a/library/version.c
+++ b/library/version.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/version_features.c b/library/version_features.c
index 16a0cd0..64e9e86 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/x509.c b/library/x509.c
index e969b8d..55afbab 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -29,11 +29,7 @@
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_USE_C)
 
diff --git a/library/x509_create.c b/library/x509_create.c
index 7df2f0e..8d58775 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CREATE_C)
 
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 371c446..d89facc 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -29,11 +29,7 @@
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CRL_PARSE_C)
 
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 04822e8..8fd8b86 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -31,11 +31,7 @@
  *  [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 
diff --git a/library/x509_csr.c b/library/x509_csr.c
index 7e2cfba..8385e50 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -29,11 +29,7 @@
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CSR_PARSE_C)
 
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 5947e43..2baff35 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -25,11 +25,7 @@
  * - attributes: PKCS#9 v2.0 aka RFC 2985
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CRT_WRITE_C)
 
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 7c51798..7dd3d45 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -24,11 +24,7 @@
  * - attributes: PKCS#9 v2.0 aka RFC 2985
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_X509_CSR_WRITE_C)
 
diff --git a/library/xtea.c b/library/xtea.c
index a33707b..dab6cd3 100644
--- a/library/xtea.c
+++ b/library/xtea.c
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_XTEA_C)
 
diff --git a/scripts/data_files/error.fmt b/scripts/data_files/error.fmt
index f65881b..ddd1be7 100644
--- a/scripts/data_files/error.fmt
+++ b/scripts/data_files/error.fmt
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
 #include <string.h>
diff --git a/scripts/data_files/version_features.fmt b/scripts/data_files/version_features.fmt
index 63ae94c..79d220e 100644
--- a/scripts/data_files/version_features.fmt
+++ b/scripts/data_files/version_features.fmt
@@ -19,11 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 8bf8de9..a3a2925 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -64,6 +64,15 @@
 );
 my $include_directories = join(';', map {"../../$_"} @include_directories);
 
+# Directories to add to the include path when building the library, but not
+# when building tests or applications.
+my @library_include_directories = qw(
+    library
+);
+my $library_include_directories =
+  join(';', map {"../../$_"} (@library_include_directories,
+                              @include_directories));
+
 my @excluded_files = qw(
     3rdparty/everest/library/Hacl_Curve25519.c
 );
@@ -202,7 +211,7 @@
     my $out = slurp_file( $main_tpl );
     $out =~ s/SOURCE_ENTRIES\r\n/$source_entries/m;
     $out =~ s/HEADER_ENTRIES\r\n/$header_entries/m;
-    $out =~ s/INCLUDE_DIRECTORIES\r\n/$include_directories/g;
+    $out =~ s/INCLUDE_DIRECTORIES\r\n/$library_include_directories/g;
 
     content_to_file( $out, $main_out );
 }
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8a74c6b..cc68663 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -48,6 +48,10 @@
 
     add_executable(test_suite_${data_name} test_suite_${data_name}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(test_suite_${data_name} ${libs})
+    # Include test-specific header files from ./include and private header
+    # files (used by some invasive tests) from ../library. Public header
+    # files are automatically included because the library targets declare
+    # them as PUBLIC.
     target_include_directories(test_suite_${data_name}
         PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
         PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../library)
diff --git a/tests/Makefile b/tests/Makefile
index 80c84fa..ffa4812 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -6,6 +6,9 @@
 WARNING_CFLAGS ?= -Wall -Wextra
 LDFLAGS ?=
 
+# Include public header files from ../include, test-specific header files
+# from ./include, and private header files (used by some invasive tests)
+# from ../library.
 LOCAL_CFLAGS = $(WARNING_CFLAGS) -I./include -I../include -I../library -D_FILE_OFFSET_BITS=64
 LOCAL_LDFLAGS = -L../library			\
 		-lmbedtls$(SHARED_SUFFIX)	\
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 9a70438..ec61d19 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -680,7 +680,7 @@
 
 component_check_files () {
     msg "Check: file sanity checks (permissions, encodings)" # < 1s
-    record_status tests/scripts/check-files.py
+    record_status tests/scripts/check_files.py
 }
 
 component_check_changelog () {
@@ -707,7 +707,7 @@
     else
         opt=''
     fi
-    record_status tests/scripts/check-test-cases.py $opt
+    record_status tests/scripts/check_test_cases.py $opt
     unset opt
 }
 
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
new file mode 100755
index 0000000..73f16bd
--- /dev/null
+++ b/tests/scripts/analyze_outcomes.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python3
+
+"""Analyze the test outcomes from a full CI run.
+
+This script can also run on outcomes from a partial run, but the results are
+less likely to be useful.
+"""
+
+import argparse
+import re
+import sys
+import traceback
+
+import check_test_cases
+
+class Results:
+    """Process analysis results."""
+
+    def __init__(self):
+        self.error_count = 0
+        self.warning_count = 0
+
+    @staticmethod
+    def log(fmt, *args, **kwargs):
+        sys.stderr.write((fmt + '\n').format(*args, **kwargs))
+
+    def error(self, fmt, *args, **kwargs):
+        self.log('Error: ' + fmt, *args, **kwargs)
+        self.error_count += 1
+
+    def warning(self, fmt, *args, **kwargs):
+        self.log('Warning: ' + fmt, *args, **kwargs)
+        self.warning_count += 1
+
+class TestCaseOutcomes:
+    """The outcomes of one test case across many configurations."""
+    # pylint: disable=too-few-public-methods
+
+    def __init__(self):
+        # Collect a list of witnesses of the test case succeeding or failing.
+        # Currently we don't do anything with witnesses except count them.
+        # The format of a witness is determined by the read_outcome_file
+        # function; it's the platform and configuration joined by ';'.
+        self.successes = []
+        self.failures = []
+
+    def hits(self):
+        """Return the number of times a test case has been run.
+
+        This includes passes and failures, but not skips.
+        """
+        return len(self.successes) + len(self.failures)
+
+class TestDescriptions(check_test_cases.TestDescriptionExplorer):
+    """Collect the available test cases."""
+
+    def __init__(self):
+        super().__init__()
+        self.descriptions = set()
+
+    def process_test_case(self, _per_file_state,
+                          file_name, _line_number, description):
+        """Record an available test case."""
+        base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name))
+        key = ';'.join([base_name, description.decode('utf-8')])
+        self.descriptions.add(key)
+
+def collect_available_test_cases():
+    """Collect the available test cases."""
+    explorer = TestDescriptions()
+    explorer.walk_all()
+    return sorted(explorer.descriptions)
+
+def analyze_coverage(results, outcomes):
+    """Check that all available test cases are executed at least once."""
+    available = collect_available_test_cases()
+    for key in available:
+        hits = outcomes[key].hits() if key in outcomes else 0
+        if hits == 0:
+            # Make this a warning, not an error, as long as we haven't
+            # fixed this branch to have full coverage of test cases.
+            results.warning('Test case not executed: {}', key)
+
+def analyze_outcomes(outcomes):
+    """Run all analyses on the given outcome collection."""
+    results = Results()
+    analyze_coverage(results, outcomes)
+    return results
+
+def read_outcome_file(outcome_file):
+    """Parse an outcome file and return an outcome collection.
+
+An outcome collection is a dictionary mapping keys to TestCaseOutcomes objects.
+The keys are the test suite name and the test case description, separated
+by a semicolon.
+"""
+    outcomes = {}
+    with open(outcome_file, 'r', encoding='utf-8') as input_file:
+        for line in input_file:
+            (platform, config, suite, case, result, _cause) = line.split(';')
+            key = ';'.join([suite, case])
+            setup = ';'.join([platform, config])
+            if key not in outcomes:
+                outcomes[key] = TestCaseOutcomes()
+            if result == 'PASS':
+                outcomes[key].successes.append(setup)
+            elif result == 'FAIL':
+                outcomes[key].failures.append(setup)
+    return outcomes
+
+def analyze_outcome_file(outcome_file):
+    """Analyze the given outcome file."""
+    outcomes = read_outcome_file(outcome_file)
+    return analyze_outcomes(outcomes)
+
+def main():
+    try:
+        parser = argparse.ArgumentParser(description=__doc__)
+        parser.add_argument('outcomes', metavar='OUTCOMES.CSV',
+                            help='Outcome file to analyze')
+        options = parser.parse_args()
+        results = analyze_outcome_file(options.outcomes)
+        if results.error_count > 0:
+            sys.exit(1)
+    except Exception: # pylint: disable=broad-except
+        # Print the backtrace and exit explicitly with our chosen status.
+        traceback.print_exc()
+        sys.exit(120)
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/scripts/basic-in-docker.sh b/tests/scripts/basic-in-docker.sh
index 37ed5ea..83d6655 100755
--- a/tests/scripts/basic-in-docker.sh
+++ b/tests/scripts/basic-in-docker.sh
@@ -4,8 +4,10 @@
 #
 # Purpose
 # -------
-# This runs a rough equivalent of the travis.yml in a Docker container.
-# The tests are run for both clang and gcc.
+# This runs sanity checks and library tests in a Docker container. The tests
+# are run for both clang and gcc. The testing includes a full test run
+# in the default configuration, partial test runs in the reference
+# configurations, and some dependency tests.
 #
 # Notes for users
 # ---------------
@@ -30,12 +32,7 @@
 
 source tests/scripts/docker_env.sh
 
-run_in_docker tests/scripts/recursion.pl library/*.c
-run_in_docker tests/scripts/check-generated-files.sh
-run_in_docker tests/scripts/check-doxy-blocks.pl
-run_in_docker tests/scripts/check-names.sh
-run_in_docker tests/scripts/check-files.py
-run_in_docker tests/scripts/doxygen.sh
+run_in_docker tests/scripts/all.sh 'check_*'
 
 for compiler in clang gcc; do
     run_in_docker -e CC=${compiler} cmake -D CMAKE_BUILD_TYPE:String="Check" .
diff --git a/tests/scripts/check-test-cases.py b/tests/scripts/check-test-cases.py
deleted file mode 100755
index 35a9987..0000000
--- a/tests/scripts/check-test-cases.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-
-"""Sanity checks for test data.
-"""
-
-# Copyright (C) 2019, 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)
-
-import argparse
-import glob
-import os
-import re
-import sys
-
-class Results:
-    """Store file and line information about errors or warnings in test suites."""
-
-    def __init__(self, options):
-        self.errors = 0
-        self.warnings = 0
-        self.ignore_warnings = options.quiet
-
-    def error(self, file_name, line_number, fmt, *args):
-        sys.stderr.write(('{}:{}:ERROR:' + fmt + '\n').
-                         format(file_name, line_number, *args))
-        self.errors += 1
-
-    def warning(self, file_name, line_number, fmt, *args):
-        if not self.ignore_warnings:
-            sys.stderr.write(('{}:{}:Warning:' + fmt + '\n')
-                             .format(file_name, line_number, *args))
-            self.warnings += 1
-
-def collect_test_directories():
-    """Get the relative path for the TLS and Crypto test directories."""
-    if os.path.isdir('tests'):
-        tests_dir = 'tests'
-    elif os.path.isdir('suites'):
-        tests_dir = '.'
-    elif os.path.isdir('../suites'):
-        tests_dir = '..'
-    directories = [tests_dir]
-    return directories
-
-def check_description(results, seen, file_name, line_number, description):
-    """Check test case descriptions for errors."""
-    if description in seen:
-        results.error(file_name, line_number,
-                      'Duplicate description (also line {})',
-                      seen[description])
-        return
-    if re.search(br'[\t;]', description):
-        results.error(file_name, line_number,
-                      'Forbidden character \'{}\' in description',
-                      re.search(br'[\t;]', description).group(0).decode('ascii'))
-    if re.search(br'[^ -~]', description):
-        results.error(file_name, line_number,
-                      'Non-ASCII character in description')
-    if len(description) > 66:
-        results.warning(file_name, line_number,
-                        'Test description too long ({} > 66)',
-                        len(description))
-    seen[description] = line_number
-
-def check_test_suite(results, data_file_name):
-    """Check the test cases in the given unit test data file."""
-    in_paragraph = False
-    descriptions = {}
-    with open(data_file_name, 'rb') as data_file:
-        for line_number, line in enumerate(data_file, 1):
-            line = line.rstrip(b'\r\n')
-            if not line:
-                in_paragraph = False
-                continue
-            if line.startswith(b'#'):
-                continue
-            if not in_paragraph:
-                # This is a test case description line.
-                check_description(results, descriptions,
-                                  data_file_name, line_number, line)
-            in_paragraph = True
-
-def check_ssl_opt_sh(results, file_name):
-    """Check the test cases in ssl-opt.sh or a file with a similar format."""
-    descriptions = {}
-    with open(file_name, 'rb') as file_contents:
-        for line_number, line in enumerate(file_contents, 1):
-            # Assume that all run_test calls have the same simple form
-            # with the test description entirely on the same line as the
-            # function name.
-            m = re.match(br'\s*run_test\s+"((?:[^\\"]|\\.)*)"', line)
-            if not m:
-                continue
-            description = m.group(1)
-            check_description(results, descriptions,
-                              file_name, line_number, description)
-
-def main():
-    parser = argparse.ArgumentParser(description=__doc__)
-    parser.add_argument('--quiet', '-q',
-                        action='store_true',
-                        help='Hide warnings')
-    parser.add_argument('--verbose', '-v',
-                        action='store_false', dest='quiet',
-                        help='Show warnings (default: on; undoes --quiet)')
-    options = parser.parse_args()
-    test_directories = collect_test_directories()
-    results = Results(options)
-    for directory in test_directories:
-        for data_file_name in glob.glob(os.path.join(directory, 'suites',
-                                                     '*.data')):
-            check_test_suite(results, data_file_name)
-        ssl_opt_sh = os.path.join(directory, 'ssl-opt.sh')
-        if os.path.exists(ssl_opt_sh):
-            check_ssl_opt_sh(results, ssl_opt_sh)
-    if (results.warnings or results.errors) and not options.quiet:
-        sys.stderr.write('{}: {} errors, {} warnings\n'
-                         .format(sys.argv[0], results.errors, results.warnings))
-    sys.exit(1 if results.errors else 0)
-
-if __name__ == '__main__':
-    main()
diff --git a/tests/scripts/check-files.py b/tests/scripts/check_files.py
similarity index 100%
rename from tests/scripts/check-files.py
rename to tests/scripts/check_files.py
diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py
new file mode 100755
index 0000000..3360d28
--- /dev/null
+++ b/tests/scripts/check_test_cases.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python3
+
+"""Sanity checks for test data.
+
+This program contains a class for traversing test cases that can be used
+independently of the checks.
+"""
+
+# Copyright (C) 2019, 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)
+
+import argparse
+import glob
+import os
+import re
+import sys
+
+class Results:
+    """Store file and line information about errors or warnings in test suites."""
+
+    def __init__(self, options):
+        self.errors = 0
+        self.warnings = 0
+        self.ignore_warnings = options.quiet
+
+    def error(self, file_name, line_number, fmt, *args):
+        sys.stderr.write(('{}:{}:ERROR:' + fmt + '\n').
+                         format(file_name, line_number, *args))
+        self.errors += 1
+
+    def warning(self, file_name, line_number, fmt, *args):
+        if not self.ignore_warnings:
+            sys.stderr.write(('{}:{}:Warning:' + fmt + '\n')
+                             .format(file_name, line_number, *args))
+            self.warnings += 1
+
+class TestDescriptionExplorer:
+    """An iterator over test cases with descriptions.
+
+The test cases that have descriptions are:
+* Individual unit tests (entries in a .data file) in test suites.
+* Individual test cases in ssl-opt.sh.
+
+This is an abstract class. To use it, derive a class that implements
+the process_test_case method, and call walk_all().
+"""
+
+    def process_test_case(self, per_file_state,
+                          file_name, line_number, description):
+        """Process a test case.
+
+per_file_state: an object created by new_per_file_state() at the beginning
+                of each file.
+file_name: a relative path to the file containing the test case.
+line_number: the line number in the given file.
+description: the test case description as a byte string.
+"""
+        raise NotImplementedError
+
+    def new_per_file_state(self):
+        """Return a new per-file state object.
+
+The default per-file state object is None. Child classes that require per-file
+state may override this method.
+"""
+        #pylint: disable=no-self-use
+        return None
+
+    def walk_test_suite(self, data_file_name):
+        """Iterate over the test cases in the given unit test data file."""
+        in_paragraph = False
+        descriptions = self.new_per_file_state() # pylint: disable=assignment-from-none
+        with open(data_file_name, 'rb') as data_file:
+            for line_number, line in enumerate(data_file, 1):
+                line = line.rstrip(b'\r\n')
+                if not line:
+                    in_paragraph = False
+                    continue
+                if line.startswith(b'#'):
+                    continue
+                if not in_paragraph:
+                    # This is a test case description line.
+                    self.process_test_case(descriptions,
+                                           data_file_name, line_number, line)
+                in_paragraph = True
+
+    def walk_ssl_opt_sh(self, file_name):
+        """Iterate over the test cases in ssl-opt.sh or a file with a similar format."""
+        descriptions = self.new_per_file_state() # pylint: disable=assignment-from-none
+        with open(file_name, 'rb') as file_contents:
+            for line_number, line in enumerate(file_contents, 1):
+                # Assume that all run_test calls have the same simple form
+                # with the test description entirely on the same line as the
+                # function name.
+                m = re.match(br'\s*run_test\s+"((?:[^\\"]|\\.)*)"', line)
+                if not m:
+                    continue
+                description = m.group(1)
+                self.process_test_case(descriptions,
+                                       file_name, line_number, description)
+
+    @staticmethod
+    def collect_test_directories():
+        """Get the relative path for the TLS and Crypto test directories."""
+        if os.path.isdir('tests'):
+            tests_dir = 'tests'
+        elif os.path.isdir('suites'):
+            tests_dir = '.'
+        elif os.path.isdir('../suites'):
+            tests_dir = '..'
+        directories = [tests_dir]
+        return directories
+
+    def walk_all(self):
+        """Iterate over all named test cases."""
+        test_directories = self.collect_test_directories()
+        for directory in test_directories:
+            for data_file_name in glob.glob(os.path.join(directory, 'suites',
+                                                         '*.data')):
+                self.walk_test_suite(data_file_name)
+            ssl_opt_sh = os.path.join(directory, 'ssl-opt.sh')
+            if os.path.exists(ssl_opt_sh):
+                self.walk_ssl_opt_sh(ssl_opt_sh)
+
+class DescriptionChecker(TestDescriptionExplorer):
+    """Check all test case descriptions.
+
+* Check that each description is valid (length, allowed character set, etc.).
+* Check that there is no duplicated description inside of one test suite.
+"""
+
+    def __init__(self, results):
+        self.results = results
+
+    def new_per_file_state(self):
+        """Dictionary mapping descriptions to their line number."""
+        return {}
+
+    def process_test_case(self, per_file_state,
+                          file_name, line_number, description):
+        """Check test case descriptions for errors."""
+        results = self.results
+        seen = per_file_state
+        if description in seen:
+            results.error(file_name, line_number,
+                          'Duplicate description (also line {})',
+                          seen[description])
+            return
+        if re.search(br'[\t;]', description):
+            results.error(file_name, line_number,
+                          'Forbidden character \'{}\' in description',
+                          re.search(br'[\t;]', description).group(0).decode('ascii'))
+        if re.search(br'[^ -~]', description):
+            results.error(file_name, line_number,
+                          'Non-ASCII character in description')
+        if len(description) > 66:
+            results.warning(file_name, line_number,
+                            'Test description too long ({} > 66)',
+                            len(description))
+        seen[description] = line_number
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--quiet', '-q',
+                        action='store_true',
+                        help='Hide warnings')
+    parser.add_argument('--verbose', '-v',
+                        action='store_false', dest='quiet',
+                        help='Show warnings (default: on; undoes --quiet)')
+    options = parser.parse_args()
+    results = Results(options)
+    checker = DescriptionChecker(results)
+    checker.walk_all()
+    if (results.warnings or results.errors) and not options.quiet:
+        sys.stderr.write('{}: {} errors, {} warnings\n'
+                         .format(sys.argv[0], results.errors, results.warnings))
+    sys.exit(1 if results.errors else 0)
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 8d28b63..5864a87 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -241,6 +241,33 @@
     fi
 }
 
+# maybe_requires_ciphersuite_enabled CMD [RUN_TEST_OPTION...]
+# If CMD (call to a TLS client or server program) requires a specific
+# ciphersuite, arrange to only run the test case if this ciphersuite is
+# enabled. As an exception, do run the test case if it expects a ciphersuite
+# mismatch.
+maybe_requires_ciphersuite_enabled() {
+    case "$1" in
+        *\ force_ciphersuite=*) :;;
+        *) return;; # No specific required ciphersuite
+    esac
+    ciphersuite="${1##*\ force_ciphersuite=}"
+    ciphersuite="${ciphersuite%%[!-0-9A-Z_a-z]*}"
+    shift
+
+    case "$*" in
+        *"-s SSL - The server has no ciphersuites in common"*)
+            # This test case expects a ciphersuite mismatch, so it doesn't
+            # require the ciphersuite to be enabled.
+            ;;
+        *)
+            requires_ciphersuite_enabled "$ciphersuite"
+            ;;
+    esac
+
+    unset ciphersuite
+}
+
 # skip next test if OpenSSL doesn't support FALLBACK_SCSV
 requires_openssl_with_fallback_scsv() {
     if [ -z "${OPENSSL_HAS_FBSCSV:-}" ]; then
@@ -658,17 +685,9 @@
        requires_config_enabled MBEDTLS_FS_IO
     fi
 
-    # Check if server forces ciphersuite
-    FORCE_CIPHERSUITE=$(echo "$SRV_CMD" | sed -n 's/^.*force_ciphersuite=\([a-zA-Z0-9\-]*\).*$/\1/p')
-    if [ ! -z "$FORCE_CIPHERSUITE" ]; then
-       requires_ciphersuite_enabled $FORCE_CIPHERSUITE
-    fi
-
-    # Check if client forces ciphersuite
-    FORCE_CIPHERSUITE=$(echo "$CLI_CMD" | sed -n 's/^.*force_ciphersuite=\([a-zA-Z0-9\-]*\).*$/\1/p')
-    if [ ! -z "$FORCE_CIPHERSUITE" ]; then
-       requires_ciphersuite_enabled $FORCE_CIPHERSUITE
-    fi
+    # If the client or serve requires a ciphersuite, check that it's enabled.
+    maybe_requires_ciphersuite_enabled "$SRV_CMD" "$@"
+    maybe_requires_ciphersuite_enabled "$CLI_CMD" "$@"
 
     # should we skip?
     if [ "X$SKIP_NEXT" = "XYES" ]; then
diff --git a/tests/suites/test_suite_cipher.gcm.data b/tests/suites/test_suite_cipher.gcm.data
index 8d728bd..a4cebd2 100644
--- a/tests/suites/test_suite_cipher.gcm.data
+++ b/tests/suites/test_suite_cipher.gcm.data
@@ -3,7 +3,7 @@
 dec_empty_buf:MBEDTLS_CIPHER_CAMELLIA_128_GCM:0:0
 
 AES GCM Decrypt empty buffer
-depends_on:MBEDTLS_CIPHER_AES_128_GCM:MBEDTLS_GCM_C
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
 dec_empty_buf:MBEDTLS_CIPHER_AES_128_GCM:0:0
 
 Aria GCM Decrypt empty buffer
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 48bdbed..2a0573d 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -574,7 +574,7 @@
 raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
 
 PSA key policy algorithm2: CTR, CBC
-depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC_NOPAD
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC
 key_policy_alg2:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING
 
 PSA key policy algorithm2: ECDH, ECDSA
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index b771e58..f888983 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -34,30 +34,6 @@
 depends_on:MBEDTLS_SHA512_C
 hash_algorithm:PSA_ALG_SHA_512:64
 
-Hash: SHA-2 SHA-512/224
-depends_on:MBEDTLS_SHA512_C:MBEDTLS_SHA512_256
-hash_algorithm:PSA_ALG_SHA_512_224:28
-
-Hash: SHA-2 SHA-512/256
-depends_on:MBEDTLS_SHA512_C:MBEDTLS_SHA512_256
-hash_algorithm:PSA_ALG_SHA_512_256:32
-
-Hash: SHA-3 SHA3-224
-depends_on:MBEDTLS_SHA3_C
-hash_algorithm:PSA_ALG_SHA3_224:28
-
-Hash: SHA-3 SHA3-256
-depends_on:MBEDTLS_SHA3_C
-hash_algorithm:PSA_ALG_SHA3_256:32
-
-Hash: SHA-3 SHA3-384
-depends_on:MBEDTLS_SHA3_C
-hash_algorithm:PSA_ALG_SHA3_384:48
-
-Hash: SHA-3 SHA3-512
-depends_on:MBEDTLS_SHA3_C
-hash_algorithm:PSA_ALG_SHA3_512:64
-
 MAC: HMAC-MD2
 depends_on:MBEDTLS_MD2_C
 hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_MD2 ):16:64
@@ -94,30 +70,6 @@
 depends_on:MBEDTLS_SHA512_C
 hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA_512 ):64:128
 
-MAC: HMAC-SHA-512/224
-depends_on:MBEDTLS_SHA512_C:MBEDTLS_SHA512_256
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA_512_224 ):28:128
-
-MAC: HMAC-SHA-512/256
-depends_on:MBEDTLS_SHA512_C:MBEDTLS_SHA512_256
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA_512_256 ):32:128
-
-MAC: HMAC-SHA3-224
-depends_on:MBEDTLS_SHA3_C
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA3_224 ):28:144
-
-MAC: HMAC-SHA3-256
-depends_on:MBEDTLS_SHA3_C
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA3_256 ):32:136
-
-MAC: HMAC-SHA3-384
-depends_on:MBEDTLS_SHA3_C
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA3_384 ):48:104
-
-MAC: HMAC-SHA3-512
-depends_on:MBEDTLS_SHA3_C
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_SHA3_512 ):64:72
-
 MAC: CBC_MAC-AES-128
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_C
 mac_algorithm:PSA_ALG_CBC_MAC:ALG_IS_BLOCK_CIPHER_MAC:16:PSA_KEY_TYPE_AES:128
@@ -155,7 +107,7 @@
 cipher_algorithm:PSA_ALG_ARC4:ALG_IS_STREAM_CIPHER
 
 Cipher: ChaCha20
-depends_on:MBEDTLS_CHACHA_C
+depends_on:MBEDTLS_CHACHA20_C
 cipher_algorithm:PSA_ALG_CHACHA20:ALG_IS_STREAM_CIPHER
 
 Cipher: CTR
@@ -206,14 +158,6 @@
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
 asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_HASH_AND_SIGN
 
-Asymmetric signature: SHA-256 + randomized DSA SHA-256 using SHA-256
-depends_on:MBEDTLS_DSA_C:MBEDTLS_SHA256_C
-asymmetric_signature_algorithm:PSA_ALG_DSA( PSA_ALG_SHA_256 ):ALG_IS_DSA | ALG_IS_RANDOMIZED_DSA | ALG_IS_HASH_AND_SIGN
-
-Asymmetric signature: SHA-256 + deterministic DSA using SHA-256 [#1]
-depends_on:MBEDTLS_DSA_C:MBEDTLS_SHA256_C:MBEDTLS_DSA_DETERMINISTIC
-asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_DSA( PSA_ALG_SHA_256 ):ALG_IS_DSA | ALG_IS_DETERMINISTIC_DSA | ALG_DSA_IS_DETERMINISTIC | ALG_IS_HASH_AND_SIGN
-
 Asymmetric signature: randomized ECDSA (no hashing)
 depends_on:MBEDTLS_ECDSA_C
 asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN
@@ -222,7 +166,7 @@
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C
 asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN
 
-Asymmetric signature: SHA-256 + deterministic DSA using SHA-256 [#2]
+Asymmetric signature: SHA-256 + deterministic ECDSA using SHA-256
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_SHA256_C
 asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_HASH_AND_SIGN
 
@@ -234,19 +178,11 @@
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21
 asymmetric_signature_wildcard:PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS
 
-Asymmetric signature: randomized DSA with wildcard hash
-depends_on:MBEDTLS_DSA_C
-asymmetric_signature_wildcard:PSA_ALG_DSA( PSA_ALG_ANY_HASH ):ALG_IS_DSA | ALG_IS_RANDOMIZED_DSA
-
-Asymmetric signature: deterministic DSA with wildcard hash [#1]
-depends_on:MBEDTLS_DSA_C:MBEDTLS_DSA_DETERMINISTIC
-asymmetric_signature_wildcard:PSA_ALG_DETERMINISTIC_DSA( PSA_ALG_ANY_HASH ):ALG_IS_DSA | ALG_IS_DETERMINISTIC_DSA | ALG_DSA_IS_DETERMINISTIC
-
 Asymmetric signature: randomized ECDSA with wildcard hash
 depends_on:MBEDTLS_ECDSA_C
 asymmetric_signature_wildcard:PSA_ALG_ECDSA( PSA_ALG_ANY_HASH ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA
 
-Asymmetric signature: deterministic DSA with wildcard hash [#2]
+Asymmetric signature: deterministic ECDSA with wildcard hash
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC
 asymmetric_signature_wildcard:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_ANY_HASH ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC
 
@@ -343,14 +279,6 @@
 depends_on:MBEDTLS_RSA_C
 key_type:PSA_KEY_TYPE_RSA_KEY_PAIR:KEY_TYPE_IS_KEY_PAIR | KEY_TYPE_IS_RSA
 
-Key type: DSA public key
-depends_on:MBEDTLS_DSA_C
-key_type:PSA_KEY_TYPE_DSA_PUBLIC_KEY:KEY_TYPE_IS_PUBLIC_KEY | KEY_TYPE_IS_DSA
-
-Key type: DSA key pair
-depends_on:MBEDTLS_DSA_C
-key_type:PSA_KEY_TYPE_DSA_KEY_PAIR:KEY_TYPE_IS_KEY_PAIR | KEY_TYPE_IS_DSA
-
 ECC key family: SECP K1
 ecc_key_family:PSA_ECC_CURVE_SECP_K1
 
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 98b9913..4422b7a 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -84,7 +84,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <AdditionalIncludeDirectories>

-../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+../../library;../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

       <CompileAs>CompileAsC</CompileAs>

     </ClCompile>

     <Link>

@@ -98,7 +98,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <AdditionalIncludeDirectories>

-../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+../../library;../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

       <CompileAs>CompileAsC</CompileAs>

     </ClCompile>

     <Link>

@@ -114,7 +114,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>NDEBUG;_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <AdditionalIncludeDirectories>

-../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+../../library;../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

     </ClCompile>

     <Link>

       <SubSystem>Windows</SubSystem>

@@ -131,7 +131,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <AdditionalIncludeDirectories>

-../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+../../library;../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

     </ClCompile>

     <Link>

       <SubSystem>Windows</SubSystem>