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]
Signed-off-by: Jerome Forissier <jerome@forissier.org>
[jf: rebase onto mbedtls-2.27.0]
Signed-off-by: Jerome Forissier <jerome@forissier.org>
diff --git a/lib/libmbedtls/mbedtls/library/cipher.c b/lib/libmbedtls/mbedtls/library/cipher.c
index 457f8f6..789185c 100644
--- a/lib/libmbedtls/mbedtls/library/cipher.c
+++ b/lib/libmbedtls/mbedtls/library/cipher.c
@@ -210,6 +210,36 @@
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( dst->cipher_info->base->ctx_clone_func )
+ dst->cipher_info->base->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 )
{
@@ -270,6 +300,15 @@
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
+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 57eb3cb..51def60 100644
--- a/lib/libmbedtls/mbedtls/library/cipher_wrap.c
+++ b/lib/libmbedtls/mbedtls/library/cipher_wrap.c
@@ -23,6 +23,8 @@
#include "common.h"
+#include <string.h>
+
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher_internal.h"
@@ -96,6 +98,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 );
@@ -115,6 +122,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 );
@@ -219,6 +231,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 );
@@ -249,6 +266,7 @@
aes_setkey_enc_wrap,
aes_setkey_dec_wrap,
aes_ctx_alloc,
+ aes_ctx_clone,
aes_ctx_free
};
@@ -543,6 +561,7 @@
gcm_aes_setkey_wrap,
gcm_aes_setkey_wrap,
gcm_ctx_alloc,
+ gcm_ctx_clone,
gcm_ctx_free,
};
@@ -612,6 +631,7 @@
ccm_aes_setkey_wrap,
ccm_aes_setkey_wrap,
ccm_ctx_alloc,
+ ccm_ctx_clone,
ccm_ctx_free,
};
@@ -715,6 +735,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 );
@@ -745,6 +770,7 @@
camellia_setkey_enc_wrap,
camellia_setkey_dec_wrap,
camellia_ctx_alloc,
+ camellia_ctx_clone,
camellia_ctx_free
};
@@ -918,6 +944,7 @@
gcm_camellia_setkey_wrap,
gcm_camellia_setkey_wrap,
gcm_ctx_alloc,
+ gcm_ctx_clone,
gcm_ctx_free,
};
@@ -987,6 +1014,7 @@
ccm_camellia_setkey_wrap,
ccm_camellia_setkey_wrap,
ccm_ctx_alloc,
+ ccm_ctx_clone,
ccm_ctx_free,
};
@@ -1496,6 +1524,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 );
@@ -1515,6 +1548,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 );
@@ -1545,6 +1583,7 @@
des_setkey_enc_wrap,
des_setkey_dec_wrap,
des_ctx_alloc,
+ des_ctx_clone,
des_ctx_free
};
@@ -1596,6 +1635,7 @@
des3_set2key_enc_wrap,
des3_set2key_dec_wrap,
des3_ctx_alloc,
+ des3_ctx_clone,
des3_ctx_free
};
@@ -1647,6 +1687,7 @@
des3_set3key_enc_wrap,
des3_set3key_dec_wrap,
des3_ctx_alloc,
+ des3_ctx_clone,
des3_ctx_free
};
@@ -1732,6 +1773,11 @@
return( ctx );
}
+static void blowfish_ctx_clone( void *dst, const void *src )
+{
+ memcpy( dst, src, sizeof( mbedtls_blowfish_context ) );
+}
+
static void blowfish_ctx_free( void *ctx )
{
mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
@@ -1762,6 +1808,7 @@
blowfish_setkey_wrap,
blowfish_setkey_wrap,
blowfish_ctx_alloc,
+ blowfish_ctx_clone,
blowfish_ctx_free
};
@@ -1848,6 +1895,11 @@
return( ctx );
}
+static void arc4_ctx_clone( void *dst, const void *src )
+{
+ memcpy( dst, src, sizeof( mbedtls_arc4_context ) );
+}
+
static void arc4_ctx_free( void *ctx )
{
mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
@@ -1878,6 +1930,7 @@
arc4_setkey_wrap,
arc4_setkey_wrap,
arc4_ctx_alloc,
+ arc4_ctx_clone,
arc4_ctx_free
};
@@ -2074,6 +2127,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);
@@ -2103,6 +2162,7 @@
null_setkey,
null_setkey,
null_ctx_alloc,
+ null_ctx_clone,
null_ctx_free
};
diff --git a/lib/libmbedtls/mbedtls/library/cmac.c b/lib/libmbedtls/mbedtls/library/cmac.c
index 3cc49d1..8dd7fab 100644
--- a/lib/libmbedtls/mbedtls/library/cmac.c
+++ b/lib/libmbedtls/mbedtls/library/cmac.c
@@ -182,11 +182,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 )
@@ -209,17 +224,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 a10a835..341a9cf 100644
--- a/lib/libmbedtls/mbedtls/library/md.c
+++ b/lib/libmbedtls/mbedtls/library/md.c
@@ -387,6 +387,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 );
}