Ed25519/448: improvements

Check lengths of buffers in import functions.
priv/pub key set flag set on success only.
This commit is contained in:
Sean Parkinson
2022-07-05 09:02:05 +10:00
parent bb68766bda
commit 4a962b7fb2
2 changed files with 50 additions and 42 deletions

View File

@@ -950,7 +950,7 @@ int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
int trusted)
{
int ret;
int ret = 0;
/* sanity check on arguments */
if (in == NULL || key == NULL)
@@ -961,7 +961,7 @@ int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
/* compressed prefix according to draft
http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
if (in[0] == 0x40 && inLen > ED25519_PUB_KEY_SIZE) {
if (in[0] == 0x40 && inLen == ED25519_PUB_KEY_SIZE + 1) {
/* key is stored in compressed format so just copy in */
XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
#ifdef FREESCALE_LTC_ECC
@@ -971,16 +971,9 @@ int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
pubKey.Y = key->pointY;
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
#endif
key->pubKeySet = 1;
if (key->privKeySet && (!trusted)) {
return wc_ed25519_check_key(key);
}
return 0;
}
/* importing uncompressed public key */
if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
else if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
#ifdef FREESCALE_LTC_ECC
/* reverse bytes for little endian byte order */
for (int i = 0; i < ED25519_KEY_SIZE; i++)
@@ -989,24 +982,15 @@ int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
}
XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
key->pubKeySet = 1;
ret = 0;
#else
/* pass in (x,y) and store compressed key */
ret = ge_compress_key(key->p, in+1,
in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
if (ret == 0)
key->pubKeySet = 1;
#endif /* FREESCALE_LTC_ECC */
if ((ret == 0) && key->privKeySet && (!trusted)) {
return wc_ed25519_check_key(key);
}
return ret;
}
/* if not specified compressed or uncompressed check key size
if key size is equal to compressed key size copy in key */
if (inLen == ED25519_PUB_KEY_SIZE) {
else if (inLen == ED25519_PUB_KEY_SIZE) {
XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
#ifdef FREESCALE_LTC_ECC
/* recover X coordinate */
@@ -1015,15 +999,23 @@ int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
pubKey.Y = key->pointY;
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
#endif
}
else {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
key->pubKeySet = 1;
if (key->privKeySet && (!trusted)) {
return wc_ed25519_check_key(key);
ret = wc_ed25519_check_key(key);
}
return 0;
}
if (ret != 0) {
key->pubKeySet = 0;
}
/* bad public key format */
return BAD_FUNC_ARG;
return ret;
}
/*
@@ -1043,12 +1035,14 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
ed25519_key* key)
{
int ret = 0;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED25519_KEY_SIZE)
if (privSz != ED25519_KEY_SIZE)
return BAD_FUNC_ARG;
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
@@ -1056,10 +1050,13 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
if (key->pubKeySet) {
/* Validate loaded public key */
return wc_ed25519_check_key(key);
ret = wc_ed25519_check_key(key);
}
if (ret != 0) {
key->privKeySet = 0;
}
return 0;
return ret;
}
@@ -1081,24 +1078,25 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key, int trusted)
{
int ret;
int ret;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED25519_KEY_SIZE)
if (privSz != ED25519_KEY_SIZE && privSz != ED25519_PRV_KEY_SIZE)
return BAD_FUNC_ARG;
if (pub == NULL) {
if (pubSz != 0)
return BAD_FUNC_ARG;
if (privSz < ED25519_PRV_KEY_SIZE)
if (privSz != ED25519_PRV_KEY_SIZE)
return BAD_FUNC_ARG;
pub = priv + ED25519_KEY_SIZE;
pubSz = ED25519_PUB_KEY_SIZE;
} else if (pubSz < ED25519_PUB_KEY_SIZE) {
}
else if (pubSz < ED25519_PUB_KEY_SIZE) {
return BAD_FUNC_ARG;
}

View File

@@ -913,7 +913,7 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
ret = BAD_FUNC_ARG;
}
if (inLen < ED448_PUB_KEY_SIZE) {
if (inLen != ED448_PUB_KEY_SIZE) {
ret = BAD_FUNC_ARG;
}
@@ -923,20 +923,16 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) {
/* key is stored in compressed format so just copy in */
XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
key->pubKeySet = 1;
}
/* importing uncompressed public key */
else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
/* pass in (x,y) and store compressed key */
ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE);
if (ret == 0)
key->pubKeySet = 1;
}
else if (inLen == ED448_PUB_KEY_SIZE) {
/* if not specified compressed or uncompressed check key size
* if key size is equal to compressed key size copy in key */
XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
key->pubKeySet = 1;
}
else {
/* bad public key format */
@@ -944,9 +940,17 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
}
}
if ((ret == 0) && key->privKeySet && (!trusted)) {
/* Check untrusted public key data matches private key. */
ret = wc_ed448_check_key(key);
if (ret == 0) {
key->pubKeySet = 1;
if (key->privKeySet && (!trusted)) {
/* Check untrusted public key data matches private key. */
ret = wc_ed448_check_key(key);
}
}
if ((ret != 0) && (key != NULL)) {
/* No public key set on failure. */
key->pubKeySet = 0;
}
return ret;
@@ -988,7 +992,7 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
}
/* key size check */
if ((ret == 0) && (privSz < ED448_KEY_SIZE)) {
if ((ret == 0) && (privSz != ED448_KEY_SIZE)) {
ret = BAD_FUNC_ARG;
}
@@ -1002,6 +1006,11 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
ret = wc_ed448_check_key(key);
}
if ((ret != 0) && (key != NULL)) {
/* No private key set on error. */
key->privKeySet = 0;
}
return ret;
}
@@ -1030,17 +1039,18 @@ int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED448_KEY_SIZE)
if (privSz != ED448_KEY_SIZE && privSz != ED448_PRV_KEY_SIZE)
return BAD_FUNC_ARG;
if (pub == NULL) {
if (pubSz != 0)
return BAD_FUNC_ARG;
if (privSz < ED448_PRV_KEY_SIZE)
if (privSz != ED448_PRV_KEY_SIZE)
return BAD_FUNC_ARG;
pub = priv + ED448_KEY_SIZE;
pubSz = ED448_PUB_KEY_SIZE;
} else if (pubSz < ED448_PUB_KEY_SIZE) {
}
else if (pubSz < ED448_PUB_KEY_SIZE) {
return BAD_FUNC_ARG;
}