Merge pull request #457 from NWilson/clang-analyze-fixes

Clang analyze fixes
diff --git a/ChangeLog b/ChangeLog
index 007f604..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
@@ -16,12 +20,20 @@
      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. 
+   * 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/include/mbedtls/config.h b/include/mbedtls/config.h
index a617d06..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
@@ -2465,6 +2466,7 @@
 //#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! */
@@ -2477,6 +2479,8 @@
 //#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/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 1371ff1..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  */
@@ -66,6 +67,9 @@
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT)
 #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
@@ -227,6 +231,37 @@
 #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 3e05f3f..96643eb 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -542,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 */
@@ -976,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
  */
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/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/library/bignum.c b/library/bignum.c
index 81af57d..4536a3b 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 972ad2a..e2f45c7 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -67,7 +67,10 @@
     }
 
     if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
+    {
+        CryptReleaseContext( provider, 0 );
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    }
 
     CryptReleaseContext( provider, 0 );
     *olen = len;
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 3b78b6b..4142bc0 100644
--- a/library/net.c
+++ b/library/net.c
@@ -32,6 +32,13 @@
 #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>
@@ -86,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 60559e2..9386a76 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 d1ef7dd..509484e 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)
@@ -269,6 +271,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;
     }
 
@@ -288,7 +296,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;
     }
@@ -663,7 +670,7 @@
     int ret;
     unsigned char *p = ssl->handshake->randbytes;
 #if defined(MBEDTLS_HAVE_TIME)
-    time_t t;
+    mbedtls_time_t t;
 #endif
 
     /*
@@ -678,7 +685,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 );
@@ -1586,7 +1593,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;
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 6bd0b59..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)
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 2e41bca..9208ec9 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;
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/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 26082ef..d3954c5 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -43,12 +43,14 @@
 #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/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/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/scripts/all.sh b/tests/scripts/all.sh
index 1cc8256..5ecf868 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2,20 +2,24 @@
 
 # all.sh
 #
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
 # Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
 #
 # Purpose
 #
-# Run all available tests (mostly).
+# To run all tests possible or available on the platform.
 #
-# 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!
+# 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.
 #
-# 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.
+# 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
@@ -28,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()
@@ -72,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
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index ffca6f9..d961230 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -37,7 +37,10 @@
 
 # Step 1 - Make and instrumented build for code coverage
 export CFLAGS=' --coverage -g3 -O0 '
-make clean; make
+make clean
+scripts/config.pl full
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+make
 
 
 # Step 2 - Execute the tests
diff --git a/tests/scripts/generate_code.pl b/tests/scripts/generate_code.pl
index 5c623f8..49af2db 100755
--- a/tests/scripts/generate_code.pl
+++ b/tests/scripts/generate_code.pl
@@ -2,6 +2,8 @@
 
 # generate_code.pl
 #
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
 # Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
 #
 # Purpose
@@ -19,13 +21,15 @@
 #       test dispatch code as well as support functions. It contains the
 #       following symbols which are substituted by this script during
 #       processing:
-#           TEST_FILENAME
+#           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
@@ -42,8 +46,8 @@
 #
 #   - 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 'TEST_FILENAME' in the main code
-#       file above.
+#       file name is used to replace the symbol 'TESTCASE_FILENAME' in the main
+#       code file above.
 #
 
 use strict;
@@ -60,23 +64,59 @@
 my $line_separator = $/;
 undef $/;
 
+
+#
+# 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;
@@ -157,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;
@@ -177,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)
@@ -202,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 |\\+\\-\\(\\)]+)";
@@ -211,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]+";
         }
@@ -248,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/;
 }
 
@@ -283,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
@@ -298,7 +342,7 @@
     if( strcmp( str, "$key" ) == 0 )
     {
         *value = ( $key );
-        return( 0 );
+        return( KEY_VALUE_MAPPING_FOUND );
     }
 END
 
@@ -315,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
index fb77e15..58f827c 100755
--- a/tests/scripts/run-test-suites.pl
+++ b/tests/scripts/run-test-suites.pl
@@ -2,6 +2,8 @@
 
 # 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
@@ -66,7 +68,8 @@
         print "(test cases passed:", $suite_cases_passed,
                 " failed:", $suite_cases_failed,
                 " skipped:", $suite_cases_skipped,
-                " of total:", ( $suite_cases_passed + $suite_cases_failed ),
+                " of total:", ($suite_cases_passed + $suite_cases_failed +
+                               $suite_cases_skipped),
                 ")\n"
     }
 
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index c18eed8..edf1d12 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -1,3 +1,4 @@
+#line 1 "helpers.function"
 /*----------------------------------------------------------------------------*/
 /* Headers */
 
