ED: add streaming API to the ED verify routines: wc_ed*_verify_msg_init(), wc_ed*_verify_msg_update(), wc_ed*_verify_msg_final();

harmonize the ED448 API with the ED25519 API by making wc_ed448_verify_msg_ex() and wc_ed448_init_ex() public functions;

track devId and heap pointer in ed*_key.{devId,heap}, and pass them through to sha init functions;

add ed*_key.{sha,sha_clean_flag}, and ed*_hash_{reset,update,final} functions, and use them for all ED hashing ops, to support streaming API and for optimally efficient reuse for the preexisting ED calls;

add ed448_hash() akin to ed25519_hash(), and use it in place of wc_Shake256Hash(), for .sha_clean_flag dynamics.

add to wc_ed*_import_private_key() the ability to import the combined key generated by wc_ed*_export_private() without supplying the redundant public key;

add macro asserts near top of ed*.h to assure the required hash functions are available;

fix {NO,HAVE}_ED*_{SIGN,VERIFY};

wolfcrypt/test/test.c: add missing key initializations in ed*_test();

wolfcrypt/test/test.c: fix unaligned access in myDecryptionFunc() detected by -fsanitize=address,undefined.
This commit is contained in:
Daniel Pouzzner
2021-07-13 13:16:15 -05:00
parent b9c707511b
commit 9b43e57ccf
13 changed files with 778 additions and 285 deletions

View File

@ -4771,6 +4771,16 @@ int Ed25519CheckPubKey(WOLFSSL* ssl)
int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
word32* outSz, ed25519_key* key, DerBuffer* keyBufInfo)
{
#ifndef HAVE_ED25519_SIGN
(void)ssl;
(void)in;
(void)inSz;
(void)out;
(void)outSz;
(void)key;
(void)keyBufInfo;
return NOT_COMPILED_IN;
#else /* HAVE_ED25519_SIGN */
int ret;
#ifdef HAVE_PK_CALLBACKS
const byte* keyBuf = NULL;
@ -4816,6 +4826,7 @@ int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
WOLFSSL_LEAVE("Ed25519Sign", ret);
return ret;
#endif /* HAVE_ED25519_SIGN */
}
/* Verify the data using EdDSA and key using Ed25519.
@ -4833,6 +4844,16 @@ int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
int Ed25519Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
word32 msgSz, ed25519_key* key, buffer* keyBufInfo)
{
#ifndef HAVE_ED25519_VERIFY
(void)ssl;
(void)in;
(void)inSz;
(void)msg;
(void)msgSz;
(void)key;
(void)keyBufInfo;
return NOT_COMPILED_IN;
#else /* HAVE_ED25519_VERIFY */
int ret;
#ifdef HAVE_PK_CALLBACKS
const byte* keyBuf = NULL;
@ -4883,6 +4904,7 @@ int Ed25519Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
WOLFSSL_LEAVE("Ed25519Verify", ret);
return ret;
#endif /* HAVE_ED25519_VERIFY */
}
#endif /* HAVE_ED25519 */
@ -5078,6 +5100,16 @@ int Ed448CheckPubKey(WOLFSSL* ssl)
int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
word32* outSz, ed448_key* key, DerBuffer* keyBufInfo)
{
#ifndef HAVE_ED448_SIGN
(void)ssl;
(void)in;
(void)inSz;
(void)out;
(void)outSz;
(void)key;
(void)keyBufInfo;
return NOT_COMPILED_IN;
#else /* HAVE_ED448_SIGN */
int ret;
#ifdef HAVE_PK_CALLBACKS
const byte* keyBuf = NULL;
@ -5123,6 +5155,7 @@ int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
WOLFSSL_LEAVE("Ed448Sign", ret);
return ret;
#endif /* HAVE_ED448_SIGN */
}
/* Verify the data using EdDSA and key using Ed448.
@ -5140,6 +5173,16 @@ int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
int Ed448Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
word32 msgSz, ed448_key* key, buffer* keyBufInfo)
{
#ifndef HAVE_ED448_VERIFY
(void)ssl;
(void)in;
(void)inSz;
(void)msg;
(void)msgSz;
(void)key;
(void)keyBufInfo;
return NOT_COMPILED_IN;
#else /* HAVE_ED448_VERIFY */
int ret;
#ifdef HAVE_PK_CALLBACKS
const byte* keyBuf = NULL;
@ -5190,6 +5233,7 @@ int Ed448Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
WOLFSSL_LEAVE("Ed448Verify", ret);
return ret;
#endif /* HAVE_ED448_VERIFY */
}
#endif /* HAVE_ED448 */

View File

@ -47205,8 +47205,12 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
const unsigned char *priv, unsigned int privSz,
unsigned char *sig, unsigned int *sigSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
#if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN)
#if !defined(HAVE_ED25519_SIGN)
WOLFSSL_MSG("No ED25519 sign built in");
#elif !defined(WOLFSSL_KEY_GEN)
WOLFSSL_MSG("No Key Gen built in");
#endif
(void) msg;
(void) msgSz;
(void) priv;
@ -47214,7 +47218,7 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
#else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN */
ed25519_key key;
int ret = WOLFSSL_FAILURE;
@ -47247,7 +47251,7 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
wc_ed25519_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN */
}
/* return 1 if success, 0 if error
@ -47258,8 +47262,12 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
const unsigned char *pub, unsigned int pubSz,
const unsigned char *sig, unsigned int sigSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
#if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN)
#if !defined(HAVE_ED25519_VERIFY)
WOLFSSL_MSG("No ED25519 verify built in");
#elif !defined(WOLFSSL_KEY_GEN)
WOLFSSL_MSG("No Key Gen built in");
#endif
(void) msg;
(void) msgSz;
(void) pub;
@ -47267,7 +47275,7 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
#else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN */
ed25519_key key;
int ret = WOLFSSL_FAILURE, check = 0;
@ -47302,7 +47310,7 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
wc_ed25519_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN */
}
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
@ -47538,8 +47546,12 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
const unsigned char *priv, unsigned int privSz,
unsigned char *sig, unsigned int *sigSz)
{
#ifndef WOLFSSL_KEY_GEN
#if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN)
#if !defined(HAVE_ED448_SIGN)
WOLFSSL_MSG("No ED448 sign built in");
#elif !defined(WOLFSSL_KEY_GEN)
WOLFSSL_MSG("No Key Gen built in");
#endif
(void) msg;
(void) msgSz;
(void) priv;
@ -47547,7 +47559,7 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
#else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN */
ed448_key key;
int ret = WOLFSSL_FAILURE;
@ -47579,7 +47591,7 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
wc_ed448_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN */
}
/* return 1 if success, 0 if error
@ -47590,8 +47602,12 @@ int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
const unsigned char *pub, unsigned int pubSz,
const unsigned char *sig, unsigned int sigSz)
{
#ifndef WOLFSSL_KEY_GEN
#if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN)
#if !defined(HAVE_ED448_VERIFY)
WOLFSSL_MSG("No ED448 verify built in");
#elif !defined(WOLFSSL_KEY_GEN)
WOLFSSL_MSG("No Key Gen built in");
#endif
(void) msg;
(void) msgSz;
(void) pub;
@ -47599,7 +47615,7 @@ int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
#else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */
ed448_key key;
int ret = WOLFSSL_FAILURE, check = 0;
@ -47634,7 +47650,7 @@ int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
wc_ed448_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */
}
#endif /* OPENSSL_EXTRA && HAVE_ED448 */

