aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2019-03-08 15:22:14 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2019-03-11 17:58:04 +0100
commitf1e9b21b29bdc21a51c6c1a4b8df7eb5e2bd5189 (patch)
tree3f7280058413d43e605e867b156f86bd6271941a /core
parent96098f011f7cc334d2c9eb694e1cc45ded4f64cf (diff)
core: crypto: introduce struct crypto_authenc_ops
Uses struct crypto_authenc_ops pointer in crypto context for authenc ciphers (AES-GCM and AES-CCM) as a glue layer instead of a switch(algo) in each cryto_authenc_*() function. Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core')
-rw-r--r--core/crypto/aes-gcm-ghash-tbl.c1
-rw-r--r--core/crypto/aes-gcm.c82
-rw-r--r--core/crypto/crypto.c237
-rw-r--r--core/include/crypto/aes-ccm.h33
-rw-r--r--core/include/crypto/aes-gcm.h31
-rw-r--r--core/include/crypto/crypto_impl.h38
-rw-r--r--core/lib/libtomcrypt/ccm.c226
-rw-r--r--core/lib/libtomcrypt/gcm.c219
-rw-r--r--core/lib/libtomcrypt/src/tee_ltc_provider.c419
-rw-r--r--core/lib/libtomcrypt/sub.mk2
10 files changed, 613 insertions, 675 deletions
diff --git a/core/crypto/aes-gcm-ghash-tbl.c b/core/crypto/aes-gcm-ghash-tbl.c
index 5e7965a9..203b5300 100644
--- a/core/crypto/aes-gcm-ghash-tbl.c
+++ b/core/crypto/aes-gcm-ghash-tbl.c
@@ -17,7 +17,6 @@
* limitations under the License.
*/
-#include <crypto/aes-gcm.h>
#include <io.h>
#include <kernel/panic.h>
#include <string.h>
diff --git a/core/crypto/aes-gcm.c b/core/crypto/aes-gcm.c
index 0cc1e99f..c4aa1ff9 100644
--- a/core/crypto/aes-gcm.c
+++ b/core/crypto/aes-gcm.c
@@ -5,6 +5,7 @@
#include <assert.h>
#include <crypto/internal_aes-gcm.h>
+#include <crypto/crypto_impl.h>
#include <io.h>
#include <string_ext.h>
#include <string.h>
@@ -402,65 +403,104 @@ TEE_Result internal_aes_gcm_dec(const struct internal_aes_gcm_key *enc_key,
#ifndef CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB
-#include <crypto/aes-gcm.h>
#include <stdlib.h>
+#include <crypto/crypto.h>
-TEE_Result crypto_aes_gcm_alloc_ctx(void **ctx_ret)
+struct aes_gcm_ctx {
+ struct crypto_authenc_ctx aec;
+ struct internal_aes_gcm_ctx ctx;
+};
+
+static const struct crypto_authenc_ops aes_gcm_ops;
+
+static struct aes_gcm_ctx *
+to_aes_gcm_ctx(struct crypto_authenc_ctx *aec)
+{
+ assert(aec->ops == &aes_gcm_ops);
+
+ return container_of(aec, struct aes_gcm_ctx, aec);
+}
+
+TEE_Result crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx **ctx_ret)
{
- struct internal_aes_gcm_ctx *ctx = calloc(1, sizeof(*ctx));
+ struct aes_gcm_ctx *ctx = calloc(1, sizeof(*ctx));
if (!ctx)
return TEE_ERROR_OUT_OF_MEMORY;
+ ctx->aec.ops = &aes_gcm_ops;
+
+ *ctx_ret = &ctx->aec;
- *ctx_ret = ctx;
return TEE_SUCCESS;
}
-void crypto_aes_gcm_free_ctx(void *ctx)
+static void aes_gcm_free_ctx(struct crypto_authenc_ctx *aec)
{
- free(ctx);
+ free(to_aes_gcm_ctx(aec));
}
-void crypto_aes_gcm_copy_state(void *dst_ctx, void *src_ctx)
+static void aes_gcm_copy_state(struct crypto_authenc_ctx *dst_ctx,
+ struct crypto_authenc_ctx *src_ctx)
{
- memcpy(dst_ctx, src_ctx, sizeof(struct internal_aes_gcm_ctx));
+ to_aes_gcm_ctx(dst_ctx)->ctx = to_aes_gcm_ctx(src_ctx)->ctx;
}
-TEE_Result crypto_aes_gcm_init(void *c, TEE_OperationMode mode,
+static TEE_Result aes_gcm_init(struct crypto_authenc_ctx *aec,
+ 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 tag_len, size_t aad_len __unused,
+ size_t payload_len __unused)
{
- return internal_aes_gcm_init(c, mode, key, key_len, nonce, nonce_len,
- tag_len);
+ return internal_aes_gcm_init(&to_aes_gcm_ctx(aec)->ctx, mode, key,
+ key_len, nonce, nonce_len, tag_len);
}
-TEE_Result crypto_aes_gcm_update_aad(void *c, const uint8_t *data, size_t len)
+static TEE_Result aes_gcm_update_aad(struct crypto_authenc_ctx *aec,
+ const uint8_t *data, size_t len)
{
- return internal_aes_gcm_update_aad(c, data, len);
+ return internal_aes_gcm_update_aad(&to_aes_gcm_ctx(aec)->ctx, data,
+ len);
}
-TEE_Result crypto_aes_gcm_update_payload(void *c, TEE_OperationMode m,
+static TEE_Result aes_gcm_update_payload(struct crypto_authenc_ctx *aec,
+ TEE_OperationMode m,
const uint8_t *src, size_t len,
uint8_t *dst)
{
- return internal_aes_gcm_update_payload(c, m, src, len, dst);
+ return internal_aes_gcm_update_payload(&to_aes_gcm_ctx(aec)->ctx,
+ m, src, len, dst);
}
-TEE_Result crypto_aes_gcm_enc_final(void *c, const uint8_t *src, size_t len,
+static TEE_Result aes_gcm_enc_final(struct crypto_authenc_ctx *aec,
+ const uint8_t *src, size_t len,
uint8_t *dst, uint8_t *tag, size_t *tag_len)
{
- return internal_aes_gcm_enc_final(c, src, len, dst, tag, tag_len);
+ return internal_aes_gcm_enc_final(&to_aes_gcm_ctx(aec)->ctx, src, len,
+ dst, tag, tag_len);
}
-TEE_Result crypto_aes_gcm_dec_final(void *c, const uint8_t *src, size_t len,
+static TEE_Result aes_gcm_dec_final(struct crypto_authenc_ctx *aec,
+ const uint8_t *src, size_t len,
uint8_t *dst, const uint8_t *tag,
size_t tag_len)
{
- return internal_aes_gcm_dec_final(c, src, len, dst, tag, tag_len);
+ return internal_aes_gcm_dec_final(&to_aes_gcm_ctx(aec)->ctx, src, len,
+ dst, tag, tag_len);
}
-void crypto_aes_gcm_final(void *c __unused)
+static void aes_gcm_final(struct crypto_authenc_ctx *aec __unused)
{
}
+
+static const struct crypto_authenc_ops aes_gcm_ops = {
+ .init = aes_gcm_init,
+ .update_aad = aes_gcm_update_aad,
+ .update_payload = aes_gcm_update_payload,
+ .enc_final = aes_gcm_enc_final,
+ .dec_final = aes_gcm_dec_final,
+ .final = aes_gcm_final,
+ .free_ctx = aes_gcm_free_ctx,
+ .copy_state = aes_gcm_copy_state,
+};
#endif /*!CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB*/
diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c
index 32123a2d..a536046f 100644
--- a/core/crypto/crypto.c
+++ b/core/crypto/crypto.c
@@ -5,8 +5,6 @@
#include <assert.h>
#include <compiler.h>
-#include <crypto/aes-ccm.h>
-#include <crypto/aes-gcm.h>
#include <crypto/crypto.h>
#include <crypto/crypto_impl.h>
#include <kernel/panic.h>
@@ -294,214 +292,113 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo __unused,
TEE_Result crypto_authenc_alloc_ctx(void **ctx, uint32_t algo)
{
- switch (algo) {
-#if defined(CFG_CRYPTO_CCM)
- case TEE_ALG_AES_CCM:
- return crypto_aes_ccm_alloc_ctx(ctx);
-#endif
-#if defined(CFG_CRYPTO_GCM)
- case TEE_ALG_AES_GCM:
- return crypto_aes_gcm_alloc_ctx(ctx);
-#endif
- default:
- return TEE_ERROR_NOT_IMPLEMENTED;
- }
-}
+ TEE_Result res = TEE_SUCCESS;
+ struct crypto_authenc_ctx *c = NULL;
-void crypto_authenc_free_ctx(void *ctx, uint32_t algo)
-{
switch (algo) {
#if defined(CFG_CRYPTO_CCM)
case TEE_ALG_AES_CCM:
- crypto_aes_ccm_free_ctx(ctx);
+ res = crypto_aes_ccm_alloc_ctx(&c);
break;
#endif
#if defined(CFG_CRYPTO_GCM)
case TEE_ALG_AES_GCM:
- crypto_aes_gcm_free_ctx(ctx);
+ res = crypto_aes_gcm_alloc_ctx(&c);
break;
#endif
default:
- if (ctx)
- assert(0);
+ return TEE_ERROR_NOT_IMPLEMENTED;
}
+
+ if (!res)
+ *ctx = c;
+
+ return res;
}
-void crypto_authenc_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo)
+static const struct crypto_authenc_ops *ae_ops(void *ctx)
{
- switch (algo) {
-#if defined(CFG_CRYPTO_CCM)
- case TEE_ALG_AES_CCM:
- crypto_aes_ccm_copy_state(dst_ctx, src_ctx);
- break;
-#endif
-#if defined(CFG_CRYPTO_GCM)
- case TEE_ALG_AES_GCM:
- crypto_aes_gcm_copy_state(dst_ctx, src_ctx);
- break;
-#endif
- default:
- assert(0);
- }
+ struct crypto_authenc_ctx *c = ctx;
+
+ assert(c && c->ops);
+
+ return c->ops;
}
-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)
+TEE_Result crypto_authenc_init(void *ctx, uint32_t algo __unused,
+ 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)
{
- 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;
- }
+ return ae_ops(ctx)->init(ctx, mode, key, key_len, nonce, nonce_len,
+ tag_len, aad_len, payload_len);
}
-TEE_Result crypto_authenc_update_aad(void *ctx __maybe_unused,
- uint32_t algo __maybe_unused,
+TEE_Result crypto_authenc_update_aad(void *ctx, uint32_t algo __unused,
TEE_OperationMode mode __unused,
- const uint8_t *data __maybe_unused,
- size_t len __maybe_unused)
+ const uint8_t *data, size_t len)
{
- 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;
- }
+ return ae_ops(ctx)->update_aad(ctx, data, len);
}
-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)
+TEE_Result crypto_authenc_update_payload(void *ctx, uint32_t algo __unused,
+ TEE_OperationMode mode,
+ const uint8_t *src_data,
+ size_t src_len, uint8_t *dst_data,
+ size_t *dst_len)
+{
+ if (*dst_len < src_len)
return TEE_ERROR_SHORT_BUFFER;
+ *dst_len = src_len;
- 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;
- }
+ return ae_ops(ctx)->update_payload(ctx, mode, src_data, src_len,
+ dst_data);
}
-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)
+TEE_Result crypto_authenc_enc_final(void *ctx, uint32_t algo __unused,
+ 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)
{
- size_t dl = *dst_len;
-
- *dst_len = src_len;
- if (dl < src_len)
+ if (*dst_len < src_len)
return TEE_ERROR_SHORT_BUFFER;
+ *dst_len = src_len;
- 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;
- }
+ return ae_ops(ctx)->enc_final(ctx, src_data, src_len, dst_data,
+ dst_tag, dst_tag_len);
}
-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)
+TEE_Result crypto_authenc_dec_final(void *ctx, uint32_t algo __unused,
+ 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)
{
- size_t dl = *dst_len;
-
- *dst_len = src_len;
- if (dl < src_len)
+ if (*dst_len < src_len)
return TEE_ERROR_SHORT_BUFFER;
+ *dst_len = src_len;
- 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;
- }
+ return ae_ops(ctx)->dec_final(ctx, src_data, src_len, dst_data, tag,
+ tag_len);
}
-void crypto_authenc_final(void *ctx __maybe_unused,
- uint32_t algo __maybe_unused)
+void crypto_authenc_final(void *ctx, uint32_t algo __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;
- }
+ ae_ops(ctx)->final(ctx);
+}
+
+void crypto_authenc_free_ctx(void *ctx, uint32_t algo __unused)
+{
+ if (ctx)
+ ae_ops(ctx)->free_ctx(ctx);
+}
+
+void crypto_authenc_copy_state(void *dst_ctx, void *src_ctx,
+ uint32_t algo __unused)
+{
+ ae_ops(dst_ctx)->copy_state(dst_ctx, src_ctx);
}
#if !defined(_CFG_CRYPTO_WITH_ACIPHER)
diff --git a/core/include/crypto/aes-ccm.h b/core/include/crypto/aes-ccm.h
deleted file mode 100644
index 365c6550..00000000
--- a/core/include/crypto/aes-ccm.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (c) 2017, Linaro Limited
- */
-
-#ifndef __CRYPTO_AES_CCM_H
-#define __CRYPTO_AES_CCM_H
-
-#include <tee_api_types.h>
-
-TEE_Result crypto_aes_ccm_alloc_ctx(void **ctx);
-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);
-void crypto_aes_ccm_free_ctx(void *ctx);
-void crypto_aes_ccm_copy_state(void *dst_ctx, void *src_ctx);
-
-#endif /*__CRYPTO_AES_CCM_H*/
-
diff --git a/core/include/crypto/aes-gcm.h b/core/include/crypto/aes-gcm.h
deleted file mode 100644
index f67fe1ea..00000000
--- a/core/include/crypto/aes-gcm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * Copyright (c) 2017, Linaro Limited
- */
-
-#ifndef __CRYPTO_AES_GCM_H
-#define __CRYPTO_AES_GCM_H
-
-#include <tee_api_types.h>
-
-TEE_Result crypto_aes_gcm_alloc_ctx(void **ctx);
-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);
-void crypto_aes_gcm_free_ctx(void *ctx);
-void crypto_aes_gcm_copy_state(void *dst_ctx, void *src_ctx);
-
-#endif /*__CRYPTO_AES_GCM_H*/
diff --git a/core/include/crypto/crypto_impl.h b/core/include/crypto/crypto_impl.h
index dc07a72e..1ae9e7a3 100644
--- a/core/include/crypto/crypto_impl.h
+++ b/core/include/crypto/crypto_impl.h
@@ -194,4 +194,42 @@ TEE_Result crypto_des3_cbc_alloc_ctx(struct crypto_cipher_ctx **ctx);
CRYPTO_ALLOC_CTX_NOT_IMPLEMENTED(des_cbc, cipher)
CRYPTO_ALLOC_CTX_NOT_IMPLEMENTED(des3_cbc, cipher)
#endif
+
+/*
+ * The crypto context used by the crypto_authen_*() functions below is
+ * defined by struct crypto_authenc_ctx.
+ */
+struct crypto_authenc_ctx {
+ const struct crypto_authenc_ops *ops;
+};
+
+struct crypto_authenc_ops {
+ TEE_Result (*init)(struct crypto_authenc_ctx *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 (*update_aad)(struct crypto_authenc_ctx *ctx,
+ const uint8_t *data, size_t len);
+ TEE_Result (*update_payload)(struct crypto_authenc_ctx *ctx,
+ TEE_OperationMode mode,
+ const uint8_t *src_data, size_t len,
+ uint8_t *dst_data);
+ TEE_Result (*enc_final)(struct crypto_authenc_ctx *ctx,
+ const uint8_t *src_data, size_t len,
+ uint8_t *dst_data, uint8_t *dst_tag,
+ size_t *dst_tag_len);
+ TEE_Result (*dec_final)(struct crypto_authenc_ctx *ctx,
+ const uint8_t *src_data, size_t len,
+ uint8_t *dst_data, const uint8_t *tag,
+ size_t tag_len);
+ void (*final)(struct crypto_authenc_ctx *ctx);
+ void (*free_ctx)(struct crypto_authenc_ctx *ctx);
+ void (*copy_state)(struct crypto_authenc_ctx *dst_ctx,
+ struct crypto_authenc_ctx *src_ctx);
+};
+
+TEE_Result crypto_aes_ccm_alloc_ctx(struct crypto_authenc_ctx **ctx);
+TEE_Result crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx **ctx);
#endif /*__CRYPTO_CRYPTO_IMPL_H*/
diff --git a/core/lib/libtomcrypt/ccm.c b/core/lib/libtomcrypt/ccm.c
new file mode 100644
index 00000000..a7c06b9c
--- /dev/null
+++ b/core/lib/libtomcrypt/ccm.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2014-2019, Linaro Limited
+ */
+
+#include <assert.h>
+#include <crypto/crypto.h>
+#include <crypto/crypto_impl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tee_api_types.h>
+#include <tomcrypt.h>
+#include <util.h>
+
+#define TEE_CCM_KEY_MAX_LENGTH 32
+#define TEE_CCM_NONCE_MAX_LENGTH 13
+#define TEE_CCM_TAG_MAX_LENGTH 16
+
+struct tee_ccm_state {
+ struct crypto_authenc_ctx aectx;
+ ccm_state ctx; /* the ccm state as defined by LTC */
+ size_t tag_len; /* tag length */
+};
+
+static const struct crypto_authenc_ops aes_ccm_ops;
+
+TEE_Result crypto_aes_ccm_alloc_ctx(struct crypto_authenc_ctx **ctx_ret)
+{
+ struct tee_ccm_state *ctx = calloc(1, sizeof(*ctx));
+
+ if (!ctx)
+ return TEE_ERROR_OUT_OF_MEMORY;
+ ctx->aectx.ops = &aes_ccm_ops;
+
+ *ctx_ret = &ctx->aectx;
+ return TEE_SUCCESS;
+}
+
+static struct tee_ccm_state *to_tee_ccm_state(struct crypto_authenc_ctx *aectx)
+{
+ assert(aectx && aectx->ops == &aes_ccm_ops);
+
+ return container_of(aectx, struct tee_ccm_state, aectx);
+}
+
+static void crypto_aes_ccm_free_ctx(struct crypto_authenc_ctx *aectx)
+{
+ free(to_tee_ccm_state(aectx));
+}
+
+static void crypto_aes_ccm_copy_state(struct crypto_authenc_ctx *dst_aectx,
+ struct crypto_authenc_ctx *src_aectx)
+{
+ struct tee_ccm_state *dst_ctx = to_tee_ccm_state(dst_aectx);
+ struct tee_ccm_state *src_ctx = to_tee_ccm_state(src_aectx);
+
+ dst_ctx->ctx = src_ctx->ctx;
+ dst_ctx->tag_len = src_ctx->tag_len;
+}
+
+static TEE_Result crypto_aes_ccm_init(struct crypto_authenc_ctx *aectx,
+ 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,
+ size_t payload_len)
+{
+ int ltc_res = 0;
+ int ltc_cipherindex = find_cipher("aes");
+ struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
+
+ if (ltc_cipherindex < 0)
+ return TEE_ERROR_NOT_SUPPORTED;
+
+ /* reset the state */
+ memset(&ccm->ctx, 0, sizeof(ccm->ctx));
+ ccm->tag_len = tag_len;
+
+ /* Check the key length */
+ if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH))
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ /* check the nonce */
+ if (nonce_len > TEE_CCM_NONCE_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;
+
+ 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;
+
+ /* Add the IV */
+ ltc_res = ccm_add_nonce(&ccm->ctx, nonce, nonce_len);
+ if (ltc_res != CRYPT_OK)
+ return TEE_ERROR_BAD_STATE;
+
+ return TEE_SUCCESS;
+}
+
+static TEE_Result crypto_aes_ccm_update_aad(struct crypto_authenc_ctx *aectx,
+ const uint8_t *data, size_t len)
+{
+ struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
+ int ltc_res = 0;
+
+ /* 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;
+}
+
+static TEE_Result
+crypto_aes_ccm_update_payload(struct crypto_authenc_ctx *aectx,
+ TEE_OperationMode mode, const uint8_t *src_data,
+ size_t len, uint8_t *dst_data)
+{
+ int ltc_res = 0;
+ int dir = 0;
+ struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
+ unsigned char *pt = NULL;
+ unsigned char *ct = NULL;
+
+ 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;
+}
+
+static TEE_Result crypto_aes_ccm_enc_final(struct crypto_authenc_ctx *aectx,
+ const uint8_t *src_data,
+ size_t len, uint8_t *dst_data,
+ uint8_t *dst_tag,
+ size_t *dst_tag_len)
+{
+ TEE_Result res = TEE_SUCCESS;
+ struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
+ int ltc_res = 0;
+
+ /* Finalize the remaining buffer */
+ res = crypto_aes_ccm_update_payload(aectx, 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;
+}
+
+static TEE_Result crypto_aes_ccm_dec_final(struct crypto_authenc_ctx *aectx,
+ 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 = to_tee_ccm_state(aectx);
+ int ltc_res = 0;
+ uint8_t dst_tag[TEE_CCM_TAG_MAX_LENGTH] = { 0 };
+ 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(aectx, 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, &ltc_tag_len);
+ if (ltc_res != CRYPT_OK)
+ return TEE_ERROR_BAD_STATE;
+
+ if (consttime_memcmp(dst_tag, tag, tag_len) != 0)
+ res = TEE_ERROR_MAC_INVALID;
+ else
+ res = TEE_SUCCESS;
+ return res;
+}
+
+static void crypto_aes_ccm_final(struct crypto_authenc_ctx *aectx)
+{
+ ccm_reset(&to_tee_ccm_state(aectx)->ctx);
+}
+
+static const struct crypto_authenc_ops aes_ccm_ops = {
+ .init = crypto_aes_ccm_init,
+ .update_aad = crypto_aes_ccm_update_aad,
+ .update_payload = crypto_aes_ccm_update_payload,
+ .enc_final = crypto_aes_ccm_enc_final,
+ .dec_final = crypto_aes_ccm_dec_final,
+ .final = crypto_aes_ccm_final,
+ .free_ctx = crypto_aes_ccm_free_ctx,
+ .copy_state = crypto_aes_ccm_copy_state,
+};
diff --git a/core/lib/libtomcrypt/gcm.c b/core/lib/libtomcrypt/gcm.c
new file mode 100644
index 00000000..5f22cb87
--- /dev/null
+++ b/core/lib/libtomcrypt/gcm.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2014-2019, Linaro Limited
+ */
+
+#include <assert.h>
+#include <crypto/crypto.h>
+#include <crypto/crypto_impl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tee_api_types.h>
+#include <tomcrypt.h>
+#include <util.h>
+
+#define TEE_GCM_TAG_MAX_LENGTH 16
+
+struct tee_gcm_state {
+ struct crypto_authenc_ctx aectx;
+ gcm_state ctx; /* the gcm state as defined by LTC */
+ size_t tag_len; /* tag length */
+};
+
+static const struct crypto_authenc_ops aes_gcm_ops;
+
+static struct tee_gcm_state *to_tee_gcm_state(struct crypto_authenc_ctx *aectx)
+{
+ assert(aectx && aectx->ops == &aes_gcm_ops);
+
+ return container_of(aectx, struct tee_gcm_state, aectx);
+}
+
+TEE_Result crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx **ctx_ret)
+{
+ struct tee_gcm_state *ctx = calloc(1, sizeof(*ctx));
+
+ if (!ctx)
+ return TEE_ERROR_OUT_OF_MEMORY;
+ ctx->aectx.ops = &aes_gcm_ops;
+
+ *ctx_ret = &ctx->aectx;
+
+ return TEE_SUCCESS;
+}
+
+static void crypto_aes_gcm_free_ctx(struct crypto_authenc_ctx *aectx)
+{
+ free(to_tee_gcm_state(aectx));
+}
+
+static void crypto_aes_gcm_copy_state(struct crypto_authenc_ctx *dst_aectx,
+ struct crypto_authenc_ctx *src_aectx)
+{
+ struct tee_gcm_state *dst_ctx = to_tee_gcm_state(dst_aectx);
+ struct tee_gcm_state *src_ctx = to_tee_gcm_state(src_aectx);
+
+ dst_ctx->ctx = src_ctx->ctx;
+ dst_ctx->tag_len = src_ctx->tag_len;
+}
+
+static TEE_Result crypto_aes_gcm_init(struct crypto_authenc_ctx *aectx,
+ 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 __unused,
+ size_t payload_len __unused)
+{
+ int ltc_res = 0;
+ int ltc_cipherindex = find_cipher("aes");
+ struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
+
+ if (ltc_cipherindex < 0)
+ return TEE_ERROR_NOT_SUPPORTED;
+
+ /* reset the state */
+ memset(&gcm->ctx, 0, sizeof(gcm->ctx));
+ 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;
+}
+
+static TEE_Result crypto_aes_gcm_update_aad(struct crypto_authenc_ctx *aectx,
+ const uint8_t *data, size_t len)
+{
+ struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
+ int ltc_res = 0;
+
+ /* 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;
+}
+
+static TEE_Result
+crypto_aes_gcm_update_payload(struct crypto_authenc_ctx *aectx,
+ TEE_OperationMode mode, const uint8_t *src_data,
+ size_t len, uint8_t *dst_data)
+{
+ TEE_Result res = TEE_SUCCESS;
+ int ltc_res = 0;
+ int dir = 0;
+ struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
+ unsigned char *pt = NULL;
+ unsigned char *ct = NULL;
+
+ 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;
+ }
+
+ /* aad is optional ==> add one without length */
+ if (gcm->ctx.mode == LTC_GCM_MODE_IV) {
+ res = crypto_aes_gcm_update_aad(aectx, 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;
+}
+
+static TEE_Result crypto_aes_gcm_enc_final(struct crypto_authenc_ctx *aectx,
+ const uint8_t *src_data, size_t len,
+ uint8_t *dst_data, uint8_t *dst_tag,
+ size_t *dst_tag_len)
+{
+ TEE_Result res = TEE_SUCCESS;
+ struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
+ int ltc_res = 0;
+
+ /* Finalize the remaining buffer */
+ res = crypto_aes_gcm_update_payload(aectx, TEE_MODE_ENCRYPT, src_data,
+ len, dst_data);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ /* Check the tag length */
+ if (*dst_tag_len < gcm->tag_len) {
+ *dst_tag_len = gcm->tag_len;
+ 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;
+}
+
+static TEE_Result crypto_aes_gcm_dec_final(struct crypto_authenc_ctx *aectx,
+ 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_gcm_state *gcm = to_tee_gcm_state(aectx);
+ int ltc_res = 0;
+ uint8_t dst_tag[TEE_GCM_TAG_MAX_LENGTH] = { 0 };
+ unsigned long ltc_tag_len = tag_len;
+
+ if (tag_len == 0)
+ return TEE_ERROR_SHORT_BUFFER;
+ if (tag_len > TEE_GCM_TAG_MAX_LENGTH)
+ return TEE_ERROR_BAD_STATE;
+
+ /* Process the last buffer, if any */
+ res = crypto_aes_gcm_update_payload(aectx, TEE_MODE_DECRYPT, src_data,
+ len, dst_data);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ /* Finalize the authentication */
+ ltc_res = gcm_done(&gcm->ctx, dst_tag, &ltc_tag_len);
+ if (ltc_res != CRYPT_OK)
+ return TEE_ERROR_BAD_STATE;
+
+ if (consttime_memcmp(dst_tag, tag, tag_len) != 0)
+ res = TEE_ERROR_MAC_INVALID;
+ else
+ res = TEE_SUCCESS;
+ return res;
+}
+
+static void crypto_aes_gcm_final(struct crypto_authenc_ctx *aectx)
+{
+ gcm_reset(&to_tee_gcm_state(aectx)->ctx);
+}
+
+static const struct crypto_authenc_ops aes_gcm_ops = {
+ .init = crypto_aes_gcm_init,
+ .update_aad = crypto_aes_gcm_update_aad,
+ .update_payload = crypto_aes_gcm_update_payload,
+ .enc_final = crypto_aes_gcm_enc_final,
+ .dec_final = crypto_aes_gcm_dec_final,
+ .final = crypto_aes_gcm_final,
+ .free_ctx = crypto_aes_gcm_free_ctx,
+ .copy_state = crypto_aes_gcm_copy_state,
+};
diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c
index 40df474f..cae91b7d 100644
--- a/core/lib/libtomcrypt/src/tee_ltc_provider.c
+++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c
@@ -4,8 +4,6 @@
*/
#include <assert.h>
-#include <crypto/aes-ccm.h>
-#include <crypto/aes-gcm.h>
#include <crypto/crypto.h>
#include <kernel/panic.h>
#include <stdlib.h>
@@ -198,60 +196,6 @@ static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex)
}
#endif /* defined(CFG_CRYPTO_RSA) */
-#if defined(CFG_CRYPTO_CCM) || defined(CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB)
-/*
- * Compute the LibTomCrypt "cipherindex" given a TEE Algorithm "algo"
- * Return
- * - TEE_SUCCESS in case of success,
- * - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo
- * - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC
- * Return -1 in case of error
- */
-static TEE_Result tee_algo_to_ltc_cipherindex(uint32_t algo,
- int *ltc_cipherindex)
-{
- switch (algo) {
-#if defined(CFG_CRYPTO_AES)
- case TEE_ALG_AES_CBC_MAC_NOPAD:
- case TEE_ALG_AES_CBC_MAC_PKCS5:
- case TEE_ALG_AES_CMAC:
- case TEE_ALG_AES_ECB_NOPAD:
- case TEE_ALG_AES_CBC_NOPAD:
- case TEE_ALG_AES_CTR:
- case TEE_ALG_AES_CTS:
- case TEE_ALG_AES_XTS:
- case TEE_ALG_AES_CCM:
- case TEE_ALG_AES_GCM:
- *ltc_cipherindex = find_cipher("aes");
- break;
-#endif
-#if defined(CFG_CRYPTO_DES)
- case TEE_ALG_DES_CBC_MAC_NOPAD:
- case TEE_ALG_DES_CBC_MAC_PKCS5:
- case TEE_ALG_DES_ECB_NOPAD:
- case TEE_ALG_DES_CBC_NOPAD:
- *ltc_cipherindex = find_cipher("des");
- break;
-
- case TEE_ALG_DES3_CBC_MAC_NOPAD:
- case TEE_ALG_DES3_CBC_MAC_PKCS5:
- case TEE_ALG_DES3_ECB_NOPAD:
- case TEE_ALG_DES3_CBC_NOPAD:
- *ltc_cipherindex = find_cipher("3des");
- break;
-#endif
- default:
- return TEE_ERROR_BAD_PARAMETERS;
- }
-
- if (*ltc_cipherindex < 0)
- return TEE_ERROR_NOT_SUPPORTED;
- else
- return TEE_SUCCESS;
-}
-#endif /* defined(CFG_CRYPTO_CCM) ||
- defined(CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB) */
-
/******************************************************************************
* Asymmetric algorithms
******************************************************************************/
@@ -1440,369 +1384,6 @@ out:
#endif /* _CFG_CRYPTO_WITH_ACIPHER */
-/******************************************************************************
- * Authenticated encryption
- ******************************************************************************/
-
-#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
-
-#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 */
-};
-
-TEE_Result crypto_aes_ccm_alloc_ctx(void **ctx_ret)
-{
- struct tee_ccm_state *ctx = calloc(1, sizeof(*ctx));
-
- if (!ctx)
- return TEE_ERROR_OUT_OF_MEMORY;
-
- *ctx_ret = ctx;
- return TEE_SUCCESS;
-}
-
-void crypto_aes_ccm_free_ctx(void *ctx)
-{
- free(ctx);
-}
-
-void crypto_aes_ccm_copy_state(void *dst_ctx, void *src_ctx)
-{
- memcpy(dst_ctx, src_ctx, sizeof(struct tee_ccm_state));
-}
-
-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,
- size_t payload_len)
-{
- TEE_Result res;
- int ltc_res;
- int ltc_cipherindex;
- struct tee_ccm_state *ccm = ctx;
-
- res = tee_algo_to_ltc_cipherindex(TEE_ALG_AES_CCM, &ltc_cipherindex);
- if (res != TEE_SUCCESS)
- return TEE_ERROR_NOT_SUPPORTED;
-
- /* reset the state */
- 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;
-
- /* check the nonce */
- if (nonce_len > TEE_CCM_NONCE_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;
-
- 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;
-
- /* Add the IV */
- ltc_res = ccm_add_nonce(&ccm->ctx, nonce, nonce_len);
- if (ltc_res != CRYPT_OK)
- return TEE_ERROR_BAD_STATE;
-
- 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_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 res;
- struct tee_ccm_state *ccm = ctx;
- int ltc_res;
-
- /* 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, &ltc_tag_len);
- if (ltc_res != CRYPT_OK)
- return TEE_ERROR_BAD_STATE;
-
- if (consttime_memcmp(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_AES_GCM_FROM_CRYPTOLIB)
-struct tee_gcm_state {
- gcm_state ctx; /* the gcm state as defined by LTC */
- size_t tag_len; /* tag length */
-};
-
-TEE_Result crypto_aes_gcm_alloc_ctx(void **ctx_ret)
-{
- struct tee_gcm_state *ctx = calloc(1, sizeof(*ctx));
-
- if (!ctx)
- return TEE_ERROR_OUT_OF_MEMORY;
-
- *ctx_ret = ctx;
- return TEE_SUCCESS;
-}
-
-void crypto_aes_gcm_free_ctx(void *ctx)
-{
- free(ctx);
-}
-
-void crypto_aes_gcm_copy_state(void *dst_ctx, void *src_ctx)
-{
- memcpy(dst_ctx, src_ctx, 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, &ltc_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_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 len, uint8_t *dst_data)
-{
- TEE_Result res;
- int ltc_res, dir;
- 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;
- }
-
- /* 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_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;
- struct tee_gcm_state *gcm = ctx;
- int ltc_res;
-
- /* Finalize the remaining buffer */
- res = crypto_aes_gcm_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 < gcm->tag_len) {
- *dst_tag_len = gcm->tag_len;
- 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_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;
- struct tee_gcm_state *gcm = ctx;
- int ltc_res;
- 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_GCM_TAG_MAX_LENGTH)
- return TEE_ERROR_BAD_STATE;
-
- /* Process the last buffer, if any */
- res = crypto_aes_gcm_update_payload(ctx, TEE_MODE_DECRYPT, src_data,
- len, dst_data);
- if (res != TEE_SUCCESS)
- return res;
-
- /* Finalize the authentication */
- ltc_res = gcm_done(&gcm->ctx, dst_tag, &ltc_tag_len);
- if (ltc_res != CRYPT_OK)
- return TEE_ERROR_BAD_STATE;
-
- if (consttime_memcmp(dst_tag, tag, tag_len) != 0)
- res = TEE_ERROR_MAC_INVALID;
- else
- res = TEE_SUCCESS;
- return res;
-}
-
-void crypto_aes_gcm_final(void *ctx)
-{
- struct tee_gcm_state *gcm = ctx;
-
- gcm_reset(&gcm->ctx);
-}
-#endif /*CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB*/
-
TEE_Result crypto_init(void)
{
init_mp_tomcrypt();
diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk
index 04637457..e9ed3841 100644
--- a/core/lib/libtomcrypt/sub.mk
+++ b/core/lib/libtomcrypt/sub.mk
@@ -14,3 +14,5 @@ srcs-$(CFG_CRYPTO_CBC) += cbc.c
srcs-$(CFG_CRYPTO_CTS) += cts.c
srcs-$(CFG_CRYPTO_CTR) += ctr.c
srcs-$(CFG_CRYPTO_XTS) += xts.c
+srcs-$(CFG_CRYPTO_CCM) += ccm.c
+srcs-$(CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB) += gcm.c