libmbedtls: add interfaces in mbedtls for context memory operation

For integrating into OPTEE_OS, it needs add some interfaces:
1. add mbedtls_cipher_clone() for cipher to copy context between two
operations.
2. add mbedtls_cipher_setup_info() for cipher. cipher need to get its
"cipher_info" according the key length, while the key length is not an
input in allocate function. So, use a default key len in the beginning.
It need to reset the cipher info again in init function.
3. add mbedtls_cipher_cmac_setup() for cmac. This function is separate
from mbedtls_cipher_cmac_starts().
4. copy hmac context in md.

Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Edison Ai <edison.ai@arm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
[jf: rebase onto mbedtls-2.22.0]
[jf: rebase onto mbedtls-2.27.0]
Signed-off-by: Jerome Forissier <jerome@forissier.org>
[jf: rebase onto mbedtls-2.28.1, fix typo in comment]
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
[jw: rebase onto mbedtls-3.4.0, adjust new coding style]
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
[tve: rebase onto mbedtls-3.6.0, adjust for changes between 3.4 and 3.6]
Signed-off-by: Tom Van Eyck <tom.vaneyck@kuleuven.be>
[sby: rebased onto mbedtls-3.6.2]
Signed-off-by: Sungbae Yoo <sungbaey@nvidia.com>
diff --git a/lib/libmbedtls/mbedtls/include/mbedtls/cipher.h b/lib/libmbedtls/mbedtls/include/mbedtls/cipher.h
index 1dc31c9..5d5fc0c 100644
--- a/lib/libmbedtls/mbedtls/include/mbedtls/cipher.h
+++ b/lib/libmbedtls/mbedtls/include/mbedtls/cipher.h
@@ -601,6 +601,20 @@
  */
 void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx);
 
