diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2019-03-08 15:22:11 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2019-03-11 17:58:04 +0100 |
commit | 6648f482e70e0fa021696c7f4fece3eeb714b9f2 (patch) | |
tree | f437b3876f2a0f34a529528d634383434fba2c6d /core/lib | |
parent | 46bd5aef4ff6daa66afcb4a8de5d5afabef01fa1 (diff) |
core: crypto: introduce struct crypto_hash_ops
Uses struct crypto_hash_ops pointer in crypto context for hashes as a
glue layer instead of a switch(algo) in each crypto_hash_*() function.
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/lib')
-rw-r--r-- | core/lib/libtomcrypt/hash.c | 168 | ||||
-rw-r--r-- | core/lib/libtomcrypt/src/tee_ltc_provider.c | 144 | ||||
-rw-r--r-- | core/lib/libtomcrypt/sub.mk | 2 |
3 files changed, 170 insertions, 144 deletions
diff --git a/core/lib/libtomcrypt/hash.c b/core/lib/libtomcrypt/hash.c new file mode 100644 index 00000000..72fabc6d --- /dev/null +++ b/core/lib/libtomcrypt/hash.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2014-2019, Linaro Limited + */ + +#include <assert.h> +#include <crypto/crypto.h> +#include <crypto/crypto_impl.h> +#include <stdlib.h> +#include <string.h> +#include <tee_api_types.h> +#include <tomcrypt.h> +#include <utee_defines.h> +#include <util.h> + +/****************************************************************************** + * Message digest functions + ******************************************************************************/ + +struct ltc_hash_ctx { + struct crypto_hash_ctx ctx; + const struct ltc_hash_descriptor *descr; + hash_state state; +}; + +static const struct crypto_hash_ops ltc_hash_ops; + +static struct ltc_hash_ctx *to_hash_ctx(struct crypto_hash_ctx *ctx) +{ + assert(ctx && ctx->ops == <c_hash_ops); + + return container_of(ctx, struct ltc_hash_ctx, ctx); +} + +static TEE_Result ltc_hash_init(struct crypto_hash_ctx *ctx) +{ + struct ltc_hash_ctx *hc = to_hash_ctx(ctx); + + if (hc->descr->init(&hc->state) == CRYPT_OK) + return TEE_SUCCESS; + else + return TEE_ERROR_BAD_STATE; +} + +static TEE_Result ltc_hash_update(struct crypto_hash_ctx *ctx, + const uint8_t *data, size_t len) +{ + struct ltc_hash_ctx *hc = to_hash_ctx(ctx); + + if (hc->descr->process(&hc->state, data, len) == CRYPT_OK) + return TEE_SUCCESS; + else + return TEE_ERROR_BAD_STATE; +} + +static TEE_Result ltc_hash_final(struct crypto_hash_ctx *ctx, uint8_t *digest, + size_t len) +{ + struct ltc_hash_ctx *hc = to_hash_ctx(ctx); + size_t hash_size = hc->descr->hashsize; + uint8_t block_digest[TEE_MAX_HASH_SIZE] = { 0 }; + uint8_t *tmp_digest = NULL; + + if (len == 0) + return TEE_ERROR_BAD_PARAMETERS; + + if (hash_size > len) { + if (hash_size > sizeof(block_digest)) + return TEE_ERROR_BAD_STATE; + tmp_digest = block_digest; /* use a tempory buffer */ + } else { + tmp_digest = digest; + } + + if (hc->descr->done(&hc->state, tmp_digest) == CRYPT_OK) { + if (hash_size > len) + memcpy(digest, tmp_digest, len); + } else { + return TEE_ERROR_BAD_STATE; + } + + return TEE_SUCCESS; +} + +static void ltc_hash_free_ctx(struct crypto_hash_ctx *ctx) +{ + free(to_hash_ctx(ctx)); +} + +static void ltc_hash_copy_state(struct crypto_hash_ctx *dst_ctx, + struct crypto_hash_ctx *src_ctx) +{ + struct ltc_hash_ctx *src = to_hash_ctx(src_ctx); + struct ltc_hash_ctx *dst = to_hash_ctx(dst_ctx); + + assert(src->descr == dst->descr); + dst->state = src->state; +} + +static const struct crypto_hash_ops ltc_hash_ops = { + .init = ltc_hash_init, + .update = ltc_hash_update, + .final = ltc_hash_final, + .free_ctx = ltc_hash_free_ctx, + .copy_state = ltc_hash_copy_state, +}; + +static TEE_Result ltc_hash_alloc_ctx(struct crypto_hash_ctx **ctx_ret, + int ltc_hash_idx) +{ + struct ltc_hash_ctx *ctx = NULL; + + if (ltc_hash_idx < 0) + return TEE_ERROR_NOT_SUPPORTED; + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) + return TEE_ERROR_OUT_OF_MEMORY; + + ctx->ctx.ops = <c_hash_ops; + ctx->descr = hash_descriptor[ltc_hash_idx]; + + *ctx_ret = &ctx->ctx; + + return TEE_SUCCESS; +} + +#if defined(CFG_CRYPTO_MD5) +TEE_Result crypto_md5_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("md5")); +} +#endif + +#if defined(CFG_CRYPTO_SHA1) +TEE_Result crypto_sha1_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("sha1")); +} +#endif + +#if defined(CFG_CRYPTO_SHA224) +TEE_Result crypto_sha224_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("sha224")); +} +#endif + +#if defined(CFG_CRYPTO_SHA256) +TEE_Result crypto_sha256_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("sha256")); +} +#endif + +#if defined(CFG_CRYPTO_SHA384) +TEE_Result crypto_sha384_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("sha384")); +} +#endif + +#if defined(CFG_CRYPTO_SHA512) +TEE_Result crypto_sha512_alloc_ctx(struct crypto_hash_ctx **ctx) +{ + return ltc_hash_alloc_ctx(ctx, find_hash("sha512")); +} +#endif diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index a29bdef7..5609d278 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -271,150 +271,6 @@ static TEE_Result tee_algo_to_ltc_cipherindex(uint32_t algo, defined(_CFG_CRYPTO_WITH_HASH) || defined(_CFG_CRYPTO_WITH_AUTHENC) */ /****************************************************************************** - * Message digest functions - ******************************************************************************/ - -#if defined(_CFG_CRYPTO_WITH_HASH) - -static TEE_Result hash_get_ctx_size(uint32_t algo, size_t *size) -{ - switch (algo) { -#if defined(CFG_CRYPTO_MD5) - case TEE_ALG_MD5: -#endif -#if defined(CFG_CRYPTO_SHA1) - case TEE_ALG_SHA1: -#endif -#if defined(CFG_CRYPTO_SHA224) - case TEE_ALG_SHA224: -#endif -#if defined(CFG_CRYPTO_SHA256) - case TEE_ALG_SHA256: -#endif -#if defined(CFG_CRYPTO_SHA384) - case TEE_ALG_SHA384: -#endif -#if defined(CFG_CRYPTO_SHA512) - case TEE_ALG_SHA512: -#endif - *size = sizeof(hash_state); - break; - default: - return TEE_ERROR_NOT_SUPPORTED; - } - - return TEE_SUCCESS; -} - -TEE_Result crypto_hash_alloc_ctx(void **ctx_ret, uint32_t algo) -{ - TEE_Result res; - size_t ctx_size; - void *ctx; - - res = hash_get_ctx_size(algo, &ctx_size); - if (res) - return res; - - ctx = calloc(1, ctx_size); - if (!ctx) - return TEE_ERROR_OUT_OF_MEMORY; - - *ctx_ret = ctx; - return TEE_SUCCESS; -} - -void crypto_hash_free_ctx(void *ctx, uint32_t algo __unused) -{ - size_t ctx_size __maybe_unused; - - /* - * Check that it's a supported algo, or crypto_hash_alloc_ctx() - * could never have succeded above. - */ - if (ctx) - assert(!hash_get_ctx_size(algo, &ctx_size)); - free(ctx); -} - -void crypto_hash_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo) -{ - TEE_Result res __maybe_unused; - size_t ctx_size = 0; - - res = hash_get_ctx_size(algo, &ctx_size); - assert(!res); - memcpy(dst_ctx, src_ctx, ctx_size); -} - -TEE_Result crypto_hash_init(void *ctx, uint32_t algo) -{ - int ltc_res; - int ltc_hashindex; - - ltc_res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); - if (ltc_res != TEE_SUCCESS) - return TEE_ERROR_NOT_SUPPORTED; - - if (hash_descriptor[ltc_hashindex]->init(ctx) == CRYPT_OK) - return TEE_SUCCESS; - else - return TEE_ERROR_BAD_STATE; -} - -TEE_Result crypto_hash_update(void *ctx, uint32_t algo, - const uint8_t *data, size_t len) -{ - int ltc_res; - int ltc_hashindex; - - ltc_res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); - if (ltc_res != TEE_SUCCESS) - return TEE_ERROR_NOT_SUPPORTED; - - if (hash_descriptor[ltc_hashindex]->process(ctx, data, len) == CRYPT_OK) - return TEE_SUCCESS; - else - return TEE_ERROR_BAD_STATE; -} - -TEE_Result crypto_hash_final(void *ctx, uint32_t algo, uint8_t *digest, - size_t len) -{ - int ltc_res; - int ltc_hashindex; - size_t hash_size; - uint8_t block_digest[TEE_MAX_HASH_SIZE]; - uint8_t *tmp_digest; - - ltc_res = tee_algo_to_ltc_hashindex(algo, <c_hashindex); - if (ltc_res != TEE_SUCCESS) - return TEE_ERROR_NOT_SUPPORTED; - - if (len == 0) - return TEE_ERROR_BAD_PARAMETERS; - - hash_size = hash_descriptor[ltc_hashindex]->hashsize; - - if (hash_size > len) { - if (hash_size > sizeof(block_digest)) - return TEE_ERROR_BAD_STATE; - tmp_digest = block_digest; /* use a tempory buffer */ - } else { - tmp_digest = digest; - } - if (hash_descriptor[ltc_hashindex]->done(ctx, tmp_digest) == CRYPT_OK) { - if (hash_size > len) - memcpy(digest, tmp_digest, len); - } else { - return TEE_ERROR_BAD_STATE; - } - - return TEE_SUCCESS; -} -#endif /*_CFG_CRYPTO_WITH_HASH*/ - -/****************************************************************************** * Asymmetric algorithms ******************************************************************************/ diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk index 8ad0db6a..3e338995 100644 --- a/core/lib/libtomcrypt/sub.mk +++ b/core/lib/libtomcrypt/sub.mk @@ -5,3 +5,5 @@ cflags-lib-$(CFG_CRYPTO_SIZE_OPTIMIZATION) += -Os global-incdirs-y += include subdirs-y += src + +srcs-$(_CFG_CRYPTO_WITH_HASH) += hash.c |