View File

@ -2608,22 +2608,28 @@ static void test_ED25519(void)
unsigned int privSz = (unsigned int)sizeof(priv);
byte pub[ED25519_PUB_KEY_SIZE];
unsigned int pubSz = (unsigned int)sizeof(pub);
#ifdef HAVE_ED25519_SIGN
const char* msg = TEST_STRING;
unsigned int msglen = (unsigned int)TEST_STRING_SZ;
byte sig[ED25519_SIG_SIZE];
unsigned int sigSz = (unsigned int)sizeof(sig);
#endif /* HAVE_ED25519_SIGN */
AssertIntEQ(wolfSSL_ED25519_generate_key(priv, &privSz, pub, &pubSz),
WOLFSSL_SUCCESS);
AssertIntEQ(privSz, ED25519_PRV_KEY_SIZE);
AssertIntEQ(pubSz, ED25519_PUB_KEY_SIZE);
#ifdef HAVE_ED25519_SIGN
AssertIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz, sig,
&sigSz), WOLFSSL_SUCCESS);
AssertIntEQ(sigSz, ED25519_SIG_SIZE);
#ifdef HAVE_ED25519_VERIFY
AssertIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig,
sigSz), WOLFSSL_SUCCESS);
#endif /* HAVE_ED25519_VERIFY */
#endif /* HAVE_ED25519_SIGN */
#endif /* HAVE_ED25519 && WOLFSSL_KEY_GEN */
}
@ -2634,22 +2640,28 @@ static void test_ED448(void)
unsigned int privSz = (unsigned int)sizeof(priv);
byte pub[ED448_PUB_KEY_SIZE];
unsigned int pubSz = (unsigned int)sizeof(pub);
#ifdef HAVE_ED448_SIGN
const char* msg = TEST_STRING;
unsigned int msglen = (unsigned int)TEST_STRING_SZ;
byte sig[ED448_SIG_SIZE];
unsigned int sigSz = (unsigned int)sizeof(sig);
#endif /* HAVE_ED448_SIGN */
AssertIntEQ(wolfSSL_ED448_generate_key(priv, &privSz, pub, &pubSz),
WOLFSSL_SUCCESS);
AssertIntEQ(privSz, ED448_PRV_KEY_SIZE);
AssertIntEQ(pubSz, ED448_PUB_KEY_SIZE);
#ifdef HAVE_ED448_SIGN
AssertIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz, sig,
&sigSz), WOLFSSL_SUCCESS);
AssertIntEQ(sigSz, ED448_SIG_SIZE);
#ifdef HAVE_ED448_VERIFY
AssertIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig,
sigSz), WOLFSSL_SUCCESS);
#endif /* HAVE_ED448_VERIFY */
#endif /* HAVE_ED448_SIGN */
#endif /* HAVE_ED448 && WOLFSSL_KEY_GEN */
}
#endif /* OPENSSL_EXTRA */
@ -18723,7 +18735,9 @@ static int test_wc_ed25519_sign_msg (void)
word32 msglen = sizeof(msg);
word32 siglen = sizeof(sig);
word32 badSigLen = sizeof(sig) - 1;
#ifdef HAVE_ED25519_VERIFY
int verify_ok = 0; /*1 = Verify success.*/
#endif
/* Initialize stack variables. */
XMEMSET(sig, 0, siglen);
@ -18902,6 +18916,8 @@ static int test_wc_ed25519_import_private_key (void)
const byte pubKey[] = "Ed25519PublicKeyUnitTest......\n";
word32 privKeySz = sizeof(privKey);
word32 pubKeySz = sizeof(pubKey);
byte bothKeys[sizeof(privKey) + sizeof(pubKey)];
word32 bothKeysSz = sizeof(bothKeys);
ret = wc_InitRng(&rng);
if (ret != 0) {
@ -18925,6 +18941,19 @@ static int test_wc_ed25519_import_private_key (void)
}
}
#ifdef HAVE_ED25519_KEY_EXPORT
if (ret == 0)
ret = wc_ed25519_export_private(&key, bothKeys, &bothKeysSz);
if (ret == 0) {
ret = wc_ed25519_import_private_key(bothKeys, bothKeysSz, NULL, 0, &key);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0
|| XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = SSL_FATAL_ERROR;
}
}
#endif
/* Test bad args. */
if (ret == 0) {
ret = wc_ed25519_import_private_key(NULL, privKeySz, pubKey, pubKeySz,
@ -18945,6 +18974,10 @@ static int test_wc_ed25519_import_private_key (void)
ret = wc_ed25519_import_private_key(privKey, privKeySz, pubKey,
pubKeySz - 1, &key);
}
if (ret == BAD_FUNC_ARG) {
ret = wc_ed25519_import_private_key(privKey, privKeySz, NULL,
0, &key);
}
if (ret == BAD_FUNC_ARG) {
ret = 0;
} else if (ret == 0) {
@ -20514,7 +20547,9 @@ static int test_wc_ed448_sign_msg (void)
word32 msglen = sizeof(msg);
word32 siglen = sizeof(sig);
word32 badSigLen = sizeof(sig) - 1;
#ifdef HAVE_ED448_VERIFY
int verify_ok = 0; /*1 = Verify success.*/
#endif
/* Initialize stack variables. */
XMEMSET(sig, 0, siglen);
@ -20700,6 +20735,8 @@ static int test_wc_ed448_import_private_key (void)
"Ed448PublicKeyUnitTest.................................\n";
word32 privKeySz = sizeof(privKey);
word32 pubKeySz = sizeof(pubKey);
byte bothKeys[sizeof(privKey) + sizeof(pubKey)];
word32 bothKeysSz = sizeof(bothKeys);
ret = wc_InitRng(&rng);
if (ret != 0) {
@ -20723,6 +20760,19 @@ static int test_wc_ed448_import_private_key (void)
}
}
#ifdef HAVE_ED448_KEY_EXPORT
if (ret == 0)
ret = wc_ed448_export_private(&key, bothKeys, &bothKeysSz);
if (ret == 0) {
ret = wc_ed448_import_private_key(bothKeys, bothKeysSz, NULL, 0, &key);
if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0 ||
XMEMCMP(privKey, key.k, pubKeySz) != 0)) {
ret = SSL_FATAL_ERROR;
}
}
#endif
/* Test bad args. */
if (ret == 0) {
ret = wc_ed448_import_private_key(NULL, privKeySz, pubKey, pubKeySz,
@ -20743,6 +20793,11 @@ static int test_wc_ed448_import_private_key (void)
ret = wc_ed448_import_private_key(privKey, privKeySz, pubKey,
pubKeySz - 1, &key);
}
if (ret == BAD_FUNC_ARG) {
ret = wc_ed448_import_private_key(privKey, privKeySz, NULL,
0, &key);
}
if (ret == BAD_FUNC_ARG) {
ret = 0;
} else if (ret == 0) {

View File

@ -887,7 +887,8 @@ int SuiteTest(int argc, char** argv)
}
#endif
#endif
#if defined(HAVE_CURVE25519) && defined(HAVE_ED25519)
#if defined(HAVE_CURVE25519) && defined(HAVE_ED25519) && \
defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_VERIFY)
/* add ED25519 certificate cipher suite tests */
strcpy(argv0[1], "tests/test-ed25519.conf");
printf("starting ED25519 extra cipher suite tests\n");
@ -898,7 +899,8 @@ int SuiteTest(int argc, char** argv)
goto exit;
}
#endif
#if defined(HAVE_CURVE448) && defined(HAVE_ED448)
#if defined(HAVE_CURVE448) && defined(HAVE_ED448) && \
defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY)
/* add ED448 certificate cipher suite tests */
strcpy(argv0[1], "tests/test-ed448.conf");
printf("starting ED448 extra cipher suite tests\n");

