Merge branch 'development' into development-restricted

Conflicts:
	programs/pkey/rsa_decrypt.c
	programs/pkey/rsa_encrypt.c
	programs/test/selftest.c
diff --git a/configs/config-thread.h b/configs/config-thread.h
index 453b17f..3193a04 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -85,10 +85,6 @@
 /* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
 #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
 
-#if defined(TARGET_LIKE_MBED)
-#include "mbedtls/target_config.h"
-#endif
-
 #include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index d31555d..a95af6c 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -3,7 +3,7 @@
  *
  * \brief Consistency checks for configuration options
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -130,6 +130,16 @@
 #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+    ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
+#endif
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+     ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
+    defined(MBEDTLS_HAVEGE_C) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
+#endif
+
 #if defined(MBEDTLS_GCM_C) && (                                        \
         !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
 #error "MBEDTLS_GCM_C defined, but not all prerequisites"
@@ -357,6 +367,38 @@
 #error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
+#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
+    !defined(MBEDTLS_ENTROPY_NV_SEED)
+#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
+#endif
+
 #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) ||         \
     !defined(MBEDTLS_OID_C) )
 #error "MBEDTLS_RSA_C defined, but not all prerequisites"
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 70000f5..c967554 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -57,6 +57,7 @@
 #define MBEDTLS_ERR_CIPHER_INVALID_PADDING                -0x6200  /**< Input data contains invalid padding and is rejected. */
 #define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED            -0x6280  /**< Decryption of block requires a full block. */
 #define MBEDTLS_ERR_CIPHER_AUTH_FAILED                    -0x6300  /**< Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT              -0x6380  /**< The context is invalid, eg because it was free()ed. */
 
 #define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length */
 #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 0efee04..1aa86bf 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -156,6 +156,7 @@
 //#define MBEDTLS_PLATFORM_FPRINTF_ALT
 //#define MBEDTLS_PLATFORM_PRINTF_ALT
 //#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
 
 /**
  * \def MBEDTLS_DEPRECATED_WARNING
@@ -279,6 +280,23 @@
 //#define MBEDTLS_AES_DECRYPT_ALT
 
 /**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
  * \def MBEDTLS_ENTROPY_HARDWARE_ALT
  *
  * Uncomment this macro to let mbed TLS use your own implementation of a
@@ -800,6 +818,34 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
  * \def MBEDTLS_MEMORY_DEBUG
  *
  * Enable debugging of buffer allocator memory issues. Automatically prints
@@ -2473,6 +2519,9 @@
 //#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
 
 /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
 /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
@@ -2485,6 +2534,8 @@
 //#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
 /* Note: your snprintf must correclty zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
 /* SSL Cache options */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
@@ -2513,11 +2564,7 @@
 /* X509 options */
 //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
 
-/* \} name SECTION: Module configuration options */
-
-#if defined(TARGET_LIKE_MBED)
-#include "mbedtls/target_config.h"
-#endif
+/* \} name SECTION: Customisation configuration options */
 
 /*
  * Allow user to override any previous default.
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 00de9a6..fed0494 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -3,7 +3,7 @@
  *
  * \brief Entropy accumulator implementation
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -134,6 +134,9 @@
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_threading_mutex_t mutex;    /*!< mutex                  */
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    int initial_entropy_run;
+#endif
 }
 mbedtls_entropy_context;
 
@@ -208,6 +211,18 @@
 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
                            const unsigned char *data, size_t len );
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Trigger an update of the seed file in NV by using the
+ *                  current entropy pool.
+ *
+ * \param ctx       Entropy context
+ *
+ * \return          0 if successful
+ */
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief               Write a seed file
diff --git a/include/mbedtls/entropy_poll.h b/include/mbedtls/entropy_poll.h
index dc11911..430e865 100644
--- a/include/mbedtls/entropy_poll.h
+++ b/include/mbedtls/entropy_poll.h
@@ -3,7 +3,7 @@
  *
  * \brief Platform-specific and custom entropy polling functions
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -43,6 +43,14 @@
 #define MBEDTLS_ENTROPY_MIN_HARDCLOCK     4     /**< Minimum for mbedtls_timing_hardclock()        */
 #define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
 