+/**
+ * \brief           Clone the state of an cipher context
+ *
+ * \note            The two contexts must have been setup to the same type
+ *                  (cloning from AES to DES make no sense).
+ *
+ * \param dst       The destination context
+ * \param src       The context to be cloned
+ *
+ * \return          \c 0 on success,
+ *                  \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure.
+ */
+int mbedtls_cipher_clone(mbedtls_cipher_context_t *dst,
+                         const mbedtls_cipher_context_t *src);
 
 /**
  * \brief               This function prepares a cipher context for
@@ -666,6 +680,18 @@
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 /**
+ * \brief               setup the cipher info structure.
+ *
+ * \param ctx           cipher's context. Must have been initialised.
+ * \param cipher_info   cipher to use.
+ *
+ * \return              0 on success,
+ *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure
+ */
+int mbedtls_cipher_setup_info(mbedtls_cipher_context_t *ctx,
+                              const mbedtls_cipher_info_t *cipher_info);
+
+/**
  * \brief        This function returns the block size of the given cipher
  *               in bytes.
  *
diff --git a/lib/libmbedtls/mbedtls/include/mbedtls/cmac.h b/lib/libmbedtls/mbedtls/include/mbedtls/cmac.h
index 97b86fc..16421ba 100644
--- a/lib/libmbedtls/mbedtls/include/mbedtls/cmac.h
+++ b/lib/libmbedtls/mbedtls/include/mbedtls/cmac.h
@@ -73,6 +73,19 @@
 #endif /* !MBEDTLS_CMAC_ALT */
 
 /**
+ * \brief               Initialises and allocate CMAC context memory
+ *                      Must be called with an initialized cipher context.
+ *
+ * \param ctx           The cipher context used for the CMAC operation, initialized
+ *                      as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
+ *                      MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
+ *                      or MBEDTLS_CIPHER_DES_EDE3_ECB.
+ * \return              \c 0 on success.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_cmac_setup(mbedtls_cipher_context_t *ctx);
+
+/**
  * \brief               This function starts a new CMAC computation
  *                      by setting the CMAC key, and preparing to authenticate
  *                      the input data.
diff --git a/lib/libmbedtls/mbedtls/library/cipher.c b/lib/libmbedtls/mbedtls/library/cipher.c
index 7f4c121..a09540e 100644
--- a/lib/libmbedtls/mbedtls/library/cipher.c
+++ b/lib/libmbedtls/mbedtls/library/cipher.c
@@ -242,6 +242,35 @@
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
 }
 
+int mbedtls_cipher_clone(mbedtls_cipher_context_t *dst,
+                         const mbedtls_cipher_context_t *src)
+{
+    if (dst == NULL || dst->cipher_info == NULL ||
+        src == NULL || src->cipher_info == NULL) {
+        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+    dst->cipher_info = src->cipher_info;
+    dst->key_bitlen = src->key_bitlen;
+    dst->operation = src->operation;
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+    dst->add_padding = src->add_padding;
+    dst->get_padding = src->get_padding;
+#endif
+    memcpy(dst->unprocessed_data, src->unprocessed_data, MBEDTLS_MAX_BLOCK_LENGTH);
+    dst->unprocessed_len = src->unprocessed_len;
+    memcpy(dst->iv, src->iv, MBEDTLS_MAX_IV_LENGTH);
+    dst->iv_size = src->iv_size;
+    if (mbedtls_cipher_get_base(dst->cipher_info)->ctx_clone_func)
+        mbedtls_cipher_get_base(dst->cipher_info)->ctx_clone_func(dst->cipher_ctx, src->cipher_ctx);
+
+#if defined(MBEDTLS_CMAC_C)
+    if (dst->cmac_ctx != NULL && src->cmac_ctx != NULL)
+        memcpy(dst->cmac_ctx, src->cmac_ctx, sizeof(mbedtls_cmac_context_t));
+#endif
+    return 0;
+}
+
 int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
                          const mbedtls_cipher_info_t *cipher_info)
 {
@@ -299,6 +328,16 @@
 }
 #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
 
+int mbedtls_cipher_setup_info(mbedtls_cipher_context_t *ctx,
+                              const mbedtls_cipher_info_t *cipher_info )
+{
+    if (NULL == cipher_info || NULL == ctx)
+        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+
+    ctx->cipher_info = cipher_info;
+    return 0;
+}
+
 int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
                           const unsigned char *key,
                           int key_bitlen,
diff --git a/lib/libmbedtls/mbedtls/library/cipher_wrap.c b/lib/libmbedtls/mbedtls/library/cipher_wrap.c
index d2fee22..05f4aa8 100644
--- a/lib/libmbedtls/mbedtls/library/cipher_wrap.c
+++ b/lib/libmbedtls/mbedtls/library/cipher_wrap.c
@@ -11,6 +11,8 @@
 
 #include "common.h"
 
+#include <string.h>
+
 #if defined(MBEDTLS_CIPHER_C)
 
 #include "cipher_wrap.h"
@@ -129,6 +131,11 @@
     return ctx;
 }
 
+static void gcm_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_gcm_context));
+}
+
 static void gcm_ctx_free(void *ctx)
 {
     mbedtls_gcm_free(ctx);
@@ -151,6 +158,11 @@
     return ctx;
 }
 
+static void ccm_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_ccm_context));
+}
+
 static void ccm_ctx_free(void *ctx)
 {
     mbedtls_ccm_free(ctx);
@@ -257,6 +269,11 @@
     return aes;
 }
 
+static void aes_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_aes_context));
+}
+
 static void aes_ctx_free(void *ctx)
 {
     mbedtls_aes_free((mbedtls_aes_context *) ctx);
@@ -289,6 +306,7 @@
     aes_setkey_dec_wrap,
 #endif
     aes_ctx_alloc,
+    aes_ctx_clone,
     aes_ctx_free
 };
 
@@ -603,6 +621,7 @@
     gcm_aes_setkey_wrap,
 #endif
     gcm_ctx_alloc,
+    gcm_ctx_clone,
     gcm_ctx_free,
 #else
     NULL,
@@ -687,6 +706,7 @@
     ccm_aes_setkey_wrap,
 #endif
     ccm_ctx_alloc,
+    ccm_ctx_clone,
     ccm_ctx_free,
 #else
     NULL,
@@ -839,6 +859,11 @@
     return ctx;
 }
 
+static void camellia_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_camellia_context));
+}
+
 static void camellia_ctx_free(void *ctx)
 {
     mbedtls_camellia_free((mbedtls_camellia_context *) ctx);
@@ -871,6 +896,7 @@
     camellia_setkey_dec_wrap,
 #endif
     camellia_ctx_alloc,
+    camellia_ctx_clone,
     camellia_ctx_free
 };
 
@@ -1046,6 +1072,7 @@
     gcm_camellia_setkey_wrap,
 #endif
     gcm_ctx_alloc,
+    gcm_ctx_clone,
     gcm_ctx_free,
 };
 
@@ -1117,6 +1144,7 @@
     ccm_camellia_setkey_wrap,
 #endif
     ccm_ctx_alloc,
+    ccm_ctx_clone,
     ccm_ctx_free,
 };
 
@@ -1702,6 +1730,11 @@
     return des;
 }
 
+static void des_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_des_context));
+}
+
 static void des_ctx_free(void *ctx)
 {
     mbedtls_des_free((mbedtls_des_context *) ctx);
@@ -1722,6 +1755,11 @@
     return des3;
 }
 
+static void des3_ctx_clone(void *dst, const void *src)
+{
+    memcpy(dst, src, sizeof(mbedtls_des3_context));
+}
+
 static void des3_ctx_free(void *ctx)
 {
     mbedtls_des3_free((mbedtls_des3_context *) ctx);
@@ -1752,6 +1790,7 @@
     des_setkey_enc_wrap,
     des_setkey_dec_wrap,
     des_ctx_alloc,
+    des_ctx_clone,
     des_ctx_free
 };
 
@@ -1803,6 +1842,7 @@
     des3_set2key_enc_wrap,
     des3_set2key_dec_wrap,
     des3_ctx_alloc,
+    des3_ctx_clone,
     des3_ctx_free
 };
 
@@ -1854,6 +1894,7 @@
     des3_set3key_enc_wrap,
     des3_set3key_dec_wrap,
     des3_ctx_alloc,
+    des3_ctx_clone,
     des3_ctx_free
 };
 
@@ -2073,6 +2114,12 @@
     return (void *) 1;
 }
 
+static void null_ctx_clone(void *dst, const void *src)
+{
+    ((void) dst);
+    ((void) src);
+}
+
 static void null_ctx_free(void *ctx)
 {
     ((void) ctx);
@@ -2104,6 +2151,7 @@
     null_setkey,
 #endif
     null_ctx_alloc,
+    null_ctx_clone,
     null_ctx_free
 };
 
diff --git a/lib/libmbedtls/mbedtls/library/cipher_wrap.h b/lib/libmbedtls/mbedtls/library/cipher_wrap.h
index f229151..aa74289 100644
--- a/lib/libmbedtls/mbedtls/library/cipher_wrap.h
+++ b/lib/libmbedtls/mbedtls/library/cipher_wrap.h
@@ -134,6 +134,9 @@
     /** Allocate a new context */
     void * (*ctx_alloc_func)(void);
 
