Merge pull request #8491 from mschulz-at-hilscher/mbedtls-2.28

Backport 2.28: "CSR parsing with critical fields fails" #8377
diff --git a/BRANCHES.md b/BRANCHES.md
index 57d4027..6711cb9 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -76,6 +76,6 @@
 - [`development`](https://github.com/Mbed-TLS/mbedtls/)
 - [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
  maintained until at least the end of 2024, see
-  <https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.5>.
+  <https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.6>.
 
 Users are urged to always use the latest version of a maintained branch.
diff --git a/ChangeLog b/ChangeLog
index 27b5820..a856275 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 Mbed TLS ChangeLog (Sorted per branch, date)
 
+= Mbed TLS 2.28.6 branch released 2023-11-06
+
+Changes
+   *  Mbed TLS is now released under a dual Apache-2.0 OR GPL-2.0-or-later
+      license. Users may choose which license they take the code under.
+
 = Mbed TLS 2.28.5 branch released 2023-10-05
 
 Features
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 1a4cc41..c2343a6 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -10,7 +10,7 @@
  */
 
 /**
- * @mainpage Mbed TLS v2.28.5 API Documentation
+ * @mainpage Mbed TLS v2.28.6 API Documentation
  *
  * This documentation describes the internal structure of Mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index f6f160d..1939ac9 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -1,4 +1,4 @@
-PROJECT_NAME           = "Mbed TLS v2.28.5"
+PROJECT_NAME           = "Mbed TLS v2.28.6"
 OUTPUT_DIRECTORY       = ../apidoc/
 FULL_PATH_NAMES        = NO
 OPTIMIZE_OUTPUT_FOR_C  = YES
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index d844bfa..ac2146e 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -851,6 +851,9 @@
  * contexts and therefore is a compatibility break for applications that access
  * fields of a mbedtls_ecdh_context structure directly. See also
  * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h.
+ *
+ * The Everest code is provided under the Apache 2.0 license only; therefore enabling this
+ * option is not compatible with taking the library under the GPL v2.0-or-later license.
  */
 //#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
 
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 21348d2..ae91a09 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -26,16 +26,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  28
-#define MBEDTLS_VERSION_PATCH  5
+#define MBEDTLS_VERSION_PATCH  6
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x021C0500
-#define MBEDTLS_VERSION_STRING         "2.28.5"
-#define MBEDTLS_VERSION_STRING_FULL    "Mbed TLS 2.28.5"
+#define MBEDTLS_VERSION_NUMBER         0x021C0600
+#define MBEDTLS_VERSION_STRING         "2.28.6"
+#define MBEDTLS_VERSION_STRING_FULL    "Mbed TLS 2.28.6"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 8d88101..c7105a1 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -204,15 +204,15 @@
 if(USE_SHARED_MBEDTLS_LIBRARY)
     set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
     add_library(${mbedcrypto_target} SHARED ${src_crypto})
-    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.28.5 SOVERSION 7)
+    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.28.6 SOVERSION 7)
     target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
 
     add_library(${mbedx509_target} SHARED ${src_x509})
-    set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.28.5 SOVERSION 1)
+    set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.28.6 SOVERSION 1)
     target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 
     add_library(${mbedtls_target} SHARED ${src_tls})
-    set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.28.5 SOVERSION 14)
+    set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.28.6 SOVERSION 14)
     target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
diff --git a/programs/.gitignore b/programs/.gitignore
index 59634b5..8420c81 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -34,6 +34,7 @@
 psa/crypto_examples
 psa/key_ladder_demo
 psa/psa_constant_names
+psa/psa_hash
 random/gen_entropy
 random/gen_random_ctr_drbg
 random/gen_random_havege
@@ -53,6 +54,7 @@
 test/cpp_dummy_build.cpp
 test/dlopen
 test/ecp-bench
+test/metatest
 test/query_compile_time_config
 test/selftest
 test/ssl_cert_test