+/**
+ * \brief           Entropy poll callback that provides 0 entropy.
+ */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    int mbedtls_null_entropy_poll( void *data,
+                                unsigned char *output, size_t len, size_t *olen );
+#endif
+
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 /**
  * \brief           Platform-specific entropy poll callback
@@ -82,6 +90,16 @@
                            unsigned char *output, size_t len, size_t *olen );
 #endif
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Entropy poll callback for a non-volatile seed file
+ *
+ * \note            This must accept NULL as its first argument.
+ */
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen );
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index fc3672c..caf8f25 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -3,7 +3,7 @@
  *
  * \brief mbed TLS Platform abstraction layer
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -76,12 +76,24 @@
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
 #define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< Default exit value to use */
 #endif
+#if defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE   "seedfile"
+#endif
+#endif /* MBEDTLS_FS_IO */
 #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
 #include MBEDTLS_PLATFORM_STD_MEM_HDR
 #endif
 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 
+
 /* \} name SECTION: Module settings */
 
 /*
@@ -264,6 +276,47 @@
 #endif /* MBEDTLS_PLATFORM_TIME_MACRO */
 #endif /* MBEDTLS_PLATFORM_TIME_ALT */
 
+/*
+ * The function pointers for reading from and writing a seed file to
+ * Non-Volatile storage (NV) in a platform-independent way
+ *
+ * Only enabled when the NV seed entropy source is enabled
+ */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Internal standard platform definitions */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
+extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
+
+/**
+ * \brief   Set your own seed file writing/reading functions
+ *
+ * \param   nv_seed_read_func   the seed reading function implementation
+ * \param   nv_seed_write_func  the seed writing function implementation
+ *
+ * \return              0
+ */
+int mbedtls_platform_set_nv_seed(
+            int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+            int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
+            );
+#else
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
+    defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
+#define mbedtls_nv_seed_read    MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
+#define mbedtls_nv_seed_write   MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
+#else
+#define mbedtls_nv_seed_read    mbedtls_platform_std_nv_seed_read
+#define mbedtls_nv_seed_write   mbedtls_platform_std_nv_seed_write
+#endif
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/base64.c b/library/base64.c
index 3432e5f..5cb12cb 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -97,7 +97,7 @@
 
     n *= 4;
 
-    if( dlen < n + 1 )
+    if( ( dlen < n + 1 ) || ( NULL == dst ) )
     {
         *olen = n + 1;
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
diff --git a/library/camellia.c b/library/camellia.c
index d50513f..ac6f96a 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -963,38 +963,38 @@
             mbedtls_printf( "  CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
                              ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
 
-    memcpy( src, camellia_test_cbc_iv, 16 );
-    memcpy( dst, camellia_test_cbc_iv, 16 );
-    memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
-
-    if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
-        mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
-    } else {
-        mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
-    }
-
-    for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
+        memcpy( src, camellia_test_cbc_iv, 16 );
+        memcpy( dst, camellia_test_cbc_iv, 16 );
+        memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
 
         if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
-            memcpy( iv , src, 16 );
-            memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
-            memcpy( dst, camellia_test_cbc_plain[i], 16 );
-        } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
-            memcpy( iv , dst, 16 );
-            memcpy( src, camellia_test_cbc_plain[i], 16 );
-            memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
+            mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
+        } else {
+            mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
         }
 
-        mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
+        for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
 
-        if( memcmp( buf, dst, 16 ) != 0 )
-        {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
+            if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
+                memcpy( iv , src, 16 );
+                memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
+                memcpy( dst, camellia_test_cbc_plain[i], 16 );
+            } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
+                memcpy( iv , dst, 16 );
+                memcpy( src, camellia_test_cbc_plain[i], 16 );
+                memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
+            }
 