View File

@ -5953,8 +5953,8 @@ void bench_ed25519KeySign(void)
byte sig[ED25519_SIG_SIZE];
byte msg[512];
word32 x = 0;
#endif
const char**desc = bench_desc_words[lng_index];
#endif
wc_ed25519_init(&genKey);
@ -6110,8 +6110,8 @@ void bench_ed448KeySign(void)
byte sig[ED448_SIG_SIZE];
byte msg[512];
word32 x = 0;
#endif
const char**desc = bench_desc_words[lng_index];
#endif
wc_ed448_init(&genKey);

View File

@ -7904,7 +7904,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
break;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY)
case ED25519k:
{
ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
@ -7912,7 +7912,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
break;
}
#endif
#ifdef HAVE_ED448
#if defined(HAVE_ED448) && defined(HAVE_ED448_VERIFY)
case ED448k:
{
ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
@ -14322,7 +14322,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
if (!rsaKey && !eccKey && ed25519Key) {
word32 outSz = sigSz;
@ -14330,9 +14330,9 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
if (ret == 0)
ret = outSz;
}
#endif /* HAVE_ECC */
#endif /* HAVE_ED25519 && HAVE_ED25519_SIGN */
#ifdef HAVE_ED448
#if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
word32 outSz = sigSz;
@ -14340,7 +14340,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
if (ret == 0)
ret = outSz;
}
#endif /* HAVE_ECC */
#endif /* HAVE_ED448 && HAVE_ED448_SIGN */
break;
}

View File

