Merge pull request #3392 from paul-elliott-arm/psa_ecc_dh_macros

PSA: update EC curve and DH group family macros
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 b44948b..631415c 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 7e55342..0c6d5a5 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 b36a773..00ae8e1 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 bb83db0..dea452b 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 d7a568e..0c23d25 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_FAMILY_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 4abdd27..f2b16e4 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_FAMILY_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>