forked from wolfSSL/wolfssl
Ed25519/448: improvements
Check lengths of buffers in import functions. priv/pub key set flag set on success only.
This commit is contained in:
@@ -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 wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
|
||||||
int trusted)
|
int trusted)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (in == NULL || key == NULL)
|
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
|
/* compressed prefix according to draft
|
||||||
http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
|
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 */
|
/* key is stored in compressed format so just copy in */
|
||||||
XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
|
XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
|
||||||
#ifdef FREESCALE_LTC_ECC
|
#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;
|
pubKey.Y = key->pointY;
|
||||||
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
|
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
|
||||||
#endif
|
#endif
|
||||||
key->pubKeySet = 1;
|
|
||||||
|
|
||||||
if (key->privKeySet && (!trusted)) {
|
|
||||||
return wc_ed25519_check_key(key);
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* importing uncompressed public key */
|
/* 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
|
#ifdef FREESCALE_LTC_ECC
|
||||||
/* reverse bytes for little endian byte order */
|
/* reverse bytes for little endian byte order */
|
||||||
for (int i = 0; i < ED25519_KEY_SIZE; i++)
|
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);
|
key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
|
||||||
}
|
}
|
||||||
XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
|
XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
|
||||||
key->pubKeySet = 1;
|
|
||||||
ret = 0;
|
|
||||||
#else
|
#else
|
||||||
/* pass in (x,y) and store compressed key */
|
/* pass in (x,y) and store compressed key */
|
||||||
ret = ge_compress_key(key->p, in+1,
|
ret = ge_compress_key(key->p, in+1,
|
||||||
in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
|
in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
|
||||||
if (ret == 0)
|
|
||||||
key->pubKeySet = 1;
|
|
||||||
#endif /* FREESCALE_LTC_ECC */
|
#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 not specified compressed or uncompressed check key size
|
||||||
if key size is equal to compressed key size copy in key */
|
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);
|
XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
|
||||||
#ifdef FREESCALE_LTC_ECC
|
#ifdef FREESCALE_LTC_ECC
|
||||||
/* recover X coordinate */
|
/* 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;
|
pubKey.Y = key->pointY;
|
||||||
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
|
LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
key->pubKeySet = 1;
|
key->pubKeySet = 1;
|
||||||
if (key->privKeySet && (!trusted)) {
|
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 */
|
/* 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,
|
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
|
||||||
ed25519_key* key)
|
ed25519_key* key)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (priv == NULL || key == NULL)
|
if (priv == NULL || key == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* key size check */
|
/* key size check */
|
||||||
if (privSz < ED25519_KEY_SIZE)
|
if (privSz != ED25519_KEY_SIZE)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
|
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) {
|
if (key->pubKeySet) {
|
||||||
/* Validate loaded public key */
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1088,17 +1085,18 @@ int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* key size check */
|
/* key size check */
|
||||||
if (privSz < ED25519_KEY_SIZE)
|
if (privSz != ED25519_KEY_SIZE && privSz != ED25519_PRV_KEY_SIZE)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (pub == NULL) {
|
if (pub == NULL) {
|
||||||
if (pubSz != 0)
|
if (pubSz != 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
if (privSz < ED25519_PRV_KEY_SIZE)
|
if (privSz != ED25519_PRV_KEY_SIZE)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
pub = priv + ED25519_KEY_SIZE;
|
pub = priv + ED25519_KEY_SIZE;
|
||||||
pubSz = ED25519_PUB_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;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -913,7 +913,7 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
|
|||||||
ret = BAD_FUNC_ARG;
|
ret = BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inLen < ED448_PUB_KEY_SIZE) {
|
if (inLen != ED448_PUB_KEY_SIZE) {
|
||||||
ret = BAD_FUNC_ARG;
|
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) {
|
if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) {
|
||||||
/* key is stored in compressed format so just copy in */
|
/* key is stored in compressed format so just copy in */
|
||||||
XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
|
XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
|
||||||
key->pubKeySet = 1;
|
|
||||||
}
|
}
|
||||||
/* importing uncompressed public key */
|
/* importing uncompressed public key */
|
||||||
else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
|
else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
|
||||||
/* pass in (x,y) and store compressed key */
|
/* pass in (x,y) and store compressed key */
|
||||||
ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE);
|
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) {
|
else if (inLen == ED448_PUB_KEY_SIZE) {
|
||||||
/* if not specified compressed or uncompressed check key size
|
/* if not specified compressed or uncompressed check key size
|
||||||
* if key size is equal to compressed key size copy in key */
|
* if key size is equal to compressed key size copy in key */
|
||||||
XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
|
XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
|
||||||
key->pubKeySet = 1;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* bad public key format */
|
/* bad public key format */
|
||||||
@@ -944,10 +940,18 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret == 0) && key->privKeySet && (!trusted)) {
|
if (ret == 0) {
|
||||||
|
key->pubKeySet = 1;
|
||||||
|
if (key->privKeySet && (!trusted)) {
|
||||||
/* Check untrusted public key data matches private key. */
|
/* Check untrusted public key data matches private key. */
|
||||||
ret = wc_ed448_check_key(key);
|
ret = wc_ed448_check_key(key);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret != 0) && (key != NULL)) {
|
||||||
|
/* No public key set on failure. */
|
||||||
|
key->pubKeySet = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -988,7 +992,7 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* key size check */
|
/* key size check */
|
||||||
if ((ret == 0) && (privSz < ED448_KEY_SIZE)) {
|
if ((ret == 0) && (privSz != ED448_KEY_SIZE)) {
|
||||||
ret = BAD_FUNC_ARG;
|
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);
|
ret = wc_ed448_check_key(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret != 0) && (key != NULL)) {
|
||||||
|
/* No private key set on error. */
|
||||||
|
key->privKeySet = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1030,17 +1039,18 @@ int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* key size check */
|
/* key size check */
|
||||||
if (privSz < ED448_KEY_SIZE)
|
if (privSz != ED448_KEY_SIZE && privSz != ED448_PRV_KEY_SIZE)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (pub == NULL) {
|
if (pub == NULL) {
|
||||||
if (pubSz != 0)
|
if (pubSz != 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
if (privSz < ED448_PRV_KEY_SIZE)
|
if (privSz != ED448_PRV_KEY_SIZE)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
pub = priv + ED448_KEY_SIZE;
|
pub = priv + ED448_KEY_SIZE;
|
||||||
pubSz = ED448_PUB_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;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user