Calculate hashes of ssl encryption and decryption keys

Optimize the key switching mechanism to set the key only if 
a different operation is performed with the context.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index f91f6b4..5e2a661 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -677,6 +677,11 @@
 #error "MBEDTLS_ARC4_C cannot be defined with MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS on"
 #endif
 
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) && !defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
+    defined(MBEDTLS_ARC4_C)
+#error "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY requires MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS to be defined."
+#endif
+
 #if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
     defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
 #error "Illegal protocol selection"
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 1cf868f..06cdde9 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -2740,6 +2740,18 @@
 //#define MBEDTLS_CRC_C
 
 /**
+ * \def MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+ *
+ * Enable validation of ssl keys by checking their hash
+ * during every encryption/decryption.
+ *
+ * Module:  library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+ */
+//#define MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+
+/**
  * \def MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY
  *
  * Enable validation of AES keys by checking their hash
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index b44be23..e0bd08c 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -340,6 +340,18 @@
                                       struct tm *tm_buf );
 #endif /* MBEDTLS_HAVE_TIME_DATE */
 
+#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) || defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+/**
+ * \brief      Calculate a hash from the given data.
+ *
+ * \param data            Data from which the hash is calculated.
+ * \param data_len_bytes  Length of the data in bytes.
+ *
+ * \return     A hash calculated from the provided data.
+ */
+uint32_t mbedtls_hash( const void *data, size_t data_len_bytes );
+#endif
+
 /**
  * \brief      Convert a 32-bit number to the big endian format and write it to
  *             the given buffer.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 40d246e..a1c5d1d 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -760,7 +760,11 @@
     unsigned char *key_enc;
     unsigned char *key_dec;
     unsigned int key_bitlen;
-    mbedtls_cipher_context_t cipher_ctx;        /*!<  encryption/decryption context */
+    mbedtls_cipher_context_t cipher_ctx;    /*!<  encryption/decryption context */
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+    uint32_t key_enc_hash;                  /*!< hash of the encryption key */
+    uint32_t key_dec_hash;                  /*!< hash of the decryption key */
+#endif
 #else
     mbedtls_cipher_context_t cipher_ctx_enc;    /*!<  encryption context      */
     mbedtls_cipher_context_t cipher_ctx_dec;    /*!<  decryption context      */