diff --git a/programs/Makefile b/programs/Makefile
index 2d0f705..2d32e00 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -114,6 +114,7 @@
 	ssl/ssl_server$(EXEXT) \
 	ssl/ssl_server2$(EXEXT) \
 	test/benchmark$(EXEXT) \
+	test/metatest$(EXEXT) \
 	test/query_compile_time_config$(EXEXT) \
 	test/selftest$(EXEXT) \
 	test/udp_proxy$(EXEXT) \
@@ -349,6 +350,10 @@
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/dlopen.c $(LDFLAGS) $(DLOPEN_LDFLAGS) -o $@
 endif
 
+test/metatest$(EXEXT): test/metatest.c $(DEP)
+	echo "  CC    test/metatest.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -I ../library test/metatest.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 test/query_config.o: test/query_config.c test/query_config.h $(DEP)
 	echo "  CC    test/query_config.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 403797c..662c5ff 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -11,6 +11,7 @@
 endif(ENABLE_ZLIB_SUPPORT)
 
 set(executables_libs
+    metatest
     selftest
     udp_proxy
 )
@@ -50,6 +51,8 @@
     endif()
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>
         ${extra_sources})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../library)
 
     # This emulates "if ( ... IN_LIST ... )" which becomes available in CMake 3.3
     list(FIND executables_libs ${exe} exe_index)