@ -56,30 +56,56 @@ static const byte ed25519Ctx[ED25519CTX_SIZE+1] =
"SigEd25519 no Ed25519 collisions";
#endif
static int ed25519_hash_reset(ed25519_key* key)
{
int ret;
if (key->sha_clean_flag)
ret = 0;
else {
wc_Sha512Free(&key->sha);
ret = wc_InitSha512_ex(&key->sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
}
return ret;
}
static int ed25519_hash_update(ed25519_key* key, const byte* data, word32 len)
{
if (key->sha_clean_flag)
key->sha_clean_flag = 0;
return wc_Sha512Update(&key->sha, data, len);
}
static int ed25519_hash_final(ed25519_key* key, byte* hash)
{
int ret = wc_Sha512Final(&key->sha, hash);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
}
static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen,
byte* hash)
{
int ret;
wc_Sha512 sha;
int devId = INVALID_DEVID;
if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLF_CRYPTO_CB
devId = key->devId;
#endif
ret = ed25519_hash_reset(key);
if (ret == 0)
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, hash);
ret = wc_InitSha512_ex(&sha, NULL, devId);
if (ret == 0) {
ret = wc_Sha512Update(&sha, in, inLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, hash);
wc_Sha512Free(&sha);
}
(void)devId;
return ret;
}
@ -187,9 +213,7 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
byte nonce[WC_SHA512_DIGEST_SIZE];
byte hram[WC_SHA512_DIGEST_SIZE];
byte az[ED25519_PRV_KEY_SIZE];
wc_Sha512 sha;
int ret;
int devId = INVALID_DEVID;
/* sanity check on arguments */
if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
@ -198,8 +222,7 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
}
#ifdef WOLF_CRYPTO_CB
devId = key->devId;
if (devId != INVALID_DEVID) {
if (key->devId != INVALID_DEVID) {
ret = wc_CryptoCb_Ed25519Sign(in, inLen, out, outLen, key, type,
context, contextLen);
if (ret != CRYPTOCB_UNAVAILABLE)
@ -229,25 +252,23 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
az[31] |= 64;
ret = wc_InitSha512_ex(&sha, NULL, devId);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
ret = ed25519_hash_update(key, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
ret = ed25519_hash_update(key, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
ret = ed25519_hash_update(key, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, in, inLen);
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, nonce);
wc_Sha512Free(&sha);
ret = ed25519_hash_final(key, nonce);
if (ret != 0)
return ret;
@ -269,27 +290,23 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
/* step 3: hash R + public key + message getting H(R,A,M) then
creating S = (r + H(R,A,M)a) mod l */
ret = wc_InitSha512_ex(&sha, NULL, devId);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
ret = ed25519_hash_update(key, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
ret = ed25519_hash_update(key, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);
ret = ed25519_hash_update(key, out, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, in, inLen);
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, hram);
wc_Sha512Free(&sha);
ret = ed25519_hash_final(key, hram);
if (ret != 0)
return ret;
@ -301,7 +318,6 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
#endif
(void)devId;
return ret;
}
@ -388,18 +404,76 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
#ifdef HAVE_ED25519_VERIFY
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
key Ed25519 public key
return 0 on success
type variant to use -- Ed25519, Ed25519ctx, or Ed25519ph
context extra signing data
contextLen length of extra signing data
*/
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
byte type, const byte* context, byte contextLen)
{
int ret;
/* sanity check on arguments */
if (sig == NULL || key == NULL ||
(context == NULL && contextLen != 0)) {
return BAD_FUNC_ARG;
}
/* check on basics needed to verify signature */
if (sigLen != ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
return BAD_FUNC_ARG;
/* find H(R,A,M) and store it as h */
ret = ed25519_hash_reset(key);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, &type, sizeof(type));
if (ret == 0)
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, context, contextLen);
}
if (ret == 0)
ret = ed25519_hash_update(key, sig, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE);
return ret;
}
/*
msgSegment an array of bytes containing a message segment
msgSegmentLen length of msgSegment
key Ed25519 public key
return 0 on success
*/
int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed25519_key* key) {
/* sanity check on arguments */
if (msgSegment == NULL || key == NULL)
return BAD_FUNC_ARG;
return ed25519_hash_update(key, msgSegment, msgSegmentLen);
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
msg the array of bytes containing the message
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
byte type, const byte* context, byte contextLen)
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
ed25519_key* key)
{
byte rcheck[ED25519_KEY_SIZE];
byte h[WC_SHA512_DIGEST_SIZE];
@ -408,14 +482,10 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
ge_p2 R;
#endif
int ret;
int devId = INVALID_DEVID;
wc_Sha512 sha;
/* sanity check on arguments */
if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
(context == NULL && contextLen != 0)) {
if (sig == NULL || res == NULL || key == NULL)
return BAD_FUNC_ARG;
}
/* set verification failed by default */
*res = 0;
@ -424,17 +494,6 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
if (sigLen != ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
return BAD_FUNC_ARG;
#ifdef WOLF_CRYPTO_CB
devId = key->devId;
if (devId != INVALID_DEVID) {
ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key,
type, context, contextLen);
if (ret != CRYPTOCB_UNAVAILABLE)
return ret;
/* fall-through when unavailable */
}
#endif
/* uncompress A (public key), test if valid, and negate it */
#ifndef FREESCALE_LTC_ECC
if (ge_frombytes_negate_vartime(&A, key->p) != 0)
@ -442,27 +501,8 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
#endif
/* find H(R,A,M) and store it as h */
ret = wc_InitSha512_ex(&sha, NULL, devId);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, msg, msgLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, h);
wc_Sha512Free(&sha);
ret = ed25519_hash_final(key, h);
if (ret != 0)
return ret;
@ -485,16 +525,59 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
/* comparison of R created to R in sig */
ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
if (ret != 0)
return SIG_VERIFY_E;
if (ret != 0) {
ret = SIG_VERIFY_E;
} else {
/* set the verification status */
*res = 1;
}
/* set the verification status */
*res = 1;
(void)devId;
return ret;
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
msg the array of bytes containing the message
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
byte type, const byte* context, byte contextLen)
{
int ret;
/* sanity check on arguments */
if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
(context == NULL && contextLen != 0))
return BAD_FUNC_ARG;
#ifdef WOLF_CRYPTO_CB
if (key->devId != INVALID_DEVID) {
ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key,
type, context, contextLen);
if (ret != CRYPTOCB_UNAVAILABLE)
return ret;
/* fall-through when unavailable */
}
#endif
ret = wc_ed25519_verify_msg_init(sig, sigLen, key,
type, context, contextLen);
if (ret < 0)
return ret;
ret = wc_ed25519_verify_msg_update(msg, msgLen, key);
if (ret < 0)
return ret;
return wc_ed25519_verify_msg_final(sig, sigLen, res, key);
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
@ -580,6 +663,8 @@ int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
/* initialize information and memory for key */
int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
{
int ret;
if (key == NULL)
return BAD_FUNC_ARG;
@ -589,13 +674,24 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
#else
(void)devId;
#endif
(void)heap; /* if needed for XMALLOC/XFREE in future */
key->heap = heap;
#ifndef FREESCALE_LTC_ECC
fe_init();
#endif
return 0;
ret = wc_InitSha512_ex(&key->sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
}
int wc_ed25519_init(ed25519_key* key)
@ -609,6 +705,8 @@ void wc_ed25519_free(ed25519_key* key)
if (key == NULL)
return;
wc_Sha512Free(&key->sha);
ForceZero(key, sizeof(ed25519_key));
}
@ -735,8 +833,17 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
return 0;
}
/*
For importing a private key and its associated public key.
/* 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)
@ -744,13 +851,24 @@ int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
int ret;
/* sanity check on arguments */
if (priv == NULL || pub == NULL || key == NULL)
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED25519_KEY_SIZE || pubSz < ED25519_PUB_KEY_SIZE)
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;
}
/* import public key */
ret = wc_ed25519_import_public(pub, pubSz, key);
if (ret != 0)

View File

