Merge pull request #3553 from AndrzejKurek/crc-calculation-base

Validate AES keys after each use checking CRC 
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index adab7a1..44cf94a 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -130,11 +130,11 @@
  */
 #define MBEDTLS_OID_CMP(oid_str, oid_buf)                                   \
         ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) ||                \
-          mbedtls_platform_memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+          mbedtls_platform_memequal( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
 
 #define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len)                  \
         ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) ||                 \
-          mbedtls_platform_memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
+          mbedtls_platform_memequal( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index 6e0fb8d..bd6de87 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/include/mbedtls/compat-1.3.h
@@ -2231,7 +2231,7 @@
 #define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext
 #define rsa_self_test mbedtls_rsa_self_test
 #define rsa_set_padding mbedtls_rsa_set_padding
-#define safer_memcmp mbedtls_platform_memcmp
+#define safer_memcmp mbedtls_platform_memequal
 #define set_alarm mbedtls_set_alarm
 #define sha1 mbedtls_sha1
 #define sha1_context mbedtls_sha1_context
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index eec05e4..19a7c44 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -77,6 +77,9 @@
 #define MBEDTLS_HMAC_DRBG_PR_OFF   0x55555555   /**< No prediction resistance       */
 #define MBEDTLS_HMAC_DRBG_PR_ON    0x2AAAAAAA   /**< Prediction resistance enabled  */
 
+#define MBEDTLS_HMAC_DRBG_RESEED    0x78547854   /**< Default environment, reseeding enabled */
+#define MBEDTLS_HMAC_DRBG_NO_RESEED 0x07AB87F0   /**< Reseeding disabled, no f_entropy required */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -91,7 +94,7 @@
     mbedtls_md_context_t md_ctx;                    /*!< HMAC context (inc. K)  */
     unsigned char V[MBEDTLS_MD_MAX_SIZE];  /*!< V in the spec          */
     int reseed_counter;                     /*!< reseed counter         */
-
+    int reseed_flag;  /*!< disables reseeding if set to MBEDTLS_HMAC_DRBG_NO_RESEED */
     /* Administrative state */
     size_t entropy_len;         /*!< entropy bytes grabbed on each (re)seed */
     int prediction_resistance;  /*!< enable prediction resistance (Automatic
@@ -221,6 +224,20 @@
                                           int resistance );
 
 /**
+ * \brief               This function turns reseeding on or off.
+ *                      Default value is on.
+ *
+ * \note                If set to MBEDTLS_HMAC_DRBG_NO_RESEED, this function
+ *                      disables reseeding, providing a no_reseed environment.
+ *                      f_entropy can then be null.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param reseed_flag   #MBEDTLS_HMAC_DRBG_NO_RESEED or #MBEDTLS_HMAC_DRBG_RESEED
+ */
+void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx,
+                                      int reseed_flag );
+
+/**
  * \brief               This function sets the amount of entropy grabbed on each
  *                      seed or reseed.
  *
@@ -228,9 +245,11 @@
  *
  * \param ctx           The HMAC_DRBG context.
  * \param len           The amount of entropy to grab, in bytes.
+ *
+ * \return              \c 0 if \p len is valid, MBEDTLS_HMAC_DRBG_MAX_INPUT otherwise.
  */
-void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
-                                size_t len );
+int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
+                                       size_t len );
 
 /**
  * \brief               Set the reseed interval.
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 7d16074..c65c853 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -161,40 +161,43 @@
  * \param buf   Buffer to be zeroized
  * \param len   Length of the buffer in bytes
  *
+ * \return      The value of \p buf if the operation was successful.
+ * \return      NULL if a potential FI attack was detected or input parameters
+ *              are not valid.
  */
-void mbedtls_platform_zeroize( void *buf, size_t len );
+void *mbedtls_platform_zeroize( void *buf, size_t len );
 
 /**
  * \brief       Secure memset
  *
- *              This is a constant-time version of memset(). If
- *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
- *              initialised with random data and the order is also
- *              randomised using the hardware RNG in order to further harden
- *              against side-channel attacks.
+ *              This is a constant-time version of memset(). The buffer is
+ *              initialised with random data and the order is also randomised
+ *              using the RNG in order to further harden against side-channel
+ *              attacks.
  *
  * \param ptr   Buffer to be set.
  * \param value Value to be used when setting the buffer.
  * \param num   The length of the buffer in bytes.
  *
- * \return      The value of \p ptr.
+ * \return      The value of \p ptr if the operation was successful.
+ * \return      NULL if a potential FI attack was detected.
  */
 void *mbedtls_platform_memset( void *ptr, int value, size_t num );
 
 /**
  * \brief       Secure memcpy
  *
- *              This is a constant-time version of memcpy(). If
- *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
- *              initialised with random data and the order is also
- *              randomised using the hardware RNG in order to further harden
- *              against side-channel attacks.
+ *              This is a constant-time version of memcpy(). The buffer is
+ *              initialised with random data and the order is also randomised
+ *              using the RNG in order to further harden against side-channel
+ *              attacks.
  *
  * \param dst   Destination buffer where the data is being copied to.
  * \param src   Source buffer where the data is being copied from.
  * \param num   The length of the buffers in bytes.
  *
  * \return      The value of \p dst.
+ * \return      NULL if a potential FI attack was detected.
  */
 void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num );
 
@@ -215,12 +218,11 @@
 int mbedtls_platform_memmove( void *dst, const void *src, size_t num );
 
 /**
- * \brief       Secure memcmp
+ * \brief       Secure check if the buffers have the same data.
  *
- *              This is a constant-time version of memcmp(). If
- *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the order is also
- *              randomised using the hardware RNG in order to further harden
- *              against side-channel attacks.
+ *              This is a constant-time version of memcmp(), but without checking
+ *              if the bytes are greater or lower. The order is also randomised
+ *              using the RNG in order to further harden against side-channel attacks.
  *
  * \param buf1  First buffer to compare.
  * \param buf2  Second buffer to compare against.
@@ -229,16 +231,11 @@
  * \return      0 if the buffers were equal or an unspecified non-zero value
  *              otherwise.
  */
