Merge tag 'mbedtls-2.3.0'

mbed TLS version 2.3.0
diff --git a/.travis.yml b/.travis.yml
index f30a4e3..fa01e5a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,7 @@
 - tests/scripts/check-generated-files.sh
 - tests/scripts/check-doxy-blocks.pl
 - tests/scripts/check-names.sh
+- tests/scripts/doxygen.sh
 - cmake -D CMAKE_BUILD_TYPE:String="Check" .
 - make
 - make test
@@ -18,11 +19,17 @@
 - tests/scripts/test-ref-configs.pl
 - tests/scripts/curves.pl
 - tests/scripts/key-exchanges.pl
+after_failure:
+- tests/scripts/travis-log-failure.sh
 env:
   global:
     secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
 
 addons:
+  apt:
+    packages:
+    - doxygen
+    - graphviz
   coverity_scan:
     project:
       name: "ARMmbed/mbedtls"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8905218..0a02ef1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,6 +6,7 @@
 
 option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
 
+option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
 
 # the test suites currently have compile errors with MSVC
 if(MSVC)
@@ -14,6 +15,43 @@
     option(ENABLE_TESTING "Build mbed TLS tests." ON)
 endif()
 
+# Warning string - created as a list for compatibility with CMake 2.8
+set(WARNING_BORDER "*******************************************************\n")
+set(NULL_ENTROPY_WARN_L1 "****  WARNING!  MBEDTLS_TEST_NULL_ENTROPY defined!\n")
+set(NULL_ENTROPY_WARN_L2 "****  THIS BUILD HAS NO DEFINED ENTROPY SOURCES\n")
+set(NULL_ENTROPY_WARN_L3 "****  AND IS *NOT* SUITABLE FOR PRODUCTION USE\n")
+
+set(NULL_ENTROPY_WARNING "${WARNING_BORDER}"
+                         "${NULL_ENTROPY_WARN_L1}"
+                         "${NULL_ENTROPY_WARN_L2}"
+                         "${NULL_ENTROPY_WARN_L3}"
+                         "${WARNING_BORDER}")
+
+find_package(Perl)
+if(PERL_FOUND)
+
+    # If NULL Entropy is configured, display an appropriate warning
+    execute_process(COMMAND ${PERL_EXECUTABLE} scripts/config.pl get MBEDTLS_TEST_NULL_ENTROPY
+                        RESULT_VARIABLE result)
+    if(${result} EQUAL 0)
+        message(WARNING ${NULL_ENTROPY_WARNING})
+
+        if(NOT UNSAFE_BUILD)
+            message(FATAL_ERROR "\
+\n\
+Warning! You have enabled MBEDTLS_TEST_NULL_ENTROPY. \
+This option is not safe for production use and negates all security \
+It is intended for development use only. \
+\n\
+To confirm you want to build with this option, re-run cmake with the \
+option: \n\
+  cmake -DUNSAFE_BUILD=ON ")
+
+            return()
+        endif()
+    endif()
+endif()
+
 set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
     CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
     FORCE)
@@ -85,20 +123,9 @@
     add_subdirectory(programs)
 endif()
 
-# targets for doxygen only work on Unix
-if(UNIX)
-    ADD_CUSTOM_TARGET(apidoc
-        COMMAND mkdir -p apidoc
-        COMMAND cp include/mbedtls/config.h include/mbedtls/config.h.bak
-        COMMAND scripts/config.pl realfull
-        COMMAND doxygen doxygen/mbedtls.doxyfile
-        COMMAND mv include/mbedtls/config.h.bak include/mbedtls/config.h
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-
-    ADD_CUSTOM_TARGET(apidoc_clean
-        COMMAND rm -rf apidoc
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-endif(UNIX)
+ADD_CUSTOM_TARGET(apidoc
+    COMMAND doxygen doxygen/mbedtls.doxyfile
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 if(ENABLE_TESTING)
     enable_testing()
diff --git a/ChangeLog b/ChangeLog
index e21187f..1ef952c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,65 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.3.0 branch released 2016-06-28
+
+Security
+   * Fix missing padding length check in mbedtls_rsa_rsaes_pkcs1_v15_decrypt
+     required by PKCS1 v2.2
+   * Fix potential integer overflow to buffer overflow in
+     mbedtls_rsa_rsaes_pkcs1_v15_encrypt and mbedtls_rsa_rsaes_oaep_encrypt
+     (not triggerable remotely in (D)TLS).
+   * Fix a potential integer underflow to buffer overread in 
+     mbedtls_rsa_rsaes_oaep_decrypt. It is not triggerable remotely in
+     SSL/TLS.
+
+Features
+   * Support for platform abstraction of the standard C library time()
+     function.
+
+Bugfix
+   * Fix bug in mbedtls_mpi_add_mpi() that caused wrong results when the three
+     arguments where the same (in-place doubling). Found and fixed by Janos
+     Follath. #309
+   * Fix potential build failures related to the 'apidoc' target, introduced
+     in the previous patch release. Found by Robert Scheck. #390 #391
+   * Fix issue in Makefile that prevented building using armar. #386
+   * Fix memory leak that occured only when ECJPAKE was enabled and ECDHE and
+     ECDSA was disabled in config.h . The leak didn't occur by default.
+   * Fix an issue that caused valid certificates to be rejected whenever an
+     expired or not yet valid certificate was parsed before a valid certificate
+     in the trusted certificate list.
+   * Fix bug in mbedtls_x509_crt_parse that caused trailing extra data in the 
+     buffer after DER certificates to be included in the raw representation.
+   * Fix issue that caused a hang when generating RSA keys of odd bitlength
+   * Fix bug in mbedtls_rsa_rsaes_pkcs1_v15_encrypt that made null pointer
+     dereference possible.
+   * Fix issue that caused a crash if invalid curves were passed to
+     mbedtls_ssl_conf_curves. #373
+   * Fix issue in ssl_fork_server which was preventing it from functioning. #429
+   * Fix memory leaks in test framework
+   * Fix test in ssl-opt.sh that does not run properly with valgrind
+   * Fix unchecked calls to mmbedtls_md_setup(). Fix by Brian Murray. #502
+
+Changes
+   * On ARM platforms, when compiling with -O0 with GCC, Clang or armcc5,
+     don't use the optimized assembly for bignum multiplication. This removes
+     the need to pass -fomit-frame-pointer to avoid a build error with -O0.
+   * Disabled SSLv3 in the default configuration.
+   * Optimized mbedtls_mpi_zeroize() for MPI integer size. (Fix by Alexey
+     Skalozub).
+   * Fix non-compliance server extension handling. Extensions for SSLv3 are now
+     ignored, as required by RFC6101.
+
 = mbed TLS 2.2.1 released 2016-01-05
 
 Security
    * Fix potential double free when mbedtls_asn1_store_named_data() fails to
      allocate memory. Only used for certificate generation, not triggerable
      remotely in SSL/TLS. Found by RafaƂ Przywara. #367
-   * Disable MD5 handshake signatures in TLS 1.2 by default
+   * Disable MD5 handshake signatures in TLS 1.2 by default to prevent the
+     SLOTH attack on TLS 1.2 server authentication (other attacks from the
+     SLOTH paper do not apply to any version of mbed TLS or PolarSSL).
+     https://www.mitls.org/pages/attacks/SLOTH
 
 Bugfix
    * Fix over-restrictive length limit in GCM. Found by Andreas-N. #362
diff --git a/Makefile b/Makefile
index 0950e6b..7f334ee 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
 
 .PHONY: all no_test programs lib tests install uninstall clean test check covtest lcov apidoc apidoc_clean
 
-all: programs tests
+all: programs tests post_build
 
 no_test: programs
 
@@ -53,6 +53,21 @@
 	done
 endif
 
+WARNING_BORDER      =*******************************************************\n
+NULL_ENTROPY_WARN_L1=****  WARNING!  MBEDTLS_TEST_NULL_ENTROPY defined! ****\n
+NULL_ENTROPY_WARN_L2=****  THIS BUILD HAS NO DEFINED ENTROPY SOURCES    ****\n
+NULL_ENTROPY_WARN_L3=****  AND IS *NOT* SUITABLE FOR PRODUCTION USE     ****\n
+
+NULL_ENTROPY_WARNING=\n$(WARNING_BORDER)$(NULL_ENTROPY_WARN_L1)$(NULL_ENTROPY_WARN_L2)$(NULL_ENTROPY_WARN_L3)$(WARNING_BORDER)
+
+# Post build steps
+post_build:
+ifndef WINDOWS
+	# If NULL Entropy is configured, display an appropriate warning
+	-scripts/config.pl get MBEDTLS_TEST_NULL_ENTROPY && ([ $$? -eq 0 ]) && \
+	    echo '$(NULL_ENTROPY_WARNING)'
+endif
+
 clean:
 	$(MAKE) -C library clean
 	$(MAKE) -C programs clean
@@ -87,10 +102,7 @@
 
 apidoc:
 	mkdir -p apidoc
-	cp include/mbedtls/config.h include/mbedtls/config.h.bak
-	scripts/config.pl realfull
 	doxygen doxygen/mbedtls.doxyfile
-	mv include/mbedtls/config.h.bak include/mbedtls/config.h
 
 apidoc_clean:
 	rm -rf apidoc
diff --git a/configs/config-thread.h b/configs/config-thread.h
index 453b17f..3193a04 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -85,10 +85,6 @@
 /* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
 #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
 
-#if defined(TARGET_LIKE_MBED)
-#include "mbedtls/target_config.h"
-#endif
-
 #include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/doxygen/input/doc_hashing.h b/doxygen/input/doc_hashing.h
index de82050..49f15ea 100644
--- a/doxygen/input/doc_hashing.h
+++ b/doxygen/input/doc_hashing.h
@@ -23,13 +23,14 @@
 /**
  * @addtogroup hashing_module Hashing module
  *
- * The Hashing module provides one-way hashing functions. Such functions can be
- * used for creating a hash message authentication code (HMAC) when sending a
- * message. Such a HMAC can be used in combination with a private key
- * for authentication, which is a message integrity control.
+ * The Message Digest (MD) or Hashing module provides one-way hashing
+ * functions. Such functions can be used for creating a hash message
+ * authentication code (HMAC) when sending a message. Such a HMAC can be used
+ * in combination with a private key for authentication, which is a message
+ * integrity control.
  *
  * All hash algorithms can be accessed via the generic MD layer (see
- * \c md_setup())
+ * \c mbedtls_md_setup())
  *
  * The following hashing-algorithms are provided:
  * - MD2, MD4, MD5 128-bit one-way hash functions by Ron Rivest.
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 9643a6f..b13083c 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -21,7 +21,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.2.1 source code documentation
+ * @mainpage mbed TLS v2.3.0 source code 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 6a00f47..253e184 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.2.1"
+PROJECT_NAME           = "mbed TLS v2.3.0"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
@@ -696,7 +696,7 @@
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = configs
+EXCLUDE                = configs yotta/module
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -710,7 +710,7 @@
 # against the file with absolute path, so to exclude all test directories
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       =
+EXCLUDE_PATTERNS       = *_internal.h *_wrap.h
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1485,13 +1485,13 @@
 # which can be used by a validating XML parser to check the
 # syntax of the XML files.
 
-XML_SCHEMA             =
+#XML_SCHEMA             =
 
 # The XML_DTD tag can be used to specify an XML DTD,
 # which can be used by a validating XML parser to check the
 # syntax of the XML files.
 
-XML_DTD                =
+#XML_DTD                =
 
 # If the XML_PROGRAMLISTING tag is set to YES Doxygen will
 # dump the program listings (including syntax highlighting
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 5408d41..cac3f14 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -162,10 +162,6 @@
 
 #define MULADDC_INIT                        \
     asm(                                    \
-        "movq   %3, %%rsi           \n\t"   \
-        "movq   %4, %%rdi           \n\t"   \
-        "movq   %5, %%rcx           \n\t"   \
-        "movq   %6, %%rbx           \n\t"   \
         "xorq   %%r8, %%r8          \n\t"
 
 #define MULADDC_CORE                        \
@@ -181,12 +177,9 @@
         "addq   $8,      %%rdi      \n\t"
 
 #define MULADDC_STOP                        \
-        "movq   %%rcx, %0           \n\t"   \
-        "movq   %%rdi, %1           \n\t"   \
-        "movq   %%rsi, %2           \n\t"   \
-        : "=m" (c), "=m" (d), "=m" (s)                      \
-        : "m" (s), "m" (d), "m" (c), "m" (b)                \
-        : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8"    \
+        : "+c" (c), "+D" (d), "+S" (s)      \
+        : "b" (b)                           \
+        : "rax", "rdx", "r8"                \
     );
 
 #endif /* AMD64 */
@@ -563,7 +556,23 @@
 
 #endif /* TriCore */
 
-#if defined(__arm__)
+/*
+ * gcc -O0 by default uses r7 for the frame pointer, so it complains about our
+ * use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
+ * passing that option is not easy when building with yotta.
+ *
+ * On the other hand, -fomit-frame-pointer is implied by any -Ox options with
+ * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
+ * clang and armcc5 under the same conditions).
+ *
+ * So, only use the optimized assembly below for optimized build, which avoids
+ * the build error and is pretty reasonable anyway.
+ */
+#if defined(__GNUC__) && !defined(__OPTIMIZE__)
+#define MULADDC_CANNOT_USE_R7
+#endif
+
+#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
 
 #if defined(__thumb__) && !defined(__thumb2__)
 
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index b6448ec..a95af6c 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -3,7 +3,7 @@
  *
  * \brief Consistency checks for configuration options
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -130,6 +130,16 @@
 #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+    ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
+#endif
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+     ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
+    defined(MBEDTLS_HAVEGE_C) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
+#endif
+
 #if defined(MBEDTLS_GCM_C) && (                                        \
         !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
 #error "MBEDTLS_GCM_C defined, but not all prerequisites"
@@ -357,11 +367,48 @@
 #error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
+#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
+    !defined(MBEDTLS_ENTROPY_NV_SEED)
+#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
+#endif
+
 #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) ||         \
     !defined(MBEDTLS_OID_C) )
 #error "MBEDTLS_RSA_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) &&         \
+    !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
+#endif
+
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) &&                        \
     ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
 #error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 70000f5..c967554 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -57,6 +57,7 @@
 #define MBEDTLS_ERR_CIPHER_INVALID_PADDING                -0x6200  /**< Input data contains invalid padding and is rejected. */
 #define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED            -0x6280  /**< Decryption of block requires a full block. */
 #define MBEDTLS_ERR_CIPHER_AUTH_FAILED                    -0x6300  /**< Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT              -0x6380  /**< The context is invalid, eg because it was free()ed. */
 
 #define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length */
 #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index d1db0d8..3b7c85b 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -152,9 +152,11 @@
  * platform function
  */
 //#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
 //#define MBEDTLS_PLATFORM_FPRINTF_ALT
 //#define MBEDTLS_PLATFORM_PRINTF_ALT
 //#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
 
 /**
  * \def MBEDTLS_DEPRECATED_WARNING
@@ -278,6 +280,23 @@
 //#define MBEDTLS_AES_DECRYPT_ALT
 
 /**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
  * \def MBEDTLS_ENTROPY_HARDWARE_ALT
  *
  * Uncomment this macro to let mbed TLS use your own implementation of a
@@ -799,6 +818,34 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
  * \def MBEDTLS_MEMORY_DEBUG
  *
  * Enable debugging of buffer allocator memory issues. Automatically prints
@@ -1058,7 +1105,7 @@
  *
  * Comment this macro to disable support for SSL 3.0
  */
-#define MBEDTLS_SSL_PROTO_SSL3
+//#define MBEDTLS_SSL_PROTO_SSL3
 
 /**
  * \def MBEDTLS_SSL_PROTO_TLS1
@@ -1897,11 +1944,19 @@
 /**
  * \def MBEDTLS_NET_C
  *
- * Enable the TCP/IP networking routines.
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
  *
  * Module:  library/net.c
  *
- * This module provides TCP/IP networking routines.
+ * This module provides networking routines.
  */
 #define MBEDTLS_NET_C
 
@@ -2247,7 +2302,8 @@
  * By default mbed TLS assumes it is used in a non-threaded environment or that
  * contexts are not shared between threads. If you do intend to use contexts
  * between threads, you will need to enable this layer to prevent race
- * conditions.
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
  *
  * Module:  library/threading.c
  *
@@ -2264,7 +2320,18 @@
 /**
  * \def MBEDTLS_TIMING_C
  *
- * Enable the portable timing interface.
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
  *
  * Module:  library/timing.c
  * Caller:  library/havege.c
@@ -2445,20 +2512,30 @@
 //#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
 /* Note: your snprintf must correclty zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
 
 /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
 /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
 //#define MBEDTLS_PLATFORM_CALLOC_MACRO        calloc /**< Default allocator macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
 /* Note: your snprintf must correclty zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
 /* SSL Cache options */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
@@ -2487,11 +2564,10 @@
 /* X509 options */
 //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
 
-/* \} name SECTION: Module configuration options */
+/* \} name SECTION: Customisation configuration options */
 
-#if defined(TARGET_LIKE_MBED)
-#include "mbedtls/target_config.h"
-#endif
+/* Target and application specific configurations */
+//#define YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE "target_config.h"
 
 /*
  * Allow user to override any previous default.
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index d859dd5..2957996 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -1,7 +1,7 @@
 /**
  * \file debug.h
  *
- * \brief Debug functions
+ * \brief Functions for controlling and providing debug output from the library.
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
@@ -80,39 +80,141 @@
 #endif
 
 /**
- * \brief   Set the level threshold to handle globally. Messages that have a
- *          level over the threshold value are ignored.
- *          (Default value: 0 (No debug))
+ * \brief   Set the threshold error level to handle globally all debug output.
+ *          Debug messages that have a level over the threshold value are
+ *          discarded.
+ *          (Default value: 0 = No debug )
  *
- * \param threshold     maximum level of messages to pass on
+ * \param threshold     theshold level of messages to filter on. Messages at a
+ *                      higher level will be discarded.
+ *                          - Debug levels
+ *                              - 0 No debug
+ *                              - 1 Error
+ *                              - 2 State change
+ *                              - 3 Informational
+ *                              - 4 Verbose
  */
 void mbedtls_debug_set_threshold( int threshold );
 
+/**
+ * \brief    Print a message to the debug output. This function is always used
+ *          through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
+ *          context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the message has occurred in
+ * \param line      line number the message has occurred at
+ * \param format    format specifier, in printf format
+ * \param ...       variables used by the format specifier
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
                               const char *file, int line,
                               const char *format, ... );
 
+/**
+ * \brief   Print the return value of a function to the debug output. This
+ *          function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      the name of the function that returned the error
+ * \param ret       the return code value
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
                       const char *file, int line,
                       const char *text, int ret );
 
+/**
+ * \brief   Output a buffer of size len bytes to the debug output. This function
+ *          is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the buffer being dumped. Normally the
+ *                  variable or buffer name
+ * \param buf       the buffer to be outputted
+ * \param len       length of the buffer
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
                       const char *file, int line, const char *text,
                       const unsigned char *buf, size_t len );
 
 #if defined(MBEDTLS_BIGNUM_C)
+/**
+ * \brief   Print a MPI variable to the debug output. This function is always
+ *          used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
+ *          ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the MPI being output. Normally the
+ *                  variable name
+ * \param X         the MPI variable
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
                       const char *file, int line,
                       const char *text, const mbedtls_mpi *X );
 #endif
 
 #if defined(MBEDTLS_ECP_C)
+/**
+ * \brief   Print an ECP point to the debug output. This function is always
+ *          used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
+ *          ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the ECP point being output. Normally the
+ *                  variable name
+ * \param X         the ECP point
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
                       const char *file, int line,
                       const char *text, const mbedtls_ecp_point *X );
 #endif
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief   Print a X.509 certificate structure to the debug output. This
+ *          function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the certificate being output
+ * \param crt       X.509 certificate structure
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
 void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
                       const char *file, int line,
                       const char *text, const mbedtls_x509_crt *crt );
@@ -123,3 +225,4 @@
 #endif
 
 #endif /* debug.h */
+
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index cd056d1..d7ab152 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -221,7 +221,7 @@
  * \param ctx      DHM context
  * \param x_size   private value size in bytes
  * \param output   destination buffer
- * \param olen     must be equal to ctx->P.len
+ * \param olen     must be at least equal to the size of P, ctx->len
  * \param f_rng    RNG function
  * \param p_rng    RNG parameter
  *
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 00de9a6..fed0494 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -3,7 +3,7 @@
  *
  * \brief Entropy accumulator implementation
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -134,6 +134,9 @@
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_threading_mutex_t mutex;    /*!< mutex                  */
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    int initial_entropy_run;
+#endif
 }
 mbedtls_entropy_context;
 
@@ -208,6 +211,18 @@
 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
                            const unsigned char *data, size_t len );
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Trigger an update of the seed file in NV by using the
+ *                  current entropy pool.
+ *
+ * \param ctx       Entropy context
+ *
+ * \return          0 if successful
+ */
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief               Write a seed file
diff --git a/include/mbedtls/entropy_poll.h b/include/mbedtls/entropy_poll.h
index dc11911..430e865 100644
--- a/include/mbedtls/entropy_poll.h
+++ b/include/mbedtls/entropy_poll.h
@@ -3,7 +3,7 @@
  *
  * \brief Platform-specific and custom entropy polling functions
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -43,6 +43,14 @@
 #define MBEDTLS_ENTROPY_MIN_HARDCLOCK     4     /**< Minimum for mbedtls_timing_hardclock()        */
 #define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
 
+/**
+ * \brief           Entropy poll callback that provides 0 entropy.
+ */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    int mbedtls_null_entropy_poll( void *data,
+                                unsigned char *output, size_t len, size_t *olen );
+#endif
+
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 /**
  * \brief           Platform-specific entropy poll callback
@@ -82,6 +90,16 @@
                            unsigned char *output, size_t len, size_t *olen );
 #endif
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Entropy poll callback for a non-volatile seed file
+ *
+ * \note            This must accept NULL as its first argument.
+ */
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen );
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index 661bc08..d5df316 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/include/mbedtls/memory_buffer_alloc.h
@@ -98,8 +98,10 @@
 /**
  * \brief   Get the peak heap usage so far
  *
- * \param max_used      Peak number of bytes reauested by the application
- * \param max_blocks    Peak number of blocks reauested by the application
+ * \param max_used      Peak number of bytes in use or committed. This
+ *                      includes bytes in allocated blocks too small to split
+ *                      into smaller blocks but larger than the requested size.
+ * \param max_blocks    Peak number of blocks in use, including free and used
  */
 void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks );
 
@@ -111,8 +113,10 @@
 /**
  * \brief   Get the current heap usage
  *
- * \param cur_used      Number of bytes reauested by the application
- * \param cur_blocks    Number of blocks reauested by the application
+ * \param cur_used      Current number of bytes in use or committed. This
+ *                      includes bytes in allocated blocks too small to split
+ *                      into smaller blocks but larger than the requested size.
+ * \param cur_blocks    Current number of blocks in use, including free and used
  */
 void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
 #endif /* MBEDTLS_MEMORY_DEBUG */
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 458bb51..f9f9b9b 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -496,11 +496,12 @@
  * \brief           Load and parse a public key
  *
  * \param ctx       key to be initialized
- * \param path      filename to read the private key from
+ * \param path      filename to read the public key from
  *
  * \note            On entry, ctx must be empty, either freshly initialised
- *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
- *                  specific key type, check the result with mbedtls_pk_can_do().
+ *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If
+ *                  you need a specific key type, check the result with
+ *                  mbedtls_pk_can_do().
  *
  * \note            The key is also checked for correctness.
  *
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index f71f1b6..caf8f25 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -3,7 +3,7 @@
  *
  * \brief mbed TLS Platform abstraction layer
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -44,6 +44,7 @@
 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
 #if defined(_WIN32)
 #define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< Default snprintf to use  */
@@ -64,14 +65,35 @@
 #define MBEDTLS_PLATFORM_STD_FREE       free /**< Default free to use */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT)
-#define MBEDTLS_PLATFORM_STD_EXIT      exit /**< Default free to use */
+#define MBEDTLS_PLATFORM_STD_EXIT      exit /**< Default exit to use */
 #endif
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+#define MBEDTLS_PLATFORM_STD_TIME       time    /**< Default time to use */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS /**< Default exit value to use */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< Default exit value to use */
+#endif
+#if defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE   "seedfile"
+#endif
+#endif /* MBEDTLS_FS_IO */
 #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
 #include MBEDTLS_PLATFORM_STD_MEM_HDR
 #endif
 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 
+
 /* \} name SECTION: Module settings */
 
 /*
@@ -207,6 +229,94 @@
 #endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
 
+/*
+ * The default exit values
+ */
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
+#else
+#define MBEDTLS_EXIT_SUCCESS 0
+#endif
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
+#else
+#define MBEDTLS_EXIT_FAILURE 1
+#endif
+
+/*
+ * The time_t datatype
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
+typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
+#else
+/* For time_t */
+#include <time.h>
+typedef time_t mbedtls_time_t;
+#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
+
+/*
+ * The function pointers for time
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
+
+/**
+ * \brief   Set your own time function pointer
+ *
+ * \param   time_func   the time function implementation
+ *
+ * \return              0
+ */
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
+#else
+#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
+#define mbedtls_time    MBEDTLS_PLATFORM_TIME_MACRO
+#else
+#define mbedtls_time   time
+#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+/*
+ * The function pointers for reading from and writing a seed file to
+ * Non-Volatile storage (NV) in a platform-independent way
+ *
+ * Only enabled when the NV seed entropy source is enabled
+ */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Internal standard platform definitions */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
+extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
+
+/**
+ * \brief   Set your own seed file writing/reading functions
+ *
+ * \param   nv_seed_read_func   the seed reading function implementation
+ * \param   nv_seed_write_func  the seed writing function implementation
+ *
+ * \return              0
+ */
+int mbedtls_platform_set_nv_seed(
+            int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+            int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
+            );
+#else
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
+    defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
+#define mbedtls_nv_seed_read    MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
+#define mbedtls_nv_seed_write   MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
+#else
+#define mbedtls_nv_seed_read    mbedtls_platform_std_nv_seed_read
+#define mbedtls_nv_seed_write   mbedtls_platform_std_nv_seed_write
+#endif
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index ff5f389..82c0760 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -232,7 +232,7 @@
  * Signaling ciphersuite values (SCSV)
  */
 #define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO    0xFF   /**< renegotiation info ext */
-#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE         0x5600 /**< draft-ietf-tls-downgrade-scsv-00 */
+#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE         0x5600 /**< RFC 7507 section 2 */
 
 /*
  * Supported Signature and Hash algorithms (For TLS 1.2)
@@ -411,6 +411,116 @@
 }
 mbedtls_ssl_states;
 
+/**
+ * \brief          Callback type: send data on the network.
+ *
+ * \note           That callback may be either blocking or non-blocking.
+ *
+ * \param ctx      Context for the send callback (typically a file descriptor)
+ * \param buf      Buffer holding the data to send
+ * \param len      Length of the data to send
+ *
+ * \return         The callback must return the number of bytes sent if any,
+ *                 or a non-zero error code.
+ *                 If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE
+ *                 must be returned when the operation would block.
+ *
+ * \note           The callback is allowed to send fewer bytes than requested.
+ *                 It must always return the number of bytes actually sent.
+ */
+typedef int mbedtls_ssl_send_t( void *ctx,
+                                const unsigned char *buf,
+                                size_t len );
+
+/**
+ * \brief          Callback type: receive data from the network.
+ *
+ * \note           That callback may be either blocking or non-blocking.
+ *
+ * \param ctx      Context for the receive callback (typically a file
+ *                 descriptor)
+ * \param buf      Buffer to write the received data to
+ * \param len      Length of the receive buffer
+ *
+ * \return         The callback must return the number of bytes received,
+ *                 or a non-zero error code.
+ *                 If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ
+ *                 must be returned when the operation would block.
+ *
+ * \note           The callback may receive fewer bytes than the length of the
+ *                 buffer. It must always return the number of bytes actually
+ *                 received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_t( void *ctx,
+                                unsigned char *buf,
+                                size_t len );
+
+/**
+ * \brief          Callback type: receive data from the network, with timeout
+ *
+ * \note           That callback must block until data is received, or the
+ *                 timeout delay expires, or the operation is interrupted by a
+ *                 signal.
+ *
+ * \param ctx      Context for the receive callback (typically a file descriptor)
+ * \param buf      Buffer to write the received data to
+ * \param len      Length of the receive buffer
+ * \param timeout  Maximum nomber of millisecondes to wait for data
+ *                 0 means no timeout (potentially waiting forever)
+ *
+ * \return         The callback must return the number of bytes received,
+ *                 or a non-zero error code:
+ *                 \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ *                 \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *
+ * \note           The callback may receive fewer bytes than the length of the
+ *                 buffer. It must always return the number of bytes actually
+ *                 received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_timeout_t( void *ctx,
+                                        unsigned char *buf,
+                                        size_t len,
+                                        uint32_t timeout );
+/**
+ * \brief          Callback type: set a pair of timers/delays to watch
+ *
+ * \param ctx      Context pointer
+ * \param int_ms   Intermediate delay in milliseconds
+ * \param fin_ms   Final delay in milliseconds
+ *                 0 cancels the current timer.
+ *
+ * \note           This callback must at least store the necessary information
+ *                 for the associated \c mbedtls_ssl_get_timer_t callback to
+ *                 return correct information.
+ *
+ * \note           If using a event-driven style of programming, an event must
+ *                 be generated when the final delay is passed. The event must
+ *                 cause a call to \c mbedtls_ssl_handshake() with the proper
+ *                 SSL context to be scheduled. Care must be taken to ensure
+ *                 that at most one such call happens at a time.
+ *
+ * \note           Only one timer at a time must be running. Calling this
+ *                 function while a timer is running must cancel it. Cancelled
+ *                 timers must not generate any event.
+ */
+typedef void mbedtls_ssl_set_timer_t( void * ctx,
+                                      uint32_t int_ms,
+                                      uint32_t fin_ms );
+
+/**
+ * \brief          Callback type: get status of timers/delays
+ *
+ * \param ctx      Context pointer
+ *
+ * \return         This callback must return:
+ *                 -1 if cancelled (fin_ms == 0),
+ *                  0 if none of the delays have passed,
+ *                  1 if only the intermediate delay has passed,
+ *                  2 if the final delay has passed.
+ */
+typedef int mbedtls_ssl_get_timer_t( void * ctx );
+
+
 /* Defined below */
 typedef struct mbedtls_ssl_session mbedtls_ssl_session;
 typedef struct mbedtls_ssl_context mbedtls_ssl_context;
@@ -432,7 +542,7 @@
 struct mbedtls_ssl_session
 {
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t start;               /*!< starting time      */
+    mbedtls_time_t start;       /*!< starting time      */
 #endif
     int ciphersuite;            /*!< chosen ciphersuite */
     int compression;            /*!< chosen compression */
@@ -662,12 +772,11 @@
     unsigned badmac_seen;       /*!< records with a bad MAC received    */
 #endif
 
-    /*
-     * Callbacks
-     */
-    int (*f_send)(void *, const unsigned char *, size_t);
-    int (*f_recv)(void *, unsigned char *, size_t);
-    int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t);
+    mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+    mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+    mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+                                /*!< Callback for network receive with timeout */
+
     void *p_bio;                /*!< context for I/O operations   */
 
     /*
@@ -693,8 +802,9 @@
      * Timers
      */
     void *p_timer;              /*!< context for the timer callbacks */