diff --git a/programs/test/metatest.c b/programs/test/metatest.c
new file mode 100644
index 0000000..2973cce
--- /dev/null
+++ b/programs/test/metatest.c
@@ -0,0 +1,351 @@
+/** \file metatest.c
+ *
+ *  \brief Test features of the test framework.
+ *
+ * When you run this program, it runs a single "meta-test". A meta-test
+ * performs an operation which should be caught as a failure by our
+ * test framework. The meta-test passes if this program calls `exit` with
+ * a nonzero status, or aborts, or is terminated by a signal, or if the
+ * framework running the program considers the run an error (this happens
+ * with Valgrind for a memory leak). The non-success of the meta-test
+ * program means that the test failure has been caught correctly.
+ *
+ * Some failures are purely functional: the logic of the code causes the
+ * test result to be set to FAIL. Other failures come from extra
+ * instrumentation which is not present in a normal build; for example,
+ * Asan or Valgrind to detect memory leaks. This is reflected by the
+ * "platform" associated with each meta-test.
+ *
+ * Use the companion script `tests/scripts/run-metatests.sh` to run all
+ * the meta-tests for a given platform and validate that they trigger a
+ * detected failure as expected.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#include <mbedtls/platform.h>
+#include <mbedtls/platform_util.h>
+#include "test/helpers.h"
+#include "test/macros.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(MBEDTLS_THREADING_C)
+#include <mbedtls/threading.h>
+#endif
+
+
+/* This is an external variable, so the compiler doesn't know that we're never
+ * changing its value.
+ */
+volatile int false_but_the_compiler_does_not_know = 0;
+
+/* Set n bytes at the address p to all-bits-zero, in such a way that
+ * the compiler should not know that p is all-bits-zero. */
+static void set_to_zero_but_the_compiler_does_not_know(volatile void *p, size_t n)
+{
+    memset((void *) p, false_but_the_compiler_does_not_know, n);
+}
+
+
+/****************************************************************/
+/* Test framework features */
+/****************************************************************/
+
+void meta_test_fail(const char *name)
+{
+    (void) name;
+    mbedtls_test_fail("Forced test failure", __LINE__, __FILE__);
+}
+
+
+/****************************************************************/
+/* Platform features */
+/****************************************************************/
+
+void null_pointer_dereference(const char *name)
+{
+    (void) name;
+    volatile char *volatile p;
+    set_to_zero_but_the_compiler_does_not_know(&p, sizeof(p));
+    /* Undefined behavior (read from null data pointer) */
+    mbedtls_printf("%p -> %u\n", p, (unsigned) *p);
+}
+
+void null_pointer_call(const char *name)
+{
+    (void) name;
+    unsigned(*volatile p)(void);
+    set_to_zero_but_the_compiler_does_not_know(&p, sizeof(p));
+    /* Undefined behavior (execute null function pointer) */
+    /* The pointer representation may be truncated, but we don't care:
+     * the only point of printing it is to have some use of the pointer
+     * to dissuade the compiler from optimizing it away. */
+    mbedtls_printf("%lx() -> %u\n", (unsigned long) (uintptr_t) p, p());
+}
+
+
+/****************************************************************/
+/* Memory */
+/****************************************************************/
+
+void read_after_free(const char *name)
+{
+    (void) name;
+    volatile char *p = mbedtls_calloc(1, 1);
+    *p = 'a';
+    mbedtls_free((void *) p);
+    /* Undefined behavior (read after free) */
+    mbedtls_printf("%u\n", (unsigned) *p);
+}
+
+void double_free(const char *name)
+{
+    (void) name;
+    volatile char *p = mbedtls_calloc(1, 1);
+    *p = 'a';
+    mbedtls_free((void *) p);
+    /* Undefined behavior (double free) */
+    mbedtls_free((void *) p);
+}
+
+void read_uninitialized_stack(const char *name)
+{
+    (void) name;
+    char buf[1];
+    if (false_but_the_compiler_does_not_know) {
+        buf[0] = '!';
+    }
+    char *volatile p = buf;
+    if (*p != 0) {
+        /* Unspecified result (read from uninitialized memory) */
+        mbedtls_printf("%u\n", (unsigned) *p);
+    }
+}
+
+void memory_leak(const char *name)
+{
+    (void) name;
+    volatile char *p = mbedtls_calloc(1, 1);
+    mbedtls_printf("%u\n", (unsigned) *p);
+    /* Leak of a heap object */
+}
+
+
+/****************************************************************/
+/* Threading */
+/****************************************************************/
+
+void mutex_lock_not_initialized(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    memset(&mutex, 0, sizeof(mutex));
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+    TEST_ASSERT(mbedtls_mutex_lock(&mutex) == 0);
+exit:
+    ;
+#endif
+}
+
+void mutex_unlock_not_initialized(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    memset(&mutex, 0, sizeof(mutex));
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+    TEST_ASSERT(mbedtls_mutex_unlock(&mutex) == 0);
+exit:
+    ;
+#endif
+}
+
+void mutex_free_not_initialized(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    memset(&mutex, 0, sizeof(mutex));
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+    mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_double_init(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    mbedtls_mutex_init(&mutex);
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+    mbedtls_mutex_init(&mutex);
+    mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_double_free(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    mbedtls_mutex_init(&mutex);
+    mbedtls_mutex_free(&mutex);
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+    mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_leak(const char *name)
+{
+    (void) name;
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+    mbedtls_mutex_init(&mutex);
+#endif
+    /* This mutex usage error is detected by our test framework's mutex usage
+     * verification framework. See tests/src/threading_helpers.c. Other
+     * threading implementations (e.g. pthread without our instrumentation)
+     * might consider this normal usage. */
+}
+
+
+/****************************************************************/
+/* Command line entry point */
+/****************************************************************/
+
+typedef struct {
+    /** Command line argument that will trigger that metatest.
+     *
+     * Conventionally matches "[a-z0-9_]+". */
+    const char *name;
+
+    /** Platform under which that metatest is valid.
+     *
+     * - "any": should work anywhere.
+     * - "asan": triggers ASan (Address Sanitizer).
+     * - "msan": triggers MSan (Memory Sanitizer).
+     * - "pthread": requires MBEDTLS_THREADING_PTHREAD and MBEDTLS_TEST_HOOKS,
+     *   which enables MBEDTLS_TEST_MUTEX_USAGE internally in the test
+     *   framework (see tests/src/threading_helpers.c).
+     */
+    const char *platform;
+
+    /** Function that performs the metatest.
+     *
+     * The function receives the name as an argument. This allows using the
+     * same function to perform multiple variants of a test based on the name.
+     *
+     * When executed on a conforming platform, the function is expected to
+     * either cause a test failure (mbedtls_test_fail()), or cause the
+     * program to abort in some way (e.g. by causing a segfault or by
+     * triggering a sanitizer).
+     *
+     * When executed on a non-conforming platform, the function may return
+     * normally or may have unpredictable behavior.
+     */
+    void (*entry_point)(const char *name);
+} metatest_t;
+
+/* The list of availble meta-tests. Remember to register new functions here!
+ *
+ * Note that we always compile all the functions, so that `metatest --list`
+ * will always list all the available meta-tests.
+ *
+ * See the documentation of metatest_t::platform for the meaning of
+ * platform values.
+ */
+metatest_t metatests[] = {
+    { "test_fail", "any", meta_test_fail },
+    { "null_dereference", "any", null_pointer_dereference },
+    { "null_call", "any", null_pointer_call },
+    { "read_after_free", "asan", read_after_free },
+    { "double_free", "asan", double_free },
+    { "read_uninitialized_stack", "msan", read_uninitialized_stack },
+    { "memory_leak", "asan", memory_leak },
+    { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized },
+    { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized },
+    { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized },
+    { "mutex_double_init", "pthread", mutex_double_init },
+    { "mutex_double_free", "pthread", mutex_double_free },
+    { "mutex_leak", "pthread", mutex_leak },
+    { NULL, NULL, NULL }
+};
+
+static void help(FILE *out, const char *argv0)
+{
+    mbedtls_fprintf(out, "Usage: %s list|TEST\n", argv0);
+    mbedtls_fprintf(out, "Run a meta-test that should cause a test failure.\n");
+    mbedtls_fprintf(out, "With 'list', list the available tests and their platform requirement.\n");
+}
+
+int main(int argc, char *argv[])
+{
+    const char *argv0 = argc > 0 ? argv[0] : "metatest";
+    if (argc != 2) {
+        help(stderr, argv0);
+        mbedtls_exit(MBEDTLS_EXIT_FAILURE);
+    }
+
+    /* Support "-help", "--help", "--list", etc. */
+    const char *command = argv[1];
+    while (*command == '-') {
+        ++command;
+    }
+
+    if (strcmp(argv[1], "help") == 0) {
+        help(stdout, argv0);
+        mbedtls_exit(MBEDTLS_EXIT_SUCCESS);
+    }
+    if (strcmp(argv[1], "list") == 0) {
+        for (const metatest_t *p = metatests; p->name != NULL; p++) {
+            mbedtls_printf("%s %s\n", p->name, p->platform);
+        }
+        mbedtls_exit(MBEDTLS_EXIT_SUCCESS);
+    }
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_init();
+#endif
+
+    for (const metatest_t *p = metatests; p->name != NULL; p++) {
+        if (strcmp(argv[1], p->name) == 0) {
+            mbedtls_printf("Running metatest %s...\n", argv[1]);
+            p->entry_point(argv[1]);
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+            mbedtls_test_mutex_usage_check();
+#endif
+            mbedtls_printf("Running metatest %s... done, result=%d\n",
+                           argv[1], (int) mbedtls_test_info.result);
+            mbedtls_exit(mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS ?
+                         MBEDTLS_EXIT_SUCCESS :
+                         MBEDTLS_EXIT_FAILURE);
+        }
+    }
+
+    mbedtls_fprintf(stderr, "%s: FATAL: No such metatest: %s\n",
+                    argv0, command);
+    mbedtls_exit(MBEDTLS_EXIT_FAILURE);
+}
diff --git a/scripts/ci.requirements.txt b/scripts/ci.requirements.txt
index 9b96a8d..e779483 100644
--- a/scripts/ci.requirements.txt
+++ b/scripts/ci.requirements.txt
@@ -12,3 +12,7 @@
 # Use the earliest version of mypy that works with our code base.
 # See https://github.com/Mbed-TLS/mbedtls/pull/3953 .
 mypy >= 0.780
+
+# For building `tests/data_files/server9-bad-saltlen.crt` and check python
+# files.
+asn1crypto
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index ab2c93d..11604cd 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -145,6 +145,7 @@
     my $guid = gen_app_guid( $path );
     $path =~ s!/!\\!g;
     (my $appname = $path) =~ s/.*\\//;
+    my $is_test_app = ($path =~ m/^test\\/);
 
     my $srcs = "<ClCompile Include=\"..\\..\\programs\\$path.c\" \/>";
     if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or
@@ -159,7 +160,9 @@
     $content =~ s/<SOURCES>/$srcs/g;
     $content =~ s/<APPNAME>/$appname/g;
     $content =~ s/<GUID>/$guid/g;
-    $content =~ s/INCLUDE_DIRECTORIES\r\n/$include_directories/g;
+    $content =~ s/INCLUDE_DIRECTORIES\r\n/($is_test_app ?
+                                           $library_include_directories :
+                                           $include_directories)/ge;
 
     content_to_file( $content, "$dir/$appname.$ext" );
 }
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index f67db07..68bc124 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -151,10 +151,8 @@
 	$(OPENSSL) x509 -req -in test-ca2.req.sha256 -extfile $< \
 		-signkey $(test_ca_key_file_ec) -days 3653 -out $@
 
-all_final += test-ca2.ku-crl.crt \
-			 test-ca2.ku-crt.crt \
-			 test-ca2.ku-crt_crl.crt \
-			 test-ca2.ku-ds.crt
+all_final += test-ca2.ku-crl.crt test-ca2.ku-crt.crt test-ca2.ku-crt_crl.crt \
+	     test-ca2.ku-ds.crt
 
 test-ca2-future.crt: $(test_ca_key_file_ec) test-ca2.req.sha256
 	$(MBEDTLS_CERT_WRITE) is_ca=1 serial=13926223505202072808 request_file=test-ca2.req.sha256 selfsign=1 \
@@ -513,10 +511,6 @@
 	cat $^ > $@
 all_final += server9-with-ca.crt
 
-# FIXME: This file needs special sequence. It should be update manually
-server9-bad-saltlen.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa)
-	false
-
 server9-bad-mgfhash.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa \
 		-passin "pass:$(test_ca_pwd_rsa)" -CA $(test_ca_crt) -CAkey $(test_ca_key_file_rsa) \
@@ -526,6 +520,16 @@
 		-in $< -out $@
 all_final += server9-bad-mgfhash.crt
 
+server9-bad-saltlen.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa) \
+			 opensslcnf/server9.crt.v3_ext \
+			 ../scripts/generate_server9_bad_saltlen.py
+	../scripts/generate_server9_bad_saltlen.py --ca-name test-ca \
+		--ca-password $(test_ca_pwd_rsa) --csr server9.csr \
+		--openssl-extfile opensslcnf/server9.crt.v3_ext \
+		--anounce_saltlen 0xde --actual_saltlen 0x20 \
+		--output $@
+all_final += server9-bad-saltlen.crt
+
 # server10*
 
 server10.crt: server10.key test-int-ca3.crt test-int-ca3.key
