Merge enc/dec cipher contexts in ssl transforms

Store the raw encryption and decryption keys in transforms
to set them before each cipher operation. Add a config option
for this - MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 7239557..f91f6b4 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -672,6 +672,11 @@
 #error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active"
 #endif
 
+#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
+    defined(MBEDTLS_ARC4_C)
+#error "MBEDTLS_ARC4_C cannot be defined with MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS on"
+#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 c4d98e4..1cf868f 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3285,6 +3285,20 @@
 #define MBEDTLS_SSL_TLS_C
 
 /**
+ * \def MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+ * Use one cipher context for both decryption and encryption in ssl transforms.
+ *
+ * This change saves some RAM, but makes the operations last longer:
+ * before every encryption and decryption a key is set on the context.
+ *
+ * This change will not work with MBEDTLS_ARC4_C, since it requires an
+ * additional table and offsets to be saved between cipher calls, and this
+ * contradicts key resetting before each use.
+ *
+ */
+//#define MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+
+/**
  * \def MBEDTLS_THREADING_C
  *
  * Enable the threading abstraction layer.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 19328d8..40d246e 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -756,9 +756,15 @@
     z_stream ctx_inflate;               /*!<  decompression context   */
 #endif
 
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+    unsigned char *key_enc;
+    unsigned char *key_dec;
+    unsigned int key_bitlen;
+    mbedtls_cipher_context_t cipher_ctx;        /*!<  encryption/decryption context */
+#else
     mbedtls_cipher_context_t cipher_ctx_enc;    /*!<  encryption context      */
     mbedtls_cipher_context_t cipher_ctx_dec;    /*!<  decryption context      */
-
+#endif
 #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
     /* We need the Hello random bytes in order to re-derive keys from the
      * Master Secret and other session info, see ssl_populate_transform() */