aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdison Ai <edison.ai@arm.com>2017-12-27 14:02:42 +0800
committerJérôme Forissier <jerome.forissier@linaro.org>2019-04-01 09:34:25 +0200
commitebc81cdc315257cd2d1dff822e822cb9d4f33495 (patch)
treef52c560e046e5d555993030b2584f74c18f4ffd3
parent2b716ccc528914f136d81ef361e0b44bc98266b2 (diff)
libmbedtls: support CMAC algorithm
Implement CMAC function based on mbedtls. 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>
-rw-r--r--lib/libmbedtls/core/aes_cmac.c159
-rw-r--r--lib/libmbedtls/core/stubbed.c3
-rw-r--r--lib/libmbedtls/core/sub.mk1
-rw-r--r--lib/libmbedtls/include/mbedtls_config_kernel.h5
4 files changed, 165 insertions, 3 deletions
diff --git a/lib/libmbedtls/core/aes_cmac.c b/lib/libmbedtls/core/aes_cmac.c
new file mode 100644
index 00000000..8a3374e1
--- /dev/null
+++ b/lib/libmbedtls/core/aes_cmac.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2018, ARM Limited
+ * Copyright (C) 2019, Linaro Limited
+ */
+
+#include <assert.h>
+#include <compiler.h>
+#include <crypto/crypto.h>
+#include <crypto/crypto_impl.h>
+#include <kernel/panic.h>
+#include <mbedtls/cipher.h>
+#include <mbedtls/cmac.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tee_api_types.h>
+#include <utee_defines.h>
+#include <util.h>
+
+struct mbed_aes_cmac_ctx {
+ struct crypto_mac_ctx mac_ctx;
+ mbedtls_cipher_context_t cipher_ctx;
+};
+
+static const struct crypto_mac_ops mbed_aes_cmac_ops;
+
+static struct mbed_aes_cmac_ctx *to_aes_cmac_ctx(struct crypto_mac_ctx *ctx)
+{
+ assert(ctx && ctx->ops == &mbed_aes_cmac_ops);
+
+ return container_of(ctx, struct mbed_aes_cmac_ctx, mac_ctx);
+}
+
+static TEE_Result mbed_aes_cmac_init(struct crypto_mac_ctx *ctx,
+ const uint8_t *key, size_t len)
+{
+ struct mbed_aes_cmac_ctx *c = to_aes_cmac_ctx(ctx);
+ const mbedtls_cipher_info_t *cipher_info = NULL;
+
+ cipher_info = mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES,
+ len * 8,
+ MBEDTLS_MODE_ECB);
+ if (!cipher_info)
+ return TEE_ERROR_NOT_SUPPORTED;
+
+ if (mbedtls_cipher_setup_info(&c->cipher_ctx, cipher_info))
+ return TEE_ERROR_BAD_STATE;
+
+ if (mbedtls_cipher_cmac_reset(&c->cipher_ctx))
+ return TEE_ERROR_BAD_STATE;
+
+ if (mbedtls_cipher_cmac_starts(&c->cipher_ctx, key, len * 8))
+ return TEE_ERROR_BAD_STATE;
+
+ return TEE_SUCCESS;
+}
+
+static TEE_Result mbed_aes_cmac_update(struct crypto_mac_ctx *ctx,
+ const uint8_t *data, size_t len)
+{
+ if (mbedtls_cipher_cmac_update(&to_aes_cmac_ctx(ctx)->cipher_ctx,
+ data, len))
+ return TEE_ERROR_BAD_STATE;
+
+ return TEE_SUCCESS;
+}
+
+static TEE_Result mbed_aes_cmac_final(struct crypto_mac_ctx *ctx, uint8_t *digest,
+ size_t len)
+{
+ struct mbed_aes_cmac_ctx *c = to_aes_cmac_ctx(ctx);
+ uint8_t block_digest[TEE_AES_BLOCK_SIZE] = { 0 };
+ uint8_t *tmp_digest = NULL;
+
+ if (len == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ if (len < sizeof(block_digest))
+ tmp_digest = block_digest; /* use a tempory buffer */
+ else
+ tmp_digest = digest;
+
+ if (mbedtls_cipher_cmac_finish(&c->cipher_ctx, tmp_digest))
+ return TEE_ERROR_BAD_STATE;
+
+ if (len < sizeof(block_digest))
+ memcpy(digest, tmp_digest, len);
+
+ return TEE_SUCCESS;
+}
+
+static void mbed_aes_cmac_free_ctx(struct crypto_mac_ctx *ctx)
+{
+ struct mbed_aes_cmac_ctx *c = to_aes_cmac_ctx(ctx);
+
+ mbedtls_cipher_free(&c->cipher_ctx);
+ free(c);
+}
+
+static void mbed_aes_cmac_copy_state(struct crypto_mac_ctx *dst_ctx,
+ struct crypto_mac_ctx *src_ctx)
+{
+ struct mbed_aes_cmac_ctx *src = to_aes_cmac_ctx(src_ctx);
+ struct mbed_aes_cmac_ctx *dst = to_aes_cmac_ctx(dst_ctx);
+
+ if (mbedtls_cipher_clone(&dst->cipher_ctx, &src->cipher_ctx))
+ panic();
+}
+
+static const struct crypto_mac_ops mbed_aes_cmac_ops = {
+ .init = mbed_aes_cmac_init,
+ .update = mbed_aes_cmac_update,
+ .final = mbed_aes_cmac_final,
+ .free_ctx = mbed_aes_cmac_free_ctx,
+ .copy_state = mbed_aes_cmac_copy_state,
+};
+
+TEE_Result crypto_aes_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret)
+{
+ int mbed_res = 0;
+ struct mbed_aes_cmac_ctx *c = NULL;
+ const mbedtls_cipher_info_t *cipher_info = NULL;
+
+ /*
+ * Use a default key length for getting 'cipher_info' to do the
+ * setup. The 'cipher_info' will need to be re-assigned with final
+ * key length obtained in mbed_aes_cmac_init() above.
+ *
+ * This is safe since 'mbedtls_cipher_base_t' (used for cipher
+ * context) uses the same fixed allocation all key lengths.
+ */
+ cipher_info = mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES,
+ 128, MBEDTLS_MODE_ECB);
+ if (!cipher_info)
+ return TEE_ERROR_NOT_SUPPORTED;
+
+ c = calloc(1, sizeof(*c));
+ if (!c)
+ return TEE_ERROR_OUT_OF_MEMORY;
+
+ c->mac_ctx.ops = &mbed_aes_cmac_ops;
+ mbedtls_cipher_init(&c->cipher_ctx);
+ mbed_res = mbedtls_cipher_setup(&c->cipher_ctx, cipher_info);
+ if (mbed_res) {
+ free(c);
+ if (mbed_res == MBEDTLS_ERR_CIPHER_ALLOC_FAILED)
+ return TEE_ERROR_OUT_OF_MEMORY;
+ return TEE_ERROR_NOT_SUPPORTED;
+ }
+ mbed_res = mbedtls_cipher_cmac_setup(&c->cipher_ctx);
+ if (mbed_res) {
+ free(c);
+ return TEE_ERROR_NOT_SUPPORTED;
+ }
+
+ *ctx_ret = &c->mac_ctx;
+
+ return TEE_SUCCESS;
+}
diff --git a/lib/libmbedtls/core/stubbed.c b/lib/libmbedtls/core/stubbed.c
index 2aca4e48..0cc6bc3c 100644
--- a/lib/libmbedtls/core/stubbed.c
+++ b/lib/libmbedtls/core/stubbed.c
@@ -283,9 +283,6 @@ crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key __unused,
crypto_##name##_alloc_ctx(struct crypto_##type##_ctx **ctx __unused) \
{ return TEE_ERROR_NOT_IMPLEMENTED; }
-#if defined(CFG_CRYPTO_CMAC)
-CRYPTO_ALLOC_CTX_NOT_IMPLEMENTED(aes_cmac, mac)
-#endif
#if defined(CFG_CRYPTO_AES) && defined(CFG_CRYPTO_XTS)
CRYPTO_ALLOC_CTX_NOT_IMPLEMENTED(aes_xts, cipher)
#endif
diff --git a/lib/libmbedtls/core/sub.mk b/lib/libmbedtls/core/sub.mk
index cd0bdb03..cf65453d 100644
--- a/lib/libmbedtls/core/sub.mk
+++ b/lib/libmbedtls/core/sub.mk
@@ -20,3 +20,4 @@ srcs-$(CFG_CRYPTO_CBC) += des3_cbc.c
endif
srcs-$(CFG_CRYPTO_HMAC) += hmac.c
+srcs-$(CFG_CRYPTO_CMAC) += aes_cmac.c
diff --git a/lib/libmbedtls/include/mbedtls_config_kernel.h b/lib/libmbedtls/include/mbedtls_config_kernel.h
index bdb34e84..bb7b3787 100644
--- a/lib/libmbedtls/include/mbedtls_config_kernel.h
+++ b/lib/libmbedtls/include/mbedtls_config_kernel.h
@@ -58,6 +58,11 @@
#define MBEDTLS_CIPHER_MODE_CTR
#endif
+#if defined(CFG_CRYPTO_CMAC)
+#define MBEDTLS_CMAC_C
+#define MBEDTLS_CIPHER_C
+#endif
+
#endif /*CFG_CRYPTOLIB_NAME_mbedtls*/
#include <mbedtls/check_config.h>