-    void (*f_set_timer)(void *, uint32_t, uint32_t); /*!< set timer callback */
-    int (*f_get_timer)(void *); /*!< get timer callback             */
+
+    mbedtls_ssl_set_timer_t *f_set_timer;       /*!< set timer callback */
+    mbedtls_ssl_get_timer_t *f_get_timer;       /*!< get timer callback */
 
     /*
      * Record layer (incoming data)
@@ -848,7 +958,7 @@
  * \note           No copy of the configuration context is made, it can be
  *                 shared by many mbedtls_ssl_context structures.
  *
- * \warning        Modifying the conf structure after is has been used in this
+ * \warning        Modifying the conf structure after it has been used in this
  *                 function is unsupported!
  *
  * \param ssl      SSL context
@@ -866,7 +976,7 @@
  *                 pointers and data.
  *
  * \param ssl      SSL context
- * \return         0 if successful, or POLASSL_ERR_SSL_MALLOC_FAILED,
+ * \return         0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED,
                    MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or
  *                 MBEDTLS_ERR_SSL_COMPRESSION_FAILED
  */
@@ -914,6 +1024,7 @@
  *
  *  MBEDTLS_SSL_VERIFY_REQUIRED:  peer *must* present a valid certificate,
  *                        handshake is aborted if verification failed.
+ *                        (default on client)
  *
  * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode.
  * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at
@@ -978,8 +1089,6 @@
  * \param f_send   write callback
  * \param f_recv   read callback
  * \param f_recv_timeout blocking read callback with timeout.
- *                 The last argument is the timeout in milliseconds,
- *                 0 means no timeout (block forever until a message comes)
  *
  * \note           One of f_recv or f_recv_timeout can be NULL, in which case
  *                 the other is used. If both are non-NULL, f_recv_timeout is
@@ -991,12 +1100,20 @@
  *
  * \note           For DTLS, you need to provide either a non-NULL
  *                 f_recv_timeout callback, or a f_recv that doesn't block.
+ *
+ * \note           See the documentations of \c mbedtls_ssl_sent_t,
+ *                 \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
+ *                 the conventions those callbacks must follow.
+ *
+ * \note           On some platforms, net.c provides \c mbedtls_net_send(),
+ *                 \c mbedtls_net_recv() and \c mbedtls_net_recv_timeout()
+ *                 that are suitable to be used here.
  */
 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
-        void *p_bio,
-        int (*f_send)(void *, const unsigned char *, size_t),
-        int (*f_recv)(void *, unsigned char *, size_t),
-        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) );
+                          void *p_bio,
+                          mbedtls_ssl_send_t *f_send,
+                          mbedtls_ssl_recv_t *f_recv,
+                          mbedtls_ssl_recv_timeout_t *f_recv_timeout );
 
 /**
  * \brief          Set the timeout period for mbedtls_ssl_read()
@@ -1017,37 +1134,42 @@
 void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
 
 /**
- * \brief          Set the timer callbacks
- *                 (Mandatory for DTLS.)
+ * \brief          Set the timer callbacks (Mandatory for DTLS.)
  *
  * \param ssl      SSL context
- * \param p_timer  parameter (context) shared by timer callback
+ * \param p_timer  parameter (context) shared by timer callbacks
  * \param f_set_timer   set timer callback
- *                 Accepts an intermediate and a final delay in milliseconcs
- *                 If the final delay is 0, cancels the running timer.
  * \param f_get_timer   get timer callback. Must return:
- *                 -1 if cancelled
- *                 0 if none of the delays is expired
- *                 1 if the intermediate delay only is expired
- *                 2 if the final delay is expired
+ *
+ * \note           See the documentation of \c mbedtls_ssl_set_timer_t and
+ *                 \c mbedtls_ssl_get_timer_t for the conventions this pair of
+ *                 callbacks must fallow.
+ *
+ * \note           On some platforms, timing.c provides
+ *                 \c mbedtls_timing_set_delay() and
+ *                 \c mbedtls_timing_get_delay() that are suitable for using
+ *                 here, except if using an event-driven style.
+ *
+ * \note           See also the "DTLS tutorial" article in our knowledge base.
+ *                 https://tls.mbed.org/kb/how-to/dtls-tutorial
  */
 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
                                void *p_timer,
-                               void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms),
-                               int (*f_get_timer)(void *) );
+                               mbedtls_ssl_set_timer_t *f_set_timer,
+                               mbedtls_ssl_get_timer_t *f_get_timer );
 
 /**
  * \brief           Callback type: generate and write session ticket
  *
  * \note            This describes what a callback implementation should do.
- *                  This callback should generate and encrypted and
+ *                  This callback should generate an encrypted and
  *                  authenticated ticket for the session and write it to the
  *                  output buffer. Here, ticket means the opaque ticket part
  *                  of the NewSessionTicket structure of RFC 5077.
  *
  * \param p_ticket  Context for the callback
- * \param session   SSL session to bo written in the ticket
- * \param start     Start of the outpur buffer
+ * \param session   SSL session to be written in the ticket
+ * \param start     Start of the output buffer
  * \param end       End of the output buffer
  * \param tlen      On exit, holds the length written
  * \param lifetime  On exit, holds the lifetime of the ticket in seconds
@@ -1298,7 +1420,7 @@
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 /**
- * \brief          Set retransmit timeout values for the DTLS handshale.
+ * \brief          Set retransmit timeout values for the DTLS handshake.
  *                 (DTLS only, no effect on TLS.)
  *
  * \param conf     SSL configuration
@@ -1309,9 +1431,24 @@
  *
  * \note           Default values are from RFC 6347 section 4.2.4.1.
  *
- * \note           Higher values for initial timeout may increase average
- *                 handshake latency. Lower values may increase the risk of
- *                 network congestion by causing more retransmissions.
+ * \note           The 'min' value should typically be slightly above the
+ *                 expected round-trip time to your peer, plus whatever time
+ *                 it takes for the peer to process the message. For example,
+ *                 if your RTT is about 600ms and you peer needs up to 1s to
+ *                 do the cryptographic operations in the handshake, then you
+ *                 should set 'min' slightly above 1600. Lower values of 'min'
+ *                 might cause spurious resends which waste network resources,
+ *                 while larger value of 'min' will increase overall latency
+ *                 on unreliable network links.
+ *
+ * \note           The more unreliable your network connection is, the larger
+ *                 your max / min ratio needs to be in order to achieve
+ *                 reliable handshakes.
+ *
+ * \note           Messages are retransmitted up to log2(ceil(max/min)) times.
+ *                 For example, if min = 1s and max = 5s, the retransmit plan
+ *                 goes: send ... 1s -> resend ... 2s -> resend ... 4s ->
+ *                 resend ... 5s -> give up and return a timeout error.
  */
 void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -1381,7 +1518,7 @@
 /**
  * \brief               Set the list of allowed ciphersuites and the preference
  *                      order. First in the list has the highest preference.
- *                      (Overrides all version specific lists)
+ *                      (Overrides all version-specific lists)
  *
  *                      The ciphersuites array is not copied, and must remain
  *                      valid for the lifetime of the ssl_config.
@@ -1459,7 +1596,12 @@
  *                 adequate, preference is given to the one set by the first
  *                 call to this function, then second, etc.
  *
- * \note           On client, only the first call has any effect.
+ * \note           On client, only the first call has any effect. That is,
+ *                 only one client certificate can be provisioned. The
+ *                 server's preferences in its CertficateRequest message will
+ *                 be ignored and our only cert will be sent regardless of
+ *                 whether it matches those preferences - the server can then
+ *                 decide what it wants to do with it.
  *
  * \param conf     SSL configuration
  * \param own_cert own public certificate chain
@@ -1479,6 +1621,12 @@
  * \note           This is mainly useful for clients. Servers will usually
  *                 want to use \c mbedtls_ssl_conf_psk_cb() instead.
  *
+ * \note           Currently clients can only register one pre-shared key.
+ *                 In other words, the servers' identity hint is ignored.
+ *                 Support for setting multiple PSKs on clients and selecting
+ *                 one based on the identity hint is not a planned feature but
+ *                 feedback is welcomed.
+ *
  * \param conf     SSL configuration
  * \param psk      pointer to the pre-shared key
  * \param psk_len  pre-shared key length
@@ -1633,10 +1781,11 @@
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
- * \brief          Set hostname for ServerName TLS extension
+ * \brief          Set the hostname to check against the received server
+ *                 certificate. It sets the ServerName TLS extension too,
+ *                 if the extension is enabled.
  *                 (client-side only)
  *
- *
  * \param ssl      SSL context
  * \param hostname the server hostname
  *
@@ -1747,8 +1896,11 @@
  * \brief          Set the supported Application Layer Protocols.
  *
  * \param conf     SSL configuration
- * \param protos   NULL-terminated list of supported protocols,
- *                 in decreasing preference order.
+ * \param protos   Pointer to a NULL-terminated list of supported protocols,
+ *                 in decreasing preference order. The pointer to the list is
+ *                 recorded by the library for later reference as required, so
+ *                 the lifetime of the table must be atleast as long as the
+ *                 lifetime of the SSL configuration structure.
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
@@ -1862,11 +2014,13 @@
  * \brief          Disable or enable support for RC4
  *                 (Default: MBEDTLS_SSL_ARC4_DISABLED)
  *
- * \warning        Use of RC4 in (D)TLS has been prohibited by RFC ????
- *                 for security reasons. Use at your own risks.
+ * \warning        Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
+ *                 for security reasons. Use at your own risk.
  *
- * \note           This function will likely be removed in future versions as
- *                 RC4 will then be disabled by default at compile time.
+ * \note           This function is deprecated and will likely be removed in
+ *                 a future version of the library.
+ *                 RC4 is disabled by default at compile time and needs to be
+ *                 actively enabled for use with legacy systems.
  *
  * \param conf     SSL configuration
  * \param arc4     MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED
@@ -1942,7 +2096,7 @@
  *
  * \warning        It is recommended to always disable renegotation unless you
  *                 know you need it and you know what you're doing. In the
- *                 past, there has been several issues associated with
+ *                 past, there have been several issues associated with
  *                 renegotiation or a poor understanding of its properties.
  *
  * \note           Server-side, enabling renegotiation also makes the server
@@ -2182,8 +2336,8 @@
  * \brief          Perform a single step of the SSL handshake
  *
  * \note           The state of the context (ssl->state) will be at
- *                 the following state after execution of this function.
- *                 Do not call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
+ *                 the next state after execution of this function. Do not
+ *                 call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
  *
  * \note           If this function returns something other than 0 or
  *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
@@ -2204,11 +2358,13 @@
  * \brief          Initiate an SSL renegotiation on the running connection.
  *                 Client: perform the renegotiation right now.
  *                 Server: request renegotiation, which will be performed
- *                 during the next call to mbedtls_ssl_read() if honored by client.
+ *                 during the next call to mbedtls_ssl_read() if honored by
+ *                 client.
  *
  * \param ssl      SSL context
  *
- * \return         0 if successful, or any mbedtls_ssl_handshake() return value.
+ * \return         0 if successful, or any mbedtls_ssl_handshake() return
+ *                 value.
  *
  * \note           If this function returns something other than 0 or
  *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h
index 1155924..3734bb7 100644
--- a/include/mbedtls/ssl_cache.h
+++ b/include/mbedtls/ssl_cache.h
@@ -60,7 +60,7 @@
 struct mbedtls_ssl_cache_entry
 {
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t timestamp;           /*!< entry timestamp    */
+    mbedtls_time_t timestamp;           /*!< entry timestamp    */
 #endif
     mbedtls_ssl_session session;        /*!< entry session      */
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 3af059f..d63d7d4 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -166,7 +166,6 @@
      * Handshake specific crypto variables
      */
     int sig_alg;                        /*!<  Hash algorithm for signature   */
-    int cert_type;                      /*!<  Requested cert type            */
     int verify_sig_alg;                 /*!<  Signature algorithm for verify */
 #if defined(MBEDTLS_DHM_C)
     mbedtls_dhm_context dhm_ctx;                /*!<  DHM key exchange        */
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index c39cbf2..b0c34ec 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -81,6 +81,7 @@
 void mbedtls_threading_free_alt( void );
 #endif /* MBEDTLS_THREADING_ALT */
 
+#if defined(MBEDTLS_THREADING_C)
 /*
  * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock
  *
@@ -96,6 +97,7 @@
  */
 extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
 extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
+#endif /* MBEDTLS_THREADING_C */
 
 #ifdef __cplusplus
 }
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index ea2966e..b40aa51 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -38,17 +38,17 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  2
-#define MBEDTLS_VERSION_PATCH  1
+#define MBEDTLS_VERSION_MINOR  3
+#define MBEDTLS_VERSION_PATCH  0
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02020100
-#define MBEDTLS_VERSION_STRING         "2.2.1"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.2.1"
+#define MBEDTLS_VERSION_NUMBER         0x02030000
+#define MBEDTLS_VERSION_STRING         "2.3.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.3.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index fe821d1..41b6bfe 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -271,9 +271,14 @@
  * \note           Same as \c mbedtls_x509_crt_verify_with_profile() with the
  *                 default security profile.
  *
- * \param crt      a certificate to be verified
- * \param trust_ca the trusted CA chain
- * \param ca_crl   the CRL chain for trusted CA's
+ * \note           It is your responsibility to provide up-to-date CRLs for
+ *                 all trusted CAs. If no CRL is provided for the CA that was
+ *                 used to sign the certificate, CRL verification is skipped
+ *                 silently, that is *without* setting any flag.
+ *
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs
+ * \param ca_crl   the list of CRLs for trusted CAs (see note above)
  * \param cn       expected Common Name (can be set to
  *                 NULL if the CN must not be verified)
  * \param flags    result of the verification
@@ -304,9 +309,9 @@
  *                 for ECDSA) apply to all certificates: trusted root,
  *                 intermediate CAs if any, and end entity certificate.
  *
- * \param crt      a certificate to be verified
- * \param trust_ca the trusted CA chain
- * \param ca_crl   the CRL chain for trusted CA's
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs
+ * \param ca_crl   the list of CRLs for trusted CAs
  * \param profile  security profile for verification
  * \param cn       expected Common Name (can be set to
  *                 NULL if the CN must not be verified)
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 34998a3..7a9c2e0 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -83,6 +83,8 @@
 /**
  * \brief          Load a Certificate Signing Request (CSR) in DER format
  *
+ * \note           CSR attributes (if any) are currently silently ignored.
+ *
  * \param csr      CSR context to fill
  * \param buf      buffer holding the CRL data
  * \param buflen   size of the buffer
@@ -95,6 +97,8 @@
 /**
  * \brief          Load a Certificate Signing Request (CSR), DER or PEM format
  *
+ * \note           See notes for \c mbedtls_x509_csr_parse_der()
+ *
  * \param csr      CSR context to fill
  * \param buf      buffer holding the CRL data
  * \param buflen   size of the buffer
@@ -108,6 +112,8 @@
 /**
  * \brief          Load a Certificate Signing Request (CSR)
  *
+ * \note           See notes for \c mbedtls_x509_csr_parse()
+ *
  * \param csr      CSR context to fill
  * \param path     filename to read the CSR from
  *
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 71d5485..6aeb385 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -139,15 +139,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.2.1 SOVERSION 0)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.3.0 SOVERSION 0)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.2.1 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.3.0 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.2.1 SOVERSION 10)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.3.0 SOVERSION 10)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/Makefile b/library/Makefile
index 7d25343..00528b3 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -90,9 +90,9 @@
 # tls
 libmbedtls.a: $(OBJS_TLS)
 	echo "  AR    $@"
-	$(AR) rc $@ $(OBJS_TLS)
+	$(AR) -rc $@ $(OBJS_TLS)
 	echo "  RL    $@"
-	$(AR) s $@
+	$(AR) -s $@
 
 libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so
 	echo "  LD    $@"
@@ -113,9 +113,9 @@
 # x509
 libmbedx509.a: $(OBJS_X509)
 	echo "  AR    $@"
-	$(AR) rc $@ $(OBJS_X509)
+	$(AR) -rc $@ $(OBJS_X509)
 	echo "  RL    $@"
-	$(AR) s $@
+	$(AR) -s $@
 
 libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
 	echo "  LD    $@"
@@ -136,9 +136,9 @@
 # crypto
 libmbedcrypto.a: $(OBJS_CRYPTO)
 	echo "  AR    $@"
-	$(AR) rc $@ $(OBJS_CRYPTO)
+	$(AR) -rc $@ $(OBJS_CRYPTO)
 	echo "  RL    $@"
-	$(AR) s $@
+	$(AR) -s $@
 
 libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO)
 	echo "  LD    $@"
diff --git a/library/aes.c b/library/aes.c
index ec9313d..a186dee 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -56,7 +56,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
@@ -1222,7 +1222,9 @@
     int ret = 0, i, j, u, v;
     unsigned char key[32];
     unsigned char buf[64];
+#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
     unsigned char iv[16];
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     unsigned char prv[16];
 #endif
diff --git a/library/aesni.c b/library/aesni.c
index 83a5868..1ca3c3e 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -100,7 +100,7 @@
     asm( "movdqu    (%3), %%xmm0    \n\t" // load input
          "movdqu    (%1), %%xmm1    \n\t" // load round key 0
          "pxor      %%xmm1, %%xmm0  \n\t" // round 0
-         "addq      $16, %1         \n\t" // point to next round key
+         "add       $16, %1         \n\t" // point to next round key
          "subl      $1, %0          \n\t" // normal rounds = nr - 1
          "test      %2, %2          \n\t" // mode?
          "jz        2f              \n\t" // 0 = decrypt
@@ -108,7 +108,7 @@
          "1:                        \n\t" // encryption loop
          "movdqu    (%1), %%xmm1    \n\t" // load round key
          AESENC     xmm1_xmm0      "\n\t" // do round
-         "addq      $16, %1         \n\t" // point to next round key
+         "add       $16, %1         \n\t" // point to next round key
          "subl      $1, %0          \n\t" // loop
          "jnz       1b              \n\t"
          "movdqu    (%1), %%xmm1    \n\t" // load round key
@@ -118,7 +118,7 @@
          "2:                        \n\t" // decryption loop
          "movdqu    (%1), %%xmm1    \n\t"
          AESDEC     xmm1_xmm0      "\n\t" // do round
-         "addq      $16, %1         \n\t"
+         "add       $16, %1         \n\t"
          "subl      $1, %0          \n\t"
          "jnz       2b              \n\t"
          "movdqu    (%1), %%xmm1    \n\t" // load round key
diff --git a/library/arc4.c b/library/arc4.c
index ff0e993..05b33d3 100644
--- a/library/arc4.c
+++ b/library/arc4.c
@@ -49,7 +49,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
diff --git a/library/asn1parse.c b/library/asn1parse.c
index b37523d..ffa2f52 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -45,7 +45,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
@@ -269,7 +269,8 @@
         /* Allocate and assign next pointer */
         if( *p < end )
         {
-            cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+            cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
+                                            sizeof( mbedtls_asn1_sequence ) );
 
             if( cur->next == NULL )
                 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
diff --git a/library/asn1write.c b/library/asn1write.c
index 00ed73c..027c858 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -312,7 +312,9 @@
     {
         // Add new entry if not present yet based on OID
         //
-        if( ( cur = mbedtls_calloc( 1, sizeof(mbedtls_asn1_named_data) ) ) == NULL )
+        cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1,
+                                            sizeof(mbedtls_asn1_named_data) );
+        if( cur == NULL )
             return( NULL );
 
         cur->oid.len = oid_len;
diff --git a/library/base64.c b/library/base64.c
index 3432e5f..5cb12cb 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -97,7 +97,7 @@
 
     n *= 4;
 
-    if( dlen < n + 1 )
+    if( ( dlen < n + 1 ) || ( NULL == dst ) )
     {
         *olen = n + 1;
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
diff --git a/library/bignum.c b/library/bignum.c
index 0e587f1..4c99e04 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -59,8 +59,8 @@
 #endif
 
 /* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
+    volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
 }
 
 #define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
@@ -99,7 +99,7 @@
 
     if( X->p != NULL )
     {
-        mbedtls_zeroize( X->p, X->n * ciL );
+        mbedtls_mpi_zeroize( X->p, X->n );
         mbedtls_free( X->p );
     }
 
@@ -120,13 +120,13 @@
 
     if( X->n < nblimbs )
     {
-        if( ( p = mbedtls_calloc( nblimbs, ciL ) ) == NULL )
+        if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
             return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
 
         if( X->p != NULL )
         {
             memcpy( p, X->p, X->n * ciL );
-            mbedtls_zeroize( X->p, X->n * ciL );
+            mbedtls_mpi_zeroize( X->p, X->n );
             mbedtls_free( X->p );
         }
 
@@ -158,13 +158,13 @@
     if( i < nblimbs )
         i = nblimbs;
 
-    if( ( p = mbedtls_calloc( i, ciL ) ) == NULL )
+    if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
 
     if( X->p != NULL )
     {
         memcpy( p, X->p, i * ciL );
-        mbedtls_zeroize( X->p, X->n * ciL );
+        mbedtls_mpi_zeroize( X->p, X->n );
         mbedtls_free( X->p );
     }
 
@@ -883,7 +883,7 @@
 {
     int ret;
     size_t i, j;
-    mbedtls_mpi_uint *o, *p, c;
+    mbedtls_mpi_uint *o, *p, c, tmp;
 
     if( X == B )
     {
@@ -906,10 +906,14 @@
 
     o = B->p; p = X->p; c = 0;
 
+    /*
+     * tmp is used because it might happen that p == o
+     */
     for( i = 0; i < j; i++, o++, p++ )
     {
+        tmp= *o;
         *p +=  c; c  = ( *p <  c );
-        *p += *o; c += ( *p < *o );
+        *p += tmp; c += ( *p < tmp );
     }
 
     while( c != 0 )
@@ -1538,12 +1542,15 @@
 /*
  * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
  */
-static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
+static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
                          const mbedtls_mpi *T )
 {
     size_t i, n, m;
     mbedtls_mpi_uint u0, u1, *d;
 
+    if( T->n < N->n + 1 || T->p == NULL )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
     memset( T->p, 0, T->n * ciL );
 
     d = T->p;
@@ -1571,12 +1578,14 @@
     else
         /* prevent timing attacks */
         mpi_sub_hlp( n, A->p, T->p );
+
+    return( 0 );
 }
 
 /*
  * Montgomery reduction: A = A * R^-1 mod N
  */
-static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
 {
     mbedtls_mpi_uint z = 1;
     mbedtls_mpi U;
@@ -1584,7 +1593,7 @@
     U.n = U.s = (int) z;
     U.p = &z;
 
-    mpi_montmul( A, &U, N, mm, T );
+    return( mpi_montmul( A, &U, N, mm, T ) );
 }
 
 /*
@@ -1661,13 +1670,13 @@
     else
         MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
 
-    mpi_montmul( &W[1], &RR, N, mm, &T );
+    MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) );
 
     /*
      * X = R^2 * R^-1 mod N = R mod N
      */
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
-    mpi_montred( X, N, mm, &T );
+    MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
 
     if( wsize > 1 )
     {
@@ -1680,7 +1689,7 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1]    ) );
 
         for( i = 0; i < wsize - 1; i++ )
-            mpi_montmul( &W[j], &W[j], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) );
 
         /*
          * W[i] = W[i - 1] * W[1]
@@ -1690,7 +1699,7 @@
             MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
 
-            mpi_montmul( &W[i], &W[1], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) );
         }
     }
 
@@ -1727,7 +1736,7 @@
             /*
              * out of window, square X
              */
-            mpi_montmul( X, X, N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
             continue;
         }
 
@@ -1745,12 +1754,12 @@
              * X = X^wsize R^-1 mod N
              */
             for( i = 0; i < wsize; i++ )
-                mpi_montmul( X, X, N, mm, &T );
+                MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
 
             /*
              * X = X * W[wbits] R^-1 mod N
              */
-            mpi_montmul( X, &W[wbits], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) );
 
             state--;
             nbits = 0;
@@ -1763,18 +1772,18 @@
      */
     for( i = 0; i < nbits; i++ )
     {
-        mpi_montmul( X, X, N, mm, &T );
+        MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
 
         wbits <<= 1;
 
         if( ( wbits & ( one << wsize ) ) != 0 )
-            mpi_montmul( X, &W[1], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) );
     }
 
     /*
      * X = A^E * R * R^-1 mod N = A^E mod N
      */
-    mpi_montred( X, N, mm, &T );
+    MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
 
     if( neg )
     {
diff --git a/library/blowfish.c b/library/blowfish.c
index 89be4d1..9003f0d 100644
--- a/library/blowfish.c
+++ b/library/blowfish.c
@@ -41,7 +41,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
diff --git a/library/camellia.c b/library/camellia.c
index e015ca2..ac6f96a 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -50,7 +50,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
@@ -963,38 +963,38 @@
             mbedtls_printf( "  CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
                              ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
 
-    memcpy( src, camellia_test_cbc_iv, 16 );
-    memcpy( dst, camellia_test_cbc_iv, 16 );
-    memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
-
-    if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
-        mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
-    } else {
-        mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
-    }
-
-    for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
+        memcpy( src, camellia_test_cbc_iv, 16 );
+        memcpy( dst, camellia_test_cbc_iv, 16 );
+        memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
 
         if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
-            memcpy( iv , src, 16 );
-            memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
-            memcpy( dst, camellia_test_cbc_plain[i], 16 );
-        } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
-            memcpy( iv , dst, 16 );
-            memcpy( src, camellia_test_cbc_plain[i], 16 );
-            memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
+            mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
+        } else {
+            mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
         }
 
-        mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
+        for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
 
-        if( memcmp( buf, dst, 16 ) != 0 )
-        {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
+            if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
+                memcpy( iv , src, 16 );
+                memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
+                memcpy( dst, camellia_test_cbc_plain[i], 16 );
+            } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
+                memcpy( iv , dst, 16 );
+                memcpy( src, camellia_test_cbc_plain[i], 16 );
+                memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
+            }
 
-            return( 1 );
+            mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
+
+            if( memcmp( buf, dst, 16 ) != 0 )
+            {
+                if( verbose != 0 )
+                    mbedtls_printf( "failed\n" );
+
+                return( 1 );
+            }
         }
-    }
 
         if( verbose != 0 )
             mbedtls_printf( "passed\n" );
diff --git a/library/ccm.c b/library/ccm.c
index 3463a0b..13a8fd1 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -51,7 +51,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 #define CCM_ENCRYPT 0
diff --git a/library/cipher.c b/library/cipher.c
index ccc0685..bbe40eb 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -51,7 +51,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 static int supported_init = 0;
@@ -252,6 +252,7 @@
                    size_t ilen, unsigned char *output, size_t *olen )
 {
     int ret;
+    size_t block_size = 0;
 
     if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
     {
@@ -259,10 +260,11 @@
     }
 
     *olen = 0;
+    block_size = mbedtls_cipher_get_block_size( ctx );
 
     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
     {
-        if( ilen != mbedtls_cipher_get_block_size( ctx ) )
+        if( ilen != block_size )
             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
 
         *olen = ilen;
@@ -285,8 +287,13 @@
     }
 #endif
 
+    if ( 0 == block_size )
+    {
+        return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+    }
+
     if( input == output &&
-       ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) )
+       ( ctx->unprocessed_len != 0 || ilen % block_size ) )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
@@ -300,9 +307,9 @@
          * If there is not enough data for a full block, cache it.
          */
         if( ( ctx->operation == MBEDTLS_DECRYPT &&
-                ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) ||
+                ilen + ctx->unprocessed_len <= block_size ) ||
              ( ctx->operation == MBEDTLS_ENCRYPT &&
-                ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) )
+                ilen + ctx->unprocessed_len < block_size ) )
         {
             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                     ilen );
@@ -314,22 +321,22 @@
         /*
          * Process cached data first
          */
-        if( ctx->unprocessed_len != 0 )
+        if( 0 != ctx->unprocessed_len )
         {
-            copy_len = mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len;
+            copy_len = block_size - ctx->unprocessed_len;
 
             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                     copy_len );
 
             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
-                    ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
+                    ctx->operation, block_size, ctx->iv,
                     ctx->unprocessed_data, output ) ) )
             {
                 return( ret );
             }
 
-            *olen += mbedtls_cipher_get_block_size( ctx );
-            output += mbedtls_cipher_get_block_size( ctx );
+            *olen += block_size;
+            output += block_size;
             ctx->unprocessed_len = 0;
 
             input += copy_len;
@@ -341,9 +348,14 @@
          */
         if( 0 != ilen )
         {
-            copy_len = ilen % mbedtls_cipher_get_block_size( ctx );
+            if( 0 == block_size )
+            {
+                return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+            }
+
+            copy_len = ilen % block_size;
             if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
-                copy_len = mbedtls_cipher_get_block_size( ctx );
+                copy_len = block_size;
 
             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
                     copy_len );
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index aefddfa..386f8ad 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -67,8 +67,8 @@
 }
 
 /*
- * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
- * tests to succeed (which require known length fixed entropy)
+ * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
+ * NIST tests to succeed (which require known length fixed entropy)
  */
 int mbedtls_ctr_drbg_seed_entropy_len(
                    mbedtls_ctr_drbg_context *ctx,
diff --git a/library/debug.c b/library/debug.c
index 4752ab1..a9cd814 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -27,21 +27,22 @@
 
 #if defined(MBEDTLS_DEBUG_C)
 
-#include "mbedtls/debug.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdlib.h>
 #define mbedtls_calloc      calloc
 #define mbedtls_free        free
+#define mbedtls_time_t      time_t
 #define mbedtls_snprintf    snprintf
 #endif
 
+#include "mbedtls/debug.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -85,7 +86,7 @@
     char str[DEBUG_BUF_SIZE];
     int ret;
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+    if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold )
         return;
 
     va_start( argp, format );
diff --git a/library/des.c b/library/des.c
index 61f214a..09f95cfc 100644
--- a/library/des.c
+++ b/library/des.c
@@ -50,7 +50,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
diff --git a/library/dhm.c b/library/dhm.c
index 0f4d316..a4715d1 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -19,9 +19,12 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 /*
- *  Reference:
+ *  The following sources were referenced in the design of this implementation
+ *  of the Diffie-Hellman-Merkle algorithm:
  *
- *  http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
+ *  [1] Handbook of Applied Cryptography - 1997, Chapter 12
+ *      Menezes, van Oorschot and Vanstone
+ *
  */
 
 #if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/library/ecp.c b/library/ecp.c
index 19bb488..f51f225 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1827,7 +1827,9 @@
         /* [M225] page 5 */
         size_t b;
 
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+        do {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+        } while( mbedtls_mpi_bitlen( d ) == 0);
 
         /* Make sure the most significant bit is nbits */
         b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
diff --git a/library/entropy.c b/library/entropy.c
index cdbd35c..45c894b 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -1,7 +1,7 @@
 /*
  *  Entropy accumulator implementation
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -27,6 +27,12 @@
 
 #if defined(MBEDTLS_ENTROPY_C)
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+#warning "**** WARNING!  MBEDTLS_TEST_NULL_ENTROPY defined! "
+#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
+#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
+#endif
+
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
@@ -73,6 +79,11 @@
     mbedtls_havege_init( &ctx->havege_data );
 #endif
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
+                                1, MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+
 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
     mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
@@ -94,6 +105,11 @@
                                 MBEDTLS_ENTROPY_MIN_HARDWARE,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG );
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
+                                MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
 }
 
@@ -272,6 +288,18 @@
     if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    /* Update the NV entropy seed before generating any entropy for outside
+     * use.
+     */
+    if( ctx->initial_entropy_run == 0 )
+    {
+        ctx->initial_entropy_run = 1;
+        if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
+            return( ret );
+    }
+#endif
+
 #if defined(MBEDTLS_THREADING_C)
     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
         return( ret );
