diff --git a/src/internal.c b/src/internal.c index e424da276..e495407cd 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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 */ diff --git a/src/ssl.c b/src/ssl.c index f9c18f1e6..41bf31590 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -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 */ diff --git a/tests/api.c b/tests/api.c index 661af1dab..92e60ef1e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -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) { diff --git a/tests/suites.c b/tests/suites.c index cd554f96e..f827cd00a 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -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"); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 68fa3dbf6..3344ee6d5 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -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); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 61c3d10f8..25f6bd2a2 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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; } diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 2df7e13b8..b24c9985d 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -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) diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index bb401d28c..44d62efb9 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -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 */ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 0ee9e52f6..f8d98fb14 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -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 diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 42a05daaa..7452b0f49 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -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) { diff --git a/wolfssl/test.h b/wolfssl/test.h index 6aca33bb1..09dcd41a4 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -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); diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 728992363..443459757 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -34,6 +34,9 @@ #include #include #include +#ifndef WOLFSSL_SHA512 +#error ED25519 requires SHA512 +#endif #include #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); diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index d45585a3f..ff7caf88a 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -34,6 +34,9 @@ #include #include #include +#ifndef WOLFSSL_SHAKE256 +#error ED448 requires SHAKE256 +#endif #include #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