-int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num );
+int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num );
 
 /**
  * \brief       RNG-function for getting a random 32-bit integer.
  *
- *
- * \note        Currently the function is dependent of hardware providing an
- *              rng with MBEDTLS_ENTROPY_HARDWARE_ALT. By default, 0 is
- *              returned.
- *
  * \return      The generated random number.
  */
 uint32_t mbedtls_platform_random_uint32( void );
@@ -253,10 +250,6 @@
  *              cryptographically secure RNG, but provide an RNG for utility
  *              functions.
  *
- * \note        Currently the function is dependent of hardware providing an
- *              rng with MBEDTLS_ENTROPY_HARDWARE_ALT. By default, 0 is
- *              returned.
- *
  * \note        If the given range is [0, 0), 0 is returned.
  *
  * \param num   Max-value for the generated random number, exclusive.
@@ -264,7 +257,7 @@
  *
  * \return      The generated random number.
  */
-uint32_t mbedtls_platform_random_in_range( size_t num );
+uint32_t mbedtls_platform_random_in_range( uint32_t num );
 
 /**
  * \brief       Random delay function.
@@ -275,8 +268,9 @@
  *              Duration of the delay is random as number of variable increments
  *              is randomized.
  *
- * \note        Currently the function is dependent of hardware providing an
- *              rng with MBEDTLS_ENTROPY_HARDWARE_ALT.
+ * \note        This function works only if the MBEDTLS_FI_COUNTERMEASURES flag
+ *              is defined in the configuration. Otherwise, the function does
+ *              nothing.
  */
 void mbedtls_platform_random_delay( void );
 
