Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support Ed25519 sign/verify scheme #5486

Merged
merged 3 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions core/crypto.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ CFG_CRYPTO_ECC ?= y
CFG_CRYPTO_SM2_PKE ?= y
CFG_CRYPTO_SM2_DSA ?= y
CFG_CRYPTO_SM2_KEP ?= y
# X25519 is only supported by libtomcrypt
# X25519 and Ed25519 are only supported by libtomcrypt
ifeq ($(CFG_CRYPTOLIB_NAME),tomcrypt)
CFG_CRYPTO_ED25519 ?= y
CFG_CRYPTO_X25519 ?= y
endif

Expand Down Expand Up @@ -167,7 +168,7 @@ core-ltc-vars += SIZE_OPTIMIZATION
core-ltc-vars += SM2_PKE
core-ltc-vars += SM2_DSA
core-ltc-vars += SM2_KEP
core-ltc-vars += X25519
core-ltc-vars += ED25519 X25519
# Assigned selected CFG_CRYPTO_xxx as _CFG_CORE_LTC_xxx
$(foreach v, $(core-ltc-vars), $(eval _CFG_CORE_LTC_$(v) := $(CFG_CRYPTO_$(v))))
_CFG_CORE_LTC_MPI := $(CFG_CORE_MBEDTLS_MPI)
Expand All @@ -192,6 +193,7 @@ _CFG_CORE_LTC_XTS := $(CFG_CRYPTO_XTS)
_CFG_CORE_LTC_CCM := $(CFG_CRYPTO_CCM)
_CFG_CORE_LTC_AES_DESC := $(call cfg-one-enabled, CFG_CRYPTO_XTS CFG_CRYPTO_CCM)
$(call force,CFG_CRYPTO_X25519,n,not supported by mbedtls)
$(call force,CFG_CRYPTO_ED25519,n,not supported by mbedtls)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already plumbing in crypto.mk to include parts of tomcrypt to get full cipher support when using mbedtls. I would prefer that 25519 is available regardless of the chosen crypto library.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larperaxis that would be nice indeed but since CFG_CRYPTO_X25519 already excludes mbedtls, that should be handled in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larperaxis @jforissier then I shall make a separate PR for this, thank you for taking a look

endif

###############################################################
Expand Down Expand Up @@ -232,7 +234,7 @@ _CFG_CORE_LTC_HASH := $(call ltc-one-enabled, MD5 SHA1 SHA224 SHA256 SHA384 \
_CFG_CORE_LTC_MAC := $(call ltc-one-enabled, HMAC CMAC CBC_MAC)
_CFG_CORE_LTC_CBC := $(call ltc-one-enabled, CBC CBC_MAC)
_CFG_CORE_LTC_ASN1 := $(call ltc-one-enabled, RSA DSA ECC)
_CFG_CORE_LTC_EC25519 := $(call ltc-one-enabled, X25519)
_CFG_CORE_LTC_EC25519 := $(call ltc-one-enabled, ED25519 X25519)

###############################################################
# Platform independent crypto-driver configuration
Expand Down
58 changes: 58 additions & 0 deletions core/crypto/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
25 changes: 25 additions & 0 deletions core/include/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ struct x25519_keypair {
uint8_t *pub; /* Public value */
};

struct ed25519_keypair {
uint8_t *priv;
uint8_t *pub;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	uint8_t *priv;	/* Private value */
	uint8_t *pub;	/* Public value */

for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was agreed with @jforissier to be unnecessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

};

/*
* Key allocation functions
* Allocate the bignum's inside a key structure.
Expand All @@ -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
Expand All @@ -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,
Expand Down
179 changes: 179 additions & 0 deletions core/lib/libtomcrypt/ed25519.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2022, Technology Innovation Institute (TII)
* Copyright (c) 2022, EPAM Systems
*/

#include <crypto/crypto.h>
#include <stdlib.h>
#include <string.h>
#include <string_ext.h>
#include <tee_api_types.h>
#include <trace.h>
#include <utee_defines.h>

#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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor suggestion:

	if (!key || key_size_bytes != ED25519_KEY_SIZE_BYTES)
		return TEE_ERROR_BAD_PARAMETERS;

	memset(key, 0, sizeof(*key));

	(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's even nicer w/o this variable, refactored in a850e12


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"),
&ltc_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(&ltc_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);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memset_explicit(private_key.priv, 0, ...) upon error?
(if so, should be also handled above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in a850e12 for private keys.
Shall it be done for public keys in crypto_acipher_ed25519_verify() as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public key content is not that sensible. I think it's not worth wiping its content.

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;
}
1 change: 1 addition & 0 deletions core/lib/libtomcrypt/src/pk/ec25519/sub.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
srcs-y += ec25519_crypto_ctx.c
srcs-y += ec25519_export.c
srcs-y += tweetnacl.c
7 changes: 7 additions & 0 deletions core/lib/libtomcrypt/src/pk/ed25519/sub.mk
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions core/lib/libtomcrypt/src/pk/sub.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions core/lib/libtomcrypt/sub.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
Loading