From a116848b51a2d071827dad4a46ec98a5316631d2 Mon Sep 17 00:00:00 2001 From: Valerii Chubar Date: Fri, 12 Aug 2022 08:35:11 +0000 Subject: [PATCH] core: libtomcrypt: add Ed25519 support Enable Ed25519 implementation of libtomcrypt and add the OP-TEE wrappers. Signed-off-by: Valerii Chubar Signed-off-by: Sergiy Kibrik Reviewed-by: Jerome Forissier Acked-by: Etienne Carriere Acked-by: Jens Wiklander --- core/crypto/crypto.c | 58 +++++++ core/include/crypto/crypto.h | 25 +++ core/lib/libtomcrypt/ed25519.c | 179 +++++++++++++++++++++ core/lib/libtomcrypt/src/pk/ec25519/sub.mk | 1 + core/lib/libtomcrypt/src/pk/ed25519/sub.mk | 7 + core/lib/libtomcrypt/src/pk/sub.mk | 2 + core/lib/libtomcrypt/sub.mk | 3 + 7 files changed, 275 insertions(+) create mode 100644 core/lib/libtomcrypt/ed25519.c create mode 100644 core/lib/libtomcrypt/src/pk/ed25519/sub.mk diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 4a892b4a5e3..fd2a3bf57b0 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -825,6 +825,64 @@ TEE_Result crypto_acipher_x25519_shared_secret(struct x25519_keypair } #endif +#if !defined(CFG_CRYPTO_ED25519) +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key + __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key __unused, + size_t key_size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_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_ed25519_verify(struct ed25519_keypair *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_ed25519ctx_sign(struct ed25519_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused, + bool ph_flag __unused, + const uint8_t *ctx __unused, + size_t ctxlen __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key + __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused, + bool ph_flag __unused, + const uint8_t *ctx __unused, + size_t ctxlen __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif + __weak void crypto_storage_obj_del(uint8_t *data __unused, size_t len __unused) { } diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 4257bfe548c..98ebf0275c7 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -172,6 +172,11 @@ struct x25519_keypair { uint8_t *pub; /* Public value */ }; +struct ed25519_keypair { + uint8_t *priv; + uint8_t *pub; +}; + /* * Key allocation functions * Allocate the bignum's inside a key structure. @@ -198,6 +203,8 @@ TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s); TEE_Result crypto_acipher_alloc_x25519_keypair(struct x25519_keypair *s, size_t key_size_bits); +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *s, + size_t key_size_bits); /* * Key generation functions @@ -209,6 +216,24 @@ TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, struct bignum *q, TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key, size_t key_size); TEE_Result crypto_acipher_gen_x25519_key(struct x25519_keypair *key, size_t key_size); +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key, + size_t key_size); +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); +TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen); +TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len); +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen); TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, struct bignum *public_key, diff --git a/core/lib/libtomcrypt/ed25519.c b/core/lib/libtomcrypt/ed25519.c new file mode 100644 index 00000000000..b85629b869f --- /dev/null +++ b/core/lib/libtomcrypt/ed25519.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022, Technology Innovation Institute (TII) + * Copyright (c) 2022, EPAM Systems + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "acipher_helpers.h" + +#define ED25519_KEY_SIZE UL(256) + +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key, + size_t key_size) +{ + if (!key || key_size != ED25519_KEY_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + + memset(key, 0, sizeof(*key)); + + key->priv = calloc(1, key_size >> 3); + key->pub = calloc(1, key_size >> 3); + + if (!key->priv || !key->pub) { + free(key->priv); + free(key->pub); + return TEE_ERROR_OUT_OF_MEMORY; + } + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key, + size_t key_size) +{ + curve25519_key ltc_tmp_key = { }; + + if (key_size != ED25519_KEY_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + + if (ed25519_make_key(NULL, find_prng("prng_crypto"), + <c_tmp_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + + assert(key_size >= sizeof(ltc_tmp_key.pub) && + key_size >= sizeof(ltc_tmp_key.priv)); + + memcpy(key->pub, ltc_tmp_key.pub, sizeof(ltc_tmp_key.pub)); + memcpy(key->priv, ltc_tmp_key.priv, sizeof(ltc_tmp_key.priv)); + memzero_explicit(<c_tmp_key, sizeof(ltc_tmp_key)); + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + int err; + unsigned long siglen; + curve25519_key private_key = { + .type = PK_PRIVATE, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(private_key.priv, key->priv, sizeof(private_key.priv)); + memcpy(private_key.pub, key->pub, sizeof(private_key.pub)); + + err = ed25519_sign(msg, msg_len, sig, &siglen, &private_key); + + memzero_explicit(&private_key, sizeof(private_key)); + + if (err != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + *sig_len = siglen; + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen) +{ + int err = CRYPT_ERROR; + unsigned long siglen; + curve25519_key private_key = { + .type = PK_PRIVATE, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(private_key.priv, key->priv, sizeof(private_key.priv)); + memcpy(private_key.pub, key->pub, sizeof(private_key.pub)); + + if (ph_flag) { + err = ed25519ph_sign(msg, msg_len, sig, &siglen, + ctx, ctxlen, &private_key); + } else { + err = ed25519ctx_sign(msg, msg_len, sig, &siglen, + ctx, ctxlen, &private_key); + } + + memzero_explicit(&private_key, sizeof(private_key)); + + if (err != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + *sig_len = siglen; + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) +{ + int stat = 0; + curve25519_key public_key = { + .type = PK_PUBLIC, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(public_key.pub, key->pub, sizeof(public_key.pub)); + + if (ed25519_verify(msg, msg_len, sig, sig_len, &stat, + &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + + if (stat != 1) + return TEE_ERROR_SIGNATURE_INVALID; + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen) +{ + int stat = 0; + curve25519_key public_key = { + .type = PK_PUBLIC, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(public_key.pub, key->pub, sizeof(public_key.pub)); + + if (ph_flag) { + if (ed25519ph_verify(msg, msg_len, sig, sig_len, ctx, ctxlen, + &stat, &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + } else { + if (ed25519ctx_verify(msg, msg_len, sig, sig_len, ctx, ctxlen, + &stat, &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + } + + if (stat != 1) + return TEE_ERROR_SIGNATURE_INVALID; + + return TEE_SUCCESS; +} diff --git a/core/lib/libtomcrypt/src/pk/ec25519/sub.mk b/core/lib/libtomcrypt/src/pk/ec25519/sub.mk index e3d07c0e04b..5040c391ce0 100644 --- a/core/lib/libtomcrypt/src/pk/ec25519/sub.mk +++ b/core/lib/libtomcrypt/src/pk/ec25519/sub.mk @@ -1,2 +1,3 @@ +srcs-y += ec25519_crypto_ctx.c srcs-y += ec25519_export.c srcs-y += tweetnacl.c diff --git a/core/lib/libtomcrypt/src/pk/ed25519/sub.mk b/core/lib/libtomcrypt/src/pk/ed25519/sub.mk new file mode 100644 index 00000000000..cb2206dabec --- /dev/null +++ b/core/lib/libtomcrypt/src/pk/ed25519/sub.mk @@ -0,0 +1,7 @@ +srcs-y += ed25519_export.c +srcs-y += ed25519_import.c +srcs-y += ed25519_import_pkcs8.c +srcs-y += ed25519_import_x509.c +srcs-y += ed25519_make_key.c +srcs-y += ed25519_sign.c +srcs-y += ed25519_verify.c diff --git a/core/lib/libtomcrypt/src/pk/sub.mk b/core/lib/libtomcrypt/src/pk/sub.mk index 968c63b5368..dca26a50a05 100644 --- a/core/lib/libtomcrypt/src/pk/sub.mk +++ b/core/lib/libtomcrypt/src/pk/sub.mk @@ -7,3 +7,5 @@ subdirs-$(_CFG_CORE_LTC_DH) += dh subdirs-$(_CFG_CORE_LTC_ECC) += ecc subdirs-$(_CFG_CORE_LTC_X25519) += ec25519 subdirs-$(_CFG_CORE_LTC_X25519) += x25519 +subdirs-$(_CFG_CORE_LTC_ED25519) += ec25519 +subdirs-$(_CFG_CORE_LTC_ED25519) += ed25519 diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk index b4de4f80bb5..941d4f0119b 100644 --- a/core/lib/libtomcrypt/sub.mk +++ b/core/lib/libtomcrypt/sub.mk @@ -95,6 +95,7 @@ ifeq ($(_CFG_CORE_LTC_ECC),y) cppflags-lib-y += -DLTC_ECC256 cppflags-lib-y += -DLTC_ECC384 cppflags-lib-y += -DLTC_ECC521 + cppflags-lib-y += -DLTC_CURVE25519 # ECC 521 bits is the max supported key size cppflags-lib-y += -DLTC_MAX_ECC=521 @@ -104,6 +105,7 @@ ifneq (,$(filter y,$(_CFG_CORE_LTC_SM2_DSA) $(_CFG_CORE_LTC_SM2_PKE))) endif cppflags-lib-$(_CFG_CORE_LTC_X25519) += -DLTC_CURVE25519 +cppflags-lib-$(_CFG_CORE_LTC_ED25519) += -DLTC_CURVE25519 cppflags-lib-y += -DLTC_NO_PRNGS -DLTC_FORTUNA @@ -134,6 +136,7 @@ srcs-$(_CFG_CORE_LTC_SM2_DSA) += sm2-dsa.c srcs-$(_CFG_CORE_LTC_SM2_PKE) += sm2-pke.c srcs-$(_CFG_CORE_LTC_SM2_KEP) += sm2-kep.c srcs-$(_CFG_CORE_LTC_X25519) += x25519.c +srcs-$(_CFG_CORE_LTC_ED25519) += ed25519.c ifeq ($(_CFG_CORE_LTC_ACIPHER),y) srcs-y += mpi_desc.c endif