diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 2e6020e62..add7fb19f 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -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; } diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index ffef6b050..d306d068f 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -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; }