@@ -1362,9 +1366,9 @@
 all_intermediate += server6-ss-child.csr
 server6-ss-child.crt: server6-ss-child.csr server5-selfsigned.crt server5.key server6-ss-child.crt.openssl.v3_ext
 	$(OPENSSL) x509 -req -CA server5-selfsigned.crt -CAkey server5.key \
-				-extfile server6-ss-child.crt.openssl.v3_ext \
-				-set_serial 0x53a2cb5822399474a7ec79ec \
-				-days 3650 -sha256 -in $< -out $@
+		-extfile server6-ss-child.crt.openssl.v3_ext \
+		-set_serial 0x53a2cb5822399474a7ec79ec \
+		-days 3650 -sha256 -in $< -out $@
 all_final += server6-ss-child.crt
 
 
@@ -1501,9 +1505,9 @@
 	$(OPENSSL) ca -gencrl -batch -cert $(test_ca_crt) -keyfile $(test_ca_key_file_rsa) -key $(test_ca_pwd_rsa) -config $(test_ca_server1_config_file) -md sha1 -crldays 3653 -out $@
 
 crl-futureRevocationDate.pem: $(test_ca_crt) $(test_ca_key_file_rsa) \
-							  $(test_ca_config_file) 				\
-							  test-ca.server1.future-crl.db  \
-							  test-ca.server1.future-crl.opensslconf
+			      $(test_ca_config_file) \
+			      test-ca.server1.future-crl.db \
+			      test-ca.server1.future-crl.opensslconf
 	$(FAKETIME) -f '+10y' $(OPENSSL) ca -gencrl \
 		-config test-ca.server1.future-crl.opensslconf -crldays 365 \
 		-passin "pass:$(test_ca_pwd_rsa)" -out $@
