Ed25519/Ed448: assume public key is not trusted

In defense against attack, assume the imported public key is not trusted
and check it matches the private key if set.
Added APIs that allow application to explicitly trust public key.
Original APIs default to not trusting public key.
This commit is contained in:
Sean Parkinson
2022-07-01 12:21:16 +10:00
committed by David Garske
parent 402a4dafd4
commit 2c943282f0
9 changed files with 350 additions and 45 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,11 +942,13 @@ 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;
@ -969,6 +972,10 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
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;
}
@ -991,6 +998,9 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
if (ret == 0)
key->pubKeySet = 1;
#endif /* FREESCALE_LTC_ECC */
if ((ret == 0) && key->privKeySet && (!trusted)) {
return wc_ed25519_check_key(key);
}
return ret;
}
@ -1006,6 +1016,9 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
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;
}
@ -1013,6 +1026,16 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
return BAD_FUNC_ARG;
}
/*
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.
@ -1029,6 +1052,7 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
return BAD_FUNC_ARG;
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
key->privKeySet = 1;
return 0;
}
@ -1036,17 +1060,21 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
/* 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.
* 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(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key)
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key, int trusted)
{
int ret;
@ -1069,18 +1097,36 @@ int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
return BAD_FUNC_ARG;
}
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
key->privKeySet = 1;
/* import public key */
ret = wc_ed25519_import_public(pub, pubSz, key);
ret = wc_ed25519_import_public_ex(pub, pubSz, key, trusted);
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;
}
/* 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.
* 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(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key)
{
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;
@ -939,9 +944,29 @@ int wc_ed448_import_public(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);
}
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.
*
@ -969,6 +994,7 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
if (ret == 0) {
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
key->privKeySet = 1;
}
return ret;
@ -977,17 +1003,20 @@ 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.
* 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(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key)
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key, int trusted)
{
int ret;
@ -1010,18 +1039,38 @@ int wc_ed448_import_private_key(const byte* priv, word32 privSz,
return BAD_FUNC_ARG;
}
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
key->privKeySet = 1;
/* import public key */
ret = wc_ed448_import_public(pub, pubSz, key);
ret = wc_ed448_import_public_ex(pub, pubSz, key, trusted);
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;
}
/* 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().
* 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.
* 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(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed448_key* key)
{
return wc_ed448_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
}
#endif /* HAVE_ED448_KEY_IMPORT */

View File

@ -27350,7 +27350,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)
@ -28813,7 +28813,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