@@ -346,6 +374,27 @@
     return( ret );
 }
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
+{
+    int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
+
+    /* Read new seed  and write it to NV */
+    if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        return( ret );
+
+    if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+
+    /* Manually update the remaining stream with a separator value to diverge */
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #if defined(MBEDTLS_FS_IO)
 int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
 {
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 25a27be..a116e60 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -1,7 +1,7 @@
 /*
  *  Platform-specific and custom entropy polling functions
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -37,8 +37,17 @@
 #if defined(MBEDTLS_HAVEGE_C)
 #include "mbedtls/havege.h"
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#include "mbedtls/platform.h"
+#endif
 
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32)
+#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
+#endif
+
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 #if !defined(_WIN32_WINNT)
@@ -61,7 +70,10 @@
     }
 
     if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
+    {
+        CryptReleaseContext( provider, 0 );
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    }
 
     CryptReleaseContext( provider, 0 );
     *olen = len;
@@ -179,6 +191,23 @@
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+int mbedtls_null_entropy_poll( void *data,
+                    unsigned char *output, size_t len, size_t *olen )
+{
+    ((void) data);
+    ((void) output);
+    *olen = 0;
+
+    if( len < sizeof(unsigned char) )
+        return( 0 );
+
+    *olen = sizeof(unsigned char);
+
+    return( 0 );
+}
+#endif
+
 #if defined(MBEDTLS_TIMING_C)
 int mbedtls_hardclock_poll( void *data,
                     unsigned char *output, size_t len, size_t *olen )
@@ -213,4 +242,27 @@
 }
 #endif /* MBEDTLS_HAVEGE_C */
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen )
+{
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    ((void) data);
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+      return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+    if( len < use_len )
+      use_len = len;
+
+    memcpy( output, buf, use_len );
+    *olen = use_len;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #endif /* MBEDTLS_ENTROPY_C */
diff --git a/library/error.c b/library/error.c
index debda1d..4bd15bf 100644
--- a/library/error.c
+++ b/library/error.c
@@ -34,6 +34,7 @@
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
+#define mbedtls_time_t   time_t
 #endif
 
 #if defined(MBEDTLS_ERROR_C)
@@ -182,6 +183,8 @@
             mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
             mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" );
 #endif /* MBEDTLS_CIPHER_C */
 
 #if defined(MBEDTLS_DHM_C)
diff --git a/library/havege.c b/library/havege.c
index 7623bc0..2b75ef7 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -174,6 +174,8 @@
     PTX  = U1 = 0;
     PTY  = U2 = 0;
 
+    (void)PTX;
+
     memset( RES, 0, sizeof( RES ) );
 
     while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index b2c775a..545d5a2 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -417,6 +417,12 @@
     heap.total_used -= hdr->size;
 #endif
 
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    free( hdr->trace );
+    hdr->trace = NULL;
+    hdr->trace_count = 0;
+#endif
+
     // Regroup with block before
     //
     if( hdr->prev != NULL && hdr->prev->alloc == 0 )
@@ -432,9 +438,6 @@
         if( hdr->next != NULL )
             hdr->next->prev = hdr;
 
-#if defined(MBEDTLS_MEMORY_BACKTRACE)
-        free( old->trace );
-#endif
         memset( old, 0, sizeof(memory_header) );
     }
 
@@ -474,9 +477,6 @@
         if( hdr->next != NULL )
             hdr->next->prev = hdr;
 
-#if defined(MBEDTLS_MEMORY_BACKTRACE)
-        free( old->trace );
-#endif
         memset( old, 0, sizeof(memory_header) );
     }
 
@@ -491,11 +491,6 @@
         heap.first_free = hdr;
     }
 
-#if defined(MBEDTLS_MEMORY_BACKTRACE)
-    hdr->trace = NULL;
-    hdr->trace_count = 0;
-#endif
-
     if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
         mbedtls_exit( 1 );
 }
diff --git a/library/net.c b/library/net.c
index a77268c..4142bc0 100644
--- a/library/net.c
+++ b/library/net.c
@@ -27,6 +27,18 @@
 
 #if defined(MBEDTLS_NET_C)
 
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32)
+#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_time_t    time_t
+#endif
+
 #include "mbedtls/net.h"
 
 #include <string.h>
@@ -81,7 +93,6 @@
 #define MSVC_INT_CAST
 #endif
 
-#include <stdlib.h>
 #include <stdio.h>
 
 #include <time.h>
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 7023b9d..c603a13 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -93,7 +93,7 @@
                                      unsigned char *key, size_t keylen,
                                      unsigned char *iv,  size_t ivlen )
 {
-    int ret, iterations;
+    int ret, iterations = 0;
     mbedtls_asn1_buf salt;
     size_t i;
     unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
diff --git a/library/platform.c b/library/platform.c
index d634c62..68ca45d 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -1,7 +1,7 @@
 /*
  *  Platform abstraction layer
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -190,4 +190,114 @@
 }
 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
 
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer )
+{
+    ((void) timer);
+    return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_TIME   platform_time_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_TIME */
+
+mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME;
+
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) )
+{
+    mbedtls_time = time_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Default implementations for the platform independent seed functions use
+ * standard libc file functions to read from and write to a pre-defined filename
+ */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+        return -1;
+
+    if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        return -1;
+    }
+
+    fclose( file );
+    return( n );
+}
+
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+        return -1;
+
+    if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        return -1;
+    }
+
+    fclose( file );
+    return( n );
+}
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   platform_nv_seed_read_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
+
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE   platform_nv_seed_write_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
+
+int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_READ;
+int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
+
+int mbedtls_platform_set_nv_seed(
+        int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+        int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) )
+{
+    mbedtls_nv_seed_read = nv_seed_read_func;
+    mbedtls_nv_seed_write = nv_seed_write_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #endif /* MBEDTLS_PLATFORM_C */
diff --git a/library/rsa.c b/library/rsa.c
index efdd055..7a33689 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -19,10 +19,16 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 /*
- *  RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *  The following sources were referenced in the design of this implementation
+ *  of the RSA algorithm:
  *
- *  http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
- *  http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ *  [1] A method for obtaining digital signatures and public-key cryptosystems
+ *      R Rivest, A Shamir, and L Adleman
+ *      http://people.csail.mit.edu/rivest/pubs.html#RSA78
+ *
+ *  [2] Handbook of Applied Cryptography - 1997, Chapter 8
+ *      Menezes, van Oorschot and Vanstone
+ *
  */
 
 #if !defined(MBEDTLS_CONFIG_FILE)
@@ -96,7 +102,8 @@
     if( f_rng == NULL || nbits < 128 || exponent < 3 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-    mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
+    mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); 
+    mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
 
     /*
      * find primes P and Q with Q < P so that:
@@ -106,14 +113,19 @@
 
     do
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
                                 f_rng, p_rng ) );
 
-        MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
+        if( nbits % 2 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, ( nbits >> 1 ) + 1, 0,
                                 f_rng, p_rng ) );
-
-        if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
-            mbedtls_mpi_swap( &ctx->P, &ctx->Q );
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
+                                f_rng, p_rng ) );
+        }
 
         if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
             continue;
@@ -465,8 +477,7 @@
 
     hlen = mbedtls_md_get_size( md_ctx->md_info );
 
-    // Generate and apply dbMask
-    //
+    /* Generate and apply dbMask */
     p = dst;
 
     while( dlen > 0 )
@@ -523,22 +534,21 @@
     olen = ctx->len;
     hlen = mbedtls_md_get_size( md_info );
 
-    if( olen < ilen + 2 * hlen + 2 )
+    /* first comparison checks for overflow */
+    if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     memset( output, 0, olen );
 
     *p++ = 0;
 
-    // Generate a random octet string seed
-    //
+    /* Generate a random octet string seed */
     if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
         return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
 
     p += hlen;
 
-    // Construct DB
-    //
+    /* Construct DB */
     mbedtls_md( md_info, label, label_len, p );
     p += hlen;
     p += olen - 2 * hlen - 2 - ilen;
@@ -546,15 +556,17 @@
     memcpy( p, input, ilen );
 
     mbedtls_md_init( &md_ctx );
-    mbedtls_md_setup( &md_ctx, md_info, 0 );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        return( ret );
+    }
 
-    // maskedDB: Apply dbMask to DB
-    //
+    /* maskedDB: Apply dbMask to DB */
     mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
                &md_ctx );
 
-    // maskedSeed: Apply seedMask to seed
-    //
+    /* maskedSeed: Apply seedMask to seed */
     mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
                &md_ctx );
 
@@ -584,12 +596,14 @@
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-    if( f_rng == NULL )
+    // We don't check p_rng because it won't be dereferenced here
+    if( f_rng == NULL || input == NULL || output == NULL )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     olen = ctx->len;
 
-    if( olen < ilen + 11 )
+    /* first comparison checks for overflow */
+    if( ilen + 11 < ilen || olen < ilen + 11 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     nb_pad = olen - 3 - ilen;
@@ -607,8 +621,7 @@
                 ret = f_rng( p_rng, p, 1 );
             } while( *p == 0 && --rng_dl && ret == 0 );
 
-            // Check if RNG failed to generate data
-            //
+            /* Check if RNG failed to generate data */
             if( rng_dl == 0 || ret != 0 )
                 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
 
@@ -699,6 +712,12 @@
     if( md_info == NULL )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
+    hlen = mbedtls_md_get_size( md_info );
+
+    // checking for integer underflow
+    if( 2 * hlen + 2 > ilen )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
     /*
      * RSA operation
      */
@@ -712,10 +731,13 @@
     /*
      * Unmask data and generate lHash
      */
-    hlen = mbedtls_md_get_size( md_info );
-
     mbedtls_md_init( &md_ctx );
-    mbedtls_md_setup( &md_ctx, md_info, 0 );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        return( ret );
+    }
+
 
     /* Generate lHash */
     mbedtls_md( md_info, label, label_len, lhash );
@@ -848,6 +870,8 @@
         bad |= *p++; /* Must be zero */
     }
 
+    bad |= ( pad_count < 8 );
+
     if( bad )
         return( MBEDTLS_ERR_RSA_INVALID_PADDING );
 
@@ -924,8 +948,7 @@
 
     if( md_alg != MBEDTLS_MD_NONE )
     {
-        // Gather length of hash to sign
-        //
+        /* Gather length of hash to sign */
         md_info = mbedtls_md_info_from_type( md_alg );
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -945,13 +968,11 @@
 
     memset( sig, 0, olen );
 
-    // Generate salt of length slen
-    //
+    /* Generate salt of length slen */
     if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
         return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
 
-    // Note: EMSA-PSS encoding is over the length of N - 1 bits
-    //
+    /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
     msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
     p += olen - hlen * 2 - 2;
     *p++ = 0x01;
@@ -959,23 +980,24 @@
     p += slen;
 
     mbedtls_md_init( &md_ctx );
-    mbedtls_md_setup( &md_ctx, md_info, 0 );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        return( ret );
+    }
 
-    // Generate H = Hash( M' )
-    //
+    /* Generate H = Hash( M' ) */
     mbedtls_md_starts( &md_ctx );
     mbedtls_md_update( &md_ctx, p, 8 );
     mbedtls_md_update( &md_ctx, hash, hashlen );
     mbedtls_md_update( &md_ctx, salt, slen );
     mbedtls_md_finish( &md_ctx, p );
 
-    // Compensate for boundary condition when applying mask
-    //
+    /* Compensate for boundary condition when applying mask */
     if( msb % 8 == 0 )
         offset = 1;
 
-    // maskedDB: Apply dbMask to DB
-    //
+    /* maskedDB: Apply dbMask to DB */
     mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
 
     mbedtls_md_free( &md_ctx );
@@ -1169,13 +1191,13 @@
     int ret;
     size_t siglen;
     unsigned char *p;
-    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
     unsigned char result[MBEDTLS_MD_MAX_SIZE];
     unsigned char zeros[8];
     unsigned int hlen;
     size_t slen, msb;
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
 
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1199,8 +1221,7 @@
 
     if( md_alg != MBEDTLS_MD_NONE )
     {
-        // Gather length of hash to sign
-        //
+        /* Gather length of hash to sign */
         md_info = mbedtls_md_info_from_type( md_alg );
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1217,12 +1238,12 @@
 
     memset( zeros, 0, 8 );
 
-    // Note: EMSA-PSS verification is over the length of N - 1 bits
-    //
+    /*
+     * Note: EMSA-PSS verification is over the length of N - 1 bits
+     */
     msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
 
-    // Compensate for boundary condition when applying mask
-    //
+    /* Compensate for boundary condition when applying mask */
     if( msb % 8 == 0 )
     {
         p++;
@@ -1232,7 +1253,11 @@
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     mbedtls_md_init( &md_ctx );
-    mbedtls_md_setup( &md_ctx, md_info, 0 );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        return( ret );
+    }
 
     mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
 
@@ -1258,8 +1283,9 @@
         return( MBEDTLS_ERR_RSA_INVALID_PADDING );
     }
 
-    // Generate H = Hash( M' )
-    //
+    /*
+     * Generate H = Hash( M' )
+     */
     mbedtls_md_starts( &md_ctx );
     mbedtls_md_update( &md_ctx, zeros, 8 );
     mbedtls_md_update( &md_ctx, hash, hashlen );
@@ -1314,10 +1340,10 @@
     int ret;
     size_t len, siglen, asn1_len;
     unsigned char *p, *end;
-    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
     mbedtls_md_type_t msg_md_alg;
     const mbedtls_md_info_t *md_info;
     mbedtls_asn1_buf oid;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
 
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1364,8 +1390,9 @@
 
     end = p + len;
 
-    // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
-    //
+    /*
+     * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
+     */
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
@@ -1660,7 +1687,7 @@
 
 #if defined(MBEDTLS_SHA1_C)
     if( verbose != 0 )
-        mbedtls_printf( "PKCS#1 data sign  : " );
+        mbedtls_printf( "  PKCS#1 data sign  : " );
 
     mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
 
diff --git a/library/sha1.c b/library/sha1.c
index 8c77cba..2ccf2a2 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -49,7 +49,7 @@
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
 /*
diff --git a/library/sha512.c b/library/sha512.c
index af610bb..0f9e1e5 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -89,53 +89,6 @@
 }
 #endif /* PUT_UINT64_BE */
 
-/*
- * Round constants
- */
-static const uint64_t K[80] =
-{
-    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
-    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
-    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
-    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
-    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
-    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
-    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
-    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
-    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
-    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
-    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
-    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
-    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
-    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
-    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
-    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
-    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
-    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
-    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
-    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
-    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
-    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
-    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
-    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
-    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
-    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
-    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
-    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
-    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
-    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
-    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
-    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
-    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
-    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
-    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
-    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
-    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
-    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
-    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
-    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
-};
-
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
@@ -192,6 +145,54 @@
 }
 
 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
+
+/*
+ * Round constants
+ */
+static const uint64_t K[80] =
+{
+    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
+    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
+    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
+    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
+    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
+    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
+    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
+    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
+    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
+    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
+    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
+    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
+    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
+    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
+    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
+    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
+    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
+    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
+    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
+    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
+    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
+    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
+    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
+    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
+    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
+    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
+    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
+    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
+    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
+    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
+    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
+    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
+    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
+    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
+    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
+    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
+    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
+    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
+    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
+    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
+};
+
 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
 {
     int i;
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 711bc53..01c66ae 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -31,18 +31,20 @@
 
 #if defined(MBEDTLS_SSL_CACHE_C)
 
-#include "mbedtls/ssl_cache.h"
-
-#include <string.h>
-
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdlib.h>
 #define mbedtls_calloc    calloc
-#define mbedtls_free       free
+#define mbedtls_free      free
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
 #endif
 
+#include "mbedtls/ssl_cache.h"
+
+#include <string.h>
+
 void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
 {
     memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
@@ -59,7 +61,7 @@
 {
     int ret = 1;
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t t = time( NULL );
+    mbedtls_time_t t = mbedtls_time( NULL );
 #endif
     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
     mbedtls_ssl_cache_entry *cur, *entry;
@@ -138,7 +140,7 @@
 {
     int ret = 1;
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t t = time( NULL ), oldest = 0;
+    mbedtls_time_t t = time( NULL ), oldest = 0;
     mbedtls_ssl_cache_entry *old = NULL;
 #endif
     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 949b9ed..3546331 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -29,10 +29,16 @@
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_time_t    time_t
+#endif
+
 #include "mbedtls/ssl_ciphersuites.h"
 #include "mbedtls/ssl.h"
 
-// #include <stdlib.h>
 #include <string.h>
 
 /*
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 4452169..cd39db0 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -27,20 +27,22 @@
 
 #if defined(MBEDTLS_SSL_CLI_C)
 
-#include "mbedtls/debug.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/ssl_internal.h"
-
-#include <string.h>
-
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdlib.h>
 #define mbedtls_calloc    calloc
-#define mbedtls_free       free
+#define mbedtls_free      free
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
 #endif
 
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+
+#include <string.h>
+
 #include <stdint.h>
 
 #if defined(MBEDTLS_HAVE_TIME)
@@ -270,6 +272,12 @@
     for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
     {
 #endif
+        if( info == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
+            return;
+        }
+
         elliptic_curve_len += 2;
     }
 
@@ -289,7 +297,6 @@
     for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
     {
 #endif
-
         elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
         elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
     }
@@ -664,7 +671,7 @@
     int ret;
     unsigned char *p = ssl->handshake->randbytes;
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t t;
+    mbedtls_time_t t;
 #endif
 
     /*
@@ -679,7 +686,7 @@
 #endif
 
 #if defined(MBEDTLS_HAVE_TIME)
-    t = time( NULL );
+    t = mbedtls_time( NULL );
     *p++ = (unsigned char)( t >> 24 );
     *p++ = (unsigned char)( t >> 16 );
     *p++ = (unsigned char)( t >>  8 );
@@ -1587,7 +1594,7 @@
         ssl->state++;
         ssl->handshake->resume = 0;
 #if defined(MBEDTLS_HAVE_TIME)
-        ssl->session_negotiate->start = time( NULL );
+        ssl->session_negotiate->start = mbedtls_time( NULL );
 #endif
         ssl->session_negotiate->ciphersuite = i;
         ssl->session_negotiate->compression = comp;
@@ -1981,8 +1988,11 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
     }
 
-    // TODO: Retrieve PSK identity hint and callback to app
-    //
+    /*
+     * Note: we currently ignore the PKS identity hint, as we only allow one
+     * PSK to be provisionned on the client. This could be changed later if
+     * someone needs that feature.
+     */
     *p += len;
     ret = 0;
 
@@ -2529,8 +2539,8 @@
 static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
 {
     int ret;
-    unsigned char *buf, *p;
-    size_t n = 0, m = 0;
+    unsigned char *buf;
+    size_t n = 0;
     size_t cert_type_len = 0, dn_len = 0;
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
 
@@ -2578,9 +2588,6 @@
 
     ssl->record_read = 0;
 
-    // TODO: handshake_failure alert for an anonymous server to request
-    // client authentication
-
     /*
      *  struct {
      *      ClientCertificateType certificate_types<1..2^8-1>;
@@ -2588,11 +2595,26 @@
      *        supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
      *      DistinguishedName certificate_authorities<0..2^16-1>;
      *  } CertificateRequest;
+     *
+     *  Since we only support a single certificate on clients, let's just
+     *  ignore all the information that's supposed to help us pick a
+     *  certificate.
+     *
+     *  We could check that our certificate matches the request, and bail out
+     *  if it doesn't, but it's simpler to just send the certificate anyway,
+     *  and give the server the opportunity to decide if it should terminate
+     *  the connection when it doesn't like our certificate.
+     *
+     *  Same goes for the hash in TLS 1.2's signature_algorithms: at this
+     *  point we only have one hash available (see comments in
+     *  write_certificate_verify), so let's just use what we have.
+     *
+     *  However, we still minimally parse the message to check it is at least
+     *  superficially sane.
      */
     buf = ssl->in_msg;
 
-    // Retrieve cert types
-    //
+    /* certificate_types */
     cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
     n = cert_type_len;
 
@@ -2602,45 +2624,14 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
     }
 
-    p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
-    while( cert_type_len > 0 )
-    {
-#if defined(MBEDTLS_RSA_C)
-        if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
-            mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
-        {
-            ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
-            break;
-        }
-        else
-#endif
-#if defined(MBEDTLS_ECDSA_C)
-        if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
-            mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
-        {
-            ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
-            break;
-        }
-        else
-#endif
-        {
-            ; /* Unsupported cert type, ignore */
-        }
-
-        cert_type_len--;
-        p++;
-    }
-
+    /* supported_signature_algorithms */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
-        /* Ignored, see comments about hash in write_certificate_verify */
-        // TODO: should check the signature part against our pk_key though
         size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
                              | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n]       ) );
 
-        m += 2;
-        n += sig_alg_len;
+        n += 2 + sig_alg_len;
 
         if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
         {
@@ -2650,13 +2641,12 @@
     }
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
-    /* Ignore certificate_authorities, we only have one cert anyway */
-    // TODO: should not send cert if no CA matches
-    dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] <<  8 )
-             | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n]       ) );
+    /* certificate_authorities */
+    dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
+             | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n]       ) );
 
     n += dn_len;
-    if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
+    if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 7e0c573..f241c86 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -31,16 +31,18 @@
 
 #if defined(MBEDTLS_SSL_COOKIE_C)
 
-#include "mbedtls/ssl_cookie.h"
-#include "mbedtls/ssl_internal.h"
-
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_calloc    calloc
-#define mbedtls_free       free
+#define mbedtls_free      free
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
 #endif
 
+#include "mbedtls/ssl_cookie.h"
+#include "mbedtls/ssl_internal.h"
+
 #include <string.h>
 
 /* Implementation that should never be optimized out by the compiler */
@@ -172,7 +174,7 @@
         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
 
 #if defined(MBEDTLS_HAVE_TIME)
-    t = (unsigned long) time( NULL );
+    t = (unsigned long) mbedtls_time( NULL );
 #else
     t = ctx->serial++;
 #endif
@@ -242,7 +244,7 @@
         return( -1 );
 
 #if defined(MBEDTLS_HAVE_TIME)
-    cur_time = (unsigned long) time( NULL );
+    cur_time = (unsigned long) mbedtls_time( NULL );
 #else
     cur_time = ctx->serial;
 #endif
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 6b5b461..7271045 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -27,6 +27,16 @@
 
 #if defined(MBEDTLS_SSL_SRV_C)
 
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
+#endif
+
 #include "mbedtls/debug.h"
 #include "mbedtls/ssl.h"
 #include "mbedtls/ssl_internal.h"
@@ -37,14 +47,6 @@
 #include "mbedtls/ecp.h"
 #endif
 
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc    calloc
-#define mbedtls_free       free
-#endif
-
 #if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
 #endif
@@ -1505,192 +1507,200 @@
         ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
 #endif
 
-    /*
-     * Check the extension length
-     */
-    ext_offset = comp_offset + 1 + comp_len;
-    if( msg_len > ext_offset )
+    /* Do not parse the extensions if the protocol is SSLv3 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
     {
-        if( msg_len < ext_offset + 2 )
+#endif
+        /*
+         * Check the extension length
+         */
+        ext_offset = comp_offset + 1 + comp_len;
+        if( msg_len > ext_offset )
         {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            if( msg_len < ext_offset + 2 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            ext_len = ( buf[ext_offset + 0] << 8 )
+                    | ( buf[ext_offset + 1]      );
+
+            if( ( ext_len > 0 && ext_len < 4 ) ||
+                msg_len != ext_offset + 2 + ext_len )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
         }
+        else
+            ext_len = 0;
 
-        ext_len = ( buf[ext_offset + 0] << 8 )
-                | ( buf[ext_offset + 1]      );
+        ext = buf + ext_offset + 2;
+        MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
 
-        if( ( ext_len > 0 && ext_len < 4 ) ||
-            msg_len != ext_offset + 2 + ext_len )
+        while( ext_len != 0 )
         {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-        }
-    }
-    else
-        ext_len = 0;
+            unsigned int ext_id   = ( ( ext[0] <<  8 )
+                                    | ( ext[1]       ) );
+            unsigned int ext_size = ( ( ext[2] <<  8 )
+                                    | ( ext[3]       ) );
 
-    ext = buf + ext_offset + 2;
-    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
-
-    while( ext_len != 0 )
-    {
-        unsigned int ext_id   = ( ( ext[0] <<  8 )
-                                | ( ext[1]       ) );
-        unsigned int ext_size = ( ( ext[2] <<  8 )
-                                | ( ext[3]       ) );
-
-        if( ext_size + 4 > ext_len )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-        }
-        switch( ext_id )
-        {
+            if( ext_size + 4 > ext_len )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+            switch( ext_id )
+            {
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-        case MBEDTLS_TLS_EXT_SERVERNAME:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
-            if( ssl->conf->f_sni == NULL )
-                break;
+            case MBEDTLS_TLS_EXT_SERVERNAME:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
+                if( ssl->conf->f_sni == NULL )
+                    break;
 
-            ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
-        case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
+            case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-            renegotiation_info_seen = 1;
+                renegotiation_info_seen = 1;
 #endif
 
-            ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
-        case MBEDTLS_TLS_EXT_SIG_ALG:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
+            case MBEDTLS_TLS_EXT_SIG_ALG:
+                    MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-            if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
-                break;
+                if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+                    break;
 #endif
 
-            ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
           MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-        case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
+            case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
 
-            ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 
-        case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
-            ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
+            case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
+                ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
 
-            ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-        case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) );
+            case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) );
 
-            ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-        case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
+            case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
 
-            ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-        case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
+            case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
 
-            ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-        case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
+            case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
 
-            ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-        case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
+            case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
 
-            ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-        case MBEDTLS_TLS_EXT_SESSION_TICKET:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
+            case MBEDTLS_TLS_EXT_SESSION_TICKET:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
 
-            ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
 #if defined(MBEDTLS_SSL_ALPN)
-        case MBEDTLS_TLS_EXT_ALPN:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
+            case MBEDTLS_TLS_EXT_ALPN:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
 
-            ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
-            if( ret != 0 )
-                return( ret );
-            break;
+                ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
-        default:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
-                           ext_id ) );
-        }
+            default:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
+                               ext_id ) );
+            }
 
-        ext_len -= 4 + ext_size;
-        ext += 4 + ext_size;
+            ext_len -= 4 + ext_size;
+            ext += 4 + ext_size;
 
-        if( ext_len > 0 && ext_len < 4 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            if( ext_len > 0 && ext_len < 4 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
         }
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
     }
+#endif
 
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
     for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 )
@@ -2210,7 +2220,7 @@
 static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t t;
+    mbedtls_time_t t;
 #endif
     int ret;
     size_t olen, ext_len = 0, n;
@@ -2253,7 +2263,7 @@
                         buf[4], buf[5] ) );
 
 #if defined(MBEDTLS_HAVE_TIME)
-    t = time( NULL );
+    t = mbedtls_time( NULL );
     *p++ = (unsigned char)( t >> 24 );
     *p++ = (unsigned char)( t >> 16 );
     *p++ = (unsigned char)( t >>  8 );
@@ -2302,7 +2312,7 @@
         ssl->state++;
 
 #if defined(MBEDTLS_HAVE_TIME)
-        ssl->session_negotiate->start = time( NULL );
+        ssl->session_negotiate->start = mbedtls_time( NULL );
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -2361,6 +2371,12 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
                    ssl->session_negotiate->compression ) );
 
+    /* Do not write the extensions if the protocol is SSLv3 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
+    {
+#endif
+
     /*
      *  First write extensions, then the total length
      */
@@ -2417,6 +2433,10 @@
         p += ext_len;
     }
 
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    }
+#endif
+
     ssl->out_msglen  = p - buf;
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
@@ -2718,7 +2738,8 @@
     if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
     {
-        /* TODO: Support identity hints */
+        /* Note: we don't support identity hints, until someone asks
+         * for them. */
         *(p++) = 0x00;
         *(p++) = 0x00;
 
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 0e27900..5d77403 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -27,16 +27,18 @@
 
 #if defined(MBEDTLS_SSL_TICKET_C)
 
-#include "mbedtls/ssl_ticket.h"
-
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdlib.h>
 #define mbedtls_calloc    calloc
-#define mbedtls_free       free
+#define mbedtls_free      free
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
 #endif
 
+#include "mbedtls/ssl_ticket.h"
+
 #include <string.h>
 
 /* Implementation that should never be optimized out by the compiler */
@@ -69,7 +71,7 @@
     mbedtls_ssl_ticket_key *key = ctx->keys + index;
 
 #if defined(MBEDTLS_HAVE_TIME)
-    key->generation_time = (uint32_t) time( NULL );
+    key->generation_time = (uint32_t) mbedtls_time( NULL );
 #endif
 
     if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 )