diff --git a/tests/data_files/opensslcnf/server9.crt.v3_ext b/tests/data_files/opensslcnf/server9.crt.v3_ext
new file mode 100644
index 0000000..f8d201b
--- /dev/null
+++ b/tests/data_files/opensslcnf/server9.crt.v3_ext
@@ -0,0 +1,4 @@
+basicConstraints = CA:false
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 69f141f..aae0209 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -875,6 +875,9 @@
     msg "test: selftest (ASan build)" # ~ 10s
     programs/test/selftest
 
+    msg "test: metatests (GCC, ASan build)"
+    tests/scripts/run-metatests.sh any asan
+
     msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
     tests/ssl-opt.sh
 
@@ -1482,6 +1485,9 @@
     msg "test: Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
     make test
 
+    msg "test: metatests (clang, ASan)"
+    tests/scripts/run-metatests.sh any asan
+
     msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
     tests/ssl-opt.sh -f ECDH
 
@@ -1572,6 +1578,9 @@
     msg "test: cpp_dummy_build (full config, clang)" # ~ 1s
     programs/test/cpp_dummy_build
 
+    msg "test: metatests (clang)"
+    tests/scripts/run-metatests.sh any pthread
+
     msg "program demos (full config, clang)" # ~10s
     tests/scripts/run_demos.py
 