@@ -5,14 +6,19 @@
 #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)
@@ -22,19 +28,28 @@
 #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>
 
 
 /*----------------------------------------------------------------------------*/
-/* Global variables */
+/* Constants */
 
-static int test_errors = 0;
+#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
 
 
 /*----------------------------------------------------------------------------*/
@@ -44,7 +59,7 @@
     do {                                            \
         if( ! (TEST) )                              \
         {                                           \
-            test_fail( #TEST );                     \
+            test_fail( #TEST, __LINE__, __FILE__ ); \
             goto exit;                              \
         }                                           \
     } while( 0 )
@@ -81,6 +96,12 @@
 
 
 /*----------------------------------------------------------------------------*/
+/* Global variables */
+
+static int test_errors = 0;
+
+
+/*----------------------------------------------------------------------------*/
 /* Helper Functions */
 
 static int unhexify( unsigned char *obuf, const char *ibuf )
@@ -329,11 +350,11 @@
     return( 0 );
 }
 
-static void test_fail( const char *test )
+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", test );
+    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 7ec69b4..c5d6cd8 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -1,3 +1,4 @@
+#line 1 "main_test.function"
 SUITE_PRE_DEP
 #define TEST_SUITE_ACTIVE
 
@@ -60,7 +61,7 @@
 MAPPING_CODE
 
     mbedtls_printf( "Expected integer for parameter and got: %s\n", str );
-    return( -1 );
+    return( KEY_VALUE_MAPPING_NOT_FOUND );
 }
 
 
@@ -70,6 +71,8 @@
 FUNCTION_CODE
 SUITE_POST_DEP
 
+#line !LINE_NO! "main_test.function"
+
 
 /*----------------------------------------------------------------------------*/
 /* Test dispatch code */
@@ -81,7 +84,7 @@
 
 DEP_CHECK_CODE
 
-    return( 1 );
+    return( DEPENDENCY_NOT_SUPPORTED );
 }
 
 int dispatch_test(int cnt, char *params[50])
@@ -91,14 +94,18 @@
     ((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 );
 }
@@ -107,6 +114,21 @@
 /*----------------------------------------------------------------------------*/
 /* 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;
@@ -216,11 +238,18 @@
 
 int main(int argc, const char *argv[])
 {
-    int testfile_index, testfile_count, ret, i, cnt;
-    int total_errors = 0, total_tests = 0, total_skipped = 0;
-    const char *default_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];
@@ -253,17 +282,41 @@
         return( 0 );
     }
 
-    if ( argc <= 1 )
+    while( arg_index < argc)
+    {
+        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++;
+    }
+
+    /* If no files were specified, assume a default */
+    if ( test_files == NULL || testfile_count == 0 )
     {
         test_files = &default_filename;
         testfile_count = 1;
     }
-    else
-    {
-        test_files = &argv[1];
-        testfile_count = argc - 1;
-    }
 
+    /* Now begin to execute the tests in the testfiles */
     for ( testfile_index = 0;
           testfile_index < testfile_count;
           testfile_index++ )
@@ -280,7 +333,8 @@
 
         while( !feof( file ) )
         {
-            int skip = 0;
+            int unmet_dep_count = 0;
+            char *unmet_dependencies[20];
 
             if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
                 break;
@@ -300,32 +354,61 @@
             if( strcmp( params[0], "depends_on" ) == 0 )
             {
                 for( i = 1; i < cnt; i++ )
-                    if( dep_check( params[i] ) != 0 )
-                        skip = 1;
+                {
+                    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( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
                     break;
                 cnt = parse_arguments( buf, strlen(buf), params );
             }
-
-            if( skip == 0 )
+ 
+            // If there are no unmet dependencies execute the test
+            if( unmet_dep_count == 0 )
             {
                 test_errors = 0;
                 ret = dispatch_test( cnt, params );
             }
 
-            if( skip == 1 || ret == 3 )
+            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 == 0 && test_errors == 0 )
+            else if( ret == DISPATCH_TEST_SUCCESS && test_errors == 0 )
             {
                 mbedtls_fprintf( stdout, "PASS\n" );
                 fflush( stdout );
             }
-            else if( ret == 2 )
+            else if( ret == DISPATCH_INVALID_TEST_DATA )
             {
                 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
                 fclose(file);
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/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/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