-            return( 1 );
+            mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
+
+            if( memcmp( buf, dst, 16 ) != 0 )
+            {
+                if( verbose != 0 )
+                    mbedtls_printf( "failed\n" );
+
+                return( 1 );
+            }
         }
-    }
 
         if( verbose != 0 )
             mbedtls_printf( "passed\n" );
diff --git a/library/cipher.c b/library/cipher.c
index 0dc5152..bbe40eb 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -252,6 +252,7 @@
                    size_t ilen, unsigned char *output, size_t *olen )
 {
     int ret;
+    size_t block_size = 0;
 
     if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
     {
@@ -259,10 +260,11 @@
     }
 
     *olen = 0;
+    block_size = mbedtls_cipher_get_block_size( ctx );
 
     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
     {
-        if( ilen != mbedtls_cipher_get_block_size( ctx ) )
+        if( ilen != block_size )
             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
 
         *olen = ilen;
@@ -285,8 +287,13 @@
     }
 #endif
 
+    if ( 0 == block_size )
+    {
+        return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+    }
+
     if( input == output &&
-       ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) )
+       ( ctx->unprocessed_len != 0 || ilen % block_size ) )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
@@ -300,9 +307,9 @@
          * If there is not enough data for a full block, cache it.
          */
         if( ( ctx->operation == MBEDTLS_DECRYPT &&
-                ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) ||
+                ilen + ctx->unprocessed_len <= block_size ) ||
              ( ctx->operation == MBEDTLS_ENCRYPT &&
-                ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) )
+                ilen + ctx->unprocessed_len < block_size ) )
         {
             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                     ilen );
@@ -314,22 +321,22 @@
         /*
          * Process cached data first
          */
-        if( ctx->unprocessed_len != 0 )
+        if( 0 != ctx->unprocessed_len )
         {
-            copy_len = mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len;
+            copy_len = block_size - ctx->unprocessed_len;
 
             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                     copy_len );
 
             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
-                    ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
+                    ctx->operation, block_size, ctx->iv,
                     ctx->unprocessed_data, output ) ) )
             {
                 return( ret );
             }
 
-            *olen += mbedtls_cipher_get_block_size( ctx );
-            output += mbedtls_cipher_get_block_size( ctx );
+            *olen += block_size;
+            output += block_size;
             ctx->unprocessed_len = 0;
 
             input += copy_len;
@@ -341,9 +348,14 @@
          */
         if( 0 != ilen )
         {
-            copy_len = ilen % mbedtls_cipher_get_block_size( ctx );
+            if( 0 == block_size )
+            {
+                return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+            }
+
+            copy_len = ilen % block_size;
             if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
-                copy_len = mbedtls_cipher_get_block_size( ctx );
+                copy_len = block_size;
 
             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
                     copy_len );
diff --git a/library/debug.c b/library/debug.c
index a032478..a9cd814 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -86,7 +86,7 @@
     char str[DEBUG_BUF_SIZE];
     int ret;
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+    if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold )
         return;
 
     va_start( argp, format );
diff --git a/library/ecp.c b/library/ecp.c
index 19bb488..f51f225 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1827,7 +1827,9 @@
         /* [M225] page 5 */
         size_t b;
 
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+        do {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+        } while( mbedtls_mpi_bitlen( d ) == 0);
 
         /* Make sure the most significant bit is nbits */
         b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
diff --git a/library/entropy.c b/library/entropy.c
index cdbd35c..282640f 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -1,7 +1,7 @@
 /*
  *  Entropy accumulator implementation
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -27,6 +27,12 @@
 
 #if defined(MBEDTLS_ENTROPY_C)
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+#warning "**** WARNING!  MBEDTLS_TEST_NULL_ENTROPY defined! ****"
+#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES    ****"
+#warning "**** NOT SUITABLE FOR PRODUCTION                  ****"
+#endif
+
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
@@ -73,6 +79,11 @@
     mbedtls_havege_init( &ctx->havege_data );
 #endif
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
+                                1, MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+
 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
     mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
@@ -94,6 +105,11 @@
                                 MBEDTLS_ENTROPY_MIN_HARDWARE,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG );
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
+                                MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
 }
 
@@ -272,6 +288,18 @@
     if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    /* Update the NV entropy seed before generating any entropy for outside
+     * use.
+     */
+    if( ctx->initial_entropy_run == 0 )
+    {
+        ctx->initial_entropy_run = 1;
+        if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
+            return( ret );
+    }
+#endif
+
 #if defined(MBEDTLS_THREADING_C)
     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
         return( ret );