@@ -98,7 +100,7 @@
 #else
     if( ctx->ticket_lifetime != 0 )
     {
-        uint32_t current_time = (uint32_t) time( NULL );
+        uint32_t current_time = (uint32_t) mbedtls_time( NULL );
         uint32_t key_time = ctx->keys[ctx->active].generation_time;
 
         if( current_time > key_time &&
@@ -451,7 +453,7 @@
 #if defined(MBEDTLS_HAVE_TIME)
     {
         /* Check for expiration */
-        time_t current_time = time( NULL );
+        mbedtls_time_t current_time = mbedtls_time( NULL );
 
         if( current_time < session->start ||
             (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4424f56..80a908d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -35,6 +35,15 @@
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#define mbedtls_time_t    time_t
+#endif
+
 #include "mbedtls/debug.h"
 #include "mbedtls/ssl.h"
 #include "mbedtls/ssl_internal.h"
@@ -46,14 +55,6 @@
 #include "mbedtls/oid.h"
 #endif
 
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc    calloc
-#define mbedtls_free       free
-#endif
-
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
@@ -2708,7 +2709,7 @@
  */
 int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
 {
-    int ret, done = 0;
+    int ret, done = 0, out_msg_type;
     size_t len = ssl->out_msglen;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
@@ -2724,7 +2725,9 @@
 #endif
     if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
     {
-        if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST &&
+        out_msg_type = ssl->out_msg[0];
+
+        if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST &&
             ssl->handshake == NULL )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@@ -2751,7 +2754,7 @@
             len += 8;
 
             /* Write message_seq and update it, except for HelloRequest */
-            if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST )
+            if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
             {
                 ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
                 ssl->out_msg[5] = ( ssl->handshake->out_msg_seq      ) & 0xFF;
@@ -2769,7 +2772,7 @@
         }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-        if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST )
+        if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
             ssl->handshake->update_checksum( ssl, ssl->out_msg, len );
     }
 
@@ -3706,10 +3709,6 @@
             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
             return( ret );
         }
-
-        // TODO: what's the purpose of these lines? is in_len used?
-        ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
-        ssl->in_len[1] = (unsigned char)( ssl->in_msglen      );
     }
 #endif /* MBEDTLS_ZLIB_SUPPORT */
 
@@ -5015,7 +5014,12 @@
 
     ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
 
-    // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
+    /*
+     * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
+     * may define some other value. Currently (early 2016), no defined
+     * ciphersuite does this (and this is unlikely to change as activity has
+     * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
+     */
     hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -5597,9 +5601,9 @@
 
 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
         void *p_bio,
-        int (*f_send)(void *, const unsigned char *, size_t),
-        int (*f_recv)(void *, unsigned char *, size_t),
-        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) )
+        mbedtls_ssl_send_t *f_send,
+        mbedtls_ssl_recv_t *f_recv,
+        mbedtls_ssl_recv_timeout_t *f_recv_timeout )
 {
     ssl->p_bio          = p_bio;
     ssl->f_send         = f_send;
@@ -5614,8 +5618,8 @@
 
 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
                                void *p_timer,
-                               void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms),
-                               int (*f_get_timer)(void *) )
+                               mbedtls_ssl_set_timer_t *f_set_timer,
+                               mbedtls_ssl_get_timer_t *f_get_timer )
 {
     ssl->p_timer        = p_timer;
     ssl->f_set_timer    = f_set_timer;
@@ -5769,7 +5773,7 @@
 {
     mbedtls_ecjpake_role role;
 
-    if( ssl->handshake == NULL && ssl->conf == NULL )
+    if( ssl->handshake == NULL || ssl->conf == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
@@ -6949,7 +6953,8 @@
 #endif
 #endif
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     /* explicit void pointer cast for buggy MS compiler */
     mbedtls_free( (void *) handshake->curves );
 #endif
diff --git a/library/timing.c b/library/timing.c
index 5d8b25b..a7c7ff0 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -38,6 +38,11 @@
 
 #if !defined(MBEDTLS_TIMING_ALT)
 
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32)
+#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
+#endif
+
 #ifndef asm
 #define asm __asm
 #endif
diff --git a/library/version_features.c b/library/version_features.c
index 1575e09..5d20ba0 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -54,6 +54,9 @@
 #if defined(MBEDTLS_PLATFORM_EXIT_ALT)
     "MBEDTLS_PLATFORM_EXIT_ALT",
 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+    "MBEDTLS_PLATFORM_TIME_ALT",
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
 #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
     "MBEDTLS_PLATFORM_FPRINTF_ALT",
 #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
@@ -63,6 +66,9 @@
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
     "MBEDTLS_PLATFORM_SNPRINTF_ALT",
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+    "MBEDTLS_PLATFORM_NV_SEED_ALT",
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
 #if defined(MBEDTLS_DEPRECATED_WARNING)
     "MBEDTLS_DEPRECATED_WARNING",
 #endif /* MBEDTLS_DEPRECATED_WARNING */
@@ -153,6 +159,9 @@
 #if defined(MBEDTLS_AES_DECRYPT_ALT)
     "MBEDTLS_AES_DECRYPT_ALT",
 #endif /* MBEDTLS_AES_DECRYPT_ALT */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    "MBEDTLS_TEST_NULL_ENTROPY",
+#endif /* MBEDTLS_TEST_NULL_ENTROPY */
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     "MBEDTLS_ENTROPY_HARDWARE_ALT",
 #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
@@ -288,6 +297,9 @@
 #if defined(MBEDTLS_ENTROPY_FORCE_SHA256)
     "MBEDTLS_ENTROPY_FORCE_SHA256",
 #endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    "MBEDTLS_ENTROPY_NV_SEED",
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
 #if defined(MBEDTLS_MEMORY_DEBUG)
     "MBEDTLS_MEMORY_DEBUG",
 #endif /* MBEDTLS_MEMORY_DEBUG */
diff --git a/library/x509.c b/library/x509.c
index ffc3d6c..a0df817 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -53,10 +53,12 @@
 #else
 #include <stdio.h>
 #include <stdlib.h>
-#define mbedtls_free       free
+#define mbedtls_free      free
 #define mbedtls_calloc    calloc
-#define mbedtls_printf     printf
-#define mbedtls_snprintf   snprintf
+#define mbedtls_time      time
+#define mbedtls_time_t    time_t
+#define mbedtls_printf    printf
+#define mbedtls_snprintf  snprintf
 #endif
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
@@ -843,7 +845,7 @@
 static int x509_get_current_time( mbedtls_x509_time *now )
 {
     struct tm *lt;
-    time_t tt;
+    mbedtls_time_t tt;
     int ret = 0;
 
 #if defined(MBEDTLS_THREADING_C)
@@ -851,7 +853,7 @@
         return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
 #endif
 
-    tt = time( NULL );
+    tt = mbedtls_time( NULL );
     lt = gmtime( &tt );
 
     if( lt == NULL )
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 125a773..7b2b473 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -502,14 +502,15 @@
     {
         mbedtls_pem_init( &pem );
 
-    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( buflen == 0 || buf[buflen - 1] != '\0' )
-        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
-    else
-        ret = mbedtls_pem_read_buffer( &pem,
-                               "-----BEGIN X509 CRL-----",
-                               "-----END X509 CRL-----",
-                               buf, NULL, 0, &use_len );
+        // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
+        // string
+        if( buflen == 0 || buf[buflen - 1] != '\0' )
+            ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+        else
+            ret = mbedtls_pem_read_buffer( &pem,
+                                           "-----BEGIN X509 CRL-----",
+                                           "-----END X509 CRL-----",
+                                            buf, NULL, 0, &use_len );
 
         if( ret == 0 )
         {
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 6dc5ad3..af6c2a4 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -516,9 +516,6 @@
 /*
  * X.509 v3 extensions
  *
- * TODO: Perform all of the basic constraints tests required by the RFC
- * TODO: Set values for undetected extensions to a sane default?
- *
  */
 static int x509_get_crt_ext( unsigned char **p,
                              const unsigned char *end,
@@ -680,14 +677,9 @@
     if( crt == NULL || buf == NULL )
         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
-    p = mbedtls_calloc( 1, len = buflen );
-    if( p == NULL )
-        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
-
-    memcpy( p, buf, buflen );
-
-    crt->raw.p = p;
-    crt->raw.len = len;
+    // Use the original buffer until we figure out actual length
+    p = (unsigned char*) buf;
+    len = buflen;
     end = p + len;
 
     /*
@@ -711,6 +703,18 @@
     }
     crt_end = p + len;
 
+    // Create and populate a new buffer for the raw field
+    crt->raw.len = crt_end - buf;
+    crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
+    if( p == NULL )
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+    memcpy( p, buf, crt->raw.len );
+
+    // Direct pointers to the new buffer 
+    p += crt->raw.len - len;
+    end = crt_end = p + len;
+
     /*
      * TBSCertificate  ::=  SEQUENCE  {
      */
@@ -966,7 +970,9 @@
 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
 {
     int success = 0, first_error = 0, total_failed = 0;
+#if defined(MBEDTLS_PEM_PARSE_C)
     int buf_format = MBEDTLS_X509_FORMAT_DER;
+#endif
 
     /*
      * Check for valid input
@@ -984,10 +990,12 @@
     {
         buf_format = MBEDTLS_X509_FORMAT_PEM;
     }
-#endif
 
     if( buf_format == MBEDTLS_X509_FORMAT_DER )
         return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#else
+    return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#endif
 
 #if defined(MBEDTLS_PEM_PARSE_C)
     if( buf_format == MBEDTLS_X509_FORMAT_PEM )
@@ -1060,7 +1068,6 @@
             success = 1;
         }
     }
-#endif /* MBEDTLS_PEM_PARSE_C */
 
     if( success )
         return( total_failed );
@@ -1068,6 +1075,7 @@
         return( first_error );
     else
         return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
+#endif /* MBEDTLS_PEM_PARSE_C */
 }
 
 #if defined(MBEDTLS_FS_IO)
@@ -1349,6 +1357,14 @@
     p = buf;
     n = size;
 
+    if( NULL == crt )
+    {
+        ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        return( (int) ( size - n ) );
+    }
+
     ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
                                prefix, crt->version );
     MBEDTLS_X509_SAFE_SNPRINTF;
@@ -1600,7 +1616,8 @@
 }
 
 /*
- * Check that the given certificate is valid according to the CRL.
+ * Check that the given certificate is not revoked according to the CRL.
+ * Skip validation is no CRL for the given CA is present.
  */
 static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
                                mbedtls_x509_crl *crl_list,
@@ -1613,12 +1630,6 @@
     if( ca == NULL )
         return( flags );
 
-    /*
-     * TODO: What happens if no CRL is present?
-     * Suggestion: Revocation state should be unknown if no CRL is present.
-     * For backwards compatibility this is not yet implemented.
-     */
-
     while( crl_list != NULL )
     {
         if( crl_list->version == 0 ||
@@ -1940,6 +1951,16 @@
             continue;
         }
 
+        if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
+        {
+            continue;
+        }
+
+        if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
+        {
+            continue;
+        }
+
         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
                            child->sig.p, child->sig.len ) != 0 )
@@ -1975,12 +1996,6 @@
         ((void) ca_crl);
 #endif
 
-        if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
-            ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
-
-        if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
-            ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
-
         if( NULL != f_vrfy )
         {
             if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
diff --git a/library/x509_csr.c b/library/x509_csr.c
index dbf659b..603d06b 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -104,7 +104,7 @@
     /*
      * Check for valid input
      */
-    if( csr == NULL || buf == NULL )
+    if( csr == NULL || buf == NULL || buflen == 0 )
         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     mbedtls_x509_csr_init( csr );
@@ -207,6 +207,13 @@
 
     /*
      *  attributes    [0] Attributes
+     *
+     *  The list of possible attributes is open-ended, though RFC 2985
+     *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
+     *  so we just ignore them. This is a safe thing to do as the worst thing
+     *  that could happen is that we issue a certificate that does not match
+     *  the requester's expectations - this cannot cause a violation of our
+     *  signature policies.
      */
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
@@ -214,7 +221,6 @@
         mbedtls_x509_csr_free( csr );
         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
     }
-    // TODO Parse Attributes / extension requests
 
     p += len;
 
@@ -268,14 +274,14 @@
     /*
      * Check for valid input
      */
-    if( csr == NULL || buf == NULL )
+    if( csr == NULL || buf == NULL || buflen == 0 )
         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_PEM_PARSE_C)
     mbedtls_pem_init( &pem );
 
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( buflen == 0 || buf[buflen - 1] != '\0' )
+    if( buf[buflen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 102144e..a14d20c 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -184,7 +184,12 @@
         mbedtls_fprintf( stderr, "Message Digest '%s' not found\n", argv[5] );
         goto exit;
     }
-    mbedtls_md_setup( &md_ctx, md_info, 1 );
+
+    if( mbedtls_md_setup( &md_ctx, md_info, 1 ) != 0 )
+    {
+        mbedtls_fprintf( stderr, "mbedtls_md_setup failed\n" );
+        goto exit;
+    }
 
     /*
      * Read the secret key and clean the command line.
@@ -399,6 +404,15 @@
             goto exit;
         }
 
+        if( mbedtls_cipher_get_block_size( &cipher_ctx ) == 0 )
+        {
+            mbedtls_fprintf( stderr, "Invalid cipher block size: 0. \n" );
+            goto exit;
+        }
+
+        /*
+         * Check the file size.
+         */
         if( ( ( filesize - mbedtls_md_get_size( md_info ) ) %
                 mbedtls_cipher_get_block_size( &cipher_ctx ) ) != 0 )
         {
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index f071d31..d1e81d4 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -83,8 +83,13 @@
     int nb_err1, nb_err2;
     int nb_tot1, nb_tot2;
     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
-    char buf[MBEDTLS_MD_MAX_SIZE * 2 + 1], line[1024];
+    char line[1024];
     char diff;
+#if defined(__clang_analyzer__)
+    char buf[MBEDTLS_MD_MAX_SIZE * 2 + 1] = { };
+#else
+    char buf[MBEDTLS_MD_MAX_SIZE * 2 + 1];
+#endif
 
     if( ( f = fopen( filename, "rb" ) ) == NULL )
     {
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 59c4fa8..8ebf34a 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -30,6 +30,7 @@
 #else
 #include <stdio.h>
 #define mbedtls_printf     printf
+#define mbedtls_time_t     time_t
 #endif
 
 #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
@@ -124,6 +125,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index 6005a62..072fe13 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -30,6 +30,7 @@
 #else
 #include <stdio.h>
 #define mbedtls_printf     printf
+#define mbedtls_time_t     time_t
 #endif
 
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) ||   \
@@ -171,6 +172,7 @@
         ( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_write_file returned %d\n\n", ret );
+        fclose( fout );
         goto exit;
     }
 
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 83b0b44..7eef845 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -30,6 +30,7 @@
 #else
 #include <stdio.h>
 #define mbedtls_printf     printf
+#define mbedtls_time_t     time_t
 #endif
 
 #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
@@ -131,6 +132,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
@@ -156,6 +158,7 @@
         mbedtls_mpi_read_file( &dhm.G, 16, f ) != 0 )
     {
         mbedtls_printf( " failed\n  ! Invalid DH parameter file\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 322e8af..daf08a9 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -142,6 +142,7 @@
     if( fwrite( buf, 1, olen, f ) != olen )
     {
         mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index 94431e0..1cc013d 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -29,7 +29,11 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_printf     printf
+#define mbedtls_exit       exit
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
 #endif
 
 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_RSA_C) && \
@@ -39,8 +43,8 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
 
-#include <stdio.h>
 #include <string.h>
+
 #endif
 
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_RSA_C) ||  \
@@ -57,7 +61,7 @@
 int main( int argc, char *argv[] )
 {
     FILE *f;
-    int ret, c;
+    int return_val, exit_val, c;
     size_t i;
     mbedtls_rsa_context rsa;
     mbedtls_entropy_context entropy;
@@ -68,8 +72,7 @@
     ((void) argv);
 
     memset(result, 0, sizeof( result ) );
-    mbedtls_ctr_drbg_init( &ctr_drbg );
-    ret = 1;
+    exit_val = MBEDTLS_EXIT_SUCCESS;
 
     if( argc != 1 )
     {
@@ -79,18 +82,23 @@
         mbedtls_printf( "\n" );
 #endif
 
-        goto exit;
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
     mbedtls_printf( "\n  . Seeding the random number generator..." );
     fflush( stdout );
 
+    mbedtls_ctr_drbg_init( &ctr_drbg );
     mbedtls_entropy_init( &entropy );
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
+
+    return_val = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
+                                        &entropy, (const unsigned char *) pers,
+                                        strlen( pers ) );
+    if( return_val != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
+                        return_val );
         goto exit;
     }
 
@@ -99,23 +107,25 @@
 
     if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
     {
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " failed\n  ! Could not open rsa_priv.txt\n" \
                 "  ! Please run rsa_genkey first\n\n" );
         goto exit;
     }
 
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
-
-    if( ( ret = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
+    if( ( return_val = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n",
+                        return_val );
+        fclose( f );
         goto exit;
     }
 
@@ -126,10 +136,9 @@
     /*
      * Extract the RSA encrypted value from the text file
      */
-    ret = 1;
-
     if( ( f = fopen( "result-enc.txt", "rb" ) ) == NULL )
     {
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( "\n  ! Could not open %s\n\n", "result-enc.txt" );
         goto exit;
     }
@@ -144,6 +153,7 @@
 
     if( i != rsa.len )
     {
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( "\n  ! Invalid RSA signature format\n\n" );
         goto exit;
     }
@@ -154,11 +164,14 @@
     mbedtls_printf( "\n  . Decrypting the encrypted data" );
     fflush( stdout );
 
-    if( ( ret = mbedtls_rsa_pkcs1_decrypt( &rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
-                                   MBEDTLS_RSA_PRIVATE, &i, buf, result,
-                                   1024 ) ) != 0 )
+    return_val = mbedtls_rsa_pkcs1_decrypt( &rsa, mbedtls_ctr_drbg_random,
+                                            &ctr_drbg, MBEDTLS_RSA_PRIVATE, &i,
+                                            buf, result, 1024 );
+    if( return_val != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_decrypt returned %d\n\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_decrypt returned %d\n\n",
+                        return_val );
         goto exit;
     }
 
@@ -166,17 +179,17 @@
 
     mbedtls_printf( "The decrypted result is: '%s'\n\n", result );
 
-    ret = 0;
-
 exit:
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
+    mbedtls_rsa_free( &rsa );
 
 #if defined(_WIN32)
     mbedtls_printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();
 #endif
 
-    return( ret );
+    return( exit_val );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_FS_IO */
+
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index 796343f..b9cb187 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -29,8 +29,12 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
+#define mbedtls_exit       exit
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
 #endif
 
 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_RSA_C) && \
@@ -40,7 +44,6 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
 
-#include <stdio.h>
 #include <string.h>
 #endif
 
@@ -58,7 +61,7 @@
 int main( int argc, char *argv[] )
 {
     FILE *f;
-    int ret;
+    int return_val, exit_val;
     size_t i;
     mbedtls_rsa_context rsa;
     mbedtls_entropy_context entropy;
@@ -67,8 +70,7 @@
     unsigned char buf[512];
     const char *pers = "rsa_encrypt";
 
-    mbedtls_ctr_drbg_init( &ctr_drbg );
-    ret = 1;
+    exit_val = MBEDTLS_EXIT_SUCCESS;
 
     if( argc != 2 )
     {
@@ -78,18 +80,24 @@
         mbedtls_printf( "\n" );
 #endif
 
-        goto exit;
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
     mbedtls_printf( "\n  . Seeding the random number generator..." );
     fflush( stdout );
 
+    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
+    mbedtls_ctr_drbg_init( &ctr_drbg );
     mbedtls_entropy_init( &entropy );
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
+
+    return_val = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
+                                        &entropy, (const unsigned char *) pers,
+                                        strlen( pers ) );
+    if( return_val != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
+                        return_val );
         goto exit;
     }
 
@@ -98,18 +106,19 @@
 
     if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
     {
-        ret = 1;
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " failed\n  ! Could not open rsa_pub.txt\n" \
                 "  ! Please run rsa_genkey first\n\n" );
         goto exit;
     }
 
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
-
-    if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
-        ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
+    if( ( return_val = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
+        ( return_val = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n",
+                        return_val );
+        fclose( f );
         goto exit;
     }
 
@@ -119,6 +128,7 @@
 
     if( strlen( argv[1] ) > 100 )
     {
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " Input data larger than 100 characters.\n\n" );
         goto exit;
     }
@@ -131,11 +141,14 @@
     mbedtls_printf( "\n  . Generating the RSA encrypted value" );
     fflush( stdout );
 
-    if( ( ret = mbedtls_rsa_pkcs1_encrypt( &rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
-                                   MBEDTLS_RSA_PUBLIC, strlen( argv[1] ),
-                                   input, buf ) ) != 0 )
+    return_val = mbedtls_rsa_pkcs1_encrypt( &rsa, mbedtls_ctr_drbg_random,
+                                            &ctr_drbg, MBEDTLS_RSA_PUBLIC,
+                                            strlen( argv[1] ), input, buf );
+    if( return_val != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_encrypt returned %d\n\n", ret );
+        exit_val = MBEDTLS_EXIT_FAILURE;
+        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_encrypt returned %d\n\n",
+                        return_val );
         goto exit;
     }
 
@@ -144,7 +157,7 @@
      */
     if( ( f = fopen( "result-enc.txt", "wb+" ) ) == NULL )
     {
-        ret = 1;
+        exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " failed\n  ! Could not create %s\n\n", "result-enc.txt" );
         goto exit;
     }
@@ -160,13 +173,14 @@
 exit:
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
+    mbedtls_rsa_free( &rsa );
 
 #if defined(_WIN32)
     mbedtls_printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();
 #endif
 
-    return( ret );
+    return( exit_val );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_ENTROPY_C &&
           MBEDTLS_FS_IO && MBEDTLS_CTR_DRBG_C */
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index e897c65..affbf7a 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -62,6 +62,7 @@
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
     char filename[512];
 
+    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
     ret = 1;
 
     if( argc != 2 )
@@ -86,8 +87,6 @@
         goto exit;
     }
 
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
-
     if( ( ret = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
         ( ret = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
         ( ret = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
@@ -98,6 +97,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
@@ -157,6 +157,8 @@
 
 exit:
 
+    mbedtls_rsa_free( &rsa );
+
 #if defined(_WIN32)
     mbedtls_printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index c045a04..7b6f14d 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -153,6 +153,7 @@
     if( fwrite( buf, 1, olen, f ) != olen )
     {
         mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index ade36dc..1f827aa 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -61,7 +61,9 @@
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
     char filename[512];
 
+    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
     ret = 1;
+
     if( argc != 2 )
     {
         mbedtls_printf( "usage: rsa_verify <filename>\n" );
@@ -83,12 +85,11 @@
         goto exit;
     }
 
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
-
     if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
         ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
@@ -149,6 +150,8 @@
 
 exit:
 
+    mbedtls_rsa_free( &rsa );
+
 #if defined(_WIN32)
     mbedtls_printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index b37eb83..14fb612 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
+#define mbedtls_time_t     time_t
 #endif
 
 #if !defined(MBEDTLS_SSL_CLI_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index df0fc78..1d6eb3b 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
+#define mbedtls_time_t     time_t
 #endif
 
 #if !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index d613124..d3954c5 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -36,19 +36,21 @@
  * This is not a good example for general use. This programs has the specific
  * goal of minimizing use of the libc functions on full-blown OSes.
  */
-#if defined(unix) || defined(__unix__) || defined(__unix)
+#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
 #define UNIX
 #endif
 
 #if !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_ENTROPY_C) || \
     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) || \
     !defined(UNIX)
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
 #define mbedtls_printf printf
 #endif
+
 int main( void )
 {
     mbedtls_printf( "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_ENTROPY_C and/or "
@@ -58,6 +60,15 @@
 }
 #else
 
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_time_t       time_t
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
+#endif
+
 #include <string.h>
 
 #include "mbedtls/net.h"
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 1aeddf7..3516e15 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -29,6 +29,9 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time       time 
+#define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 559e502..78f9e00 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -29,6 +29,9 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
 #define mbedtls_snprintf   snprintf
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 13ce5dd..363f38f 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
+#define mbedtls_time_t     time_t
 #endif
 
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) ||    \
@@ -127,7 +128,7 @@
                                (const unsigned char *) pers,
                                strlen( pers ) ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        mbedtls_printf( " failed!  mbedtls_ctr_drbg_seed returned %d\n\n", ret );
         goto exit;
     }
 
@@ -148,7 +149,7 @@
                           mbedtls_test_srv_crt_len );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_x509_crt_parse returned %d\n\n", ret );
         goto exit;
     }
 
@@ -156,7 +157,7 @@
                           mbedtls_test_cas_pem_len );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_x509_crt_parse returned %d\n\n", ret );
         goto exit;
     }
 
@@ -164,7 +165,7 @@
                           mbedtls_test_srv_key_len, NULL, 0 );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_pk_parse_key returned %d\n\n", ret );
         goto exit;
     }
 
@@ -181,7 +182,7 @@
                     MBEDTLS_SSL_TRANSPORT_STREAM,
                     MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_ssl_config_defaults returned %d\n\n", ret );
         goto exit;
     }
 
@@ -191,7 +192,7 @@
     mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
     if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
         goto exit;
     }
 
@@ -205,7 +206,7 @@
 
     if( ( ret = mbedtls_net_bind( &listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_TCP ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_net_bind returned %d\n\n", ret );
+        mbedtls_printf( " failed!  mbedtls_net_bind returned %d\n\n", ret );
         goto exit;
     }
 
@@ -219,96 +220,101 @@
         mbedtls_net_init( &client_fd );
         mbedtls_ssl_init( &ssl );
 
-        mbedtls_printf( "  . Waiting for a remote connection ..." );
+        mbedtls_printf( "  . Waiting for a remote connection ...\n" );
         fflush( stdout );
 
         if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
                                         NULL, 0, NULL ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_net_accept returned %d\n\n", ret );
+            mbedtls_printf( " failed!  mbedtls_net_accept returned %d\n\n", ret );
             goto exit;
         }
 
-        mbedtls_printf( " ok\n" );
-
         /*
          * 3.5. Forking server thread
          */
 
-        pid = fork();
-
         mbedtls_printf( "  . Forking to handle connection ..." );
         fflush( stdout );
 
+        pid = fork();
+
         if( pid < 0 )
         {
-            mbedtls_printf(" failed\n  ! fork returned %d\n\n", pid );
+            mbedtls_printf(" failed!  fork returned %d\n\n", pid );
             goto exit;
         }
 
-        mbedtls_printf( " ok\n" );
-
         if( pid != 0 )
         {
+            mbedtls_printf( " ok\n" );
+
             if( ( ret = mbedtls_ctr_drbg_reseed( &ctr_drbg,
                                          (const unsigned char *) "parent",
                                          6 ) ) != 0 )
             {
-                mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_reseed returned %d\n", ret );
+                mbedtls_printf( " failed!  mbedtls_ctr_drbg_reseed returned %d\n\n", ret );
                 goto exit;
             }
 
-            mbedtls_net_free( &client_fd );
             continue;
         }
 
-        mbedtls_net_free( &listen_fd );
+        mbedtls_net_init( &listen_fd );
+
+        pid = getpid();
 
         /*
          * 4. Setup stuff
          */
-        mbedtls_printf( "  . Setting up the SSL data...." );
+        mbedtls_printf( "pid %d: Setting up the SSL data.\n", pid );
         fflush( stdout );
 
         if( ( ret = mbedtls_ctr_drbg_reseed( &ctr_drbg,
                                      (const unsigned char *) "child",
                                      5 ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_reseed returned %d\n", ret );
+            mbedtls_printf(
+                    "pid %d: SSL setup failed!  mbedtls_ctr_drbg_reseed returned %d\n\n",
+                    pid, ret );
             goto exit;
         }
 
         if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+            mbedtls_printf(
+                    "pid %d: SSL setup failed!  mbedtls_ssl_setup returned %d\n\n",
+                    pid, ret );
             goto exit;
         }
 
         mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
-        mbedtls_printf( " ok\n" );
+        mbedtls_printf( "pid %d: SSL setup ok\n", pid );
 
         /*
          * 5. Handshake
          */
-        mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
+        mbedtls_printf( "pid %d: Performing the SSL/TLS handshake.\n", pid );
         fflush( stdout );
 
         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
         {
             if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
-                mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned %d\n\n", ret );
+                mbedtls_printf(
+                        "pid %d: SSL handshake failed!  mbedtls_ssl_handshake returned %d\n\n",
+                        pid, ret );
                 goto exit;
             }
         }
 
-        mbedtls_printf( " ok\n" );
+        mbedtls_printf( "pid %d: SSL handshake ok\n", pid );
 
         /*
          * 6. Read the HTTP Request
          */
-        mbedtls_printf( "  < Read from client:" );
+        mbedtls_printf( "pid %d: Start reading from client.\n", pid );
         fflush( stdout );
 
         do
@@ -325,15 +331,15 @@
                 switch( ret )
                 {
                     case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
-                        mbedtls_printf( " connection was closed gracefully\n" );
+                        mbedtls_printf( "pid %d: connection was closed gracefully\n", pid );
                         break;
 
                     case MBEDTLS_ERR_NET_CONN_RESET:
-                        mbedtls_printf( " connection was reset by peer\n" );
+                        mbedtls_printf( "pid %d: connection was reset by peer\n", pid );
                         break;
 
                     default:
-                        mbedtls_printf( " mbedtls_ssl_read returned %d\n", ret );
+                        mbedtls_printf( "pid %d: mbedtls_ssl_read returned %d\n", pid, ret );
                         break;
                 }
 
@@ -341,7 +347,7 @@
             }
 
             len = ret;
-            mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
+            mbedtls_printf( "pid %d: %d bytes read\n\n%s", pid, len, (char *) buf );
 
             if( ret > 0 )
                 break;
@@ -351,7 +357,7 @@
         /*
          * 7. Write the 200 Response
          */
-        mbedtls_printf( "  > Write to client:" );
+        mbedtls_printf( "pid %d: Start writing to client.\n", pid );
         fflush( stdout );
 
         len = sprintf( (char *) buf, HTTP_RESPONSE,
@@ -363,18 +369,21 @@
             {
                 if( ret == MBEDTLS_ERR_NET_CONN_RESET )
                 {
-                    mbedtls_printf( " failed\n  ! peer closed the connection\n\n" );
+                    mbedtls_printf(
+                            "pid %d: Write failed!  peer closed the connection\n\n", pid );
                     goto exit;
                 }
 
                 if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
                 {
-                    mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
+                    mbedtls_printf(
+                            "pid %d: Write failed!  mbedtls_ssl_write returned %d\n\n",
+                            pid, ret );
                     goto exit;
                 }
             }
             len = ret;
-            mbedtls_printf( " %d bytes written\n\n%s\n", len, (char *) buf );
+            mbedtls_printf( "pid %d: %d bytes written\n\n%s\n", pid, len, (char *) buf );
 
             mbedtls_net_usleep( 1000000 );
         }
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 974c170..c807eb5 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -29,6 +29,9 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t 
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 70efba9..c7f5267 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -29,6 +29,9 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t 
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index b586a70..6d4e916 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -29,7 +29,10 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_free       free
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t
 #define mbedtls_calloc    calloc
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index fe5d514..6923453 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -26,6 +26,7 @@
 #endif
 
 #include "mbedtls/entropy.h"
+#include "mbedtls/entropy_poll.h"
 #include "mbedtls/hmac_drbg.h"
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/dhm.h"
@@ -52,15 +53,18 @@
 #include "mbedtls/ecjpake.h"
 #include "mbedtls/timing.h"
 
-#include <stdio.h>
 #include <string.h>
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
+#define mbedtls_exit       exit
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
 #endif
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
@@ -97,9 +101,43 @@
             test_snprintf( 5, "123",         3 ) != 0 );
 }
 
