Merge pull request #409 from attilamolnar/fix-handle-leak

Fix handle leak in mbedtls_platform_entropy_poll() on Windows on error
diff --git a/.travis.yml b/.travis.yml
index dbc2347..fa01e5a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,8 @@
 - 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="
diff --git a/ChangeLog b/ChangeLog
index 71aa605..3b32873 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
 
 = mbed TLS 2.x branch
 
+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
@@ -9,11 +13,27 @@
    * 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
 
 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).
 
 = mbed TLS 2.2.1 released 2016-01-05
 
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/include/mbedtls/config.h b/include/mbedtls/config.h
index d1db0d8..0efee04 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -152,6 +152,7 @@
  * 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
@@ -1058,7 +1059,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 +1898,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 +2256,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 +2274,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,16 +2466,21 @@
 //#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 */
 
 /* 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! */
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/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..039cb58 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -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,7 +65,16 @@
 #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
 #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
@@ -207,6 +217,51 @@
 #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
+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 */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index ff5f389..96643eb 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -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 wait 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 is passed,
+ *                  1 if only the intermediate delay is passed,
+ *                  2 if the final delay is 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)
@@ -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
  */
@@ -978,8 +1088,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 +1099,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,24 +1133,29 @@
 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
@@ -1309,9 +1430,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 */
@@ -1459,7 +1595,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 +1620,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
@@ -1747,8 +1894,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 should be as long as the
+ *                 SSL configuration structure.
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
@@ -1862,11 +2012,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
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/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/bignum.c b/library/bignum.c
index 7841bea..d6f415c 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 );
     }
 
@@ -126,7 +126,7 @@
         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 );
         }
 
@@ -164,7 +164,7 @@
     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 );
     }
 
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..a032478 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
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 01bd58e..e2f45c7 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -39,6 +39,12 @@
 #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)
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/platform.c b/library/platform.c
index d634c62..89a2bd6 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -190,4 +190,27 @@
 }
 #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 */
+
 #endif /* MBEDTLS_PLATFORM_C */
diff --git a/library/rsa.c b/library/rsa.c
index fba68dd..18fc702 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -102,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:
@@ -112,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;
@@ -590,7 +596,8 @@
     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;
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..9fc21a5 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
@@ -2210,7 +2212,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 +2255,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 +2304,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)
@@ -2718,7 +2720,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..19cc357 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;
@@ -3706,10 +3707,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 +5012,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 +5599,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 +5616,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;
@@ -6949,7 +6951,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..b852ca8 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 */
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_crt.c b/library/x509_crt.c
index 6dc5ad3..c3adf7c 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  {
      */
@@ -1600,7 +1604,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 +1618,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 +1939,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 +1984,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..f8c45f8 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -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;
 
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..545e2fb 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -127,7 +127,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 +148,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 +156,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 +164,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 +181,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 +191,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 +205,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 +219,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 +330,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 +346,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 +356,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 +368,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..6ca07bb 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -52,15 +52,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)
@@ -99,7 +102,7 @@
 
 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 +117,7 @@
     if( pointer != NULL )
     {
         mbedtls_printf( "all-bits-zero is not a NULL pointer\n" );
-        return( 1 );
+        mbedtls_exit( MBEDTLS_EXIT_FAILURE );
     }
 
     /*
@@ -123,11 +126,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 +147,213 @@
 #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( 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 +369,34 @@
 
 #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 );
+
+    mbedtls_exit( 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/config.pl b/scripts/config.pl
index d4c32fd..a6dcfe7 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -1,22 +1,73 @@
 #!/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. 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> | full | realfull]
+#
+# Full usage description provided below.
+#
+# Things that shouldn't be enabled with "full".
+#
+#   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> | 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 <symnol> 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 any #define present 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_DEPRECATED_REMOVED
 MBEDTLS_HAVE_SSE2
@@ -40,40 +91,65 @@
 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") {
+            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;
+# Check the config file is present
+if (! -f $config_file)  {
 
-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;
+    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>;
@@ -122,9 +198,27 @@
     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 "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/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/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 1cca818..23eb2a4 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
     )
 
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 2f716bb..5ecf868 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
@@ -22,23 +32,16 @@
 
 MEMORY=0
 SHORT=0
+FORCE=0
 
-while [ $# -gt 0 ]; do
-    case "$1" in
-        -m*)
-            MEMORY=${1#-m}
-            ;;
-        -s)
-            SHORT=1
-            ;;
-        *)
-            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()
@@ -66,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
@@ -125,9 +172,25 @@
 msg "test: compat.sh (ASan build)" # ~ 6 min
 tests/compat.sh
 
-msg "build: cmake, full config, clang" # ~ 50s
+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
 scripts/config.pl full
 scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
 CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check .
@@ -222,6 +285,7 @@
 scripts/config.pl unset MBEDTLS_NET_C
 scripts/config.pl unset MBEDTLS_TIMING_C
 scripts/config.pl unset MBEDTLS_FS_IO
+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
@@ -241,6 +305,7 @@
 scripts/config.pl unset MBEDTLS_FS_IO
 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
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
new file mode 100755
index 0000000..d961230
--- /dev/null
+++ b/tests/scripts/basic-build-test.sh
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+# basic-build-tests.sh
+#
+# 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
+
+
+# Step 1 - Make and instrumented build for code coverage
+export CFLAGS=' --coverage -g3 -O0 '
+make clean
+scripts/config.pl full
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+make
+
+
+# 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 ..
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/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/ssl-opt.sh b/tests/ssl-opt.sh
index c0b6f94..c08af7b 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -695,6 +695,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,6 +708,7 @@
             -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" \
@@ -754,6 +756,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,6 +768,7 @@
             -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" \
@@ -883,6 +887,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 +1559,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 +1737,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 +2657,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 +2707,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 +2715,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 \
@@ -2783,6 +2850,7 @@
 
 # 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 +2858,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 \
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 8f681db..edf1d12 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -1,28 +1,69 @@
+#line 1 "helpers.function"
+/*----------------------------------------------------------------------------*/
+/* Headers */
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
 #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 +94,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 +349,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..c5d6cd8 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,12 +61,22 @@
 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 )
