Skip to content

Commit

Permalink
core: crypto: add Ed25519 support
Browse files Browse the repository at this point in the history
Put in place Ed25519 core functionality and support it for
OP-TEE crypto syscalls.

Signed-off-by: Valerii Chubar <[email protected]>
Signed-off-by: Sergiy Kibrik <[email protected]>
  • Loading branch information
Valerii Chubar authored and sa-kib committed Aug 15, 2022
1 parent d549aab commit 10a9fdd
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 3 deletions.
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)
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
57 changes: 57 additions & 0 deletions core/crypto/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,63 @@ 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,
uint8_t flag __unused,
const uint8_t *ctx __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,
uint8_t flag __unused,
const uint8_t *ctx __unused)
{
return TEE_ERROR_NOT_IMPLEMENTED;
}

#endif

__weak void crypto_storage_obj_del(uint8_t *data __unused, size_t len __unused)
{
}
23 changes: 23 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; /* Private value */
uint8_t *pub; /* Public value */
};

/*
* 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,22 @@ 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,
uint8_t flag, const uint8_t *ctx);
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,
uint8_t flag, const uint8_t *ctx);

TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key,
struct bignum *public_key,
Expand Down
176 changes: 176 additions & 0 deletions core/tee/tee_svc_cryp.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,33 @@ const struct tee_cryp_obj_type_attrs tee_cryp_obj_x25519_keypair_attrs[] = {
},
};

static
const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_pub_key_attrs[] = {
{
.attr_id = TEE_ATTR_ED25519_PUBLIC_VALUE,
.flags = TEE_TYPE_ATTR_REQUIRED,
.ops_index = ATTR_OPS_INDEX_25519,
RAW_DATA(struct ed25519_keypair, pub)
},
};

static
const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_keypair_attrs[] = {
{
.attr_id = TEE_ATTR_ED25519_PRIVATE_VALUE,
.flags = TEE_TYPE_ATTR_REQUIRED,
.ops_index = ATTR_OPS_INDEX_25519,
RAW_DATA(struct ed25519_keypair, priv)
},

{
.attr_id = TEE_ATTR_ED25519_PUBLIC_VALUE,
.flags = TEE_TYPE_ATTR_REQUIRED,
.ops_index = ATTR_OPS_INDEX_25519,
RAW_DATA(struct ed25519_keypair, pub)
},
};

struct tee_cryp_obj_type_props {
TEE_ObjectType obj_type;
uint16_t min_size; /* may not be smaller than this */
Expand Down Expand Up @@ -578,6 +605,14 @@ static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = {
PROP(TEE_TYPE_X25519_KEYPAIR, 1, 256, 256,
sizeof(struct x25519_keypair),
tee_cryp_obj_x25519_keypair_attrs),

PROP(TEE_TYPE_ED25519_PUBLIC_KEY, 1, 256, 256,
sizeof(struct ed25519_keypair),
tee_cryp_obj_ed25519_pub_key_attrs),

PROP(TEE_TYPE_ED25519_KEYPAIR, 1, 256, 256,
sizeof(struct ed25519_keypair),
tee_cryp_obj_ed25519_keypair_attrs),
};