+/*
+ * Check if a seed file is present, and if not create one for the entropy
+ * self-test. If this fails, we attempt the test anyway, so no error is passed
+ * back.
+ */
+#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && \
+        !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+static void create_entropy_seed_file( void )
+{
+    int result;
+    size_t output_len = 0;
+    unsigned char seed_value[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    /* Attempt to read the entropy seed file. If this fails - attempt to write
+     * to the file to ensure one is present. */
+    result = mbedtls_platform_std_nv_seed_read( seed_value,
+                                                    MBEDTLS_ENTROPY_BLOCK_SIZE );
+    if( 0 == result )
+        return;
+
+    result = mbedtls_platform_entropy_poll( NULL,
+                                            seed_value,
+                                            MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                            &output_len );
+    if( 0 != result )
+        return;
+
+    if( MBEDTLS_ENTROPY_BLOCK_SIZE != output_len )
+        return;
+
+    mbedtls_platform_std_nv_seed_write( seed_value, MBEDTLS_ENTROPY_BLOCK_SIZE );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
-    int ret = 0, v;
+    int v, suites_tested = 0, suites_failed = 0;
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     unsigned char buf[1000000];
 #endif
@@ -114,7 +152,7 @@
     if( pointer != NULL )
     {
         mbedtls_printf( "all-bits-zero is not a NULL pointer\n" );
-        return( 1 );
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
     /*
@@ -123,11 +161,14 @@
     if( run_test_snprintf() != 0 )
     {
         mbedtls_printf( "the snprintf implementation is broken\n" );
-        return( 0 );
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
-    if( argc == 2 && strcmp( argv[1], "-quiet" ) == 0 )
+    if( argc == 2 && ( strcmp( argv[1], "--quiet" ) == 0  ||
+        strcmp( argv[1], "-q" ) == 0 ) )
+    {
         v = 0;
+    }
     else
     {
         v = 1;
@@ -141,135 +182,218 @@
 #endif
 
 #if defined(MBEDTLS_MD2_C)
-    if( ( ret = mbedtls_md2_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_md2_self_test( v )  != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_MD4_C)
-    if( ( ret = mbedtls_md4_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_md4_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_MD5_C)
-    if( ( ret = mbedtls_md5_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_md5_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_RIPEMD160_C)
-    if( ( ret = mbedtls_ripemd160_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_ripemd160_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_SHA1_C)
-    if( ( ret = mbedtls_sha1_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_sha1_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_SHA256_C)
-    if( ( ret = mbedtls_sha256_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_sha256_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_SHA512_C)
-    if( ( ret = mbedtls_sha512_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_sha512_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_ARC4_C)
-    if( ( ret = mbedtls_arc4_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_arc4_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_DES_C)
-    if( ( ret = mbedtls_des_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_des_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_AES_C)
-    if( ( ret = mbedtls_aes_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_aes_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C)
-    if( ( ret = mbedtls_gcm_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_gcm_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)
-    if( ( ret = mbedtls_ccm_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_ccm_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_BASE64_C)
-    if( ( ret = mbedtls_base64_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_base64_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_BIGNUM_C)
-    if( ( ret = mbedtls_mpi_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_mpi_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_RSA_C)
-    if( ( ret = mbedtls_rsa_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_rsa_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_X509_USE_C)
-    if( ( ret = mbedtls_x509_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_x509_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_XTEA_C)
-    if( ( ret = mbedtls_xtea_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_xtea_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_CAMELLIA_C)
-    if( ( ret = mbedtls_camellia_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_camellia_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_CTR_DRBG_C)
-    if( ( ret = mbedtls_ctr_drbg_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_ctr_drbg_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_HMAC_DRBG_C)
-    if( ( ret = mbedtls_hmac_drbg_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_hmac_drbg_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_ECP_C)
-    if( ( ret = mbedtls_ecp_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_ecp_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_ECJPAKE_C)
-    if( ( ret = mbedtls_ecjpake_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_ecjpake_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_DHM_C)
-    if( ( ret = mbedtls_dhm_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_dhm_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_ENTROPY_C)
-    if( ( ret = mbedtls_entropy_self_test( v ) ) != 0 )
-        return( ret );
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+    create_entropy_seed_file();
+#endif
+
+    if( mbedtls_entropy_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #if defined(MBEDTLS_PKCS5_C)
-    if( ( ret = mbedtls_pkcs5_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_pkcs5_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 /* Slow tests last */
 
 #if defined(MBEDTLS_TIMING_C)
-    if( ( ret = mbedtls_timing_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_timing_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
 #else
@@ -285,19 +409,35 @@
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_free();
-
-    if( ( ret = mbedtls_memory_buffer_alloc_self_test( v ) ) != 0 )
-        return( ret );
+    if( mbedtls_memory_buffer_alloc_self_test( v ) != 0 )
+    {
+        suites_failed++;
+    }
+    suites_tested++;
 #endif
 
     if( v != 0 )
     {
-        mbedtls_printf( "  [ All tests passed ]\n\n" );
+        mbedtls_printf( "  Executed %d test suites\n\n", suites_tested );
+
+        if( suites_failed > 0)
+        {
+            mbedtls_printf( "  [ %d tests FAIL ]\n\n", suites_failed );
+        }
+        else
+        {
+            mbedtls_printf( "  [ All tests PASS ]\n\n" );
+        }
 #if defined(_WIN32)
         mbedtls_printf( "  Press Enter to exit this program.\n" );
         fflush( stdout ); getchar();
 #endif
     }
 
-    return( ret );
+    if( suites_failed > 0)
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
+
+    /* return() is here to prevent compiler warnings */
+    return( MBEDTLS_EXIT_SUCCESS );
 }
+
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index eb8d29e..b698c78 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -34,11 +34,15 @@
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t
 #define mbedtls_printf     printf
 #endif
 
 #if !defined(MBEDTLS_NET_C)
-#include <stdio.h>
 int main( void )
 {
     mbedtls_printf( "MBEDTLS_NET_C not defined.\n" );
@@ -50,10 +54,7 @@
 #include "mbedtls/error.h"
 #include "mbedtls/ssl.h"
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <time.h>
 
 /* For select() */
 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 84f67e6..3f50a7a 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -29,6 +29,9 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/scripts/apidoc_full.sh b/scripts/apidoc_full.sh
new file mode 100755
index 0000000..bebab10
--- /dev/null
+++ b/scripts/apidoc_full.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Generate doxygen documentation with a full config.h (this ensures that every
+# available flag is documented, and avoids warnings about documentation
+# without a corresponding #define).
+#
+# /!\ This must not be a Makefile target, as it would create a race condition
+# when multiple targets are invoked in the same parallel build.
+
+set -eu
+
+CONFIG_H='include/mbedtls/config.h'
+
+if [ -r $CONFIG_H ]; then :; else
+    echo "$CONFIG_H not found" >&2
+    exit 1
+fi
+
+CONFIG_BAK=${CONFIG_H}.bak
+cp -p $CONFIG_H $CONFIG_BAK
+
+scripts/config.pl realfull
+make apidoc
+
+mv $CONFIG_BAK $CONFIG_H
diff --git a/scripts/bump_version.sh b/scripts/bump_version.sh
index 97d2f1f..fc8b800 100755
--- a/scripts/bump_version.sh
+++ b/scripts/bump_version.sh
@@ -1,4 +1,17 @@
 #!/bin/bash
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2012-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Sets the version numbers in the source code to those given.
+#
+# Usage: bump_version.sh [ --version <version> ] [ --so-crypto <version>]
+#                           [ --so-x509 <version> ] [ --so-tls <version> ]
+#                           [ -v | --verbose ] [ -h | --help ]
+#
 
 VERSION=""
 SOVERSION=""
@@ -109,10 +122,6 @@
 sed -e "s/version:\".\{1,\}/version:\"$VERSION\"/g" < tests/suites/test_suite_version.data > tmp
 mv tmp tests/suites/test_suite_version.data
 
-[ $VERBOSE ] && echo "Bumping version in yotta/data/module.json"
-sed -e "s/\"version\": \".\{1,\}\"/\"version\": \"$VERSION\"/g" < yotta/data/module.json > tmp
-mv tmp yotta/data/module.json
-
 [ $VERBOSE ] && echo "Bumping PROJECT_NAME in doxygen/mbedtls.doxyfile and doxygen/input/doc_mainpage.h"
 for i in doxygen/mbedtls.doxyfile doxygen/input/doc_mainpage.h;
 do
@@ -128,3 +137,4 @@
 
 [ $VERBOSE ] && echo "Re-generating visualc files"
 scripts/generate_visualc_files.pl
+
diff --git a/scripts/config.pl b/scripts/config.pl
index d4c32fd..8921a87 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -1,23 +1,82 @@
 #!/usr/bin/perl
-
-# Tune the configuration file
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Comments and uncomments #define lines in the given header file and optionally
+# sets their value or can get the value. This is to provide scripting control of
+# what preprocessor symbols, and therefore what build time configuration flags
+# are set in the 'config.h' file.
+#
+# Usage: config.pl [-f <file> | --file <file>] [-o | --force]
+#                   [set <symbol> <value> | unset <symbol> | get <symbol> |
+#                       full | realfull]
+#
+# Full usage description provided below.
+#
+# Things that shouldn't be enabled with "full".
+#
+#   MBEDTLS_TEST_NULL_ENTROPY
+#   MBEDTLS_DEPRECATED_REMOVED
+#   MBEDTLS_HAVE_SSE2
+#   MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+#   MBEDTLS_ECP_DP_M221_ENABLED
+#   MBEDTLS_ECP_DP_M383_ENABLED
+#   MBEDTLS_ECP_DP_M511_ENABLED
+#   MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#   MBEDTLS_NO_PLATFORM_ENTROPY
+#   MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+#   MBEDTLS_SSL_HW_RECORD_ACCEL
+#   MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+#   MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+#       - this could be enabled if the respective tests were adapted
+#   MBEDTLS_ZLIB_SUPPORT
+#   MBEDTLS_PKCS11_C
+#   and any symbol beginning _ALT
+#
 
 use warnings;
 use strict;
 
+my $config_file = "include/mbedtls/config.h";
 my $usage = <<EOU;
-$0 [-f <file>] unset <name>
-$0 [-f <file>] set <name> [<value>]
-EOU
-# for our eyes only:
-# $0 [-f <file>] full|realfull
+$0 [-f <file> | --file <file>] [-o | --force]
+                   [set <symbol> <value> | unset <symbol> | get <symbol> |
+                        full | realfull]
 
-# Things that shouldn't be enabled with "full".
-# Notes:
-# - MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 and
-#   MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION could be enabled if the
-#   respective tests were adapted
+Commands
+    set <symbol> [<value>]  - Uncomments or adds a #define for the <symbol> to
+                              the configuration file, and optionally making it
+                              of <value>.
+                              If the symbol isn't present in the file an error
+                              is returned.
+    unset <symbol>          - Comments out the #define for the given symbol if
+                              present in the configuration file.
+    get <symbol>            - Finds the #define for the given symbol, returning
+                              an exitcode of 0 if the symbol is found, and -1 if
+                              not. The value of the symbol is output if one is
+                              specified in the configuration file.
+    full                    - Uncomments all #define's in the configuration file
+                              excluding some reserved symbols, until the
+                              'Module configuration options' section
+    realfull                - Uncomments all #define's with no exclusions
+
+Options
+    -f | --file <filename>  - The file or file path for the configuration file
+                              to edit. When omitted, the following default is
+                              used:
+                                $config_file
+    -o | --force            - If the symbol isn't present in the configuration
+                              file when setting it's value, a #define is
+                              appended to the end of the file.
+
+EOU
+
 my @excluded = qw(
+MBEDTLS_TEST_NULL_ENTROPY
 MBEDTLS_DEPRECATED_REMOVED
 MBEDTLS_HAVE_SSE2
 MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
@@ -40,40 +99,68 @@
 PLATFORM_[A-Z0-9]+_ALT
 );
 
-my $config_file = "include/mbedtls/config.h";
+# Process the command line arguments
 
-# get -f option
-if (@ARGV >= 2 && $ARGV[0] eq "-f") {
-    shift; # -f
-    $config_file = shift;
+my $force_option = 0;
 
-    -f $config_file or die "No such file: $config_file\n";
-} else {
-    if (! -f $config_file)  {
-        chdir '..' or die;
-        -f $config_file
-            or die "Without -f, must be run from root or scripts\n"
+my ($arg, $name, $value, $action);
+
+while ($arg = shift) {
+
+    # Check if the argument is an option
+    if ($arg eq "-f" || $arg eq "--file") {
+        $config_file = shift;
+
+        -f $config_file or die "No such file: $config_file\n";
+
+    }
+    elsif ($arg eq "-o" || $arg eq "--force") {
+        $force_option = 1;
+
+    }
+    else
+    {
+        # ...else assume it's a command
+        $action = $arg;
+
+        if ($action eq "full" || $action eq "realfull") {
+            # No additional parameters
+            die $usage if @ARGV;
+
+        }
+        elsif ($action eq "unset" || $action eq "get") {
+            die $usage unless @ARGV;
+            $name = shift;
+
+        }
+        elsif ($action eq "set") {
+            die $usage unless @ARGV;
+            $name = shift;
+            $value = shift if @ARGV;
+
+        }
+        else {
+            die "Command '$action' not recognised.\n\n".$usage;
+        }
     }
 }
 
-# get action
-die $usage unless @ARGV;
-my $action = shift;
+# If no command was specified, exit...
+if ( not defined($action) ){ die $usage; }
 
-my ($name, $value);
-if ($action eq "full" || $action eq "realfull") {
-    # nothing to do
-} elsif ($action eq "unset") {
-    die $usage unless @ARGV;
-    $name = shift;
-} elsif ($action eq "set") {
-    die $usage unless @ARGV;
-    $name = shift;
-    $value = shift if @ARGV;
-} else {
-    die $usage;
+# Check the config file is present
+if (! -f $config_file)  {
+
+    chdir '..' or die;
+
+    # Confirm this is the project root directory and try again
+    if ( !(-d 'scripts' && -d 'include' && -d 'library' && -f $config_file) ) {
+        die "If no file specified, must be run from the project root or scripts directory.\n";
+    }
 }
-die $usage if @ARGV;
+
+
+# Now read the file and process the contents
 
 open my $config_read, '<', $config_file or die "read $config_file: $!\n";
 my @config_lines = <$config_read>;
@@ -117,14 +204,49 @@
             $line .= "\n";
             $done = 1;
         }
+    } elsif (!$done && $action eq "get") {
+        if ($line =~ /^\s*#define\s*$name\s*(.*)\s*\b/) {
+            $value = $1;
+            $done = 1;
+        }
     }
 
     print $config_write $line;
 }
 
+# Did the set command work?
+if ($action eq "set"&& $force_option && !$done) {
+
+    # If the force option was set, append the symbol to the end of the file
+    my $line = "#define $name";
+    $line .= " $value" if defined $value && $value ne "";
+    $line .= "\n";
+    $done = 1;
+
+    print $config_write $line;
+}
+
 close $config_write;
 
-die "configuration section not found" if ($action eq "full" && !$done);
-die "$name not found" if ($action ne "full" && !$done);
+if ($action eq "get") {
+    if($done) {
+        if ($value ne '') {
+            print $value;
+        }
+        exit 0;
+    } else {
+        # If the symbol was not found, return an error
+        exit -1;
+    }
+}
+
+if ($action eq "full" && !$done) {
+    die "Configuration section was not found in $config_file\n";
+
+}
+
+if ($action ne "full" && $action ne "unset" && !$done) {
+    die "A #define for the symbol $name was not found in $config_file\n";
+}
 
 __END__
diff --git a/scripts/data_files/error.fmt b/scripts/data_files/error.fmt
index bd6ef01..a08742c 100644
--- a/scripts/data_files/error.fmt
+++ b/scripts/data_files/error.fmt
@@ -34,6 +34,7 @@
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
+#define mbedtls_time_t   time_t
 #endif
 
 #if defined(MBEDTLS_ERROR_C)
diff --git a/scripts/footprint.sh b/scripts/footprint.sh
index 87d62df..026e7a8 100755
--- a/scripts/footprint.sh
+++ b/scripts/footprint.sh
@@ -1,5 +1,23 @@
 #!/bin/sh
-
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# This script determines ROM size (or code size) for the standard mbed TLS
+# configurations, when built for a Cortex M3/M4 target.
+#
+# Configurations included:
+#   default    include/mbedtls/config.h
+#   yotta      yotta/module/mbedtls/config.h
+#   thread     configs/config-thread.h
+#   suite-b    configs/config-suite-b.h
+#   psk        configs/config-ccm-psk-tls1_2.h
+#
+# Usage: footprint.sh
+#
 set -eu
 
 CONFIG_H='include/mbedtls/config.h'
@@ -48,6 +66,7 @@
         scripts/config.pl unset MBEDTLS_NET_C || true
         scripts/config.pl unset MBEDTLS_TIMING_C || true
         scripts/config.pl unset MBEDTLS_FS_IO || true
+        scripts/config.pl --force set MBEDTLS_NO_PLATFORM_ENTROPY || true
     } >/dev/null 2>&1
 
     CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld \
diff --git a/scripts/rename.pl b/scripts/rename.pl
index c169078..c29519e 100755
--- a/scripts/rename.pl
+++ b/scripts/rename.pl
@@ -1,12 +1,25 @@
 #!/usr/bin/perl
-
-# rename identifiers (functions, types, enum constant, etc)
-# on upgrades of major version according to a list
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# This script migrates application source code from the mbed TLS 1.3 API to the
+# mbed TLS 2.0 API.
+#
+# The script processes the given source code and renames identifiers - functions
+# types, enums etc, as
+#
+# Usage:  rename.pl [-f datafile] [-s] [--] [filenames...]
+#
 
 use warnings;
 use strict;
 
 use utf8;
+use Path::Class;
 use open qw(:std utf8);
 
 my $usage = "Usage: $0 [-f datafile] [-s] [--] [filenames...]\n";
@@ -45,15 +58,28 @@
 my $idnum = qr/[a-zA-Z0-9_]+/;
 my $symbols = qr/[-!#\$%&'()*+,.\/:;<=>?@[\\\]^_`{|}~]+|"/;
 
+my $lib_include_dir = dir($0)->parent->parent->subdir('include', 'mbedtls');
+my $lib_source_dir = dir($0)->parent->parent->subdir('library');
+
 # if we replace inside strings, we don't consider them a token
 my $token = $do_strings ?         qr/$space|$idnum|$symbols/
                         : qr/$string|$space|$idnum|$symbols/;
 
 my %warnings;
 
+# If no files were passed, exit...
+if ( not defined($ARGV[0]) ){ die $usage; }
+
 while( my $filename = shift )
 {
     print STDERR "$filename... ";
+
+    if( dir($filename)->parent eq $lib_include_dir ||
+         dir($filename)->parent eq $lib_source_dir )
+    {
+        die "Script cannot be executed on the mbed TLS library itself.";
+    }
+
     if( -d $filename ) { print STDERR "skip (directory)\n"; next }
 
     open my $rfh, '<', $filename or die;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 1cca818..a004a3d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -10,6 +10,11 @@
     set(libs ${libs} ${ZLIB_LIBRARIES})
 endif(ENABLE_ZLIB_SUPPORT)
 
+find_package(Perl)
+if(NOT PERL_FOUND)
+    message(FATAL_ERROR "Cannot build test suites without Perl")
+endif()
+
 function(add_test_suite suite_name)
     if(ARGV1)
         set(data_name ${ARGV1})
@@ -19,7 +24,7 @@
 
     add_custom_command(
         OUTPUT test_suite_${data_name}.c
-        COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_code.pl ${CMAKE_CURRENT_SOURCE_DIR}/suites test_suite_${suite_name} test_suite_${data_name}
+        COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_code.pl ${CMAKE_CURRENT_SOURCE_DIR}/suites test_suite_${suite_name} test_suite_${data_name}
         DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_code.pl mbedtls suites/helpers.function suites/main_test.function suites/test_suite_${suite_name}.function suites/test_suite_${data_name}.data
     )
 
@@ -82,6 +87,7 @@
 add_test_suite(memory_buffer_alloc)
 add_test_suite(mpi)
 add_test_suite(pem)
+add_test_suite(pkcs1_v15)
 add_test_suite(pkcs1_v21)
 add_test_suite(pkcs5)
 add_test_suite(pk)
diff --git a/tests/Makefile b/tests/Makefile
index c5172e4..58c404e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -76,7 +76,7 @@
 	test_suite_md$(EXEXT)		test_suite_mdx$(EXEXT)		\
 	test_suite_memory_buffer_alloc$(EXEXT)				\
 	test_suite_mpi$(EXEXT)						\
-	test_suite_pem$(EXEXT)						\
+	test_suite_pem$(EXEXT)			test_suite_pkcs1_v15$(EXEXT)	\
 	test_suite_pkcs1_v21$(EXEXT)	test_suite_pkcs5$(EXEXT)	\
 	test_suite_pkparse$(EXEXT)	test_suite_pkwrite$(EXEXT)	\
 	test_suite_pk$(EXEXT)						\
@@ -376,6 +376,10 @@
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test_suite_pkcs1_v15$(EXEXT): test_suite_pkcs1_v15.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 test_suite_pkcs1_v21$(EXEXT): test_suite_pkcs1_v21.c $(DEP)
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/tests/compat.sh b/tests/compat.sh
index 4b43e33..a333a19 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -45,7 +45,7 @@
 fi
 
 # default values for options
-MODES="ssl3 tls1 tls1_1 tls1_2 dtls1 dtls1_2"
+MODES="tls1 tls1_1 tls1_2 dtls1 dtls1_2"
 VERIFIES="NO YES"
 TYPES="ECDSA RSA PSK"
 FILTER=""
diff --git a/tests/data_files/server5-der0.crt b/tests/data_files/server5-der0.crt
new file mode 100644
index 0000000..08d8dd3
--- /dev/null
+++ b/tests/data_files/server5-der0.crt
Binary files differ
diff --git a/tests/data_files/server5-der1a.crt b/tests/data_files/server5-der1a.crt
new file mode 100644
index 0000000..015017b
--- /dev/null
+++ b/tests/data_files/server5-der1a.crt
Binary files differ
diff --git a/tests/data_files/server5-der1b.crt b/tests/data_files/server5-der1b.crt
new file mode 100644
index 0000000..6340d9e
--- /dev/null
+++ b/tests/data_files/server5-der1b.crt
Binary files differ
diff --git a/tests/data_files/server5-der2.crt b/tests/data_files/server5-der2.crt
new file mode 100644
index 0000000..c6e320a
--- /dev/null
+++ b/tests/data_files/server5-der2.crt
Binary files differ
diff --git a/tests/data_files/server5-der4.crt b/tests/data_files/server5-der4.crt
new file mode 100644
index 0000000..4af05cc
--- /dev/null
+++ b/tests/data_files/server5-der4.crt
Binary files differ
diff --git a/tests/data_files/server5-der8.crt b/tests/data_files/server5-der8.crt
new file mode 100644
index 0000000..65be7dc
--- /dev/null
+++ b/tests/data_files/server5-der8.crt
Binary files differ
diff --git a/tests/data_files/server5-der9.crt b/tests/data_files/server5-der9.crt
new file mode 100644
index 0000000..4947f1f
--- /dev/null
+++ b/tests/data_files/server5-der9.crt
Binary files differ
diff --git a/tests/data_files/test-ca2_cat-future-present.crt b/tests/data_files/test-ca2_cat-future-present.crt
new file mode 100644
index 0000000..776e725
--- /dev/null
+++ b/tests/data_files/test-ca2_cat-future-present.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIB+zCCAYCgAwIBAgIBATAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTAe
+Fw0yMzA5MjIxNTQ5NDlaFw0zMDEyMzEyMzU5NTlaMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTB2
+MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBuww5XUzM5
+WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiyaY7zQa0p
+w7RfdadHb9UZKVVpmlM7ILRmFmAzHqNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4E
+FgQUnW0gJEkBPyvLeLUZvH4kydv7NnwwHwYDVR0jBBgwFoAUnW0gJEkBPyvLeLUZ
+vH4kydv7NnwwDAYIKoZIzj0EAwIFAANnADBkAjB1ZNdOM7KRJiPo45hP17A1sJSH
+qHFPEJbml6KdNevoVZ1HqvP8AoFGcPJRpQVtzC0CMDa7JEqn0dOss8EmW9pVF/N2
++XvzNczj89mWMgPhJJlT+MONQx3LFQO+TMSI9hLdkw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu
+ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy
+aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g
+JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7
+NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE
+AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w
+CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56
+t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv
+uCjn8pwUOkABXK8Mss90fzCfCEOtIA==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca2_cat-past-present.crt b/tests/data_files/test-ca2_cat-past-present.crt
new file mode 100644
index 0000000..bc1ba9a
--- /dev/null
+++ b/tests/data_files/test-ca2_cat-past-present.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIB/TCCAYCgAwIBAgIBATAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTAe
+Fw0wMzA5MjQxNTQ5NDhaFw0xMzA5MjQxNTQ5NDhaMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTB2
+MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBuww5XUzM5
+WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiyaY7zQa0p
+w7RfdadHb9UZKVVpmlM7ILRmFmAzHqNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4E
+FgQUnW0gJEkBPyvLeLUZvH4kydv7NnwwHwYDVR0jBBgwFoAUnW0gJEkBPyvLeLUZ
+vH4kydv7NnwwDAYIKoZIzj0EAwIFAANpADBmAjEAvQ/49lXXrLYdOIGtTaYWjpZP
+tRBXQiGPMzUvmKBk7gM7bF4iFPsdJikyXHmuwv3RAjEA8vtUX8fAAB3fbh5dEXRm
+l7tz0Sw/RW6AHFtaIauGkhHqeKIaKIi6WSgHu6x97uyg
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu
+ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy
+aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g
+JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7
+NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE
+AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w
+CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56
+t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv
+uCjn8pwUOkABXK8Mss90fzCfCEOtIA==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca2_cat-present-future.crt b/tests/data_files/test-ca2_cat-present-future.crt
new file mode 100644
index 0000000..d62ed09
--- /dev/null
+++ b/tests/data_files/test-ca2_cat-present-future.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu
+ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy
+aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g
+JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7
+NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE
+AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w
+CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56
+t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv
+uCjn8pwUOkABXK8Mss90fzCfCEOtIA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB+zCCAYCgAwIBAgIBATAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTAe
+Fw0yMzA5MjIxNTQ5NDlaFw0zMDEyMzEyMzU5NTlaMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTB2
+MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBuww5XUzM5
+WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiyaY7zQa0p
+w7RfdadHb9UZKVVpmlM7ILRmFmAzHqNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4E
+FgQUnW0gJEkBPyvLeLUZvH4kydv7NnwwHwYDVR0jBBgwFoAUnW0gJEkBPyvLeLUZ
+vH4kydv7NnwwDAYIKoZIzj0EAwIFAANnADBkAjB1ZNdOM7KRJiPo45hP17A1sJSH
+qHFPEJbml6KdNevoVZ1HqvP8AoFGcPJRpQVtzC0CMDa7JEqn0dOss8EmW9pVF/N2
++XvzNczj89mWMgPhJJlT+MONQx3LFQO+TMSI9hLdkw==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca2_cat-present-past.crt b/tests/data_files/test-ca2_cat-present-past.crt
new file mode 100644
index 0000000..a321d5d
--- /dev/null
+++ b/tests/data_files/test-ca2_cat-present-past.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF
+QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu
+ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy
+aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g
+JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7
+NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE
+AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w
+CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56
+t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv
+uCjn8pwUOkABXK8Mss90fzCfCEOtIA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB/TCCAYCgAwIBAgIBATAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTAe
+Fw0wMzA5MjQxNTQ5NDhaFw0xMzA5MjQxNTQ5NDhaMD4xCzAJBgNVBAYTAk5MMREw
+DwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQTB2
+MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBuww5XUzM5
+WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiyaY7zQa0p
+w7RfdadHb9UZKVVpmlM7ILRmFmAzHqNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4E
+FgQUnW0gJEkBPyvLeLUZvH4kydv7NnwwHwYDVR0jBBgwFoAUnW0gJEkBPyvLeLUZ
+vH4kydv7NnwwDAYIKoZIzj0EAwIFAANpADBmAjEAvQ/49lXXrLYdOIGtTaYWjpZP
+tRBXQiGPMzUvmKBk7gM7bF4iFPsdJikyXHmuwv3RAjEA8vtUX8fAAB3fbh5dEXRm
+l7tz0Sw/RW6AHFtaIauGkhHqeKIaKIi6WSgHu6x97uyg
+-----END CERTIFICATE-----
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d96615b..5262397 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1,15 +1,25 @@
 #!/bin/sh
 
-# Run all available tests (mostly).
+# all.sh
 #
-# Warning: includes various build modes, so it will mess with the current
-# CMake configuration. After this script is run, the CMake cache is lost and
-# CMake is not initialised any more!
+# This file is part of mbed TLS (https://tls.mbed.org)
 #
-# Assumes gcc and clang (recent enough for using ASan with gcc and MemSan with
-# clang, or valgrind) are available, as well as cmake and a "good" find.
+# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To run all tests possible or available on the platform.
+#
+# Warning: the test is destructive. It includes various build modes and
+# configurations, and can and will arbitrarily change the current CMake
+# configuration. After this script has been run, the CMake cache will be lost
+# and CMake will no longer be initialised.
+#
+# The script assumes the presence of gcc and clang (recent enough for using
+# ASan with gcc and MemSan with clang, or valgrind) are available, as well as
+# cmake and a "good" find.
 
-# Abort on errors (and uninitiliased variables)
+# Abort on errors (and uninitialised variables)
 set -eu
 
 if [ -d library -a -d include -a -d tests ]; then :; else
@@ -21,20 +31,17 @@
 CONFIG_BAK="$CONFIG_H.bak"
 
 MEMORY=0
+SHORT=0
+FORCE=0
 
-while [ $# -gt 0 ]; do
-    case "$1" in
-        -m*)
-            MEMORY=${1#-m}
-            ;;
-        *)
-            echo "Unknown argument: '$1'" >&2
-            echo "Use the source, Luke!" >&2
-            exit 1
-            ;;
-    esac
-    shift
-done
+usage()
+{
+    echo "Usage: $0"
+    echo -e "  -h|--help\t\tPrint this help."
+    echo -e "  -m|--memory\t\tAdditional optional memory tests."
+    echo -e "  -s|--short\t\tSubset of tests."
+    echo -e "  -f|--force\t\tForce the tests to overwrite any modified files."
+}
 
 # remove built files as well as the cmake cache/config
 cleanup()
@@ -62,6 +69,50 @@
     echo "******************************************************************"
 }
 
+while [ $# -gt 0 ]; do
+    case "$1" in
+        --memory|-m*)
+            MEMORY=${1#-m}
+            ;;
+        --short|-s)
+            SHORT=1
+            ;;
+        --force|-f)
+            FORCE=1
+            ;;
+        --help|-h|*)
+            usage()
+            exit 1
+            ;;
+    esac
+    shift
+done
+
+if [ $FORCE -eq 1 ]; then
+    rm -rf yotta/module
+    git checkout-index -f -q $CONFIG_H
+    cleanup
+else
+
+    if [ -d yotta/module ]; then
+        echo "Warning - there is an existing yotta module in the directory 'yotta/module'" >&2
+        echo "You can either delete your work and retry, or force the test to overwrite the"
+        echo "test by rerunning the script as: $0 --force"
+        exit 1
+    fi
+
+    if ! git diff-files --quiet include/mbedtls/config.h; then
+        echo $?
+        echo "Warning - the configuration file 'include/mbedtls/config.h' has been edited. " >&2
+        echo "You can either delete or preserve your work, or force the test by rerunning the"
+        echo "script as: $0 --force"
+        exit 1
+    fi
+fi
+
+#
+# Test Suites to be executed
+#
 # The test ordering tries to optimize for the following criteria:
 # 1. Catch possible problems early, by running first tests that run quickly
 #    and/or are more likely to fail than others (eg I use Clang most of the
@@ -83,6 +134,12 @@
 cleanup
 tests/scripts/check-names.sh
 
+if which doxygen >/dev/null; then
+    msg "test: doxygen warnings" # ~ 3s
+    cleanup
+    tests/scripts/doxygen.sh
+fi
+
 msg "build: create and build yotta module" # ~ 30s
 cleanup
 tests/scripts/yotta-build.sh
@@ -103,6 +160,11 @@
 tests/scripts/test-ref-configs.pl
 
 # Most frequent issues are likely to be caught at this point
+if [ $SHORT -eq 1 ]; then
+    msg "Done, cleaning up"
+    cleanup
+    exit 0
+fi
 
 msg "build: with ASan (rebuild after ref-configs)" # ~ 1 min
 make
@@ -110,6 +172,23 @@
 msg "test: compat.sh (ASan build)" # ~ 6 min
 tests/compat.sh
 
+msg "build: Default + SSLv3 (ASan build)" # ~ 6 min
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl set MBEDTLS_SSL_PROTO_SSL3
+CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+make
+
+msg "test: SSLv3 - main suites and selftest (ASan build)" # ~ 50s
+make test
+programs/test/selftest
+
+msg "build: SSLv3 - compat.sh (ASan build)" # ~ 6 min
+tests/compat.sh -m 'ssl3 tls1 tls1_1 tls1_2 dtls1 dtls1_2'
+
+msg "build: SSLv3 - ssl-opt.sh (ASan build)" # ~ 6 min
+tests/ssl-opt.sh
+
 msg "build: cmake, full config, clang" # ~ 50s
 cleanup
 cp "$CONFIG_H" "$CONFIG_BAK"
@@ -153,6 +232,7 @@
 scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT
 scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT
 scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
 scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
 scripts/config.pl unset MBEDTLS_FS_IO
 CC=gcc CFLAGS='-Werror -O0' make
@@ -163,6 +243,7 @@
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
 scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
 CC=gcc CFLAGS='-Werror -O0' make
 
 msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
@@ -187,6 +268,22 @@
 scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
 CC=gcc CFLAGS='-Werror -O0 -std=c99 -pedantic' make lib
 
+msg "build: default config with  MBEDTLS_TEST_NULL_ENTROPY (ASan build)"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl set MBEDTLS_TEST_NULL_ENTROPY
+scripts/config.pl set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+scripts/config.pl set MBEDTLS_ENTROPY_C
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+scripts/config.pl unset MBEDTLS_ENTROPY_HARDWARE_ALT
+scripts/config.pl unset MBEDTLS_HAVEGE_C
+CC=gcc cmake  -D UNSAFE_BUILD=ON -D CMAKE_C_FLAGS:String="-fsanitize=address -fno-common -O3" .
+make
+
+msg "test: MBEDTLS_TEST_NULL_ENTROPY - main suites and selftest (ASan build)"
+make test
+programs/test/selftest
+
 if uname -a | grep -F Linux >/dev/null; then
 msg "build/test: make shared" # ~ 40s
 cleanup
@@ -207,6 +304,8 @@
 scripts/config.pl unset MBEDTLS_NET_C
 scripts/config.pl unset MBEDTLS_TIMING_C
 scripts/config.pl unset MBEDTLS_FS_IO
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
 # following things are not in the default config
 scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
 scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
@@ -224,8 +323,10 @@
 scripts/config.pl unset MBEDTLS_NET_C
 scripts/config.pl unset MBEDTLS_TIMING_C
 scripts/config.pl unset MBEDTLS_FS_IO
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
 scripts/config.pl unset MBEDTLS_HAVE_TIME
 scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE
+scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
 # following things are not in the default config
 scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING
 scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
@@ -233,7 +334,7 @@
 scripts/config.pl unset MBEDTLS_THREADING_C
 scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
 scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
-CC=armcc WARNING_CFLAGS= make lib 2> armcc.stderr
+CC=armcc AR=armar WARNING_CFLAGS= make lib 2> armcc.stderr
 if [ -s armcc.stderr ]; then
     cat armcc.stderr
     exit 1;
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
new file mode 100755
index 0000000..9fab396
--- /dev/null
+++ b/tests/scripts/basic-build-test.sh
@@ -0,0 +1,215 @@
+#!/bin/sh
+
+# basic-build-tests.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Executes the basic test suites, captures the results, and generates a simple
+# test report and code coverage report.
+#
+# The tests include:
+#   * Self-tests                - executed using program/test/selftest
+#   * Unit tests                - executed using tests/scripts/run-test-suite.pl
+#   * System tests              - executed using tests/ssl-opt.sh
+#   * Interoperability tests    - executed using tests/compat.sh
+#
+# The tests focus on functionality and do not consider performance.
+#
+# Note the tests self-adapt due to configurations in include/mbedtls/config.h
+# which can lead to some tests being skipped, and can cause the number of
+# available self-tests to fluctuate.
+#
+# This script has been written to be generic and should work on any shell.
+#
+# Usage: basic-build-tests.sh
+#
+
+# Abort on errors (and uninitiliased variables)
+set -eu
+
+if [ -d library -a -d include -a -d tests ]; then :; else
+    echo "Must be run from mbed TLS root" >&2
+    exit 1
+fi
+
+CONFIG_H='include/mbedtls/config.h'
+CONFIG_BAK="$CONFIG_H.bak"
+
+# Step 1 - Make and instrumented build for code coverage
+export CFLAGS=' --coverage -g3 -O0 '
+make clean
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+make -j
+
+
+# Step 2 - Execute the tests
+TEST_OUTPUT=out_${PPID}
+cd tests
+
+# Step 2a - Self-tests
+../programs/test/selftest |tee self-test-$TEST_OUTPUT
+echo
+
+# Step 2b - Unit Tests
+perl scripts/run-test-suites.pl -v |tee unit-test-$TEST_OUTPUT
+echo
+
+# Step 2c - System Tests
+sh ssl-opt.sh |tee sys-test-$TEST_OUTPUT
+echo
+
+# Step 2d - Compatibility tests
+sh compat.sh |tee compat-test-$TEST_OUTPUT
+echo
+
+# Step 3 - Process the coverage report
+cd ..
+make lcov |tee tests/cov-$TEST_OUTPUT
+
+
+# Step 4 - Summarise the test report
+echo
+echo "========================================================================="
+echo "Test Report Summary"
+echo
+
+cd tests
+
+# Step 4a - Self-tests
+echo "Self tests - ./programs/test/selftest"
+
+PASSED_TESTS=$(grep 'passed' self-test-$TEST_OUTPUT |wc -l)
+FAILED_TESTS=$(grep 'failed' self-test-$TEST_OUTPUT |wc -l)
+AVAIL_TESTS=$(($PASSED_TESTS + $FAILED_TESTS))
+EXED_TESTS=$(($PASSED_TESTS + $FAILED_TESTS))
+
+echo "Passed             : $PASSED_TESTS"
+echo "Failed             : $FAILED_TESTS"
+echo "Skipped            : n/a"
+echo "Total tests        : $AVAIL_TESTS"
+echo
+
+TOTAL_PASS=$PASSED_TESTS
+TOTAL_FAIL=$FAILED_TESTS
+TOTAL_SKIP=0
+TOTAL_AVAIL=$(($PASSED_TESTS + $FAILED_TESTS))
+TOTAL_EXED=$(($PASSED_TESTS + $FAILED_TESTS))
+
+
+# Step 4b - Unit tests
+echo "Unit tests - tests/scripts/run-test-suites.pl"
+
+PASSED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/test cases passed :[\t]*\([0-9]*\)/\1/p'| tr -d ' ')
+SKIPPED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/skipped :[ \t]*\([0-9]*\)/\1/p'| tr -d ' ')
+TOTAL_SUITES=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) .*, [0-9]* tests run)/\1/p'| tr -d ' ')
+FAILED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/failed :[\t]*\([0-9]*\)/\1/p' |tr -d ' ')
+
+echo "No test suites     : $TOTAL_SUITES"
+echo "Passed             : $PASSED_TESTS"
+echo "Failed             : $FAILED_TESTS"
+echo "Skipped            : $SKIPPED_TESTS"
+echo "Total exec'd tests : $(($PASSED_TESTS + $FAILED_TESTS))"
+echo "Total avail tests  : $(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+TOTAL_AVAIL=$(($TOTAL_AVAIL + $PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($TOTAL_EXED + $PASSED_TESTS + $FAILED_TESTS))
+
+
+# Step 4c - TLS Options tests
+echo "TLS Options tests - tests/ssl-opt.sh"
+
+PASSED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p')
+SKIPPED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p')
+TOTAL_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p')
+FAILED_TESTS=$(($TOTAL_TESTS - $PASSED_TESTS))
+
+echo "Passed             : $PASSED_TESTS"
+echo "Failed             : $FAILED_TESTS"
+echo "Skipped            : $SKIPPED_TESTS"
+echo "Total exec'd tests : $TOTAL_TESTS"
+echo "Total avail tests  : $(($TOTAL_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+TOTAL_AVAIL=$(($TOTAL_AVAIL + $TOTAL_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($TOTAL_EXED + $TOTAL_TESTS))
+
+
+# Step 4d - System Compatibility tests
+echo "System/Compatibility tests - tests/compat.sh"
+
+PASSED_TESTS=$(tail -n5 compat-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p')
+SKIPPED_TESTS=$(tail -n5 compat-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p')
+EXED_TESTS=$(tail -n5 compat-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p')
+FAILED_TESTS=$(($EXED_TESTS - $PASSED_TESTS))
+
+echo "Passed             : $PASSED_TESTS"
+echo "Failed             : $FAILED_TESTS"
+echo "Skipped            : $SKIPPED_TESTS"
+echo "Total exec'd tests : $EXED_TESTS"
+echo "Total avail tests  : $(($EXED_TESTS + $SKIPPED_TESTS))"
+echo
+
+TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+TOTAL_AVAIL=$(($TOTAL_AVAIL + $EXED_TESTS + $SKIPPED_TESTS))
+TOTAL_EXED=$(($TOTAL_EXED + $EXED_TESTS))
+
+
+# Step 4e - Grand totals
+echo "-------------------------------------------------------------------------"
+echo "Total tests"
+
+echo "Total Passed       : $TOTAL_PASS"
+echo "Total Failed       : $TOTAL_FAIL"
+echo "Total Skipped      : $TOTAL_SKIP"
+echo "Total exec'd tests : $TOTAL_EXED"
+echo "Total avail tests  : $TOTAL_AVAIL"
+echo
+
+
+# Step 4f - Coverage
+echo "Coverage"
+
+LINES_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* lines)/\1/p')
+LINES_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) lines)/\1/p')
+FUNCS_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* functions)$/\1/p')
+FUNCS_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) functions)$/\1/p')
+
+LINES_PERCENT=$((1000*$LINES_TESTED/$LINES_TOTAL))
+LINES_PERCENT="$(($LINES_PERCENT/10)).$(($LINES_PERCENT-($LINES_PERCENT/10)*10))"
+
+FUNCS_PERCENT=$((1000*$FUNCS_TESTED/$FUNCS_TOTAL))
+FUNCS_PERCENT="$(($FUNCS_PERCENT/10)).$(($FUNCS_PERCENT-($FUNCS_PERCENT/10)*10))"
+
+echo "Lines Tested       : $LINES_TESTED of $LINES_TOTAL $LINES_PERCENT%"
+echo "Functions Tested   : $FUNCS_TESTED of $FUNCS_TOTAL $FUNCS_PERCENT%"
+echo
+
+
+rm self-test-$TEST_OUTPUT
+rm unit-test-$TEST_OUTPUT
+rm sys-test-$TEST_OUTPUT
+rm compat-test-$TEST_OUTPUT
+rm cov-$TEST_OUTPUT
+
+cd ..
+
+make clean
+
+if [ -f "$CONFIG_BAK" ]; then
+    mv "$CONFIG_BAK" "$CONFIG_H"
+fi
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
index 7e67cef..191594c 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -1,7 +1,23 @@
 #!/bin/sh