@ -51,6 +51,60 @@
static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448";
#endif
static int ed448_hash_reset(ed448_key* key)
{
int ret;
if (key->sha_clean_flag)
ret = 0;
else {
wc_Shake256_Free(&key->sha);
ret = wc_InitShake256(&key->sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
}
return ret;
}
static int ed448_hash_update(ed448_key* key, const byte* data, word32 len)
{
if (key->sha_clean_flag)
key->sha_clean_flag = 0;
return wc_Shake256_Update(&key->sha, data, len);
}
static int ed448_hash_final(ed448_key* key, byte* hash, word32 hashLen)
{
int ret = wc_Shake256_Final(&key->sha, hash, hashLen);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
}
static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
byte* hash, word32 hashLen)
{
int ret;
if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
return BAD_FUNC_ARG;
}
ret = ed448_hash_reset(key);
if (ret == 0)
ret = ed448_hash_update(key, in, inLen);
if (ret == 0)
ret = ed448_hash_final(key, hash, hashLen);
return ret;
}
/* Derive the public key for the private key.
*
* key [in] Ed448 key object.
@ -71,9 +125,9 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az));
}
if (ret == 0)
ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
if (ret == 0) {
/* apply clamp */
az[0] &= 0xfc;
@ -129,7 +183,6 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
return ret;
}
#ifdef HAVE_ED448_SIGN
/* Sign the message using the ed448 private key.
*
@ -148,7 +201,7 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
* other -ve values when hash fails,
* 0 otherwise.
*/
static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed448_key* key, byte type,
const byte* context, byte contextLen)
{
@ -156,7 +209,6 @@ static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
byte nonce[ED448_SIG_SIZE];
byte hram[ED448_SIG_SIZE];
byte az[ED448_PRV_KEY_SIZE];
wc_Shake sha;
int ret = 0;
/* sanity check on arguments */
@ -179,7 +231,7 @@ static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
/* step 1: create nonce to use where nonce is r in
r = H(h_b, ... ,h_2b-1,M) */
ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az));
ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
}
if (ret == 0) {
/* apply clamp */
@ -187,29 +239,27 @@ static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
az[55] |= 0x80;
az[56] = 0x00;
ret = wc_InitShake256(&sha, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE);
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &type, sizeof(type));
ret = ed448_hash_update(key, &type, sizeof(type));
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen));
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = wc_Shake256_Update(&sha, context, contextLen);
ret = ed448_hash_update(key, context, contextLen);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
ret = ed448_hash_update(key, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, in, inLen);
ret = ed448_hash_update(key, in, inLen);
}
if (ret == 0) {
ret = wc_Shake256_Final(&sha, nonce, sizeof(nonce));
ret = ed448_hash_final(key, nonce, sizeof(nonce));
}
wc_Shake256_Free(&sha);
}
if (ret == 0) {
sc448_reduce(nonce);
@ -221,31 +271,29 @@ static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
/* step 3: hash R + public key + message getting H(R,A,M) then
creating S = (r + H(R,A,M)a) mod l */
ret = wc_InitShake256(&sha, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE);
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &type, sizeof(type));
ret = ed448_hash_update(key, &type, sizeof(type));
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen));
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = wc_Shake256_Update(&sha, context, contextLen);
ret = ed448_hash_update(key, context, contextLen);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, out, ED448_SIG_SIZE/2);
ret = ed448_hash_update(key, out, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE);
ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, in, inLen);
ret = ed448_hash_update(key, in, inLen);
}
if (ret == 0) {
ret = wc_Shake256_Final(&sha, hram, sizeof(hram));
ret = ed448_hash_final(key, hram, sizeof(hram));
}
wc_Shake256_Free(&sha);
}
}
@ -277,7 +325,7 @@ static int ed448_sign_msg(const byte* in, word32 inLen, byte* out,
int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
ed448_key* key, const byte* context, byte contextLen)
{
return ed448_sign_msg(in, inLen, out, outLen, key, Ed448, context,
return wc_ed448_sign_msg_ex(in, inLen, out, outLen, key, Ed448, context,
contextLen);
}
@ -302,8 +350,8 @@ int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
word32 *outLen, ed448_key* key,
const byte* context, byte contextLen)
{
return ed448_sign_msg(hash, hashLen, out, outLen, key, Ed448ph, context,
contextLen);
return wc_ed448_sign_msg_ex(hash, hashLen, out, outLen, key, Ed448ph,
context, contextLen);
}
/* Sign the message using the ed448 private key.
@ -329,7 +377,8 @@ int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
int ret = 0;
byte hash[64];
ret = wc_Shake256Hash(in, inLen, hash, sizeof(hash));
ret = ed448_hash(key, in, inLen, hash, sizeof(hash));
if (ret == 0) {
ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key,
context, contextLen);
@ -345,8 +394,6 @@ int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
*
* sig [in] Signature to verify.
* sigLen [in] Size of signature in bytes.
* msg [in] Message to verify.
* msgLen [in] Length of the message in bytes.
* key [in] Ed448 key to use to verify.
* type [in] Type of signature to verify: Ed448 or Ed448ph
* context [in] Context of verification.
@ -357,93 +404,160 @@ int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
* other -ve values when hash fails,
* 0 otherwise.
*/
static int ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed448_key* key,
byte type, const byte* context, byte contextLen)
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
byte type, const byte* context, byte contextLen)
{
int ret;
/* sanity check on arguments */
if ((sig == NULL) || (key == NULL) ||
((context == NULL) && (contextLen != 0))) {
return BAD_FUNC_ARG;
}
/* check on basics needed to verify signature */
if (sigLen != ED448_SIG_SIZE) {
return BAD_FUNC_ARG;
}
/* find H(R,A,M) and store it as h */
ret = ed448_hash_reset(key);
if (ret < 0)
return ret;
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = ed448_hash_update(key, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = ed448_hash_update(key, context, contextLen);
}
if (ret == 0) {
ret = ed448_hash_update(key, sig, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE);
}
return ret;
}
/*
msgSegment an array of bytes containing a message segment
msgSegmentLen length of msgSegment
key Ed448 public key
return 0 on success
*/
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed448_key* key)
{
/* sanity check on arguments */
if (msgSegment == NULL || key == NULL)
return BAD_FUNC_ARG;
return ed448_hash_update(key, msgSegment, msgSegmentLen);
}
/* Verify the message using the ed448 public key.
*
* sig [in] Signature to verify.
* sigLen [in] Size of signature in bytes.
* res [out] *res is set to 1 on successful verification.
* key [in] Ed448 key to use to verify.
* returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
* BUFFER_E when sigLen is less than ED448_SIG_SIZE,
* other -ve values when hash fails,
* 0 otherwise.
*/
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
int* res, ed448_key* key)
{
byte rcheck[ED448_KEY_SIZE];
byte h[ED448_SIG_SIZE];
ge448_p2 A;
ge448_p2 R;
int ret = 0;
wc_Shake sha;
int ret;
/* sanity check on arguments */
if ((sig == NULL) || (msg == NULL) || (res == NULL) || (key == NULL) ||
((context == NULL) && (contextLen != 0))) {
ret = BAD_FUNC_ARG;
}
if ((sig == NULL) || (res == NULL) || (key == NULL))
return BAD_FUNC_ARG;
if (ret == 0) {
/* set verification failed by default */
*res = 0;
/* set verification failed by default */
*res = 0;
/* check on basics needed to verify signature */
if (sigLen != ED448_SIG_SIZE) {
ret = BAD_FUNC_ARG;
}
}
/* check on basics needed to verify signature */
if (sigLen != ED448_SIG_SIZE)
return BAD_FUNC_ARG;
/* uncompress A (public key), test if valid, and negate it */
if ((ret == 0) && (ge448_from_bytes_negate_vartime(&A, key->p) != 0)) {
ret = BAD_FUNC_ARG;
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
return BAD_FUNC_ARG;
ret = ed448_hash_final(key, h, sizeof(h));
if (ret != 0)
return ret;
sc448_reduce(h);
/* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
* SB - H(R,A,M)A saving decompression of R
*/
ret = ge448_double_scalarmult_vartime(&R, h, &A,
sig + (ED448_SIG_SIZE/2));
if (ret != 0)
return ret;
ge448_to_bytes(rcheck, &R);
/* comparison of R created to R in sig */
if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) {
ret = SIG_VERIFY_E;
}
if (ret == 0) {
/* find H(R,A,M) and store it as h */
ret = wc_InitShake256(&sha, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &type, sizeof(type));
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = wc_Shake256_Update(&sha, context, contextLen);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, sig, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE);
}
if (ret == 0) {
ret = wc_Shake256_Update(&sha, msg, msgLen);
}
if (ret == 0) {
ret = wc_Shake256_Final(&sha, h, sizeof(h));
}
wc_Shake256_Free(&sha);
}
}
if (ret == 0) {
sc448_reduce(h);
/* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
* SB - H(R,A,M)A saving decompression of R
*/
ret = ge448_double_scalarmult_vartime(&R, h, &A,
sig + (ED448_SIG_SIZE/2));
}
if (ret == 0) {
ge448_to_bytes(rcheck, &R);
/* comparison of R created to R in sig */
if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) {
ret = SIG_VERIFY_E;
}
else {
/* set the verification status */
*res = 1;
}
else {
/* set the verification status */
*res = 1;
}
return ret;
}
/* Verify the message using the ed448 public key.
*
* sig [in] Signature to verify.
* sigLen [in] Size of signature in bytes.
* msg [in] Message to verify.
* msgLen [in] Length of the message in bytes.
* res [out] *res is set to 1 on successful verification.
* key [in] Ed448 key to use to verify.
* type [in] Type of signature to verify: Ed448 or Ed448ph
* context [in] Context of verification.
* contextLen [in] Length of context in bytes.
* returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
* context is not NULL or public key not set,
* BUFFER_E when sigLen is less than ED448_SIG_SIZE,
* other -ve values when hash fails,
* 0 otherwise.
*/
int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed448_key* key,
byte type, const byte* context, byte contextLen)
{
int ret;
ret = wc_ed448_verify_msg_init(sig, sigLen, key,
type, context, contextLen);
if (ret < 0)
return ret;
ret = wc_ed448_verify_msg_update(msg, msgLen, key);
if (ret < 0)
return ret;
return wc_ed448_verify_msg_final(sig, sigLen, res, key);
}
/* Verify the message using the ed448 public key.
* Signature type is Ed448.
*
@ -464,7 +578,7 @@ int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed448_key* key,
const byte* context, byte contextLen)
{
return ed448_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed448,
return wc_ed448_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, Ed448,
context, contextLen);
}
@ -488,7 +602,7 @@ int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
word32 hashLen, int* res, ed448_key* key,
const byte* context, byte contextLen)
{
return ed448_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed448ph,
return wc_ed448_verify_msg_ex(sig, sigLen, hash, hashLen, res, key, Ed448ph,
context, contextLen);
}
@ -515,7 +629,8 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
int ret = 0;
byte hash[64];
ret = wc_Shake256Hash(msg, msgLen, hash, sizeof(hash));
ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash));
if (ret == 0) {
ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
context, contextLen);
@ -528,24 +643,49 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
/* Initialize the ed448 private/public key.
*
* key [in] Ed448 key.
* heap [in] heap pointer to pass to wc_InitShake256().
* returns BAD_FUNC_ARG when key is NULL
*/
int wc_ed448_init(ed448_key* key)
int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
{
int ret = 0;
int ret;
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
XMEMSET(key, 0, sizeof(ed448_key));
if (key == NULL)
return BAD_FUNC_ARG;
fe448_init();
}
XMEMSET(key, 0, sizeof(ed448_key));
#ifdef WOLF_CRYPTO_CB
key->devId = devId;
#else
(void)devId;
#endif
key->heap = heap;
fe448_init();
ret = wc_InitShake256(&key->sha, heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
}
/* Initialize the ed448 private/public key.
*
* key [in] Ed448 key.
* returns BAD_FUNC_ARG when key is NULL
*/
int wc_ed448_init(ed448_key* key) {
return wc_ed448_init_ex(key, NULL, INVALID_DEVID);
}
/* Clears the ed448 key data
*
@ -554,6 +694,7 @@ int wc_ed448_init(ed448_key* key)
void wc_ed448_free(ed448_key* key)
{
if (key != NULL) {
wc_Shake256_Free(&key->sha);
ForceZero(key, sizeof(ed448_key));
}
}
@ -681,46 +822,55 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz,
return ret;
}
/* Import an ed448 private and public keys from a byte arrays.
/* Import an ed448 private and public keys from byte array(s).
*
* priv [in] Array holding 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 private key.
* pubSz [in] Number of bytes of data in public 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 parameter is NULL or privSz is less than
* ED448_KEY_SIZE or pubSz is less than ED448_PUB_KEY_SIZE,
* 0 otherwise.
* 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 ret = 0;
int ret;
/* sanity check on arguments */
if ((priv == NULL) || (pub == NULL) || (key == NULL)) {
ret = BAD_FUNC_ARG;
}
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if ((ret == 0) && ((privSz < ED448_KEY_SIZE) ||
(pubSz < ED448_PUB_KEY_SIZE))) {
ret = BAD_FUNC_ARG;
if (privSz < ED448_KEY_SIZE)
return BAD_FUNC_ARG;
if (pub == NULL) {
if (pubSz != 0)
return BAD_FUNC_ARG;
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) {
return BAD_FUNC_ARG;
}
if (ret == 0) {
/* import public key */
ret = wc_ed448_import_public(pub, pubSz, key);
}
if (ret == 0) {
/* 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);
}
/* import public key */
ret = wc_ed448_import_public(pub, pubSz, key);
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;
}
#endif /* HAVE_ED448_KEY_IMPORT */

View File

@ -544,14 +544,14 @@ static int _Transform_Sha512(wc_Sha512* sha512)
#ifdef WOLFSSL_SMALL_STACK_CACHE
word64* W = sha512->W;
if (W == NULL) {
W = (word64*)XMALLOC(sizeof(word64) * 16, NULL,DYNAMIC_TYPE_TMP_BUFFER);
W = (word64*)XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (W == NULL)
return MEMORY_E;
sha512->W = W;
}
#elif defined(WOLFSSL_SMALL_STACK)
word64* W;
W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
W = (word64*) XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (W == NULL)
return MEMORY_E;
#else
@ -595,7 +595,7 @@ static int _Transform_Sha512(wc_Sha512* sha512)
ForceZero(T, sizeof(T));
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return 0;
@ -940,7 +940,7 @@ void wc_Sha512Free(wc_Sha512* sha512)
#ifdef WOLFSSL_SMALL_STACK_CACHE
if (sha512->W != NULL) {
XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
sha512->W = NULL;
}
#endif
@ -960,7 +960,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
/* back up buffer */
#if defined(WOLFSSL_SMALL_STACK)
word64* buffer;
buffer = (word64*) XMALLOC(sizeof(word64) * 16, NULL,
buffer = (word64*) XMALLOC(sizeof(word64) * 16, sha->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (buffer == NULL)
return MEMORY_E;
@ -971,7 +971,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
/* sanity check */
if (sha == NULL || data == NULL) {
#if defined(WOLFSSL_SMALL_STACK)
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BAD_FUNC_ARG;
}
@ -998,7 +998,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE);
#if defined(WOLFSSL_SMALL_STACK)
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
@ -1191,7 +1191,7 @@ void wc_Sha384Free(wc_Sha384* sha384)
#ifdef WOLFSSL_SMALL_STACK_CACHE
if (sha384->W != NULL) {
XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(sha384->W, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER);
sha384->W = NULL;
}
#endif

View File

@ -25143,6 +25143,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
int i;
word32 outlen;
#ifdef HAVE_ED25519_VERIFY
int j;
int verify;
#endif /* HAVE_ED25519_VERIFY */
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */
@ -25501,9 +25502,11 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
};
word32 idx;
ed25519_key key3;
#endif /* NO_ASN */
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */
#if !defined(NO_ASN) && defined(HAVE_ED25519_SIGN)
ed25519_key key3;
#endif
/* create ed25519 keys */
#ifndef HAVE_FIPS
@ -25516,7 +25519,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
wc_ed25519_init_ex(&key, HEAP_HINT, devId);
wc_ed25519_init_ex(&key2, HEAP_HINT, devId);
#ifndef NO_ASN
#if !defined(NO_ASN) && defined(HAVE_ED25519_SIGN)
wc_ed25519_init_ex(&key3, HEAP_HINT, devId);
#endif
wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key);
@ -25548,6 +25551,18 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
&key) != 0 || verify != 1)
return -11031 - i;
/* test verify on good msg using streaming interface directly */
if (wc_ed25519_verify_msg_init(out, outlen,
&key, (byte)Ed25519, NULL, 0) != 0)
return -11211 - i;
for (j = 0; j < msgSz[i]; j += i) {
if (wc_ed25519_verify_msg_update(msgs[i] + j, MIN(i, msgSz[i] - j), &key) != 0)
return -11221 - i;
}
if (wc_ed25519_verify_msg_final(out, outlen, &verify,
&key) != 0 || verify != 1)
return -11231 - i;
/* test verify on bad msg */
out[outlen-1] = out[outlen-1] + 1;
if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify,
@ -26232,22 +26247,25 @@ static int ed448_ctx_test(void)
outlen = sizeof(out);
XMEMSET(out, 0, sizeof(out));
if (wc_ed448_init_ex(&key, HEAP_HINT, devId) != 0)
return -11500;
if (wc_ed448_import_private_key(sKeyCtx, ED448_KEY_SIZE, pKeyCtx,
sizeof(pKeyCtx), &key) != 0)
return -11500;
return -11501;
if (wc_ed448_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key,
contextCtx, sizeof(contextCtx)) != 0)
return -11501;
return -11502;
if (XMEMCMP(out, sigCtx, sizeof(sigCtx)))
return -11502;
return -11503;
#if defined(HAVE_ED448_VERIFY)
/* test verify on good msg */
if (wc_ed448_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key,
contextCtx, sizeof(contextCtx)) != 0 || verify != 1)
return -11503;
return -11504;
#endif
wc_ed448_free(&key);
@ -26345,72 +26363,75 @@ static int ed448ph_test(void)
outlen = sizeof(out);
XMEMSET(out, 0, sizeof(out));
if (wc_ed448_init_ex(&key, HEAP_HINT, devId) != 0)
return -11600;
if (wc_ed448_import_private_key(sKeyPh, ED448_KEY_SIZE, pKeyPh,
sizeof(pKeyPh), &key) != 0) {
return -11600;
return -11601;
}
if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL,
0) != 0) {
return -11601;
return -11602;
}
if (XMEMCMP(out, sigPh1, sizeof(sigPh1)))
return -11602;
return -11603;
#if defined(HAVE_ED448_VERIFY)
/* test verify on good msg */
if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key,
NULL, 0) != 0 || verify != 1) {
return -11603;
return -11604;
}
#endif
if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key,
contextPh2, sizeof(contextPh2)) != 0) {
return -11604;
return -11605;
}
if (XMEMCMP(out, sigPh2, sizeof(sigPh2)))
return -11605;
return -11606;
#if defined(HAVE_ED448_VERIFY)
/* test verify on good msg */
if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key,
contextPh2, sizeof(contextPh2)) != 0 ||
verify != 1) {
return -11606;
return -11607;
}
#endif
if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL,
0) != 0) {
return -11607;
return -11608;
}
if (XMEMCMP(out, sigPh1, sizeof(sigPh1)))
return -11608;
return -11609;
#if defined(HAVE_ED448_VERIFY)
if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
&key, NULL, 0) != 0 || verify != 1) {
return -11609;
return -11610;
}
#endif
if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key,
contextPh2, sizeof(contextPh2)) != 0) {
return -11610;
return -11611;
}
if (XMEMCMP(out, sigPh2, sizeof(sigPh2)))
return -11611;
return -11612;
#if defined(HAVE_ED448_VERIFY)
if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
&key, contextPh2, sizeof(contextPh2)) != 0 ||
verify != 1) {
return -11612;
return -11613;
}
#endif
@ -26434,6 +26455,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
int i;
word32 outlen;
#ifdef HAVE_ED448_VERIFY
int j;
int verify;
#endif /* HAVE_ED448_VERIFY */
#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */
@ -26892,9 +26914,11 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
};
word32 idx;
ed448_key key3;
#endif /* NO_ASN */
#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */
#if !defined(NO_ASN) && defined(HAVE_ED448_SIGN)
ed448_key key3;
#endif
/* create ed448 keys */
#ifndef HAVE_FIPS
@ -26907,7 +26931,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
wc_ed448_init(&key);
wc_ed448_init(&key2);
#ifndef NO_ASN
#if !defined(NO_ASN) && defined(HAVE_ED448_SIGN)
wc_ed448_init(&key3);
#endif
wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key);
@ -26942,6 +26966,18 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
return -11731 - i;
}
/* test verify on good msg using streaming interface directly */
if (wc_ed448_verify_msg_init(out, outlen,
&key, (byte)Ed448, NULL, 0) != 0)
return -11911 - i;
for (j = 0; j < msgSz[i]; j += i) {
if (wc_ed448_verify_msg_update(msgs[i] + j, MIN(i, msgSz[i] - j), &key) != 0)
return -11921 - i;
}
if (wc_ed448_verify_msg_final(out, outlen, &verify,
&key) != 0 || verify != 1)
return -11931 - i;
/* test verify on bad msg */
out[outlen-2] = out[outlen-2] + 1;
if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key,
@ -30219,7 +30255,7 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz,
keyId = 1;
}
#else
keyId = *(int*)(keyIdRaw + 2);
XMEMCPY(&keyId, keyIdRaw + 2, sizeof(keyId));
#endif
}
@ -37052,6 +37088,7 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
/* reset devId */
info->pk.ed25519kg.key->devId = devIdArg;
}
#ifdef HAVE_ED25519_SIGN
else if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
/* set devId to invalid, so software is used */
info->pk.ed25519sign.key->devId = INVALID_DEVID;
@ -37065,6 +37102,8 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
/* reset devId */
info->pk.ed25519sign.key->devId = devIdArg;
}
#endif
#ifdef HAVE_ED25519_VERIFY
else if (info->pk.type == WC_PK_TYPE_ED25519_VERIFY) {
/* set devId to invalid, so software is used */
info->pk.ed25519verify.key->devId = INVALID_DEVID;
@ -37079,6 +37118,7 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
/* reset devId */
info->pk.ed25519verify.key->devId = devIdArg;
}
#endif
#endif /* HAVE_ED25519 */
}
else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {

View File

@ -3698,6 +3698,7 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
#ifdef HAVE_ED25519_SIGN
static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
{
@ -3734,8 +3735,10 @@ static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
return ret;
}
#endif /* HAVE_ED25519_SIGN */
#ifdef HAVE_ED25519_VERIFY
static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
const byte* msg, word32 msgSz, const byte* key, word32 keySz,
int* result, void* ctx)
@ -3762,6 +3765,7 @@ static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz
return ret;
}
#endif /* HAVE_ED25519_VERIFY */
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
@ -3858,6 +3862,7 @@ static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ED448
#ifdef HAVE_ED448_SIGN
static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
{
@ -3894,8 +3899,10 @@ static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
return ret;
}
#endif /* HAVE_ED448_SIGN */
#ifdef HAVE_ED448_VERIFY
static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
const byte* msg, word32 msgSz, const byte* key, word32 keySz,
int* result, void* ctx)
@ -3924,6 +3931,7 @@ static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
return ret;
}
#endif /* HAVE_ED448_VERIFY */
#endif /* HAVE_ED448 */
#ifdef HAVE_CURVE448
@ -4436,16 +4444,24 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx)
wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback);
#endif
#ifdef HAVE_ED25519
#ifdef HAVE_ED25519_SIGN
wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
#endif
#ifdef HAVE_ED25519_VERIFY
wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
#endif
#endif
#ifdef HAVE_CURVE25519
wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen);
wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
#endif
#ifdef HAVE_ED448
#ifdef HAVE_ED448_SIGN
wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign);
#endif
#ifdef HAVE_ED448_VERIFY
wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify);
#endif
#endif
#ifdef HAVE_CURVE448
wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen);

