aboutsummaryrefslogtreecommitdiff
path: root/core/lib
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2019-03-08 15:22:11 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2019-03-11 17:58:04 +0100
commit6648f482e70e0fa021696c7f4fece3eeb714b9f2 (patch)
treef437b3876f2a0f34a529528d634383434fba2c6d /core/lib
parent46bd5aef4ff6daa66afcb4a8de5d5afabef01fa1 (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.c168
-rw-r--r--core/lib/libtomcrypt/src/tee_ltc_provider.c144
-rw-r--r--core/lib/libtomcrypt/sub.mk2
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 == &ltc_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 = &ltc_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, &ltc_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, &ltc_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, &ltc_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