Merge pull request #5311 from SparkiDev/ed_check_pubkey

Ed25519/Ed448: assume public key is not trusted
This commit is contained in:
David Garske
2022-07-05 09:25:50 -07:00
committed by GitHub
10 changed files with 450 additions and 119 deletions

View File

@@ -564,7 +564,8 @@ void wc_ed25519_free(ed25519_key* key);
\brief This function imports a public ed25519_key pair from a buffer
containing the public key. This function will handle both compressed and
uncompressed keys.
uncompressed keys. The public key is checked that it matches the private
key when one is present.
\return 0 Returned on successfully importing the ed25519_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or inLen is
@@ -588,12 +589,54 @@ void wc_ed25519_free(ed25519_key* key);
}
\endcode
\sa wc_ed25519_import_public_ex
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
\sa wc_ed25519_export_public
*/
int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);
/*!
\ingroup ED25519
\brief This function imports a public ed25519_key pair from a buffer
containing the public key. This function will handle both compressed and
uncompressed keys. Check public key matches private key, when present,
when not trusted.
\return 0 Returned on successfully importing the ed25519_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or inLen is
less than the size of an Ed25519 key.
\param [in] in Pointer to the buffer containing the public key.
\param [in] inLen Length of the buffer containing the public key.
\param [in,out] key Pointer to the ed25519_key object in which to store the
public key.
\param [in] trusted Public key data is trusted or not.
_Example_
\code
int ret;
byte pub[] = { initialize Ed25519 public key };
ed_25519 key;
wc_ed25519_init_key(&key);
ret = wc_ed25519_import_public_ex(pub, sizeof(pub), &key, 1);
if (ret != 0) {
// error importing key
}
\endcode
\sa wc_ed25519_import_public
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
\sa wc_ed25519_export_public
*/
int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
int trusted);
/*!
\ingroup ED25519
@@ -618,14 +661,16 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);
ed25519_key key;
wc_ed25519_init_key(&key);
ret = wc_ed25519_import_private_key(priv, sizeof(priv), &key);
ret = wc_ed25519_import_private_only(priv, sizeof(priv), &key);
if (ret != 0) {
// error importing private key
}
\endcode
\sa wc_ed25519_import_public
\sa wc_ed25519_import_public_ex
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
\sa wc_ed25519_export_private_only
*/
@@ -637,7 +682,8 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
\brief This function imports a public/private Ed25519 key pair from a
pair of buffers. This function will handle both compressed and
uncompressed keys.
uncompressed keys. The public key is assumed to be untrusted and is
checked against the private key.
\return 0 Returned on successfully importing the ed25519_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or if
@@ -667,13 +713,60 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
\endcode
\sa wc_ed25519_import_public
\sa wc_ed25519_import_public_ex
\sa wc_ed25519_import_private_only
\sa wc_ed25519_import_private_key_ex
\sa wc_ed25519_export_private
*/
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key);
/*!
\ingroup ED25519
\brief This function imports a public/private Ed25519 key pair from a
pair of buffers. This function will handle both compressed and
uncompressed keys. The public is checked against private key if not trusted.
\return 0 Returned on successfully importing the ed25519_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or if
either privSz is less than ED25519_KEY_SIZE or pubSz is less than
ED25519_PUB_KEY_SIZE.
\param [in] priv Pointer to the buffer containing the private key.
\param [in] privSz Length of the private key.
\param [in] pub Pointer to the buffer containing the public key.
\param [in] pubSz Length of the public key.
\param [in,out] key Pointer to the ed25519_key object in which to store the
imported private/public key pair.
\param [in] trusted Public key data is trusted or not.
_Example_
\code
int ret;
byte priv[] = { initialize with 32 byte private key };
byte pub[] = { initialize with the corresponding public key };
ed25519_key key;
wc_ed25519_init_key(&key);
ret = wc_ed25519_import_private_key(priv, sizeof(priv), pub, sizeof(pub),
&key, 1);
if (ret != 0) {
// error importing key
}
\endcode
\sa wc_ed25519_import_public
\sa wc_ed25519_import_public_ex
\sa wc_ed25519_import_private_only
\sa wc_ed25519_import_private_key
\sa wc_ed25519_export_private
*/
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key, int trusted);
/*!
\ingroup ED25519
@@ -710,6 +803,7 @@ int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
\endcode
\sa wc_ed25519_import_public
\sa wc_ed25519_import_public_ex
\sa wc_ed25519_export_private_only
*/
@@ -750,6 +844,7 @@ int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen);
\sa wc_ed25519_export_public
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
*/
int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen);
@@ -792,6 +887,7 @@ int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen);
\endcode
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
\sa wc_ed25519_export_private_only
*/
@@ -866,7 +962,8 @@ int wc_ed25519_export_key(ed25519_key* key,
ed25519_key key;
wc_ed25519_init_key(&key);
wc_ed25519_import_private_key(priv, sizeof(priv), pub, sizeof(pub), &key);
wc_ed25519_import_private_key_ex(priv, sizeof(priv), pub, sizeof(pub), &key,
1);
ret = wc_ed25519_check_key(&key);
if (ret != 0) {
// error checking key
@@ -874,6 +971,7 @@ int wc_ed25519_export_key(ed25519_key* key,
\endcode
\sa wc_ed25519_import_private_key
\sa wc_ed25519_import_private_key_ex
*/
int wc_ed25519_check_key(ed25519_key* key);

View File

@@ -447,7 +447,8 @@ void wc_ed448_free(ed448_key* key);
\brief This function imports a public ed448_key pair from a buffer
containing the public key. This function will handle both compressed and
uncompressed keys.
uncompressed keys. The public key is checked that it matches the private
key when one is present.
\return 0 Returned on successfully importing the ed448_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or inLen is
@@ -471,12 +472,54 @@ void wc_ed448_free(ed448_key* key);
}
\endcode
\sa wc_ed448_import_public_ex
\sa wc_ed448_import_private_key
\sa wc_ed448_import_private_key_ex
\sa wc_ed448_export_public
*/
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key);
/*!
\ingroup ED448
\brief This function imports a public ed448_key pair from a buffer
containing the public key. This function will handle both compressed and
uncompressed keys. Check public key matches private key, when present,
when not trusted.
\return 0 Returned on successfully importing the ed448_key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or inLen is
less than the size of an Ed448 key.
\param [in] in Pointer to the buffer containing the public key.
\param [in] inLen Length of the buffer containing the public key.
\param [in,out] key Pointer to the ed448_key object in which to store the
public key.
\param [in] trusted Public key data is trusted or not.
_Example_
\code
int ret;
byte pub[] = { initialize Ed448 public key };
ed_448 key;
wc_ed448_init_key(&key);
ret = wc_ed448_import_public_ex(pub, sizeof(pub), &key, 1);
if (ret != 0) {
// error importing key
}
\endcode
\sa wc_ed448_import_public
\sa wc_ed448_import_private_key
\sa wc_ed448_import_private_key_ex
\sa wc_ed448_export_public
*/
int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
int trusted);
/*!
\ingroup ED448
@@ -506,7 +549,9 @@ int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key);
\endcode
\sa wc_ed448_import_public
\sa wc_ed448_import_public_ex
\sa wc_ed448_import_private_key
\sa wc_ed448_import_private_key_ex
\sa wc_ed448_export_private_only
*/
@@ -548,13 +593,60 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
\endcode
\sa wc_ed448_import_public
\sa wc_ed448_import_public_ex
\sa wc_ed448_import_private_only
\sa wc_ed448_import_private_key_ex
\sa wc_ed448_export_private
*/
int wc_ed448_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key);
/*!
\ingroup ED448
\brief This function imports a public/private Ed448 key pair from a
pair of buffers. This function will handle both compressed and
uncompressed keys. The public is checked against private key if not trusted.
\return 0 Returned on successfully importing the Ed448 key.
\return BAD_FUNC_ARG Returned if in or key evaluate to NULL, or if
either privSz is less than ED448_KEY_SIZE or pubSz is less than
ED448_PUB_KEY_SIZE.
\param [in] priv Pointer to the buffer containing the private key.
\param [in] privSz Length of the private key.
\param [in] pub Pointer to the buffer containing the public key.
\param [in] pubSz Length of the public key.
\param [in,out] key Pointer to the ed448_key object in which to store the
imported private/public key pair.
\param [in] trusted Public key data is trusted or not.
_Example_
\code
int ret;
byte priv[] = { initialize with 57 byte private key };
byte pub[] = { initialize with the corresponding public key };
ed448_key key;
wc_ed448_init_key(&key);
ret = wc_ed448_import_private_key_ex(priv, sizeof(priv), pub, sizeof(pub),
&key, 1);
if (ret != 0) {
// error importing key
}
\endcode
\sa wc_ed448_import_public
\sa wc_ed448_import_public_ex
\sa wc_ed448_import_private_only
\sa wc_ed448_import_private_key
\sa wc_ed448_export_private
*/
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key, int trusted);
/*!
\ingroup ED448
@@ -591,6 +683,7 @@ int wc_ed448_import_private_key(const byte* priv, word32 privSz,
\endcode
\sa wc_ed448_import_public
\sa wc_ed448_import_public_ex
\sa wc_ed448_export_private_only
*/
@@ -631,6 +724,7 @@ int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen);
\sa wc_ed448_export_public
\sa wc_ed448_import_private_key
\sa wc_ed448_import_private_key_ex
*/
int wc_ed448_export_private_only(ed448_key* key, byte* out, word32* outLen);
@@ -747,7 +841,8 @@ int wc_ed448_export_key(ed448_key* key,
ed448_key key;
wc_ed448_init_key(&key);
wc_ed448_import_private_key(priv, sizeof(priv), pub, sizeof(pub), &key);
wc_ed448_import_private_key_ex(priv, sizeof(priv), pub, sizeof(pub), &key,
1);
ret = wc_ed448_check_key(&key);
if (ret != 0) {
// error checking key
@@ -755,6 +850,7 @@ int wc_ed448_export_key(ed448_key* key,
\endcode
\sa wc_ed448_import_private_key
\sa wc_ed448_import_private_key_ex
*/
int wc_ed448_check_key(ed448_key* key);

View File

@@ -21230,7 +21230,7 @@ static int test_wc_ed25519_import_public (void)
printf(testingFmt, "wc_ed25519_import_public()");
if (ret == 0) {
ret = wc_ed25519_import_public(in, inlen, &pubKey);
ret = wc_ed25519_import_public_ex(in, inlen, &pubKey, 1);
if (ret == 0 && XMEMCMP(in, pubKey.p, inlen) == 0) {
ret = 0;
@@ -21300,8 +21300,8 @@ static int test_wc_ed25519_import_private_key (void)
printf(testingFmt, "wc_ed25519_import_private_key()");
if (ret == 0) {
ret = wc_ed25519_import_private_key(privKey, privKeySz, pubKey,
pubKeySz, &key);
ret = wc_ed25519_import_private_key_ex(privKey, privKeySz, pubKey,
pubKeySz, &key, 1);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0
|| XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = WOLFSSL_FATAL_ERROR;
@@ -21313,7 +21313,8 @@ static int test_wc_ed25519_import_private_key (void)
ret = wc_ed25519_export_private(&key, bothKeys, &bothKeysSz);
if (ret == 0) {
ret = wc_ed25519_import_private_key(bothKeys, bothKeysSz, NULL, 0, &key);
ret = wc_ed25519_import_private_key_ex(bothKeys, bothKeysSz, NULL, 0,
&key, 1);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0
|| XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = WOLFSSL_FATAL_ERROR;
@@ -23051,7 +23052,7 @@ static int test_wc_ed448_import_public (void)
printf(testingFmt, "wc_ed448_import_public()");
if (ret == 0) {
ret = wc_ed448_import_public(in, inlen, &pubKey);
ret = wc_ed448_import_public_ex(in, inlen, &pubKey, 1);
if (ret == 0 && XMEMCMP(in, pubKey.p, inlen) == 0) {
ret = 0;
@@ -23123,8 +23124,8 @@ static int test_wc_ed448_import_private_key (void)
printf(testingFmt, "wc_ed448_import_private_key()");
if (ret == 0) {
ret = wc_ed448_import_private_key(privKey, privKeySz, pubKey, pubKeySz,
&key);
ret = wc_ed448_import_private_key_ex(privKey, privKeySz, pubKey,
pubKeySz, &key, 1);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0 ||
XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = WOLFSSL_FATAL_ERROR;
@@ -23136,7 +23137,8 @@ static int test_wc_ed448_import_private_key (void)
ret = wc_ed448_export_private(&key, bothKeys, &bothKeysSz);
if (ret == 0) {
ret = wc_ed448_import_private_key(bothKeys, bothKeysSz, NULL, 0, &key);
ret = wc_ed448_import_private_key_ex(bothKeys, bothKeysSz, NULL, 0,
&key, 1);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0 ||
XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = WOLFSSL_FATAL_ERROR;

View File

@@ -60,7 +60,7 @@ Possible ECC enable options:
* USE_ECC_B_PARAM: Enable ECC curve B param default: off
* (on for HAVE_COMP_KEY)
* WOLFSSL_ECC_CURVE_STATIC: default off (on for windows)
* For the ECC curve paramaters `ecc_set_type` use fixed
* For the ECC curve parameters `ecc_set_type` use fixed
* array for hex string
* WC_ECC_NONBLOCK: Enable non-blocking support for sign/verify.
* Requires SP with WOLFSSL_SP_NONBLOCK

View File

@@ -242,6 +242,7 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
/* put public key after private key, on the same buffer */
XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
key->privKeySet = 1;
key->pubKeySet = 1;
return ret;
@@ -941,13 +942,15 @@ int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
#ifdef HAVE_ED25519_KEY_IMPORT
/*
Imports a compressed/uncompressed public key.
in the byte array containing the public key
inLen the length of the byte array being passed in
key ed25519 key struct to put the public key in
in the byte array containing the public key
inLen the length of the byte array being passed in
key ed25519 key struct to put the public key in
trusted whether the public key is trusted to match private key if set
*/
int wc_ed25519_import_public(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 ret;
int ret = 0;
/* sanity check on arguments */
if (in == NULL || key == NULL)
@@ -958,7 +961,7 @@ int wc_ed25519_import_public(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
@@ -968,12 +971,9 @@ int wc_ed25519_import_public(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;
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++)
@@ -982,21 +982,15 @@ int wc_ed25519_import_public(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 */
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 */
@@ -1005,14 +999,35 @@ int wc_ed25519_import_public(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;
return 0;
if (key->privKeySet && (!trusted)) {
ret = wc_ed25519_check_key(key);
}
}
if (ret != 0) {
key->pubKeySet = 0;
}
/* bad public key format */
return BAD_FUNC_ARG;
return ret;
}
/*
Imports a compressed/uncompressed public key.
in the byte array containing the public key
inLen the length of the byte array being passed in
key ed25519 key struct to put the public key in
*/
int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
{
return wc_ed25519_import_public_ex(in, inLen, key, 0);
}
/*
For importing a private key.
@@ -1020,20 +1035,89 @@ 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);
key->privKeySet = 1;
return 0;
if (key->pubKeySet) {
/* Validate loaded public key */
ret = wc_ed25519_check_key(key);
}
if (ret != 0) {
key->privKeySet = 0;
ForceZero(key->k, ED25519_KEY_SIZE);
}
return ret;
}
/* Import an ed25519 private and public keys from byte array(s).
*
* priv [in] Array holding private key from
* wc_ed25519_export_private_only(), or private+public keys from
* wc_ed25519_export_private().
* privSz [in] Number of bytes of data in private key array.
* pub [in] Array holding public key (or NULL).
* pubSz [in] Number of bytes of data in public key array (or 0).
* key [in] Ed25519 private/public key.
* trusted [in] Indicates whether the public key data is trusted.
* When 0, checks public key matches private key.
* When 1, doesn't check public key matches private key.
* returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
* combination of keys/lengths is supplied, 0 otherwise.
*/
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key, int trusted)
{
int ret;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
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)
return BAD_FUNC_ARG;
pub = priv + ED25519_KEY_SIZE;
pubSz = ED25519_PUB_KEY_SIZE;
}
else if (pubSz < ED25519_PUB_KEY_SIZE) {
return BAD_FUNC_ARG;
}
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
key->privKeySet = 1;
/* import public key */
ret = wc_ed25519_import_public_ex(pub, pubSz, key, trusted);
if (ret != 0) {
key->privKeySet = 0;
ForceZero(key->k, ED25519_KEY_SIZE);
return ret;
}
/* make the private key (priv + pub) */
XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
return ret;
}
/* Import an ed25519 private and public keys from byte array(s).
*
* priv [in] Array holding private key from wc_ed25519_export_private_only(),
@@ -1046,41 +1130,10 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
* combination of keys/lengths is supplied, 0 otherwise.
*/
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key)
const byte* pub, word32 pubSz, ed25519_key* key)
{
int ret;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED25519_KEY_SIZE)
return BAD_FUNC_ARG;
if (pub == NULL) {
if (pubSz != 0)
return BAD_FUNC_ARG;
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) {
return BAD_FUNC_ARG;
}
/* import public key */
ret = wc_ed25519_import_public(pub, pubSz, key);
if (ret != 0)
return ret;
/* make the private key (priv + pub) */
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
return ret;
return wc_ed25519_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
}
#endif /* HAVE_ED25519_KEY_IMPORT */

View File

@@ -228,6 +228,7 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE);
}
if (ret == 0) {
key->privKeySet = 1;
ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE);
if (ret != 0) {
ForceZero(key->k, ED448_KEY_SIZE);
@@ -893,13 +894,17 @@ int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen)
/* Import a compressed or uncompressed ed448 public key from a byte array.
* Public key encoded in big-endian.
*
* in [in] Array holding public key.
* inLen [in] Number of bytes of data in array.
* key [in] Ed448 public key.
* in [in] Array holding public key.
* inLen [in] Number of bytes of data in array.
* key [in] Ed448 public key.
* trusted [in] Indicates whether the public key data is trusted.
* When 0, checks public key matches private key.
* When 1, doesn't check public key matches private key.
* returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
* 0 otherwise.
*/
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key)
int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
int trusted)
{
int ret = 0;
@@ -908,7 +913,7 @@ int wc_ed448_import_public(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;
}
@@ -918,20 +923,16 @@ int wc_ed448_import_public(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 */
@@ -939,9 +940,37 @@ int wc_ed448_import_public(const byte* in, word32 inLen, ed448_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;
}
/* Import a compressed or uncompressed ed448 public key from a byte array.
*
* Public key encoded in big-endian.
* Public key is not trusted and is checked against private key if set.
*
* in [in] Array holding public key.
* inLen [in] Number of bytes of data in array.
* key [in] Ed448 public key.
* returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
* 0 otherwise.
*/
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key)
{
return wc_ed448_import_public_ex(in, inLen, key, 0);
}
/* Import an ed448 private key from a byte array.
*
@@ -963,12 +992,24 @@ 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;
}
if (ret == 0) {
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
key->privKeySet = 1;
}
if ((ret == 0) && key->pubKeySet) {
/* Validate loaded public key */
ret = wc_ed448_check_key(key);
}
if ((ret != 0) && (key != NULL)) {
/* No private key set on error. */
key->privKeySet = 0;
ForceZero(key->k, ED448_KEY_SIZE);
}
return ret;
@@ -976,6 +1017,64 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
/* Import an ed448 private and public keys from byte array(s).
*
* priv [in] Array holding private key from wc_ed448_export_private_only(),
* or private+public keys from wc_ed448_export_private().
* privSz [in] Number of bytes of data in private key array.
* pub [in] Array holding public key (or NULL).
* pubSz [in] Number of bytes of data in public key array (or 0).
* key [in] Ed448 private/public key.
* trusted [in] Indicates whether the public key data is trusted.
* When 0, checks public key matches private key.
* When 1, doesn't check public key matches private key.
* returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
* combination of keys/lengths is supplied, 0 otherwise.
*/
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key, int trusted)
{
int ret;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
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)
return BAD_FUNC_ARG;
pub = priv + ED448_KEY_SIZE;
pubSz = ED448_PUB_KEY_SIZE;
}
else if (pubSz < ED448_PUB_KEY_SIZE) {
return BAD_FUNC_ARG;
}
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
key->privKeySet = 1;
/* import public key */
ret = wc_ed448_import_public_ex(pub, pubSz, key, trusted);
if (ret != 0) {
key->privKeySet = 0;
ForceZero(key->k, ED448_KEY_SIZE);
return ret;
}
/* make the private key (priv + pub) */
XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
return ret;
}
/* Import an ed448 private and public keys from byte array(s).
*
* Public key is not trusted and is checked against private key.
*
* priv [in] Array holding private key from wc_ed448_export_private_only(),
* or private+public keys from wc_ed448_export_private().
@@ -989,40 +1088,9 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
int wc_ed448_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key)
{
int ret;
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED448_KEY_SIZE)
return BAD_FUNC_ARG;
if (pub == NULL) {
if (pubSz != 0)
return BAD_FUNC_ARG;
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) {
return BAD_FUNC_ARG;
}
/* import public key */
ret = wc_ed448_import_public(pub, pubSz, key);
if (ret != 0)
return ret;
/* make the private key (priv + pub) */
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
return ret;
return wc_ed448_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
}
#endif /* HAVE_ED448_KEY_IMPORT */