View File

@ -34,6 +34,9 @@
#include <wolfssl/wolfcrypt/fe_operations.h>
#include <wolfssl/wolfcrypt/ge_operations.h>
#include <wolfssl/wolfcrypt/random.h>
#ifndef WOLFSSL_SHA512
#error ED25519 requires SHA512
#endif
#include <wolfssl/wolfcrypt/sha512.h>
#ifdef WOLFSSL_ASYNC_CRYPT
@ -90,6 +93,9 @@ struct ed25519_key {
#if defined(WOLF_CRYPTO_CB)
int devId;
#endif
void *heap;
wc_Sha512 sha;
int sha_clean_flag;
};
@ -98,6 +104,7 @@ int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
word32 pubKeySz);
WOLFSSL_API
int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
#ifdef HAVE_ED25519_SIGN
WOLFSSL_API
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key);
@ -117,6 +124,8 @@ WOLFSSL_API
int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key, byte type,
const byte* context, byte contextLen);
#endif /* HAVE_ED25519_SIGN */
#ifdef HAVE_ED25519_VERIFY
WOLFSSL_API
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed25519_key* key);
@ -136,6 +145,17 @@ WOLFSSL_API
int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
byte type, const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
byte type, const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed25519_key* key);
WOLFSSL_API
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
ed25519_key* key);
#endif /* HAVE_ED25519_VERIFY */
WOLFSSL_API
int wc_ed25519_init(ed25519_key* key);