-
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# This script confirms that the naming of all symbols and identifiers in mbed
+# TLS are consistent with the house style and are also self-consistent.
+#
 set -eu
 
+if grep --version|head -n1|grep GNU >/dev/null; then :; else
+    echo "This script requires GNU grep."
+    exit 1
+fi
+
+printf "Analysing source code...\n"
+
 tests/scripts/list-macros.sh
 tests/scripts/list-enum-consts.pl
 tests/scripts/list-identifiers.sh
@@ -9,7 +25,7 @@
 
 FAIL=0
 
-printf "Exported symbols declared in header: "
+printf "\nExported symbols declared in header: "
 UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' )
 if [ "x$UNDECLARED" = "x" ]; then
     echo "PASS"
@@ -24,7 +40,7 @@
 for THING in actual-macros enum-consts; do
     printf "Names of $THING: "
     test -r $THING
-    BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
+    BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$\|^YOTTA_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
     if [ "x$BAD" = "x" ]; then
         echo "PASS"
     else
@@ -66,6 +82,7 @@
     FAIL=1
 fi
 
+printf "\nOverall: "
 if [ "$FAIL" -eq 0 ]; then
     rm macros actual-macros enum-consts identifiers exported-symbols
     echo "PASSED"
diff --git a/tests/scripts/curves.pl b/tests/scripts/curves.pl
index 654bc5c..85eb7e6 100755
--- a/tests/scripts/curves.pl
+++ b/tests/scripts/curves.pl
@@ -1,10 +1,25 @@
 #!/usr/bin/perl
 
-# test dependencies on individual curves in tests
-# - build
-# - run test suite
+# curves.pl
 #
-# Usage: tests/scripts/curves.pl
+# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# To test the code dependencies on individual curves in each test suite. This
+# is a verification step to ensure we don't ship test suites that do not work
+# for some build options.
+#
+# The process is:
+#       for each possible curve
+#           build the library and test suites with the curve disabled
+#           execute the test suites
+#
+# And any test suite with the wrong dependencies will fail.
+#
+# Usage: curves.pl
+#
+# This script should be executed from the root of the project directory.
 
 use warnings;
 use strict;
diff --git a/tests/scripts/doxygen.sh b/tests/scripts/doxygen.sh
new file mode 100755
index 0000000..e7758c9
--- /dev/null
+++ b/tests/scripts/doxygen.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Make sure the doxygen documentation builds without warnings
+
+# Abort on errors (and uninitiliased variables)
+set -eu
+
+if [ -d library -a -d include -a -d tests ]; then :; else
+    echo "Must be run from mbed TLS root" >&2
+    exit 1
+fi
+
+if scripts/apidoc_full.sh > doc.out 2>doc.err; then :; else
+    cat doc.err
+    echo "FAIL" >&2
+    exit 1;
+fi
+
+cat doc.out doc.err | \
+    grep -v "warning: ignoring unsupported tag" \
+    > doc.filtered
+
+if egrep "(warning|error):" doc.filtered; then
+    echo "FAIL" >&2
+    exit 1;
+fi
+
+make apidoc_clean
+rm -f doc.out doc.err doc.filtered
diff --git a/tests/scripts/generate-afl-tests.sh b/tests/scripts/generate-afl-tests.sh
new file mode 100755
index 0000000..cbc2f59
--- /dev/null
+++ b/tests/scripts/generate-afl-tests.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+# This script splits the data test files containing the test cases into
+# individual files (one test case per file) suitable for use with afl
+# (American Fuzzy Lop). http://lcamtuf.coredump.cx/afl/
+#
+# Usage: generate-afl-tests.sh <test data file path>
+#  <test data file path> - should be the path to one of the test suite files
+#                          such as 'test_suite_mpi.data'
+
+# Abort on errors
+set -e
+
+if [ -z $1 ]
+then
+    echo " [!] No test file specified" >&2
+    echo "Usage: $0 <test data file>" >&2
+    exit 1
+fi
+
+SRC_FILEPATH=$(dirname $1)/$(basename $1)
+TESTSUITE=$(basename $1 .data)
+
+THIS_DIR=$(basename $PWD)
+
+if [ -d ../library -a -d ../include -a -d ../tests -a $THIS_DIR == "tests" ];
+then :;
+else
+    echo " [!] Must be run from mbed TLS tests directory" >&2
+    exit 1
+fi
+
+DEST_TESTCASE_DIR=$TESTSUITE-afl-tests
+DEST_OUTPUT_DIR=$TESTSUITE-afl-out
+
+echo " [+] Creating output directories" >&2
+
+if [ -e $DEST_OUTPUT_DIR/* ];
+then :
+    echo " [!] Test output files already exist." >&2
+    exit 1
+else
+    mkdir -p $DEST_OUTPUT_DIR
+fi
+
+if [ -e $DEST_TESTCASE_DIR/* ];
+then :
+    echo " [!] Test output files already exist." >&2
+else
+    mkdir -p $DEST_TESTCASE_DIR
+fi
+
+echo " [+] Creating test cases" >&2
+cd $DEST_TESTCASE_DIR
+
+split -p '^\s*$' ../$SRC_FILEPATH
+
+for f in *;
+do
+    # Strip out any blank lines (no trim on OS X)
+    sed '/^\s*$/d' $f >testcase_$f
+    rm $f
+done
+
+cd ..
+
+echo " [+] Test cases in $DEST_TESTCASE_DIR" >&2
+
diff --git a/tests/scripts/generate_code.pl b/tests/scripts/generate_code.pl
index 1c7a281..49af2db 100755
--- a/tests/scripts/generate_code.pl
+++ b/tests/scripts/generate_code.pl
@@ -1,4 +1,53 @@
 #!/usr/bin/env perl
+
+# generate_code.pl
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Generates the test suite code given inputs of the test suite directory that
+# contain the test suites, and the test suite file names for the test code and
+# test data.
+#
+# Usage: generate_code.pl <suite dir> <code file> <data file> [main code file]
+#
+# Structure of files
+#
+#   - main code file - 'main_test.function'
+#       Template file that contains the main() function for the test suite,
+#       test dispatch code as well as support functions. It contains the
+#       following symbols which are substituted by this script during
+#       processing:
+#           TESTCASE_FILENAME
+#           TESTCODE_FILENAME
+#           SUITE_PRE_DEP
+#           MAPPING_CODE
+#           FUNCTION CODE
+#           SUITE_POST_DEP
+#           DEP_CHECK_CODE
+#           DISPATCH_FUNCTION
+#           !LINE_NO!
+#
+#   - common helper code file - 'helpers.function'
+#       Common helper functions
+#
+#   - test suite code file - file name in the form 'test_suite_xxx.function'
+#       Code file that contains the actual test cases. The file contains a
+#       series of code sequences delimited by the following:
+#           BEGIN_HEADER / END_HEADER - list of headers files
+#           BEGIN_SUITE_HELPERS / END_SUITE_HELPERS - helper functions common to
+#               the test suite
+#           BEGIN_CASE / END_CASE - the test cases in the test suite. Each test
+#               case contains at least one function that is used to create the
+#               dispatch code.
+#
+#   - test data file - file name in the form 'test_suite_xxxx.data'
+#       The test case parameters to to be used in execution of the test. The
+#       file name is used to replace the symbol 'TESTCASE_FILENAME' in the main
+#       code file above.
 #
 
 use strict;
@@ -8,31 +57,69 @@
 my $data_name = shift or die "Missing data name";
 my $test_main_file = do { my $arg = shift; defined($arg) ? $arg :  $suite_dir."/main_test.function" };
 my $test_file = $data_name.".c";
-my $test_helper_file = $suite_dir."/helpers.function";
+my $test_common_helper_file = $suite_dir."/helpers.function";
 my $test_case_file = $suite_dir."/".$suite_name.".function";
 my $test_case_data = $suite_dir."/".$data_name.".data";
 
 my $line_separator = $/;
 undef $/;
 
-open(TEST_HELPERS, "$test_helper_file") or die "Opening test helpers '$test_helper_file': $!";
-my $test_helpers = <TEST_HELPERS>;
+
+#
+# Open and read in the input files
+#
+
+open(TEST_HELPERS, "$test_common_helper_file") or die "Opening test helpers
+'$test_common_helper_file': $!";
+my $test_common_helpers = <TEST_HELPERS>;
 close(TEST_HELPERS);
 
 open(TEST_MAIN, "$test_main_file") or die "Opening test main '$test_main_file': $!";
-my $test_main = <TEST_MAIN>;
+my @test_main_lines = split/^/,  <TEST_MAIN>;
+my $test_main;
+my $index = 2;
+for my $line (@test_main_lines) {
+    $line =~ s/!LINE_NO!/$index/;
+    $test_main = $test_main.$line;
+    $index++;
+}
 close(TEST_MAIN);
 
 open(TEST_CASES, "$test_case_file") or die "Opening test cases '$test_case_file': $!";
-my $test_cases = <TEST_CASES>;
+my @test_cases_lines = split/^/,  <TEST_CASES>;
+my $test_cases;
+my $index = 2;
+for my $line (@test_cases_lines) {
+    if ($line =~ /^\/\* BEGIN_SUITE_HELPERS .*\*\//)
+    {
+        $line = $line."#line $index \"$test_case_file\"\n";
+    }
+
+    if ($line =~ /^\/\* BEGIN_CASE .*\*\//)
+    {
+        $line = $line."#line $index \"$test_case_file\"\n";
+    }
+
+    $line =~ s/!LINE_NO!/$index/;
+
+    $test_cases = $test_cases.$line;
+    $index++;
+}
+
 close(TEST_CASES);
 
 open(TEST_DATA, "$test_case_data") or die "Opening test data '$test_case_data': $!";
 my $test_data = <TEST_DATA>;
 close(TEST_DATA);
 
+
+#
+# Find the headers, dependencies, and suites in the test cases file
+#
+
 my ( $suite_header ) = $test_cases =~ /\/\* BEGIN_HEADER \*\/\n(.*?)\n\/\* END_HEADER \*\//s;
 my ( $suite_defines ) = $test_cases =~ /\/\* BEGIN_DEPENDENCIES\n \* (.*?)\n \* END_DEPENDENCIES/s;
+my ( $suite_helpers ) = $test_cases =~ /\/\* BEGIN_SUITE_HELPERS \*\/\n(.*?)\n\/\* END_SUITE_HELPERS \*\//s;
 
 my $requirements;
 if ($suite_defines =~ /^depends_on:/)
@@ -60,16 +147,43 @@
 
 open(TEST_FILE, ">$test_file") or die "Opening destination file '$test_file': $!";
 print TEST_FILE << "END";
+/*
+ * *** THIS FILE HAS BEEN MACHINE GENERATED ***
+ *
+ * This file has been machine generated using the script: $0
+ *
+ * Test file      : $test_file
+ *
+ * The following files were used to create this file.
+ *
+ *      Main code file  : $test_main_file
+ *      Helper file     : $test_common_helper_file
+ *      Test suite file : $test_case_file
+ *      Test suite data : $test_case_data
+ *
+ *
+ *  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
 
-$test_helpers
+
+/*----------------------------------------------------------------------------*/
+/* Common helper code */
+
+$test_common_helpers
+
+
+/*----------------------------------------------------------------------------*/
+/* Test Suite Code */
 
 $suite_pre_code
 $suite_header
+$suite_helpers
 $suite_post_code
 
 END
@@ -83,16 +197,19 @@
     my $function_decl = $2;
 
     # Sanity checks of function
-    if ($function_decl !~ /^void /)
+    if ($function_decl !~ /^#line\s*.*\nvoid /)
     {
-        die "Test function does not have 'void' as return type\n";
+        die "Test function does not have 'void' as return type.\n" .
+            "Function declaration:\n" .
+            $function_decl;
     }
-    if ($function_decl !~ /^void (\w+)\(\s*(.*?)\s*\)\s*{(.*)}/ms)
+    if ($function_decl !~ /^(#line\s*.*)\nvoid (\w+)\(\s*(.*?)\s*\)\s*{(.*)}/ms)
     {
         die "Function declaration not in expected format\n";
     }
-    my $function_name = $1;
-    my $function_params = $2;
+    my $line_directive = $1;
+    my $function_name = $2;
+    my $function_params = $3;
     my $function_pre_code;
     my $function_post_code;
     my $param_defs;
@@ -103,7 +220,7 @@
     my $mapping_regex = "".$function_name;
     my $mapping_count = 0;
 
-    $function_decl =~ s/^void /void test_suite_/;
+    $function_decl =~ s/(^#line\s*.*)\nvoid /$1\nvoid test_suite_/;
 
     # Add exit label if not present
     if ($function_decl !~ /^exit:$/m)
@@ -128,7 +245,7 @@
         if( substr($def, 0, 4) eq "int " )
         {
             $param_defs .= "    int param$i;\n";
-            $param_checks .= "    if( verify_int( params[$i], &param$i ) != 0 ) return( 2 );\n";
+            $param_checks .= "    if( verify_int( params[$i], &param$i ) != 0 ) return( DISPATCH_INVALID_TEST_DATA );\n";
             push @dispatch_params, "param$i";
 
             $mapping_regex .= ":([\\d\\w |\\+\\-\\(\\)]+)";
@@ -137,7 +254,7 @@
         elsif( substr($def, 0, 6) eq "char *" )
         {
             $param_defs .= "    char *param$i = params[$i];\n";
-            $param_checks .= "    if( verify_string( &param$i ) != 0 ) return( 2 );\n";
+            $param_checks .= "    if( verify_string( &param$i ) != 0 ) return( DISPATCH_INVALID_TEST_DATA );\n";
             push @dispatch_params, "param$i";
             $mapping_regex .= ":[^:\n]+";
         }
@@ -174,19 +291,20 @@
     if( cnt != $param_count )
     {
         mbedtls_fprintf( stderr, "\\nIncorrect argument count (%d != %d)\\n", cnt, $param_count );
-        return( 2 );
+        return( DISPATCH_INVALID_TEST_DATA );
     }
 
 $param_checks
     test_suite_$function_name( $call_params );
-    return ( 0 );
+    return ( DISPATCH_TEST_SUCCESS );
 $function_post_code
-    return ( 3 );
+    return ( DISPATCH_UNSUPPORTED_SUITE );
 }
 else
 END
 
-    my $function_code = $function_pre_code . $function_decl . "\n" . $function_post_code;
+    my $function_code = $function_pre_code . $function_decl . "\n" .
+                        $function_post_code;
     $test_main =~ s/FUNCTION_CODE/$function_code\nFUNCTION_CODE/;
 }
 
@@ -209,9 +327,9 @@
     if( strcmp( str, "$key" ) == 0 )
     {
 #if defined($key)
-        return( 0 );
+        return( DEPENDENCY_SUPPORTED );
 #else
-        return( 1 );
+        return( DEPENDENCY_NOT_SUPPORTED );
 #endif
     }
 END
@@ -224,7 +342,7 @@
     if( strcmp( str, "$key" ) == 0 )
     {
         *value = ( $key );
-        return( 0 );
+        return( KEY_VALUE_MAPPING_FOUND );
     }
 END
 
@@ -241,7 +359,8 @@
 
 $dispatch_code =~ s/^(.+)/    $1/mg;
 
-$test_main =~ s/TEST_FILENAME/$test_case_data/;
+$test_main =~ s/TESTCASE_FILENAME/$test_case_data/g;
+$test_main =~ s/TESTCODE_FILENAME/$test_case_file/g;
 $test_main =~ s/FUNCTION_CODE//;
 $test_main =~ s/DEP_CHECK_CODE/$dep_check_code/;
 $test_main =~ s/DISPATCH_FUNCTION/$dispatch_code/;
diff --git a/tests/scripts/run-test-suites.pl b/tests/scripts/run-test-suites.pl
old mode 100644
new mode 100755
index b91355d..58f827c
--- a/tests/scripts/run-test-suites.pl
+++ b/tests/scripts/run-test-suites.pl
@@ -1,12 +1,39 @@
 #!/usr/bin/perl
 
+# run-test-suites.pl
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Executes all the available test suites, and provides a basic summary of the
+# results.
+#
+# Usage: run-test-suites.pl [-v]
+#
+# Options :
+#   -v|--verbose    - Provide a pass/fail/skip breakdown per test suite and
+#                     in total
+#
+
 use warnings;
 use strict;
 
 use utf8;
 use open qw(:std utf8);
 
-my @suites = grep { ! /\.(?:c|gcno)$/ } glob 'test_suite_*';
+use constant FALSE => 0;
+use constant TRUE => 1;
+
+my $verbose;
+my $switch = shift;
+if ( defined($switch) && ( $switch eq "-v" || $switch eq "--verbose" ) ) {
+    $verbose = TRUE;
+}
+
+my @suites = grep { ! /\.(?:c|gcno|gcda|dSYM)$/ } glob 'test_suite_*';
 die "$0: no test suite found\n" unless @suites;
 
 # in case test suites are linked dynamically
@@ -14,22 +41,57 @@
 
 my $prefix = $^O eq "MSWin32" ? '' : './';
 
-my ($failed_suites, $total_tests_run);
+my ($failed_suites, $total_tests_run, $failed, $suite_cases_passed,
+    $suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
+    $total_cases_failed, $total_cases_skipped );
+
 for my $suite (@suites)
 {
     print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
     my $result = `$prefix$suite`;
+
+    $suite_cases_passed = () = $result =~ /.. PASS/g;
+    $suite_cases_failed = () = $result =~ /.. FAILED/g;
+    $suite_cases_skipped = () = $result =~ /.. ----/g;
+
     if( $result =~ /PASSED/ ) {
         print "PASS\n";
-        my ($tests, $skipped) = $result =~ /([0-9]*) tests.*?([0-9]*) skipped/;
-        $total_tests_run += $tests - $skipped;
     } else {
         $failed_suites++;
         print "FAIL\n";
     }
+
+    my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
+    $total_tests_run += $tests - $skipped;
+
+    if ( $verbose ) {
+        print "(test cases passed:", $suite_cases_passed,
+                " failed:", $suite_cases_failed,
+                " skipped:", $suite_cases_skipped,
+                " of total:", ($suite_cases_passed + $suite_cases_failed +
+                               $suite_cases_skipped),
+                ")\n"
+    }
+
+    $total_cases_passed += $suite_cases_passed;
+    $total_cases_failed += $suite_cases_failed;
+    $total_cases_skipped += $suite_cases_skipped;
 }
 
 print "-" x 72, "\n";
 print $failed_suites ? "FAILED" : "PASSED";
 printf " (%d suites, %d tests run)\n", scalar @suites, $total_tests_run;
+
+if ( $verbose ) {
+    print "  test cases passed :", $total_cases_passed, "\n";
+    print "             failed :", $total_cases_failed, "\n";
+    print "            skipped :", $total_cases_skipped, "\n";
+    print "  of tests executed :", ( $total_cases_passed + $total_cases_failed ),
+            "\n";
+    print " of available tests :",
+            ( $total_cases_passed + $total_cases_failed + $total_cases_skipped ),
+            "\n"
+    }
+
 exit( $failed_suites ? 1 : 0 );
+
diff --git a/tests/scripts/travis-log-failure.sh b/tests/scripts/travis-log-failure.sh
new file mode 100755
index 0000000..9866ca7
--- /dev/null
+++ b/tests/scripts/travis-log-failure.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# travis-log-failure.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# List the server and client logs on failed ssl-opt.sh and compat.sh tests.
+# This script is used to make the logs show up in the Travis test results.
+#
+# Some of the logs can be very long: this means usually a couple of megabytes
+# but it can be much more. For example, the client log of test 273 in ssl-opt.sh
+# is more than 630 Megabytes long.
+
+if [ -d include/mbedtls ]; then :; else
+    echo "$0: must be run from root" >&2
+    exit 1
+fi
+
+FILES="o-srv-*.log o-cli-*.log c-srv-*.log c-cli-*.log o-pxy-*.log"
+MAX_LOG_SIZE=1048576
+
+for PATTERN in $FILES; do
+    for LOG in $( ls tests/$PATTERN 2>/dev/null ); do
+        echo
+        echo "****** BEGIN file: $LOG ******"
+        echo
+        tail -c $MAX_LOG_SIZE $LOG
+        echo "****** END file: $LOG ******"
+        echo
+        rm $LOG
+    done
+done
diff --git a/tests/scripts/yotta-build.sh b/tests/scripts/yotta-build.sh
index 0651bae..19cc576 100755
--- a/tests/scripts/yotta-build.sh
+++ b/tests/scripts/yotta-build.sh
@@ -11,8 +11,12 @@
 yotta_build()
 {
     TARGET=$1
-    echo; echo "*** $TARGET ***"
+
+    echo; echo "*** $TARGET (release) ***"
     yt -t $TARGET build
+
+    echo; echo "*** $TARGET (debug) ***"
+    yt -t $TARGET build -d
 }
 
 if uname -a | grep 'Linux.*x86' >/dev/null; then
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index c0b6f94..8635242 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1,12 +1,23 @@
 #!/bin/sh
 
-# Test various options that are not covered by compat.sh
+# ssl-opt.sh
 #
-# Here the goal is not to cover every ciphersuite/version, but
-# rather specific options (max fragment length, truncated hmac, etc)
-# or procedures (session resumption from cache or ticket, renego, etc).
+# This file is part of mbed TLS (https://tls.mbed.org)
 #
-# Assumes a build with default options.
+# Copyright (c) 2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Executes tests to prove various TLS/SSL options and extensions.
+#
+# The goal is not to cover every ciphersuite/version, but instead to cover
+# specific options (max fragment length, truncated hmac, etc) or procedures
+# (session resumption from cache or ticket, renego, etc).
+#
+# The tests assume a build with default options, with exceptions expressed
+# with a dependency.  The tests focus on functionality and do not consider
+# performance.
+#
 
 set -u
 
@@ -33,12 +44,20 @@
 FILTER='.*'
 EXCLUDE='^$'
 
+SHOW_TEST_NUMBER=0
+RUN_TEST_NUMBER=''
+
+PRESERVE_LOGS=0
+
 print_usage() {
     echo "Usage: $0 [options]"
     printf "  -h|--help\tPrint this help.\n"
     printf "  -m|--memcheck\tCheck memory leaks and errors.\n"
     printf "  -f|--filter\tOnly matching tests are executed (default: '$FILTER')\n"
     printf "  -e|--exclude\tMatching tests are excluded (default: '$EXCLUDE')\n"
+    printf "  -n|--number\tExecute only numbered test (comma-separated, e.g. '245,256')\n"
+    printf "  -s|--show-numbers\tShow test numbers in front of test names\n"
+    printf "  -p|--preserve-logs\tPreserve logs of successful tests as well\n"
 }
 
 get_options() {
@@ -53,6 +72,15 @@
             -m|--memcheck)
                 MEMCHECK=1
                 ;;
+            -n|--number)
+                shift; RUN_TEST_NUMBER=$1
+                ;;
+            -s|--show-numbers)
+                SHOW_TEST_NUMBER=1
+                ;;
+            -p|--preserve-logs)
+                PRESERVE_LOGS=1
+                ;;
             -h|--help)
                 print_usage
                 exit 0
@@ -130,6 +158,13 @@
     fi
 }
 