struct attr_ops {
Expand Down Expand Up @@ -1343,6 +1378,9 @@ TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src)
} else if (o->info.objectType == TEE_TYPE_SM2_KEP_PUBLIC_KEY) {
if (src->info.objectType != TEE_TYPE_SM2_KEP_KEYPAIR)
return TEE_ERROR_BAD_PARAMETERS;
} else if (o->info.objectType == TEE_TYPE_ED25519_PUBLIC_KEY) {
if (src->info.objectType != TEE_TYPE_ED25519_KEYPAIR)
return TEE_ERROR_BAD_PARAMETERS;
} else {
return TEE_ERROR_BAD_PARAMETERS;
}
Expand Down Expand Up @@ -1476,6 +1514,11 @@ TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type,
res = crypto_acipher_alloc_x25519_keypair(o->attr,
max_key_size);
break;
case TEE_TYPE_ED25519_KEYPAIR:
case TEE_TYPE_ED25519_PUBLIC_KEY:
res = crypto_acipher_alloc_ed25519_keypair(o->attr,
max_key_size);
break;
default:
if (obj_type != TEE_TYPE_DATA) {
struct tee_cryp_obj_secret *key = o->attr;
Expand Down Expand Up @@ -2095,6 +2138,114 @@ tee_svc_obj_generate_key_x25519(struct tee_obj *o,
return TEE_SUCCESS;
}

static TEE_Result
tee_svc_obj_generate_key_ed25519(struct tee_obj *o,
const struct tee_cryp_obj_type_props
*type_props,
uint32_t key_size,
const TEE_Attribute *params,
uint32_t param_count)
{
TEE_Result res = TEE_ERROR_GENERIC;
struct ed25519_keypair *tee_ed25519_key = NULL;

/* Copy the present attributes into the obj before starting */
res = tee_svc_cryp_obj_populate_type(o, type_props, params,
param_count);
if (res != TEE_SUCCESS)
return res;

tee_ed25519_key = (struct ed25519_keypair *)o->attr;

res = crypto_acipher_gen_ed25519_key(tee_ed25519_key, key_size);
if (res != TEE_SUCCESS)
return res;

/* Set bits for the generated public and private key */
set_attribute(o, type_props, TEE_ATTR_ED25519_PRIVATE_VALUE);
set_attribute(o, type_props, TEE_ATTR_ED25519_PUBLIC_VALUE);
return TEE_SUCCESS;
}

static TEE_Result
tee_svc_obj_ed25519_sign(struct ed25519_keypair *key,
const uint8_t *msg, size_t msg_len,
uint8_t *sig, size_t *sig_len,
const TEE_Attribute *params, size_t num_params)
{
size_t n;
size_t ctx_len;
uint8_t ctx[256] = {0};
uint8_t ph_flag = 0;
uint8_t cx_flag = 0;

for (n = 0u; n < num_params; n++) {
switch (params[n].attributeID) {
case TEE_ATTR_EDDSA_PREHASH:
ph_flag = 1;
break;

case TEE_ATTR_EDDSA_CTX:
cx_flag = 1;
ctx_len = params[n].content.ref.length;
if (ctx_len > 255)
return TEE_ERROR_BAD_PARAMETERS;

memcpy(ctx, params[n].content.ref.buffer, ctx_len);
ctx[ctx_len] = 0;
break;

default:
return TEE_ERROR_BAD_PARAMETERS;
}
}

if (ph_flag || cx_flag)
return crypto_acipher_ed25519ctx_sign(key, msg, msg_len, sig,
sig_len, ph_flag, ctx);

return crypto_acipher_ed25519_sign(key, msg, msg_len, sig, sig_len);
}

static TEE_Result
tee_svc_obj_ed25519_verify(struct ed25519_keypair *key,
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len,
const TEE_Attribute *params, size_t num_params)
{
size_t n;
size_t ctx_len;
uint8_t ctx[256] = {0};
uint8_t ph_flag = 0;
uint8_t cx_flag = 0;

for (n = 0u; n < num_params; n++) {
switch (params[n].attributeID) {
case TEE_ATTR_EDDSA_PREHASH:
ph_flag = 1;
break;

case TEE_ATTR_EDDSA_CTX:
cx_flag = 1;
ctx_len = params[n].content.ref.length;
if (ctx_len > 255)
return TEE_ERROR_BAD_PARAMETERS;

memcpy(ctx, params[n].content.ref.buffer, ctx_len);
ctx[ctx_len] = 0;
break;

default:
return TEE_ERROR_BAD_PARAMETERS;
}
}
if (ph_flag || cx_flag)
return crypto_acipher_ed25519ctx_verify(key, msg, msg_len, sig,
sig_len, ph_flag, ctx);

return crypto_acipher_ed25519_verify(key, msg, msg_len, sig, sig_len);
}

TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size,
const struct utee_attribute *usr_params,
unsigned long param_count)
Expand Down Expand Up @@ -2224,6 +2375,13 @@ TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size,
goto out;
break;

case TEE_TYPE_ED25519_KEYPAIR:
res = tee_svc_obj_generate_key_ed25519(o, type_props, key_size,
params, param_count);
if (res != TEE_SUCCESS)
goto out;
break;

default:
res = TEE_ERROR_BAD_FORMAT;
}
Expand Down Expand Up @@ -2348,6 +2506,11 @@ static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o,
case TEE_MAIN_ALGO_ECDH:
req_key_type = TEE_TYPE_ECDH_KEYPAIR;
break;
case TEE_MAIN_ALGO_ED25519:
req_key_type = TEE_TYPE_ED25519_KEYPAIR;
if (mode == TEE_MODE_VERIFY)
req_key_type2 = TEE_TYPE_ED25519_PUBLIC_KEY;
break;
case TEE_MAIN_ALGO_SM2_PKE:
if (mode == TEE_MODE_ENCRYPT)
req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY;
Expand Down Expand Up @@ -3969,6 +4132,13 @@ TEE_Result syscall_asymm_operate(unsigned long state,
res = crypto_acipher_dsa_sign(cs->algo, o->attr, src_data,
src_len, dst_data, &dlen);
break;

case TEE_ALG_ED25519:
res = tee_svc_obj_ed25519_sign(o->attr, src_data, src_len,
dst_data, &dlen, params,
num_params);
break;

case TEE_ALG_ECDSA_P192:
case TEE_ALG_ECDSA_P224:
case TEE_ALG_ECDSA_P256:
Expand Down Expand Up @@ -4115,6 +4285,12 @@ TEE_Result syscall_asymm_verify(unsigned long state,
data_len, sig, sig_len);
break;

case TEE_MAIN_ALGO_ED25519:
res = tee_svc_obj_ed25519_verify(o->attr, data,
data_len, sig, sig_len,
params, num_params);
break;

case TEE_MAIN_ALGO_ECDSA:
case TEE_MAIN_ALGO_SM2_DSA_SM3:
res = crypto_acipher_ecc_verify(cs->algo, o->attr, data,
Expand Down

0 comments on commit 10a9fdd

Please sign in to comment.