@@ -3345,6 +3354,9 @@
     msg "test: main suites (MSan)" # ~ 10s
     make test
 
+    msg "test: metatests (MSan)"
+    tests/scripts/run-metatests.sh any msan
+
     msg "program demos (MSan)" # ~20s
     tests/scripts/run_demos.py
 
diff --git a/tests/scripts/generate_server9_bad_saltlen.py b/tests/scripts/generate_server9_bad_saltlen.py
new file mode 100755
index 0000000..9af4dd3
--- /dev/null
+++ b/tests/scripts/generate_server9_bad_saltlen.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+"""Generate server9-bad-saltlen.crt
+
+Generate a certificate signed with RSA-PSS, with an incorrect salt length.
+"""
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+import subprocess
+import argparse
+from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error
+
+OPENSSL_RSA_PSS_CERT_COMMAND = r'''
+openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \
+    {openssl_extfile} -days 3650 -outform DER -in {csr}  \
+    -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \
+    -sigopt rsa_mgf1_md:sha256
+'''
+SIG_OPT = \
+    r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256'
+OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \
+    -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \
+    -sigopt rsa_mgf1_md:sha256'''
+
+
+def auto_int(x):
+    return int(x, 0)
+
+
+def build_argparser(parser):
+    """Build argument parser"""
+    parser.description = __doc__
+    parser.add_argument('--ca-name', type=str, required=True,
+                        help='Basename of CA files')
+    parser.add_argument('--ca-password', type=str,
+                        required=True, help='CA key file password')
+    parser.add_argument('--csr', type=str, required=True,
+                        help='CSR file for generating certificate')
+    parser.add_argument('--openssl-extfile', type=str,
+                        required=True, help='X905 v3 extension config file')
+    parser.add_argument('--anounce_saltlen', type=auto_int,
+                        required=True, help='Announced salt length')
+    parser.add_argument('--actual_saltlen', type=auto_int,
+                        required=True, help='Actual salt length')
+    parser.add_argument('--output', type=str, required=True)
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    build_argparser(parser)
+    args = parser.parse_args()
+
+    return generate(**vars(args))
+
+def generate(**kwargs):
+    """Generate different salt length certificate file."""
+    ca_password = kwargs.get('ca_password', '')
+    if ca_password:
+        kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format(
+            **kwargs)
+    else:
+        kwargs['ca_password'] = ''
+    extfile = kwargs.get('openssl_extfile', '')
+    if extfile:
+        kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format(
+            **kwargs)
+    else:
+        kwargs['openssl_extfile'] = ''
+
+    cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs)
+    der_bytes = subprocess.check_output(cmd, shell=True)
+    target_certificate = x509.Certificate.load(der_bytes)
+
+    cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs)
+    #pylint: disable=unexpected-keyword-arg
+    der_bytes = subprocess.check_output(cmd,
+                                        input=target_certificate['tbs_certificate'].dump(),
+                                        shell=True)
+
+    with open(kwargs.get('output'), 'wb') as f:
+        target_certificate['signature_value'] = core.OctetBitString(der_bytes)
+        f.write(pem.armor('CERTIFICATE', target_certificate.dump()))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/scripts/run-metatests.sh b/tests/scripts/run-metatests.sh
new file mode 100755
index 0000000..22a302c
--- /dev/null
+++ b/tests/scripts/run-metatests.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+help () {
+    cat <<EOF
+Usage: $0 [OPTION] [PLATFORM]...
+Run all the metatests whose platform matches any of the given PLATFORM.
+A PLATFORM can contain shell wildcards.
+
+Expected output: a lot of scary-looking error messages, since each
+metatest is expected to report a failure. The final line should be
+"Ran N metatests, all good."
+
+If something goes wrong: the final line should be
+"Ran N metatests, X unexpected successes". Look for "Unexpected success"
+in the logs above.
+
+  -l  List the available metatests, don't run them.
+EOF
+}
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+set -e -u
+
+if [ -d programs ]; then
+    METATEST_PROGRAM=programs/test/metatest
+elif [ -d ../programs ]; then
+    METATEST_PROGRAM=../programs/test/metatest
+elif [ -d ../../programs ]; then
+    METATEST_PROGRAM=../../programs/test/metatest
+else
+    echo >&2 "$0: FATAL: programs/test/metatest not found"
+    exit 120
+fi
+
+LIST_ONLY=
+while getopts hl OPTLET; do
+    case $OPTLET in
+        h) help; exit;;
+        l) LIST_ONLY=1;;
+        \?) help >&2; exit 120;;
+    esac
+done
+shift $((OPTIND - 1))
+
+list_matches () {
+    while read name platform junk; do
+        for pattern in "$@"; do
+            case $platform in
+                $pattern) echo "$name"; break;;
+            esac
+        done
+    done
+}
+
+count=0
+errors=0
+run_metatest () {
+    ret=0
+    "$METATEST_PROGRAM" "$1" || ret=$?
+    if [ $ret -eq 0 ]; then
+        echo >&2 "$0: Unexpected success: $1"
+        errors=$((errors + 1))
+    fi
+    count=$((count + 1))
+}
+
+# Don't pipe the output of metatest so that if it fails, this script exits
+# immediately with a failure status.
+full_list=$("$METATEST_PROGRAM" list)
+matching_list=$(printf '%s\n' "$full_list" | list_matches "$@")
+
+if [ -n "$LIST_ONLY" ]; then
+    printf '%s\n' $matching_list
+    exit
+fi
+
+for name in $matching_list; do
+    run_metatest "$name"
+done
+
+if [ $errors -eq 0 ]; then
+    echo "Ran $count metatests, all good."
+    exit 0
+else
+    echo "Ran $count metatests, $errors unexpected successes."
+    exit 1
+fi
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 25974db..c1b81a4 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compile time library version
-check_compiletime_version:"2.28.5"
+check_compiletime_version:"2.28.6"
 
 Check runtime library version
-check_runtime_version:"2.28.5"
+check_runtime_version:"2.28.6"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/visualc/VS2010/benchmark.vcxproj b/visualc/VS2010/benchmark.vcxproj
index 0be32fc..ab27b6c 100644
--- a/visualc/VS2010/benchmark.vcxproj
+++ b/visualc/VS2010/benchmark.vcxproj
@@ -93,7 +93,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index 3624735..995ba52 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -203,6 +203,11 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

 	EndProjectSection

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "metatest", "metatest.vcxproj", "{95B15C5B-0EB4-4353-7990-22F6965A9437}"

+	ProjectSection(ProjectDependencies) = postProject

+		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

+	EndProjectSection

+EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "query_compile_time_config", "query_compile_time_config.vcxproj", "{D6F58AF2-9D80-562A-E2B0-F743281522B9}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -599,6 +604,14 @@
 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Release|Win32.Build.0 = Release|Win32

 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Release|x64.ActiveCfg = Release|x64

 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Release|x64.Build.0 = Release|x64

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Debug|Win32.ActiveCfg = Debug|Win32

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Debug|Win32.Build.0 = Debug|Win32

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Debug|x64.ActiveCfg = Debug|x64

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Debug|x64.Build.0 = Debug|x64

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Release|Win32.ActiveCfg = Release|Win32

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Release|Win32.Build.0 = Release|Win32

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Release|x64.ActiveCfg = Release|x64

+		{95B15C5B-0EB4-4353-7990-22F6965A9437}.Release|x64.Build.0 = Release|x64

 		{D6F58AF2-9D80-562A-E2B0-F743281522B9}.Debug|Win32.ActiveCfg = Debug|Win32

 		{D6F58AF2-9D80-562A-E2B0-F743281522B9}.Debug|Win32.Build.0 = Debug|Win32

 		{D6F58AF2-9D80-562A-E2B0-F743281522B9}.Debug|x64.ActiveCfg = Debug|x64

diff --git a/visualc/VS2010/metatest.vcxproj b/visualc/VS2010/metatest.vcxproj
new file mode 100644
index 0000000..b1addb6
--- /dev/null
+++ b/visualc/VS2010/metatest.vcxproj
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup Label="ProjectConfigurations">

+    <ProjectConfiguration Include="Debug|Win32">

+      <Configuration>Debug</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug|x64">

+      <Configuration>Debug</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|x64">

+      <Configuration>Release</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\programs\test\metatest.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="mbedTLS.vcxproj">

+      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

+      <LinkLibraryDependencies>true</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{95B15C5B-0EB4-4353-7990-22F6965A9437}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>metatest</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <LinkIncremental>true</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <LinkIncremental>true</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <LinkIncremental>false</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <LinkIncremental>false</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <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>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <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>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <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>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <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>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>

diff --git a/visualc/VS2010/query_compile_time_config.vcxproj b/visualc/VS2010/query_compile_time_config.vcxproj
index d0e0a6d..97bfad4 100644
--- a/visualc/VS2010/query_compile_time_config.vcxproj
+++ b/visualc/VS2010/query_compile_time_config.vcxproj
@@ -94,7 +94,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

diff --git a/visualc/VS2010/selftest.vcxproj b/visualc/VS2010/selftest.vcxproj
index 6feb593..3629901 100644
--- a/visualc/VS2010/selftest.vcxproj
+++ b/visualc/VS2010/selftest.vcxproj
@@ -93,7 +93,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

diff --git a/visualc/VS2010/udp_proxy.vcxproj b/visualc/VS2010/udp_proxy.vcxproj
index 69678f6..993fbc0 100644
--- a/visualc/VS2010/udp_proxy.vcxproj
+++ b/visualc/VS2010/udp_proxy.vcxproj
@@ -93,7 +93,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

diff --git a/visualc/VS2010/zeroize.vcxproj b/visualc/VS2010/zeroize.vcxproj
index 9e0746d..f70896f 100644
--- a/visualc/VS2010/zeroize.vcxproj
+++ b/visualc/VS2010/zeroize.vcxproj
@@ -93,7 +93,7 @@
       <Optimization>Disabled</Optimization>

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>

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

       <PreprocessorDefinitions>NDEBUG;%(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>Console</SubSystem>