+# skip the next test if valgrind is NOT in use
+only_with_valgrind() {
+    if [ "$MEMCHECK" -eq 0 ]; then
+        SKIP_NEXT="YES"
+    fi
+}
+
 # multiply the client timeout delay by the given factor for the next test
 needs_more_time() {
     CLI_DELAY_FACTOR=$1
@@ -137,12 +172,19 @@
 
 # print_name <name>
 print_name() {
-    printf "$1 "
-    LEN=$(( 72 - `echo "$1" | wc -c` ))
+    TESTS=$(( $TESTS + 1 ))
+    LINE=""
+
+    if [ "$SHOW_TEST_NUMBER" -gt 0 ]; then
+        LINE="$TESTS "
+    fi
+
+    LINE="$LINE$1"
+    printf "$LINE "
+    LEN=$(( 72 - `echo "$LINE" | wc -c` ))
     for i in `seq 1 $LEN`; do printf '.'; done
     printf ' '
 
-    TESTS=$(( $TESTS + 1 ))
 }
 
 # fail <message>
@@ -293,6 +335,13 @@
 
     print_name "$NAME"
 
+    # Do we only run numbered tests?
+    if [ "X$RUN_TEST_NUMBER" = "X" ]; then :
+    elif echo ",$RUN_TEST_NUMBER," | grep ",$TESTS," >/dev/null; then :
+    else
+        SKIP_NEXT="YES"
+    fi
+
     # should we skip?
     if [ "X$SKIP_NEXT" = "XYES" ]; then
         SKIP_NEXT="NO"
@@ -408,32 +457,33 @@
 
     # check other assertions
     # lines beginning with == are added by valgrind, ignore them
+    # lines with 'Serious error when reading debug info', are valgrind issues as well
     while [ $# -gt 0 ]
     do
         case $1 in
             "-s")
-                if grep -v '^==' $SRV_OUT | grep "$2" >/dev/null; then :; else
+                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
                     fail "-s $2"
                     return
                 fi
                 ;;
 
             "-c")
-                if grep -v '^==' $CLI_OUT | grep "$2" >/dev/null; then :; else
+                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
                     fail "-c $2"
                     return
                 fi
                 ;;
 
             "-S")
-                if grep -v '^==' $SRV_OUT | grep "$2" >/dev/null; then
+                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
                     fail "-S $2"
                     return
                 fi
                 ;;
 
             "-C")
-                if grep -v '^==' $CLI_OUT | grep "$2" >/dev/null; then
+                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
                     fail "-C $2"
                     return
                 fi
@@ -460,6 +510,11 @@
 
     # if we're here, everything is ok
     echo "PASS"
+    if [ "$PRESERVE_LOGS" -gt 0 ]; then
+        mv $SRV_OUT o-srv-${TESTS}.log
+        mv $CLI_OUT o-cli-${TESTS}.log
+    fi
+
     rm -f $SRV_OUT $CLI_OUT $PXY_OUT
 }
 
@@ -496,6 +551,12 @@
     echo "Command '$P_PXY' is not an executable file"
     exit 1
 fi
+if [ "$MEMCHECK" -gt 0 ]; then
+    if which valgrind >/dev/null 2>&1; then :; else
+        echo "Memcheck not possible. Valgrind not found"
+        exit 1
+    fi
+fi
 if which $OPENSSL_CMD >/dev/null 2>&1; then :; else
     echo "Command '$OPENSSL_CMD' not found"
     exit 1
@@ -567,12 +628,14 @@
 
 # Tests for rc4 option
 
+requires_config_enabled MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 run_test    "RC4: server disabled, client enabled" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA" \
             1 \
             -s "SSL - The server has no ciphersuites in common"
 
+requires_config_enabled MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 run_test    "RC4: server half, client enabled" \
             "$P_SRV arc4=1" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA" \
@@ -695,6 +758,7 @@
             -C "using encrypt then mac" \
             -S "using encrypt then mac"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Encrypt then MAC: client SSLv3, server enabled" \
             "$P_SRV debug_level=3 min_version=ssl3 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
@@ -707,13 +771,14 @@
             -C "using encrypt then mac" \
             -S "using encrypt then mac"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Encrypt then MAC: client enabled, server SSLv3" \
             "$P_SRV debug_level=3 force_version=ssl3 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
             "$P_CLI debug_level=3 min_version=ssl3" \
             0 \
             -c "client hello, adding encrypt_then_mac extension" \
-            -s "found encrypt then mac extension" \
+            -S "found encrypt then mac extension" \
             -S "server hello, adding encrypt then mac extension" \
             -C "found encrypt_then_mac extension" \
             -C "using encrypt then mac" \
@@ -754,6 +819,7 @@
             -C "using extended master secret" \
             -S "using extended master secret"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Extended Master Secret: client SSLv3, server enabled" \
             "$P_SRV debug_level=3 min_version=ssl3" \
             "$P_CLI debug_level=3 force_version=ssl3" \
@@ -765,12 +831,13 @@
             -C "using extended master secret" \
             -S "using extended master secret"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Extended Master Secret: client enabled, server SSLv3" \
             "$P_SRV debug_level=3 force_version=ssl3" \
             "$P_CLI debug_level=3 min_version=ssl3" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
-            -s "found extended master secret extension" \
+            -S "found extended master secret extension" \
             -S "server hello, adding extended master secret extension" \
             -C "found extended_master_secret extension" \
             -C "using extended master secret" \
@@ -883,6 +950,7 @@
             -s "Read from client: 1 bytes read" \
             -s "122 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "CBC Record splitting: SSLv3, splitting" \
             "$P_SRV min_version=ssl3" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
@@ -1554,6 +1622,64 @@
             -S "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
             -S "server hello, secure renegotiation extension"
 
+# Tests for silently dropping trailing extra bytes in .der certificates
+
+requires_gnutls
+run_test    "DER format: no trailing bytes" \
+            "$P_SRV crt_file=data_files/server5-der0.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with a trailing zero byte" \
+            "$P_SRV crt_file=data_files/server5-der1a.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with a trailing random byte" \
+            "$P_SRV crt_file=data_files/server5-der1b.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with 2 trailing random bytes" \
+            "$P_SRV crt_file=data_files/server5-der2.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with 4 trailing random bytes" \
+            "$P_SRV crt_file=data_files/server5-der4.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with 8 trailing random bytes" \
+            "$P_SRV crt_file=data_files/server5-der8.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
+requires_gnutls
+run_test    "DER format: with 9 trailing random bytes" \
+            "$P_SRV crt_file=data_files/server5-der9.crt \
+             key_file=data_files/server5.key" \
+            "$G_CLI " \
+            0 \
+            -c "Handshake was completed" \
+
 # Tests for auth_mode
 
 run_test    "Authentication: server badcert, client required" \
@@ -1674,6 +1800,7 @@
             -c "skip write certificate verify" \
             -C "! mbedtls_ssl_handshake returned"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Authentication: client no cert, ssl3" \
             "$P_SRV debug_level=3 auth_mode=optional force_version=ssl3" \
             "$P_CLI debug_level=3 crt_file=none key_file=none min_version=ssl3" \
@@ -2593,6 +2720,7 @@
 
 # Tests for ciphersuites per version
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Per-version suites: SSL3" \
             "$P_SRV min_version=ssl3 version_suites=TLS-RSA-WITH-3DES-EDE-CBC-SHA,TLS-RSA-WITH-AES-256-CBC-SHA,TLS-RSA-WITH-AES-128-CBC-SHA,TLS-RSA-WITH-AES-128-GCM-SHA256" \
             "$P_CLI force_version=ssl3" \
@@ -2642,6 +2770,7 @@
 
 # Tests for small packets
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Small packet SSLv3 BlockCipher" \
             "$P_SRV min_version=ssl3" \
             "$P_CLI request_size=1 force_version=ssl3 \
@@ -2649,6 +2778,7 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Small packet SSLv3 StreamCipher" \
             "$P_SRV min_version=ssl3 arc4=1 force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA" \
             "$P_CLI request_size=1 force_version=ssl3 \
@@ -2781,8 +2911,19 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+# A test for extensions in SSLv3
+
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
+run_test    "SSLv3 with extensions, server side" \
+            "$P_SRV min_version=ssl3 debug_level=3" \
+            "$P_CLI force_version=ssl3 tickets=1 max_frag_len=4096 alpn=abc,1234" \
+            0 \
+            -S "dumping 'client hello extensions'" \
+            -S "server hello, total extension length:"
+
 # Test for large packets
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Large packet SSLv3 BlockCipher" \
             "$P_SRV min_version=ssl3" \
             "$P_CLI request_size=16384 force_version=ssl3 recsplit=0 \
@@ -2790,6 +2931,7 @@
             0 \
             -s "Read from client: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Large packet SSLv3 StreamCipher" \
             "$P_SRV min_version=ssl3 arc4=1 force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA" \
             "$P_CLI request_size=16384 force_version=ssl3 \
@@ -2979,13 +3121,22 @@
             -S "The operation timed out" \
             -s "Client initiated reconnection from same port"
 
-run_test    "DTLS client reconnect from same port: reconnect, nbio" \
+not_with_valgrind # server/client too slow to respond in time (next test has higher timeouts)
+run_test    "DTLS client reconnect from same port: reconnect, nbio, no valgrind" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=1000 nbio=2" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \
             0 \
             -S "The operation timed out" \
             -s "Client initiated reconnection from same port"
 
+only_with_valgrind # Only with valgrind, do previous test but with higher read_timeout and hs_timeout
+run_test    "DTLS client reconnect from same port: reconnect, nbio, valgrind" \
+            "$P_SRV dtls=1 exchanges=2 read_timeout=2000 nbio=2 hs_timeout=1500-6000" \
+            "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=1500-3000 reconnect_hard=1" \
+            0 \
+            -S "The operation timed out" \
+            -s "Client initiated reconnection from same port"
+
 run_test    "DTLS client reconnect from same port: no cookies" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=1000 cookies=0" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-8000 reconnect_hard=1" \
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 8f681db..d12be75 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -1,3 +1,9 @@
+#line 1 "helpers.function"
+/*----------------------------------------------------------------------------*/
+/* Headers */
+
+#include <stdlib.h>
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
@@ -7,22 +13,58 @@
 #define mbedtls_calloc    calloc
 #define mbedtls_free       free
 #define mbedtls_exit       exit
+#define mbedtls_time       time
+#define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
+#endif
+
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#include "mbedtls/memory_buffer_alloc.h"
 #endif
 
 #ifdef _MSC_VER
 #include <basetsd.h>
 typedef UINT32 uint32_t;
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
 #else
 #include <stdint.h>
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 
+
+/*----------------------------------------------------------------------------*/
+/* Constants */
+
+#define DEPENDENCY_SUPPORTED        0
+#define DEPENDENCY_NOT_SUPPORTED    1
+
+#define KEY_VALUE_MAPPING_FOUND     0
+#define KEY_VALUE_MAPPING_NOT_FOUND -1
+
+#define DISPATCH_TEST_SUCCESS       0
+#define DISPATCH_TEST_FN_NOT_FOUND  1
+#define DISPATCH_INVALID_TEST_DATA  2
+#define DISPATCH_UNSUPPORTED_SUITE  3
+
+
+/*----------------------------------------------------------------------------*/
+/* Macros */
+
+#define TEST_ASSERT( TEST )                         \
+    do {                                            \
+        if( ! (TEST) )                              \
+        {                                           \
+            test_fail( #TEST, __LINE__, __FILE__ ); \
+            goto exit;                              \
+        }                                           \
+    } while( 0 )
+
 #define assert(a) if( !( a ) )                                      \
 {                                                                   \
     mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n",   \
@@ -53,11 +95,21 @@
 }
 #endif
 
+
+/*----------------------------------------------------------------------------*/
+/* Global variables */
+
+static int test_errors = 0;
+
+
+/*----------------------------------------------------------------------------*/
+/* Helper Functions */
+
 static int unhexify( unsigned char *obuf, const char *ibuf )
 {
     unsigned char c, c2;
     int len = strlen( ibuf ) / 2;
-    assert( strlen( ibuf ) % 2 == 0 ); // must be even number of bytes
+    assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
 
     while( *ibuf != 0 )
     {
@@ -298,3 +350,12 @@
 
     return( 0 );
 }
+
+static void test_fail( const char *test, int line_no, const char* filename )
+{
+    test_errors++;
+    if( test_errors == 1 )
+        mbedtls_printf( "FAILED\n" );
+    mbedtls_printf( "  %s\n  at line %d, %s\n", test, line_no, filename );
+}
+
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 420ee76..ac5322e 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -1,44 +1,7 @@
-#include <string.h>
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_exit       exit
-#define mbedtls_free       free
-#define mbedtls_calloc     calloc
-#define mbedtls_fprintf    fprintf
-#define mbedtls_printf     printf
-#define mbedtls_snprintf   snprintf
-#endif
-
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#include "mbedtls/memory_buffer_alloc.h"
-#endif
-
-static int test_errors = 0;
-
+#line 1 "main_test.function"
 SUITE_PRE_DEP
 #define TEST_SUITE_ACTIVE
 
-static void test_fail( const char *test )
-{
-    test_errors++;
-    if( test_errors == 1 )
-        mbedtls_printf( "FAILED\n" );
-    mbedtls_printf( "  %s\n", test );
-}
-
-#define TEST_ASSERT( TEST )                         \
-    do {                                            \
-        if( ! (TEST) )                              \
-        {                                           \
-            test_fail( #TEST );                     \
-            goto exit;                              \
-        }                                           \
-    } while( 0 )
-
 int verify_string( char **str )
 {
     if( (*str)[0] != '"' ||
@@ -98,20 +61,31 @@
 MAPPING_CODE
 
     mbedtls_printf( "Expected integer for parameter and got: %s\n", str );
-    return( -1 );
+    return( KEY_VALUE_MAPPING_NOT_FOUND );
 }
 
+
+/*----------------------------------------------------------------------------*/
+/* Test Case code */
+
 FUNCTION_CODE
 SUITE_POST_DEP
 
+#line !LINE_NO! "main_test.function"
+
+
+/*----------------------------------------------------------------------------*/
+/* Test dispatch code */
+
 int dep_check( char *str )
 {
     if( str == NULL )
         return( 1 );
 
 DEP_CHECK_CODE
+#line !LINE_NO! "main_test.function"
 
-    return( 1 );
+    return( DEPENDENCY_NOT_SUPPORTED );
 }
 
 int dispatch_test(int cnt, char *params[50])
@@ -121,18 +95,45 @@
     ((void) params);
 
 #if defined(TEST_SUITE_ACTIVE)
+    ret = DISPATCH_TEST_SUCCESS;
+
+    // Cast to void to avoid compiler warnings
+    (void)ret;
+
 DISPATCH_FUNCTION
     {
-        mbedtls_fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
+#line !LINE_NO! "main_test.function"
+        mbedtls_fprintf( stdout,
+                         "FAILED\nSkipping unknown test function '%s'\n",
+                         params[0] );
         fflush( stdout );
-        return( 1 );
+        ret = DISPATCH_TEST_FN_NOT_FOUND;
     }
 #else
-    return( 3 );
+    ret = DISPATCH_UNSUPPORTED_SUITE;
 #endif
     return( ret );
 }
 
+
+/*----------------------------------------------------------------------------*/
+/* Main Test code */
+
+#line !LINE_NO! "main_test.function"
+
+#define USAGE \
+    "Usage: %s [OPTIONS] files...\n\n" \
+    "   Command line arguments:\n" \
+    "     files...          One or more test data file. If no file is specified\n" \
+    "                       the followimg default test case is used:\n" \
+    "                           %s\n\n" \
+    "   Options:\n" \
+    "     -v | --verbose    Display full information about each test\n" \
+    "     -h | --help       Display this information\n\n", \
+    argv[0], \
+    "TESTCASE_FILENAME"
+
+
 int get_line( FILE *f, char *buf, size_t len )
 {
     char *ret;
@@ -178,7 +179,7 @@
         p++;
     }
 
-    // Replace newlines, question marks and colons in strings
+    /* Replace newlines, question marks and colons in strings */
     for( i = 0; i < cnt; i++ )
     {
         p = params[i];
@@ -240,10 +241,20 @@
             test_snprintf( 5, "123",         3 ) != 0 );
 }
 
-int main()
+int main(int argc, const char *argv[])
 {
-    int ret, i, cnt, total_errors = 0, total_tests = 0, total_skipped = 0;
-    const char *filename = "TEST_FILENAME";
+    /* Local Configurations and options */
+    const char *default_filename = "TESTCASE_FILENAME";
+    const char *test_filename = NULL;
+    const char **test_files = NULL;
+    int testfile_count = 0;
+    int option_verbose = 0;
+
+    /* Other Local variables */
+    int arg_index = 1;
+    const char *next_arg;
+    int testfile_index, ret, i, cnt;
+    int total_errors = 0, total_tests = 0, total_skipped = 0;
     FILE *file;
     char buf[5000];
     char *params[50];
@@ -276,78 +287,171 @@
         return( 0 );
     }
 
-    file = fopen( filename, "r" );
-    if( file == NULL )
+    while( arg_index < argc)
     {
-        mbedtls_fprintf( stderr, "Failed to open\n" );
-        return( 1 );
+        next_arg = argv[ arg_index ];
+
+        if( strcmp(next_arg, "--verbose" ) == 0 ||
+                 strcmp(next_arg, "-v" ) == 0 )
+        {
+            option_verbose = 1;
+        }
+        else if( strcmp(next_arg, "--help" ) == 0 ||
+                 strcmp(next_arg, "-h" ) == 0 )
+        {
+            mbedtls_fprintf( stdout, USAGE );
+            mbedtls_exit( EXIT_SUCCESS );
+        }
+        else
+        {
+            /* Not an option, therefore treat all further arguments as the file
+             * list.
+             */
+            test_files = &argv[ arg_index ];
+            testfile_count = argc - arg_index;
+        }
+
+        arg_index++;
     }
 
-    while( !feof( file ) )
+    /* If no files were specified, assume a default */
+    if ( test_files == NULL || testfile_count == 0 )
     {
-        int skip = 0;
+        test_files = &default_filename;
+        testfile_count = 1;
+    }
 
-        if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
-            break;
-        mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
-        mbedtls_fprintf( stdout, " " );
-        for( i = strlen( buf ) + 1; i < 67; i++ )
-            mbedtls_fprintf( stdout, "." );
-        mbedtls_fprintf( stdout, " " );
-        fflush( stdout );
+    /* Now begin to execute the tests in the testfiles */
+    for ( testfile_index = 0;
+          testfile_index < testfile_count;
+          testfile_index++ )
+    {
+        int unmet_dep_count = 0;
+        char *unmet_dependencies[20];
 
-        total_tests++;
+        test_filename = test_files[ testfile_index ];
 
-        if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
-            break;
-        cnt = parse_arguments( buf, strlen(buf), params );
-
-        if( strcmp( params[0], "depends_on" ) == 0 )
+        file = fopen( test_filename, "r" );
+        if( file == NULL )
         {
-            for( i = 1; i < cnt; i++ )
-                if( dep_check( params[i] ) != 0 )
-                    skip = 1;
+            mbedtls_fprintf( stderr, "Failed to open test file: %s\n",
+                             test_filename );
+            return( 1 );
+        }
+
+        while( !feof( file ) )
+        {
+            if( unmet_dep_count > 0 )
+            {
+                mbedtls_printf("FATAL: Dep count larger than zero at start of loop\n");
+                mbedtls_exit( MBEDTLS_EXIT_FAILURE );
+            }
+            unmet_dep_count = 0;
+
+            if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
+                break;
+            mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
+            mbedtls_fprintf( stdout, " " );
+            for( i = strlen( buf ) + 1; i < 67; i++ )
+                mbedtls_fprintf( stdout, "." );
+            mbedtls_fprintf( stdout, " " );
+            fflush( stdout );
+
+            total_tests++;
 
             if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
                 break;
             cnt = parse_arguments( buf, strlen(buf), params );
-        }
 
-        if( skip == 0 )
-        {
-            test_errors = 0;
-            ret = dispatch_test( cnt, params );
-        }
+            if( strcmp( params[0], "depends_on" ) == 0 )
+            {
+                for( i = 1; i < cnt; i++ )
+                {
+                    if( dep_check( params[i] ) != DEPENDENCY_SUPPORTED )
+                    {
+                        if( 0 == option_verbose )
+                        {
+                            /* Only one count is needed if not verbose */
+                            unmet_dep_count++;
+                            break;
+                        }
 
-        if( skip == 1 || ret == 3 )
-        {
-            total_skipped++;
-            mbedtls_fprintf( stdout, "----\n" );
-            fflush( stdout );
-        }
-        else if( ret == 0 && test_errors == 0 )
-        {
-            mbedtls_fprintf( stdout, "PASS\n" );
-            fflush( stdout );
-        }
-        else if( ret == 2 )
-        {
-            mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
-            fclose(file);
-            mbedtls_exit( 2 );
-        }
-        else
-            total_errors++;
+                        unmet_dependencies[ unmet_dep_count ] = strdup(params[i]);
+                        if(  unmet_dependencies[ unmet_dep_count ] == NULL )
+                        {
+                            mbedtls_printf("FATAL: Out of memory\n");
+                            mbedtls_exit( MBEDTLS_EXIT_FAILURE );
+                        }
+                        unmet_dep_count++;
+                    }
+                }
 
-        if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
-            break;
-        if( strlen(buf) != 0 )
-        {
-            mbedtls_fprintf( stderr, "Should be empty %d\n", (int) strlen(buf) );
-            return( 1 );
+                if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
+                    break;
+                cnt = parse_arguments( buf, strlen(buf), params );
+            }
+ 
+            // If there are no unmet dependencies execute the test
+            if( unmet_dep_count == 0 )
+            {
+                test_errors = 0;
+                ret = dispatch_test( cnt, params );
+            }
+
+            if( unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE )
+            {
+                total_skipped++;
+                mbedtls_fprintf( stdout, "----\n" );
+
+                if( 1 == option_verbose && ret == DISPATCH_UNSUPPORTED_SUITE )
+                {
+                    mbedtls_fprintf( stdout, "   Test Suite not enabled" );
+                }
+
+                if( 1 == option_verbose && unmet_dep_count > 0 )
+                {
+                    mbedtls_fprintf( stdout, "   Unmet dependencies: " );
+                    for( i = 0; i < unmet_dep_count; i++ )
+                    {
+                        mbedtls_fprintf(stdout, "%s  ",
+                                        unmet_dependencies[i]);
+                        free(unmet_dependencies[i]);
+                    }
+                    mbedtls_fprintf( stdout, "\n" );
+                }
+                fflush( stdout );
+
+                unmet_dep_count = 0;
+            }
+            else if( ret == DISPATCH_TEST_SUCCESS && test_errors == 0 )
+            {
+                mbedtls_fprintf( stdout, "PASS\n" );
+                fflush( stdout );
+            }
+            else if( ret == DISPATCH_INVALID_TEST_DATA )
+            {
+                mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
+                fclose(file);
+                mbedtls_exit( 2 );
+            }
+            else
+                total_errors++;
+
+            if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
+                break;
+            if( strlen(buf) != 0 )
+            {
+                mbedtls_fprintf( stderr, "Should be empty %d\n",
+                                 (int) strlen(buf) );
+                return( 1 );
+            }
         }
+        fclose(file);
+
+        /* In case we encounter early end of file */
+        for( i = 0; i < unmet_dep_count; i++ )
+            free( unmet_dependencies[i] );
     }
-    fclose(file);
 
     mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
     if( total_errors == 0 )
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
index 833eef5..5ca99f8 100644
--- a/tests/suites/test_suite_entropy.data
+++ b/tests/suites/test_suite_entropy.data
@@ -1,3 +1,6 @@
+Create NV seed_file
+nv_seed_file_create:
+
 Entropy write/update seed file
 entropy_seed_file:"data_files/entropy_seed":0
 
@@ -37,5 +40,17 @@
 Entropy thershold #4
 entropy_threshold:1024:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
+Check NV seed standard IO
+entropy_nv_seed_std_io:
+
+Check NV seed manually #1
+entropy_nv_seed:"00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF"
+
+Check NV seed manually #2
+entropy_nv_seed:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+
+Check NV seed manually #3
+entropy_nv_seed:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+
 Entropy self test
 entropy_selftest:
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 3b739cc..d1ef94b 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -1,5 +1,6 @@
 /* BEGIN_HEADER */
 #include "mbedtls/entropy.h"
+#include "mbedtls/entropy_poll.h"
 
 /*
  * Number of calls made to entropy_dummy_source()
@@ -33,6 +34,88 @@
 
     return( 0 );
 }
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/*
+ * Ability to clear entropy sources to allow testing with just predefined
+ * entropy sources. This function or tests depending on it might break if there
+ * are internal changes to how entropy sources are registered.
+ *
+ * To be called immediately after mbedtls_entropy_init().
+ *
+ * Just resetting the counter. New sources will overwrite existing ones.
+ * This might break memory checks in the future if sources need 'free-ing' then
+ * as well.
+ */
+static void entropy_clear_sources( mbedtls_entropy_context *ctx )
+{
+    ctx->source_count = 0;
+}
+
+/*
+ * NV seed read/write functions that use a buffer instead of a file
+ */
+static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    return( 0 );
+}
+
+static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    return( 0 );
+}
+
+/*
+ * NV seed read/write helpers that fill the base seedfile
+ */
+static int write_nv_seed( unsigned char *buf, size_t buf_len )
+{
+    FILE *f;
+
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+        return( -1 );
+
+    if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
+                    MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    fclose( f );
+
+    return( 0 );
+}
+
+static int read_nv_seed( unsigned char *buf, size_t buf_len )
+{
+    FILE *f;
+
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+        return( -1 );
+
+    if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
+                    MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    fclose( f );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -160,6 +243,10 @@
     if( result >= 0 )
     {
         TEST_ASSERT( ret == 0 );
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+        // Two times as much calls due to the NV seed update
+        result *= 2;
+#endif
         TEST_ASSERT( entropy_dummy_calls == (size_t) result );
     }
     else
@@ -172,6 +259,124 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void nv_seed_file_create()
+{
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
+void entropy_nv_seed_std_io()
+{
+    unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
+                                  mbedtls_platform_std_nv_seed_write );
+
+    /* Check if platform NV read and write manipulate the same data */
+    TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+    TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
+                    MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    /* Check if platform NV write and raw read manipulate the same data */
+    TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
+                    MBEDTLS_ENTROPY_BLOCK_SIZE );
+    TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT:MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
+void entropy_nv_seed( char *read_seed_str )
+{
+    mbedtls_sha512_context accumulator;
+    mbedtls_entropy_context ctx;
+
+    unsigned char header[2];
+    unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char read_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( buffer_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    // Set the initial NV seed to read
+    unhexify( read_seed, read_seed_str );
+    memcpy( buffer_seed, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    // Make sure we read/write NV seed from our buffers
+    mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
+
+    mbedtls_entropy_init( &ctx );
+    entropy_clear_sources( &ctx );
+
+    TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
+                                             MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                             MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
+
+    // Do an entropy run
+    TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
+
+    // Determine what should have happened with manual entropy internal logic
+    // Only use the SHA-512 version to check
+
+    // Init accumulator
+    header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    mbedtls_sha512_starts( &accumulator, 0 );
+
+    // First run for updating write_seed
+    header[0] = 0;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha512_finish( &accumulator, buf );
+
+    memset( &accumulator, 0, sizeof( mbedtls_sha512_context ) );
+    mbedtls_sha512_starts( &accumulator, 0 );
+    mbedtls_sha512_update( &accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_seed, 0 );
+
+    // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
+    header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, empty, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    header[0] = 0;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha512_finish( &accumulator, buf );
+
+    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_entropy, 0 );
+
+    // Check result of both NV file and entropy received with the manual calculations
+    TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+    TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    mbedtls_entropy_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void entropy_selftest( )
 {
diff --git a/tests/suites/test_suite_memory_buffer_alloc.data b/tests/suites/test_suite_memory_buffer_alloc.data
index a0b0460..8d3813a 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.data
+++ b/tests/suites/test_suite_memory_buffer_alloc.data
@@ -1,2 +1,18 @@
 Memory buffer alloc self test
 mbedtls_memory_buffer_alloc_self_test:
+
+Memory buffer alloc - free in middle, alloc at end
+memory_buffer_alloc_free_alloc:100:100:100:0:0:1:0:0:200:0
+
+Memory buffer alloc - free in middle, realloc
+memory_buffer_alloc_free_alloc:100:100:100:0:0:1:0:0:100:0
+
+Memory buffer alloc - free in middle, merge, realloc
+memory_buffer_alloc_free_alloc:100:100:100:100:0:1:1:0:201:0
+
+Memory buffer alloc - free at end, merge, realloc
+memory_buffer_alloc_free_alloc:100:64:100:100:0:0:0:1:200:0
+
+Memory buffer alloc - Out of Memory test
+memory_buffer_alloc_oom_test:
+
diff --git a/tests/suites/test_suite_memory_buffer_alloc.function b/tests/suites/test_suite_memory_buffer_alloc.function
index 59b0643..04dd68b 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.function
+++ b/tests/suites/test_suite_memory_buffer_alloc.function
@@ -1,6 +1,7 @@
 /* BEGIN_HEADER */
 #include "mbedtls/memory_buffer_alloc.h"
 #define TEST_SUITE_MEMORY_BUFFER_ALLOC
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -8,9 +9,226 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_SUITE_HELPERS */
+static int check_pointer( void *p )
+{
+    if( p == NULL )
+        return( -1 );
+
+    if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
+        return( -1 );
+
+    return( 0 );
+}
+/* END_SUITE_HELPERS */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void mbedtls_memory_buffer_alloc_self_test( )
 {
     TEST_ASSERT( mbedtls_memory_buffer_alloc_self_test( 0 ) == 0 );
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
+                                        int d_bytes,
+                                     int free_a, int free_b, int free_c,
+                                        int free_d,
+                                     int e_bytes, int f_bytes )
+{
+    unsigned char buf[1024];
+    unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL,
+                    *ptr_e = NULL, *ptr_f = NULL;
+
+    size_t reported_blocks;
+    size_t allocated_bytes = 0, reported_bytes;
+
+    mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    mbedtls_memory_buffer_set_verify( MBEDTLS_MEMORY_VERIFY_ALWAYS );
+
+    if( a_bytes > 0 )
+    {
+        ptr_a = mbedtls_calloc( a_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_a ) == 0 );
+
+        allocated_bytes += a_bytes * sizeof(char);
+    }
+
+    if( b_bytes > 0 )
+    {
+        ptr_b = mbedtls_calloc( b_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_b ) == 0 );
+
+        allocated_bytes += b_bytes * sizeof(char);
+    }
+
+    if( c_bytes > 0 )
+    {
+        ptr_c = mbedtls_calloc( c_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_c ) == 0 );
+
+        allocated_bytes += c_bytes * sizeof(char);
+    }
+
+    if( d_bytes > 0 )
+    {
+        ptr_d = mbedtls_calloc( d_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_d ) == 0 );
+
+        allocated_bytes += d_bytes * sizeof(char);
+    }
+
+    mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+    TEST_ASSERT( reported_bytes == allocated_bytes );
+
+    if( free_a )
+    {
+        mbedtls_free( ptr_a );
+        ptr_a = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+        allocated_bytes -= a_bytes * sizeof(char);
+    }
+
+    if( free_b )
+    {
+        mbedtls_free( ptr_b );
+        ptr_b = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+        allocated_bytes -= b_bytes * sizeof(char);
+    }
+
+    if( free_c )
+    {
+        mbedtls_free( ptr_c );
+        ptr_c = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+        allocated_bytes -= c_bytes * sizeof(char);
+    }
+
+    if( free_d )
+    {
+        mbedtls_free( ptr_d );
+        ptr_d = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+        allocated_bytes -= d_bytes * sizeof(char);
+    }
+
+    mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+    TEST_ASSERT( reported_bytes == allocated_bytes );
+
+    if( e_bytes > 0 )
+    {
+        ptr_e = mbedtls_calloc( e_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_e ) == 0 );
+    }
+
+    if( f_bytes > 0 )
+    {
+        ptr_f = mbedtls_calloc( f_bytes, sizeof(char) );
+        TEST_ASSERT( check_pointer( ptr_f ) == 0 );
+    }
+
+    /* Once blocks are reallocated, the block allocated to the memory request
+     * may be bigger than the request itself, which is indicated by the reported
+     * bytes, and makes it hard to know what the reported size will be, so
+     * we don't check the size after blocks have been reallocated. */
+
+    if( ptr_a != NULL )
+    {
+        mbedtls_free( ptr_a );
+        ptr_a = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+    }
+
+    if( ptr_b != NULL )
+    {
+        mbedtls_free( ptr_b );
+        ptr_b = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+    }
+
+    if( ptr_c != NULL )
+    {
+        mbedtls_free( ptr_c );
+        ptr_c = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+    }
+
+    if( ptr_d != NULL )
+    {
+        mbedtls_free( ptr_d );
+        ptr_d = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+    }
+
+    if( ptr_e != NULL )
+    {
+        mbedtls_free( ptr_e );
+        ptr_e = NULL;
+        TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+    }
+
+    if( ptr_f != NULL )
+    {
+        mbedtls_free( ptr_f );
+        ptr_f = NULL;
+    }
+
+    mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+    TEST_ASSERT( reported_bytes == 0 );
+
+    TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+exit:
+    mbedtls_memory_buffer_alloc_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_alloc_oom_test()
+{
+    unsigned char buf[1024];
+    unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL;
+    size_t reported_blocks, reported_bytes;
+
+    (void)ptr_c;
+
+    mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    mbedtls_memory_buffer_set_verify( MBEDTLS_MEMORY_VERIFY_ALWAYS );
+
+    ptr_a = mbedtls_calloc( 432, sizeof(char) );
+    TEST_ASSERT( check_pointer( ptr_a ) == 0 );
+
+    ptr_b = mbedtls_calloc( 432, sizeof(char) );
+    TEST_ASSERT( check_pointer( ptr_b ) == 0 );
+
+    ptr_c = mbedtls_calloc( 431, sizeof(char) );
+    TEST_ASSERT( ptr_c == NULL );
+
+    mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+    TEST_ASSERT( reported_bytes >= 864 && reported_bytes <= sizeof(buf) );
+
+    mbedtls_free( ptr_a );
+    ptr_a = NULL;
+    TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+    mbedtls_free( ptr_b );
+    ptr_b = NULL;
+    TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+    mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+    TEST_ASSERT( reported_bytes == 0 );
+
+    TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+exit:
+    mbedtls_memory_buffer_alloc_free( );
+}
+/* END_CASE */
+
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index f838f3b..3fd7f2d 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -295,6 +295,15 @@
 Test mbedtls_mpi_add_mpi #2
 mbedtls_mpi_add_mpi:10:"643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"56125680981752282333498088313568935051383833838594899821664631784577337171193624243181360054669678410455329112434552942717084003541384594864129940145043086760031292483340068923506115878221189886491132772739661669044958531131327771":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924"
 