View File

@ -34,6 +34,9 @@
#include <wolfssl/wolfcrypt/fe_448.h>
#include <wolfssl/wolfcrypt/ge_448.h>
#include <wolfssl/wolfcrypt/random.h>
#ifndef WOLFSSL_SHAKE256
#error ED448 requires SHAKE256
#endif
#include <wolfssl/wolfcrypt/sha3.h>
#ifdef WOLFSSL_ASYNC_CRYPT
@ -86,6 +89,12 @@ struct ed448_key {
#ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev;
#endif
#if defined(WOLF_CRYPTO_CB)
int devId;
#endif
void *heap;
wc_Shake sha;
int sha_clean_flag;
};
@ -94,6 +103,7 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey,
word32 pubKeySz);
WOLFSSL_API
int wc_ed448_make_key(WC_RNG* rng, int keysize, ed448_key* key);
#ifdef HAVE_ED448_SIGN
WOLFSSL_API
int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
ed448_key* key, const byte* context, byte contextLen);
@ -102,9 +112,28 @@ int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
word32 *outLen, ed448_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed448_key* key, byte type,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed448_key* key, const byte* context,
byte contextLen);
#endif /* HAVE_ED448_SIGN */
#ifdef HAVE_ED448_VERIFY
WOLFSSL_API
int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed448_key* key,
byte type, const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
byte type, const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed448_key* key);
WOLFSSL_API
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
int* stat, ed448_key* key);
WOLFSSL_API
int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed448_key* key,
@ -117,6 +146,9 @@ WOLFSSL_API
int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed448_key* key,
const byte* context, byte contextLen);
#endif /* HAVE_ED448_VERIFY */
WOLFSSL_API
int wc_ed448_init_ex(ed448_key* key, void *heap, int devId);
WOLFSSL_API
int wc_ed448_init(ed448_key* key);
WOLFSSL_API