diff --git a/doc/dox_comments/header_files/ed25519.h b/doc/dox_comments/header_files/ed25519.h index 167765c2d..83f302c3d 100644 --- a/doc/dox_comments/header_files/ed25519.h +++ b/doc/dox_comments/header_files/ed25519.h @@ -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); diff --git a/doc/dox_comments/header_files/ed448.h b/doc/dox_comments/header_files/ed448.h index 75550aa11..a3ea82088 100644 --- a/doc/dox_comments/header_files/ed448.h +++ b/doc/dox_comments/header_files/ed448.h @@ -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); diff --git a/tests/api.c b/tests/api.c index a19bcf2b1..7e2e14ddc 100644 --- a/tests/api.c +++ b/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; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9397c43bd..ca70c217b 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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 diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 8304a46ea..ff5bd7ebd 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -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 */ diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index ea092d18b..0225c2f04 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -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 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index ec7d34603..7f7c7ce6f 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -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; } diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 4f2171ead..b7d2ef949 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -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 diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index c1ce329fc..4ee888bfd 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -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