@@ -346,6 +374,27 @@
     return( ret );
 }
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
+{
+    int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
+
+    /* Read new seed  and write it to NV */
+    if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        return( ret );
+
+    if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+
+    /* Manually update the remaining stream with a separator value to diverge */
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #if defined(MBEDTLS_FS_IO)
 int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
 {
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index e2f45c7..a116e60 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -1,7 +1,7 @@
 /*
  *  Platform-specific and custom entropy polling functions
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -37,6 +37,9 @@
 #if defined(MBEDTLS_HAVEGE_C)
 #include "mbedtls/havege.h"
 #endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#include "mbedtls/platform.h"
+#endif
 
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 
@@ -188,6 +191,23 @@
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+int mbedtls_null_entropy_poll( void *data,
+                    unsigned char *output, size_t len, size_t *olen )
+{
+    ((void) data);
+    ((void) output);
+    *olen = 0;
+
+    if( len < sizeof(unsigned char) )
+        return( 0 );
+
+    *olen = sizeof(unsigned char);
+
+    return( 0 );
+}
+#endif
+
 #if defined(MBEDTLS_TIMING_C)
 int mbedtls_hardclock_poll( void *data,
                     unsigned char *output, size_t len, size_t *olen )
@@ -222,4 +242,27 @@
 }
 #endif /* MBEDTLS_HAVEGE_C */
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen )
+{
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    ((void) data);
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+      return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+    if( len < use_len )
+      use_len = len;
+
+    memcpy( output, buf, use_len );
+    *olen = use_len;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #endif /* MBEDTLS_ENTROPY_C */
diff --git a/library/error.c b/library/error.c
index 4718b51..4bd15bf 100644
--- a/library/error.c
+++ b/library/error.c
@@ -183,6 +183,8 @@
             mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
             mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" );
 #endif /* MBEDTLS_CIPHER_C */
 
 #if defined(MBEDTLS_DHM_C)
diff --git a/library/platform.c b/library/platform.c
index 89a2bd6..68ca45d 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -1,7 +1,7 @@
 /*
  *  Platform abstraction layer
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -213,4 +213,91 @@
 }
 #endif /* MBEDTLS_PLATFORM_TIME_ALT */
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Default implementations for the platform independent seed functions use
+ * standard libc file functions to read from and write to a pre-defined filename
+ */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+        return -1;
+
+    if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        return -1;
+    }
+
+    fclose( file );
+    return( n );
+}
+
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+        return -1;
+
+    if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        return -1;
+    }
+
+    fclose( file );
+    return( n );
+}
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   platform_nv_seed_read_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
+
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE   platform_nv_seed_write_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
+
+int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_READ;
+int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
+
+int mbedtls_platform_set_nv_seed(
+        int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+        int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) )
+{
+    mbedtls_nv_seed_read = nv_seed_read_func;
+    mbedtls_nv_seed_write = nv_seed_write_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
 #endif /* MBEDTLS_PLATFORM_C */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9208ec9..80a908d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5773,7 +5773,7 @@
 {
     mbedtls_ecjpake_role role;
 
-    if( ssl->handshake == NULL && ssl->conf == NULL )
+    if( ssl->handshake == NULL || ssl->conf == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
diff --git a/library/version_features.c b/library/version_features.c
index b852ca8..5d20ba0 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -66,6 +66,9 @@
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
     "MBEDTLS_PLATFORM_SNPRINTF_ALT",
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+    "MBEDTLS_PLATFORM_NV_SEED_ALT",
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
 #if defined(MBEDTLS_DEPRECATED_WARNING)
     "MBEDTLS_DEPRECATED_WARNING",
 #endif /* MBEDTLS_DEPRECATED_WARNING */
@@ -156,6 +159,9 @@
 #if defined(MBEDTLS_AES_DECRYPT_ALT)
     "MBEDTLS_AES_DECRYPT_ALT",
 #endif /* MBEDTLS_AES_DECRYPT_ALT */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    "MBEDTLS_TEST_NULL_ENTROPY",
+#endif /* MBEDTLS_TEST_NULL_ENTROPY */
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     "MBEDTLS_ENTROPY_HARDWARE_ALT",
 #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
@@ -291,6 +297,9 @@
 #if defined(MBEDTLS_ENTROPY_FORCE_SHA256)
     "MBEDTLS_ENTROPY_FORCE_SHA256",
 #endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    "MBEDTLS_ENTROPY_NV_SEED",
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
 #if defined(MBEDTLS_MEMORY_DEBUG)
     "MBEDTLS_MEMORY_DEBUG",
 #endif /* MBEDTLS_MEMORY_DEBUG */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index c3adf7c..af6c2a4 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -970,7 +970,9 @@
 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
 {
     int success = 0, first_error = 0, total_failed = 0;
+#if defined(MBEDTLS_PEM_PARSE_C)
     int buf_format = MBEDTLS_X509_FORMAT_DER;
+#endif
 
     /*
      * Check for valid input
@@ -988,10 +990,12 @@
     {
         buf_format = MBEDTLS_X509_FORMAT_PEM;
     }
-#endif
 
     if( buf_format == MBEDTLS_X509_FORMAT_DER )
         return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#else
+    return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#endif
 
 #if defined(MBEDTLS_PEM_PARSE_C)
     if( buf_format == MBEDTLS_X509_FORMAT_PEM )
@@ -1064,7 +1068,6 @@
             success = 1;
         }
     }
-#endif /* MBEDTLS_PEM_PARSE_C */
 
     if( success )
         return( total_failed );
@@ -1072,6 +1075,7 @@
         return( first_error );
     else
         return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
+#endif /* MBEDTLS_PEM_PARSE_C */
 }
 
 #if defined(MBEDTLS_FS_IO)
@@ -1353,6 +1357,14 @@
     p = buf;
     n = size;
 
+    if( NULL == crt )
+    {
+        ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        return( (int) ( size - n ) );
+    }
+
     ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
                                prefix, crt->version );
     MBEDTLS_X509_SAFE_SNPRINTF;
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 102144e..a14d20c 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -184,7 +184,12 @@
         mbedtls_fprintf( stderr, "Message Digest '%s' not found\n", argv[5] );
         goto exit;
     }
-    mbedtls_md_setup( &md_ctx, md_info, 1 );
+
+    if( mbedtls_md_setup( &md_ctx, md_info, 1 ) != 0 )
+    {
+        mbedtls_fprintf( stderr, "mbedtls_md_setup failed\n" );
+        goto exit;
+    }
 
     /*
      * Read the secret key and clean the command line.
@@ -399,6 +404,15 @@
             goto exit;
         }
 
+        if( mbedtls_cipher_get_block_size( &cipher_ctx ) == 0 )
+        {
+            mbedtls_fprintf( stderr, "Invalid cipher block size: 0. \n" );
+            goto exit;
+        }
+
+        /*
+         * Check the file size.
+         */
         if( ( ( filesize - mbedtls_md_get_size( md_info ) ) %
                 mbedtls_cipher_get_block_size( &cipher_ctx ) ) != 0 )
         {
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 230bf4d..8ebf34a 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -125,6 +125,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index d30c73b..072fe13 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -172,6 +172,7 @@
         ( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_write_file returned %d\n\n", ret );
+        fclose( fout );
         goto exit;
     }
 
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index cb156f7..7eef845 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -132,6 +132,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
@@ -157,6 +158,7 @@
         mbedtls_mpi_read_file( &dhm.G, 16, f ) != 0 )
     {
         mbedtls_printf( " failed\n  ! Invalid DH parameter file\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 322e8af..daf08a9 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -142,6 +142,7 @@
     if( fwrite( buf, 1, olen, f ) != olen )
     {
         mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index 57c6720..1cc013d 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -125,6 +125,7 @@
         exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n",
                         return_val );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index e78e273..b9cb187 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -118,6 +118,7 @@
         exit_val = MBEDTLS_EXIT_FAILURE;
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n",
                         return_val );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index 27f3566..affbf7a 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -97,6 +97,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index c045a04..7b6f14d 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -153,6 +153,7 @@
     if( fwrite( buf, 1, olen, f ) != olen )
     {
         mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index a22b555..1f827aa 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -89,6 +89,7 @@
         ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
+        fclose( f );
         goto exit;
     }
 
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index e57a78e..00aa5c6 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -397,6 +397,7 @@
     if( suites_failed > 0)
         mbedtls_exit( MBEDTLS_EXIT_FAILURE );
 
+    /* return() is here to prevent compiler warnings */
     return( MBEDTLS_EXIT_SUCCESS );
 }
 
diff --git a/scripts/config.pl b/scripts/config.pl
index a6dcfe7..84ec38e 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -18,6 +18,7 @@
 #
 # Things that shouldn't be enabled with "full".
 #
+#   MBEDTLS_TEST_NULL_ENTROPY
 #   MBEDTLS_DEPRECATED_REMOVED
 #   MBEDTLS_HAVE_SSE2
 #   MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
@@ -69,6 +70,7 @@
 EOU
 
 my @excluded = qw(
+MBEDTLS_TEST_NULL_ENTROPY
 MBEDTLS_DEPRECATED_REMOVED
 MBEDTLS_HAVE_SSE2
 MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index c3b708f..469827e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -266,6 +266,22 @@
 scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
 CC=gcc CFLAGS='-Werror -O0 -std=c99 -pedantic' make lib
 
+msg "build: default config with  MBEDTLS_TEST_NULL_ENTROPY (ASan build)"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl set MBEDTLS_TEST_NULL_ENTROPY
+scripts/config.pl set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+scripts/config.pl set MBEDTLS_ENTROPY_C
+scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+scripts/config.pl unset MBEDTLS_ENTROPY_HARDWARE_ALT
+scripts/config.pl unset MBEDTLS_HAVEGE_C
+CC=gcc cmake -D CMAKE_C_FLAGS:String="-fsanitize=address -fno-common -O3" .
+make
+
+msg "test: MBEDTLS_TEST_NULL_ENTROPY - main suites and selftest (ASan build)"
+make test
+programs/test/selftest
+
 if uname -a | grep -F Linux >/dev/null; then
 msg "build/test: make shared" # ~ 40s
 cleanup
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index 010c0c6..9fab396 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -36,10 +36,13 @@
     exit 1
 fi
 
+CONFIG_H='include/mbedtls/config.h'
+CONFIG_BAK="$CONFIG_H.bak"
 
 # Step 1 - Make and instrumented build for code coverage
 export CFLAGS=' --coverage -g3 -O0 '
 make clean
+cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
 scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
 make -j
@@ -204,3 +207,9 @@
 rm cov-$TEST_OUTPUT
 
 cd ..
+
+make clean
+
+if [ -f "$CONFIG_BAK" ]; then
+    mv "$CONFIG_BAK" "$CONFIG_H"
+fi
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
index 833eef5..5ca99f8 100644
--- a/tests/suites/test_suite_entropy.data
+++ b/tests/suites/test_suite_entropy.data
@@ -1,3 +1,6 @@
+Create NV seed_file
+nv_seed_file_create:
+
 Entropy write/update seed file
 entropy_seed_file:"data_files/entropy_seed":0
 
@@ -37,5 +40,17 @@
 Entropy thershold #4
 entropy_threshold:1024:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
+Check NV seed standard IO
+entropy_nv_seed_std_io:
+
+Check NV seed manually #1
+entropy_nv_seed:"00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF"
+
+Check NV seed manually #2
+entropy_nv_seed:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+
+Check NV seed manually #3
+entropy_nv_seed:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+
 Entropy self test
 entropy_selftest:
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 3b739cc..d1ef94b 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -1,5 +1,6 @@
 /* BEGIN_HEADER */
 #include "mbedtls/entropy.h"
+#include "mbedtls/entropy_poll.h"
 
 /*
  * Number of calls made to entropy_dummy_source()
@@ -33,6 +34,88 @@
 
     return( 0 );
 }
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/*
+ * Ability to clear entropy sources to allow testing with just predefined
+ * entropy sources. This function or tests depending on it might break if there
+ * are internal changes to how entropy sources are registered.
+ *
+ * To be called immediately after mbedtls_entropy_init().
+ *
+ * Just resetting the counter. New sources will overwrite existing ones.
+ * This might break memory checks in the future if sources need 'free-ing' then
+ * as well.
+ */
+static void entropy_clear_sources( mbedtls_entropy_context *ctx )
+{
+    ctx->source_count = 0;
+}
+
+/*
+ * NV seed read/write functions that use a buffer instead of a file
+ */
+static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    return( 0 );
+}
+
+static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    return( 0 );
+}
+
+/*
+ * NV seed read/write helpers that fill the base seedfile
+ */
+static int write_nv_seed( unsigned char *buf, size_t buf_len )
+{
+    FILE *f;
+
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+        return( -1 );
+
+    if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
+                    MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    fclose( f );
+
+    return( 0 );
+}
+
+static int read_nv_seed( unsigned char *buf, size_t buf_len )
+{
+    FILE *f;
+
+    if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+        return( -1 );
+
+    if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
+                    MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( -1 );
+
+    fclose( f );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -160,6 +243,10 @@
     if( result >= 0 )
     {
         TEST_ASSERT( ret == 0 );
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+        // Two times as much calls due to the NV seed update
+        result *= 2;
+#endif
         TEST_ASSERT( entropy_dummy_calls == (size_t) result );
     }
     else
@@ -172,6 +259,124 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void nv_seed_file_create()
+{
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
+void entropy_nv_seed_std_io()
+{
+    unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
+                                  mbedtls_platform_std_nv_seed_write );
+
+    /* Check if platform NV read and write manipulate the same data */
+    TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+    TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
+                    MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    /* Check if platform NV write and raw read manipulate the same data */
+    TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
+                    MBEDTLS_ENTROPY_BLOCK_SIZE );
+    TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT:MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
+void entropy_nv_seed( char *read_seed_str )
+{
+    mbedtls_sha512_context accumulator;
+    mbedtls_entropy_context ctx;
+
+    unsigned char header[2];
+    unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char read_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( buffer_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    // Set the initial NV seed to read
+    unhexify( read_seed, read_seed_str );
+    memcpy( buffer_seed, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    // Make sure we read/write NV seed from our buffers
+    mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
+
+    mbedtls_entropy_init( &ctx );
+    entropy_clear_sources( &ctx );
+
+    TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
+                                             MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                             MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
+
+    // Do an entropy run
+    TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
+
+    // Determine what should have happened with manual entropy internal logic
+    // Only use the SHA-512 version to check
+
+    // Init accumulator
+    header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    mbedtls_sha512_starts( &accumulator, 0 );
+
+    // First run for updating write_seed
+    header[0] = 0;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha512_finish( &accumulator, buf );
+
+    memset( &accumulator, 0, sizeof( mbedtls_sha512_context ) );
+    mbedtls_sha512_starts( &accumulator, 0 );
+    mbedtls_sha512_update( &accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_seed, 0 );
+
+    // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
+    header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, empty, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    header[0] = 0;
+    mbedtls_sha512_update( &accumulator, header, 2 );
+    mbedtls_sha512_update( &accumulator, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha512_finish( &accumulator, buf );
+
+    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_entropy, 0 );
+
+    // Check result of both NV file and entropy received with the manual calculations
+    TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+    TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
+
+    mbedtls_entropy_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void entropy_selftest( )
 {