+Base test mbedtls_mpi_add_mpi inplace #1
+mbedtls_mpi_add_mpi_inplace:10:"12345678":10:"24691356"
+
+Test mbedtls_mpi_add_mpi inplace #2 
+mbedtls_mpi_add_mpi_inplace:10:"643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"1287616013607108878460259709922985398302772215068026865836146879048276529684741260122739430789478268181845874665180769440794266671939098512645241958073373266427807905932350214193538360035292323703146295192780306"
+
+Test mbedtls_mpi_add_mpi inplace #3 
+mbedtls_mpi_add_mpi_inplace:16:"ffffffffffffffffffffffffffffffff":16:"01fffffffffffffffffffffffffffffffe"
+
 Test mbedtls_mpi_add_int #1
 mbedtls_mpi_add_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":9871232:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227022647561"
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 5dd6f0d..c41ca69 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -443,6 +443,32 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mbedtls_mpi_add_mpi_inplace( int radix_X, char *input_X, int radix_A, char *input_A )
+{
+    mbedtls_mpi X, A;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
+}
+/* END_CASE */
+
+
+/* BEGIN_CASE */
 void mbedtls_mpi_add_abs( int radix_X, char *input_X, int radix_Y, char *input_Y,
                   int radix_A, char *input_A )
 {
diff --git a/tests/suites/test_suite_pkcs1_v15.data b/tests/suites/test_suite_pkcs1_v15.data
new file mode 100644
index 0000000..db7a4cd
--- /dev/null
+++ b/tests/suites/test_suite_pkcs1_v15.data
@@ -0,0 +1,35 @@
+RSAES-V15 Encryption Test Vector Int
+pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"d436e99569fd32a7c8a05bbc90d32c49":"aafd12f659cae63489b479e5076ddec2f06cb58f67c6697351ff4aec29cdbaabf2fbe3467cc254f81be8e78d765a2e63339fc99a66320db73158a35a255d051758e95ed4abb2cdc69bb454110e827441213ddc8770e93ea141e1fc673e017e97eadc6b968f385c2aecb03bfb32":"6c5ebca6116b1e91316613fbb5e93197270a849122d549122d05815e2626f80d20f7f3f038c98295203c0f7f6bb8c3568455c67dec82bca86be86eff43b56b7ba2d15375f9a42454c2a2c709953a6e4a977462e35fd21a9c2fb3c0ad2a370f7655267bf6f04814784982988e663b869fc8588475af860d499e5a6ffdfc2c6bfd":0
+
+RSAES-V15 Decryption Test Vector Int
+pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"d436e99569fd32a7c8a05bbc90d32c49":"aafd12f659cae63489b479e5076ddec2f06cb58f":"28818cb14236ad18f4527e7f1f7633e96cef021bc3234475d7f61e88702b6335b42a352ed3f3267ac7c3e9ba4af17e45096c63eefd8d9a7cb42dfc52fffb2f5b8afb305b46312c2eb50634123b4437a2287ac57b7509d59a583fb741989a49f32625e9267b4641a6607b7303d35c68489db53c8d387b620d0d46a852e72ea43c":0
+
+RSAES-V15 Encryption Test Vector Data just fits
+pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"4293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"18cdb161f40a18509a3501b7e8ec1c7522e2490319efee8581179b5bcf3750f83a865952d078efd48f58f8060b0d43f9888b43a094fe15209451826ef797195885ff9fa3e26994eee85dbe5dd0404a71565708286027b433c88c85af555b96c34c304dc7c8278233654c022ef340042cfff55e6b15b67cfea8a5a384ef64a6ac":0
+
+RSAES-V15 Decryption Test Vector Data just fits
+pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"4293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"18cdb161f40a18509a3501b7e8ec1c7522e2490319efee8581179b5bcf3750f83a865952d078efd48f58f8060b0d43f9888b43a094fe15209451826ef797195885ff9fa3e26994eee85dbe5dd0404a71565708286027b433c88c85af555b96c34c304dc7c8278233654c022ef340042cfff55e6b15b67cfea8a5a384ef64a6ac":0
+
+RSAES-V15 Encryption Test Vector Data too long 1
+pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"b84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"05abded6751d620a95177abdba915027b58dd6eecf4ebe71f71c400b115e1d9e12465ace4db3cc03eb57fcbbfe017770f438cf84c10bad505919aefebfa0752087f6376b055beabf0e089fbb90e10f99c795d2d5676eea196db7f94a8fd34aedaba39fb230281bb9917cc91793eb37f84dedb2421e9680c39cfda34d4a012134":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSAES-V15 Decryption Test Vector Padding too short 7 
+pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"b84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"05abded6751d620a95177abdba915027b58dd6eecf4ebe71f71c400b115e1d9e12465ace4db3cc03eb57fcbbfe017770f438cf84c10bad505919aefebfa0752087f6376b055beabf0e089fbb90e10f99c795d2d5676eea196db7f94a8fd34aedaba39fb230281bb9917cc91793eb37f84dedb2421e9680c39cfda34d4a012134":MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 Encryption Test Vector Data too long 3
+pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"aa1ab84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"10d60b8040d57d8701bacb55f2f283d54601ec24d465601ac7f7d5a2f75cac380ba78ca4ab6f3c159f3a9fd6839f5adde0333852ebf876c585664c1a58a1e6885231982f2027be6d7f08ff1807d3ceda8e41ad1f02ddf97a7458832fd13a1f431de6a4ab79e3d4b88bb1df2c5c77fcde9e7b5aa1e7bb29112eae58763127752a":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSAES-V15 Decryption Test Vector Padding too short 5 
+pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"aa1ab84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"10d60b8040d57d8701bacb55f2f283d54601ec24d465601ac7f7d5a2f75cac380ba78ca4ab6f3c159f3a9fd6839f5adde0333852ebf876c585664c1a58a1e6885231982f2027be6d7f08ff1807d3ceda8e41ad1f02ddf97a7458832fd13a1f431de6a4ab79e3d4b88bb1df2c5c77fcde9e7b5aa1e7bb29112eae58763127752a":MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 Encryption Test Vector Data too long 8
+pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"a5a384ef64a6acb84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"72f98d12ddc230484179ec3022d11b3719222daaa0dc016fc3dbd6771a3f2c9fdd0560f86d616dd50ef1fa5b8c7e1fc40b5abf7b845d7795b3a6af02457b97f783360575cde7497bdf9c104650d4e9a8f4034406de1af95ace39bef2b9e979b74d9a2c0a741d8a21221d9afc98992776cad52d73151613dbc10da9bd8038751a":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSAES-V15 Decryption Test Vector Padding too short 0 
+pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"a5a384ef64a6acb84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"72f98d12ddc230484179ec3022d11b3719222daaa0dc016fc3dbd6771a3f2c9fdd0560f86d616dd50ef1fa5b8c7e1fc40b5abf7b845d7795b3a6af02457b97f783360575cde7497bdf9c104650d4e9a8f4034406de1af95ace39bef2b9e979b74d9a2c0a741d8a21221d9afc98992776cad52d73151613dbc10da9bd8038751a":MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSASSA-V15 Signing Test Vector Int
+pkcs1_rsassa_v15_sign:1024:16:"d17f655bf27c8b16d35462c905cc04a26f37e2a67fa9c0ce0dced472394a0df743fe7f929e378efdb368eddff453cf007af6d948e0ade757371f8a711e278f6b":16:"c6d92b6fee7414d1358ce1546fb62987530b90bd15e0f14963a5e2635adb69347ec0c01b2ab1763fd8ac1a592fb22757463a982425bb97a3a437c5bf86d03f2f":16:"a2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5":16:"010001":MBEDTLS_MD_SHA1:MBEDTLS_MD_SHA1:"859eef2fd78aca00308bdc471193bf55bf9d78db8f8a672b484634f3c9c26e6478ae10260fe0dd8c082e53a5293af2173cd50c6d5d354febf78b26021c25c02712e78cd4694c9f469777e451e7f8e9e04cd3739c6bbfedae487fb55644e9ca74ff77a53cb729802f6ed4a5ffa8ba159890fc":"e3b5d5d002c1bce50c2b65ef88a188d83bce7e61":"2154f928615e5101fcdeb57bc08fc2f35c3d5996403861ae3efb1d0712f8bb05cc21f7f5f11f62e5b6ea9f0f2b62180e5cbe7ba535032d6ac8068fff7f362f73d2c3bf5eca6062a1723d7cfd5abb6dcf7e405f2dc560ffe6fc37d38bee4dc9e24fe2bece3e3b4a3f032701d3f0947b42930083dd4ad241b3309b514595482d42":0
+
+RSASSA-V15 Verification Test Vector Int
+pkcs1_rsassa_v15_verify:1024:16:"a2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5":16:"010001":MBEDTLS_MD_SHA1:MBEDTLS_MD_SHA1:"859eef2fd78aca00308bdc471193bf55bf9d78db8f8a672b484634f3c9c26e6478ae10260fe0dd8c082e53a5293af2173cd50c6d5d354febf78b26021c25c02712e78cd4694c9f469777e451e7f8e9e04cd3739c6bbfedae487fb55644e9ca74ff77a53cb729802f6ed4a5ffa8ba159890fc":"e3b5d5d002c1bce50c2b65ef88a188d83bce7e61":"2154f928615e5101fcdeb57bc08fc2f35c3d5996403861ae3efb1d0712f8bb05cc21f7f5f11f62e5b6ea9f0f2b62180e5cbe7ba535032d6ac8068fff7f362f73d2c3bf5eca6062a1723d7cfd5abb6dcf7e405f2dc560ffe6fc37d38bee4dc9e24fe2bece3e3b4a3f032701d3f0947b42930083dd4ad241b3309b514595482d42":0
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
new file mode 100644
index 0000000..09fe05b
--- /dev/null
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -0,0 +1,210 @@
+/* BEGIN_HEADER */
+#include "mbedtls/rsa.h"
+#include "mbedtls/md.h"
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char *input_N, int radix_E,
+                               char *input_E, int hash,
+                               char *message_hex_string, char *seed,
+                               char *result_hex_str, int result )
+{
+    unsigned char message_str[1000];
+    unsigned char output[1000];
+    unsigned char output_str[1000];
+    unsigned char rnd_buf[1000];
+    mbedtls_rsa_context ctx;
+    size_t msg_len;
+    rnd_buf_info info;
+
+    info.length = unhexify( rnd_buf, seed );
+    info.buf = rnd_buf;
+
+    mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
+    memset( message_str, 0x00, 1000 );
+    memset( output, 0x00, 1000 );
+    memset( output_str, 0x00, 1000 );
+
+    ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
+
+    msg_len = unhexify( message_str, message_hex_string );
+
+    TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PUBLIC, msg_len, message_str, output ) == result );
+    if( result == 0 )
+    {
+        hexify( output_str, output, ctx.len );
+
+        TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
+    }
+
+exit:
+    mbedtls_rsa_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char *input_P,
+                               int radix_Q, char *input_Q, int radix_N,
+                               char *input_N, int radix_E, char *input_E,
+                               int hash, char *result_hex_str, char *seed,
+                               char *message_hex_string, int result )
+{
+    unsigned char message_str[1000];
+    unsigned char output[1000];
+    unsigned char output_str[1000];
+    mbedtls_rsa_context ctx;
+    mbedtls_mpi P1, Q1, H, G;
+    size_t output_len;
+    rnd_pseudo_info rnd_info;
+    ((void) seed);
+
+    mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
+    mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
+
+    memset( message_str, 0x00, 1000 );
+    memset( output, 0x00, 1000 );
+    memset( output_str, 0x00, 1000 );
+    memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
+
+    ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H  ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H  ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
+
+    unhexify( message_str, message_hex_string );
+
+    TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, &output_len, message_str, output, 1000 ) == result );
+    if( result == 0 )
+    {
+        hexify( output_str, output, ctx.len );
+
+        TEST_ASSERT( strncasecmp( (char *) output_str, result_hex_str, strlen( result_hex_str ) ) == 0 );
+    }
+
+exit:
+    mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
+    mbedtls_rsa_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void pkcs1_rsassa_v15_sign( int mod, int radix_P, char *input_P, int radix_Q,
+                            char *input_Q, int radix_N, char *input_N,
+                            int radix_E, char *input_E, int digest, int hash,
+                            char *message_hex_string, char *salt,
+                            char *result_hex_str, int result )
+{
+    unsigned char message_str[1000];
+    unsigned char hash_result[1000];
+    unsigned char output[1000];
+    unsigned char output_str[1000];
+    unsigned char rnd_buf[1000];
+    mbedtls_rsa_context ctx;
+    mbedtls_mpi P1, Q1, H, G;
+    size_t msg_len;
+    rnd_buf_info info;
+
+    info.length = unhexify( rnd_buf, salt );
+    info.buf = rnd_buf;
+
+    mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
+    mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
+
+    memset( message_str, 0x00, 1000 );
+    memset( hash_result, 0x00, 1000 );
+    memset( output, 0x00, 1000 );
+    memset( output_str, 0x00, 1000 );
+
+    ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H  ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H  ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
+
+    msg_len = unhexify( message_str, message_hex_string );
+
+    if( mbedtls_md_info_from_type( digest ) != NULL )
+        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PRIVATE, digest, 0, hash_result, output ) == result );
+    if( result == 0 )
+    {
+        hexify( output_str, output, ctx.len);
+
+        TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
+    }
+
+exit:
+    mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
+    mbedtls_rsa_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void pkcs1_rsassa_v15_verify( int mod, int radix_N, char *input_N, int radix_E,
+                              char *input_E, int digest, int hash,
+                              char *message_hex_string, char *salt,
+                              char *result_hex_str, int result )
+{
+    unsigned char message_str[1000];
+    unsigned char hash_result[1000];
+    unsigned char result_str[1000];
+    mbedtls_rsa_context ctx;
+    size_t msg_len;
+    ((void) salt);
+
+    mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
+    memset( message_str, 0x00, 1000 );
+    memset( hash_result, 0x00, 1000 );
+    memset( result_str, 0x00, 1000 );
+
+    ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
+
+    msg_len = unhexify( message_str, message_hex_string );
+    unhexify( result_str, result_hex_str );
+
+    if( mbedtls_md_info_from_type( digest ) != NULL )
+        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, digest, 0, hash_result, result_str ) == result );
+
+exit:
+    mbedtls_rsa_free( &ctx );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index bf16248..7c989d6 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -19,7 +19,7 @@
 pbkdf2_hmac:MBEDTLS_MD_SHA1:"7061737300776f7264":"7361006c74":4096:16:"56fa6aa75548099dcc37d7f03425e0c3"
 
 PBES2 Decrypt (OK)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
 
 PBES2 Decrypt (bad params tag)
@@ -47,7 +47,7 @@
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"300D06092A864886F70D01050C3001":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
 
 PBES2 Decrypt (bad PBKDF2 params salt: not an octet string)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"300E06092A864886F70D01050C30010500":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:""
 
 PBES2 Decrypt (bad PBKDF2 params salt: overlong)
@@ -63,7 +63,7 @@
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301906092A864886F70D01050C300C04082ED7F24A1D516DD70201":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
 
 PBES2 Decrypt (OK, PBKDF2 params explicit keylen)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301E06092A864886F70D01050C301104082ED7F24A1D516DD702020800020118301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
 
 PBES2 Decrypt (bad PBKDF2 params explicit keylen: overlong)
@@ -71,7 +71,7 @@
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208000201":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
 
 PBES2 Decrypt (OK, PBKDF2 params explicit prf_alg)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0207301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
 
 PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg not a sequence)
@@ -103,7 +103,7 @@
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300A06082A864886F70D03FF":"":"":MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE:""
 
 PBES2 Decrypt (bad enc_scheme_alg params: not an octet string)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300C06082A864886F70D03070500":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT:""
 
 PBES2 Decrypt (bad enc_scheme_alg params: overlong)
@@ -111,13 +111,13 @@
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800300C06082A864886F70D03070401":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
 
 PBES2 Decrypt (bad enc_scheme_alg params: len != iv_len)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301306082A864886F70D030704078A4FCC9DCC3949":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT:""
 
 PBES2 Decrypt (bad password)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"F0617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
 
 PBES2 Decrypt (bad iter value)
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020801301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index c43d6ae..d522332 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -345,7 +345,7 @@
 RSA Public (Data larger than N)
 mbedtls_rsa_public:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":MBEDTLS_ERR_RSA_PUBLIC_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-RSA Generate Key
+RSA Generate Key - 128bit key
 mbedtls_rsa_gen_key:128:3:0
 
 RSA Generate Key (Number of bits too small)
@@ -354,9 +354,15 @@
 RSA Generate Key (Exponent too small)
 mbedtls_rsa_gen_key:128:2:MBEDTLS_ERR_RSA_BAD_INPUT_DATA
 
-RSA Generate Key
+RSA Generate Key - 1024 bit key
 mbedtls_rsa_gen_key:1024:3:0
 
+RSA Generate Key - 2048 bit key
+mbedtls_rsa_gen_key:2048:3:0
+
+RSA Generate Key - 1025 bit key
+mbedtls_rsa_gen_key:1025:3:0
+
 RSA PKCS1 Encrypt Bad RNG
 depends_on:MBEDTLS_PKCS1_V15
 rsa_pkcs1_encrypt_bad_rng:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_RSA_PKCS_V15:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_ERR_RSA_RNG_FAILED
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index ac13f11..f9c2011 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.2.1"
+check_compiletime_version:"2.3.0"
 
 Check runtime library version
-check_runtime_version:"2.2.1"
+check_runtime_version:"2.3.0"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 2f2137f..5c68872 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -699,6 +699,22 @@
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL"
 
+X509 Certificate verification #82 (Not yet valid CA and valid CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify:"data_files/server5.crt":"data_files/test-ca2_cat-future-present.crt":"data_files/crl-ec-sha1.pem":"NULL":0:0:"NULL"
+
+X509 Certificate verification #83 (valid CA and Not yet valid CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify:"data_files/server5.crt":"data_files/test-ca2_cat-present-future.crt":"data_files/crl-ec-sha1.pem":"NULL":0:0:"NULL"
+
+X509 Certificate verification #84 (valid CA and Not yet valid CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify:"data_files/server5.crt":"data_files/test-ca2_cat-present-past.crt":"data_files/crl-ec-sha1.pem":"NULL":0:0:"NULL"
+
+X509 Certificate verification #85 (Not yet valid CA and valid CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify:"data_files/server5.crt":"data_files/test-ca2_cat-past-present.crt":"data_files/crl-ec-sha1.pem":"NULL":0:0:"NULL"
+
 X509 Certificate verification callback: trusted EE cert
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 x509_verify_callback:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":0:"depth 0 - serial 53\:A2\:CB\:4B\:12\:4E\:AD\:83\:7D\:A8\:94\:B2 - subject CN=selfsigned, OU=testing, O=PolarSSL, C=NL\n"
@@ -755,7 +771,7 @@
 x509parse_crt:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT
 
 X509 Certificate ASN1 (Correct first tag, data length does not match)
-x509parse_crt:"300000":"":MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+x509parse_crt:"300000":"":MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA
 
 X509 Certificate ASN1 (Correct first tag, no more data)
 x509parse_crt:"3000":"":MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA
diff --git a/tests/suites/test_suite_xtea.function b/tests/suites/test_suite_xtea.function
index 68ab543..e294a9b 100644
--- a/tests/suites/test_suite_xtea.function
+++ b/tests/suites/test_suite_xtea.function
@@ -59,7 +59,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_encrypt_cbc( char *hex_key_string, char *hex_iv_string,
                        char *hex_src_string, char *hex_dst_string )
 {
@@ -90,7 +90,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_decrypt_cbc( char *hex_key_string, char *hex_iv_string,
                        char *hex_src_string, char *hex_dst_string )
 {
diff --git a/yotta/data/adjust-config.sh b/yotta/data/adjust-config.sh
index 9088fd5..6580c09 100755
--- a/yotta/data/adjust-config.sh
+++ b/yotta/data/adjust-config.sh
@@ -14,6 +14,10 @@
     $SCRIPT -f $FILE $@
 }
 
+
+# Set the target specific header
+conf set YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE \"target_config.h\"
+
 # not supported on mbed OS, nor used by mbed Client
 conf unset MBEDTLS_NET_C
 conf unset MBEDTLS_TIMING_C
@@ -68,7 +72,6 @@
 conf unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
 conf unset MBEDTLS_SSL_FALLBACK_SCSV
 conf unset MBEDTLS_SSL_CBC_RECORD_SPLITTING
-conf unset MBEDTLS_SSL_PROTO_SSL3
 conf unset MBEDTLS_SSL_PROTO_TLS1
 conf unset MBEDTLS_SSL_PROTO_TLS1_1
 conf unset MBEDTLS_SSL_TRUNCATED_HMAC
diff --git a/yotta/data/entropy_hardware_poll.c b/yotta/data/entropy_hardware_poll.c
index 1924302..3a61e22 100644
--- a/yotta/data/entropy_hardware_poll.c
+++ b/yotta/data/entropy_hardware_poll.c
@@ -1,5 +1,5 @@
 /*
- *  Temporary "entropy" collector for Cortex-M4
+ *  Hardware entropy collector for the K64F, using Freescale's RNGA
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
@@ -20,46 +20,69 @@
  */
 
 /*
- * WARNING: this is a temporary hack!
- * 1. Currently does not provide strong entropy, should be replaced to use the
- * on-board hardware RNG (see IOTSSL-303)
- * 2. This should be in a separete yotta module which would be a target
+ * WARNING: this is temporary!
+ * This should be in a separate yotta module which would be a target
  * dependency of mbedtls (see IOTSSL-313)
  */
 
-#if defined(TARGET_LIKE_CORTEX_M4)
+#if defined(TARGET_LIKE_K64F)
 
-#include "MK64F12.h"
-#include "core_cm4.h"
-#include <string.h>
+/*
+ * Reference: "K64 Sub-Family Reference Manual, Rev. 2", chapter 34
+ */
 
-unsigned long hardclock( void )
+#include "fsl_clock_manager.h"
+
+/*
+ * Get one byte of entropy from the RNG, assuming it is up and running.
+ * As recommended (34.1.1), get only one bit of each output.
+ */
+static void rng_get_byte( unsigned char *byte )
 {
-    static int dwt_started = 0;
+    size_t bit;
 
-    if( dwt_started == 0 )
+    /* 34.5 Steps 3-4-5: poll SR and read from OR when ready */
+    for( bit = 0; bit < 8; bit++ )
     {
-        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
-        DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+        while( ( RNG->SR & RNG_SR_OREG_LVL_MASK ) == 0 );
+        *byte |= ( RNG->OR & 1 ) << bit;
     }
-
-    return( DWT->CYCCNT );
 }
 
+/*
+ * Get len bytes of entropy from the hardware RNG.
+ */
 int mbedtls_hardware_poll( void *data,
                     unsigned char *output, size_t len, size_t *olen )
 {
-    unsigned long timer = hardclock();
+    size_t i;
+    int ret;
     ((void) data);
-    *olen = 0;
 
-    if( len < sizeof(unsigned long) )
-        return( 0 );
+    CLOCK_SYS_EnableRngaClock( 0 );
 
-    memcpy( output, &timer, sizeof(unsigned long) );
-    *olen = sizeof(unsigned long);
+    /* Set "Interrupt Mask", "High Assurance" and "Go",
+     * unset "Clear interrupt" and "Sleep" */
+    RNG->CR = RNG_CR_INTM_MASK | RNG_CR_HA_MASK | RNG_CR_GO_MASK;
 
-    return( 0 );
+    for( i = 0; i < len; i++ )
+        rng_get_byte( output + i );
+
+    /* Just be extra sure that we didn't do it wrong */
+    if( ( RNG->SR & RNG_SR_SECV_MASK ) != 0 )
+    {
+        ret = -1;
+        goto cleanup;
+    }
+
+    *olen = len;
+    ret = 0;
+
+cleanup:
+    /* Disable clock to save power - assume we're the only users of RNG */
+    CLOCK_SYS_DisableRngaClock( 0 );
+
+    return( ret );
 }
 
 #endif
diff --git a/yotta/data/example-authcrypt/main.cpp b/yotta/data/example-authcrypt/main.cpp
index 83d5566..23fad27 100644
--- a/yotta/data/example-authcrypt/main.cpp
+++ b/yotta/data/example-authcrypt/main.cpp
@@ -175,10 +175,6 @@
 #include "minar/minar.h"
 
 static void run() {
-    /* Use 115200 bps for consistency with other examples */
-    Serial pc(USBTX, USBRX);
-    pc.baud(115200);
-
     MBED_HOSTTEST_TIMEOUT(10);
     MBED_HOSTTEST_SELECT(default);
     MBED_HOSTTEST_DESCRIPTION(mbed TLS example authcrypt);
@@ -187,6 +183,8 @@
 }
 
 void app_start(int, char*[]) {
+    /* Use 115200 bps for consistency with other examples */
+    get_stdio_serial().baud(115200);
     minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void>(run).bind());
 }
 
diff --git a/yotta/data/example-benchmark/README.md b/yotta/data/example-benchmark/README.md
index 1a534a2..8589e7b 100644
--- a/yotta/data/example-benchmark/README.md
+++ b/yotta/data/example-benchmark/README.md
@@ -92,3 +92,9 @@
     {{success}}
     {{end}}
     ```
+
+Any performance data generated by this example application are indicative only of the performance of the mbed TLS module on the platform it's executed on.
+
+Differences in the integration of mbed TLS into the platform, such as whether all available hardware accelerators have been used or not, can lead to significant differences in performance, and so results from the program are not intended to be used to meaningfully compare platforms.
+
+The figures may also slightly change from execution to execution due to variations in the timing functions.
diff --git a/yotta/data/example-benchmark/main.cpp b/yotta/data/example-benchmark/main.cpp
index 77c7005..ef38c44 100644
--- a/yotta/data/example-benchmark/main.cpp
+++ b/yotta/data/example-benchmark/main.cpp
@@ -935,10 +935,6 @@
 #include "minar/minar.h"
 
 static void run() {
-    /* Use 115200 bps for consistency with other examples */
-    Serial pc(USBTX, USBRX);
-    pc.baud(115200);
-
     MBED_HOSTTEST_TIMEOUT(150);
     MBED_HOSTTEST_SELECT(default);
     MBED_HOSTTEST_DESCRIPTION(mbed TLS benchmark program);
@@ -947,6 +943,8 @@
 }
 
 void app_start(int, char*[]) {
+    /* Use 115200 bps for consistency with other examples */
+    get_stdio_serial().baud(115200);
     minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void>(run).bind());
 }
 
diff --git a/yotta/data/example-hashing/main.cpp b/yotta/data/example-hashing/main.cpp
index 27c469b..574152a 100644
--- a/yotta/data/example-hashing/main.cpp
+++ b/yotta/data/example-hashing/main.cpp
@@ -155,10 +155,6 @@
 #include "minar/minar.h"
 
 static void run() {
-    /* Use 115200 bps for consistency with other examples */
-    Serial pc(USBTX, USBRX);
-    pc.baud(115200);
-
     MBED_HOSTTEST_TIMEOUT(10);
     MBED_HOSTTEST_SELECT(default);
     MBED_HOSTTEST_DESCRIPTION(mbed TLS example on hashing);
@@ -167,6 +163,8 @@
 }
 
 void app_start(int, char*[]) {
+    /* Use 115200 bps for consistency with other examples */
+    get_stdio_serial().baud(115200);
     minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void>(run).bind());
 }
 
diff --git a/yotta/data/example-selftest/main.cpp b/yotta/data/example-selftest/main.cpp
index b1b15f1..0ff5b04 100644
--- a/yotta/data/example-selftest/main.cpp
+++ b/yotta/data/example-selftest/main.cpp
@@ -246,10 +246,6 @@
 #include "minar/minar.h"
 
 static void run() {
-    /* Use 115200 bps for consistency with other examples */
-    Serial pc(USBTX, USBRX);
-    pc.baud(115200);
-
     MBED_HOSTTEST_TIMEOUT(40);
     MBED_HOSTTEST_SELECT(default);
     MBED_HOSTTEST_DESCRIPTION(mbed TLS selftest program);
@@ -258,6 +254,8 @@
 }
 
 void app_start(int, char*[]) {
+    /* Use 115200 bps for consistency with other examples */
+    get_stdio_serial().baud(115200);
     minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void>(run).bind());
 }
 
diff --git a/yotta/data/module.json b/yotta/data/module.json
index 6345f08..0b8b822 100644
--- a/yotta/data/module.json
+++ b/yotta/data/module.json
@@ -1,6 +1,6 @@
 {
     "name": "mbedtls",
-    "version": "2.2.1",
+    "version": "2.3.1",
     "description": "The mbed TLS crypto/SSL/TLS library",
     "licenses": [
         {
@@ -13,6 +13,6 @@
         "mbed": { "cmsis-core": "^1.0.0" }
     },
     "testTargetDependencies": {
-        "mbed": { "mbed-drivers": "~0.11.0" }
+        "mbed": { "mbed-drivers": "^1.0.0" }
     }
 }
diff --git a/yotta/data/target_config.h b/yotta/data/target_config.h
index df1a208..f350ce3 100644
--- a/yotta/data/target_config.h
+++ b/yotta/data/target_config.h
@@ -26,10 +26,10 @@
 #endif
 
 /*
- * WARNING: this is a temporary hack!
- * 2. This should be in a separete yotta module which would be a target
+ * WARNING: this is temporary!
+ * This should be in a separate yotta module which would be a target
  * dependency of mbedtls (see IOTSSL-313)
  */
-#if defined(TARGET_LIKE_CORTEX_M4)
+#if defined(TARGET_LIKE_K64F)
 #define MBEDTLS_ENTROPY_HARDWARE_ALT
 #endif