From 323f59e859ce8921ac424f929eb5ef86b25e854c Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 13 Nov 2017 18:20:14 +0100 Subject: [PATCH 01/12] core: crypto: fix crypto_rng_read() comment Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/include/tee/tee_cryp_provider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index b94e022b263..c6db4e1a58a 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -308,7 +308,7 @@ TEE_Result hash_sha256_check(const uint8_t *hash, const uint8_t *data, /* Add entropy to PRNG entropy pool. */ TEE_Result crypto_rng_add_entropy(const uint8_t *inbuf, size_t len); -/* To read random data from PRNG implementation. */ +/* To read random data from PRNG implementation. */ TEE_Result crypto_rng_read(void *buf, size_t blen); TEE_Result rng_generate(void *buffer, size_t len); From 6867c715455aa19290f6f8c82df3deb10950ae5a Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 9 Nov 2017 22:28:20 +0100 Subject: [PATCH 02/12] Replace struct hash_ops with function interface Adds crypto_hash_get_ctx_size(), crypto_hash_init(), crypto_hash_update() and crypto_hash_final() replacing struct hash_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/kernel/ree_fs_ta.c | 17 ++++------- core/crypto/crypto.c | 32 +++++++++++++++++++++ core/crypto/sub.mk | 1 + core/include/tee/tee_cryp_provider.h | 20 ++++++------- core/lib/libtomcrypt/src/tee_ltc_provider.c | 22 ++++---------- core/sub.mk | 1 + core/tee/fs_htree.c | 26 +++++++---------- core/tee/tee_cryp_concat_kdf.c | 19 ++++-------- core/tee/tee_cryp_utl.c | 14 +++------ core/tee/tee_fs_key_manager.c | 8 +++--- core/tee/tee_svc_cryp.c | 24 ++++------------ 11 files changed, 84 insertions(+), 100 deletions(-) create mode 100644 core/crypto/crypto.c create mode 100644 core/crypto/sub.mk diff --git a/core/arch/arm/kernel/ree_fs_ta.c b/core/arch/arm/kernel/ree_fs_ta.c index 888bcfcdcc4..cc5b4b1a37d 100644 --- a/core/arch/arm/kernel/ree_fs_ta.c +++ b/core/arch/arm/kernel/ree_fs_ta.c @@ -187,11 +187,6 @@ static TEE_Result ta_open(const TEE_UUID *uuid, uint64_t cookie = 0; TEE_Result res; - if (!crypto_ops.hash.get_ctx_size || - !crypto_ops.hash.init || - !crypto_ops.hash.update) - return TEE_ERROR_NOT_SUPPORTED; - handle = calloc(1, sizeof(*handle)); if (!handle) return TEE_ERROR_OUT_OF_MEMORY; @@ -216,7 +211,7 @@ static TEE_Result ta_open(const TEE_UUID *uuid, * header (less the final file hash and its signature of course) */ hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo); - res = crypto_ops.hash.get_ctx_size(hash_algo, &hash_ctx_size); + res = crypto_hash_get_ctx_size(hash_algo, &hash_ctx_size); if (res != TEE_SUCCESS) goto error_free_payload; hash_ctx = malloc(hash_ctx_size); @@ -224,10 +219,10 @@ static TEE_Result ta_open(const TEE_UUID *uuid, res = TEE_ERROR_OUT_OF_MEMORY; goto error_free_payload; } - res = crypto_ops.hash.init(hash_ctx, hash_algo); + res = crypto_hash_init(hash_ctx, hash_algo); if (res != TEE_SUCCESS) goto error_free_payload; - res = crypto_ops.hash.update(hash_ctx, hash_algo, (uint8_t *)shdr, + res = crypto_hash_update(hash_ctx, hash_algo, (uint8_t *)shdr, sizeof(*shdr)); if (res != TEE_SUCCESS) goto error_free_payload; @@ -269,12 +264,10 @@ static TEE_Result check_digest(struct user_ta_store_handle *h) void *digest = NULL; TEE_Result res; - if (!crypto_ops.hash.final) - return TEE_ERROR_NOT_SUPPORTED; digest = malloc(h->shdr->hash_size); if (!digest) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.hash.final(h->hash_ctx, h->hash_algo, digest, + res = crypto_hash_final(h->hash_ctx, h->hash_algo, digest, h->shdr->hash_size); if (res != TEE_SUCCESS) { res = TEE_ERROR_SECURITY; @@ -300,7 +293,7 @@ static TEE_Result ta_read(struct user_ta_store_handle *h, void *data, dst = data; /* Hash secure buffer (shm might be modified) */ memcpy(dst, src, len); } - res = crypto_ops.hash.update(h->hash_ctx, h->hash_algo, dst, len); + res = crypto_hash_update(h->hash_ctx, h->hash_algo, dst, len); if (res != TEE_SUCCESS) return TEE_ERROR_SECURITY; h->offs += len; diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c new file mode 100644 index 00000000000..91b325b3f46 --- /dev/null +++ b/core/crypto/crypto.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +#if !defined(_CFG_CRYPTO_WITH_HASH) +TEE_Result crypto_hash_get_ctx_size(uint32_t algo __unused, + size_t *size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_hash_init(void *ctx __unused, uint32_t algo __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +TEE_Result crypto_hash_update(void *ctx __unused, uint32_t algo __unused, + const uint8_t *data __unused, size_t len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +TEE_Result crypto_hash_final(void *ctx __unused, uint32_t algo __unused, + uint8_t *digest __unused, size_t len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*_CFG_CRYPTO_WITH_HASH*/ diff --git a/core/crypto/sub.mk b/core/crypto/sub.mk new file mode 100644 index 00000000000..7f72ebd0775 --- /dev/null +++ b/core/crypto/sub.mk @@ -0,0 +1 @@ +srcs-y += crypto.c diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index c6db4e1a58a..81915aa9cd8 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,16 +47,6 @@ #include -/* Message digest functions */ -struct hash_ops { - TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); - TEE_Result (*init)(void *ctx, uint32_t algo); - TEE_Result (*update)(void *ctx, uint32_t algo, - const uint8_t *data, size_t len); - TEE_Result (*final)(void *ctx, uint32_t algo, uint8_t *digest, - size_t len); -}; - /* Symmetric ciphers */ struct cipher_ops { TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); @@ -285,7 +275,6 @@ struct crypto_ops { const char *name; TEE_Result (*init)(void); - struct hash_ops hash; struct cipher_ops cipher; struct mac_ops mac; struct authenc_ops authenc; @@ -295,6 +284,15 @@ struct crypto_ops { extern const struct crypto_ops crypto_ops; + +/* Message digest functions */ +TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size); +TEE_Result crypto_hash_init(void *ctx, uint32_t algo); +TEE_Result crypto_hash_update(void *ctx, uint32_t algo, const uint8_t *data, + size_t len); +TEE_Result crypto_hash_final(void *ctx, uint32_t algo, uint8_t *digest, + size_t len); + /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in * advance and has as few dependencies as possible. diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index fc062a502e0..5e8ce25568a 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -369,8 +369,7 @@ static TEE_Result tee_algo_to_ltc_cipherindex(uint32_t algo, ******************************************************************************/ #if defined(_CFG_CRYPTO_WITH_HASH) - -static TEE_Result hash_get_ctx_size(uint32_t algo, size_t *size) +TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size) { switch (algo) { #if defined(CFG_CRYPTO_MD5) @@ -400,7 +399,7 @@ static TEE_Result hash_get_ctx_size(uint32_t algo, size_t *size) return TEE_SUCCESS; } -static TEE_Result hash_init(void *ctx, uint32_t algo) +TEE_Result crypto_hash_init(void *ctx, uint32_t algo) { int ltc_res; int ltc_hashindex; @@ -415,7 +414,7 @@ static TEE_Result hash_init(void *ctx, uint32_t algo) return TEE_ERROR_BAD_STATE; } -static TEE_Result hash_update(void *ctx, uint32_t algo, +TEE_Result crypto_hash_update(void *ctx, uint32_t algo, const uint8_t *data, size_t len) { int ltc_res; @@ -431,8 +430,8 @@ static TEE_Result hash_update(void *ctx, uint32_t algo, return TEE_ERROR_BAD_STATE; } -static TEE_Result hash_final(void *ctx, uint32_t algo, uint8_t *digest, - size_t len) +TEE_Result crypto_hash_final(void *ctx, uint32_t algo, uint8_t *digest, + size_t len) { int ltc_res; int ltc_hashindex; @@ -465,8 +464,7 @@ static TEE_Result hash_final(void *ctx, uint32_t algo, uint8_t *digest, return TEE_SUCCESS; } - -#endif /* _CFG_CRYPTO_WITH_HASH */ +#endif /*_CFG_CRYPTO_WITH_HASH*/ /****************************************************************************** * Asymmetric algorithms @@ -2982,14 +2980,6 @@ static TEE_Result tee_ltc_init(void) const struct crypto_ops crypto_ops = { .name = "LibTomCrypt provider", .init = tee_ltc_init, -#if defined(_CFG_CRYPTO_WITH_HASH) - .hash = { - .get_ctx_size = hash_get_ctx_size, - .init = hash_init, - .update = hash_update, - .final = hash_final, - }, -#endif #if defined(_CFG_CRYPTO_WITH_CIPHER) .cipher = { .final = cipher_final, diff --git a/core/sub.mk b/core/sub.mk index 20f97e17e4b..7e8b61bd2bb 100644 --- a/core/sub.mk +++ b/core/sub.mk @@ -1,4 +1,5 @@ subdirs-y += kernel +subdirs-y += crypto subdirs-y += tee subdirs-y += drivers diff --git a/core/tee/fs_htree.c b/core/tee/fs_htree.c index 31d412cd559..e91a8a97154 100644 --- a/core/tee/fs_htree.c +++ b/core/tee/fs_htree.c @@ -427,31 +427,29 @@ static TEE_Result calc_node_hash(struct htree_node *node, void *ctx, uint8_t *ndata = (uint8_t *)&node->node + sizeof(node->node.hash); size_t nsize = sizeof(node->node) - sizeof(node->node.hash); - res = crypto_ops.hash.init(ctx, alg); + res = crypto_hash_init(ctx, alg); if (res != TEE_SUCCESS) return res; - res = crypto_ops.hash.update(ctx, alg, ndata, nsize); + res = crypto_hash_update(ctx, alg, ndata, nsize); if (res != TEE_SUCCESS) return res; if (node->child[0]) { - res = crypto_ops.hash.update(ctx, alg, - node->child[0]->node.hash, - sizeof(node->child[0]->node.hash)); + res = crypto_hash_update(ctx, alg, node->child[0]->node.hash, + sizeof(node->child[0]->node.hash)); if (res != TEE_SUCCESS) return res; } if (node->child[1]) { - res = crypto_ops.hash.update(ctx, alg, - node->child[1]->node.hash, - sizeof(node->child[1]->node.hash)); + res = crypto_hash_update(ctx, alg, node->child[1]->node.hash, + sizeof(node->child[1]->node.hash)); if (res != TEE_SUCCESS) return res; } - return crypto_ops.hash.final(ctx, alg, digest, TEE_FS_HTREE_HASH_SIZE); + return crypto_hash_final(ctx, alg, digest, TEE_FS_HTREE_HASH_SIZE); } static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode, @@ -609,11 +607,7 @@ static TEE_Result verify_tree(struct tee_fs_htree *ht) size_t size; void *ctx; - if (!crypto_ops.hash.get_ctx_size || !crypto_ops.hash.init || - !crypto_ops.hash.update || !crypto_ops.hash.final) - return TEE_ERROR_NOT_SUPPORTED; - - res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); + res = crypto_hash_get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); if (res != TEE_SUCCESS) return res; @@ -633,7 +627,7 @@ static TEE_Result init_root_node(struct tee_fs_htree *ht) size_t size; void *ctx; - res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); + res = crypto_hash_get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); if (res != TEE_SUCCESS) return res; ctx = malloc(size); @@ -797,7 +791,7 @@ TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht_arg, if (!ht->dirty) return TEE_SUCCESS; - res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); + res = crypto_hash_get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); if (res != TEE_SUCCESS) return res; ctx = malloc(size); diff --git a/core/tee/tee_cryp_concat_kdf.c b/core/tee/tee_cryp_concat_kdf.c index b0c7c3d47ef..a68dbd6bf49 100644 --- a/core/tee/tee_cryp_concat_kdf.c +++ b/core/tee/tee_cryp_concat_kdf.c @@ -45,15 +45,8 @@ TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret, uint32_t be_count; uint8_t *out = derived_key; uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); - const struct hash_ops *hash = &crypto_ops.hash; - if (!hash->get_ctx_size || !hash->init || !hash->update || - !hash->final) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto out; - } - - res = hash->get_ctx_size(hash_algo, &ctx_size); + res = crypto_hash_get_ctx_size(hash_algo, &ctx_size); if (res != TEE_SUCCESS) goto out; @@ -72,24 +65,24 @@ TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret, for (i = 1; i <= n + 1; i++) { be_count = TEE_U32_TO_BIG_ENDIAN(i); - res = hash->init(ctx, hash_algo); + res = crypto_hash_init(ctx, hash_algo); if (res != TEE_SUCCESS) goto out; - res = hash->update(ctx, hash_algo, (uint8_t *)&be_count, + res = crypto_hash_update(ctx, hash_algo, (uint8_t *)&be_count, sizeof(be_count)); if (res != TEE_SUCCESS) goto out; - res = hash->update(ctx, hash_algo, shared_secret, + res = crypto_hash_update(ctx, hash_algo, shared_secret, shared_secret_len); if (res != TEE_SUCCESS) goto out; if (other_info && other_info_len) { - res = hash->update(ctx, hash_algo, other_info, + res = crypto_hash_update(ctx, hash_algo, other_info, other_info_len); if (res != TEE_SUCCESS) goto out; } - res = hash->final(ctx, hash_algo, tmp, sizeof(tmp)); + res = crypto_hash_final(ctx, hash_algo, tmp, sizeof(tmp)); if (res != TEE_SUCCESS) goto out; diff --git a/core/tee/tee_cryp_utl.c b/core/tee/tee_cryp_utl.c index a40ec9adbc5..e40a685086e 100644 --- a/core/tee/tee_cryp_utl.c +++ b/core/tee/tee_cryp_utl.c @@ -97,13 +97,7 @@ TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data, void *ctx = NULL; size_t ctxsize; - if (crypto_ops.hash.get_ctx_size == NULL || - crypto_ops.hash.init == NULL || - crypto_ops.hash.update == NULL || - crypto_ops.hash.final == NULL) - return TEE_ERROR_NOT_IMPLEMENTED; - - if (crypto_ops.hash.get_ctx_size(algo, &ctxsize) != TEE_SUCCESS) { + if (crypto_hash_get_ctx_size(algo, &ctxsize) != TEE_SUCCESS) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } @@ -114,16 +108,16 @@ TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data, goto out; } - if (crypto_ops.hash.init(ctx, algo) != TEE_SUCCESS) + if (crypto_hash_init(ctx, algo) != TEE_SUCCESS) goto out; if (datalen != 0) { - if (crypto_ops.hash.update(ctx, algo, data, datalen) + if (crypto_hash_update(ctx, algo, data, datalen) != TEE_SUCCESS) goto out; } - if (crypto_ops.hash.final(ctx, algo, digest, digestlen) != TEE_SUCCESS) + if (crypto_hash_final(ctx, algo, digest, digestlen) != TEE_SUCCESS) goto out; res = TEE_SUCCESS; diff --git a/core/tee/tee_fs_key_manager.c b/core/tee/tee_fs_key_manager.c index e42e731525e..4a834a9b69d 100644 --- a/core/tee/tee_fs_key_manager.c +++ b/core/tee/tee_fs_key_manager.c @@ -221,7 +221,7 @@ static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in, size_t ctx_size; uint32_t algo = TEE_ALG_SHA256; - res = crypto_ops.hash.get_ctx_size(algo, &ctx_size); + res = crypto_hash_get_ctx_size(algo, &ctx_size); if (res != TEE_SUCCESS) return res; @@ -229,15 +229,15 @@ static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in, if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.hash.init(ctx, algo); + res = crypto_hash_init(ctx, algo); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.hash.update(ctx, algo, in, in_size); + res = crypto_hash_update(ctx, algo, in, in_size); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.hash.final(ctx, algo, out, out_size); + res = crypto_hash_final(ctx, algo, out, out_size); out: free(ctx); diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 05c6fcfd1e8..814737434e1 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -2076,11 +2076,7 @@ TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode, if (key1 != 0 || key2 != 0) { res = TEE_ERROR_BAD_PARAMETERS; } else { - if (crypto_ops.hash.get_ctx_size) - res = crypto_ops.hash.get_ctx_size(algo, - &cs->ctx_size); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_hash_get_ctx_size(algo, &cs->ctx_size); if (res != TEE_SUCCESS) break; cs->ctx = calloc(1, cs->ctx_size); @@ -2195,9 +2191,7 @@ TEE_Result syscall_hash_init(unsigned long state, switch (TEE_ALG_GET_CLASS(cs->algo)) { case TEE_OPERATION_DIGEST: - if (!crypto_ops.hash.init) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.hash.init(cs->ctx, cs->algo); + res = crypto_hash_init(cs->ctx, cs->algo); if (res != TEE_SUCCESS) return res; break; @@ -2263,10 +2257,7 @@ TEE_Result syscall_hash_update(unsigned long state, const void *chunk, switch (TEE_ALG_GET_CLASS(cs->algo)) { case TEE_OPERATION_DIGEST: - if (!crypto_ops.hash.update) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.hash.update(cs->ctx, cs->algo, chunk, - chunk_size); + res = crypto_hash_update(cs->ctx, cs->algo, chunk, chunk_size); if (res != TEE_SUCCESS) return res; break; @@ -2327,8 +2318,6 @@ TEE_Result syscall_hash_final(unsigned long state, const void *chunk, switch (TEE_ALG_GET_CLASS(cs->algo)) { case TEE_OPERATION_DIGEST: - if (!crypto_ops.hash.update || !crypto_ops.hash.final) - return TEE_ERROR_NOT_IMPLEMENTED; res = tee_hash_get_digest_size(cs->algo, &hash_size); if (res != TEE_SUCCESS) return res; @@ -2338,14 +2327,13 @@ TEE_Result syscall_hash_final(unsigned long state, const void *chunk, } if (chunk_size) { - res = crypto_ops.hash.update(cs->ctx, cs->algo, chunk, - chunk_size); + res = crypto_hash_update(cs->ctx, cs->algo, chunk, + chunk_size); if (res != TEE_SUCCESS) return res; } - res = crypto_ops.hash.final(cs->ctx, cs->algo, hash, - hash_size); + res = crypto_hash_final(cs->ctx, cs->algo, hash, hash_size); if (res != TEE_SUCCESS) return res; break; From f51389bd5c7ec159019bf1f12284d34f0f62ec8e Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 9 Nov 2017 23:06:30 +0100 Subject: [PATCH 03/12] Replace struct cipher_ops with function interface Adds crypto_cipher_get_ctx_size(), crypto_cipher_init(), crypto_cipher_update(), crypto_cipher_final() and crypto_cipher_get_block_size() replacing struct cipher_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/crypto/crypto.c | 38 +++++++++++++++++++++ core/include/tee/tee_cryp_provider.h | 29 +++++++--------- core/lib/libtomcrypt/src/tee_ltc_provider.c | 33 ++++++------------ core/tee/tee_cryp_utl.c | 6 ++-- core/tee/tee_fs_key_manager.c | 34 +++++++++--------- core/tee/tee_svc_cryp.c | 30 +++++----------- 6 files changed, 89 insertions(+), 81 deletions(-) diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 91b325b3f46..b1a1baf570b 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -30,3 +30,41 @@ TEE_Result crypto_hash_final(void *ctx __unused, uint32_t algo __unused, return TEE_ERROR_NOT_IMPLEMENTED; } #endif /*_CFG_CRYPTO_WITH_HASH*/ + +#if !defined(_CFG_CRYPTO_WITH_CIPHER) +TEE_Result crypto_cipher_get_ctx_size(uint32_t algo, size_t *size) +{ + return TEE_ERROR_NOT_IMPLEMENTED +} + +TEE_Result crypto_cipher_init(void *ctx __unused, uint32_t algo __unused, + TEE_OperationMode mode __unused, + const uint8_t *key1 __unused, + size_t key1_len __unused, + const uint8_t *key2 __unused, + size_t key2_len __unused, + const uint8_t *iv __unused, + size_t iv_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED +} + +TEE_Result crypto_cipher_update(void *ctx __unused, uint32_t algo __unused, + TEE_OperationMode mode __unused, + bool last_block __unused, + const uint8_t *data __unused, + size_t len __unused, uint8_t *dst __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED +} + +void crypto_cipher_final(void *ctx __unused, uint32_t algo __unused) +{ +} + +TEE_Result crypto_cipher_get_block_size(uint32_t algo __unused, + size_t *size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED +} +#endif /*_CFG_CRYPTO_WITH_CIPHER*/ diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index 81915aa9cd8..3ab704160cd 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,22 +47,6 @@ #include -/* Symmetric ciphers */ -struct cipher_ops { - TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); - TEE_Result (*init)(void *ctx, uint32_t algo, - TEE_OperationMode mode, - const uint8_t *key1, size_t key1_len, - const uint8_t *key2, size_t key2_len, - const uint8_t *iv, size_t iv_len); - TEE_Result (*update)(void *ctx, uint32_t algo, - TEE_OperationMode mode, - bool last_block, const uint8_t *data, - size_t len, uint8_t *dst); - void (*final)(void *ctx, uint32_t algo); - TEE_Result (*get_block_size)(uint32_t algo, size_t *size); -}; - /* Message Authentication Code functions */ struct mac_ops { TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); @@ -275,7 +259,6 @@ struct crypto_ops { const char *name; TEE_Result (*init)(void); - struct cipher_ops cipher; struct mac_ops mac; struct authenc_ops authenc; struct acipher_ops acipher; @@ -293,6 +276,18 @@ TEE_Result crypto_hash_update(void *ctx, uint32_t algo, const uint8_t *data, TEE_Result crypto_hash_final(void *ctx, uint32_t algo, uint8_t *digest, size_t len); +/* Symmetric ciphers */ +TEE_Result crypto_cipher_get_ctx_size(uint32_t algo, size_t *size); +TEE_Result crypto_cipher_init(void *ctx, uint32_t algo, TEE_OperationMode mode, + const uint8_t *key1, size_t key1_len, + const uint8_t *key2, size_t key2_len, + const uint8_t *iv, size_t iv_len); +TEE_Result crypto_cipher_update(void *ctx, uint32_t algo, + TEE_OperationMode mode, bool last_block, + const uint8_t *data, size_t len, uint8_t *dst); +void crypto_cipher_final(void *ctx, uint32_t algo); +TEE_Result crypto_cipher_get_block_size(uint32_t algo, size_t *size); + /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in * advance and has as few dependencies as possible. diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index 5e8ce25568a..a26b8522ec0 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -1922,7 +1922,7 @@ static TEE_Result cipher_get_block_size(uint32_t algo, size_t *size) return TEE_SUCCESS; } -static TEE_Result cipher_get_ctx_size(uint32_t algo, size_t *size) +TEE_Result crypto_cipher_get_ctx_size(uint32_t algo, size_t *size) { switch (algo) { #if defined(CFG_CRYPTO_AES) @@ -1999,7 +1999,7 @@ static void get_des2_key(const uint8_t *key, size_t key_len, } } -static TEE_Result cipher_init(void *ctx, uint32_t algo, +TEE_Result crypto_cipher_init(void *ctx, uint32_t algo, TEE_OperationMode mode __maybe_unused, const uint8_t *key1, size_t key1_len, const uint8_t *key2 __maybe_unused, @@ -2076,16 +2076,14 @@ static TEE_Result cipher_init(void *ctx, uint32_t algo, #if defined(CFG_CRYPTO_CTS) case TEE_ALG_AES_CTS: cts = ctx; - res = cipher_init((void *)(&(cts->ecb)), - TEE_ALG_AES_ECB_NOPAD, mode, key1, - key1_len, key2, key2_len, iv, - iv_len); + res = crypto_cipher_init((void *)(&(cts->ecb)), + TEE_ALG_AES_ECB_NOPAD, mode, key1, + key1_len, key2, key2_len, iv, iv_len); if (res != TEE_SUCCESS) return res; - res = cipher_init((void *)(&(cts->cbc)), - TEE_ALG_AES_CBC_NOPAD, mode, key1, - key1_len, key2, key2_len, iv, - iv_len); + res = crypto_cipher_init((void *)(&(cts->cbc)), + TEE_ALG_AES_CBC_NOPAD, mode, key1, + key1_len, key2, key2_len, iv, iv_len); if (res != TEE_SUCCESS) return res; ltc_res = CRYPT_OK; @@ -2118,7 +2116,7 @@ static TEE_Result cipher_init(void *ctx, uint32_t algo, return TEE_ERROR_BAD_STATE; } -static TEE_Result cipher_update(void *ctx, uint32_t algo, +TEE_Result crypto_cipher_update(void *ctx, uint32_t algo, TEE_OperationMode mode, bool last_block __maybe_unused, const uint8_t *data, size_t len, uint8_t *dst) @@ -2187,7 +2185,7 @@ static TEE_Result cipher_update(void *ctx, uint32_t algo, return TEE_ERROR_BAD_STATE; } -static void cipher_final(void *ctx, uint32_t algo) +void crypto_cipher_final(void *ctx, uint32_t algo) { switch (algo) { #if defined(CFG_CRYPTO_ECB) @@ -2509,7 +2507,7 @@ static TEE_Result mac_final(void *ctx, uint32_t algo, uint8_t *digest, memcpy(digest, cbc->digest, MIN(ltc_digest_len, cbc->block_len)); - cipher_final(&cbc->cbc, algo); + crypto_cipher_final(&cbc->cbc, algo); break; #endif #if defined(CFG_CRYPTO_CMAC) @@ -2980,15 +2978,6 @@ static TEE_Result tee_ltc_init(void) const struct crypto_ops crypto_ops = { .name = "LibTomCrypt provider", .init = tee_ltc_init, -#if defined(_CFG_CRYPTO_WITH_CIPHER) - .cipher = { - .final = cipher_final, - .get_block_size = cipher_get_block_size, - .get_ctx_size = cipher_get_ctx_size, - .init = cipher_init, - .update = cipher_update, - }, -#endif #if defined(_CFG_CRYPTO_WITH_MAC) .mac = { .get_ctx_size = mac_get_ctx_size, diff --git a/core/tee/tee_cryp_utl.c b/core/tee/tee_cryp_utl.c index e40a685086e..9cc736c422c 100644 --- a/core/tee/tee_cryp_utl.c +++ b/core/tee/tee_cryp_utl.c @@ -199,8 +199,6 @@ TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo, if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) return TEE_ERROR_BAD_PARAMETERS; - if (crypto_ops.cipher.update == NULL) - return TEE_ERROR_NOT_IMPLEMENTED; /* * Check that the block contains the correct number of data, apart * for the last block in some XTS / CTR / XTS mode @@ -242,8 +240,8 @@ TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo, } } - return crypto_ops.cipher.update(ctx, algo, mode, last_block, data, len, - dst); + return crypto_cipher_update(ctx, algo, mode, last_block, data, len, + dst); } /* diff --git a/core/tee/tee_fs_key_manager.c b/core/tee/tee_fs_key_manager.c index 4a834a9b69d..9afd186b682 100644 --- a/core/tee/tee_fs_key_manager.c +++ b/core/tee/tee_fs_key_manager.c @@ -136,7 +136,7 @@ TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode, return res; } - res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size); + res = crypto_cipher_get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size); if (res != TEE_SUCCESS) return res; @@ -144,17 +144,17 @@ TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode, if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.cipher.init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk, - sizeof(tsk), NULL, 0, NULL, 0); + res = crypto_cipher_init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk, + sizeof(tsk), NULL, 0, NULL, 0); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.cipher.update(ctx, TEE_FS_KM_ENC_FEK_ALG, - mode, true, in_key, size, dst_key); + res = crypto_cipher_update(ctx, TEE_FS_KM_ENC_FEK_ALG, + mode, true, in_key, size, dst_key); if (res != TEE_SUCCESS) goto exit; - crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG); + crypto_cipher_final(ctx, TEE_FS_KM_ENC_FEK_ALG); memcpy(out_key, dst_key, sizeof(dst_key)); @@ -253,7 +253,7 @@ static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE], size_t ctx_size; uint32_t algo = TEE_ALG_AES_ECB_NOPAD; - res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size); + res = crypto_cipher_get_ctx_size(algo, &ctx_size); if (res != TEE_SUCCESS) return res; @@ -261,17 +261,17 @@ static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE], if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.cipher.init(ctx, algo, TEE_MODE_ENCRYPT, key, - key_size, NULL, 0, NULL, 0); + res = crypto_cipher_init(ctx, algo, TEE_MODE_ENCRYPT, key, + key_size, NULL, 0, NULL, 0); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.cipher.update(ctx, algo, TEE_MODE_ENCRYPT, true, in, - TEE_AES_BLOCK_SIZE, out); + res = crypto_cipher_update(ctx, algo, TEE_MODE_ENCRYPT, true, in, + TEE_AES_BLOCK_SIZE, out); if (res != TEE_SUCCESS) goto out; - crypto_ops.cipher.final(ctx, algo); + crypto_cipher_final(ctx, algo); res = TEE_SUCCESS; out: @@ -325,22 +325,22 @@ TEE_Result tee_fs_crypt_block(const TEE_UUID *uuid, uint8_t *out, res = essiv(iv, fek, blk_idx); /* Run AES CBC */ - res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size); + res = crypto_cipher_get_ctx_size(algo, &ctx_size); if (res != TEE_SUCCESS) return res; ctx = malloc(ctx_size); if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.cipher.init(ctx, algo, mode, fek, sizeof(fek), NULL, - 0, iv, TEE_AES_BLOCK_SIZE); + res = crypto_cipher_init(ctx, algo, mode, fek, sizeof(fek), NULL, + 0, iv, TEE_AES_BLOCK_SIZE); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.cipher.update(ctx, algo, mode, true, in, size, out); + res = crypto_cipher_update(ctx, algo, mode, true, in, size, out); if (res != TEE_SUCCESS) goto exit; - crypto_ops.cipher.final(ctx, algo); + crypto_cipher_final(ctx, algo); exit: free(ctx); diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 814737434e1..570c5ed198a 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -2028,11 +2028,7 @@ TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode, (algo != TEE_ALG_AES_XTS && (key1 == 0 || key2 != 0))) { res = TEE_ERROR_BAD_PARAMETERS; } else { - if (crypto_ops.cipher.get_ctx_size) - res = crypto_ops.cipher.get_ctx_size(algo, - &cs->ctx_size); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_cipher_get_ctx_size(algo, &cs->ctx_size); if (res != TEE_SUCCESS) break; cs->ctx = calloc(1, cs->ctx_size); @@ -2406,33 +2402,25 @@ TEE_Result syscall_cipher_init(unsigned long state, const void *iv, key1 = o->attr; - if (!crypto_ops.cipher.init) - return TEE_ERROR_NOT_IMPLEMENTED; - if (tee_obj_get(utc, cs->key2, &o) == TEE_SUCCESS) { struct tee_cryp_obj_secret *key2 = o->attr; if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) return TEE_ERROR_BAD_PARAMETERS; - res = crypto_ops.cipher.init(cs->ctx, cs->algo, cs->mode, - (uint8_t *)(key1 + 1), - key1->key_size, - (uint8_t *)(key2 + 1), - key2->key_size, - iv, iv_len); + res = crypto_cipher_init(cs->ctx, cs->algo, cs->mode, + (uint8_t *)(key1 + 1), key1->key_size, + (uint8_t *)(key2 + 1), key2->key_size, + iv, iv_len); } else { - res = crypto_ops.cipher.init(cs->ctx, cs->algo, cs->mode, - (uint8_t *)(key1 + 1), - key1->key_size, - NULL, - 0, - iv, iv_len); + res = crypto_cipher_init(cs->ctx, cs->algo, cs->mode, + (uint8_t *)(key1 + 1), key1->key_size, + NULL, 0, iv, iv_len); } if (res != TEE_SUCCESS) return res; - cs->ctx_finalize = crypto_ops.cipher.final; + cs->ctx_finalize = crypto_cipher_final; return TEE_SUCCESS; } From c5f430b27843e19869b4d29f6d3ae90616313052 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 9 Nov 2017 23:20:25 +0100 Subject: [PATCH 04/12] Replace struct mac_ops with function interface Adds mac_cipher_get_ctx_size(), mac_cipher_init(), mac_cipher_update() and mac_cipher_final() replacing struct mac_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/crypto/crypto.c | 28 ++++++++++++ core/include/tee/tee_cryp_provider.h | 21 ++++----- core/lib/libtomcrypt/src/tee_ltc_provider.c | 21 +++------ core/tee/tee_cryp_hkdf.c | 32 +++++-------- core/tee/tee_cryp_pbkdf2.c | 26 +++++------ core/tee/tee_fs_key_manager.c | 10 ++--- core/tee/tee_rpmb_fs.c | 50 ++++++++------------- core/tee/tee_svc_cryp.c | 26 +++-------- 8 files changed, 95 insertions(+), 119 deletions(-) diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index b1a1baf570b..5521f1da646 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -68,3 +68,31 @@ TEE_Result crypto_cipher_get_block_size(uint32_t algo __unused, return TEE_ERROR_NOT_IMPLEMENTED } #endif /*_CFG_CRYPTO_WITH_CIPHER*/ + +#if !defined(_CFG_CRYPTO_WITH_MAC) +TEE_Result crypto_mac_get_ctx_size(uint32_t algo __unused, + size_t *size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_mac_init(void *ctx __unused, uint32_t algo __unused, + const uint8_t *key __unused, size_t len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_mac_update(void *ctx __unused, uint32_t algo __unused, + const uint8_t *data __unused, size_t len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_mac_final(void *ctx __unused, uint32_t algo __unused, + uint8_t *digest __unused, + size_t digest_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*_CFG_CRYPTO_WITH_MAC*/ + diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index 3ab704160cd..ac32d014f23 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,17 +47,6 @@ #include -/* Message Authentication Code functions */ -struct mac_ops { - TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); - TEE_Result (*init)(void *ctx, uint32_t algo, - const uint8_t *key, size_t len); - TEE_Result (*update)(void *ctx, uint32_t algo, - const uint8_t *data, size_t len); - TEE_Result (*final)(void *ctx, uint32_t algo, - uint8_t *digest, size_t digest_len); -}; - /* Authenticated encryption */ struct authenc_ops { TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); @@ -259,7 +248,6 @@ struct crypto_ops { const char *name; TEE_Result (*init)(void); - struct mac_ops mac; struct authenc_ops authenc; struct acipher_ops acipher; struct bignum_ops bignum; @@ -288,6 +276,15 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo, void crypto_cipher_final(void *ctx, uint32_t algo); TEE_Result crypto_cipher_get_block_size(uint32_t algo, size_t *size); +/* Message Authentication Code functions */ +TEE_Result crypto_mac_get_ctx_size(uint32_t algo, size_t *size); +TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key, + size_t len); +TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data, + size_t len); +TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest, + size_t digest_len); + /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in * advance and has as few dependencies as possible. diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index a26b8522ec0..e6f54c9aa46 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -2254,7 +2254,7 @@ struct cbc_state { }; #endif -static TEE_Result mac_get_ctx_size(uint32_t algo, size_t *size) +TEE_Result crypto_mac_get_ctx_size(uint32_t algo, size_t *size) { switch (algo) { #if defined(CFG_CRYPTO_HMAC) @@ -2289,7 +2289,7 @@ static TEE_Result mac_get_ctx_size(uint32_t algo, size_t *size) return TEE_SUCCESS; } -static TEE_Result mac_init(void *ctx, uint32_t algo, const uint8_t *key, +TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key, size_t len) { TEE_Result res; @@ -2373,7 +2373,7 @@ static TEE_Result mac_init(void *ctx, uint32_t algo, const uint8_t *key, return TEE_SUCCESS; } -static TEE_Result mac_update(void *ctx, uint32_t algo, const uint8_t *data, +TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data, size_t len) { #if defined(CFG_CRYPTO_CBC_MAC) @@ -2448,7 +2448,7 @@ static TEE_Result mac_update(void *ctx, uint32_t algo, const uint8_t *data, return TEE_SUCCESS; } -static TEE_Result mac_final(void *ctx, uint32_t algo, uint8_t *digest, +TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest, size_t digest_len) { #if defined(CFG_CRYPTO_CBC_MAC) @@ -2493,8 +2493,9 @@ static TEE_Result mac_final(void *ctx, uint32_t algo, uint8_t *digest, memset(cbc->block+cbc->current_block_len, pad_len, pad_len); cbc->current_block_len = 0; - if (TEE_SUCCESS != mac_update( - ctx, algo, cbc->block, cbc->block_len)) + if (TEE_SUCCESS != crypto_mac_update(ctx, algo, + cbc->block, + cbc->block_len)) return TEE_ERROR_BAD_STATE; break; default: @@ -2978,14 +2979,6 @@ static TEE_Result tee_ltc_init(void) const struct crypto_ops crypto_ops = { .name = "LibTomCrypt provider", .init = tee_ltc_init, -#if defined(_CFG_CRYPTO_WITH_MAC) - .mac = { - .get_ctx_size = mac_get_ctx_size, - .init = mac_init, - .update = mac_update, - .final = mac_final, - }, -#endif #if defined(_CFG_CRYPTO_WITH_AUTHENC) .authenc = { .dec_final = authenc_dec_final, diff --git a/core/tee/tee_cryp_hkdf.c b/core/tee/tee_cryp_hkdf.c index d5287d97689..7c93f70d3b0 100644 --- a/core/tee/tee_cryp_hkdf.c +++ b/core/tee/tee_cryp_hkdf.c @@ -44,12 +44,6 @@ static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm, void *ctx = NULL; uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); uint32_t hmac_algo = (TEE_OPERATION_MAC << 28) | hash_id; - const struct mac_ops *m = &crypto_ops.mac; - - if (!m->get_ctx_size || !m->init || !m->update) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto out; - } if (!salt || !salt_len) { /* @@ -63,7 +57,7 @@ static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm, goto out; } - res = m->get_ctx_size(hmac_algo, &ctx_size); + res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size); if (res != TEE_SUCCESS) goto out; @@ -79,15 +73,15 @@ static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm, * Therefore, salt is the HMAC key in the formula from section 2.2: * "PRK = HMAC-Hash(salt, IKM)" */ - res = m->init(ctx, hmac_algo, salt, salt_len); + res = crypto_mac_init(ctx, hmac_algo, salt, salt_len); if (res != TEE_SUCCESS) goto out; - res = m->update(ctx, hmac_algo, ikm, ikm_len); + res = crypto_mac_update(ctx, hmac_algo, ikm, ikm_len); if (res != TEE_SUCCESS) goto out; - res = m->final(ctx, hmac_algo, prk, *prk_len); + res = crypto_mac_final(ctx, hmac_algo, prk, *prk_len); if (res != TEE_SUCCESS) goto out; @@ -105,15 +99,9 @@ static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk, size_t tn_len, hash_len, i, n, where, ctx_size; TEE_Result res = TEE_SUCCESS; void *ctx = NULL; - const struct mac_ops *m = &crypto_ops.mac; uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); uint32_t hmac_algo = TEE_ALG_HMAC_ALGO(hash_id); - if (!m->get_ctx_size || !m->init || !m->update || !m->final) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto out; - } - res = tee_hash_get_digest_size(hash_algo, &hash_len); if (res != TEE_SUCCESS) goto out; @@ -126,7 +114,7 @@ static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk, if (!info) info_len = 0; - res = m->get_ctx_size(hmac_algo, &ctx_size); + res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size); if (res != TEE_SUCCESS) goto out; @@ -162,19 +150,19 @@ static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk, for (i = 1; i <= n; i++) { uint8_t c = i; - res = m->init(ctx, hmac_algo, prk, prk_len); + res = crypto_mac_init(ctx, hmac_algo, prk, prk_len); if (res != TEE_SUCCESS) goto out; - res = m->update(ctx, hmac_algo, tn, tn_len); + res = crypto_mac_update(ctx, hmac_algo, tn, tn_len); if (res != TEE_SUCCESS) goto out; - res = m->update(ctx, hmac_algo, info, info_len); + res = crypto_mac_update(ctx, hmac_algo, info, info_len); if (res != TEE_SUCCESS) goto out; - res = m->update(ctx, hmac_algo, &c, 1); + res = crypto_mac_update(ctx, hmac_algo, &c, 1); if (res != TEE_SUCCESS) goto out; - res = m->final(ctx, hmac_algo, tn, sizeof(tn)); + res = crypto_mac_final(ctx, hmac_algo, tn, sizeof(tn)); if (res != TEE_SUCCESS) goto out; diff --git a/core/tee/tee_cryp_pbkdf2.c b/core/tee/tee_cryp_pbkdf2.c index 5e6abc1f8cd..d10584a5aa0 100644 --- a/core/tee/tee_cryp_pbkdf2.c +++ b/core/tee/tee_cryp_pbkdf2.c @@ -53,36 +53,37 @@ static TEE_Result pbkdf2_f(uint8_t *out, size_t len, uint32_t idx, uint8_t u[TEE_MAX_HASH_SIZE]; uint32_t be_index; size_t i, j; - const struct mac_ops *mac = &crypto_ops.mac; memset(out, 0, len); for (i = 1; i <= p->iteration_count; i++) { - res = mac->init(h->ctx, h->algo, p->password, p->password_len); + res = crypto_mac_init(h->ctx, h->algo, p->password, + p->password_len); if (res != TEE_SUCCESS) return res; if (i == 1) { if (p->salt && p->salt_len) { - res = mac->update(h->ctx, h->algo, p->salt, - p->salt_len); + res = crypto_mac_update(h->ctx, h->algo, + p->salt, p->salt_len); if (res != TEE_SUCCESS) return res; } be_index = TEE_U32_TO_BIG_ENDIAN(idx); - res = mac->update(h->ctx, h->algo, - (uint8_t *)&be_index, - sizeof(be_index)); + res = crypto_mac_update(h->ctx, h->algo, + (uint8_t *)&be_index, + sizeof(be_index)); if (res != TEE_SUCCESS) return res; } else { - res = mac->update(h->ctx, h->algo, u, h->hash_len); + res = crypto_mac_update(h->ctx, h->algo, u, + h->hash_len); if (res != TEE_SUCCESS) return res; } - res = mac->final(h->ctx, h->algo, u, sizeof(u)); + res = crypto_mac_final(h->ctx, h->algo, u, sizeof(u)); if (res != TEE_SUCCESS) return res; @@ -102,11 +103,6 @@ TEE_Result tee_cryp_pbkdf2(uint32_t hash_id, const uint8_t *password, uint8_t *out = derived_key; struct pbkdf2_parms pbkdf2_parms; struct hmac_parms hmac_parms = {0, }; - const struct mac_ops *mac = &crypto_ops.mac; - - if (!mac->get_ctx_size || !mac->init || !mac->update || - !mac->final) - return TEE_ERROR_NOT_IMPLEMENTED; hmac_parms.algo = TEE_ALG_HMAC_ALGO(hash_id); @@ -114,7 +110,7 @@ TEE_Result tee_cryp_pbkdf2(uint32_t hash_id, const uint8_t *password, if (res != TEE_SUCCESS) return res; - res = mac->get_ctx_size(hmac_parms.algo, &ctx_size); + res = crypto_mac_get_ctx_size(hmac_parms.algo, &ctx_size); if (res != TEE_SUCCESS) return res; diff --git a/core/tee/tee_fs_key_manager.c b/core/tee/tee_fs_key_manager.c index 9afd186b682..6b9148872d0 100644 --- a/core/tee/tee_fs_key_manager.c +++ b/core/tee/tee_fs_key_manager.c @@ -70,7 +70,7 @@ static TEE_Result do_hmac(void *out_key, size_t out_key_size, if (!out_key || !in_key || !message) return TEE_ERROR_BAD_PARAMETERS; - res = crypto_ops.mac.get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size); + res = crypto_mac_get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size); if (res != TEE_SUCCESS) return res; @@ -78,17 +78,15 @@ static TEE_Result do_hmac(void *out_key, size_t out_key_size, if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.mac.init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size); + res = crypto_mac_init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.mac.update(ctx, TEE_FS_KM_HMAC_ALG, - message, message_size); + res = crypto_mac_update(ctx, TEE_FS_KM_HMAC_ALG, message, message_size); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.mac.final(ctx, TEE_FS_KM_HMAC_ALG, out_key, - out_key_size); + res = crypto_mac_final(ctx, TEE_FS_KM_HMAC_ALG, out_key, out_key_size); if (res != TEE_SUCCESS) goto exit; diff --git a/core/tee/tee_rpmb_fs.c b/core/tee/tee_rpmb_fs.c index bde489e4e7a..a63f022c998 100644 --- a/core/tee/tee_rpmb_fs.c +++ b/core/tee/tee_rpmb_fs.c @@ -353,18 +353,18 @@ static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused, memcpy(message, rpmb_ctx->cid, RPMB_EMMC_CID_SIZE); memset(message + RPMB_CID_PRV_OFFSET, 0, 1); memset(message + RPMB_CID_CRC_OFFSET, 0, 1); - res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, hwkey.data, - HW_UNIQUE_KEY_LENGTH); + res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, hwkey.data, + HW_UNIQUE_KEY_LENGTH); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256, + res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, message, RPMB_EMMC_CID_SIZE); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, key, len); + res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, key, len); out: free(ctx); @@ -415,19 +415,19 @@ static TEE_Result tee_rpmb_mac_calc(uint8_t *mac, uint32_t macsize, if (!ctx) return TEE_ERROR_OUT_OF_MEMORY; - res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, key, keysize); + res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, key, keysize); if (res != TEE_SUCCESS) goto func_exit; for (i = 0; i < blkcnt; i++) { - res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256, - datafrms[i].data, - RPMB_MAC_PROTECT_DATA_SIZE); + res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, + datafrms[i].data, + RPMB_MAC_PROTECT_DATA_SIZE); if (res != TEE_SUCCESS) goto func_exit; } - res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, mac, macsize); + res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, mac, macsize); if (res != TEE_SUCCESS) goto func_exit; @@ -741,8 +741,8 @@ static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm, goto func_exit; } - res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, rpmb_ctx->key, - RPMB_KEY_MAC_SIZE); + res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, rpmb_ctx->key, + RPMB_KEY_MAC_SIZE); if (res != TEE_SUCCESS) goto func_exit; @@ -762,9 +762,8 @@ static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm, */ memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE); - res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256, - localfrm.data, - RPMB_MAC_PROTECT_DATA_SIZE); + res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, localfrm.data, + RPMB_MAC_PROTECT_DATA_SIZE); if (res != TEE_SUCCESS) goto func_exit; @@ -796,13 +795,13 @@ static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm, goto func_exit; /* Update MAC against the last block */ - res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256, lastfrm->data, - RPMB_MAC_PROTECT_DATA_SIZE); + res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, lastfrm->data, + RPMB_MAC_PROTECT_DATA_SIZE); if (res != TEE_SUCCESS) goto func_exit; - res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, rawdata->key_mac, - RPMB_KEY_MAC_SIZE); + res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, rawdata->key_mac, + RPMB_KEY_MAC_SIZE); if (res != TEE_SUCCESS) goto func_exit; @@ -1128,22 +1127,12 @@ static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id __unused) } #endif -/* True when all the required crypto functions are available */ -static bool have_crypto_ops(void) -{ - return (crypto_ops.mac.init && crypto_ops.mac.update && - crypto_ops.mac.final); -} - /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */ static TEE_Result tee_rpmb_init(uint16_t dev_id) { TEE_Result res = TEE_SUCCESS; struct rpmb_dev_info dev_info; - if (!have_crypto_ops()) - return TEE_ERROR_NOT_SUPPORTED; - if (!rpmb_ctx) { rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx)); if (!rpmb_ctx) @@ -1178,9 +1167,8 @@ static TEE_Result tee_rpmb_init(uint16_t dev_id) memcpy(rpmb_ctx->cid, dev_info.cid, RPMB_EMMC_CID_SIZE); if ((rpmb_ctx->hash_ctx_size == 0) && - (crypto_ops.mac.get_ctx_size( - TEE_ALG_HMAC_SHA256, - &rpmb_ctx->hash_ctx_size))) { + crypto_mac_get_ctx_size(TEE_ALG_HMAC_SHA256, + &rpmb_ctx->hash_ctx_size)) { rpmb_ctx->hash_ctx_size = 0; res = TEE_ERROR_GENERIC; goto func_exit; diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 570c5ed198a..838315667b7 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -2056,11 +2056,7 @@ TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode, if (key1 == 0 || key2 != 0) { res = TEE_ERROR_BAD_PARAMETERS; } else { - if (crypto_ops.mac.get_ctx_size) - res = crypto_ops.mac.get_ctx_size(algo, - &cs->ctx_size); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_mac_get_ctx_size(algo, &cs->ctx_size); if (res != TEE_SUCCESS) break; cs->ctx = calloc(1, cs->ctx_size); @@ -2205,11 +2201,8 @@ TEE_Result syscall_hash_init(unsigned long state, return TEE_ERROR_BAD_PARAMETERS; key = (struct tee_cryp_obj_secret *)o->attr; - if (!crypto_ops.mac.init) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.mac.init(cs->ctx, cs->algo, - (void *)(key + 1), - key->key_size); + res = crypto_mac_init(cs->ctx, cs->algo, + (void *)(key + 1), key->key_size); if (res != TEE_SUCCESS) return res; break; @@ -2258,10 +2251,7 @@ TEE_Result syscall_hash_update(unsigned long state, const void *chunk, return res; break; case TEE_OPERATION_MAC: - if (!crypto_ops.mac.update) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.mac.update(cs->ctx, cs->algo, chunk, - chunk_size); + res = crypto_mac_update(cs->ctx, cs->algo, chunk, chunk_size); if (res != TEE_SUCCESS) return res; break; @@ -2335,8 +2325,6 @@ TEE_Result syscall_hash_final(unsigned long state, const void *chunk, break; case TEE_OPERATION_MAC: - if (!crypto_ops.mac.update || !crypto_ops.mac.final) - return TEE_ERROR_NOT_IMPLEMENTED; res = tee_mac_get_digest_size(cs->algo, &hash_size); if (res != TEE_SUCCESS) return res; @@ -2346,13 +2334,13 @@ TEE_Result syscall_hash_final(unsigned long state, const void *chunk, } if (chunk_size) { - res = crypto_ops.mac.update(cs->ctx, cs->algo, chunk, - chunk_size); + res = crypto_mac_update(cs->ctx, cs->algo, chunk, + chunk_size); if (res != TEE_SUCCESS) return res; } - res = crypto_ops.mac.final(cs->ctx, cs->algo, hash, hash_size); + res = crypto_mac_final(cs->ctx, cs->algo, hash, hash_size); if (res != TEE_SUCCESS) return res; break; From a0176d8903f636cf686c380fdc6c4758571e61c4 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 10 Nov 2017 07:42:35 +0100 Subject: [PATCH 05/12] Replace struct authenc_ops with function interface Adds crypto_authenc_*() replacing struct authenc_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/crypto/crypto.c | 65 +++++++++++++++++++++ core/include/tee/tee_cryp_provider.h | 59 +++++++++---------- core/lib/libtomcrypt/src/tee_ltc_provider.c | 37 +++++------- core/tee/fs_htree.c | 47 ++++++++------- core/tee/tee_svc_cryp.c | 48 +++++---------- 5 files changed, 144 insertions(+), 112 deletions(-) diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 5521f1da646..a396e8e658b 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -96,3 +96,68 @@ TEE_Result crypto_mac_final(void *ctx __unused, uint32_t algo __unused, } #endif /*_CFG_CRYPTO_WITH_MAC*/ +#if !defined(_CFG_CRYPTO_WITH_AUTHENC) +TEE_Result crypto_authenc_get_ctx_size(uint32_t algo __unused, + size_t *size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_authenc_init(void *ctx __unused, uint32_t algo __unused, + TEE_OperationMode mode __unused, + const uint8_t *key __unused, + size_t key_len __unused, + const uint8_t *nonce __unused, + size_t nonce_len __unused, + size_t tag_len __unused, + size_t aad_len __unused, + size_t payload_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_authenc_update_aad(void *ctx __unused, uint32_t algo __unused, + TEE_OperationMode mode __unused, + const uint8_t *data __unused, + size_t len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_authenc_update_payload(void *ctx __unused, + uint32_t algo __unused, + TEE_OperationMode mode __unused, + const uint8_t *src_data __unused, + size_t src_len __unused, + uint8_t *dst_data __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_authenc_enc_final(void *ctx __unused, uint32_t algo __unused, + const uint8_t *src_data __unused, + size_t src_len __unused, + uint8_t *dst_data __unused, + size_t *dst_len __unused, + uint8_t *dst_tag __unused, + size_t *dst_tag_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_authenc_dec_final(void *ctx __unused, uint32_t algo __unused, + const uint8_t *src_data __unused, + size_t src_len __unused, + uint8_t *dst_data __unused, + size_t *dst_len __unused, + const uint8_t *tag __unused, + size_t tag_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +void crypto_authenc_final(void *ctx __unused, uint32_t algo __unused) +{ +} +#endif /*_CFG_CRYPTO_WITH_AUTHENC*/ diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index ac32d014f23..8e230a58741 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,38 +47,6 @@ #include -/* Authenticated encryption */ -struct authenc_ops { - TEE_Result (*get_ctx_size)(uint32_t algo, size_t *size); - TEE_Result (*init)(void *ctx, uint32_t algo, - TEE_OperationMode mode, - const uint8_t *key, size_t key_len, - const uint8_t *nonce, size_t nonce_len, - size_t tag_len, size_t aad_len, - size_t payload_len); - TEE_Result (*update_aad)(void *ctx, uint32_t algo, - TEE_OperationMode mode, - const uint8_t *data, size_t len); - TEE_Result (*update_payload)(void *ctx, uint32_t algo, - TEE_OperationMode mode, - const uint8_t *src_data, - size_t src_len, - uint8_t *dst_data, - size_t *dst_len); - TEE_Result (*enc_final)(void *ctx, uint32_t algo, - const uint8_t *src_data, - size_t src_len, uint8_t *dst_data, - size_t *dst_len, uint8_t *dst_tag, - size_t *dst_tag_len); - TEE_Result (*dec_final)(void *ctx, uint32_t algo, - const uint8_t *src_data, - size_t src_len, uint8_t *dst_data, - size_t *dst_len, const uint8_t *tag, - size_t tag_len); - - void (*final)(void *ctx, uint32_t algo); -}; - /* Implementation-defined big numbers */ struct bignum_ops { /* @@ -248,7 +216,6 @@ struct crypto_ops { const char *name; TEE_Result (*init)(void); - struct authenc_ops authenc; struct acipher_ops acipher; struct bignum_ops bignum; }; @@ -285,6 +252,32 @@ TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data, TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest, size_t digest_len); +/* Authenticated encryption */ +TEE_Result crypto_authenc_get_ctx_size(uint32_t algo, size_t *size); +TEE_Result crypto_authenc_init(void *ctx, uint32_t algo, TEE_OperationMode mode, + const uint8_t *key, size_t key_len, + const uint8_t *nonce, size_t nonce_len, + size_t tag_len, size_t aad_len, + size_t payload_len); +TEE_Result crypto_authenc_update_aad(void *ctx, uint32_t algo, + TEE_OperationMode mode, + const uint8_t *data, size_t len); +TEE_Result crypto_authenc_update_payload(void *ctx, uint32_t algo, + TEE_OperationMode mode, + const uint8_t *src_data, + size_t src_len, uint8_t *dst_data, + size_t *dst_len); +TEE_Result crypto_authenc_enc_final(void *ctx, uint32_t algo, + const uint8_t *src_data, size_t src_len, + uint8_t *dst_data, size_t *dst_len, + uint8_t *dst_tag, size_t *dst_tag_len); +TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo, + const uint8_t *src_data, size_t src_len, + uint8_t *dst_data, size_t *dst_len, + const uint8_t *tag, size_t tag_len); +void crypto_authenc_final(void *ctx, uint32_t algo); + + /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in * advance and has as few dependencies as possible. diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index e6f54c9aa46..e84cbac63b6 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -2552,7 +2552,7 @@ struct tee_gcm_state { }; #endif -static TEE_Result authenc_get_ctx_size(uint32_t algo, size_t *size) +TEE_Result crypto_authenc_get_ctx_size(uint32_t algo, size_t *size) { switch (algo) { #if defined(CFG_CRYPTO_CCM) @@ -2571,7 +2571,7 @@ static TEE_Result authenc_get_ctx_size(uint32_t algo, size_t *size) return TEE_SUCCESS; } -static TEE_Result authenc_init(void *ctx, uint32_t algo, +TEE_Result crypto_authenc_init(void *ctx, uint32_t algo, TEE_OperationMode mode __unused, const uint8_t *key, size_t key_len, const uint8_t *nonce, size_t nonce_len, @@ -2648,7 +2648,7 @@ static TEE_Result authenc_init(void *ctx, uint32_t algo, return TEE_SUCCESS; } -static TEE_Result authenc_update_aad(void *ctx, uint32_t algo, +TEE_Result crypto_authenc_update_aad(void *ctx, uint32_t algo, TEE_OperationMode mode __unused, const uint8_t *data, size_t len) { @@ -2686,7 +2686,7 @@ static TEE_Result authenc_update_aad(void *ctx, uint32_t algo, return TEE_SUCCESS; } -static TEE_Result authenc_update_payload(void *ctx, uint32_t algo, +TEE_Result crypto_authenc_update_payload(void *ctx, uint32_t algo, TEE_OperationMode mode, const uint8_t *src_data, size_t src_len, @@ -2729,7 +2729,7 @@ static TEE_Result authenc_update_payload(void *ctx, uint32_t algo, /* aad is optional ==> add one without length */ gcm = ctx; if (gcm->ctx.mode == LTC_GCM_MODE_IV) { - res = authenc_update_aad(gcm, algo, mode, 0, 0); + res = crypto_authenc_update_aad(gcm, algo, mode, 0, 0); if (res != TEE_SUCCESS) return res; } @@ -2749,7 +2749,7 @@ static TEE_Result authenc_update_payload(void *ctx, uint32_t algo, return TEE_SUCCESS; } -static TEE_Result authenc_enc_final(void *ctx, uint32_t algo, +TEE_Result crypto_authenc_enc_final(void *ctx, uint32_t algo, const uint8_t *src_data, size_t src_len, uint8_t *dst_data, size_t *dst_len, uint8_t *dst_tag, @@ -2771,8 +2771,9 @@ static TEE_Result authenc_enc_final(void *ctx, uint32_t algo, return res; /* Finalize the remaining buffer */ - res = authenc_update_payload(ctx, algo, TEE_MODE_ENCRYPT, src_data, - src_len, dst_data, dst_len); + res = crypto_authenc_update_payload(ctx, algo, TEE_MODE_ENCRYPT, + src_data, src_len, dst_data, + dst_len); if (res != TEE_SUCCESS) return res; @@ -2818,7 +2819,7 @@ static TEE_Result authenc_enc_final(void *ctx, uint32_t algo, return TEE_SUCCESS; } -static TEE_Result authenc_dec_final(void *ctx, uint32_t algo, +TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo, const uint8_t *src_data, size_t src_len, uint8_t *dst_data, size_t *dst_len, const uint8_t *tag, size_t tag_len) @@ -2840,8 +2841,9 @@ static TEE_Result authenc_dec_final(void *ctx, uint32_t algo, return TEE_ERROR_BAD_STATE; /* Process the last buffer, if any */ - res = authenc_update_payload(ctx, algo, TEE_MODE_DECRYPT, src_data, - src_len, dst_data, dst_len); + res = crypto_authenc_update_payload(ctx, algo, TEE_MODE_DECRYPT, + src_data, src_len, dst_data, + dst_len); if (res != TEE_SUCCESS) return res; @@ -2875,7 +2877,7 @@ static TEE_Result authenc_dec_final(void *ctx, uint32_t algo, return res; } -static void authenc_final(void *ctx, uint32_t algo) +void crypto_authenc_final(void *ctx, uint32_t algo) { #if defined(CFG_CRYPTO_CCM) struct tee_ccm_state *ccm; @@ -2979,17 +2981,6 @@ static TEE_Result tee_ltc_init(void) const struct crypto_ops crypto_ops = { .name = "LibTomCrypt provider", .init = tee_ltc_init, -#if defined(_CFG_CRYPTO_WITH_AUTHENC) - .authenc = { - .dec_final = authenc_dec_final, - .enc_final = authenc_enc_final, - .final = authenc_final, - .get_ctx_size = authenc_get_ctx_size, - .init = authenc_init, - .update_aad = authenc_update_aad, - .update_payload = authenc_update_payload, - }, -#endif #if defined(_CFG_CRYPTO_WITH_ACIPHER) .acipher = { #if defined(CFG_CRYPTO_RSA) diff --git a/core/tee/fs_htree.c b/core/tee/fs_htree.c index e91a8a97154..d9656fbb013 100644 --- a/core/tee/fs_htree.c +++ b/core/tee/fs_htree.c @@ -477,7 +477,7 @@ static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode, return res; } - res = crypto_ops.authenc.get_ctx_size(alg, &ctx_size); + res = crypto_authenc_get_ctx_size(alg, &ctx_size); if (res != TEE_SUCCESS) return res; @@ -487,35 +487,34 @@ static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode, return TEE_ERROR_OUT_OF_MEMORY; } - res = crypto_ops.authenc.init(ctx, alg, mode, - ht->fek, TEE_FS_HTREE_FEK_SIZE, - iv, TEE_FS_HTREE_IV_SIZE, - TEE_FS_HTREE_TAG_SIZE, aad_len, - payload_len); + res = crypto_authenc_init(ctx, alg, mode, ht->fek, + TEE_FS_HTREE_FEK_SIZE, iv, + TEE_FS_HTREE_IV_SIZE, TEE_FS_HTREE_TAG_SIZE, + aad_len, payload_len); if (res != TEE_SUCCESS) goto exit; if (!ni) { - res = crypto_ops.authenc.update_aad(ctx, alg, mode, - ht->root.node.hash, - TEE_FS_HTREE_FEK_SIZE); + res = crypto_authenc_update_aad(ctx, alg, mode, + ht->root.node.hash, + TEE_FS_HTREE_FEK_SIZE); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.authenc.update_aad(ctx, alg, mode, - (void *)&ht->head.counter, - sizeof(ht->head.counter)); + res = crypto_authenc_update_aad(ctx, alg, mode, + (void *)&ht->head.counter, + sizeof(ht->head.counter)); if (res != TEE_SUCCESS) goto exit; } - res = crypto_ops.authenc.update_aad(ctx, alg, mode, ht->head.enc_fek, - TEE_FS_HTREE_FEK_SIZE); + res = crypto_authenc_update_aad(ctx, alg, mode, ht->head.enc_fek, + TEE_FS_HTREE_FEK_SIZE); if (res != TEE_SUCCESS) goto exit; - res = crypto_ops.authenc.update_aad(ctx, alg, mode, iv, - TEE_FS_HTREE_IV_SIZE); + res = crypto_authenc_update_aad(ctx, alg, mode, iv, + TEE_FS_HTREE_IV_SIZE); exit: if (res == TEE_SUCCESS) @@ -533,10 +532,10 @@ static TEE_Result authenc_decrypt_final(void *ctx, const uint8_t *tag, TEE_Result res; size_t out_size = len; - res = crypto_ops.authenc.dec_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, - crypt, len, plain, &out_size, - tag, TEE_FS_HTREE_TAG_SIZE); - crypto_ops.authenc.final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); + res = crypto_authenc_dec_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, crypt, + len, plain, &out_size, tag, + TEE_FS_HTREE_TAG_SIZE); + crypto_authenc_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); free(ctx); if (res == TEE_SUCCESS && out_size != len) @@ -555,10 +554,10 @@ static TEE_Result authenc_encrypt_final(void *ctx, uint8_t *tag, size_t out_size = len; size_t out_tag_size = TEE_FS_HTREE_TAG_SIZE; - res = crypto_ops.authenc.enc_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, - plain, len, crypt, &out_size, - tag, &out_tag_size); - crypto_ops.authenc.final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); + res = crypto_authenc_enc_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, plain, + len, crypt, &out_size, tag, + &out_tag_size); + crypto_authenc_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); free(ctx); if (res == TEE_SUCCESS && diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 838315667b7..d3c0c1a0e88 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -2040,11 +2040,7 @@ TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode, if (key1 == 0 || key2 != 0) { res = TEE_ERROR_BAD_PARAMETERS; } else { - if (crypto_ops.authenc.get_ctx_size) - res = crypto_ops.authenc.get_ctx_size(algo, - &cs->ctx_size); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_authenc_get_ctx_size(algo, &cs->ctx_size); if (res != TEE_SUCCESS) break; cs->ctx = calloc(1, cs->ctx_size); @@ -2935,18 +2931,15 @@ TEE_Result syscall_authenc_init(unsigned long state, const void *nonce, if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) return TEE_ERROR_BAD_PARAMETERS; - if (!crypto_ops.authenc.init) - return TEE_ERROR_NOT_IMPLEMENTED; key = o->attr; - res = crypto_ops.authenc.init(cs->ctx, cs->algo, cs->mode, - (uint8_t *)(key + 1), key->key_size, - nonce, nonce_len, tag_len, aad_len, - payload_len); + res = crypto_authenc_init(cs->ctx, cs->algo, cs->mode, + (uint8_t *)(key + 1), key->key_size, + nonce, nonce_len, tag_len, aad_len, + payload_len); if (res != TEE_SUCCESS) return res; - cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t) - crypto_ops.authenc.final; + cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t)crypto_authenc_final; return TEE_SUCCESS; } @@ -2973,10 +2966,8 @@ TEE_Result syscall_authenc_update_aad(unsigned long state, if (res != TEE_SUCCESS) return res; - if (!crypto_ops.authenc.update_aad) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.authenc.update_aad(cs->ctx, cs->algo, cs->mode, - aad_data, aad_data_len); + res = crypto_authenc_update_aad(cs->ctx, cs->algo, cs->mode, + aad_data, aad_data_len); if (res != TEE_SUCCESS) return res; @@ -3025,12 +3016,10 @@ TEE_Result syscall_authenc_update_payload(unsigned long state, goto out; } - if (!crypto_ops.authenc.update_payload) - return TEE_ERROR_NOT_IMPLEMENTED; tmp_dlen = dlen; - res = crypto_ops.authenc.update_payload(cs->ctx, cs->algo, cs->mode, - src_data, src_len, dst_data, - &tmp_dlen); + res = crypto_authenc_update_payload(cs->ctx, cs->algo, cs->mode, + src_data, src_len, dst_data, + &tmp_dlen); dlen = tmp_dlen; out: @@ -3107,13 +3096,11 @@ TEE_Result syscall_authenc_enc_final(unsigned long state, if (res != TEE_SUCCESS) return res; - if (!crypto_ops.authenc.enc_final) - return TEE_ERROR_NOT_IMPLEMENTED; tmp_dlen = dlen; tmp_tlen = tlen; - res = crypto_ops.authenc.enc_final(cs->ctx, cs->algo, src_data, - src_len, dst_data, &tmp_dlen, tag, - &tmp_tlen); + res = crypto_authenc_enc_final(cs->ctx, cs->algo, src_data, + src_len, dst_data, &tmp_dlen, tag, + &tmp_tlen); dlen = tmp_dlen; tlen = tmp_tlen; @@ -3192,12 +3179,9 @@ TEE_Result syscall_authenc_dec_final(unsigned long state, if (res != TEE_SUCCESS) return res; - if (!crypto_ops.authenc.dec_final) - return TEE_ERROR_NOT_IMPLEMENTED; tmp_dlen = dlen; - res = crypto_ops.authenc.dec_final(cs->ctx, cs->algo, src_data, - src_len, dst_data, &tmp_dlen, tag, - tag_len); + res = crypto_authenc_dec_final(cs->ctx, cs->algo, src_data, src_len, + dst_data, &tmp_dlen, tag, tag_len); dlen = tmp_dlen; out: From c4afa2d5e07560f9c2ba5e2b6453678f9521a18e Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 10 Nov 2017 08:01:50 +0100 Subject: [PATCH 06/12] Replace struct bignum_ops with function interface Adds crypto_bignum_*() replacing struct bignum_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/kernel/ree_fs_ta.c | 9 +- core/crypto/crypto.c | 71 ++++++++++++++++ core/include/tee/tee_cryp_provider.h | 40 +++++---- core/lib/libtomcrypt/src/tee_ltc_provider.c | 93 +++++++++------------ core/tee/tee_svc_cryp.c | 65 ++++++-------- 5 files changed, 162 insertions(+), 116 deletions(-) diff --git a/core/arch/arm/kernel/ree_fs_ta.c b/core/arch/arm/kernel/ree_fs_ta.c index cc5b4b1a37d..bf507752626 100644 --- a/core/arch/arm/kernel/ree_fs_ta.c +++ b/core/arch/arm/kernel/ree_fs_ta.c @@ -100,19 +100,18 @@ static TEE_Result check_shdr(struct shdr *shdr) if (!crypto_ops.acipher.alloc_rsa_public_key || !crypto_ops.acipher.free_rsa_public_key || - !crypto_ops.acipher.rsassa_verify || - !crypto_ops.bignum.bin2bn) + !crypto_ops.acipher.rsassa_verify) return TEE_ERROR_NOT_SUPPORTED; res = crypto_ops.acipher.alloc_rsa_public_key(&key, shdr->sig_size); if (res != TEE_SUCCESS) return res; - res = crypto_ops.bignum.bin2bn((uint8_t *)&e, sizeof(e), key.e); + res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); if (res != TEE_SUCCESS) goto out; - res = crypto_ops.bignum.bin2bn(ta_pub_key_modulus, - ta_pub_key_modulus_size, key.n); + res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size, + key.n); if (res != TEE_SUCCESS) goto out; diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index a396e8e658b..899695e985e 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -6,6 +6,7 @@ */ #include +#include #include #if !defined(_CFG_CRYPTO_WITH_HASH) @@ -161,3 +162,73 @@ void crypto_authenc_final(void *ctx __unused, uint32_t algo __unused) { } #endif /*_CFG_CRYPTO_WITH_AUTHENC*/ + +#if !defined(_CFG_CRYPTO_WITH_ACIPHER) +struct bignum *crypto_bignum_allocate(size_t size_bits __unused) +{ + return NULL; +} + +TEE_Result crypto_bignum_bin2bn(const uint8_t *from __unused, + size_t fromsize __unused, + struct bignum *to __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +size_t crypto_bignum_num_bytes(struct bignum *a __unused) +{ + return 0; +} + +size_t crypto_bignum_num_bits(struct bignum *a __unused) +{ + return 0; +} + +/* + * crypto_bignum_allocate() and crypto_bignum_bin2bn() failing should be + * enough to guarantee that the functions calling this function aren't + * called, but just in case add a panic() here to avoid unexpected + * behavoir. + */ +static void bignum_cant_happen(void) +{ + volatile bool b = true; + + /* Avoid warning about function does not return */ + if (b) + panic(); +} + +void crypto_bignum_bn2bin(const struct bignum *from __unused, + uint8_t *to __unused) +{ + bignum_cant_happen(); +} + +void crypto_bignum_copy(struct bignum *to __unused, + const struct bignum *from __unused) +{ + bignum_cant_happen(); +} + +void crypto_bignum_free(struct bignum *a) +{ + if (a) + panic(); +} + +void crypto_bignum_clear(struct bignum *a __unused) +{ + bignum_cant_happen(); +} + +/* return -1 if ab */ +int32_t crypto_bignum_compare(struct bignum *a __unused, + struct bignum *b __unused) +{ + bignum_cant_happen(); + return -1; +} +#endif /*!_CFG_CRYPTO_WITH_ACIPHER*/ diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index 8e230a58741..afc447734b3 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,26 +47,6 @@ #include -/* Implementation-defined big numbers */ -struct bignum_ops { - /* - * Allocate a bignum capable of holding an unsigned integer value of - * up to bitsize bits - */ - struct bignum *(*allocate)(size_t size_bits); - TEE_Result (*bin2bn)(const uint8_t *from, size_t fromsize, - struct bignum *to); - size_t (*num_bytes)(struct bignum *a); - size_t (*num_bits)(struct bignum *a); - void (*bn2bin)(const struct bignum *from, uint8_t *to); - void (*copy)(struct bignum *to, const struct bignum *from); - void (*free)(struct bignum *a); - void (*clear)(struct bignum *a); - - /* return -1 if ab */ - int32_t (*compare)(struct bignum *a, struct bignum *b); -}; - /* Asymmetric algorithms */ struct rsa_keypair { @@ -217,7 +197,6 @@ struct crypto_ops { TEE_Result (*init)(void); struct acipher_ops acipher; - struct bignum_ops bignum; }; extern const struct crypto_ops crypto_ops; @@ -277,6 +256,25 @@ TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo, const uint8_t *tag, size_t tag_len); void crypto_authenc_final(void *ctx, uint32_t algo); +/* Implementation-defined big numbers */ + +/* + * Allocate a bignum capable of holding an unsigned integer value of + * up to bitsize bits + */ +struct bignum *crypto_bignum_allocate(size_t size_bits); +TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize, + struct bignum *to); +size_t crypto_bignum_num_bytes(struct bignum *a); +size_t crypto_bignum_num_bits(struct bignum *a); +void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to); +void crypto_bignum_copy(struct bignum *to, const struct bignum *from); +void crypto_bignum_free(struct bignum *a); +void crypto_bignum_clear(struct bignum *a); + +/* return -1 if ab */ +int32_t crypto_bignum_compare(struct bignum *a, struct bignum *b); + /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index e84cbac63b6..f0fd0aaac4a 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -639,27 +639,27 @@ static void tee_ltc_alloc_mpa(void) mpa_set_random_generator(crypto_rng_read); } -static size_t num_bytes(struct bignum *a) +size_t crypto_bignum_num_bytes(struct bignum *a) { return mp_unsigned_bin_size(a); } -static size_t num_bits(struct bignum *a) +size_t crypto_bignum_num_bits(struct bignum *a) { return mp_count_bits(a); } -static int32_t compare(struct bignum *a, struct bignum *b) +int32_t crypto_bignum_compare(struct bignum *a, struct bignum *b) { return mp_cmp(a, b); } -static void bn2bin(const struct bignum *from, uint8_t *to) +void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to) { mp_to_unsigned_bin((struct bignum *)from, to); } -static TEE_Result bin2bn(const uint8_t *from, size_t fromsize, +TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize, struct bignum *to) { if (mp_read_unsigned_bin(to, (uint8_t *)from, fromsize) != CRYPT_OK) @@ -667,12 +667,12 @@ static TEE_Result bin2bn(const uint8_t *from, size_t fromsize, return TEE_SUCCESS; } -static void copy(struct bignum *to, const struct bignum *from) +void crypto_bignum_copy(struct bignum *to, const struct bignum *from) { mp_copy((void *)from, to); } -static struct bignum *bn_allocate(size_t size_bits) +struct bignum *crypto_bignum_allocate(size_t size_bits) { size_t sz = mpa_StaticVarSizeInU32(size_bits) * sizeof(uint32_t); struct mpa_numbase_struct *bn = calloc(1, sz); @@ -683,12 +683,12 @@ static struct bignum *bn_allocate(size_t size_bits) return (struct bignum *)bn; } -static void bn_free(struct bignum *s) +void crypto_bignum_free(struct bignum *s) { free(s); } -static void bn_clear(struct bignum *s) +void crypto_bignum_clear(struct bignum *s) { struct mpa_numbase_struct *bn = (struct mpa_numbase_struct *)s; @@ -701,7 +701,7 @@ static bool bn_alloc_max(struct bignum **s) size_t sz = mpa_StaticVarSizeInU32(LTC_MAX_BITS_PER_VARIABLE) * sizeof(uint32_t) * 8; - *s = bn_allocate(sz); + *s = crypto_bignum_allocate(sz); return !!(*s); } @@ -731,13 +731,13 @@ static TEE_Result alloc_rsa_keypair(struct rsa_keypair *s, return TEE_SUCCESS; err: - bn_free(s->e); - bn_free(s->d); - bn_free(s->n); - bn_free(s->p); - bn_free(s->q); - bn_free(s->qp); - bn_free(s->dp); + crypto_bignum_free(s->e); + crypto_bignum_free(s->d); + crypto_bignum_free(s->n); + crypto_bignum_free(s->p); + crypto_bignum_free(s->q); + crypto_bignum_free(s->qp); + crypto_bignum_free(s->dp); return TEE_ERROR_OUT_OF_MEMORY; } @@ -753,7 +753,7 @@ static TEE_Result alloc_rsa_public_key(struct rsa_public_key *s, goto err; return TEE_SUCCESS; err: - bn_free(s->e); + crypto_bignum_free(s->e); return TEE_ERROR_OUT_OF_MEMORY; } @@ -761,8 +761,8 @@ static void free_rsa_public_key(struct rsa_public_key *s) { if (!s) return; - bn_free(s->n); - bn_free(s->e); + crypto_bignum_free(s->n); + crypto_bignum_free(s->e); } static TEE_Result gen_rsa_key(struct rsa_keypair *key, size_t key_size) @@ -892,7 +892,7 @@ static TEE_Result rsanopad_decrypt(struct rsa_keypair *key, ltc_key.e = key->e; ltc_key.N = key->n; ltc_key.d = key->d; - if (key->p && num_bytes(key->p)) { + if (key->p && crypto_bignum_num_bytes(key->p)) { ltc_key.p = key->p; ltc_key.q = key->q; ltc_key.qP = key->qp; @@ -920,7 +920,7 @@ static TEE_Result rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, ltc_key.e = key->e; ltc_key.d = key->d; ltc_key.N = key->n; - if (key->p && num_bytes(key->p)) { + if (key->p && crypto_bignum_num_bytes(key->p)) { ltc_key.p = key->p; ltc_key.q = key->q; ltc_key.qP = key->qp; @@ -1073,7 +1073,7 @@ static TEE_Result rsassa_sign(uint32_t algo, struct rsa_keypair *key, ltc_key.e = key->e; ltc_key.N = key->n; ltc_key.d = key->d; - if (key->p && num_bytes(key->p)) { + if (key->p && crypto_bignum_num_bytes(key->p)) { ltc_key.p = key->p; ltc_key.q = key->q; ltc_key.qP = key->qp; @@ -1235,10 +1235,10 @@ static TEE_Result alloc_dsa_keypair(struct dsa_keypair *s, goto err; return TEE_SUCCESS; err: - bn_free(s->g); - bn_free(s->p); - bn_free(s->q); - bn_free(s->y); + crypto_bignum_free(s->g); + crypto_bignum_free(s->p); + crypto_bignum_free(s->q); + crypto_bignum_free(s->y); return TEE_ERROR_OUT_OF_MEMORY; } @@ -1258,9 +1258,9 @@ static TEE_Result alloc_dsa_public_key(struct dsa_public_key *s, goto err; return TEE_SUCCESS; err: - bn_free(s->g); - bn_free(s->p); - bn_free(s->q); + crypto_bignum_free(s->g); + crypto_bignum_free(s->p); + crypto_bignum_free(s->q); return TEE_ERROR_OUT_OF_MEMORY; } @@ -1438,10 +1438,10 @@ static TEE_Result alloc_dh_keypair(struct dh_keypair *s, goto err; return TEE_SUCCESS; err: - bn_free(s->g); - bn_free(s->p); - bn_free(s->y); - bn_free(s->x); + crypto_bignum_free(s->g); + crypto_bignum_free(s->p); + crypto_bignum_free(s->y); + crypto_bignum_free(s->x); return TEE_ERROR_OUT_OF_MEMORY; } @@ -1504,9 +1504,9 @@ static TEE_Result alloc_ecc_keypair(struct ecc_keypair *s, goto err; return TEE_SUCCESS; err: - bn_free(s->d); - bn_free(s->x); - bn_free(s->y); + crypto_bignum_free(s->d); + crypto_bignum_free(s->x); + crypto_bignum_free(s->y); return TEE_ERROR_OUT_OF_MEMORY; } @@ -1520,8 +1520,8 @@ static TEE_Result alloc_ecc_public_key(struct ecc_public_key *s, goto err; return TEE_SUCCESS; err: - bn_free(s->x); - bn_free(s->y); + crypto_bignum_free(s->x); + crypto_bignum_free(s->y); return TEE_ERROR_OUT_OF_MEMORY; } @@ -1530,8 +1530,8 @@ static void free_ecc_public_key(struct ecc_public_key *s) if (!s) return; - bn_free(s->x); - bn_free(s->y); + crypto_bignum_free(s->x); + crypto_bignum_free(s->y); } /* @@ -3021,17 +3021,6 @@ const struct crypto_ops crypto_ops = { .ecc_shared_secret = do_ecc_shared_secret, #endif }, - .bignum = { - .allocate = bn_allocate, - .num_bytes = num_bytes, - .num_bits = num_bits, - .compare = compare, - .bn2bin = bn2bin, - .bin2bn = bin2bn, - .copy = copy, - .free = bn_free, - .clear = bn_clear - }, #endif /* _CFG_CRYPTO_WITH_ACIPHER */ }; diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index d3c0c1a0e88..6b58b985db8 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -650,9 +650,7 @@ static TEE_Result op_attr_bignum_from_user(void *attr, const void *buffer, { struct bignum **bn = attr; - if (!crypto_ops.bignum.bin2bn) - return TEE_ERROR_NOT_IMPLEMENTED; - return crypto_ops.bignum.bin2bn(buffer, size, *bn); + return crypto_bignum_bin2bn(buffer, size, *bn); } static TEE_Result op_attr_bignum_to_user(void *attr, @@ -668,7 +666,7 @@ static TEE_Result op_attr_bignum_to_user(void *attr, if (res != TEE_SUCCESS) return res; - req_size = crypto_ops.bignum.num_bytes(*bn); + req_size = crypto_bignum_num_bytes(*bn); res = tee_svc_copy_to_user(size, &req_size, sizeof(req_size)); if (res != TEE_SUCCESS) return res; @@ -689,7 +687,7 @@ static TEE_Result op_attr_bignum_to_user(void *attr, * Write the bignum (wich raw data points to) into an array of * bytes (stored in buffer) */ - crypto_ops.bignum.bn2bin(*bn, buffer); + crypto_bignum_bn2bin(*bn, buffer); return TEE_SUCCESS; } @@ -698,7 +696,7 @@ static TEE_Result op_attr_bignum_to_binary(void *attr, void *data, { TEE_Result res; struct bignum **bn = attr; - uint32_t n = crypto_ops.bignum.num_bytes(*bn); + uint32_t n = crypto_bignum_num_bytes(*bn); size_t next_offs; res = op_u32_to_binary_helper(n, data, data_len, offs); @@ -709,7 +707,7 @@ static TEE_Result op_attr_bignum_to_binary(void *attr, void *data, return TEE_ERROR_OVERFLOW; if (data && next_offs <= data_len) - crypto_ops.bignum.bn2bin(*bn, (uint8_t *)data + *offs); + crypto_bignum_bn2bin(*bn, (uint8_t *)data + *offs); (*offs) = next_offs; return TEE_SUCCESS; @@ -726,8 +724,7 @@ static bool op_attr_bignum_from_binary(void *attr, const void *data, if ((*offs + n) > data_len) return false; - if (crypto_ops.bignum.bin2bn((const uint8_t *)data + *offs, - n, *bn) != TEE_SUCCESS) + if (crypto_bignum_bin2bn((const uint8_t *)data + *offs, n, *bn)) return false; (*offs) += n; return true; @@ -738,7 +735,7 @@ static TEE_Result op_attr_bignum_from_obj(void *attr, void *src_attr) struct bignum **bn = attr; struct bignum **src_bn = src_attr; - crypto_ops.bignum.copy(*bn, *src_bn); + crypto_bignum_copy(*bn, *src_bn); return TEE_SUCCESS; } @@ -746,14 +743,14 @@ static void op_attr_bignum_clear(void *attr) { struct bignum **bn = attr; - crypto_ops.bignum.clear(*bn); + crypto_bignum_clear(*bn); } static void op_attr_bignum_free(void *attr) { struct bignum **bn = attr; - crypto_ops.bignum.free(*bn); + crypto_bignum_free(*bn); *bn = NULL; } @@ -1626,7 +1623,7 @@ static TEE_Result tee_svc_obj_generate_key_rsa( struct rsa_keypair *key = o->attr; uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537); - if (!crypto_ops.acipher.gen_rsa_key || !crypto_ops.bignum.bin2bn) + if (!crypto_ops.acipher.gen_rsa_key) return TEE_ERROR_NOT_IMPLEMENTED; /* Copy the present attributes into the obj before starting */ @@ -1635,8 +1632,7 @@ static TEE_Result tee_svc_obj_generate_key_rsa( if (res != TEE_SUCCESS) return res; if (!get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT)) - crypto_ops.bignum.bin2bn((const uint8_t *)&e, sizeof(e), - key->e); + crypto_bignum_bin2bn((const uint8_t *)&e, sizeof(e), key->e); res = crypto_ops.acipher.gen_rsa_key(key, key_size); if (res != TEE_SUCCESS) return res; @@ -2684,12 +2680,7 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, struct bignum *pub; struct bignum *ss; - if (!crypto_ops.bignum.allocate || - !crypto_ops.bignum.free || - !crypto_ops.bignum.bin2bn || - !crypto_ops.bignum.bn2bin || - !crypto_ops.bignum.num_bytes || - !crypto_ops.acipher.dh_shared_secret) { + if (!crypto_ops.acipher.dh_shared_secret) { res = TEE_ERROR_NOT_IMPLEMENTED; goto out; } @@ -2700,17 +2691,16 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, } alloc_size = params[0].content.ref.length * 8; - pub = crypto_ops.bignum.allocate(alloc_size); - ss = crypto_ops.bignum.allocate(alloc_size); + pub = crypto_bignum_allocate(alloc_size); + ss = crypto_bignum_allocate(alloc_size); if (pub && ss) { - crypto_ops.bignum.bin2bn(params[0].content.ref.buffer, - params[0].content.ref.length, pub); + crypto_bignum_bin2bn(params[0].content.ref.buffer, + params[0].content.ref.length, pub); res = crypto_ops.acipher.dh_shared_secret(ko->attr, pub, ss); if (res == TEE_SUCCESS) { - sk->key_size = crypto_ops.bignum.num_bytes(ss); - crypto_ops.bignum.bn2bin(ss, - (uint8_t *)(sk + 1)); + sk->key_size = crypto_bignum_num_bytes(ss); + crypto_bignum_bn2bin(ss, (uint8_t *)(sk + 1)); so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED; set_attribute(so, type_props, @@ -2719,16 +2709,15 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, } else { res = TEE_ERROR_OUT_OF_MEMORY; } - crypto_ops.bignum.free(pub); - crypto_ops.bignum.free(ss); + crypto_bignum_free(pub); + crypto_bignum_free(ss); } else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_ECDH) { size_t alloc_size; struct ecc_public_key key_public; uint8_t *pt_secret; unsigned long pt_secret_len; - if (!crypto_ops.bignum.bin2bn || - !crypto_ops.acipher.alloc_ecc_public_key || + if (!crypto_ops.acipher.alloc_ecc_public_key || !crypto_ops.acipher.free_ecc_public_key || !crypto_ops.acipher.ecc_shared_secret) { res = TEE_ERROR_NOT_IMPLEMENTED; @@ -2768,12 +2757,12 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, if (res != TEE_SUCCESS) goto out; key_public.curve = ((struct ecc_keypair *)ko->attr)->curve; - crypto_ops.bignum.bin2bn(params[0].content.ref.buffer, - params[0].content.ref.length, - key_public.x); - crypto_ops.bignum.bin2bn(params[1].content.ref.buffer, - params[1].content.ref.length, - key_public.y); + crypto_bignum_bin2bn(params[0].content.ref.buffer, + params[0].content.ref.length, + key_public.x); + crypto_bignum_bin2bn(params[1].content.ref.buffer, + params[1].content.ref.length, + key_public.y); pt_secret = (uint8_t *)(sk + 1); pt_secret_len = sk->alloc_size; From c4c2749c16a75f96e65d9f59fa37086ce1e3aac7 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 10 Nov 2017 08:28:31 +0100 Subject: [PATCH 07/12] Replace struct acipher_ops with function interface Adds crypto_acipher_*() replacing struct acipher_ops in crypto_ops. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/kernel/ree_fs_ta.c | 15 +- core/crypto/crypto.c | 206 ++++++++++++++ core/include/tee/tee_cryp_provider.h | 281 ++++++++++---------- core/lib/libtomcrypt/src/tee_ltc_provider.c | 161 +++++------ core/tee/tee_svc_cryp.c | 168 ++++-------- 5 files changed, 458 insertions(+), 373 deletions(-) diff --git a/core/arch/arm/kernel/ree_fs_ta.c b/core/arch/arm/kernel/ree_fs_ta.c index bf507752626..11582995d43 100644 --- a/core/arch/arm/kernel/ree_fs_ta.c +++ b/core/arch/arm/kernel/ree_fs_ta.c @@ -98,12 +98,7 @@ static TEE_Result check_shdr(struct shdr *shdr) if (hash_size != shdr->hash_size) return TEE_ERROR_SECURITY; - if (!crypto_ops.acipher.alloc_rsa_public_key || - !crypto_ops.acipher.free_rsa_public_key || - !crypto_ops.acipher.rsassa_verify) - return TEE_ERROR_NOT_SUPPORTED; - - res = crypto_ops.acipher.alloc_rsa_public_key(&key, shdr->sig_size); + res = crypto_acipher_alloc_rsa_public_key(&key, shdr->sig_size); if (res != TEE_SUCCESS) return res; @@ -115,11 +110,11 @@ static TEE_Result check_shdr(struct shdr *shdr) if (res != TEE_SUCCESS) goto out; - res = crypto_ops.acipher.rsassa_verify(shdr->algo, &key, -1, - SHDR_GET_HASH(shdr), shdr->hash_size, - SHDR_GET_SIG(shdr), shdr->sig_size); + res = crypto_acipher_rsassa_verify(shdr->algo, &key, -1, + SHDR_GET_HASH(shdr), shdr->hash_size, + SHDR_GET_SIG(shdr), shdr->sig_size); out: - crypto_ops.acipher.free_rsa_public_key(&key); + crypto_acipher_free_rsa_public_key(&key); if (res != TEE_SUCCESS) return TEE_ERROR_SECURITY; return TEE_SUCCESS; diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 899695e985e..372c9898041 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -232,3 +232,209 @@ int32_t crypto_bignum_compare(struct bignum *a __unused, return -1; } #endif /*!_CFG_CRYPTO_WITH_ACIPHER*/ + +#if !defined(CFG_CRYPTO_RSA) || !defined(_CFG_CRYPTO_WITH_ACIPHER) +TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result +crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s __unused) +{ +} + +TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key __unused, + size_t key_size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo __unused, + struct rsa_keypair *key __unused, + const uint8_t *label __unused, + size_t label_len __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo __unused, + struct rsa_public_key *key __unused, + const uint8_t *label __unused, + size_t label_len __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsassa_sign(uint32_t algo __unused, + struct rsa_keypair *key __unused, + int salt_len __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_rsassa_verify(uint32_t algo __unused, + struct rsa_public_key *key __unused, + int salt_len __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*!CFG_CRYPTO_RSA || !_CFG_CRYPTO_WITH_ACIPHER*/ + +#if !defined(CFG_CRYPTO_DSA) || !defined(_CFG_CRYPTO_WITH_ACIPHER) +TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result +crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key __unused, + size_t key_size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_dsa_sign(uint32_t algo __unused, + struct dsa_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_dsa_verify(uint32_t algo __unused, + struct dsa_public_key *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*!CFG_CRYPTO_DSA || !_CFG_CRYPTO_WITH_ACIPHER*/ + +#if !defined(CFG_CRYPTO_DH) || !defined(_CFG_CRYPTO_WITH_ACIPHER) +TEE_Result crypto_acipher_alloc_dh_keypair(struct dh_keypair *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key __unused, + struct bignum *q __unused, + size_t xbits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result +crypto_acipher_dh_shared_secret(struct dh_keypair *private_key __unused, + struct bignum *public_key __unused, + struct bignum *secret __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*!CFG_CRYPTO_DH || !_CFG_CRYPTO_WITH_ACIPHER*/ + +#if !defined(CFG_CRYPTO_ECC) || !defined(_CFG_CRYPTO_WITH_ACIPHER) +TEE_Result +crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s __unused) +{ +} + +TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ecc_sign(uint32_t algo __unused, + struct ecc_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ecc_verify(uint32_t algo __unused, + struct ecc_public_key *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result +crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key __unused, + struct ecc_public_key *public_key __unused, + void *secret __unused, + unsigned long *secret_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /*!CFG_CRYPTO_ECC || !_CFG_CRYPTO_WITH_ACIPHER*/ diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index afc447734b3..4226ab00d0f 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -47,148 +47,6 @@ #include -/* Asymmetric algorithms */ - -struct rsa_keypair { - struct bignum *e; /* Public exponent */ - struct bignum *d; /* Private exponent */ - struct bignum *n; /* Modulus */ - - /* Optional CRT parameters (all NULL if unused) */ - struct bignum *p; /* N = pq */ - struct bignum *q; - struct bignum *qp; /* 1/q mod p */ - struct bignum *dp; /* d mod (p-1) */ - struct bignum *dq; /* d mod (q-1) */ -}; - -struct rsa_public_key { - struct bignum *e; /* Public exponent */ - struct bignum *n; /* Modulus */ -}; - -struct dsa_keypair { - struct bignum *g; /* Generator of subgroup (public) */ - struct bignum *p; /* Prime number (public) */ - struct bignum *q; /* Order of subgroup (public) */ - struct bignum *y; /* Public key */ - struct bignum *x; /* Private key */ -}; - -struct dsa_public_key { - struct bignum *g; /* Generator of subgroup (public) */ - struct bignum *p; /* Prime number (public) */ - struct bignum *q; /* Order of subgroup (public) */ - struct bignum *y; /* Public key */ -}; - -struct dh_keypair { - struct bignum *g; /* Generator of Z_p (shared) */ - struct bignum *p; /* Prime modulus (shared) */ - struct bignum *x; /* Private key */ - struct bignum *y; /* Public key y = g^x */ - - /* - * Optional parameters used by key generation. - * When not used, q == NULL and xbits == 0 - */ - struct bignum *q; /* x must be in the range [2, q-2] */ - uint32_t xbits; /* Number of bits in the private key */ -}; - -struct ecc_public_key { - struct bignum *x; /* Public value x */ - struct bignum *y; /* Public value y */ - uint32_t curve; /* Curve type */ -}; - -struct ecc_keypair { - struct bignum *d; /* Private value */ - struct bignum *x; /* Public value x */ - struct bignum *y; /* Public value y */ - uint32_t curve; /* Curve type */ -}; - -struct acipher_ops { - - /* - * Key allocation functions - * Allocate the bignum's inside a key structure. - * TEE core will later use bignum.free(). - */ - TEE_Result (*alloc_rsa_keypair)(struct rsa_keypair *s, - size_t key_size_bits); - TEE_Result (*alloc_rsa_public_key)(struct rsa_public_key *s, - size_t key_size_bits); - void (*free_rsa_public_key)(struct rsa_public_key *s); - TEE_Result (*alloc_dsa_keypair)(struct dsa_keypair *s, - size_t key_size_bits); - TEE_Result (*alloc_dsa_public_key)(struct dsa_public_key *s, - size_t key_size_bits); - TEE_Result (*alloc_dh_keypair)(struct dh_keypair *s, - size_t key_size_bits); - TEE_Result (*alloc_ecc_public_key)(struct ecc_public_key *s, - size_t key_size_bits); - TEE_Result (*alloc_ecc_keypair)(struct ecc_keypair *s, - size_t key_size_bits); - void (*free_ecc_public_key)(struct ecc_public_key *s); - - /* - * Key generation functions - */ - TEE_Result (*gen_rsa_key)(struct rsa_keypair *key, size_t key_size); - TEE_Result (*gen_dsa_key)(struct dsa_keypair *key, size_t key_size); - TEE_Result (*gen_dh_key)(struct dh_keypair *key, struct bignum *q, - size_t xbits); - TEE_Result (*gen_ecc_key)(struct ecc_keypair *key); - - TEE_Result (*dh_shared_secret)(struct dh_keypair *private_key, - struct bignum *public_key, - struct bignum *secret); - - TEE_Result (*rsanopad_decrypt)(struct rsa_keypair *key, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len); - TEE_Result (*rsanopad_encrypt)(struct rsa_public_key *key, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len); - TEE_Result (*rsaes_decrypt)(uint32_t algo, struct rsa_keypair *key, - const uint8_t *label, size_t label_len, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len); - TEE_Result (*rsaes_encrypt)(uint32_t algo, - struct rsa_public_key *key, - const uint8_t *label, size_t label_len, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len); - /* RSA SSA sign/verify: if salt_len == -1, use default value */ - TEE_Result (*rsassa_sign)(uint32_t algo, struct rsa_keypair *key, - int salt_len, const uint8_t *msg, - size_t msg_len, uint8_t *sig, - size_t *sig_len); - TEE_Result (*rsassa_verify)(uint32_t algo, - struct rsa_public_key *key, - int salt_len, const uint8_t *msg, - size_t msg_len, const uint8_t *sig, - size_t sig_len); - TEE_Result (*dsa_sign)(uint32_t algo, struct dsa_keypair *key, - const uint8_t *msg, size_t msg_len, - uint8_t *sig, size_t *sig_len); - TEE_Result (*dsa_verify)(uint32_t algo, struct dsa_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len); - TEE_Result (*ecc_sign)(uint32_t algo, struct ecc_keypair *key, - const uint8_t *msg, size_t msg_len, - uint8_t *sig, size_t *sig_len); - TEE_Result (*ecc_verify)(uint32_t algo, struct ecc_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len); - TEE_Result (*ecc_shared_secret)(struct ecc_keypair *private_key, - struct ecc_public_key *public_key, - void *secret, - unsigned long *secret_len); - -}; /* Cryptographic Provider API */ struct crypto_ops { @@ -196,7 +54,6 @@ struct crypto_ops { const char *name; TEE_Result (*init)(void); - struct acipher_ops acipher; }; extern const struct crypto_ops crypto_ops; @@ -275,6 +132,144 @@ void crypto_bignum_clear(struct bignum *a); /* return -1 if ab */ int32_t crypto_bignum_compare(struct bignum *a, struct bignum *b); +/* Asymmetric algorithms */ + +struct rsa_keypair { + struct bignum *e; /* Public exponent */ + struct bignum *d; /* Private exponent */ + struct bignum *n; /* Modulus */ + + /* Optional CRT parameters (all NULL if unused) */ + struct bignum *p; /* N = pq */ + struct bignum *q; + struct bignum *qp; /* 1/q mod p */ + struct bignum *dp; /* d mod (p-1) */ + struct bignum *dq; /* d mod (q-1) */ +}; + +struct rsa_public_key { + struct bignum *e; /* Public exponent */ + struct bignum *n; /* Modulus */ +}; + +struct dsa_keypair { + struct bignum *g; /* Generator of subgroup (public) */ + struct bignum *p; /* Prime number (public) */ + struct bignum *q; /* Order of subgroup (public) */ + struct bignum *y; /* Public key */ + struct bignum *x; /* Private key */ +}; + +struct dsa_public_key { + struct bignum *g; /* Generator of subgroup (public) */ + struct bignum *p; /* Prime number (public) */ + struct bignum *q; /* Order of subgroup (public) */ + struct bignum *y; /* Public key */ +}; + +struct dh_keypair { + struct bignum *g; /* Generator of Z_p (shared) */ + struct bignum *p; /* Prime modulus (shared) */ + struct bignum *x; /* Private key */ + struct bignum *y; /* Public key y = g^x */ + + /* + * Optional parameters used by key generation. + * When not used, q == NULL and xbits == 0 + */ + struct bignum *q; /* x must be in the range [2, q-2] */ + uint32_t xbits; /* Number of bits in the private key */ +}; + +struct ecc_public_key { + struct bignum *x; /* Public value x */ + struct bignum *y; /* Public value y */ + uint32_t curve; /* Curve type */ +}; + +struct ecc_keypair { + struct bignum *d; /* Private value */ + struct bignum *x; /* Public value x */ + struct bignum *y; /* Public value y */ + uint32_t curve; /* Curve type */ +}; + +/* + * Key allocation functions + * Allocate the bignum's inside a key structure. + * TEE core will later use crypto_bignum_free(). + */ +TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s, + size_t key_size_bits); +TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s, + size_t key_size_bits); +void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s); +TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s, + size_t key_size_bits); +TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s, + size_t key_size_bits); +TEE_Result crypto_acipher_alloc_dh_keypair(struct dh_keypair *s, + size_t key_size_bits); +TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s, + size_t key_size_bits); +TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, + size_t key_size_bits); +void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s); + +/* + * Key generation functions + */ +TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, size_t key_size); +TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size); +TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, struct bignum *q, + size_t xbits); +TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key); + +TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, + struct bignum *public_key, + struct bignum *secret); + +TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); +TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); +TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, + const uint8_t *label, size_t label_len, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); +TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo, + struct rsa_public_key *key, + const uint8_t *label, size_t label_len, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); +/* RSA SSA sign/verify: if salt_len == -1, use default value */ +TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, + int salt_len, const uint8_t *msg, + size_t msg_len, uint8_t *sig, + size_t *sig_len); +TEE_Result crypto_acipher_rsassa_verify(uint32_t algo, + struct rsa_public_key *key, + int salt_len, const uint8_t *msg, + size_t msg_len, const uint8_t *sig, + size_t sig_len); +TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); +TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len); +TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); +TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len); +TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, + struct ecc_public_key *public_key, + void *secret, + unsigned long *secret_len); /* * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index f0fd0aaac4a..d3f3bb8b095 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -707,8 +707,8 @@ static bool bn_alloc_max(struct bignum **s) #if defined(CFG_CRYPTO_RSA) -static TEE_Result alloc_rsa_keypair(struct rsa_keypair *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->e)) { @@ -742,8 +742,8 @@ static TEE_Result alloc_rsa_keypair(struct rsa_keypair *s, return TEE_ERROR_OUT_OF_MEMORY; } -static TEE_Result alloc_rsa_public_key(struct rsa_public_key *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->e)) { @@ -757,7 +757,7 @@ static TEE_Result alloc_rsa_public_key(struct rsa_public_key *s, return TEE_ERROR_OUT_OF_MEMORY; } -static void free_rsa_public_key(struct rsa_public_key *s) +void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s) { if (!s) return; @@ -765,7 +765,7 @@ static void free_rsa_public_key(struct rsa_public_key *s) crypto_bignum_free(s->e); } -static TEE_Result gen_rsa_key(struct rsa_keypair *key, size_t key_size) +TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, size_t key_size) { TEE_Result res; rsa_key ltc_tmp_key; @@ -803,7 +803,6 @@ static TEE_Result gen_rsa_key(struct rsa_keypair *key, size_t key_size) return res; } - static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src, size_t src_len, uint8_t *dst, size_t *dst_len) { @@ -866,9 +865,9 @@ static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src, return res; } -static TEE_Result rsanopad_encrypt(struct rsa_public_key *key, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len) +TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len) { TEE_Result res; rsa_key ltc_key = { 0, }; @@ -881,9 +880,9 @@ static TEE_Result rsanopad_encrypt(struct rsa_public_key *key, return res; } -static TEE_Result rsanopad_decrypt(struct rsa_keypair *key, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len) +TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len) { TEE_Result res; rsa_key ltc_key = { 0, }; @@ -904,10 +903,10 @@ static TEE_Result rsanopad_decrypt(struct rsa_keypair *key, return res; } -static TEE_Result rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, - const uint8_t *label, size_t label_len, - const uint8_t *src, size_t src_len, - uint8_t *dst, size_t *dst_len) +TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, + const uint8_t *label, size_t label_len, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len) { TEE_Result res = TEE_SUCCESS; void *buf = NULL; @@ -1000,7 +999,8 @@ static TEE_Result rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, return res; } -static TEE_Result rsaes_encrypt(uint32_t algo, struct rsa_public_key *key, +TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo, + struct rsa_public_key *key, const uint8_t *label, size_t label_len, const uint8_t *src, size_t src_len, uint8_t *dst, size_t *dst_len) @@ -1057,10 +1057,10 @@ static TEE_Result rsaes_encrypt(uint32_t algo, struct rsa_public_key *key, return res; } -static TEE_Result rsassa_sign(uint32_t algo, struct rsa_keypair *key, - int salt_len, const uint8_t *msg, - size_t msg_len, uint8_t *sig, - size_t *sig_len) +TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key, + int salt_len, const uint8_t *msg, + size_t msg_len, uint8_t *sig, + size_t *sig_len) { TEE_Result res; size_t hash_size, mod_size; @@ -1144,10 +1144,11 @@ static TEE_Result rsassa_sign(uint32_t algo, struct rsa_keypair *key, return res; } -static TEE_Result rsassa_verify(uint32_t algo, struct rsa_public_key *key, - int salt_len, const uint8_t *msg, - size_t msg_len, const uint8_t *sig, - size_t sig_len) +TEE_Result crypto_acipher_rsassa_verify(uint32_t algo, + struct rsa_public_key *key, + int salt_len, const uint8_t *msg, + size_t msg_len, const uint8_t *sig, + size_t sig_len) { TEE_Result res; uint32_t bigint_size; @@ -1217,8 +1218,8 @@ static TEE_Result rsassa_verify(uint32_t algo, struct rsa_public_key *key, #if defined(CFG_CRYPTO_DSA) -static TEE_Result alloc_dsa_keypair(struct dsa_keypair *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->g)) { @@ -1242,8 +1243,8 @@ static TEE_Result alloc_dsa_keypair(struct dsa_keypair *s, return TEE_ERROR_OUT_OF_MEMORY; } -static TEE_Result alloc_dsa_public_key(struct dsa_public_key *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->g)) { @@ -1264,7 +1265,7 @@ static TEE_Result alloc_dsa_public_key(struct dsa_public_key *s, return TEE_ERROR_OUT_OF_MEMORY; } -static TEE_Result gen_dsa_key(struct dsa_keypair *key, size_t key_size) +TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size) { TEE_Result res; dsa_key ltc_tmp_key; @@ -1304,9 +1305,9 @@ static TEE_Result gen_dsa_key(struct dsa_keypair *key, size_t key_size) return res; } -static TEE_Result dsa_sign(uint32_t algo, struct dsa_keypair *key, - const uint8_t *msg, size_t msg_len, uint8_t *sig, - size_t *sig_len) +TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) { TEE_Result res; size_t hash_size; @@ -1374,9 +1375,9 @@ static TEE_Result dsa_sign(uint32_t algo, struct dsa_keypair *key, return res; } -static TEE_Result dsa_verify(uint32_t algo, struct dsa_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len) +TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) { TEE_Result res; int ltc_stat, ltc_res; @@ -1420,8 +1421,8 @@ static TEE_Result dsa_verify(uint32_t algo, struct dsa_public_key *key, #if defined(CFG_CRYPTO_DH) -static TEE_Result alloc_dh_keypair(struct dh_keypair *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_dh_keypair(struct dh_keypair *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->g)) { @@ -1445,8 +1446,8 @@ static TEE_Result alloc_dh_keypair(struct dh_keypair *s, return TEE_ERROR_OUT_OF_MEMORY; } -static TEE_Result gen_dh_key(struct dh_keypair *key, struct bignum *q, - size_t xbits) +TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, struct bignum *q, + size_t xbits) { TEE_Result res; dh_key ltc_tmp_key; @@ -1471,9 +1472,9 @@ static TEE_Result gen_dh_key(struct dh_keypair *key, struct bignum *q, return res; } -static TEE_Result do_dh_shared_secret(struct dh_keypair *private_key, - struct bignum *public_key, - struct bignum *secret) +TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, + struct bignum *public_key, + struct bignum *secret) { int err; dh_key pk = { @@ -1492,8 +1493,8 @@ static TEE_Result do_dh_shared_secret(struct dh_keypair *private_key, #if defined(CFG_CRYPTO_ECC) -static TEE_Result alloc_ecc_keypair(struct ecc_keypair *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->d)) @@ -1510,8 +1511,8 @@ static TEE_Result alloc_ecc_keypair(struct ecc_keypair *s, return TEE_ERROR_OUT_OF_MEMORY; } -static TEE_Result alloc_ecc_public_key(struct ecc_public_key *s, - size_t key_size_bits __unused) +TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s, + size_t key_size_bits __unused) { memset(s, 0, sizeof(*s)); if (!bn_alloc_max(&s->x)) @@ -1525,7 +1526,7 @@ static TEE_Result alloc_ecc_public_key(struct ecc_public_key *s, return TEE_ERROR_OUT_OF_MEMORY; } -static void free_ecc_public_key(struct ecc_public_key *s) +void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s) { if (!s) return; @@ -1604,7 +1605,7 @@ static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo, return TEE_SUCCESS; } -static TEE_Result gen_ecc_key(struct ecc_keypair *key) +TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key) { TEE_Result res; ecc_key ltc_tmp_key; @@ -1726,9 +1727,9 @@ static TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, return ecc_compute_key_idx(ltc_key, *key_size_bytes); } -static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key, - const uint8_t *msg, size_t msg_len, uint8_t *sig, - size_t *sig_len) +TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) { TEE_Result res; int ltc_res; @@ -1780,9 +1781,9 @@ static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key, return res; } -static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len) +TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) { TEE_Result res; int ltc_stat; @@ -1827,9 +1828,10 @@ static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key, return res; } -static TEE_Result do_ecc_shared_secret(struct ecc_keypair *private_key, - struct ecc_public_key *public_key, - void *secret, unsigned long *secret_len) +TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, + struct ecc_public_key *public_key, + void *secret, + unsigned long *secret_len) { TEE_Result res; int ltc_res; @@ -2981,47 +2983,6 @@ static TEE_Result tee_ltc_init(void) const struct crypto_ops crypto_ops = { .name = "LibTomCrypt provider", .init = tee_ltc_init, -#if defined(_CFG_CRYPTO_WITH_ACIPHER) - .acipher = { -#if defined(CFG_CRYPTO_RSA) - .alloc_rsa_keypair = alloc_rsa_keypair, - .alloc_rsa_public_key = alloc_rsa_public_key, - .free_rsa_public_key = free_rsa_public_key, - .gen_rsa_key = gen_rsa_key, - .rsaes_decrypt = rsaes_decrypt, - .rsaes_encrypt = rsaes_encrypt, - .rsanopad_decrypt = rsanopad_decrypt, - .rsanopad_encrypt = rsanopad_encrypt, - .rsassa_sign = rsassa_sign, - .rsassa_verify = rsassa_verify, -#endif -#if defined(CFG_CRYPTO_DH) - .alloc_dh_keypair = alloc_dh_keypair, - .gen_dh_key = gen_dh_key, - .dh_shared_secret = do_dh_shared_secret, -#endif -#if defined(CFG_CRYPTO_DSA) - .alloc_dsa_keypair = alloc_dsa_keypair, - .alloc_dsa_public_key = alloc_dsa_public_key, - .gen_dsa_key = gen_dsa_key, - .dsa_sign = dsa_sign, - .dsa_verify = dsa_verify, -#endif -#if defined(CFG_CRYPTO_ECC) - /* ECDSA and ECDH */ - .alloc_ecc_keypair = alloc_ecc_keypair, - .alloc_ecc_public_key = alloc_ecc_public_key, - .gen_ecc_key = gen_ecc_key, - .free_ecc_public_key = free_ecc_public_key, - - /* ECDSA only */ - .ecc_sign = ecc_sign, - .ecc_verify = ecc_verify, - /* ECDH only */ - .ecc_shared_secret = do_ecc_shared_secret, -#endif - }, -#endif /* _CFG_CRYPTO_WITH_ACIPHER */ }; #if defined(CFG_WITH_VFP) diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 6b58b985db8..8351150e916 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -1197,48 +1197,30 @@ TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type, /* If we have a key structure, pre-allocate the bignums inside */ switch (obj_type) { case TEE_TYPE_RSA_PUBLIC_KEY: - if (!crypto_ops.acipher.alloc_rsa_public_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_rsa_public_key(o->attr, - max_key_size); + res = crypto_acipher_alloc_rsa_public_key(o->attr, + max_key_size); break; case TEE_TYPE_RSA_KEYPAIR: - if (!crypto_ops.acipher.alloc_rsa_keypair) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_rsa_keypair(o->attr, - max_key_size); + res = crypto_acipher_alloc_rsa_keypair(o->attr, max_key_size); break; case TEE_TYPE_DSA_PUBLIC_KEY: - if (!crypto_ops.acipher.alloc_dsa_public_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_dsa_public_key(o->attr, - max_key_size); + res = crypto_acipher_alloc_dsa_public_key(o->attr, + max_key_size); break; case TEE_TYPE_DSA_KEYPAIR: - if (!crypto_ops.acipher.alloc_dsa_keypair) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_dsa_keypair(o->attr, - max_key_size); + res = crypto_acipher_alloc_dsa_keypair(o->attr, max_key_size); break; case TEE_TYPE_DH_KEYPAIR: - if (!crypto_ops.acipher.alloc_dh_keypair) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_dh_keypair(o->attr, - max_key_size); + res = crypto_acipher_alloc_dh_keypair(o->attr, max_key_size); break; case TEE_TYPE_ECDSA_PUBLIC_KEY: case TEE_TYPE_ECDH_PUBLIC_KEY: - if (!crypto_ops.acipher.alloc_ecc_public_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_ecc_public_key(o->attr, - max_key_size); + res = crypto_acipher_alloc_ecc_public_key(o->attr, + max_key_size); break; case TEE_TYPE_ECDSA_KEYPAIR: case TEE_TYPE_ECDH_KEYPAIR: - if (!crypto_ops.acipher.alloc_ecc_keypair) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.alloc_ecc_keypair(o->attr, - max_key_size); + res = crypto_acipher_alloc_ecc_keypair(o->attr, max_key_size); break; default: if (obj_type != TEE_TYPE_DATA) { @@ -1623,9 +1605,6 @@ static TEE_Result tee_svc_obj_generate_key_rsa( struct rsa_keypair *key = o->attr; uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537); - if (!crypto_ops.acipher.gen_rsa_key) - return TEE_ERROR_NOT_IMPLEMENTED; - /* Copy the present attributes into the obj before starting */ res = tee_svc_cryp_obj_populate_type(o, type_props, params, param_count); @@ -1633,7 +1612,7 @@ static TEE_Result tee_svc_obj_generate_key_rsa( return res; if (!get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT)) crypto_bignum_bin2bn((const uint8_t *)&e, sizeof(e), key->e); - res = crypto_ops.acipher.gen_rsa_key(key, key_size); + res = crypto_acipher_gen_rsa_key(key, key_size); if (res != TEE_SUCCESS) return res; @@ -1649,9 +1628,7 @@ static TEE_Result tee_svc_obj_generate_key_dsa( { TEE_Result res; - if (!crypto_ops.acipher.gen_dsa_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.gen_dsa_key(o->attr, key_size); + res = crypto_acipher_gen_dsa_key(o->attr, key_size); if (res != TEE_SUCCESS) return res; @@ -1683,9 +1660,7 @@ static TEE_Result tee_svc_obj_generate_key_dh( dh_q = tee_dh_key->q; if (get_attribute(o, type_props, TEE_ATTR_DH_X_BITS)) dh_xbits = tee_dh_key->xbits; - if (!crypto_ops.acipher.gen_dh_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.gen_dh_key(tee_dh_key, dh_q, dh_xbits); + res = crypto_acipher_gen_dh_key(tee_dh_key, dh_q, dh_xbits); if (res != TEE_SUCCESS) return res; @@ -1712,9 +1687,7 @@ static TEE_Result tee_svc_obj_generate_key_ecc( tee_ecc_key = (struct ecc_keypair *)o->attr; - if (!crypto_ops.acipher.gen_ecc_key) - return TEE_ERROR_NOT_IMPLEMENTED; - res = crypto_ops.acipher.gen_ecc_key(tee_ecc_key); + res = crypto_acipher_gen_ecc_key(tee_ecc_key); if (res != TEE_SUCCESS) return res; @@ -2680,10 +2653,6 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, struct bignum *pub; struct bignum *ss; - if (!crypto_ops.acipher.dh_shared_secret) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto out; - } if (param_count != 1 || params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE) { res = TEE_ERROR_BAD_PARAMETERS; @@ -2696,8 +2665,8 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, if (pub && ss) { crypto_bignum_bin2bn(params[0].content.ref.buffer, params[0].content.ref.length, pub); - res = crypto_ops.acipher.dh_shared_secret(ko->attr, - pub, ss); + res = crypto_acipher_dh_shared_secret(ko->attr, + pub, ss); if (res == TEE_SUCCESS) { sk->key_size = crypto_bignum_num_bytes(ss); crypto_bignum_bn2bin(ss, (uint8_t *)(sk + 1)); @@ -2717,12 +2686,6 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, uint8_t *pt_secret; unsigned long pt_secret_len; - if (!crypto_ops.acipher.alloc_ecc_public_key || - !crypto_ops.acipher.free_ecc_public_key || - !crypto_ops.acipher.ecc_shared_secret) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto out; - } if (param_count != 2 || params[0].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_X || params[1].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_Y) { @@ -2752,8 +2715,8 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, } /* Create the public key */ - res = crypto_ops.acipher.alloc_ecc_public_key(&key_public, - alloc_size); + res = crypto_acipher_alloc_ecc_public_key(&key_public, + alloc_size); if (res != TEE_SUCCESS) goto out; key_public.curve = ((struct ecc_keypair *)ko->attr)->curve; @@ -2766,8 +2729,9 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, pt_secret = (uint8_t *)(sk + 1); pt_secret_len = sk->alloc_size; - res = crypto_ops.acipher.ecc_shared_secret(ko->attr, - &key_public, pt_secret, &pt_secret_len); + res = crypto_acipher_ecc_shared_secret(ko->attr, &key_public, + pt_secret, + &pt_secret_len); if (res == TEE_SUCCESS) { sk->key_size = pt_secret_len; @@ -2776,7 +2740,7 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, } /* free the public key */ - crypto_ops.acipher.free_ecc_public_key(&key_public); + crypto_acipher_free_ecc_public_key(&key_public); } #if defined(CFG_CRYPTO_HKDF) else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_HKDF) { @@ -3272,19 +3236,13 @@ TEE_Result syscall_asymm_operate(unsigned long state, switch (cs->algo) { case TEE_ALG_RSA_NOPAD: if (cs->mode == TEE_MODE_ENCRYPT) { - if (crypto_ops.acipher.rsanopad_encrypt) - res = crypto_ops.acipher.rsanopad_encrypt( - o->attr, src_data, src_len, - dst_data, &dlen); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_acipher_rsanopad_encrypt(o->attr, src_data, + src_len, dst_data, + &dlen); } else if (cs->mode == TEE_MODE_DECRYPT) { - if (crypto_ops.acipher.rsanopad_decrypt) - res = crypto_ops.acipher.rsanopad_decrypt( - o->attr, src_data, src_len, dst_data, - &dlen); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_acipher_rsanopad_decrypt(o->attr, src_data, + src_len, dst_data, + &dlen); } else { /* * We will panic because "the mode is not compatible @@ -3309,20 +3267,14 @@ TEE_Result syscall_asymm_operate(unsigned long state, } if (cs->mode == TEE_MODE_ENCRYPT) { - if (crypto_ops.acipher.rsaes_encrypt) - res = crypto_ops.acipher.rsaes_encrypt( - cs->algo, o->attr, label, label_len, - src_data, src_len, dst_data, &dlen); - else - res = TEE_ERROR_NOT_IMPLEMENTED; + res = crypto_acipher_rsaes_encrypt(cs->algo, o->attr, + label, label_len, + src_data, src_len, + dst_data, &dlen); } else if (cs->mode == TEE_MODE_DECRYPT) { - if (crypto_ops.acipher.rsaes_decrypt) - res = crypto_ops.acipher.rsaes_decrypt( - cs->algo, o->attr, - label, label_len, + res = crypto_acipher_rsaes_decrypt( + cs->algo, o->attr, label, label_len, src_data, src_len, dst_data, &dlen); - else - res = TEE_ERROR_NOT_IMPLEMENTED; } else { res = TEE_ERROR_BAD_PARAMETERS; } @@ -3344,36 +3296,24 @@ TEE_Result syscall_asymm_operate(unsigned long state, break; } salt_len = pkcs1_get_salt_len(params, num_params, src_len); - if (!crypto_ops.acipher.rsassa_sign) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.rsassa_sign(cs->algo, o->attr, - salt_len, src_data, - src_len, dst_data, &dlen); + res = crypto_acipher_rsassa_sign(cs->algo, o->attr, salt_len, + src_data, src_len, dst_data, + &dlen); break; case TEE_ALG_DSA_SHA1: case TEE_ALG_DSA_SHA224: case TEE_ALG_DSA_SHA256: - if (!crypto_ops.acipher.dsa_sign) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.dsa_sign(cs->algo, o->attr, src_data, - src_len, dst_data, &dlen); + res = crypto_acipher_dsa_sign(cs->algo, o->attr, src_data, + src_len, dst_data, &dlen); break; case TEE_ALG_ECDSA_P192: case TEE_ALG_ECDSA_P224: case TEE_ALG_ECDSA_P256: case TEE_ALG_ECDSA_P384: case TEE_ALG_ECDSA_P521: - if (!crypto_ops.acipher.ecc_sign) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.ecc_sign(cs->algo, o->attr, src_data, - src_len, dst_data, &dlen); + res = crypto_acipher_ecc_sign(cs->algo, o->attr, src_data, + src_len, dst_data, &dlen); break; default: @@ -3463,13 +3403,9 @@ TEE_Result syscall_asymm_verify(unsigned long state, break; } salt_len = pkcs1_get_salt_len(params, num_params, hash_size); - if (!crypto_ops.acipher.rsassa_verify) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.rsassa_verify(cs->algo, o->attr, - salt_len, data, - data_len, sig, sig_len); + res = crypto_acipher_rsassa_verify(cs->algo, o->attr, salt_len, + data, data_len, sig, + sig_len); break; case TEE_MAIN_ALGO_DSA: @@ -3487,21 +3423,13 @@ TEE_Result syscall_asymm_verify(unsigned long state, res = TEE_ERROR_BAD_PARAMETERS; break; } - if (!crypto_ops.acipher.dsa_verify) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.dsa_verify(cs->algo, o->attr, data, - data_len, sig, sig_len); + res = crypto_acipher_dsa_verify(cs->algo, o->attr, data, + data_len, sig, sig_len); break; case TEE_MAIN_ALGO_ECDSA: - if (!crypto_ops.acipher.ecc_verify) { - res = TEE_ERROR_NOT_IMPLEMENTED; - break; - } - res = crypto_ops.acipher.ecc_verify(cs->algo, o->attr, data, - data_len, sig, sig_len); + res = crypto_acipher_ecc_verify(cs->algo, o->attr, data, + data_len, sig, sig_len); break; default: From cbccb6062a81fb6444d0b6e4f363a39fa09ad559 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 10 Nov 2017 08:38:05 +0100 Subject: [PATCH 08/12] core: remove struct crypto_ops Removes struct crypto_ops and adds crypto_init() Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/include/tee/tee_cryp_provider.h | 13 ++----------- core/lib/libtomcrypt/src/tee_ltc_provider.c | 7 +------ core/tee/tee_cryp_utl.c | 5 +---- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/tee/tee_cryp_provider.h index 4226ab00d0f..555fe05b400 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/tee/tee_cryp_provider.h @@ -48,16 +48,7 @@ #include -/* Cryptographic Provider API */ -struct crypto_ops { - /* Human-readable provider name */ - const char *name; - - TEE_Result (*init)(void); -}; - -extern const struct crypto_ops crypto_ops; - +TEE_Result crypto_init(void); /* Message digest functions */ TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size); @@ -272,7 +263,7 @@ TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, unsigned long *secret_len); /* - * Verifies a SHA-256 hash, doesn't require tee_cryp_init() to be called in + * Verifies a SHA-256 hash, doesn't require crypto_init() to be called in * advance and has as few dependencies as possible. * * This function is primarily used by pager and early initialization code diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index d3f3bb8b095..e7bfe8f09ae 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -2970,7 +2970,7 @@ TEE_Result crypto_rng_add_entropy(const uint8_t *inbuf, size_t len) return TEE_SUCCESS; } -static TEE_Result tee_ltc_init(void) +TEE_Result crypto_init(void) { #if defined(_CFG_CRYPTO_WITH_ACIPHER) tee_ltc_alloc_mpa(); @@ -2980,11 +2980,6 @@ static TEE_Result tee_ltc_init(void) return tee_ltc_prng_init(tee_ltc_get_prng()); } -const struct crypto_ops crypto_ops = { - .name = "LibTomCrypt provider", - .init = tee_ltc_init, -}; - #if defined(CFG_WITH_VFP) void tomcrypt_arm_neon_enable(struct tomcrypt_arm_neon_state *state) { diff --git a/core/tee/tee_cryp_utl.c b/core/tee/tee_cryp_utl.c index 9cc736c422c..aff6f964dca 100644 --- a/core/tee/tee_cryp_utl.c +++ b/core/tee/tee_cryp_utl.c @@ -390,10 +390,7 @@ __weak void plat_prng_add_jitter_entropy_norpc(void) static TEE_Result tee_cryp_init(void) { - if (crypto_ops.init) - return crypto_ops.init(); - - return TEE_SUCCESS; + return crypto_init(); } service_init(tee_cryp_init); From 8759aec097d15b80a9c33319e52448500436ff32 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 13 Nov 2017 08:42:17 +0100 Subject: [PATCH 09/12] core: rename to Renames core/include/tee/tee_cryp_provider.h to core/include/crypto/crypto.h Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/kernel/generic_boot.c | 2 +- core/arch/arm/kernel/ree_fs_ta.c | 4 ++-- core/arch/arm/kernel/user_ta.c | 1 - core/arch/arm/mm/tee_pager.c | 2 +- core/arch/arm/pta/interrupt_tests.c | 2 +- core/arch/arm/tee/init.c | 1 - core/crypto/crypto.c | 2 +- .../{tee/tee_cryp_provider.h => crypto/crypto.h} | 10 ++++------ core/lib/libtomcrypt/src/tee_ltc_provider.c | 2 +- core/tee/fs_htree.c | 2 +- core/tee/tee_cryp_concat_kdf.c | 6 +++--- core/tee/tee_cryp_hkdf.c | 6 +++--- core/tee/tee_cryp_pbkdf2.c | 6 +++--- core/tee/tee_cryp_utl.c | 12 ++++++------ core/tee/tee_fs_key_manager.c | 8 ++++---- core/tee/tee_ree_fs.c | 1 - core/tee/tee_rpmb_fs.c | 2 +- core/tee/tee_svc_cryp.c | 16 ++++++++-------- 18 files changed, 40 insertions(+), 45 deletions(-) rename core/include/{tee/tee_cryp_provider.h => crypto/crypto.h} (98%) diff --git a/core/arch/arm/kernel/generic_boot.c b/core/arch/arm/kernel/generic_boot.c index d15d8f146c2..951eb2f11a6 100644 --- a/core/arch/arm/kernel/generic_boot.c +++ b/core/arch/arm/kernel/generic_boot.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,6 @@ #include #include #include -#include #include #include #include diff --git a/core/arch/arm/kernel/ree_fs_ta.c b/core/arch/arm/kernel/ree_fs_ta.c index 11582995d43..81250c64272 100644 --- a/core/arch/arm/kernel/ree_fs_ta.c +++ b/core/arch/arm/kernel/ree_fs_ta.c @@ -25,6 +25,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include #include @@ -36,10 +37,9 @@ #include #include #include -#include +#include #include #include -#include #include #include diff --git a/core/arch/arm/kernel/user_ta.c b/core/arch/arm/kernel/user_ta.c index 7c27bc2c173..efbfc9e8fc2 100644 --- a/core/arch/arm/kernel/user_ta.c +++ b/core/arch/arm/kernel/user_ta.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/core/arch/arm/mm/tee_pager.c b/core/arch/arm/mm/tee_pager.c index 2e709faa27c..3f69e0eeb7a 100644 --- a/core/arch/arm/mm/tee_pager.c +++ b/core/arch/arm/mm/tee_pager.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/core/arch/arm/pta/interrupt_tests.c b/core/arch/arm/pta/interrupt_tests.c index dfffc3ad46a..8bf4c6973f9 100644 --- a/core/arch/arm/pta/interrupt_tests.c +++ b/core/arch/arm/pta/interrupt_tests.c @@ -24,6 +24,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #define TA_NAME "interrupt_tests.ta" diff --git a/core/arch/arm/tee/init.c b/core/arch/arm/tee/init.c index 0549340d891..f1565c25f80 100644 --- a/core/arch/arm/tee/init.c +++ b/core/arch/arm/tee/init.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 372c9898041..de6e0d28868 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -6,8 +6,8 @@ */ #include +#include #include -#include #if !defined(_CFG_CRYPTO_WITH_HASH) TEE_Result crypto_hash_get_ctx_size(uint32_t algo __unused, diff --git a/core/include/tee/tee_cryp_provider.h b/core/include/crypto/crypto.h similarity index 98% rename from core/include/tee/tee_cryp_provider.h rename to core/include/crypto/crypto.h index 555fe05b400..914bbd74b7a 100644 --- a/core/include/tee/tee_cryp_provider.h +++ b/core/include/crypto/crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Linaro Limited + * Copyright (c) 2014-2017, Linaro Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,13 +41,11 @@ * @algo: algorithm identifier (TEE_ALG_*) */ - -#ifndef TEE_CRYP_PROVIDER_H -#define TEE_CRYP_PROVIDER_H +#ifndef __CRYPTO_CRYPTO_H +#define __CRYPTO_CRYPTO_H #include - TEE_Result crypto_init(void); /* Message digest functions */ @@ -280,4 +278,4 @@ TEE_Result crypto_rng_read(void *buf, size_t blen); TEE_Result rng_generate(void *buffer, size_t len); -#endif /* TEE_CRYP_PROVIDER_H */ +#endif /* __CRYPTO_CRYPTO_H */ diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index e7bfe8f09ae..6979877769d 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -26,7 +26,7 @@ */ #include -#include +#include #include #include diff --git a/core/tee/fs_htree.c b/core/tee/fs_htree.c index d9656fbb013..bdc57fe6dfe 100644 --- a/core/tee/fs_htree.c +++ b/core/tee/fs_htree.c @@ -26,6 +26,7 @@ */ #include +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/core/tee/tee_cryp_concat_kdf.c b/core/tee/tee_cryp_concat_kdf.c index a68dbd6bf49..0733c42f603 100644 --- a/core/tee/tee_cryp_concat_kdf.c +++ b/core/tee/tee_cryp_concat_kdf.c @@ -25,12 +25,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include -#include #include #include -#include -#include TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret, size_t shared_secret_len, diff --git a/core/tee/tee_cryp_hkdf.c b/core/tee/tee_cryp_hkdf.c index 7c93f70d3b0..e89d3b7940a 100644 --- a/core/tee/tee_cryp_hkdf.c +++ b/core/tee/tee_cryp_hkdf.c @@ -25,11 +25,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include +#include #include #include +#include +#include #include diff --git a/core/tee/tee_cryp_pbkdf2.c b/core/tee/tee_cryp_pbkdf2.c index d10584a5aa0..1a2eea5b959 100644 --- a/core/tee/tee_cryp_pbkdf2.c +++ b/core/tee/tee_cryp_pbkdf2.c @@ -25,12 +25,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include -#include #include #include -#include -#include struct hmac_parms { uint32_t algo; diff --git a/core/tee/tee_cryp_utl.c b/core/tee/tee_cryp_utl.c index aff6f964dca..42876371d39 100644 --- a/core/tee/tee_cryp_utl.c +++ b/core/tee/tee_cryp_utl.c @@ -25,15 +25,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include +#include #include -#include #include -#include +#include #include -#include -#include -#include -#include +#include #if !defined(CFG_WITH_SOFTWARE_PRNG) TEE_Result get_rng_array(void *buffer, int len) diff --git a/core/tee/tee_fs_key_manager.c b/core/tee/tee_fs_key_manager.c index 6b9148872d0..a218c5b7a60 100644 --- a/core/tee/tee_fs_key_manager.c +++ b/core/tee/tee_fs_key_manager.c @@ -37,16 +37,16 @@ * RNG - Random Number Generator */ +#include +#include #include -#include -#include #include #include #include +#include +#include #include -#include #include -#include #include #include diff --git a/core/tee/tee_ree_fs.c b/core/tee/tee_ree_fs.c index 7d3cc6c97d6..1641a2abd81 100644 --- a/core/tee/tee_ree_fs.c +++ b/core/tee/tee_ree_fs.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/core/tee/tee_rpmb_fs.c b/core/tee/tee_rpmb_fs.c index a63f022c998..f07f2e8e00e 100644 --- a/core/tee/tee_rpmb_fs.c +++ b/core/tee/tee_rpmb_fs.c @@ -26,6 +26,7 @@ */ #include +#include #include #include #include @@ -42,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 8351150e916..68cf8ae2224 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -26,19 +26,19 @@ */ #include -#include +#include #include -#include #include -#include -#include -#include +#include +#include #include +#include +#include #include -#include +#include +#include #include -#include -#include +#include #include #if defined(CFG_CRYPTO_HKDF) || defined(CFG_CRYPTO_CONCAT_KDF) || \ defined(CFG_CRYPTO_PBKDF2) From 67010813ea4b7cb24609be860c0a1e1e1e2bede9 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 13 Nov 2017 08:42:19 +0100 Subject: [PATCH 10/12] core: move crypto_authenc_*() from LTC * Moves crypto_authenc_*() from LTC to core/crypto/crypto.c * Defines and and implements the functions in core/lib/libtomcrypt/src/tee_ltc_provider.c based on the old implementations of crypto_authenc_*(). Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/crypto/crypto.c | 240 ++++++--- core/include/crypto/aes-ccm.h | 33 ++ core/include/crypto/aes-gcm.h | 31 ++ core/lib/libtomcrypt/src/tee_ltc_provider.c | 526 +++++++++----------- 4 files changed, 474 insertions(+), 356 deletions(-) create mode 100644 core/include/crypto/aes-ccm.h create mode 100644 core/include/crypto/aes-gcm.h diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index de6e0d28868..acc1e33234e 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -6,6 +6,8 @@ */ #include +#include +#include #include #include @@ -97,71 +99,183 @@ TEE_Result crypto_mac_final(void *ctx __unused, uint32_t algo __unused, } #endif /*_CFG_CRYPTO_WITH_MAC*/ -#if !defined(_CFG_CRYPTO_WITH_AUTHENC) -TEE_Result crypto_authenc_get_ctx_size(uint32_t algo __unused, - size_t *size __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result crypto_authenc_init(void *ctx __unused, uint32_t algo __unused, - TEE_OperationMode mode __unused, - const uint8_t *key __unused, - size_t key_len __unused, - const uint8_t *nonce __unused, - size_t nonce_len __unused, - size_t tag_len __unused, - size_t aad_len __unused, - size_t payload_len __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result crypto_authenc_update_aad(void *ctx __unused, uint32_t algo __unused, +TEE_Result crypto_authenc_get_ctx_size(uint32_t algo __maybe_unused, + size_t *size __maybe_unused) +{ + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + *size = crypto_aes_ccm_get_ctx_size(); + return TEE_SUCCESS; +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + *size = crypto_aes_gcm_get_ctx_size(); + return TEE_SUCCESS; +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +TEE_Result crypto_authenc_init(void *ctx __maybe_unused, + uint32_t algo __maybe_unused, + TEE_OperationMode mode __maybe_unused, + const uint8_t *key __maybe_unused, + size_t key_len __maybe_unused, + const uint8_t *nonce __maybe_unused, + size_t nonce_len __maybe_unused, + size_t tag_len __maybe_unused, + size_t aad_len __maybe_unused, + size_t payload_len __maybe_unused) +{ + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + return crypto_aes_ccm_init(ctx, mode, key, key_len, nonce, + nonce_len, tag_len, aad_len, + payload_len); +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + return crypto_aes_gcm_init(ctx, mode, key, key_len, nonce, + nonce_len, tag_len); +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +TEE_Result crypto_authenc_update_aad(void *ctx __maybe_unused, + uint32_t algo __maybe_unused, TEE_OperationMode mode __unused, - const uint8_t *data __unused, - size_t len __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result crypto_authenc_update_payload(void *ctx __unused, - uint32_t algo __unused, - TEE_OperationMode mode __unused, - const uint8_t *src_data __unused, - size_t src_len __unused, - uint8_t *dst_data __unused, - size_t *dst_len __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result crypto_authenc_enc_final(void *ctx __unused, uint32_t algo __unused, - const uint8_t *src_data __unused, - size_t src_len __unused, - uint8_t *dst_data __unused, - size_t *dst_len __unused, - uint8_t *dst_tag __unused, - size_t *dst_tag_len __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result crypto_authenc_dec_final(void *ctx __unused, uint32_t algo __unused, - const uint8_t *src_data __unused, - size_t src_len __unused, - uint8_t *dst_data __unused, - size_t *dst_len __unused, - const uint8_t *tag __unused, - size_t tag_len __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -void crypto_authenc_final(void *ctx __unused, uint32_t algo __unused) -{ + const uint8_t *data __maybe_unused, + size_t len __maybe_unused) +{ + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + return crypto_aes_ccm_update_aad(ctx, data, len); +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + return crypto_aes_gcm_update_aad(ctx, data, len); +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +TEE_Result crypto_authenc_update_payload(void *ctx __maybe_unused, + uint32_t algo __maybe_unused, + TEE_OperationMode mode __maybe_unused, + const uint8_t *src_data __maybe_unused, + size_t src_len __maybe_unused, + uint8_t *dst_data __maybe_unused, + size_t *dst_len __maybe_unused) +{ + size_t dl = *dst_len; + + *dst_len = src_len; + if (dl < src_len) + return TEE_ERROR_SHORT_BUFFER; + + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + return crypto_aes_ccm_update_payload(ctx, mode, src_data, + src_len, dst_data); +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + return crypto_aes_gcm_update_payload(ctx, mode, src_data, + src_len, dst_data); +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +TEE_Result crypto_authenc_enc_final(void *ctx __maybe_unused, + uint32_t algo __maybe_unused, + const uint8_t *src_data __maybe_unused, + size_t src_len __maybe_unused, + uint8_t *dst_data __maybe_unused, + size_t *dst_len __maybe_unused, + uint8_t *dst_tag __maybe_unused, + size_t *dst_tag_len __maybe_unused) +{ + size_t dl = *dst_len; + + *dst_len = src_len; + if (dl < src_len) + return TEE_ERROR_SHORT_BUFFER; + + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + return crypto_aes_ccm_enc_final(ctx, src_data, src_len, + dst_data, dst_tag, dst_tag_len); +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + return crypto_aes_gcm_enc_final(ctx, src_data, src_len, + dst_data, dst_tag, dst_tag_len); +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +TEE_Result crypto_authenc_dec_final(void *ctx __maybe_unused, + uint32_t algo __maybe_unused, + const uint8_t *src_data __maybe_unused, + size_t src_len __maybe_unused, + uint8_t *dst_data __maybe_unused, + size_t *dst_len __maybe_unused, + const uint8_t *tag __maybe_unused, + size_t tag_len __maybe_unused) +{ + size_t dl = *dst_len; + + *dst_len = src_len; + if (dl < src_len) + return TEE_ERROR_SHORT_BUFFER; + + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + return crypto_aes_ccm_dec_final(ctx, src_data, src_len, + dst_data, tag, tag_len); +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + return crypto_aes_gcm_dec_final(ctx, src_data, src_len, + dst_data, tag, tag_len); +#endif + default: + return TEE_ERROR_NOT_IMPLEMENTED; + } +} + +void crypto_authenc_final(void *ctx __maybe_unused, + uint32_t algo __maybe_unused) +{ + switch (algo) { +#if defined(CFG_CRYPTO_CCM) + case TEE_ALG_AES_CCM: + crypto_aes_ccm_final(ctx); + break; +#endif +#if defined(CFG_CRYPTO_GCM) + case TEE_ALG_AES_GCM: + crypto_aes_gcm_final(ctx); + break; +#endif + default: + break; + } } -#endif /*_CFG_CRYPTO_WITH_AUTHENC*/ #if !defined(_CFG_CRYPTO_WITH_ACIPHER) struct bignum *crypto_bignum_allocate(size_t size_bits __unused) diff --git a/core/include/crypto/aes-ccm.h b/core/include/crypto/aes-ccm.h new file mode 100644 index 00000000000..d3a3edfba39 --- /dev/null +++ b/core/include/crypto/aes-ccm.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef __CRYPTO_AES_CCM_H +#define __CRYPTO_AES_CCM_H + +#include + +size_t crypto_aes_ccm_get_ctx_size(void); +TEE_Result crypto_aes_ccm_init(void *ctx, TEE_OperationMode mode, + const uint8_t *key, size_t key_len, + const uint8_t *nonce, size_t nonce_len, + size_t tag_len, size_t aad_len, + size_t payload_len); +TEE_Result crypto_aes_ccm_update_aad(void *ctx, const uint8_t *data, + size_t len); +TEE_Result crypto_aes_ccm_update_payload(void *ctx, TEE_OperationMode mode, + const uint8_t *src_data, + size_t len, uint8_t *dst_data); +TEE_Result crypto_aes_ccm_enc_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + uint8_t *dst_tag, size_t *dst_tag_len); +TEE_Result crypto_aes_ccm_dec_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + const uint8_t *tag, size_t tag_len); +void crypto_aes_ccm_final(void *ctx); + +#endif /*__CRYPTO_AES_CCM_H*/ + diff --git a/core/include/crypto/aes-gcm.h b/core/include/crypto/aes-gcm.h new file mode 100644 index 00000000000..3b90eea519a --- /dev/null +++ b/core/include/crypto/aes-gcm.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef __CRYPTO_AES_GCM_H +#define __CRYPTO_AES_GCM_H + +#include + +size_t crypto_aes_gcm_get_ctx_size(void); +TEE_Result crypto_aes_gcm_init(void *ctx, TEE_OperationMode mode, + const uint8_t *key, size_t key_len, + const uint8_t *nonce, size_t nonce_len, + size_t tag_len); +TEE_Result crypto_aes_gcm_update_aad(void *ctx, const uint8_t *data, + size_t len); +TEE_Result crypto_aes_gcm_update_payload(void *ctx, TEE_OperationMode mode, + const uint8_t *src_data, + size_t len, uint8_t *dst_data); +TEE_Result crypto_aes_gcm_enc_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + uint8_t *dst_tag, size_t *dst_tag_len); +TEE_Result crypto_aes_gcm_dec_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + const uint8_t *tag, size_t tag_len); +void crypto_aes_gcm_final(void *ctx); + +#endif /*__CRYPTO_AES_GCM_H*/ diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index 6979877769d..36378fd0697 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -26,20 +26,21 @@ */ #include +#include +#include #include -#include - -#include +#include #include #include +#include #include -#include -#include #include -#include -#include -#include +#include +#include #include "tomcrypt_mpa.h" +#include +#include +#include #if defined(CFG_WITH_VFP) #include @@ -1911,19 +1912,6 @@ struct tee_symmetric_xts { }; #endif -static TEE_Result cipher_get_block_size(uint32_t algo, size_t *size) -{ - TEE_Result res; - int ltc_cipherindex; - - res = tee_algo_to_ltc_cipherindex(algo, <c_cipherindex); - if (res != TEE_SUCCESS) - return TEE_ERROR_NOT_SUPPORTED; - - *size = cipher_descriptor[ltc_cipherindex]->block_length; - return TEE_SUCCESS; -} - TEE_Result crypto_cipher_get_ctx_size(uint32_t algo, size_t *size) { switch (algo) { @@ -2532,345 +2520,317 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest, * Authenticated encryption ******************************************************************************/ -#if defined(_CFG_CRYPTO_WITH_AUTHENC) - #define TEE_CCM_KEY_MAX_LENGTH 32 #define TEE_CCM_NONCE_MAX_LENGTH 13 #define TEE_CCM_TAG_MAX_LENGTH 16 #define TEE_GCM_TAG_MAX_LENGTH 16 -#define TEE_xCM_TAG_MAX_LENGTH 16 #if defined(CFG_CRYPTO_CCM) struct tee_ccm_state { ccm_state ctx; /* the ccm state as defined by LTC */ size_t tag_len; /* tag length */ }; -#endif - -#if defined(CFG_CRYPTO_GCM) -struct tee_gcm_state { - gcm_state ctx; /* the gcm state as defined by LTC */ - size_t tag_len; /* tag length */ -}; -#endif -TEE_Result crypto_authenc_get_ctx_size(uint32_t algo, size_t *size) +size_t crypto_aes_ccm_get_ctx_size(void) { - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - *size = sizeof(struct tee_ccm_state); - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - *size = sizeof(struct tee_gcm_state); - break; -#endif - default: - return TEE_ERROR_NOT_SUPPORTED; - } - return TEE_SUCCESS; + return sizeof(struct tee_ccm_state); } -TEE_Result crypto_authenc_init(void *ctx, uint32_t algo, - TEE_OperationMode mode __unused, +TEE_Result crypto_aes_ccm_init(void *ctx, TEE_OperationMode mode __unused, const uint8_t *key, size_t key_len, const uint8_t *nonce, size_t nonce_len, - size_t tag_len, size_t aad_len __maybe_unused, - size_t payload_len __maybe_unused) + size_t tag_len, size_t aad_len, + size_t payload_len) { TEE_Result res; int ltc_res; int ltc_cipherindex; -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif + struct tee_ccm_state *ccm = ctx; - res = tee_algo_to_ltc_cipherindex(algo, <c_cipherindex); + res = tee_algo_to_ltc_cipherindex(TEE_ALG_AES_CCM, <c_cipherindex); if (res != TEE_SUCCESS) return TEE_ERROR_NOT_SUPPORTED; - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - /* reset the state */ - ccm = ctx; - memset(ccm, 0, sizeof(struct tee_ccm_state)); - ccm->tag_len = tag_len; - /* Check the key length */ - if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH)) - return TEE_ERROR_BAD_PARAMETERS; + /* reset the state */ + memset(ccm, 0, sizeof(struct tee_ccm_state)); + ccm->tag_len = tag_len; - /* check the nonce */ - if (nonce_len > TEE_CCM_NONCE_MAX_LENGTH) - return TEE_ERROR_BAD_PARAMETERS; + /* Check the key length */ + if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH)) + return TEE_ERROR_BAD_PARAMETERS; - /* check the tag len */ - if ((tag_len < 4) || - (tag_len > TEE_CCM_TAG_MAX_LENGTH) || - (tag_len % 2 != 0)) - return TEE_ERROR_NOT_SUPPORTED; + /* check the nonce */ + if (nonce_len > TEE_CCM_NONCE_MAX_LENGTH) + return TEE_ERROR_BAD_PARAMETERS; - ltc_res = ccm_init(&ccm->ctx, ltc_cipherindex, key, key_len, - payload_len, tag_len, aad_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; + /* check the tag len */ + if ((tag_len < 4) || (tag_len > TEE_CCM_TAG_MAX_LENGTH) || + (tag_len % 2 != 0)) + return TEE_ERROR_NOT_SUPPORTED; - /* Add the IV */ - ltc_res = ccm_add_nonce(&ccm->ctx, nonce, nonce_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - /* reset the state */ - gcm = ctx; - memset(gcm, 0, sizeof(struct tee_gcm_state)); - gcm->tag_len = tag_len; + ltc_res = ccm_init(&ccm->ctx, ltc_cipherindex, key, key_len, + payload_len, tag_len, aad_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; - ltc_res = gcm_init(&gcm->ctx, ltc_cipherindex, key, key_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; + /* Add the IV */ + ltc_res = ccm_add_nonce(&ccm->ctx, nonce, nonce_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; - /* Add the IV */ - ltc_res = gcm_add_iv(&gcm->ctx, nonce, nonce_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif - default: - return TEE_ERROR_NOT_SUPPORTED; + return TEE_SUCCESS; +} + +TEE_Result crypto_aes_ccm_update_aad(void *ctx, const uint8_t *data, size_t len) +{ + struct tee_ccm_state *ccm = ctx; + int ltc_res; + + /* Add the AAD (note: aad can be NULL if aadlen == 0) */ + ltc_res = ccm_add_aad(&ccm->ctx, data, len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + + return TEE_SUCCESS; +} + +TEE_Result crypto_aes_ccm_update_payload(void *ctx, TEE_OperationMode mode, + const uint8_t *src_data, + size_t len, uint8_t *dst_data) +{ + int ltc_res, dir; + struct tee_ccm_state *ccm = ctx; + unsigned char *pt, *ct; /* the plain and the cipher text */ + + if (mode == TEE_MODE_ENCRYPT) { + pt = (unsigned char *)src_data; + ct = dst_data; + dir = CCM_ENCRYPT; + } else { + pt = dst_data; + ct = (unsigned char *)src_data; + dir = CCM_DECRYPT; } + ltc_res = ccm_process(&ccm->ctx, pt, len, ct, dir); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; return TEE_SUCCESS; } -TEE_Result crypto_authenc_update_aad(void *ctx, uint32_t algo, - TEE_OperationMode mode __unused, - const uint8_t *data, size_t len) +TEE_Result crypto_aes_ccm_enc_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + uint8_t *dst_tag, size_t *dst_tag_len) { -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif + TEE_Result res; + struct tee_ccm_state *ccm = ctx; int ltc_res; - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - /* Add the AAD (note: aad can be NULL if aadlen == 0) */ - ccm = ctx; - ltc_res = ccm_add_aad(&ccm->ctx, data, len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif + /* Finalize the remaining buffer */ + res = crypto_aes_ccm_update_payload(ctx, TEE_MODE_ENCRYPT, src_data, + len, dst_data); + if (res != TEE_SUCCESS) + return res; + + /* Check the tag length */ + if (*dst_tag_len < ccm->tag_len) { + *dst_tag_len = ccm->tag_len; + return TEE_ERROR_SHORT_BUFFER; + } + *dst_tag_len = ccm->tag_len; + + /* Compute the tag */ + ltc_res = ccm_done(&ccm->ctx, dst_tag, + (unsigned long *)dst_tag_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + + return TEE_SUCCESS; +} + +TEE_Result crypto_aes_ccm_dec_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + const uint8_t *tag, size_t tag_len) +{ + TEE_Result res = TEE_ERROR_BAD_STATE; + struct tee_ccm_state *ccm = ctx; + int ltc_res; + uint8_t dst_tag[TEE_CCM_TAG_MAX_LENGTH]; + unsigned long ltc_tag_len = tag_len; + + if (tag_len == 0) + return TEE_ERROR_SHORT_BUFFER; + if (tag_len > TEE_CCM_TAG_MAX_LENGTH) + return TEE_ERROR_BAD_STATE; + + /* Process the last buffer, if any */ + res = crypto_aes_ccm_update_payload(ctx, TEE_MODE_DECRYPT, src_data, + len, dst_data); + if (res != TEE_SUCCESS) + return res; + + /* Finalize the authentication */ + ltc_res = ccm_done(&ccm->ctx, dst_tag, <c_tag_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + + if (buf_compare_ct(dst_tag, tag, tag_len) != 0) + res = TEE_ERROR_MAC_INVALID; + else + res = TEE_SUCCESS; + return res; +} + +void crypto_aes_ccm_final(void *ctx) +{ + struct tee_ccm_state *ccm = ctx; + + ccm_reset(&ccm->ctx); +} +#endif /*CFG_CRYPTO_CCM*/ + #if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - /* Add the AAD (note: aad can be NULL if aadlen == 0) */ - gcm = ctx; - ltc_res = gcm_add_aad(&gcm->ctx, data, len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif - default: +struct tee_gcm_state { + gcm_state ctx; /* the gcm state as defined by LTC */ + size_t tag_len; /* tag length */ +}; + +size_t crypto_aes_gcm_get_ctx_size(void) +{ + return sizeof(struct tee_gcm_state); +} + +TEE_Result crypto_aes_gcm_init(void *ctx, TEE_OperationMode mode __unused, + const uint8_t *key, size_t key_len, + const uint8_t *nonce, size_t nonce_len, + size_t tag_len) +{ + TEE_Result res; + int ltc_res; + int ltc_cipherindex; + struct tee_gcm_state *gcm = ctx; + + res = tee_algo_to_ltc_cipherindex(TEE_ALG_AES_GCM, <c_cipherindex); + if (res != TEE_SUCCESS) return TEE_ERROR_NOT_SUPPORTED; - } + + /* reset the state */ + memset(gcm, 0, sizeof(struct tee_gcm_state)); + gcm->tag_len = tag_len; + + ltc_res = gcm_init(&gcm->ctx, ltc_cipherindex, key, key_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + + /* Add the IV */ + ltc_res = gcm_add_iv(&gcm->ctx, nonce, nonce_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; return TEE_SUCCESS; } -TEE_Result crypto_authenc_update_payload(void *ctx, uint32_t algo, - TEE_OperationMode mode, +TEE_Result crypto_aes_gcm_update_aad(void *ctx, const uint8_t *data, size_t len) +{ + struct tee_gcm_state *gcm = ctx; + int ltc_res; + + /* Add the AAD (note: aad can be NULL if aadlen == 0) */ + ltc_res = gcm_add_aad(&gcm->ctx, data, len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + + return TEE_SUCCESS; +} + +TEE_Result crypto_aes_gcm_update_payload(void *ctx, TEE_OperationMode mode, const uint8_t *src_data, - size_t src_len, - uint8_t *dst_data, - size_t *dst_len) + size_t len, uint8_t *dst_data) { -#if defined(CFG_CRYPTO_GCM) TEE_Result res; -#endif int ltc_res, dir; -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif + struct tee_gcm_state *gcm = ctx; unsigned char *pt, *ct; /* the plain and the cipher text */ if (mode == TEE_MODE_ENCRYPT) { pt = (unsigned char *)src_data; ct = dst_data; + dir = GCM_ENCRYPT; } else { pt = dst_data; ct = (unsigned char *)src_data; + dir = GCM_DECRYPT; } - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - ccm = ctx; - dir = (mode == TEE_MODE_ENCRYPT ? CCM_ENCRYPT : CCM_DECRYPT); - ltc_res = ccm_process(&ccm->ctx, pt, src_len, ct, dir); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - *dst_len = src_len; - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - /* aad is optional ==> add one without length */ - gcm = ctx; - if (gcm->ctx.mode == LTC_GCM_MODE_IV) { - res = crypto_authenc_update_aad(gcm, algo, mode, 0, 0); - if (res != TEE_SUCCESS) - return res; - } - - /* process the data */ - dir = (mode == TEE_MODE_ENCRYPT ? GCM_ENCRYPT : GCM_DECRYPT); - ltc_res = gcm_process(&gcm->ctx, pt, src_len, ct, dir); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - *dst_len = src_len; - break; -#endif - default: - return TEE_ERROR_NOT_SUPPORTED; + /* aad is optional ==> add one without length */ + if (gcm->ctx.mode == LTC_GCM_MODE_IV) { + res = crypto_aes_gcm_update_aad(gcm, NULL, 0); + if (res != TEE_SUCCESS) + return res; } + /* process the data */ + ltc_res = gcm_process(&gcm->ctx, pt, len, ct, dir); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; + return TEE_SUCCESS; } -TEE_Result crypto_authenc_enc_final(void *ctx, uint32_t algo, - const uint8_t *src_data, - size_t src_len, uint8_t *dst_data, - size_t *dst_len, uint8_t *dst_tag, - size_t *dst_tag_len) +TEE_Result crypto_aes_gcm_enc_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, + uint8_t *dst_tag, size_t *dst_tag_len) { TEE_Result res; -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif - size_t digest_size; + struct tee_gcm_state *gcm = ctx; int ltc_res; - /* Check the resulting buffer is not too short */ - res = cipher_get_block_size(algo, &digest_size); - if (res != TEE_SUCCESS) - return res; - /* Finalize the remaining buffer */ - res = crypto_authenc_update_payload(ctx, algo, TEE_MODE_ENCRYPT, - src_data, src_len, dst_data, - dst_len); + res = crypto_aes_gcm_update_payload(ctx, TEE_MODE_ENCRYPT, src_data, + len, dst_data); if (res != TEE_SUCCESS) return res; - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - /* Check the tag length */ - ccm = ctx; - if (*dst_tag_len < ccm->tag_len) { - *dst_tag_len = ccm->tag_len; - return TEE_ERROR_SHORT_BUFFER; - } - *dst_tag_len = ccm->tag_len; - - /* Compute the tag */ - ltc_res = ccm_done(&ccm->ctx, dst_tag, - (unsigned long *)dst_tag_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - /* Check the tag length */ - gcm = ctx; - if (*dst_tag_len < gcm->tag_len) { - *dst_tag_len = gcm->tag_len; - return TEE_ERROR_SHORT_BUFFER; - } + /* Check the tag length */ + if (*dst_tag_len < gcm->tag_len) { *dst_tag_len = gcm->tag_len; - - /* Compute the tag */ - ltc_res = gcm_done(&gcm->ctx, dst_tag, - (unsigned long *)dst_tag_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif - default: - return TEE_ERROR_NOT_SUPPORTED; + return TEE_ERROR_SHORT_BUFFER; } + *dst_tag_len = gcm->tag_len; + + /* Compute the tag */ + ltc_res = gcm_done(&gcm->ctx, dst_tag, (unsigned long *)dst_tag_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; return TEE_SUCCESS; } -TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo, - const uint8_t *src_data, size_t src_len, - uint8_t *dst_data, size_t *dst_len, +TEE_Result crypto_aes_gcm_dec_final(void *ctx, const uint8_t *src_data, + size_t len, uint8_t *dst_data, const uint8_t *tag, size_t tag_len) { TEE_Result res = TEE_ERROR_BAD_STATE; -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif + struct tee_gcm_state *gcm = ctx; int ltc_res; - uint8_t dst_tag[TEE_xCM_TAG_MAX_LENGTH]; + uint8_t dst_tag[TEE_GCM_TAG_MAX_LENGTH]; unsigned long ltc_tag_len = tag_len; if (tag_len == 0) return TEE_ERROR_SHORT_BUFFER; - if (tag_len > TEE_xCM_TAG_MAX_LENGTH) + if (tag_len > TEE_GCM_TAG_MAX_LENGTH) return TEE_ERROR_BAD_STATE; /* Process the last buffer, if any */ - res = crypto_authenc_update_payload(ctx, algo, TEE_MODE_DECRYPT, - src_data, src_len, dst_data, - dst_len); + res = crypto_aes_gcm_update_payload(ctx, TEE_MODE_DECRYPT, src_data, + len, dst_data); if (res != TEE_SUCCESS) return res; - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - /* Finalize the authentication */ - ccm = ctx; - ltc_res = ccm_done(&ccm->ctx, dst_tag, <c_tag_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - /* Finalize the authentication */ - gcm = ctx; - ltc_res = gcm_done(&gcm->ctx, dst_tag, <c_tag_len); - if (ltc_res != CRYPT_OK) - return TEE_ERROR_BAD_STATE; - break; -#endif - default: - return TEE_ERROR_NOT_SUPPORTED; - } + /* Finalize the authentication */ + ltc_res = gcm_done(&gcm->ctx, dst_tag, <c_tag_len); + if (ltc_res != CRYPT_OK) + return TEE_ERROR_BAD_STATE; if (buf_compare_ct(dst_tag, tag, tag_len) != 0) res = TEE_ERROR_MAC_INVALID; @@ -2879,33 +2839,13 @@ TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo, return res; } -void crypto_authenc_final(void *ctx, uint32_t algo) +void crypto_aes_gcm_final(void *ctx) { -#if defined(CFG_CRYPTO_CCM) - struct tee_ccm_state *ccm; -#endif -#if defined(CFG_CRYPTO_GCM) - struct tee_gcm_state *gcm; -#endif + struct tee_gcm_state *gcm = ctx; - switch (algo) { -#if defined(CFG_CRYPTO_CCM) - case TEE_ALG_AES_CCM: - ccm = ctx; - ccm_reset(&ccm->ctx); - break; -#endif -#if defined(CFG_CRYPTO_GCM) - case TEE_ALG_AES_GCM: - gcm = ctx; - gcm_reset(&gcm->ctx); - break; -#endif - default: - break; - } + gcm_reset(&gcm->ctx); } -#endif /* _CFG_CRYPTO_WITH_AUTHENC */ +#endif /*CFG_CRYPTO_GCM*/ /****************************************************************************** * Pseudo Random Number Generator From b3e82872592a1c6c46b4f15c182397bb6dcc8416 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 13 Nov 2017 08:42:20 +0100 Subject: [PATCH 11/12] Documentation: sync with new crypto.h Update documentation of the Crypto API with the new replacing the old crypto_ops based API. Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- documentation/crypto.md | 116 ++++++++++++---------------- documentation/porting_guidelines.md | 15 ++-- 2 files changed, 58 insertions(+), 73 deletions(-) diff --git a/documentation/crypto.md b/documentation/crypto.md index 18d3933fdc1..1f8c95d5db6 100644 --- a/documentation/crypto.md +++ b/documentation/crypto.md @@ -12,12 +12,12 @@ algorithms. Most of the crypto code runs in kernel mode inside the TEE core. Here is a schematic view of a typical call to the crypto API. The numbers in square brackets ([1], [2]...) refer to the sections below. - some_function() (Trusted App) - [1] TEE_*() User space (libutee.a) - ------- utee_*() ----------------------------------------------- - [2] tee_svc_*() Kernel space - [3] crypto_ops.*() (libtomcrypt.a) - [4] /* LibTomCrypt */ (libtomcrypt.a) + some_function() (Trusted App) + [1] TEE_*() User space (libutee.a) + ------- utee_*() ---------------------------------------------- + [2] tee_svc_*() Kernel space + [3] crypto_*() (libtomcrypt.a and crypto.c) + [4] /* LibTomCrypt */ (libtomcrypt.a) ## The TEE Cryptographic Operations API [1] @@ -51,68 +51,62 @@ All cryptography-related system calls are declared in [tee_svc_cryp.c](../core/tee/tee_svc_cryp.c). In addition to dealing with the usual work required at the user/kernel interface (checking parameters and copying memory buffers between user and kernel space), -the system calls invoke a private abstraction layer: the **crypto_ops** -structure, which is declared in -[tee_cryp_provider.h](../core/include/tee/tee_cryp_provider.h). +the system calls invoke a private abstraction layer: the **Crypto API**, +which is declared in [crypto.h](core/include/crypto/crypto.h). It serves two main purposes: 1. Allow for alternative implementations, such as hardware-accelerated versions. 2. Provide an easy way to disable some families of algorithms at compile-time to save space. See *LibTomCrypt* below. -## struct crypto_ops [3] +## crypto_*() [3] -The **crypto_ops** structure contains pointer to functions that implement the -actual algorithms and helper functions. The TEE Core has one global instance of -this structure. The default implementation, based on +The **crypto_*()** functions implement the actual algorithms and helper +functions. The TEE Core has one global active implementeation of this interface. +The default implementation, mostly based on [LibTomCrypt](https://github.com/libtom/libtomcrypt), is as follows: ```c -/* core/lib/libtomcrypt/tee_ltc_provider.c */ +/* core/crypto/crypto.c */ /* - * static functions: tee_ltc_init(), hash_get_ctx_size(), etc. - * ... + * Default implementation for all functions in crypto.h */ -struct crypto_ops crypto_ops = { - .name = "LibTomCrypt provider", - .init = tee_ltc_init, +#if !defined(_CFG_CRYPTO_WITH_HASH) +TEE_Result crypto_hash_get_ctx_size(uint32_t algo __unused, + size_t *size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +... +#endif /*_CFG_CRYPTO_WITH_HASH*/ + +/* core/lib/libtomcrypt/tee_ltc_provider.c */ + #if defined(_CFG_CRYPTO_WITH_HASH) - .hash = { - .get_ctx_size = hash_get_ctx_size, - .init = hash_init, - .update = hash_update, - .final = hash_final, - }, -#endif -#if defined(_CFG_CRYPTO_WITH_CIPHER) - .cipher = { - .final = cipher_final, - .get_block_size = cipher_get_block_size, - .get_ctx_size = cipher_get_ctx_size, - .init = cipher_init, - .update = cipher_update, - }, -#endif +TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size) +{ /* ... */ + return TEE_SUCCESS; } + +#endif /*_CFG_CRYPTO_WITH_HASH*/ + ``` -As shown above, it is allowed to omit some pointers, in which case they will be -set to NULL by the compiler and not used by the system service layer. -When a Trusted Application calls **TEE_AllocateOperation()** to request an -operation that is not available, it receives an error status -(**TEE_ERROR_NOT_IMPLEMENTED**) but it will not panic. +As shown above, families of algorithms can be disabled and +[crypto.c]((core/include/crypto/crypto.h)) will provide default null +implementations that will return **TEE_ERROR_NOT_IMPLEMENTED**. ## Public/private key format -**crypto_ops** uses implementation-specific types to hold key data +**** uses implementation-specific types to hold key data for asymmetric algorithms. For instance, here is how a public RSA key is represented: ```c -/* core/include/tee/tee_cryp_provider.h */ +/* core/include/crypt/crypt.h */ struct rsa_public_key { struct bignum *e; /* Public exponent */ @@ -130,20 +124,14 @@ conversion to or from the big endian binary format. ```c -/* core/include/tee/tee_cryp_provider.h */ +/* core/include/core/core.h */ -struct bignum_ops { - /* ... */ - struct bignum *(*allocate)(size_t size_bits); - TEE_Result (*bin2bn)(const uint8_t *from, size_t fromsize, - struct bignum *to); - void (*bn2bin)(const struct bignum *from, uint8_t *to); -}; +struct bignum *crypto_bignum_allocate(size_t size_bits); +TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize, + struct bignum *to); +void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to); +/*...*/ -struct crypto_ops { - /* ... */ - struct bignum_ops bignum; -}; ``` ## LibTomCrypt [4] @@ -169,22 +157,18 @@ return **TEE_ERROR_NOT_IMPLEMENTED**). ## How to add a new crypto implementation To add a new implementation, the default one in -[core/lib/libtomcrypt](../core/lib/libtomcrypt) should -be used as a reference. A proof-of-concept implementation based on OpenSSL was -developed when the `crypto_ops` abstraction layer was introduced. It is not -included in the main branch of the OP-TEE repository essentially due to -licensing concerns; however it is available in the -[poc/openssl_cryptolib](https://github.com/OP-TEE/optee_os/tree/poc/openssl_cryptolib) -branch. +[core/lib/libtomcrypt](../core/lib/libtomcrypt) in combination with what is +in [core/crypto](../core/crypto) should be used as a reference. Here are the main things to consider when adding a new crypto provider: -- Put all the new code in its own directory under `core/lib`. +- Put all the new code in its own directory under `core/lib` unless it is + code that will be used regardless of which crypto provider is in use. + How we are dealing with AES-GCM in [core/crypto](../core/crypto) could + serve as an example. - Avoid modifying [tee_svc_cryp.c](../core/tee/tee_svc_cryp.c). It should not be needed. -- Your own **struct crypto_ops crypto_ops = ...** should be defined in a file at - the top level of your new directory. -- Although not all pointers in **crypto_ops** need to be defined, all are - required for compliance to the GlobalPlatform specification. +- Although not all crypto families need to be defined, all are required for + compliance to the GlobalPlatform specification. - If you intend to make some algorithms optional, please try to re-use the same names for configuration variables as the default implementation. diff --git a/documentation/porting_guidelines.md b/documentation/porting_guidelines.md index a395a5aff2d..3e56250a7ab 100644 --- a/documentation/porting_guidelines.md +++ b/documentation/porting_guidelines.md @@ -306,13 +306,14 @@ have the ability to enable Crypto Extensions that were introduced with ARMv8-A have hardware crypto IP's, but due to NDA's etc it has not been possible to enable it. If you have a device capable of doing crypto operations on a dedicated crypto block and you prefer to use that in favor for the software -implementation, then you will need to implement a new `crypto_ops` structure and -write the low level driver that communicates with the device. Our [crypto.md] -file describes how to add and implement a new `struct crypto_ops`. Since the -communication with crypto blocks tends to be quite different depending on what -kind of crypto block you have, we have not written how that should be done. It -might be that we do that in the future when get hold of a device where we can -use the crypto block. +implementation, then you will need to implement relevant functions defined in +`core/include/crypto/crypto.h`, the Crypto API, and write the low level +driver that communicates with the device. Our [crypto.md] file describes +how the Crypto API is integrated. Since the communication with crypto +blocks tends to be quite different depending on what kind of crypto block +you have, we have not written how that should be done. It might be that we +do that in the future when get hold of a device where we can use the crypto +block. ## 7. Power Management / PSCI In section 2 when we talked about the file `main.c`, we added a couple of From 04c628d060d0dff59e38b4d1ef74d64c18acd7fc Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 13 Nov 2017 08:42:23 +0100 Subject: [PATCH 12/12] core: fix asan build error Fixes the build error: kern.ld:153: undefined symbol `__asan_shadow_start' referenced in expression Tested-by: Jerome Forissier (HiKey960, GP) Acked-by: Jerome Forissier Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/kernel/kern.ld.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/arch/arm/kernel/kern.ld.S b/core/arch/arm/kernel/kern.ld.S index 918cb793a73..30f7cc01c0b 100644 --- a/core/arch/arm/kernel/kern.ld.S +++ b/core/arch/arm/kernel/kern.ld.S @@ -489,8 +489,10 @@ PROVIDE(__vcore_init_ro_size = 0); #endif /* CFG_CORE_RODATA_NOEXEC */ #endif /* CFG_WITH_PAGER */ +#ifdef CFG_CORE_SANITIZE_KADDRESS PROVIDE(__asan_map_start = (__asan_shadow_start / SMALL_PAGE_SIZE) * SMALL_PAGE_SIZE); PROVIDE(__asan_map_end = ((__asan_shadow_end - 1) / SMALL_PAGE_SIZE) * SMALL_PAGE_SIZE + SMALL_PAGE_SIZE); PROVIDE(__asan_map_size = __asan_map_end - __asan_map_start); +#endif /*CFG_CORE_SANITIZE_KADDRESS*/