mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 20:54:41 +02:00
Merge pull request #5311 from SparkiDev/ed_check_pubkey
Ed25519/Ed448: assume public key is not trusted
This commit is contained in:
@@ -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);
|
||||
|
@@ -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);
|
||||
|
18
tests/api.c
18
tests/api.c
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
@@ -944,10 +945,12 @@ int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
|
||||
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,19 +1035,88 @@ 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).
|
||||
*
|
||||
@@ -1048,39 +1132,8 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
|
||||
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
|
||||
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;
|
||||
return wc_ed25519_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ED25519_KEY_IMPORT */
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
@@ -896,10 +897,14 @@ int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen)
|
||||
* 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;
|
||||
@@ -983,11 +1024,14 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
|
||||
* 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;
|
||||
|
||||
@@ -996,32 +1040,56 @@ int wc_ed448_import_private_key(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;
|
||||
}
|
||||
|
||||
XMEMCPY(key->k, priv, ED448_KEY_SIZE);
|
||||
key->privKeySet = 1;
|
||||
|
||||
/* import public key */
|
||||
ret = wc_ed448_import_public(pub, pubSz, key);
|
||||
if (ret != 0)
|
||||
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, 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 */
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user