mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #11424 from Frauschi/ed448-make-public-store-pub
Ed448 pub key fixpull/11439/head
commit
1e46e2fc65
|
|
@ -1,14 +1,14 @@
|
|||
/*!
|
||||
\ingroup ED25519
|
||||
|
||||
\brief この関数は、ed25519_keyオブジェクトに格納された秘密鍵からEd25519公開鍵を生成します。公開鍵をバッファpubKeyに格納します。
|
||||
\brief この関数は、ed25519_keyオブジェクトに格納された秘密鍵からEd25519公開鍵を生成します。公開鍵をバッファpubKeyに格納します。キーオブジェクトがまだ公開鍵を保持していない場合、導出された鍵はキーオブジェクトにも格納され、署名に使用できるようになります。
|
||||
|
||||
\return 0 公開鍵の作成に成功した場合に返されます。
|
||||
\return BAD_FUNC_ARG keyまたはpubKeyがNULLと評価された場合、または指定されたキーサイズが32バイトでない場合に返されます(Ed25519は32バイトのキーを持ちます)。
|
||||
\return ECC_PRIV_KEY_E ed25519_keyオブジェクトに秘密鍵が含まれていない場合に返されます。
|
||||
\return MEMORY_E 関数実行中にメモリの割り当てエラーが発生した場合に返されます。
|
||||
|
||||
\param [in] key キーを生成するed25519_keyへのポインタ。
|
||||
\param [in,out] key キーを生成するed25519_keyへのポインタ。
|
||||
\param [out] pubKey 公開鍵を格納するバッファへのポインタ。
|
||||
\param [in] pubKeySz 公開鍵のサイズ。ED25519_PUB_KEY_SIZEである必要があります。
|
||||
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
wc_ed25519_init(&key);
|
||||
wc_ed25519_import_private_only(priv, sizeof(priv), &key);
|
||||
ret = wc_ed25519_make_public(&key, pub, &pubSz);
|
||||
ret = wc_ed25519_make_public(&key, pub, pubSz);
|
||||
if (ret != 0) {
|
||||
// 公開鍵の作成エラー
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/*!
|
||||
\ingroup ED448
|
||||
|
||||
\brief この関数は、秘密鍵からEd448公開鍵を生成します。公開鍵をバッファpubKeyに格納し、このバッファに書き込まれたバイト数をpubKeySzに設定します。
|
||||
\brief この関数は、秘密鍵からEd448公開鍵を生成します。公開鍵をバッファpubKeyに格納し、このバッファに書き込まれたバイト数をpubKeySzに設定します。キーオブジェクトがまだ公開鍵を保持していない場合、導出された鍵はキーオブジェクトにも格納され、署名に使用できるようになります。
|
||||
|
||||
\return 0 公開鍵の作成に成功した場合に返されます。
|
||||
\return BAD_FUNC_ARG keyまたはpubKeyがNULLと評価された場合、または指定されたキーサイズが57バイトでない場合に返されます(Ed448は57バイトのキーを持ちます)。
|
||||
\return MEMORY_E 関数実行中にメモリの割り当てエラーが発生した場合に返されます。
|
||||
|
||||
\param [in] key キーを生成するed448_keyへのポインタ。
|
||||
\param [in,out] key キーを生成するed448_keyへのポインタ。
|
||||
\param [out] pubKey 公開鍵を格納するバッファへのポインタ。
|
||||
\param [in] pubKeySz pubKeyバッファのサイズ(バイト単位)。
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
wc_ed448_init(&key);
|
||||
wc_ed448_import_private_only(priv, sizeof(priv), &key);
|
||||
ret = wc_ed448_make_public(&key, pub, &pubSz);
|
||||
ret = wc_ed448_make_public(&key, pub, pubSz);
|
||||
if (ret != 0) {
|
||||
// 公開鍵の作成エラー
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
\brief This function generates the Ed25519 public key from the private key,
|
||||
stored in the ed25519_key object. It stores the public key in the buffer
|
||||
pubKey.
|
||||
pubKey. If the key object does not already carry a public key, the derived
|
||||
key is also stored in it, so that the key can be used for signing.
|
||||
|
||||
\return 0 Returned upon successfully making the public key.
|
||||
\return BAD_FUNC_ARG Returned if key or pubKey evaluate to NULL, or if the
|
||||
|
|
@ -13,7 +14,7 @@
|
|||
\return MEMORY_E Returned if there is an error allocating memory
|
||||
during function execution.
|
||||
|
||||
\param [in] key Pointer to the ed25519_key for which to generate a key.
|
||||
\param [in,out] key Pointer to the ed25519_key for which to generate a key.
|
||||
\param [out] pubKey Pointer to the buffer in which to store the public key.
|
||||
\param [in] pubKeySz Size of the public key. Should be ED25519_PUB_KEY_SIZE.
|
||||
|
||||
|
|
@ -28,7 +29,7 @@
|
|||
|
||||
wc_ed25519_init(&key);
|
||||
wc_ed25519_import_private_only(priv, sizeof(priv), &key);
|
||||
ret = wc_ed25519_make_public(&key, pub, &pubSz);
|
||||
ret = wc_ed25519_make_public(&key, pub, pubSz);
|
||||
if (ret != 0) {
|
||||
// error making public key
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
\brief This function generates the Ed448 public key from the private key.
|
||||
It stores the public key in the buffer pubKey, and sets the bytes
|
||||
written to this buffer in pubKeySz.
|
||||
written to this buffer in pubKeySz. If the key object does not already
|
||||
carry a public key, the derived key is also stored in it, so that the key
|
||||
can be used for signing.
|
||||
|
||||
\return 0 Returned upon successfully making the public key.
|
||||
\return BAD_FUNC_ARG Returned ifi key or pubKey evaluate to NULL, or if the
|
||||
|
|
@ -11,7 +13,7 @@
|
|||
\return MEMORY_E Returned if there is an error allocating memory
|
||||
during function execution.
|
||||
|
||||
\param [in] key Pointer to the ed448_key for which to generate a key.
|
||||
\param [in,out] key Pointer to the ed448_key for which to generate a key.
|
||||
\param [out] pubKey Pointer to the buffer in which to store the public key.
|
||||
\param [in] pubKeySz Size of the pubKey buffer in bytes.
|
||||
|
||||
|
|
@ -26,7 +28,7 @@
|
|||
|
||||
wc_ed448_init(&key);
|
||||
wc_ed448_import_private_only(priv, sizeof(priv), &key);
|
||||
ret = wc_ed448_make_public(&key, pub, &pubSz);
|
||||
ret = wc_ed448_make_public(&key, pub, pubSz);
|
||||
if (ret != 0) {
|
||||
// error making public key
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29305,8 +29305,6 @@ static int test_wc_SignCRL_ed25519(void)
|
|||
/* The key file carries the private key only, so derive the public key that
|
||||
* Ed25519 signing needs. */
|
||||
ExpectIntEQ(wc_ed25519_make_public(&key, key.p, ED25519_PUB_KEY_SIZE), 0);
|
||||
if (EXPECT_SUCCESS())
|
||||
key.pubKeySet = 1;
|
||||
|
||||
if (EXPECT_SUCCESS()) {
|
||||
ExpectIntEQ(crl_sign_verify_ex2(certDer, (word32)certDerSz,
|
||||
|
|
@ -29348,8 +29346,6 @@ static int test_wc_SignCRL_ed448(void)
|
|||
/* The key file carries the private key only, so derive the public key that
|
||||
* Ed448 signing needs. */
|
||||
ExpectIntEQ(wc_ed448_make_public(&key, key.p, ED448_PUB_KEY_SIZE), 0);
|
||||
if (EXPECT_SUCCESS())
|
||||
key.pubKeySet = 1;
|
||||
|
||||
if (EXPECT_SUCCESS()) {
|
||||
ExpectIntEQ(crl_sign_verify_ex2(certDer, (word32)certDerSz,
|
||||
|
|
|
|||
|
|
@ -89,6 +89,95 @@ int test_wc_ed448_make_key(void)
|
|||
} /* END test_wc_ed448_make_key */
|
||||
|
||||
|
||||
/*
|
||||
* Testing that wc_ed448_make_public() adopts the derived key into the key
|
||||
* object when the key arrived without a public half.
|
||||
*/
|
||||
int test_wc_ed448_make_public_stores_pub(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && \
|
||||
defined(HAVE_ED448_KEY_EXPORT)
|
||||
ed448_key key;
|
||||
ed448_key privOnly;
|
||||
WC_RNG rng;
|
||||
byte priv[ED448_KEY_SIZE];
|
||||
byte pub[ED448_PUB_KEY_SIZE];
|
||||
byte derived[ED448_PUB_KEY_SIZE];
|
||||
byte exported[ED448_PRV_KEY_SIZE];
|
||||
word32 privSz = sizeof(priv);
|
||||
word32 pubSz = sizeof(pub);
|
||||
word32 exportedSz = sizeof(exported);
|
||||
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY)
|
||||
ed448_key pubOnly;
|
||||
byte msg[] = "Everybody gets Friday off.\n";
|
||||
byte sig[ED448_SIG_SIZE];
|
||||
word32 sigSz = sizeof(sig);
|
||||
int verify_ok = 0;
|
||||
#endif
|
||||
|
||||
XMEMSET(&key, 0, sizeof(ed448_key));
|
||||
XMEMSET(&privOnly, 0, sizeof(ed448_key));
|
||||
XMEMSET(&rng, 0, sizeof(WC_RNG));
|
||||
XMEMSET(derived, 0, sizeof(derived));
|
||||
XMEMSET(exported, 0, sizeof(exported));
|
||||
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY)
|
||||
XMEMSET(&pubOnly, 0, sizeof(ed448_key));
|
||||
XMEMSET(sig, 0, sizeof(sig));
|
||||
#endif
|
||||
|
||||
ExpectIntEQ(wc_ed448_init(&key), 0);
|
||||
ExpectIntEQ(wc_ed448_init(&privOnly), 0);
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ExpectIntEQ(wc_ed448_export_private_only(&key, priv, &privSz), 0);
|
||||
PRIVATE_KEY_LOCK();
|
||||
ExpectIntEQ(wc_ed448_export_public(&key, pub, &pubSz), 0);
|
||||
|
||||
/* A PKCS#8 v1 PrivateKeyInfo has no public-key field, so this is the
|
||||
* state a decoded private key arrives in. */
|
||||
ExpectIntEQ(wc_ed448_import_private_only(priv, privSz, &privOnly), 0);
|
||||
ExpectIntEQ(wc_ed448_make_public(&privOnly, derived, sizeof(derived)), 0);
|
||||
ExpectIntEQ(XMEMCMP(derived, pub, ED448_PUB_KEY_SIZE), 0);
|
||||
|
||||
/* Setting pubKeySet is not enough: wc_ed448_sign_msg() gates on the flag
|
||||
* and hashes key->p, so a key left with an empty p signs over zeros. */
|
||||
ExpectIntEQ(XMEMCMP(privOnly.p, pub, ED448_PUB_KEY_SIZE), 0);
|
||||
|
||||
/* wc_ed448_export_private() gates on privKeySet alone and hands back all
|
||||
* of key->k, so the mirrored public half has to be there too. */
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ExpectIntEQ(wc_ed448_export_private(&privOnly, exported, &exportedSz), 0);
|
||||
PRIVATE_KEY_LOCK();
|
||||
ExpectIntEQ(exportedSz, ED448_PRV_KEY_SIZE);
|
||||
ExpectIntEQ(XMEMCMP(exported, priv, ED448_KEY_SIZE), 0);
|
||||
ExpectIntEQ(XMEMCMP(exported + ED448_KEY_SIZE, pub, ED448_PUB_KEY_SIZE), 0);
|
||||
|
||||
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY)
|
||||
/* Verify against a key that only ever saw the real public half, so a
|
||||
* signature made over an empty p cannot verify against itself. */
|
||||
ExpectIntEQ(wc_ed448_init(&pubOnly), 0);
|
||||
ExpectIntEQ(wc_ed448_import_public(pub, pubSz, &pubOnly), 0);
|
||||
ExpectIntEQ(wc_ed448_sign_msg(msg, sizeof(msg), sig, &sigSz, &privOnly,
|
||||
NULL, 0), 0);
|
||||
ExpectIntEQ(wc_ed448_verify_msg(sig, sigSz, msg, sizeof(msg), &verify_ok,
|
||||
&pubOnly, NULL, 0), 0);
|
||||
ExpectIntEQ(verify_ok, 1);
|
||||
#endif
|
||||
|
||||
DoExpectIntEQ(wc_FreeRng(&rng), 0);
|
||||
wc_ed448_free(&key);
|
||||
wc_ed448_free(&privOnly);
|
||||
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY)
|
||||
wc_ed448_free(&pubOnly);
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_ed448_make_public_stores_pub */
|
||||
|
||||
|
||||
/*
|
||||
* Testing wc_ed448_init()
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <tests/api/api_decl.h>
|
||||
|
||||
int test_wc_ed448_make_key(void);
|
||||
int test_wc_ed448_make_public_stores_pub(void);
|
||||
int test_wc_ed448_init(void);
|
||||
int test_wc_ed448_sign_msg(void);
|
||||
int test_wc_ed448_verify_sig_S_range(void);
|
||||
|
|
@ -48,6 +49,7 @@ int test_wc_ed448_cryptocb(void);
|
|||
|
||||
#define TEST_ED448_DECLS \
|
||||
TEST_DECL_GROUP("ed448", test_wc_ed448_make_key), \
|
||||
TEST_DECL_GROUP("ed448", test_wc_ed448_make_public_stores_pub), \
|
||||
TEST_DECL_GROUP("ed448", test_wc_ed448_init), \
|
||||
TEST_DECL_GROUP("ed448", test_wc_ed448_sign_msg), \
|
||||
TEST_DECL_GROUP("ed448", test_wc_ed448_verify_sig_S_range), \
|
||||
|
|
|
|||
|
|
@ -315,7 +315,24 @@ static int ed448_is_small_order(const byte p[ED448_PUB_KEY_SIZE])
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Mirror a derived public key into the key object, in the layout
|
||||
* wc_ed448_make_key() leaves: key->p, and a copy after the private key in
|
||||
* key->k. Only ever called for a key with no public half yet - deriving into
|
||||
* scratch and comparing against key->p is how wc_ed448_check_key() works.
|
||||
*/
|
||||
static void ed448_store_public(ed448_key* key, const byte* pubKey)
|
||||
{
|
||||
if (pubKey != key->p) {
|
||||
XMEMCPY(key->p, pubKey, ED448_PUB_KEY_SIZE);
|
||||
}
|
||||
/* put public key after private key, on the same buffer */
|
||||
XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
|
||||
}
|
||||
|
||||
/* Derive the public key for the private key.
|
||||
*
|
||||
* Also stores the derived key in the key object when it did not already carry
|
||||
* a public half.
|
||||
*
|
||||
* key [in] Ed448 key object.
|
||||
* pubKey [in] Byte array to hold the public key.
|
||||
|
|
@ -328,6 +345,7 @@ static int ed448_is_small_order(const byte p[ED448_PUB_KEY_SIZE])
|
|||
int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
|
||||
{
|
||||
int ret = 0;
|
||||
int storePub = 0;
|
||||
byte az[ED448_PRV_KEY_SIZE];
|
||||
ge448_p2 A;
|
||||
|
||||
|
|
@ -339,6 +357,14 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
|
|||
ret = ECC_PRIV_KEY_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* The key doesn't carry its public half yet (e.g. it was decoded from
|
||||
* a PKCS#8 v1 PrivateKeyInfo, which holds only the seed): fill it in
|
||||
* as well, so pubKeySet below doesn't end up set on a key whose p/k
|
||||
* are still empty. */
|
||||
storePub = !key->pubKeySet;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
|
||||
|
||||
|
|
@ -354,6 +380,8 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
|
|||
if (ret == 0) {
|
||||
ge448_to_bytes(pubKey, &A);
|
||||
|
||||
if (storePub)
|
||||
ed448_store_public(key, pubKey);
|
||||
key->pubKeySet = 1;
|
||||
}
|
||||
|
||||
|
|
@ -391,23 +419,22 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
|
|||
}
|
||||
if (ret == 0) {
|
||||
key->privKeySet = 1;
|
||||
/* pubKeySet was just cleared, so this also stores the public key in
|
||||
* key->p and after the private key in key->k */
|
||||
ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE);
|
||||
if (ret != 0) {
|
||||
key->privKeySet = 0;
|
||||
ForceZero(key->k, ED448_KEY_SIZE);
|
||||
}
|
||||
}
|
||||
#if FIPS_VERSION3_GE(6,0,0)
|
||||
if (ret == 0) {
|
||||
/* put public key after private key, on the same buffer */
|
||||
XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
|
||||
|
||||
#if FIPS_VERSION3_GE(6,0,0)
|
||||
ret = wc_ed448_check_key(key);
|
||||
if (ret == 0) {
|
||||
ret = ed448_pairwise_consistency_test(key, rng);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1401,7 +1428,7 @@ int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
|
|||
}
|
||||
|
||||
/* make the private key (priv + pub) */
|
||||
XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
|
||||
ed448_store_public(key, key->p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue