Add FI countermeasures to the ssl module

This commit adds mainly buffer pointer and length duplication and checks,
but also some hamming distance and return values checking improvements.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 24c73b5..5b47c0a 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -3587,7 +3587,10 @@
 {
     int ret;
     unsigned char *p, *end;
+    volatile unsigned char *buf_dup = buf;
+    volatile size_t buflen_dup = buflen;
     size_t n;
+
     mbedtls_ssl_ciphersuite_handle_t ciphersuite_info =
         mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake );
 
@@ -3870,7 +3873,12 @@
     }
 
     *olen = p - buf;
-    return( 0 );
+    /* Secure against buffer substitution */
+    if( buf_dup == buf && buflen_dup == buflen )
+    {
+       return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 static int ssl_out_client_key_exchange_postprocess( mbedtls_ssl_context *ssl )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index d560d35..7094a89 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3269,13 +3269,19 @@
                            - sig_start );
     int ret = ssl->conf->f_async_resume( ssl,
                                          sig_start, signature_len, sig_max_len );
+    volatile size_t *signature_len_dup = signature_len;
     if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
     {
         ssl->handshake->async_in_progress = 0;
         mbedtls_ssl_set_async_operation_data( ssl, NULL );
     }
     MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
-    return( ret );
+    /* Secure against buffer substitution */
+    if( signature_len_dup == signature_len )
+    {
+        return( ret );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 #endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
@@ -3678,7 +3684,7 @@
     {
         return( 0 );
     }
-    return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /* Prepare the ServerKeyExchange message and send it. For ciphersuites
@@ -3826,6 +3832,8 @@
                                        const unsigned char *end )
 {
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    unsigned char ** volatile p_dup = p;
+    volatile const unsigned char *end_dup = end;
     size_t n;
 
     /*
@@ -3856,7 +3864,12 @@
 
     MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
 
-    return( ret );
+    /* Secure against buffer substitution */
+    if( p_dup == p && end_dup == end )
+    {
+        return( ret );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
@@ -4423,7 +4436,7 @@
     {
         return( ret );
     }
-    return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /* Update the handshake state */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ad2dc98..cfb8717 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -232,7 +232,7 @@
 
     if( buf_dup != buf || buflen_dup != buflen )
     {
-        return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
     }
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
     return( ret );
@@ -288,6 +288,9 @@
                          unsigned char const *own_cid,
                          size_t own_cid_len )
 {
+    volatile unsigned char const *own_cid_dup = own_cid;
+    volatile size_t own_cid_len_dup = own_cid_len;
+
     if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
@@ -314,7 +317,12 @@
      * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
     ssl->own_cid_len = (uint8_t) own_cid_len;
 
-    return( 0 );
+    /* Secure against buffer substitution */
+    if( own_cid_dup == own_cid && own_cid_len_dup == own_cid_len )
+    {
+        return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
@@ -611,7 +619,13 @@
     mbedtls_sha1_context sha1;
     unsigned char padding[16];
     unsigned char sha1sum[20];
-    ((void)label);
+    volatile const unsigned char *secret_dup = secret;
+    volatile size_t slen_dup = slen;
+    volatile const char *label_dup = label;
+    volatile const unsigned char *random_dup = random;
+    volatile size_t rlen_dup = rlen;
+    volatile unsigned char *dstbuf_dup = dstbuf;
+    volatile size_t dlen_dup = dlen;
 
     mbedtls_md5_init(  &md5  );
     mbedtls_sha1_init( &sha1 );
@@ -656,7 +670,14 @@
     mbedtls_platform_zeroize( padding, sizeof( padding ) );
     mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
 
-    return( ret );
+    /* Secure against buffer substitution */
+    if( secret_dup == secret && slen_dup == slen && label_dup == label &&
+        random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf &&
+        dlen_dup == dlen )
+    {
+        return( ret );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
@@ -674,6 +695,13 @@
     mbedtls_md_handle_t md_info;
     mbedtls_md_context_t md_ctx;
     int ret;
+    volatile const unsigned char *secret_dup = secret;
+    volatile size_t slen_dup = slen;
+    volatile const char *label_dup = label;
+    volatile const unsigned char *random_dup = random;
+    volatile size_t rlen_dup = rlen;
+    volatile unsigned char *dstbuf_dup = dstbuf;
+    volatile size_t dlen_dup = dlen;
 
     mbedtls_md_init( &md_ctx );
 
@@ -760,7 +788,14 @@
     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
     mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
 
-    return( 0 );
+    /* Secure against buffer substitution */
+    if( secret_dup == secret && slen_dup == slen && label_dup == label &&
+        random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf &&
+        dlen_dup == dlen )
+    {
+        return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
 
@@ -783,6 +818,13 @@
     mbedtls_md_handle_t md_info;
     mbedtls_md_context_t md_ctx;
     int ret;
+    volatile const unsigned char *secret_dup = secret;
+    volatile size_t slen_dup = slen;
+    volatile const char *label_dup = label;
+    volatile const unsigned char *random_dup = random;
+    volatile size_t rlen_dup = rlen;
+    volatile unsigned char *dstbuf_dup = dstbuf;
+    volatile size_t dlen_dup = dlen;
 
     mbedtls_md_init( &md_ctx );
 
@@ -842,7 +884,14 @@
     (void)mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
     (void)mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
 
-    return( 0 );
+    /* Secure against buffer substitution */
+    if( secret_dup == secret && slen_dup == slen && label_dup == label &&
+        random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf &&
+        dlen_dup == dlen )
+    {
+        return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 #if defined(MBEDTLS_SHA256_C)
@@ -1834,6 +1883,7 @@
                                const mbedtls_ssl_context *ssl )
 {
     int ret;
+    volatile unsigned char *master_dup = master;
 
 /* #if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) */
 /*     ssl = NULL; /\* make sure we don't use it except for debug and EMS *\/ */
@@ -1894,8 +1944,12 @@
 
     mbedtls_platform_zeroize( handshake->premaster,
                               sizeof(handshake->premaster) );
-
-    return( 0 );
+    /* Secure against buffer substitution */
+    if( master_dup == master )
+    {
+        return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
@@ -2412,22 +2466,33 @@
     size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY -
                    ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) %
         MBEDTLS_SSL_CID_PADDING_GRANULARITY;
+    volatile unsigned char *content_dup = content;
+    volatile size_t *content_size_dup = content_size;
+    volatile size_t remaining_dup = remaining;
+
 
     /* Write real content type */
     if( remaining == 0 )
-        return( -1 );
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
     content[ len ] = rec_type;
     len++;
     remaining--;
 
     if( remaining < pad )
-        return( -1 );
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
     mbedtls_platform_memset( content + len, 0, pad );
     len += pad;
     remaining -= pad;
 
     *content_size = len;
-    return( 0 );
+
+    /* Secure against buffer substitution */
+    if( content_dup == content && content_size_dup == content_size &&
+        ( remaining_dup - 1 - pad ) == remaining )
+    {
+        return( 0 );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /* This function parses a DTLSInnerPlaintext structure.
@@ -2572,6 +2637,7 @@
 
     if( rec->cid_len != 0 )
     {
+        int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
         /*
          * Wrap plaintext into DTLSInnerPlaintext structure.
          * See ssl_cid_build_inner_plaintext() for more information.
@@ -2579,12 +2645,12 @@
          * Note that this changes `rec->data_len`, and hence
          * `post_avail` needs to be recalculated afterwards.
          */
-        if( ssl_cid_build_inner_plaintext( data,
-                        &rec->data_len,
-                        post_avail,
-                        rec->type ) != 0 )
+        if( ( ret = ssl_cid_build_inner_plaintext( data,
+                                                   &rec->data_len,
+                                                   post_avail,
+                                                   rec->type ) ) != 0 )
         {
-            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+            return( ret );
         }
 
         rec->type = MBEDTLS_SSL_MSG_CID;
@@ -4831,13 +4897,13 @@
 
     for( i = 0; i < len / 8; i++ )
         if( mask[i] != 0xFF )
-            return( -1 );
+            return( 0x75555555 );
 
     for( i = 0; i < len % 8; i++ )
         if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
-            return( -1 );
+            return( 0x75555555 );
 
-    return( 0 );
+        return( 0 );
 }
 
 /* msg_len does not include the handshake header */
@@ -7070,10 +7136,10 @@
     mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
 
     if( peer_crt == NULL )
-        return( -1 );
+        return( 0x75555555 );
 
     if( peer_crt->raw.len != crt_buf_len )
-        return( -1 );
+        return( 0x75555555 );
 
     return( mbedtls_platform_memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) );
 }
@@ -7095,16 +7161,16 @@
     if( peer_cert_digest == NULL ||
         digest_info == MBEDTLS_MD_INVALID_HANDLE )
     {
-        return( -1 );
+        return( 0x75555555 );
     }
 
     digest_len = mbedtls_md_get_size( digest_info );
     if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
-        return( -1 );
+        return( 0x75555555 );
 
     ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
     if( ret != 0 )
-        return( -1 );
+        return( 0x75555555 );
 
     return( mbedtls_platform_memcmp( tmp_digest, peer_cert_digest, digest_len ) );
 }
@@ -10869,6 +10935,8 @@
 {
     int ret;
     size_t n;
+    volatile unsigned char *buf_dup = buf;
+    volatile size_t len_dup = len;
 
     if( ssl == NULL || ssl->conf == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -11182,7 +11250,12 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
 
-    return( (int) n );
+    /* Secure against buffer substitution */
+    if( buf_dup == buf && len_dup == len )
+    {
+        return( (int) n );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /*
@@ -11202,6 +11275,8 @@
 {
     int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
     const size_t max_len = (size_t) ret;
+    volatile const unsigned char *buf_dup = buf;
+    volatile size_t len_dup = len;
 
     if( ret < 0 )
     {
@@ -11224,6 +11299,7 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS)
         {
             len = max_len;
+            len_dup = len;
         }
 #endif
     }
@@ -11259,8 +11335,12 @@
             return( ret );
         }
     }
-
-    return( (int) len );
+    /* Secure against buffer substitution */
+    if( buf_dup == buf && len_dup == len )
+    {
+        return( (int) len );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /*
@@ -11309,6 +11389,8 @@
 int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
 {
     int ret;
+    volatile const unsigned char *buf_dup = buf;
+    volatile size_t len_dup = len;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
 
@@ -11340,7 +11422,12 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
 
-    return( ret );
+    /* Secure against buffer substitution */
+    if( buf_dup == buf && len_dup == len )
+    {
+        return( ret );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 
 /*
@@ -12924,6 +13011,11 @@
 {
     int ret = 0;
     mbedtls_md_context_t ctx;
+    volatile unsigned char* hash_dup = hash;
+    volatile size_t *hashlen_dup = hashlen;
+    volatile unsigned char* data_dup = data;
+    volatile size_t data_len_dup = data_len;
+
     mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( md_alg );
     *hashlen = mbedtls_md_get_size( md_info );
 
@@ -12969,7 +13061,13 @@
         mbedtls_ssl_pend_fatal_alert( ssl,
                                       MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
 
-    return( ret );
+    /* Secure against buffer substitution */
+    if( hash_dup == hash && hashlen_dup == hashlen &&
+        data_dup == data && data_len_dup == data_len )
+    {
+        return( ret );
+    }
+    return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
 }
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
           MBEDTLS_SSL_PROTO_TLS1_2 */