forked from wolfSSL/wolfssl
EdDSA FIPS checks on public key
Check that the Ed25519 and Ed448 public key is valid even without private key. Perform pairwise consistency test, only in FIPS, when making a key i Ed25519 and Ed448.
This commit is contained in:
@ -208,6 +208,56 @@ static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen,
|
||||
}
|
||||
|
||||
#ifdef HAVE_ED25519_MAKE_KEY
|
||||
#if FIPS_VERSION_GE(7,0)
|
||||
/* Performs a Pairwise Consistency Test on an Ed25519 key pair.
|
||||
*
|
||||
* @param [in] key Ed25519 key to test.
|
||||
* @param [in] rng Random number generator to use to create random digest.
|
||||
* @return 0 on success.
|
||||
* @return ECC_PCT_E when signing or verification fail.
|
||||
* @return Other -ve when random number generation fails.
|
||||
*/
|
||||
static int ed25519_pairwise_consistency_test(ed25519_key* key, WC_RNG* rng)
|
||||
{
|
||||
int err = 0;
|
||||
byte digest[WC_SHA512_DIGEST_SIZE];
|
||||
word32 digestLen = WC_SHA512_DIGEST_SIZE;
|
||||
byte sig[ED25519_SIG_SIZE];
|
||||
word32 sigLen = ED25519_SIG_SIZE;
|
||||
int res = 0;
|
||||
|
||||
/* Generate a random digest to sign. */
|
||||
err = wc_RNG_GenerateBlock(rng, digest, digestLen);
|
||||
if (err == 0) {
|
||||
/* Sign digest without context. */
|
||||
err = wc_ed25519_sign_msg_ex(digest, digestLen, sig, &sigLen, key,
|
||||
Ed25519, NULL, 0);
|
||||
if (err != 0) {
|
||||
/* Any sign failure means test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
/* Verify digest without context. */
|
||||
err = wc_ed25519_verify_msg_ex(sig, sigLen, digest, digestLen, &res,
|
||||
key, Ed25519, NULL, 0);
|
||||
if (err != 0) {
|
||||
/* Any verification operation failure means test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
/* Check whether the signature verified. */
|
||||
else if (res == 0) {
|
||||
/* Test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
}
|
||||
|
||||
ForceZero(sig, sigLen);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
|
||||
word32 pubKeySz)
|
||||
{
|
||||
@ -291,6 +341,13 @@ 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);
|
||||
|
||||
#if FIPS_VERSION_GE(7,0)
|
||||
ret = wc_ed25519_check_key(key);
|
||||
if (ret == 0) {
|
||||
ret = ed25519_pairwise_consistency_test(key, rng);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ED25519_MAKE_KEY */
|
||||
@ -1077,7 +1134,7 @@ int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
|
||||
|
||||
if (ret == 0) {
|
||||
key->pubKeySet = 1;
|
||||
if (key->privKeySet && (!trusted)) {
|
||||
if (!trusted) {
|
||||
ret = wc_ed25519_check_key(key);
|
||||
}
|
||||
}
|
||||
@ -1278,23 +1335,84 @@ int wc_ed25519_export_key(ed25519_key* key,
|
||||
|
||||
#endif /* HAVE_ED25519_KEY_EXPORT */
|
||||
|
||||
/* check the private and public keys match */
|
||||
/* Check the public key is valid.
|
||||
*
|
||||
* When private key available, check the calculated public key matches.
|
||||
* When no private key, check Y is in range and an X is able to be calculated.
|
||||
*
|
||||
* @param [in] key Ed25519 private/public key.
|
||||
* @return 0 otherwise.
|
||||
* @return BAD_FUNC_ARG when key is NULL.
|
||||
* @return PUBLIC_KEY_E when the public key is not set, doesn't match or is
|
||||
* invalid.
|
||||
* @return other -ve value on hash failure.
|
||||
*/
|
||||
int wc_ed25519_check_key(ed25519_key* key)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef HAVE_ED25519_MAKE_KEY
|
||||
ALIGN16 unsigned char pubKey[ED25519_PUB_KEY_SIZE];
|
||||
|
||||
if (!key->pubKeySet)
|
||||
/* Validate parameter. */
|
||||
if (key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Check we have a public key to check. */
|
||||
if ((ret == 0) && (!key->pubKeySet)) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
if (ret == 0)
|
||||
}
|
||||
|
||||
#ifdef HAVE_ED25519_MAKE_KEY
|
||||
/* If we have a private key just make the public key and compare. */
|
||||
if ((ret == 0) && (key->privKeySet)) {
|
||||
ALIGN16 unsigned char pubKey[ED25519_PUB_KEY_SIZE];
|
||||
|
||||
ret = wc_ed25519_make_public(key, pubKey, sizeof(pubKey));
|
||||
if (ret == 0 && XMEMCMP(pubKey, key->p, ED25519_PUB_KEY_SIZE) != 0)
|
||||
ret = PUBLIC_KEY_E;
|
||||
if (ret == 0 && XMEMCMP(pubKey, key->p, ED25519_PUB_KEY_SIZE) != 0)
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
#else
|
||||
(void)key;
|
||||
(void)key;
|
||||
#endif /* HAVE_ED25519_MAKE_KEY */
|
||||
|
||||
/* No private key (or ability to make a public key), check Y is valid. */
|
||||
if ((ret == 0)
|
||||
#ifdef HAVE_ED25519_MAKE_KEY
|
||||
&& (!key->privKeySet)
|
||||
#endif
|
||||
) {
|
||||
/* Verify that Q is not identity element 0.
|
||||
* 0 has no representation for Ed25519. */
|
||||
|
||||
/* Verify that xQ and yQ are integers in the interval [0, p - 1].
|
||||
* Only have yQ so check that ordinate. p = 2^255 - 19 */
|
||||
if ((key->p[ED25519_PUB_KEY_SIZE - 1] & 0x7f) == 0x7f) {
|
||||
int i;
|
||||
|
||||
ret = PUBLIC_KEY_E;
|
||||
/* Check up to last byte. */
|
||||
for (i = ED25519_PUB_KEY_SIZE - 2; i > 0; i--) {
|
||||
if (key->p[i] != 0xff) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Bits are all one up to last byte - check less than -19. */
|
||||
if ((ret == PUBLIC_KEY_E) && (key->p[0] < 0xed)) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Verify that Q is on the curve.
|
||||
* Uncompressing the public key will validate yQ. */
|
||||
ge_p3 A;
|
||||
|
||||
if (ge_frombytes_negate_vartime(&A, key->p) != 0) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,56 @@ static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if FIPS_VERSION_GE(7,0)
|
||||
/* Performs a Pairwise Consistency Test on an Ed448 key pair.
|
||||
*
|
||||
* @param [in] key Ed448 key to test.
|
||||
* @param [in] rng Random number generator to use to create random digest.
|
||||
* @return 0 on success.
|
||||
* @return ECC_PCT_E when signing or verification fail.
|
||||
* @return Other -ve when random number generation fails.
|
||||
*/
|
||||
static int ed448_pairwise_consistency_test(ed448_key* key, WC_RNG* rng)
|
||||
{
|
||||
int err = 0;
|
||||
byte digest[WC_SHA256_DIGEST_SIZE];
|
||||
word32 digestLen = WC_SHA256_DIGEST_SIZE;
|
||||
byte sig[ED448_SIG_SIZE];
|
||||
word32 sigLen = ED448_SIG_SIZE;
|
||||
int res = 0;
|
||||
|
||||
/* Generate a random digest to sign. */
|
||||
err = wc_RNG_GenerateBlock(rng, digest, digestLen);
|
||||
if (err == 0) {
|
||||
/* Sign digest without context. */
|
||||
err = wc_ed448_sign_msg_ex(digest, digestLen, sig, &sigLen, key, Ed448,
|
||||
NULL, 0);
|
||||
if (err != 0) {
|
||||
/* Any sign failure means test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
/* Verify digest without context. */
|
||||
err = wc_ed448_verify_msg_ex(sig, sigLen, digest, digestLen, &res, key,
|
||||
Ed448, NULL, 0);
|
||||
if (err != 0) {
|
||||
/* Any verification operation failure means test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
/* Check whether the signature verified. */
|
||||
else if (res == 0) {
|
||||
/* Test failed. */
|
||||
err = ECC_PCT_E;
|
||||
}
|
||||
}
|
||||
|
||||
ForceZero(sig, sigLen);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Derive the public key for the private key.
|
||||
*
|
||||
* key [in] Ed448 key object.
|
||||
@ -272,6 +322,13 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
|
||||
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_VERSION_GE(7,0)
|
||||
ret = wc_ed448_check_key(key);
|
||||
if (ret == 0) {
|
||||
ret = ed448_pairwise_consistency_test(key, rng);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -966,7 +1023,7 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (inLen != ED448_PUB_KEY_SIZE) {
|
||||
if ((inLen != ED448_PUB_KEY_SIZE) && (inLen != ED448_PUB_KEY_SIZE + 1)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@ -995,7 +1052,7 @@ int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
|
||||
|
||||
if (ret == 0) {
|
||||
key->pubKeySet = 1;
|
||||
if (key->privKeySet && (!trusted)) {
|
||||
if (!trusted) {
|
||||
/* Check untrusted public key data matches private key. */
|
||||
ret = wc_ed448_check_key(key);
|
||||
}
|
||||
@ -1243,31 +1300,90 @@ int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz,
|
||||
|
||||
#endif /* HAVE_ED448_KEY_EXPORT */
|
||||
|
||||
/* Check the public key of the ed448 key matches the private key.
|
||||
/* Check the public key is valid.
|
||||
*
|
||||
* key [in] Ed448 private/public key.
|
||||
* returns BAD_FUNC_ARG when key is NULL,
|
||||
* PUBLIC_KEY_E when the public key is not set or doesn't match,
|
||||
* other -ve value on hash failure,
|
||||
* 0 otherwise.
|
||||
* When private key available, check the calculated public key matches.
|
||||
* When no private key, check Y is in range and an X is able to be calculated.
|
||||
*
|
||||
* @param [in] key Ed448 private/public key.
|
||||
* @return 0 otherwise.
|
||||
* @return BAD_FUNC_ARG when key is NULL.
|
||||
* @return PUBLIC_KEY_E when the public key is not set, doesn't match or is
|
||||
* invalid.
|
||||
* @return other -ve value on hash failure.
|
||||
*/
|
||||
int wc_ed448_check_key(ed448_key* key)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char pubKey[ED448_PUB_KEY_SIZE];
|
||||
|
||||
/* Validate parameter. */
|
||||
if (key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Check we have a public key to check. */
|
||||
if (ret == 0 && !key->pubKeySet) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
|
||||
/* If we have a private key just make the public key and compare. */
|
||||
if ((ret == 0) && key->privKeySet) {
|
||||
ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey));
|
||||
if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
}
|
||||
if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
/* No private key, check Y is valid. */
|
||||
else if ((ret == 0) && (!key->privKeySet)) {
|
||||
/* Verify that Q is not identity element 0.
|
||||
* 0 has no representation for Ed448. */
|
||||
|
||||
/* Verify that xQ and yQ are integers in the interval [0, p - 1].
|
||||
* Only have yQ so check that ordinate.
|
||||
* p = 2^448-2^224-1 = 0xff..fe..ff
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
ret = PUBLIC_KEY_E;
|
||||
|
||||
/* Check top part before 0xFE. */
|
||||
for (i = ED448_PUB_KEY_SIZE - 1; i > ED448_PUB_KEY_SIZE/2; i--) {
|
||||
if (key->p[i] < 0xff) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == PUBLIC_KEY_E) {
|
||||
/* Check against 0xFE. */
|
||||
if (key->p[ED448_PUB_KEY_SIZE/2] < 0xfe) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (key->p[ED448_PUB_KEY_SIZE/2] == 0xfe) {
|
||||
/* Check bottom part before last byte. */
|
||||
for (i = ED448_PUB_KEY_SIZE/2 - 1; i > 0; i--) {
|
||||
if (key->p[i] != 0xff) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check last byte. */
|
||||
if ((ret == PUBLIC_KEY_E) && (key->p[0] < 0xff)) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Verify that Q is on the curve.
|
||||
* Uncompressing the public key will validate yQ. */
|
||||
ge448_p2 A;
|
||||
|
||||
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0) {
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -32902,6 +32902,88 @@ done:
|
||||
}
|
||||
#endif /* WOLFSSL_TEST_CERT */
|
||||
|
||||
#if defined(HAVE_ED25519_KEY_IMPORT)
|
||||
static wc_test_ret_t ed25519_test_check_key(void)
|
||||
{
|
||||
/* Fails to find x-ordinate from this y-ordinate. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y[] = {
|
||||
0x40,
|
||||
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
/* Y-ordinate value larger than prime. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y_max[] = {
|
||||
0x40,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
};
|
||||
/* Y-ordinate value equal to prime. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y_is_p[] = {
|
||||
0x40,
|
||||
0xed,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
};
|
||||
/* Y-ordinate value equal to prime - 1. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_y_is_p_minus_1[] = {
|
||||
0x40,
|
||||
0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
};
|
||||
ed25519_key key;
|
||||
int ret;
|
||||
int res = 0;
|
||||
|
||||
/* Initialize key for use. */
|
||||
ret = wc_ed25519_init_ex(&key, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
return WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed25519_import_public(key_bad_y, ED25519_PUB_KEY_SIZE + 1, &key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed25519_import_public(key_bad_y_max, ED25519_PUB_KEY_SIZE + 1,
|
||||
&key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed25519_import_public(key_bad_y_is_p, ED25519_PUB_KEY_SIZE + 1,
|
||||
&key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Load good public key only and perform checks. */
|
||||
ret = wc_ed25519_import_public(key_y_is_p_minus_1,
|
||||
ED25519_PUB_KEY_SIZE + 1, &key);
|
||||
if (ret != 0) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispose of key. */
|
||||
wc_ed25519_free(&key);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_EXPORT) && \
|
||||
defined(HAVE_ED25519_KEY_IMPORT)
|
||||
static wc_test_ret_t ed25519ctx_test(void)
|
||||
@ -33735,6 +33817,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ed25519_test(void)
|
||||
(void)keySz;
|
||||
(void)sigSz;
|
||||
|
||||
ret = ed25519_test_check_key();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#ifdef WOLFSSL_TEST_CERT
|
||||
ret = ed25519_test_cert();
|
||||
if (ret < 0)
|
||||
@ -34260,6 +34345,104 @@ done:
|
||||
}
|
||||
#endif /* WOLFSSL_TEST_CERT */
|
||||
|
||||
#if defined(HAVE_ED448_KEY_IMPORT)
|
||||
static wc_test_ret_t ed448_test_check_key(void)
|
||||
{
|
||||
/* Fails to find x-ordinate from this y-ordinate. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y[] = {
|
||||
0x40,
|
||||
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00
|
||||
};
|
||||
/* Y-ordinate value larger than prime. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y_max[] = {
|
||||
0x40,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff
|
||||
};
|
||||
/* Y-ordinate value equal to prime. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_bad_y_is_p[] = {
|
||||
0x40,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff
|
||||
};
|
||||
/* Y-ordinate value equal to prime - 1. */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key_y_is_p_minus_1[] = {
|
||||
0x40,
|
||||
0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff
|
||||
};
|
||||
ed448_key key;
|
||||
int ret;
|
||||
int res = 0;
|
||||
|
||||
/* Initialize key for use. */
|
||||
ret = wc_ed448_init_ex(&key, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
return WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed448_import_public(key_bad_y, ED448_PUB_KEY_SIZE + 1, &key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed448_import_public(key_bad_y_max, ED448_PUB_KEY_SIZE + 1,
|
||||
&key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Load bad public key only and perform checks. */
|
||||
ret = wc_ed448_import_public(key_bad_y_is_p, ED448_PUB_KEY_SIZE + 1,
|
||||
&key);
|
||||
if (ret != PUBLIC_KEY_E) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Load good public key only and perform checks. */
|
||||
ret = wc_ed448_import_public(key_y_is_p_minus_1, ED448_PUB_KEY_SIZE + 1,
|
||||
&key);
|
||||
if (ret != 0) {
|
||||
res = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispose of key. */
|
||||
wc_ed448_free(&key);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_EXPORT) && \
|
||||
defined(HAVE_ED448_KEY_IMPORT)
|
||||
static wc_test_ret_t ed448_ctx_test(void)
|
||||
@ -35258,6 +35441,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ed448_test(void)
|
||||
(void)keySz;
|
||||
(void)sigSz;
|
||||
|
||||
ret = ed448_test_check_key();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#ifdef WOLFSSL_TEST_CERT
|
||||
ret = ed448_test_cert();
|
||||
if (ret < 0)
|
||||
|
Reference in New Issue
Block a user