@@ -111,7 +84,7 @@
 
 DEP_CHECK_CODE
 
-    return( 1 );
+    return( DEPENDENCY_NOT_SUPPORTED );
 }
 
 int dispatch_test(int cnt, char *params[50])
@@ -121,18 +94,41 @@
     ((void) params);
 
 #if defined(TEST_SUITE_ACTIVE)
+    ret = DISPATCH_TEST_SUCCESS;
+
 DISPATCH_FUNCTION
     {
-        mbedtls_fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
+        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 +174,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 +236,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 +282,152 @@
         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++ )
+    {
+        test_filename = test_files[ testfile_index ];
 
-        total_tests++;
-
-        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 ) )
+        {
+            int unmet_dep_count = 0;
+            char *unmet_dependencies[20];
+
+            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 )
+                    {
+                        unmet_dependencies[ i-1 ] = strdup(params[i]);
+                        if(  unmet_dependencies[ i-1 ] == NULL )
+                        {
+                            mbedtls_printf("FATAL: Out of memory\n");
+                            mbedtls_exit( MBEDTLS_EXIT_FAILURE );
+                        }
+                        unmet_dep_count++;
+                    }
+                }
 
-        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++;
+                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( ( 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( 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: " );
+                    while( unmet_dep_count > 0)
+                    {
+                        mbedtls_fprintf(stdout, "%s  ",
+                                        unmet_dependencies[unmet_dep_count - 1]);
+                        free(unmet_dependencies[unmet_dep_count - 1]);
+                        unmet_dep_count--;
+                    }
+                    mbedtls_fprintf( stdout, "\n" );
+                }
+                fflush( stdout );
+            }
+            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);
     }
-    fclose(file);
 
     mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
     if( total_errors == 0 )
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_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_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/yotta/data/adjust-config.sh b/yotta/data/adjust-config.sh
index 9088fd5..170d307 100755
--- a/yotta/data/adjust-config.sh
+++ b/yotta/data/adjust-config.sh
@@ -68,7 +68,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..f303783 100644
--- a/yotta/data/module.json
+++ b/yotta/data/module.json
@@ -1,6 +1,6 @@
 {
     "name": "mbedtls",
-    "version": "2.2.1",
+    "version": "2.3.0",
     "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