-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -172,6 +172,11 @@ struct x25519_keypair { | |
uint8_t *pub; /* Public value */ | ||
}; | ||
|
||
struct ed25519_keypair { | ||
uint8_t *priv; | ||
uint8_t *pub; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uint8_t *priv; /* Private value */
uint8_t *pub; /* Public value */ for consistency? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it was agreed with @jforissier to be unnecessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
}; | ||
|
||
/* | ||
* 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, | ||
|
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)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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));
(...) There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"), | ||
<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); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done in a850e12 for private keys. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} |
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 |
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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