diff --git a/library/asn1parse.c b/library/asn1parse.c
index 8cdc1f1..1563716 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -431,7 +431,7 @@
     while( list != NULL )
     {
         if( list->oid.len == len &&
-            mbedtls_platform_memcmp( list->oid.p, oid, len ) == 0 )
+            mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
         {
             break;
         }
diff --git a/library/asn1write.c b/library/asn1write.c
index e393ef8..fe10e21 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -348,7 +348,7 @@
     while( list != NULL )
     {
         if( list->oid.len == len &&
-            mbedtls_platform_memcmp( list->oid.p, oid, len ) == 0 )
+            mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
         {
             break;
         }
diff --git a/library/des.c b/library/des.c
index c920328..8f01ec1 100644
--- a/library/des.c
+++ b/library/des.c
@@ -417,7 +417,7 @@
     int i;
 
     for( i = 0; i < WEAK_KEY_COUNT; i++ )
-        if( mbedtls_platform_memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
+        if( mbedtls_platform_memequal( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
             return( 1 );
 
     return( 0 );
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 6cfaa08..a0b890d 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -482,6 +482,7 @@
         mbedtls_hmac_drbg_context rng_ctx_blind;
 
         mbedtls_hmac_drbg_init( &rng_ctx_blind );
+        mbedtls_hmac_drbg_set_reseeding( &rng_ctx_blind, MBEDTLS_HMAC_DRBG_NO_RESEED );
         p_rng_blind_det = &rng_ctx_blind;
 
         mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
@@ -509,6 +510,7 @@
          * a valid ECDSA signature.
          */
         p_rng_blind_det = p_rng;
+        mbedtls_hmac_drbg_set_reseeding( p_rng_blind_det, MBEDTLS_HMAC_DRBG_NO_RESEED );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
         /*
diff --git a/library/entropy.c b/library/entropy.c
index 8db3d94..2b1e7ef 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -462,9 +462,10 @@
     for( i = 0; i < ctx->source_count; i++ )
         ctx->source[i].size = 0;
 
-    mbedtls_platform_memcpy( output, buf, len );
-
-    ret = 0;
+    if( output == mbedtls_platform_memcpy( output, buf, len ) )
+    {
+        ret = 0;
+    }
 
 exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 58750c8..d8669c3 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -62,6 +62,8 @@
 {
     memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
 
+    ctx->prediction_resistance = MBEDTLS_HMAC_DRBG_PR_OFF;
+    ctx->reseed_flag = MBEDTLS_HMAC_DRBG_RESEED;
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_init( &ctx->mutex );
 #endif
@@ -210,7 +212,7 @@
     size_t seedlen = 0;
     size_t total_entropy_len;
     int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
-    volatile const unsigned char *additional_dup = additional;
+    const unsigned char * volatile additional_dup = additional;
     volatile size_t len_dup = len;
     int reseed_counter_backup = -1;
 
@@ -388,11 +390,24 @@
 }
 
 /*
+ * Set the reseeding flag
+ */
+void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx,
+                                      int reseed_flag )
+{
+    ctx->reseed_flag = reseed_flag;
+}
+
+/*
  * Set entropy length grabbed for seeding
  */
-void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
+int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
 {
+    if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
+        return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
+
     ctx->entropy_len = len;
+    return 0;
 }
 
 /*
@@ -417,7 +432,7 @@
     mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
     size_t md_len = mbedtls_md_get_size(
         mbedtls_md_get_handle( &ctx->md_ctx ) );
-    size_t left = out_len;
+    volatile size_t left = out_len;
     unsigned char *out = output;
 
     /* II. Check request length */
@@ -429,14 +444,20 @@
         return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
 
     /* 1. (aka VII and IX) Check reseed counter and PR */
-    if( ctx->f_entropy != NULL && /* For no-reseeding instances */
+    if( ctx->reseed_flag != MBEDTLS_HMAC_DRBG_NO_RESEED &&
         ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
           ctx->reseed_counter > ctx->reseed_interval ) )
     {
-        if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
-            return( ret );
-
-        add_len = 0; /* VII.4 */
+            if( ctx->f_entropy == NULL )
+            {
+                return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
+            }
+            else
+            {
+                if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+                    return( ret );
+                add_len = 0; /* VII.4 */
+            }
     }
 
     /* 2. Use additional data if any */
diff --git a/library/oid.c b/library/oid.c
index 00a02c3..98235a1 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -75,7 +75,7 @@
         if( p == NULL || oid == NULL ) return( NULL );                  \
         while( cur->asn1 != NULL ) {                                    \
             if( cur->asn1_len == oid->len &&                            \
-                mbedtls_platform_memcmp( cur->asn1, oid->p, oid->len ) == 0 ) {          \
+                mbedtls_platform_memequal( cur->asn1, oid->p, oid->len ) == 0 ) {          \
                 return( p );                                            \
             }                                                           \
             p++;                                                        \
diff --git a/library/pem.c b/library/pem.c
index 5e2fca9..41a4931 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -273,7 +273,7 @@
 
     enc = 0;
 
-    if( s2 - s1 >= 22 && mbedtls_platform_memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
+    if( s2 - s1 >= 22 && mbedtls_platform_memequal( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
     {
 #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) &&         \
     ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
@@ -286,7 +286,7 @@
 
 
 #if defined(MBEDTLS_DES_C)
-        if( s2 - s1 >= 23 && mbedtls_platform_memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
+        if( s2 - s1 >= 23 && mbedtls_platform_memequal( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
         {
             enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
 
@@ -296,7 +296,7 @@
 
             s1 += 16;
         }
-        else if( s2 - s1 >= 18 && mbedtls_platform_memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
+        else if( s2 - s1 >= 18 && mbedtls_platform_memequal( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
         {
             enc_alg = MBEDTLS_CIPHER_DES_CBC;
 
@@ -309,15 +309,15 @@
 #endif /* MBEDTLS_DES_C */
 
 #if defined(MBEDTLS_AES_C)
-        if( s2 - s1 >= 14 && mbedtls_platform_memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
+        if( s2 - s1 >= 14 && mbedtls_platform_memequal( s1, "DEK-Info: AES-", 14 ) == 0 )
         {
             if( s2 - s1 < 22 )
                 return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
-            else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
+            else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
                 enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
-            else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
+            else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
                 enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
-            else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
+            else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
                 enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
             else
                 return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
diff --git a/library/pk.c b/library/pk.c
index fea7576..4976f1f 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -556,7 +556,7 @@
     const mbedtls_uecc_keypair *uecc_prv =
         (const mbedtls_uecc_keypair *) prv;
 
-    if( mbedtls_platform_memcmp( uecc_pub->public_key,
+    if( mbedtls_platform_memequal( uecc_pub->public_key,
                 uecc_prv->public_key,
                 2 * NUM_ECC_BYTES ) == 0 )
     {
diff --git a/library/pkparse.c b/library/pkparse.c
index 411fbaa..83974f8 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -309,7 +309,7 @@
         return( ret );
 
     if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
-        mbedtls_platform_memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
+        mbedtls_platform_memequal( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
     {
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
     }
@@ -561,9 +561,13 @@
     if( buf[0] != 0x04 )
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 
-    mbedtls_platform_memcpy( uecc_keypair->public_key, buf + 1, 2 * NUM_ECC_BYTES );
+    if( mbedtls_platform_memcpy( uecc_keypair->public_key, buf + 1, 2 * NUM_ECC_BYTES ) ==
+                                 uecc_keypair->public_key )
+    {
+        return( 0 );
+    }
 
-    return( 0 );
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 static int pk_get_ueccpubkey( unsigned char **p,
@@ -976,7 +980,11 @@
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
 
-    mbedtls_platform_memcpy( keypair->private_key, p, len );
+    if( mbedtls_platform_memcpy( keypair->private_key, p, len ) !=
+                                 keypair->private_key )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
 
     p += len;
 
diff --git a/library/platform_util.c b/library/platform_util.c
index fc6eb5a..3b098d2 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -51,9 +51,20 @@
 #include <stddef.h>
 #include <string.h>
 
-/* Max number of loops for mbedtls_platform_random_delay */
+/* Max number of loops for mbedtls_platform_random_delay. */
 #define MAX_RAND_DELAY  100
 
+/* Parameters for the linear congruential generator used as a non-cryptographic
+ * random number generator. The same parameters are used by e.g. ANSI C. */
+#define RAND_MULTIPLIER 1103515245
+#define RAND_INCREMENT  12345
+#define RAND_MODULUS    0x80000000
+
+/* The number of iterations after which the seed of the non-cryptographic
+ * random number generator will be changed. This is used only if the
+ * MBEDTLS_ENTROPY_HARDWARE_ALT option is enabled. */
+#define RAND_SEED_LIFE  10000
+
 #if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
 /*
  * This implementation should never be optimized out by the compiler
@@ -84,67 +95,142 @@
 void *mbedtls_platform_memset( void *, int, size_t );
 static void * (* const volatile memset_func)( void *, int, size_t ) = mbedtls_platform_memset;
 
-void mbedtls_platform_zeroize( void *buf, size_t len )
+void *mbedtls_platform_zeroize( void *buf, size_t len )
 {
-    MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
+    volatile size_t vlen = len;
 
-    if( len > 0 )
-        memset_func( buf, 0, len );
+    MBEDTLS_INTERNAL_VALIDATE_RET( ( len == 0 || buf != NULL ), NULL );
+
+    if( vlen > 0 )
+    {
+        return memset_func( buf, 0, vlen );
+    }
+    else
+    {
+        mbedtls_platform_random_delay();
+        if( vlen == 0 && vlen == len )
+        {
+            return buf;
+        }
+    }
+    return NULL;
 }
 #endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
 
 void *mbedtls_platform_memset( void *ptr, int value, size_t num )
 {
-    /* Randomize start offset. */
-    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
-    /* Randomize data */
-    uint32_t data = mbedtls_platform_random_in_range( 256 );
+    size_t i, start_offset;
+    volatile size_t flow_counter = 0;
+    volatile char *b = ptr;
+    char rnd_data;
 
-    /* Perform a pair of memset operations from random locations with
-     * random data */
-    memset( (void *) ( (unsigned char *) ptr + start_offset ), data,
-            ( num - start_offset ) );
-    memset( (void *) ptr, data, start_offset );
+    start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
+    rnd_data = (char) mbedtls_platform_random_in_range( 256 );
 
-    /* Perform the original memset */
-    return( memset( ptr, value, num ) );
+    /* Perform a memset operations with random data and start from a random
+     * location */
+    for( i = start_offset; i < num; ++i )
+    {
+        b[i] = rnd_data;
+        flow_counter++;
+    }
+
+    /* Start from a random location with target data */
+    for( i = start_offset; i < num; ++i )
+    {
+        b[i] = value;
+        flow_counter++;
+    }
+
+    /* Second memset operation with random data */
+    for( i = 0; i < start_offset; ++i )
+    {
+        b[i] = rnd_data;
+        flow_counter++;
+    }
+
+    /* Finish memset operation with correct data */
+    for( i = 0; i < start_offset; ++i )
+    {
+        b[i] = value;
+        flow_counter++;
+    }
+
+    /* check the correct number of iterations */
+    if( flow_counter == 2 * num )
+    {
+        mbedtls_platform_random_delay();
+        if( flow_counter == 2 * num )
+        {
+            return ptr;
+        }
+    }
+    return NULL;
 }
 
 void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num )
 {
-    /* Randomize start offset. */
-    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
-    /* Randomize initial data to prevent leakage while copying */
-    uint32_t data = mbedtls_platform_random_in_range( 256 );
+    size_t i;
+    volatile size_t flow_counter = 0;
 
-    /* Use memset with random value at first to increase security - memset is
-       not normally part of the memcpy function and here can be useed
-       with regular, unsecured implementation */
-    memset( (void *) dst, data, num );
-    memcpy( (void *) ( (unsigned char *) dst + start_offset ),
-            (void *) ( (unsigned char *) src + start_offset ),
-            ( num - start_offset ) );
-    return( memcpy( (void *) dst, (void *) src, start_offset ) );
+    if( num > 0 )
+    {
+        /* Randomize start offset. */
+        size_t start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
+        /* Randomize initial data to prevent leakage while copying */
+        uint32_t data = mbedtls_platform_random_in_range( 256 );
+
+        /* Use memset with random value at first to increase security - memset is
+        not normally part of the memcpy function and here can be useed
+        with regular, unsecured implementation */
+        memset( (void *) dst, data, num );
+
+        /* Make a copy starting from a random location. */
+        i = start_offset;
+        do
+        {
+            ( (char*) dst )[i] = ( (char*) src )[i];
+            flow_counter++;
+        }
+        while( ( i = ( i + 1 ) % num ) != start_offset );
+    }
+
+    /* check the correct number of iterations */
+    if( flow_counter == num )
+    {
+        mbedtls_platform_random_delay();
+        if( flow_counter == num )
+        {
+            return dst;
+        }
+    }
+    return NULL;
 }
 
 int mbedtls_platform_memmove( void *dst, const void *src, size_t num )
 {
+    void *ret1 = NULL;
+    void *ret2 = NULL;
     /* The buffers can have a common part, so we cannot do a copy from a random
      * location. By using a temporary buffer we can do so, but the cost of it
      * is using more memory and longer transfer time. */
     void *tmp = mbedtls_calloc( 1, num );
     if( tmp != NULL )
     {
-        mbedtls_platform_memcpy( tmp, src, num );
-        mbedtls_platform_memcpy( dst, tmp, num );
+        ret1 = mbedtls_platform_memcpy( tmp, src, num );
+        ret2 = mbedtls_platform_memcpy( dst, tmp, num );
         mbedtls_free( tmp );
-        return 0;
+        if( ret1 == tmp && ret2 == dst )
+        {
+            return 0;
+        }
+        return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
     }
 
     return MBEDTLS_ERR_PLATFORM_ALLOC_FAILED;
 }
 
-int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num )
+int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num )
 {
     volatile const unsigned char *A = (volatile const unsigned char *) buf1;
     volatile const unsigned char *B = (volatile const unsigned char *) buf2;
@@ -152,7 +238,7 @@
 
     /* Start from a random location and check the correct number of iterations */
     size_t i, flow_counter = 0;
-    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
+    size_t start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
 
     for( i = start_offset; i < num; i++ )
     {
@@ -172,51 +258,80 @@
     return( (int) diff | (int) ( flow_counter ^ num ) );
 }
 
-uint32_t mbedtls_platform_random_uint32( )
+/* This function implements a non-cryptographic random number generator based
+ * on the linear congruential generator algorithm. Additionally, if the
+ * MBEDTLS_ENTROPY_HARDWARE_ALT flag is defined, the seed is set at the first
+ * call of this function with using a hardware random number generator and
+ * changed every RAND_SEED_LIFE number of iterations.
+ *
+ * The value of the returned number is in the range [0; 0xffff].
+ *
+ * Note: The range of values with a 16-bit precision is related to the modulo
+ * parameter of the generator and the fact that the function does not return the
+ * full value of the internal state of the generator.
+ */
+static uint32_t mbedtls_platform_random_uint16( void )
 {
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
-    return 0;
-#else
-    uint32_t result = 0;
-    size_t olen = 0;
+    /* Set random_state - the first random value should not be zero. */
+    static uint32_t random_state = RAND_INCREMENT;
 
-    mbedtls_hardware_poll( NULL, (unsigned char *) &result, sizeof( result ),
-                           &olen );
-    return( result );
-#endif
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+    static uint32_t random_seed_life = 0;
+
+    if( 0 < random_seed_life )
+    {
+        --random_seed_life;
+    }
+    else
+    {
+        size_t olen = 0;
+        uint32_t hw_random;
+        mbedtls_hardware_poll( NULL,
+                               (unsigned char *) &hw_random, sizeof( hw_random ),
+                               &olen );
+        if( olen == sizeof( hw_random ) )
+        {
+            random_state ^= hw_random;
+            random_seed_life = RAND_SEED_LIFE;
+        }
+    }
+
+#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+
+    random_state = ( ( random_state * RAND_MULTIPLIER ) + RAND_INCREMENT ) % RAND_MODULUS;
+
+    /* Do not return the entire random_state to hide generator predictability for
+     * the next iteration */
+    return( ( random_state >> 15 ) & 0xffff );
 }
 
-uint32_t mbedtls_platform_random_in_range( size_t num )
+uint32_t mbedtls_platform_random_uint32( void )
 {
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
-    (void) num;
-    return 0;
-#else
-    uint32_t result = 0;
-    size_t olen = 0;
+    return( ( mbedtls_platform_random_uint16() << 16 ) |
+              mbedtls_platform_random_uint16() );
+}
 
-    mbedtls_hardware_poll( NULL, (unsigned char *) &result, sizeof( result ),
-                           &olen );
+uint32_t mbedtls_platform_random_in_range( uint32_t num )
+{
+    uint32_t result;
 
-    if( num == 0 )
+    if( num <= 1 )
     {
         result = 0;
     }
     else
     {
-        result %= num;
+        result = mbedtls_platform_random_uint32() % num;
     }
 
     return( result );
-#endif
 }
 
 void mbedtls_platform_random_delay( void )
 {
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
-    return;
-#else
-    size_t rn_1, rn_2, rn_3;
+#if defined(MBEDTLS_FI_COUNTERMEASURES)
+    uint32_t rn_1, rn_2, rn_3;
     volatile size_t i = 0;
     uint8_t shift;
 
@@ -229,17 +344,17 @@
         i++;
         /* Dummy calculations to increase the time between iterations and
          * make side channel attack more difficult by reducing predictability
-         * of its behaviour */
-        shift = rn_2 & 0x07;
+         * of its behaviour. */
+        shift = ( rn_2 & 0x07 ) + 1;
         if ( i % 2 )
-            rn_2 = (uint32_t)( rn_2 >> shift | rn_2 << ( 32 - shift ) );
+            rn_2 = ( rn_2 >> shift ) | ( rn_2 << ( 32 - shift ) );
         else
-            rn_3 = (uint32_t)( rn_3 << shift | rn_3 >> ( 32 - shift ) );
+            rn_3 = ( rn_3 << shift ) | ( rn_3 >> ( 32 - shift ) );
         rn_2 ^= rn_3;
     } while( i < rn_1 || rn_2 == 0 || rn_3 == 0 );
 
+#endif /* MBEDTLS_FI_COUNTERMEASURES */
     return;
-#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT */
 }
 
 #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
diff --git a/library/rsa.c b/library/rsa.c
index 3f480a3..83a4f38 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -60,9 +60,9 @@
 #include <stdlib.h>
 #endif
 
-#if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
-#else
+
+#if !defined(MBEDTLS_PLATFORM_C)
 #include <stdio.h>
 #define mbedtls_printf printf
 #define mbedtls_calloc calloc
@@ -1974,8 +1974,11 @@
     /* Are we signing raw data? */
     if( md_alg == MBEDTLS_MD_NONE )
     {
-        mbedtls_platform_memcpy( p, hash, hashlen );
-        return( 0 );
+        if( mbedtls_platform_memcpy( p, hash, hashlen ) == p )
+        {
+            return( 0 );
+        }
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
     }
 
     /* Signing hashed data, add corresponding ASN.1 structure
@@ -2003,7 +2006,10 @@
     *p++ = 0x00;
     *p++ = MBEDTLS_ASN1_OCTET_STRING;
     *p++ = (unsigned char) hashlen;
-    mbedtls_platform_memcpy( p, hash, hashlen );
+    if( mbedtls_platform_memcpy( p, hash, hashlen ) != p )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
     p += hashlen;
 
     /* Just a sanity-check, should be automatic
@@ -2029,7 +2035,7 @@
                                const unsigned char *hash,
                                unsigned char *sig )
 {
-    int ret;
+    int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
     unsigned char *sig_try = NULL, *verif = NULL;
 
     RSA_VALIDATE_RET( ctx != NULL );
@@ -2087,7 +2093,10 @@
         goto cleanup;
     }
 
-    mbedtls_platform_memcpy( sig, sig_try, ctx->len );
+    if( mbedtls_platform_memcpy( sig, sig_try, ctx->len ) != sig )
+    {
+        ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+    }
 
 cleanup:
     mbedtls_free( sig_try );
@@ -2275,7 +2284,7 @@
     if ( ret != 0 )
         goto exit;
 
-    if( mbedtls_platform_memcmp( hash_start, result, hlen ) != 0 )
+    if( mbedtls_platform_memequal( hash_start, result, hlen ) != 0 )
     {
         ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
         goto exit;
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index a4d8cd3..278a477 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -94,7 +94,7 @@
             continue;
         }
 
-        if( mbedtls_platform_memcmp( session->id, entry->session.id,
+        if( mbedtls_platform_memequal( session->id, entry->session.id,
                     entry->session.id_len ) != 0 )
             continue;
 
@@ -180,7 +180,7 @@
         }
 #endif
 
-        if( mbedtls_platform_memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
+        if( mbedtls_platform_memequal( session->id, cur->session.id, cur->session.id_len ) == 0 )
             break; /* client reconnected, keep timestamp for session id */
 
 #if defined(MBEDTLS_HAVE_TIME)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 58cbd87..e2c24e2 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1164,9 +1164,9 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len * 2 ||
             buf[0] !=     ssl->verify_data_len * 2 ||
-            mbedtls_platform_memcmp( buf + 1,
+            mbedtls_platform_memequal( buf + 1,
                           ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
-            mbedtls_platform_memcmp( buf + 1 + ssl->verify_data_len,
+            mbedtls_platform_memequal( buf + 1 + ssl->verify_data_len,
                           ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -1495,7 +1495,7 @@
     for( p = ssl->conf->alpn_list; *p != NULL; p++ )
     {
         if( name_len == strlen( *p ) &&
-            mbedtls_platform_memcmp( buf + 3, *p, name_len ) == 0 )
+            mbedtls_platform_memequal( buf + 3, *p, name_len ) == 0 )
         {
             ssl->alpn_chosen = *p;
             return( 0 );
@@ -1746,7 +1746,7 @@
 
     mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
 
-    if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 )
+    if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 )
     {
         ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
     }
@@ -1847,7 +1847,7 @@
         mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) != i ||
         mbedtls_ssl_session_get_compression( ssl->session_negotiate ) != comp ||
         ssl->session_negotiate->id_len != n ||
-        mbedtls_platform_memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
+        mbedtls_platform_memequal( ssl->session_negotiate->id, buf + 35, n ) != 0 )
     {
         ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_UNSET;
     }
@@ -2876,7 +2876,7 @@
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
         }
 
-        if( mbedtls_platform_memcmp( p, ecdh_group, sizeof( ecdh_group ) ) != 0 )
+        if( mbedtls_platform_memequal( p, ecdh_group, sizeof( ecdh_group ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (unexpected header)" ) );
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 5b590db..f2d3ede 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -229,7 +229,7 @@
     if( ret != 0 )
         return( ret );
 
-    if( mbedtls_platform_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+    if( mbedtls_platform_memequal( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
         return( -1 );
 
 #if defined(MBEDTLS_HAVE_TIME)
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index abfef5d..ec0c21a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -162,7 +162,7 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len ||
             buf[0] !=     ssl->verify_data_len ||
-            mbedtls_platform_memcmp( buf + 1, ssl->peer_verify_data,
+            mbedtls_platform_memequal( buf + 1, ssl->peer_verify_data,
                           ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -711,7 +711,7 @@
             cur_len = *theirs++;
 
             if( cur_len == ours_len &&
-                mbedtls_platform_memcmp( theirs, *ours, cur_len ) == 0 )
+                mbedtls_platform_memequal( theirs, *ours, cur_len ) == 0 )
             {
                 ssl->alpn_chosen = *ours;
                 return( 0 );
@@ -1228,7 +1228,7 @@
     ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET;
     memset( ssl->handshake->randbytes, 0, 64 );
     mbedtls_platform_memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
-    if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 )
+    if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 )
     {
         ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
     }
@@ -1628,7 +1628,7 @@
          * fragment_offset == 0 and fragment_length == length
          */
         if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
-            mbedtls_platform_memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
+            mbedtls_platform_memequal( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) );
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
@@ -1728,7 +1728,7 @@
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 );
 
     mbedtls_platform_memcpy( ssl->handshake->randbytes, buf + 2, 32 );
-    if( mbedtls_platform_memcmp( ssl->handshake->randbytes, buf + 2, 32 ) == 0 )
+    if( mbedtls_platform_memequal( ssl->handshake->randbytes, buf + 2, 32 ) == 0 )
     {
         ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
     }
@@ -2827,7 +2827,7 @@
     p += 28;
     ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET;
     mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
-    if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 )
+    if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 )
     {
         ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
     }
@@ -4119,7 +4119,7 @@
         /* Identity is not a big secret since clients send it in the clear,
          * but treat it carefully anyway, just in case */
         if( n != ssl->conf->psk_identity_len ||
-            mbedtls_platform_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+            mbedtls_platform_memequal( ssl->conf->psk_identity, *p, n ) != 0 )
         {
             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
         }
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 98147b7..96478f6 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -259,7 +259,7 @@
     unsigned char i;
 
     for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ )
-        if( mbedtls_platform_memcmp( name, ctx->keys[i].name, 4 ) == 0 )
+        if( mbedtls_platform_memequal( name, ctx->keys[i].name, 4 ) == 0 )
             return( &ctx->keys[i] );
 
     return( NULL );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1ee7af0..4ebfb5c 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -92,7 +92,11 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES );
+    if( mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES ) !=
+                                 ssl->handshake->ecdh_peerkey )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
 
     *p += secp256r1_uncompressed_point_length;
     return( 0 );
@@ -1886,9 +1890,13 @@
         return( ret );
     }
 
-    mbedtls_platform_zeroize( handshake->premaster,
-                              sizeof(handshake->premaster) );
-    return( 0 );
+    if( handshake->premaster == mbedtls_platform_zeroize(
+                    handshake->premaster, sizeof(handshake->premaster) ) )
+    {
+        return( 0 );
+    }
+
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
@@ -2289,7 +2297,10 @@
     if( end < p || (size_t)( end - p ) < psk_len )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    mbedtls_platform_memcpy( p, psk, psk_len );
+    if( mbedtls_platform_memcpy( p, psk, psk_len ) != p )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
     p += psk_len;
 
     ssl->handshake->pmslen = p - ssl->handshake->premaster;
@@ -3164,7 +3175,7 @@
              *
              * Afterwards, we know that data + data_len is followed by at
              * least maclen Bytes, which justifies the call to
-             * mbedtls_platform_memcmp() below.
+             * mbedtls_platform_memequal() below.
              *
              * Further, we still know that data_len > minlen */
             rec->data_len -= transform->maclen;
@@ -3186,8 +3197,8 @@
                                    transform->maclen );
 
             /* Compare expected MAC with MAC at the end of the record. */
-            if( mbedtls_platform_memcmp( data + rec->data_len, mac_expect,
-                                          transform->maclen ) != 0 )
+            if( mbedtls_platform_memequal( data + rec->data_len, mac_expect,
+                                           transform->maclen ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
                 return( MBEDTLS_ERR_SSL_INVALID_MAC );
@@ -3525,8 +3536,8 @@
         MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", data + rec->data_len, transform->maclen );
 #endif
 
-        if( mbedtls_platform_memcmp( data + rec->data_len, mac_expect,
-                                      transform->maclen ) != 0 )
+        if( mbedtls_platform_memequal( data + rec->data_len, mac_expect,
+                                       transform->maclen ) != 0 )
         {
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
@@ -4491,8 +4502,16 @@
 
             /* Handshake hashes are computed without fragmentation,
              * so set frag_offset = 0 and frag_len = hs_len for now */
-            mbedtls_platform_memset( ssl->out_msg + 6, 0x00, 3 );
-            mbedtls_platform_memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
+            if( mbedtls_platform_memset( ssl->out_msg + 6, 0x00, 3 ) !=
+                                         ssl->out_msg + 6 )
+            {
+                return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+            }
+            if( mbedtls_platform_memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ) !=
+                                         ssl->out_msg + 9 )
+            {
+                return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+            }
         }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
@@ -4734,8 +4753,8 @@
 static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
 {
     if( ssl->in_msglen < ssl->in_hslen ||
-        mbedtls_platform_memcmp( ssl->in_msg + 6, "\0\0\0",        3 ) != 0 ||
-        mbedtls_platform_memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
+        mbedtls_platform_memequal( ssl->in_msg + 6, "\0\0\0",        3 ) != 0 ||
+        mbedtls_platform_memequal( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
     {
         return( PROPER_HS_FRAGMENT );
     }
@@ -6123,9 +6142,24 @@
 
                 /* Prepare final header: copy msg_type, length and message_seq,
                  * then add standardised fragment_offset and fragment_length */
-                mbedtls_platform_memcpy( hs_buf->data, ssl->in_msg, 6 );
-                mbedtls_platform_memset( hs_buf->data + 6, 0, 3 );
-                mbedtls_platform_memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
+                if( mbedtls_platform_memcpy( hs_buf->data, ssl->in_msg, 6 ) !=
+                                             hs_buf->data )
+                {
+                    ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+                    goto exit;
+                }
+                if( mbedtls_platform_memset( hs_buf->data + 6, 0, 3 ) !=
+                                             hs_buf->data + 6 )
+                {
+                    ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+                    goto exit;
+                }
+                if( mbedtls_platform_memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ) !=
+                                             hs_buf->data + 9 )
+                {
+                    ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+                    goto exit;
+                }
 
                 hs_buf->is_valid = 1;
 
@@ -7070,7 +7104,7 @@
     if( peer_crt->raw.len != crt_buf_len )
         return( PEER_CRT_CHANGED );
 
-    return( mbedtls_platform_memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) );
+    return( mbedtls_platform_memequal( peer_crt->raw.p, crt_buf, crt_buf_len ) );
 }
 #elif defined(MBEDTLS_SSL_RENEGOTIATION)
 #define PEER_CRT_CHANGED 0x75555555
@@ -7102,7 +7136,7 @@
     if( ret != 0 )
         return( PEER_CRT_CHANGED );
 
-    return( mbedtls_platform_memcmp( tmp_digest, peer_cert_digest, digest_len ) );
+    return( mbedtls_platform_memequal( tmp_digest, peer_cert_digest, digest_len ) );
 }
 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */
 #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
@@ -8350,8 +8384,8 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
     }
 
-    if( mbedtls_platform_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
-                      buf, hash_len ) != 0 )
+    if( mbedtls_platform_memequal( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+                                   buf, hash_len ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_pend_fatal_alert( ssl,
@@ -11175,11 +11209,19 @@
     n = ( len < ssl->in_msglen )
         ? len : ssl->in_msglen;
 
-    mbedtls_platform_memcpy( buf, ssl->in_offt, n );
+    if( mbedtls_platform_memcpy( buf, ssl->in_offt, n ) !=
+                                 buf )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
     ssl->in_msglen -= n;
 
     // clear incoming data after it's copied to buffer
-    mbedtls_platform_memset(ssl->in_offt, 0, n);
+    if( mbedtls_platform_memset( ssl->in_offt, 0, n ) !=
+                                 ssl->in_offt )
+    {
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    }
 
     if( ssl->in_msglen == 0 )
     {
@@ -11269,7 +11311,10 @@
          */
         ssl->out_msglen = len;
         ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
-        mbedtls_platform_memcpy( ssl->out_msg, buf, len );
+        if( mbedtls_platform_memcpy( ssl->out_msg, buf, len ) != ssl->out_msg )
+        {
+            return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+        }
 
 #if defined(MBEDTLS_FI_COUNTERMEASURES) && !defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
         /*
@@ -12125,7 +12170,7 @@
             for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
             {
                 if( strlen( *cur ) == alpn_len &&
-                    mbedtls_platform_memcmp( p, cur, alpn_len ) == 0 )
+                    mbedtls_platform_memequal( p, cur, alpn_len ) == 0 )
                 {
                     ssl->alpn_chosen = *cur;
                     break;
diff --git a/library/x509.c b/library/x509.c
index 65f2ec6..f86e9e3 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -516,7 +516,7 @@
 {
     if( a->tag == b->tag &&
         a->len == b->len &&
-        mbedtls_platform_memcmp( a->p, b->p, b->len ) == 0 )
+        mbedtls_platform_memequal( a->p, b->p, b->len ) == 0 )
     {
         return( 0 );
     }
@@ -605,7 +605,7 @@
             goto exit;
 
         if( oid[0].len != oid[1].len ||
-            mbedtls_platform_memcmp( oid[0].p, oid[1].p, oid[1].len ) != 0 )
+            mbedtls_platform_memequal( oid[0].p, oid[1].p, oid[1].len ) != 0 )
         {
             return( 1 );
         }
diff --git a/library/x509_crl.c b/library/x509_crl.c
index d295229..8af5de8 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -511,10 +511,10 @@
     }
 
     if( crl->sig_oid.len != sig_oid2.len ||
-        mbedtls_platform_memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
+        mbedtls_platform_memequal( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
         sig_params1.len != sig_params2.len ||
         ( sig_params1.len != 0 &&
-          mbedtls_platform_memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
+          mbedtls_platform_memequal( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
     {
         mbedtls_x509_crl_free( crl );
         return( MBEDTLS_ERR_X509_SIG_MISMATCH );
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 43bb977..3b75bb5 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1322,7 +1322,7 @@
      *    signature field in the sequence tbsCertificate (Section 4.1.2.3).
      */
     if( outer_sig_alg.len != inner_sig_alg_len ||
-        mbedtls_platform_memcmp( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 )
+        mbedtls_platform_memequal( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 )
     {
         return( MBEDTLS_ERR_X509_SIG_MISMATCH );
     }
@@ -2594,7 +2594,7 @@
         return( 1 );
     }
 
-    if( data_len == cb_ctx->oid_len && mbedtls_platform_memcmp( data, cb_ctx->oid,
+    if( data_len == cb_ctx->oid_len && mbedtls_platform_memequal( data, cb_ctx->oid,
                                                data_len ) == 0 )
     {
         return( 1 );
@@ -2652,7 +2652,7 @@
     while( cur != NULL && cur->serial.len != 0 )
     {
         if( serial_len == cur->serial.len &&
-            mbedtls_platform_memcmp( serial, cur->serial.p, serial_len ) == 0 )
+            mbedtls_platform_memequal( serial, cur->serial.p, serial_len ) == 0 )
         {
             if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
                 return( 1 );
@@ -3191,7 +3191,7 @@
     for( cur = trust_ca; cur != NULL; cur = cur->next )
     {
         if( crt->raw.len == cur->raw.len &&
-            mbedtls_platform_memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
+            mbedtls_platform_memequal( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
         {
             return( 0 );
         }
diff --git a/tests/suites/test_suite_hmac_drbg.function b/tests/suites/test_suite_hmac_drbg.function
index da280db..b812b70 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -94,12 +94,12 @@
     TEST_ASSERT( entropy.len < last_len );
 
     /* Finally, check setting entropy_len */
-    mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 );
+    TEST_ASSERT( mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 ) == 0 );
     last_len = entropy.len;
     TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
     TEST_ASSERT( (int) last_len - entropy.len == 42 );
 
-    mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 );
+    TEST_ASSERT( mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 ) == 0 );
     last_len = entropy.len;
     TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
     TEST_ASSERT( (int) last_len - entropy.len == 13 );
@@ -149,6 +149,7 @@
     TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info, buf, sizeof( buf ) ) == 0 );
 
     /* Make sure it never tries to reseed (would segfault otherwise) */
+    mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
     mbedtls_hmac_drbg_set_reseed_interval( &ctx, 3 );
     mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
 
@@ -172,7 +173,7 @@
     mbedtls_hmac_drbg_context ctx;
 
     mbedtls_hmac_drbg_init( &ctx );
-
+    mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
     p_entropy.p = entropy->x;
     p_entropy.len = entropy->len;
 
@@ -219,6 +220,7 @@
     mbedtls_hmac_drbg_context ctx;
 
     mbedtls_hmac_drbg_init( &ctx );
+    mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
 
     p_entropy.p = entropy->x;
     p_entropy.len = entropy->len;
diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c
index 5a7a9e5..6285cf3 100644
--- a/tinycrypt/ecc_dh.c
+++ b/tinycrypt/ecc_dh.c
@@ -81,7 +81,10 @@
 	/* This function is designed for test purposes-only (such as validating NIST
 	 * test vectors) as it uses a provided value for d instead of generating
 	 * it uniformly at random. */
-	mbedtls_platform_memcpy (_private, d, NUM_ECC_BYTES);
+	if( mbedtls_platform_memcpy (_private, d, NUM_ECC_BYTES) != _private )
+	{
+		goto exit;
+	}
 
 	/* Computing public-key from private: */
 	ret = EccPoint_compute_public_key(_public, _private);
@@ -186,7 +189,9 @@
 	uECC_vli_nativeToBytes(secret, num_bytes, _public);
 
 	/* erasing temporary buffer used to store secret: */
-	mbedtls_platform_zeroize(_private, sizeof(_private));
+	if (_private == mbedtls_platform_zeroize(_private, sizeof(_private))) {
+		return r;
+	}
 
-	return r;
+	return UECC_FAULT_DETECTED;
 }