+    /** Clone context **/
+    void (*ctx_clone_func)( void *dst, const void *src );
+
     /** Free the given context */
     void (*ctx_free_func)(void *ctx);
 
diff --git a/lib/libmbedtls/mbedtls/library/cmac.c b/lib/libmbedtls/mbedtls/library/cmac.c
index eda10d0..a1ef947 100644
--- a/lib/libmbedtls/mbedtls/library/cmac.c
+++ b/lib/libmbedtls/mbedtls/library/cmac.c
@@ -153,11 +153,26 @@
     }
 }
 
+int mbedtls_cipher_cmac_setup(mbedtls_cipher_context_t *ctx)
+{
+    mbedtls_cmac_context_t *cmac_ctx;
+
+    /* Allocated and initialise in the cipher context memory for the CMAC
+     * context */
+    cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
+    if (cmac_ctx == NULL)
+        return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
+
+    ctx->cmac_ctx = cmac_ctx;
+
+    mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
+    return 0;
+}
+
 int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
                                const unsigned char *key, size_t keybits)
 {
     mbedtls_cipher_type_t type;
-    mbedtls_cmac_context_t *cmac_ctx;
     int retval;
 
     if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
@@ -181,18 +196,11 @@
             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
-    /* Allocated and initialise in the cipher context memory for the CMAC
-     * context */
-    cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
-    if (cmac_ctx == NULL) {
-        return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
-    }
+    /* Check if cmac ctx had been allocated by mbedtls_cipher_cmac_setup() */
+    if( ctx->cmac_ctx != NULL )
+        return 0;
 
-    ctx->cmac_ctx = cmac_ctx;
-
-    mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
-
-    return 0;
+    return mbedtls_cipher_cmac_setup( ctx );
 }
 
 int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
diff --git a/lib/libmbedtls/mbedtls/library/md.c b/lib/libmbedtls/mbedtls/library/md.c
index c95846a..f263dcb 100644
--- a/lib/libmbedtls/mbedtls/library/md.c
+++ b/lib/libmbedtls/mbedtls/library/md.c
@@ -403,6 +403,9 @@
             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
     }
 
+    if (dst->hmac_ctx != NULL && src->hmac_ctx != NULL)
+        memcpy(dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size);
+
     return 0;
 }