diff options
author | Edison Ai <edison.ai@arm.com> | 2017-12-27 14:02:42 +0800 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2019-04-01 09:34:25 +0200 |
commit | ebc81cdc315257cd2d1dff822e822cb9d4f33495 (patch) | |
tree | f52c560e046e5d555993030b2584f74c18f4ffd3 | |
parent | 2b716ccc528914f136d81ef361e0b44bc98266b2 (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.c | 159 | ||||
-rw-r--r-- | lib/libmbedtls/core/stubbed.c | 3 | ||||
-rw-r--r-- | lib/libmbedtls/core/sub.mk | 1 | ||||
-rw-r--r-- | lib/libmbedtls/include/mbedtls_config_kernel.h | 5 |
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> |