View File

@@ -27352,7 +27352,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
if (wc_ed25519_export_public(&key, exportPKey, &exportPSz) != 0)
return -11051 - i;
if (wc_ed25519_import_public(exportPKey, exportPSz, &key2) != 0)
if (wc_ed25519_import_public_ex(exportPKey, exportPSz, &key2, 1) != 0)
return -11061 - i;
if (wc_ed25519_export_private_only(&key, exportSKey, &exportSSz) != 0)
@@ -28815,7 +28815,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
break;
}
if (wc_ed448_import_public(exportPKey, exportPSz, key2) != 0) {
if (wc_ed448_import_public_ex(exportPKey, exportPSz, key2, 1) != 0) {
ret = -11761 - i;
break;
}

View File

@@ -96,6 +96,7 @@ struct ed25519_key {
int keyId;
word32 flags;
#endif
word16 privKeySet:1;
word16 pubKeySet:1;
#ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev;
@@ -181,11 +182,17 @@ void wc_ed25519_free(ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
int trusted);
WOLFSSL_API
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key, int trusted);
#endif /* HAVE_ED25519_KEY_IMPORT */
#ifdef HAVE_ED25519_KEY_EXPORT

View File

@@ -86,6 +86,7 @@ struct ed448_key {
byte pointX[ED448_KEY_SIZE]; /* recovered X coordinate */
byte pointY[ED448_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */
#endif
word16 privKeySet:1;
word16 pubKeySet:1;
#ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev;
@@ -163,11 +164,17 @@ void wc_ed448_free(ed448_key* key);
WOLFSSL_API
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key);
WOLFSSL_API
int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
int trusted);
WOLFSSL_API
int wc_ed448_import_private_only(const byte* priv, word32 privSz,
ed448_key* key);
WOLFSSL_API
int wc_ed448_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key);
WOLFSSL_API
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key, int trusted);
#endif /* HAVE_ED448_KEY_IMPORT */
#ifdef HAVE_ED448_KEY_EXPORT

View File

@@ -44,8 +44,8 @@ decouple library dependencies with standard string, memory and so on.
/*
* This struct is used multiple time by other structs and
* needs to be defined somwhere that all structs can import
* (with minimal depencencies).
* needs to be defined somewhere that all structs can import
* (with minimal dependencies).
*/
#ifdef HAVE_EX_DATA
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
@@ -208,14 +208,14 @@ decouple library dependencies with standard string, memory and so on.
#elif defined(WC_16BIT_CPU)
#undef WORD64_AVAILABLE
typedef word16 wolfssl_word;
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as
mp_digit, no 64 bit type so make mp_digit 16 bit */
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \
* mp_digit, no 64 bit type so make mp_digit 16 bit */
#else
#undef WORD64_AVAILABLE
typedef word32 wolfssl_word;
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as
mp_digit, no 64 bit type so make mp_digit 16 bit */
#define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \
* mp_digit, no 64 bit type so make mp_digit 16 bit */
#endif
typedef struct w64wrapper {