From 9b43e57ccf0f6b4132cffb1c4ea9ece941c413ea Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 13 Jul 2021 13:16:15 -0500 Subject: [PATCH 1/7] 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. --- src/internal.c | 44 ++++ src/ssl.c | 44 ++-- tests/api.c | 55 +++++ tests/suites.c | 6 +- wolfcrypt/benchmark/benchmark.c | 4 +- wolfcrypt/src/asn.c | 12 +- wolfcrypt/src/ed25519.c | 306 ++++++++++++++++------- wolfcrypt/src/ed448.c | 424 +++++++++++++++++++++----------- wolfcrypt/src/sha512.c | 16 +- wolfcrypt/test/test.c | 84 +++++-- wolfssl/test.h | 16 ++ wolfssl/wolfcrypt/ed25519.h | 20 ++ wolfssl/wolfcrypt/ed448.h | 32 +++ 13 files changed, 778 insertions(+), 285 deletions(-) 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 From 5e8da2348fa6ae4d49fe090046708b784e0e7ac5 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 14 Jul 2021 15:32:33 -0500 Subject: [PATCH 2/7] ED: add --enable-ed25519-stream and --enable-ed448-stream to configure.ac, disabled by default, and add them to --enable-all and --enable-all-crypto lists, along with --enable-aesgcm-stream; report AES-GCM and ED* streaming API options in feature summary rendered at end; refactor ED routines to pivot on WOLFSSL_ED*_PERSISTENT_SHA and WOLFSSL_ED*_STREAMING_VERIFY macros, with sha state in the key struct only when WOLFSSL_ED*_PERSISTENT_SHA, otherwise on the stack as before; add ed*_hash_init() and ed*_hash_free() local helpers; ED* peer review: fix line lengths, remove superfluous retval checks, tweaks for efficiency, and add ED448_PREHASH_SIZE to ed448.h. --- configure.ac | 43 +++++- wolfcrypt/src/ed25519.c | 270 +++++++++++++++++++++++++--------- wolfcrypt/src/ed448.c | 274 +++++++++++++++++++++++++---------- wolfcrypt/test/test.c | 8 + wolfssl/wolfcrypt/ed25519.h | 4 + wolfssl/wolfcrypt/ed448.h | 5 + wolfssl/wolfcrypt/settings.h | 8 + 7 files changed, 462 insertions(+), 150 deletions(-) diff --git a/configure.ac b/configure.ac index b25fb2389..0caa104dd 100644 --- a/configure.ac +++ b/configure.ac @@ -350,6 +350,7 @@ then test "$enable_atomicuser" = "" && enable_atomicuser=yes test "$enable_pkcallbacks" = "" && enable_pkcallbacks=yes test "$enable_aesgcm" = "" && enable_aesgcm=yes + test "$enable_aesgcm_stream" = "" && enable_aesgcm_stream=yes test "$enable_aesccm" = "" && enable_aesccm=yes test "$enable_aesctr" = "" && enable_aesctr=yes test "$enable_aesofb" = "" && enable_aesofb=yes @@ -459,7 +460,9 @@ then test "$enable_scep" = "" && enable_scep=yes test "$enable_pkcs7" = "" && enable_pkcs7=yes test "$enable_ed25519" = "" && enable_ed25519=yes + test "$enable_ed25519_stream" = "" && enable_ed25519_stream=yes test "$enable_ed448" = "" && enable_ed448=yes + test "$enable_ed448_stream" = "" && enable_ed448_stream=yes if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" then @@ -493,6 +496,7 @@ then test "$enable_atomicuser" = "" && enable_atomicuser=yes test "$enable_pkcallbacks" = "" && enable_pkcallbacks=yes test "$enable_aesgcm" = "" && enable_aesgcm=yes + test "$enable_aesgcm_stream" = "" && enable_aesgcm_stream=yes test "$enable_aesccm" = "" && enable_aesccm=yes test "$enable_aesctr" = "" && enable_aesctr=yes test "$enable_aesofb" = "" && enable_aesofb=yes @@ -561,7 +565,9 @@ then then test "$enable_xchacha" = "" && enable_xchacha=yes test "$enable_ed25519" = "" && enable_ed25519=yes + test "$enable_ed25519_stream" = "" && enable_ed25519_stream=yes test "$enable_ed448" = "" && enable_ed448=yes + test "$enable_ed448_stream" = "" && enable_ed448_stream=yes test "$enable_pkcs7" = "" && enable_pkcs7=yes if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" @@ -1311,7 +1317,7 @@ AC_ARG_ENABLE([aesgcm], [ ENABLED_AESGCM=yes ] ) AC_ARG_ENABLE([aesgcm-stream], - [AS_HELP_STRING([--enable-aesgcm-stream],[Enable wolfSSL AES-GCM support with streaming APIs (default: enabled)])], + [AS_HELP_STRING([--enable-aesgcm-stream],[Enable wolfSSL AES-GCM support with streaming APIs (default: disabled)])], [ ENABLED_AESGCM_STREAM=$enableval ], [ ENABLED_AESGCM_STREAM=no ] ) @@ -2141,6 +2147,11 @@ AC_ARG_ENABLE([ed25519], [ ENABLED_ED25519=$enableval ], [ ENABLED_ED25519=no ] ) +AC_ARG_ENABLE([ed25519-stream], + [AS_HELP_STRING([--enable-ed25519-stream],[Enable wolfSSL ED25519 support with streaming verify APIs (default: disabled)])], + [ ENABLED_ED25519_STREAM=$enableval ], + [ ENABLED_ED25519_STREAM=no ] + ) if test "$ENABLED_OPENSSH" = "yes" @@ -2169,6 +2180,17 @@ then ENABLED_CERTS=yes fi +if test "$ENABLED_ED25519_STREAM" != "no" +then + if test "$ENABLED_ED25519" = "no" + then + AC_MSG_ERROR([ED25519 verify streaming enabled but ED25519 is disabled]) + else + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY" + fi +fi + # for using memory optimization setting on both curve448 and ed448 ENABLED_CURVE448_SMALL=no @@ -2206,6 +2228,11 @@ AC_ARG_ENABLE([ed448], [ ENABLED_ED448=$enableval ], [ ENABLED_ED448=no ] ) +AC_ARG_ENABLE([ed448-stream], + [AS_HELP_STRING([--enable-ed448-stream],[Enable wolfSSL ED448 support with streaming verify APIs (default: disabled)])], + [ ENABLED_ED448_STREAM=$enableval ], + [ ENABLED_ED448_STREAM=no ] + ) if test "$ENABLED_ED448" != "no" && test "$ENABLED_32BIT" = "no" then @@ -2236,6 +2263,17 @@ then ENABLED_CERTS=yes fi +if test "$ENABLED_ED448_STREAM" != "no" +then + if test "$ENABLED_ED448" = "no" + then + AC_MSG_ERROR([ED448 verify streaming enabled but ED448 is disabled]) + else + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ED448_STREAMING_VERIFY" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ED448_STREAMING_VERIFY" + fi +fi + # FP ECC, Fixed Point cache ECC @@ -6671,6 +6709,7 @@ echo " * AES-NI: $ENABLED_AESNI" echo " * AES-CBC: $ENABLED_AESCBC" echo " * AES-CBC length checks: $ENABLED_AESCBC_LENGTH_CHECKS" echo " * AES-GCM: $ENABLED_AESGCM" +echo " * AES-GCM streaming: $ENABLED_AESGCM_STREAM" echo " * AES-CCM: $ENABLED_AESCCM" echo " * AES-CTR: $ENABLED_AESCTR" echo " * AES-CFB: $ENABLED_AESCFB" @@ -6722,8 +6761,10 @@ echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES" echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ" echo " * CURVE25519: $ENABLED_CURVE25519" echo " * ED25519: $ENABLED_ED25519" +echo " * ED25519 streaming: $ENABLED_ED25519_STREAM" echo " * CURVE448: $ENABLED_CURVE448" echo " * ED448: $ENABLED_ED448" +echo " * ED448 streaming: $ENABLED_ED448_STREAM" echo " * FPECC: $ENABLED_FPECC" echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" echo " * ECCSI $ENABLED_ECCSI" diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index b24c9985d..9c31699a9 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -56,6 +56,27 @@ static const byte ed25519Ctx[ED25519CTX_SIZE+1] = "SigEd25519 no Ed25519 collisions"; #endif +static int ed25519_hash_init(ed25519_key* key, wc_Sha512 *sha) +{ + int ret; + + ret = wc_InitSha512_ex(sha, key->heap, +#if defined(WOLF_CRYPTO_CB) + key->devId +#else + INVALID_DEVID +#endif + ); + +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + if (ret == 0) + key->sha_clean_flag = 1; +#endif + + return ret; +} + +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA static int ed25519_hash_reset(ed25519_key* key) { int ret; @@ -75,36 +96,73 @@ static int ed25519_hash_reset(ed25519_key* key) } return ret; } +#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */ -static int ed25519_hash_update(ed25519_key* key, const byte* data, word32 len) +static int ed25519_hash_update(ed25519_key* key, wc_Sha512 *sha, + const byte* data, word32 len) { +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA if (key->sha_clean_flag) key->sha_clean_flag = 0; - return wc_Sha512Update(&key->sha, data, len); +#else + (void)key; +#endif + return wc_Sha512Update(sha, data, len); } -static int ed25519_hash_final(ed25519_key* key, byte* hash) +static int ed25519_hash_final(ed25519_key* key, wc_Sha512 *sha, byte* hash) { - int ret = wc_Sha512Final(&key->sha, hash); + int ret = wc_Sha512Final(sha, hash); +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA if (ret == 0) key->sha_clean_flag = 1; +#else + (void)key; +#endif return ret; } +static void ed25519_hash_free(ed25519_key* key, wc_Sha512 *sha) +{ + wc_Sha512Free(sha); +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + key->sha_clean_flag = 0; +#else + (void)key; +#endif +} + + static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen, byte* hash) { int ret; +#ifndef WOLFSSL_ED25519_PERSISTENT_SHA + wc_Sha512 sha[1]; +#else + wc_Sha512 *sha; +#endif if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) { return BAD_FUNC_ARG; } +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + sha = &key->sha; ret = ed25519_hash_reset(key); +#else + ret = ed25519_hash_init(key, sha); +#endif + if (ret < 0) + return ret; + + ret = ed25519_hash_update(key, sha, in, inLen); if (ret == 0) - ret = ed25519_hash_update(key, in, inLen); - if (ret == 0) - ret = ed25519_hash_final(key, hash); + ret = ed25519_hash_final(key, sha, hash); + +#ifndef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, sha); +#endif return ret; } @@ -252,23 +310,38 @@ 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; - if (ret != 0) - return ret; - if (type == Ed25519ctx || type == Ed25519ph) { - ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE); + { +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + wc_Sha512 *sha = &key->sha; +#else + wc_Sha512 sha[1]; + ret = ed25519_hash_init(key, sha); + if (ret < 0) + return ret; +#endif + + if (type == Ed25519ctx || type == Ed25519ph) { + ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE); + if (ret == 0) + ret = ed25519_hash_update(key, sha, &type, sizeof(type)); + if (ret == 0) + ret = ed25519_hash_update(key, sha, &contextLen, + sizeof(contextLen)); + if (ret == 0 && context != NULL) + ret = ed25519_hash_update(key, sha, context, contextLen); + } if (ret == 0) - ret = ed25519_hash_update(key, &type, sizeof(type)); + ret = ed25519_hash_update(key, sha, az + ED25519_KEY_SIZE, + ED25519_KEY_SIZE); if (ret == 0) - ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen)); - if (ret == 0 && context != NULL) - ret = ed25519_hash_update(key, context, contextLen); + ret = ed25519_hash_update(key, sha, in, inLen); + if (ret == 0) + ret = ed25519_hash_final(key, sha, nonce); +#ifndef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, sha); +#endif } - if (ret == 0) - ret = ed25519_hash_update(key, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE); - if (ret == 0) - ret = ed25519_hash_update(key, in, inLen); - if (ret == 0) - ret = ed25519_hash_final(key, nonce); + if (ret != 0) return ret; @@ -290,23 +363,39 @@ 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 */ - if (type == Ed25519ctx || type == Ed25519ph) { - ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE); + { +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + wc_Sha512 *sha = &key->sha; +#else + wc_Sha512 sha[1]; + ret = ed25519_hash_init(key, sha); + if (ret < 0) + return ret; +#endif + + if (type == Ed25519ctx || type == Ed25519ph) { + ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE); + if (ret == 0) + ret = ed25519_hash_update(key, sha, &type, sizeof(type)); + if (ret == 0) + ret = ed25519_hash_update(key, sha, &contextLen, + sizeof(contextLen)); + if (ret == 0 && context != NULL) + ret = ed25519_hash_update(key, sha, context, contextLen); + } if (ret == 0) - ret = ed25519_hash_update(key, &type, sizeof(type)); + ret = ed25519_hash_update(key, sha, out, ED25519_SIG_SIZE/2); if (ret == 0) - ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen)); - if (ret == 0 && context != NULL) - ret = ed25519_hash_update(key, context, contextLen); + ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE); + if (ret == 0) + ret = ed25519_hash_update(key, sha, in, inLen); + if (ret == 0) + ret = ed25519_hash_final(key, sha, hram); +#ifndef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, sha); +#endif } - if (ret == 0) - ret = ed25519_hash_update(key, out, ED25519_SIG_SIZE/2); - if (ret == 0) - ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE); - if (ret == 0) - ret = ed25519_hash_update(key, in, inLen); - if (ret == 0) - ret = ed25519_hash_final(key, hram); + if (ret != 0) return ret; @@ -413,10 +502,12 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out, 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) +static int ed25519_verify_msg_init_with_sha(const byte* sig, word32 sigLen, + ed25519_key* key, wc_Sha512 *sha, + byte type, const byte* context, + byte contextLen) { - int ret; + int ret; /* sanity check on arguments */ if (sig == NULL || key == NULL || @@ -430,22 +521,27 @@ int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key, /* find H(R,A,M) and store it as h */ +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA ret = ed25519_hash_reset(key); if (ret != 0) return ret; +#else + ret = 0; +#endif + if (type == Ed25519ctx || type == Ed25519ph) { - ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE); + ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE); if (ret == 0) - ret = ed25519_hash_update(key, &type, sizeof(type)); + ret = ed25519_hash_update(key, sha, &type, sizeof(type)); if (ret == 0) - ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen)); + ret = ed25519_hash_update(key, sha, &contextLen, sizeof(contextLen)); if (ret == 0 && context != NULL) - ret = ed25519_hash_update(key, context, contextLen); + ret = ed25519_hash_update(key, sha, context, contextLen); } if (ret == 0) - ret = ed25519_hash_update(key, sig, ED25519_SIG_SIZE/2); + ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2); if (ret == 0) - ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE); + ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE); return ret; } @@ -456,13 +552,15 @@ int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key, key Ed25519 public key return 0 on success */ -int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, - ed25519_key* key) { +static int ed25519_verify_msg_update_with_sha(const byte* msgSegment, + word32 msgSegmentLen, + ed25519_key* key, + wc_Sha512 *sha) { /* sanity check on arguments */ if (msgSegment == NULL || key == NULL) return BAD_FUNC_ARG; - return ed25519_hash_update(key, msgSegment, msgSegmentLen); + return ed25519_hash_update(key, sha, msgSegment, msgSegmentLen); } /* @@ -472,8 +570,9 @@ int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, key Ed25519 public key return 0 and res of 1 on success */ -int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res, - ed25519_key* key) +static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen, + int* res, ed25519_key* key, + wc_Sha512 *sha) { byte rcheck[ED25519_KEY_SIZE]; byte h[WC_SHA512_DIGEST_SIZE]; @@ -502,7 +601,7 @@ int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res, /* find H(R,A,M) and store it as h */ - ret = ed25519_hash_final(key, h); + ret = ed25519_hash_final(key, sha, h); if (ret != 0) return ret; @@ -535,6 +634,27 @@ int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res, return ret; } +#ifdef WOLFSSL_ED25519_STREAMING_VERIFY + +int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key, + byte type, const byte* context, byte contextLen) { + return ed25519_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, + type, context, contextLen); +} + +int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, + ed25519_key* key) { + return ed25519_verify_msg_update_with_sha(msgSegment, msgSegmentLen, + key, &key->sha); +} + +int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res, + ed25519_key* key) { + return ed25519_verify_msg_final_with_sha(sig, sigLen, res, + key, &key->sha); +} + +#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */ /* sig is array of bytes containing the signature @@ -550,6 +670,11 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, byte type, const byte* context, byte contextLen) { int ret; +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + wc_Sha512 *sha; +#else + wc_Sha512 sha[1]; +#endif /* sanity check on arguments */ if (sig == NULL || msg == NULL || res == NULL || key == NULL || @@ -566,16 +691,24 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, } #endif - ret = wc_ed25519_verify_msg_init(sig, sigLen, key, +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + sha = &key->sha; +#else + ret = ed25519_hash_init(key, sha); + if (ret < 0) + return ret; +#endif + + ret = ed25519_verify_msg_init_with_sha(sig, sigLen, key, sha, type, context, contextLen); if (ret < 0) return ret; - ret = wc_ed25519_verify_msg_update(msg, msgLen, key); + ret = ed25519_verify_msg_update_with_sha(msg, msgLen, key, sha); if (ret < 0) return ret; - return wc_ed25519_verify_msg_final(sig, sigLen, res, key); + return ed25519_verify_msg_final_with_sha(sig, sigLen, res, key, sha); } /* @@ -591,7 +724,7 @@ int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, ed25519_key* key) { return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, - (byte)Ed25519, NULL, 0); + (byte)Ed25519, NULL, 0); } /* @@ -610,7 +743,7 @@ int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg, const byte* context, byte contextLen) { return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, - Ed25519ctx, context, contextLen); + Ed25519ctx, context, contextLen); } /* @@ -629,7 +762,7 @@ int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash, const byte* context, byte contextLen) { return wc_ed25519_verify_msg_ex(sig, sigLen, hash, hashLen, res, key, - Ed25519ph, context, contextLen); + Ed25519ph, context, contextLen); } /* @@ -655,7 +788,7 @@ int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, return ret; return wc_ed25519_verify_msg_ex(sig, sigLen, hash, sizeof(hash), res, key, - Ed25519ph, context, contextLen); + Ed25519ph, context, contextLen); } #endif /* HAVE_ED25519_VERIFY */ @@ -663,8 +796,6 @@ 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; @@ -680,18 +811,11 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId) fe_init(); #endif - 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; +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + return ed25519_hash_init(key, &key->sha); +#else /* !WOLFSSL_ED25519_PERSISTENT_SHA */ + return 0; +#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */ } int wc_ed25519_init(ed25519_key* key) @@ -705,7 +829,9 @@ void wc_ed25519_free(ed25519_key* key) if (key == NULL) return; - wc_Sha512Free(&key->sha); +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, &key->sha); +#endif ForceZero(key, sizeof(ed25519_key)); } diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index 44d62efb9..cdbb3111b 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -51,6 +51,28 @@ static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448"; #endif + +static int ed448_hash_init(ed448_key* key, wc_Shake *sha) +{ + int ret; + + ret = wc_InitShake256(sha, key->heap, +#if defined(WOLF_CRYPTO_CB) + key->devId +#else + INVALID_DEVID +#endif + ); + +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + if (ret == 0) + key->sha_clean_flag = 1; +#endif + + return ret; +} + +#ifdef WOLFSSL_ED448_PERSISTENT_SHA static int ed448_hash_reset(ed448_key* key) { int ret; @@ -71,36 +93,74 @@ static int ed448_hash_reset(ed448_key* key) } return ret; } +#endif /* WOLFSSL_ED448_PERSISTENT_SHA */ -static int ed448_hash_update(ed448_key* key, const byte* data, word32 len) +static int ed448_hash_update(ed448_key* key, wc_Shake *sha, const byte* data, + word32 len) { +#ifdef WOLFSSL_ED448_PERSISTENT_SHA if (key->sha_clean_flag) key->sha_clean_flag = 0; - return wc_Shake256_Update(&key->sha, data, len); +#else + (void)key; +#endif + return wc_Shake256_Update(sha, data, len); } -static int ed448_hash_final(ed448_key* key, byte* hash, word32 hashLen) +static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash, + word32 hashLen) { - int ret = wc_Shake256_Final(&key->sha, hash, hashLen); + int ret = wc_Shake256_Final(sha, hash, hashLen); +#ifdef WOLFSSL_ED448_PERSISTENT_SHA if (ret == 0) key->sha_clean_flag = 1; +#else + (void)key; +#endif return ret; } +static void ed448_hash_free(ed448_key* key, wc_Shake *sha) +{ + wc_Shake256_Free(sha); +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + key->sha_clean_flag = 0; +#else + (void)key; +#endif +} + + static int ed448_hash(ed448_key* key, const byte* in, word32 inLen, byte* hash, word32 hashLen) { int ret; +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + wc_Shake sha[1]; +#else + wc_Shake *sha; +#endif if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) { return BAD_FUNC_ARG; } +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + sha = &key->sha; ret = ed448_hash_reset(key); +#else + ret = ed448_hash_init(key, sha); +#endif + if (ret < 0) + return ret; + + ret = ed448_hash_update(key, sha, in, inLen); if (ret == 0) - ret = ed448_hash_update(key, in, inLen); - if (ret == 0) - ret = ed448_hash_final(key, hash, hashLen); + ret = ed448_hash_final(key, sha, hash, hashLen); + +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif return ret; } @@ -234,34 +294,52 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out, ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az)); } if (ret == 0) { +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + wc_Shake *sha = &key->sha; +#else + wc_Shake sha[1]; + ret = ed448_hash_init(key, sha); + if (ret < 0) + return ret; +#endif /* apply clamp */ az[0] &= 0xfc; az[55] |= 0x80; az[56] = 0x00; + ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); + if (ret == 0) { - ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE); + ret = ed448_hash_update(key, sha, &type, sizeof(type)); } if (ret == 0) { - ret = ed448_hash_update(key, &type, sizeof(type)); - } - if (ret == 0) { - ret = ed448_hash_update(key, &contextLen, sizeof(contextLen)); + ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen)); } if ((ret == 0) && (context != NULL)) { - ret = ed448_hash_update(key, context, contextLen); + ret = ed448_hash_update(key, sha, context, contextLen); } if (ret == 0) { - ret = ed448_hash_update(key, az + ED448_KEY_SIZE, ED448_KEY_SIZE); + ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE); } if (ret == 0) { - ret = ed448_hash_update(key, in, inLen); + ret = ed448_hash_update(key, sha, in, inLen); } if (ret == 0) { - ret = ed448_hash_final(key, nonce, sizeof(nonce)); + ret = ed448_hash_final(key, sha, nonce, sizeof(nonce)); } +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif } if (ret == 0) { +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + wc_Shake *sha = &key->sha; +#else + wc_Shake sha[1]; + ret = ed448_hash_init(key, sha); + if (ret < 0) + return ret; +#endif sc448_reduce(nonce); /* step 2: computing R = rB where rB is the scalar multiplication of @@ -271,30 +349,32 @@ int wc_ed448_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 = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); if (ret == 0) { - 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, out, ED448_SIG_SIZE/2); - } - if (ret == 0) { - ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE); - } - if (ret == 0) { - ret = ed448_hash_update(key, in, inLen); - } - if (ret == 0) { - ret = ed448_hash_final(key, hram, sizeof(hram)); - } + ret = ed448_hash_update(key, sha, &type, sizeof(type)); } + if (ret == 0) { + ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen)); + } + if ((ret == 0) && (context != NULL)) { + ret = ed448_hash_update(key, sha, context, contextLen); + } + if (ret == 0) { + ret = ed448_hash_update(key, sha, out, ED448_SIG_SIZE/2); + } + if (ret == 0) { + ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE); + } + if (ret == 0) { + ret = ed448_hash_update(key, sha, in, inLen); + } + if (ret == 0) { + ret = ed448_hash_final(key, sha, hram, sizeof(hram)); + } +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif } if (ret == 0) { @@ -374,8 +454,8 @@ int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out, int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, ed448_key* key, const byte* context, byte contextLen) { - int ret = 0; - byte hash[64]; + int ret; + byte hash[ED448_PREHASH_SIZE]; ret = ed448_hash(key, in, inLen, hash, sizeof(hash)); @@ -404,8 +484,10 @@ int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, * other -ve values when hash fails, * 0 otherwise. */ -int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key, - byte type, const byte* context, byte contextLen) + +static int ed448_verify_msg_init_with_sha(const byte* sig, word32 sigLen, + ed448_key* key, wc_Shake *sha, byte type, + const byte* context, byte contextLen) { int ret; @@ -421,25 +503,27 @@ int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key, } /* find H(R,A,M) and store it as h */ +#ifdef WOLFSSL_ED448_PERSISTENT_SHA ret = ed448_hash_reset(key); if (ret < 0) return ret; +#endif - ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE); + ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); if (ret == 0) { - ret = ed448_hash_update(key, &type, sizeof(type)); + ret = ed448_hash_update(key, sha, &type, sizeof(type)); } if (ret == 0) { - ret = ed448_hash_update(key, &contextLen, sizeof(contextLen)); + ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen)); } if ((ret == 0) && (context != NULL)) { - ret = ed448_hash_update(key, context, contextLen); + ret = ed448_hash_update(key, sha, context, contextLen); } if (ret == 0) { - ret = ed448_hash_update(key, sig, ED448_SIG_SIZE/2); + ret = ed448_hash_update(key, sha, sig, ED448_SIG_SIZE/2); } if (ret == 0) { - ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE); + ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE); } return ret; @@ -451,14 +535,16 @@ int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key, key Ed448 public key return 0 on success */ -int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, - ed448_key* key) +static int ed448_verify_msg_update_with_sha(const byte* msgSegment, + word32 msgSegmentLen, + ed448_key* key, + wc_Shake *sha) { /* sanity check on arguments */ if (msgSegment == NULL || key == NULL) return BAD_FUNC_ARG; - return ed448_hash_update(key, msgSegment, msgSegmentLen); + return ed448_hash_update(key, sha, msgSegment, msgSegmentLen); } /* Verify the message using the ed448 public key. @@ -472,8 +558,8 @@ int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, * other -ve values when hash fails, * 0 otherwise. */ -int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen, - int* res, ed448_key* key) +static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen, + int* res, ed448_key* key, wc_Shake *sha) { byte rcheck[ED448_KEY_SIZE]; byte h[ED448_SIG_SIZE]; @@ -496,7 +582,7 @@ int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen, if (ge448_from_bytes_negate_vartime(&A, key->p) != 0) return BAD_FUNC_ARG; - ret = ed448_hash_final(key, h, sizeof(h)); + ret = ed448_hash_final(key, sha, h, sizeof(h)); if (ret != 0) return ret; @@ -524,6 +610,28 @@ int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen, return ret; } +#ifdef WOLFSSL_ED448_STREAMING_VERIFY +int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key, + byte type, const byte* context, byte contextLen) +{ + return ed448_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, type, + context, contextLen); +} + +int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, + ed448_key* key) +{ + return ed448_verify_msg_update_with_sha(msgSegment, msgSegmentLen, key, + &key->sha); +} + +int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen, + int* res, ed448_key* key) +{ + return ed448_verify_msg_final_with_sha(sig, sigLen, res, key, &key->sha); +} +#endif + /* Verify the message using the ed448 public key. * * sig [in] Signature to verify. @@ -546,16 +654,35 @@ int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, byte type, const byte* context, byte contextLen) { int ret; - ret = wc_ed448_verify_msg_init(sig, sigLen, key, +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + wc_Shake *sha; +#else + wc_Shake sha[1]; +#endif + + if (key == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + sha = &key->sha; +#else + ret = ed448_hash_init(key, sha); + if (ret < 0) + return ret; +#endif + + ret = ed448_verify_msg_init_with_sha(sig, sigLen, key, sha, type, context, contextLen); - if (ret < 0) - return ret; + if (ret == 0) + ret = ed448_verify_msg_update_with_sha(msg, msgLen, key, sha); + if (ret == 0) + ret = ed448_verify_msg_final_with_sha(sig, sigLen, res, key, sha); - ret = wc_ed448_verify_msg_update(msg, msgLen, key); - if (ret < 0) - return ret; +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif - return wc_ed448_verify_msg_final(sig, sigLen, res, key); + return ret; } /* Verify the message using the ed448 public key. @@ -627,7 +754,7 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, const byte* context, byte contextLen) { int ret = 0; - byte hash[64]; + byte hash[ED448_PREHASH_SIZE]; ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash)); @@ -648,8 +775,6 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, */ int wc_ed448_init_ex(ed448_key* key, void *heap, int devId) { - int ret; - if (key == NULL) return BAD_FUNC_ARG; @@ -664,18 +789,11 @@ int wc_ed448_init_ex(ed448_key* key, void *heap, int devId) 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; +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + return ed448_hash_init(key, &key->sha); +#else /* !WOLFSSL_ED448_PERSISTENT_SHA */ + return 0; +#endif /* WOLFSSL_ED448_PERSISTENT_SHA */ } /* Initialize the ed448 private/public key. @@ -694,7 +812,9 @@ int wc_ed448_init(ed448_key* key) { void wc_ed448_free(ed448_key* key) { if (key != NULL) { - wc_Shake256_Free(&key->sha); +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, &key->sha); +#endif ForceZero(key, sizeof(ed448_key)); } } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7452b0f49..e11194245 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -25143,7 +25143,9 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void) int i; word32 outlen; #ifdef HAVE_ED25519_VERIFY +#ifdef WOLFSSL_ED25519_STREAMING_VERIFY int j; +#endif int verify; #endif /* HAVE_ED25519_VERIFY */ #endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */ @@ -25551,6 +25553,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void) &key) != 0 || verify != 1) return -11031 - i; +#ifdef WOLFSSL_ED25519_STREAMING_VERIFY /* test verify on good msg using streaming interface directly */ if (wc_ed25519_verify_msg_init(out, outlen, &key, (byte)Ed25519, NULL, 0) != 0) @@ -25562,6 +25565,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void) if (wc_ed25519_verify_msg_final(out, outlen, &verify, &key) != 0 || verify != 1) return -11231 - i; +#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */ /* test verify on bad msg */ out[outlen-1] = out[outlen-1] + 1; @@ -26455,7 +26459,9 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void) int i; word32 outlen; #ifdef HAVE_ED448_VERIFY +#ifdef WOLFSSL_ED448_STREAMING_VERIFY int j; +#endif /* WOLFSSL_ED448_STREAMING_VERIFY */ int verify; #endif /* HAVE_ED448_VERIFY */ #endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */ @@ -26966,6 +26972,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void) return -11731 - i; } +#ifdef WOLFSSL_ED448_STREAMING_VERIFY /* test verify on good msg using streaming interface directly */ if (wc_ed448_verify_msg_init(out, outlen, &key, (byte)Ed448, NULL, 0) != 0) @@ -26977,6 +26984,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void) if (wc_ed448_verify_msg_final(out, outlen, &verify, &key) != 0 || verify != 1) return -11931 - i; +#endif /* WOLFSSL_ED448_STREAMING_VERIFY */ /* test verify on bad msg */ out[outlen-2] = out[outlen-2] + 1; diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 443459757..f944d8fec 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -94,8 +94,10 @@ struct ed25519_key { int devId; #endif void *heap; +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA wc_Sha512 sha; int sha_clean_flag; +#endif }; @@ -145,6 +147,7 @@ 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); +#ifdef WOLFSSL_ED25519_STREAMING_VERIFY WOLFSSL_API int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key, byte type, const byte* context, byte contextLen); @@ -154,6 +157,7 @@ int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, WOLFSSL_API int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res, ed25519_key* key); +#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */ #endif /* HAVE_ED25519_VERIFY */ diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index ff7caf88a..cb317111e 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -65,6 +65,7 @@ /* both private and public key */ #define ED448_PRV_KEY_SIZE (ED448_PUB_KEY_SIZE+ED448_KEY_SIZE) +#define ED448_PREHASH_SIZE 64 enum { Ed448 = 0, @@ -93,8 +94,10 @@ struct ed448_key { int devId; #endif void *heap; +#ifdef WOLFSSL_ED448_PERSISTENT_SHA wc_Shake sha; int sha_clean_flag; +#endif }; @@ -125,6 +128,7 @@ 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); +#ifdef WOLFSSL_ED448_STREAMING_VERIFY WOLFSSL_API int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key, byte type, const byte* context, byte contextLen); @@ -134,6 +138,7 @@ int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen, WOLFSSL_API int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen, int* stat, ed448_key* key); +#endif /* WOLFSSL_ED448_STREAMING_VERIFY */ WOLFSSL_API int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* stat, ed448_key* key, diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 3a3dfae66..5c62e5758 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1867,6 +1867,10 @@ extern void uITRON4_free(void *p) ; #ifndef NO_ED25519_VERIFY #undef HAVE_ED25519_VERIFY #define HAVE_ED25519_VERIFY + #ifdef WOLFSSL_ED25519_STREAMING_VERIFY + #undef WOLFSSL_ED25519_PERSISTENT_SHA + #define WOLFSSL_ED25519_PERSISTENT_SHA + #endif #endif #ifndef NO_ED25519_KEY_EXPORT #undef HAVE_ED25519_KEY_EXPORT @@ -1905,6 +1909,10 @@ extern void uITRON4_free(void *p) ; #ifndef NO_ED448_VERIFY #undef HAVE_ED448_VERIFY #define HAVE_ED448_VERIFY + #ifdef WOLFSSL_ED448_STREAMING_VERIFY + #undef WOLFSSL_ED448_PERSISTENT_SHA + #define WOLFSSL_ED448_PERSISTENT_SHA + #endif #endif #ifndef NO_ED448_KEY_EXPORT #undef HAVE_ED448_KEY_EXPORT From 05128968f67b5cb3f4247174f054f7e9343364b4 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 14 Jul 2021 23:43:14 -0500 Subject: [PATCH 3/7] fixes for null pointer accesses detected by clang sanitizer. also, gate SuiteTest() on !NO_WOLFSSL_CIPHER_SUITE_TEST in tests/unit.c, greatly reducing time to completion when not debugging cipher suites. --- tests/unit.c | 2 + wolfcrypt/src/dsa.c | 94 ++++++++++++++++++++++-------------------- wolfcrypt/src/evp.c | 2 +- wolfcrypt/src/rsa.c | 26 +++++++----- wolfcrypt/src/sha512.c | 31 +++++++------- wolfcrypt/src/srp.c | 29 ++++++++----- 6 files changed, 103 insertions(+), 81 deletions(-) diff --git a/tests/unit.c b/tests/unit.c index 5d7325983..bebcc2a97 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -80,6 +80,7 @@ int unit_test(int argc, char** argv) goto exit; } +#ifndef NO_WOLFSSL_CIPHER_SUITE_TEST #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) #ifndef SINGLE_THREADED if ( (ret = SuiteTest(argc, argv)) != 0){ @@ -88,6 +89,7 @@ int unit_test(int argc, char** argv) } #endif #endif +#endif /* NO_WOLFSSL_CIPHER_SUITE_TEST */ SrpTest(); diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 53a8d6099..74254c518 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -665,22 +665,15 @@ int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz) int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) { #ifdef WOLFSSL_SMALL_STACK - mp_int *k = (mp_int *)XMALLOC(sizeof *k, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *kInv = (mp_int *)XMALLOC(sizeof *kInv, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *r = (mp_int *)XMALLOC(sizeof *r, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *s = (mp_int *)XMALLOC(sizeof *s, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *H = (mp_int *)XMALLOC(sizeof *H, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); + mp_int *k = NULL; + mp_int *kInv = NULL; + mp_int *r = NULL; + mp_int *s = NULL; + mp_int *H = NULL; #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME - mp_int *b = (mp_int *)XMALLOC(sizeof *b, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); + mp_int *b = NULL; #endif - byte *buffer = (byte *)XMALLOC(DSA_HALF_SIZE, key->heap, - DYNAMIC_TYPE_TMP_BUFFER); + byte *buffer = NULL; #else mp_int k[1], kInv[1], r[1], s[1], H[1]; #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME @@ -693,17 +686,24 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) byte* tmp; /* initial output pointer */ do { -#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME - if (mp_init_multi(k, kInv, r, s, H, 0) != MP_OKAY) -#else - if (mp_init_multi(k, kInv, r, s, H, b) != MP_OKAY) -#endif - { - ret = MP_INIT_E; - break; - } + if (digest == NULL || out == NULL || key == NULL || rng == NULL) { + ret = BAD_FUNC_ARG; + break; + } #ifdef WOLFSSL_SMALL_STACK + k = (mp_int *)XMALLOC(sizeof *k, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + kInv = (mp_int *)XMALLOC(sizeof *kInv, key->heap, + DYNAMIC_TYPE_TMP_BUFFER); + r = (mp_int *)XMALLOC(sizeof *r, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + s = (mp_int *)XMALLOC(sizeof *s, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + H = (mp_int *)XMALLOC(sizeof *H, key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME + b = (mp_int *)XMALLOC(sizeof *b, key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + buffer = (byte *)XMALLOC(DSA_HALF_SIZE, key->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if ((k == NULL) || (kInv == NULL) || (r == NULL) || @@ -718,10 +718,15 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) } #endif - if (digest == NULL || out == NULL || key == NULL || rng == NULL) { - ret = BAD_FUNC_ARG; - break; - } +#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME + if (mp_init_multi(k, kInv, r, s, H, 0) != MP_OKAY) +#else + if (mp_init_multi(k, kInv, r, s, H, b) != MP_OKAY) +#endif + { + ret = MP_INIT_E; + break; + } sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q)); tmp = out; @@ -979,35 +984,31 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) { #ifdef WOLFSSL_SMALL_STACK - mp_int *w = (mp_int *)XMALLOC(sizeof *w, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *u1 = (mp_int *)XMALLOC(sizeof *u1, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *u2 = (mp_int *)XMALLOC(sizeof *u2, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *v = (mp_int *)XMALLOC(sizeof *v, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *r = (mp_int *)XMALLOC(sizeof *r, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); - mp_int *s = (mp_int *)XMALLOC(sizeof *s, - key->heap, DYNAMIC_TYPE_TMP_BUFFER); + mp_int *w = NULL; + mp_int *u1 = NULL; + mp_int *u2 = NULL; + mp_int *v = NULL; + mp_int *r = NULL; + mp_int *s = NULL; #else mp_int w[1], u1[1], u2[1], v[1], r[1], s[1]; #endif int ret = 0; do { - if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) { - ret = MP_INIT_E; - break; - } - if (digest == NULL || sig == NULL || key == NULL || answer == NULL) { ret = BAD_FUNC_ARG; break; } #ifdef WOLFSSL_SMALL_STACK + w = (mp_int *)XMALLOC(sizeof *w, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + u1 = (mp_int *)XMALLOC(sizeof *u1, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + u2 = (mp_int *)XMALLOC(sizeof *u2, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + v = (mp_int *)XMALLOC(sizeof *v, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + r = (mp_int *)XMALLOC(sizeof *r, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + s = (mp_int *)XMALLOC(sizeof *s, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if ((w == NULL) || (u1 == NULL) || (u2 == NULL) || @@ -1019,6 +1020,11 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) } #endif + if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) { + ret = MP_INIT_E; + break; + } + /* set r and s from signature */ if (mp_read_unsigned_bin(r, sig, DSA_HALF_SIZE) != MP_OKAY || mp_read_unsigned_bin(s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) { diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8cc68b005..13c528217 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -4377,7 +4377,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if ((ctx->cipherType == AES_128_GCM_TYPE) || (ctx->cipherType == AES_192_GCM_TYPE) || (ctx->cipherType == AES_256_GCM_TYPE)) { - wc_AesFree(&ctx->cipher.aes); + wc_AesFree(&ctx->cipher.aes); } #endif /* HAVE_AESGCM && WOLFSSL_AESGCM_STREAM */ #endif /* not FIPS or new FIPS */ diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 0362e531b..d45e21024 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4098,11 +4098,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) { #ifndef WC_NO_RNG #ifdef WOLFSSL_SMALL_STACK - mp_int *p = (mp_int *)XMALLOC(sizeof *p, key->heap, DYNAMIC_TYPE_RSA); - mp_int *q = (mp_int *)XMALLOC(sizeof *q, key->heap, DYNAMIC_TYPE_RSA); - mp_int *tmp1 = (mp_int *)XMALLOC(sizeof *tmp1, key->heap, DYNAMIC_TYPE_RSA); - mp_int *tmp2 = (mp_int *)XMALLOC(sizeof *tmp2, key->heap, DYNAMIC_TYPE_RSA); - mp_int *tmp3 = (mp_int *)XMALLOC(sizeof *tmp3, key->heap, DYNAMIC_TYPE_RSA); + mp_int *p = NULL; + mp_int *q = NULL; + mp_int *tmp1 = NULL; + mp_int *tmp2 = NULL; + mp_int *tmp3 = NULL; #else mp_int p_buf, *p = &p_buf; mp_int q_buf, *q = &q_buf; @@ -4113,7 +4113,18 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) int err, i, failCount, primeSz, isPrime = 0; byte* buf = NULL; + if (key == NULL || rng == NULL) { + err = BAD_FUNC_ARG; + goto out; + } + #ifdef WOLFSSL_SMALL_STACK + p = (mp_int *)XMALLOC(sizeof *p, key->heap, DYNAMIC_TYPE_RSA); + q = (mp_int *)XMALLOC(sizeof *q, key->heap, DYNAMIC_TYPE_RSA); + tmp1 = (mp_int *)XMALLOC(sizeof *tmp1, key->heap, DYNAMIC_TYPE_RSA); + tmp2 = (mp_int *)XMALLOC(sizeof *tmp2, key->heap, DYNAMIC_TYPE_RSA); + tmp3 = (mp_int *)XMALLOC(sizeof *tmp3, key->heap, DYNAMIC_TYPE_RSA); + if ((p == NULL) || (q == NULL) || (tmp1 == NULL) || @@ -4124,11 +4135,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) } #endif - if (key == NULL || rng == NULL) { - err = BAD_FUNC_ARG; - goto out; - } - if (!RsaSizeCheck(size)) { err = BAD_FUNC_ARG; goto out; diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index f8d98fb14..d772496b0 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -956,25 +956,26 @@ void wc_Sha512Free(wc_Sha512* sha512) /* @return 0 on successful, otherwise non-zero on failure */ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) { - int ret ; + int ret; /* back up buffer */ - #if defined(WOLFSSL_SMALL_STACK) - word64* buffer; - buffer = (word64*) XMALLOC(sizeof(word64) * 16, sha->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (buffer == NULL) - return MEMORY_E; - #else +#ifdef WOLFSSL_SMALL_STACK + word64 *buffer; +#else word64 buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64)]; - #endif - +#endif + /* sanity check */ if (sha == NULL || data == NULL) { - #if defined(WOLFSSL_SMALL_STACK) - XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); - #endif return BAD_FUNC_ARG; } + +#ifdef WOLFSSL_SMALL_STACK + buffer = (word64 *)XMALLOC(sizeof(word64) * 16, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (buffer == NULL) + return MEMORY_E; +#endif + #if defined(USE_INTEL_SPEEDUP) && \ (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) Sha512_SetTransform(); @@ -997,9 +998,9 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) ret = Transform_Sha512(sha); XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE); - #if defined(WOLFSSL_SMALL_STACK) +#ifdef WOLFSSL_SMALL_STACK XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); - #endif +#endif return ret; } #endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index cb3c575e2..b30f415bf 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -634,12 +634,12 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, byte* serverPubKey, word32 serverPubKeySz) { #ifdef WOLFSSL_SMALL_STACK - SrpHash *hash = (SrpHash *)XMALLOC(sizeof *hash, srp->heap, DYNAMIC_TYPE_SRP); - byte *digest = (byte *)XMALLOC(SRP_MAX_DIGEST_SIZE, srp->heap, DYNAMIC_TYPE_SRP); - mp_int *u = (mp_int *)XMALLOC(sizeof *u, srp->heap, DYNAMIC_TYPE_SRP); - mp_int *s = (mp_int *)XMALLOC(sizeof *s, srp->heap, DYNAMIC_TYPE_SRP); - mp_int *temp1 = (mp_int *)XMALLOC(sizeof *temp1, srp->heap, DYNAMIC_TYPE_SRP); - mp_int *temp2 = (mp_int *)XMALLOC(sizeof *temp2, srp->heap, DYNAMIC_TYPE_SRP); + SrpHash *hash = NULL; + byte *digest = NULL; + mp_int *u = NULL; + mp_int *s = NULL; + mp_int *temp1 = NULL; + mp_int *temp2 = NULL; #else SrpHash hash[1]; byte digest[SRP_MAX_DIGEST_SIZE]; @@ -652,11 +652,6 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, /* validating params */ - if ((mp_init_multi(u, s, temp1, temp2, 0, 0)) != MP_OKAY) { - r = MP_INIT_E; - goto out; - } - if (!srp || !clientPubKey || clientPubKeySz == 0 || !serverPubKey || serverPubKeySz == 0) { r = BAD_FUNC_ARG; @@ -664,6 +659,13 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, } #ifdef WOLFSSL_SMALL_STACK + hash = (SrpHash *)XMALLOC(sizeof *hash, srp->heap, DYNAMIC_TYPE_SRP); + digest = (byte *)XMALLOC(SRP_MAX_DIGEST_SIZE, srp->heap, DYNAMIC_TYPE_SRP); + u = (mp_int *)XMALLOC(sizeof *u, srp->heap, DYNAMIC_TYPE_SRP); + s = (mp_int *)XMALLOC(sizeof *s, srp->heap, DYNAMIC_TYPE_SRP); + temp1 = (mp_int *)XMALLOC(sizeof *temp1, srp->heap, DYNAMIC_TYPE_SRP); + temp2 = (mp_int *)XMALLOC(sizeof *temp2, srp->heap, DYNAMIC_TYPE_SRP); + if ((hash == NULL) || (digest == NULL) || (u == NULL) || @@ -675,6 +677,11 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, } #endif + if ((mp_init_multi(u, s, temp1, temp2, 0, 0)) != MP_OKAY) { + r = MP_INIT_E; + goto out; + } + if (mp_iszero(&srp->priv) == MP_YES) { r = SRP_CALL_ORDER_E; goto out; From c97eff6e612f5f11493bea5c3b0ed2b55b0f4d2e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 16 Jul 2021 15:30:23 -0500 Subject: [PATCH 4/7] evp.c: add missing checks and logic in wolfSSL_EVP_CIPHER_CTX_ctrl(), and fix api.c:test_IncCtr() to exercise wolfSSL_EVP_CIPHER_CTX_ctrl() with EVP_CTRL_GCM_IV_GEN using an AES cipher, with thanks to Juliusz. --- tests/api.c | 17 ++++++----------- wolfcrypt/src/evp.c | 41 ++++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/tests/api.c b/tests/api.c index 92e60ef1e..bb2033531 100644 --- a/tests/api.c +++ b/tests/api.c @@ -39295,28 +39295,23 @@ static void test_wolfSSL_EVP_BytesToKey(void) } static void test_IncCtr(void) { -#if defined(OPENSSL_ALL) && defined(HAVE_AESGCM) && !defined(NO_DES3) - byte key[DES3_KEY_SIZE] = {0}; - byte iv[DES_IV_SIZE] = {0}; +#if defined(OPENSSL_ALL) && defined(HAVE_AESGCM) && !defined(HAVE_FIPS) + byte key[AES_128_KEY_SIZE] = {0}; + byte iv[GCM_NONCE_MID_SZ] = {0}; int type = EVP_CTRL_GCM_IV_GEN; int arg = 0; - void *ptr; - ptr = NULL; + void *ptr = NULL; printf(testingFmt, "IncCtr"); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - const EVP_CIPHER *init = EVP_des_ede3_cbc(); + const EVP_CIPHER *init = EVP_aes_128_gcm(); AssertNotNull(ctx); wolfSSL_EVP_CIPHER_CTX_init(ctx); AssertIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS); - - ctx->cipher.aes.keylen = 128; - - AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr), 0); - + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr), WOLFSSL_SUCCESS); EVP_CIPHER_CTX_free(ctx); printf(resultFmt, passed); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 13c528217..7d3951b1e 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -4277,41 +4277,42 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) && !defined(WC_NO_RNG) case EVP_CTRL_GCM_SET_IVLEN: + if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + break; if(arg <= 0 || arg > 16) - return WOLFSSL_FAILURE; + break; ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); break; case EVP_CTRL_AEAD_SET_IV_FIXED: + if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + break; if (arg == -1) { /* arg == -1 copies ctx->ivSz from ptr */ ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, (byte*)ptr, ctx->ivSz); - } - else { + } else { /* * Fixed field must be at least 4 bytes and invocation * field at least 8. */ if ((arg < 4) || (ctx->ivSz - arg) < 8) { WOLFSSL_MSG("Fixed field or invocation field too short"); - ret = WOLFSSL_FAILURE; break; } /* arg is 4...(ctx->ivSz - 8) */ XMEMCPY(ctx->iv, ptr, arg); if (wc_InitRng(&rng) != 0) { WOLFSSL_MSG("wc_InitRng failed"); - ret = WOLFSSL_FAILURE; break; } if (wc_RNG_GenerateBlock(&rng, ctx->iv + arg, - ctx->ivSz - arg) != 0) { + ctx->ivSz - arg) == 0) { + ret = WOLFSSL_SUCCESS; + } else { /* rng is freed immediately after if block so no need * to do it here */ WOLFSSL_MSG("wc_RNG_GenerateBlock failed"); - ret = WOLFSSL_FAILURE; } - if (wc_FreeRng(&rng) != 0) { WOLFSSL_MSG("wc_FreeRng failed"); ret = WOLFSSL_FAILURE; @@ -4321,39 +4322,45 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #if !defined(_WIN32) && !defined(HAVE_FIPS) case EVP_CTRL_GCM_IV_GEN: + if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + break; if (ctx->cipher.aes.keylen == 0 || ctx->ivSz == 0) { - ret = WOLFSSL_FAILURE; WOLFSSL_MSG("Key or IV not set"); break; } if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, ctx->ivSz)) != 0) { WOLFSSL_MSG("wc_AesGcmSetIV failed"); - ret = WOLFSSL_FAILURE; + break; } #ifdef WOLFSSL_AESGCM_STREAM /* Initialize using IV cached in Aes object. */ if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, NULL, 0) != 0) { WOLFSSL_MSG("wc_AesGcmInit failed"); ret = WOLFSSL_FAILURE; + break; } #endif /* WOLFSSL_AESGCM_STREAM */ /* OpenSSL increments the IV. Not sure why */ IncCtr(ctx->iv, ctx->ivSz); + ret = WOLFSSL_SUCCESS; break; #endif case EVP_CTRL_AEAD_SET_TAG: + if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + break; if(arg <= 0 || arg > 16 || (ptr == NULL)) - return WOLFSSL_FAILURE; + break; XMEMCPY(ctx->authTag, ptr, arg); ctx->authTagSz = arg; ret = WOLFSSL_SUCCESS; - break; case EVP_CTRL_AEAD_GET_TAG: + if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + break; if(arg <= 0 || arg > 16) - return WOLFSSL_FAILURE; + break; XMEMCPY(ptr, ctx->authTag, arg); ret = WOLFSSL_SUCCESS; @@ -4361,7 +4368,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* HAVE_AESGCM && !HAVE_SELFTEST && !WC_NO_RNG */ default: WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); - ret = WOLFSSL_FAILURE; + break; } return ret; } @@ -5406,8 +5413,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length"); if (ctx) return ctx->keyLen; - - return 0; /* failure */ + else + return WOLFSSL_FAILURE; } /* WOLFSSL_SUCCESS on ok */ @@ -5418,7 +5425,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (ctx) ctx->keyLen = keylen; else - return 0; /* failure */ + return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; } From 785a8f83ed753a86d5a53f69e1048a202a164cc9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 16 Jul 2021 17:52:28 -0500 Subject: [PATCH 5/7] evp.c: fixes in wolfSSL_EVP_CIPHER_CTX_ctrl() from peer review. --- wolfcrypt/src/evp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 7d3951b1e..9928699c2 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -4328,8 +4328,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) WOLFSSL_MSG("Key or IV not set"); break; } - if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, - ctx->ivSz)) != 0) { + if (wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, + ctx->ivSz) != 0) { WOLFSSL_MSG("wc_AesGcmSetIV failed"); break; } @@ -4337,7 +4337,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) /* Initialize using IV cached in Aes object. */ if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, NULL, 0) != 0) { WOLFSSL_MSG("wc_AesGcmInit failed"); - ret = WOLFSSL_FAILURE; break; } #endif /* WOLFSSL_AESGCM_STREAM */ From ac92204c156e9ee9a35eb36713028153bc3d3137 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 16 Jul 2021 18:21:30 -0500 Subject: [PATCH 6/7] make -DNO_ED448_KEY_{IMPORT,EXPORT} buildable --- src/internal.c | 13 +++++++++---- src/ssl.c | 29 ++++++++++++++++++++--------- tests/api.c | 14 ++++++++------ wolfcrypt/src/asn.c | 27 ++++++++++++++------------- wolfssl/test.h | 14 +++++++------- wolfssl/wolfcrypt/asn_public.h | 8 +++++++- wolfssl/wolfcrypt/ed448.h | 6 ++++++ 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/internal.c b/src/internal.c index e495407cd..3bd73b9f2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5057,6 +5057,10 @@ static int X25519MakeKey(WOLFSSL* ssl, curve25519_key* key, */ int Ed448CheckPubKey(WOLFSSL* ssl) { +#ifndef HAVE_ED448_KEY_IMPORT + (void)ssl; + return NOT_COMPILED_IN; +#else /* HAVE_ED448_KEY_IMPORT */ ed448_key* key = (ed448_key*)ssl->hsKey; int ret = 0; @@ -5083,6 +5087,7 @@ int Ed448CheckPubKey(WOLFSSL* ssl) } return ret; +#endif /* HAVE_ED448_KEY_IMPORT */ } /* Sign the data using EdDSA and key using Ed448. @@ -12680,7 +12685,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } #endif /* HAVE_ED25519 */ - #ifdef HAVE_ED448 + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) case ED448k: { int keyRet = 0; @@ -12732,7 +12737,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->ecdhCurveOID = ECC_X448_OID; break; } - #endif /* HAVE_ED448 */ + #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */ default: break; } @@ -21757,7 +21762,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } } #endif /* HAVE_ED25519 */ -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) #if !defined(NO_RSA) || defined(HAVE_ECC) FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); #endif @@ -21800,7 +21805,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) goto exit_dpk; } } -#endif /* HAVE_ED448 */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */ (void)idx; (void)keySz; diff --git a/src/ssl.c b/src/ssl.c index 41bf31590..d4b01dcf3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5379,7 +5379,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der #endif } #endif /* HAVE_ED25519 */ -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) { /* make sure Ed448 key can be used */ #ifdef WOLFSSL_SMALL_STACK @@ -5435,7 +5435,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der XFREE(key, heap, DYNAMIC_TYPE_ED448); #endif } -#endif /* HAVE_ED448 */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */ return ret; } @@ -47476,7 +47476,14 @@ int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz, (void) pub; (void) pubSz; return WOLFSSL_FAILURE; -#else /* WOLFSSL_KEY_GEN */ +#elif !defined(HAVE_ED448_KEY_EXPORT) + WOLFSSL_MSG("No ED448 key export built in"); + (void) priv; + (void) privSz; + (void) pub; + (void) pubSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */ int ret = WOLFSSL_FAILURE; int initTmpRng = 0; WC_RNG *rng = NULL; @@ -47535,7 +47542,7 @@ int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz, #endif return ret; -#endif /* WOLFSSL_KEY_GEN */ +#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */ } /* return 1 if success, 0 if error @@ -47546,11 +47553,13 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz, const unsigned char *priv, unsigned int privSz, unsigned char *sig, unsigned int *sigSz) { -#if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN) +#if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT) #if !defined(HAVE_ED448_SIGN) WOLFSSL_MSG("No ED448 sign built in"); #elif !defined(WOLFSSL_KEY_GEN) WOLFSSL_MSG("No Key Gen built in"); +#elif !defined(HAVE_ED448_KEY_IMPORT) + WOLFSSL_MSG("No ED448 Key import built in"); #endif (void) msg; (void) msgSz; @@ -47559,7 +47568,7 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz, (void) sig; (void) sigSz; return WOLFSSL_FAILURE; -#else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN */ +#else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */ ed448_key key; int ret = WOLFSSL_FAILURE; @@ -47591,7 +47600,7 @@ int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz, wc_ed448_free(&key); return ret; -#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN */ +#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */ } /* return 1 if success, 0 if error @@ -47602,11 +47611,13 @@ 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) { -#if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN) +#if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT) #if !defined(HAVE_ED448_VERIFY) WOLFSSL_MSG("No ED448 verify built in"); #elif !defined(WOLFSSL_KEY_GEN) WOLFSSL_MSG("No Key Gen built in"); +#elif !defined(HAVE_ED448_KEY_IMPORT) + WOLFSSL_MSG("No ED448 Key import built in"); #endif (void) msg; (void) msgSz; @@ -47615,7 +47626,7 @@ int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz, (void) sig; (void) sigSz; return WOLFSSL_FAILURE; -#else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */ +#else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */ ed448_key key; int ret = WOLFSSL_FAILURE, check = 0; diff --git a/tests/api.c b/tests/api.c index bb2033531..441d50fdf 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20735,8 +20735,10 @@ static int test_wc_ed448_import_private_key (void) "Ed448PublicKeyUnitTest.................................\n"; word32 privKeySz = sizeof(privKey); word32 pubKeySz = sizeof(pubKey); +#ifdef HAVE_ED448_KEY_EXPORT byte bothKeys[sizeof(privKey) + sizeof(pubKey)]; word32 bothKeysSz = sizeof(bothKeys); +#endif ret = wc_InitRng(&rng); if (ret != 0) { @@ -21106,8 +21108,8 @@ static int test_wc_Ed448PublicKeyToDer (void) { int ret = 0; -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) int tmp; ed448_key key; byte derBuf[1024]; @@ -24177,8 +24179,8 @@ static int test_wc_Ed25519PrivateKeyToDer (void) static int test_wc_Ed448KeyToDer (void) { int ret = 0; -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) byte output[ONEK_BUF]; ed448_key ed448Key; @@ -24242,8 +24244,8 @@ static int test_wc_Ed448KeyToDer (void) static int test_wc_Ed448PrivateKeyToDer (void) { int ret = 0; -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) byte output[ONEK_BUF]; ed448_key ed448PrivKey; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 25f6bd2a2..93b9dc77d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3298,7 +3298,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, else #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ - #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (ks == ED448k) { #ifdef WOLFSSL_SMALL_STACK ed448_key* key_pair = NULL; @@ -3556,7 +3556,7 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ -#if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (*algoID != RSAk && *algoID != ECDSAk && *algoID != ED25519k) { ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap, DYNAMIC_TYPE_TMP_BUFFER); if (ed448 == NULL) @@ -3577,7 +3577,7 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, } XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER); } -#endif /* HAVE_ED448 && !NO_ASN_CRYPT */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */ /* if flag is not set then is neither RSA or ECC key that could be * found */ @@ -7786,7 +7786,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif - #ifdef HAVE_ED448 + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) case ED448k: { sigCtx->verify = 0; @@ -12711,8 +12711,8 @@ int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen, return SetEd25519PublicKey(output, key, withAlg); } #endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) /* Write a public ECC key to output */ static int SetEd448PublicKey(byte* output, ed448_key* key, int with_header) @@ -12814,7 +12814,7 @@ int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen, return SetEd448PublicKey(output, key, withAlg); } -#endif /* HAVE_ED448 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ #ifdef WOLFSSL_CERT_GEN @@ -13903,7 +13903,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) if (cert->keyType == ED448_KEY) { if (ed448Key == NULL) return PUBLIC_KEY_E; @@ -14660,7 +14660,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) if (cert->keyType == ED448_KEY) { if (ed448Key == NULL) return PUBLIC_KEY_E; @@ -15121,7 +15121,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, if (ed25519Key != NULL) bufferSz = SetEd25519PublicKey(buf, ed25519Key, 0); #endif -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) /* ED448 public key */ if (ed448Key != NULL) bufferSz = SetEd448PublicKey(buf, ed448Key, 0); @@ -17318,6 +17318,7 @@ int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen) #ifdef HAVE_ED448 +#ifdef HAVE_ED448_KEY_IMPORT int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx, ed448_key* key, word32 inSz) { @@ -17417,9 +17418,9 @@ int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx, return 0; } +#endif /* HAVE_ED448_KEY_IMPORT */ - -#ifdef WOLFSSL_KEY_GEN +#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT) /* build DER formatted ED448 key, * return length on success, negative on error */ @@ -17492,7 +17493,7 @@ int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen) return wc_BuildEd448KeyDer(key, output, inLen, 0); } -#endif /* WOLFSSL_KEY_GEN */ +#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */ #endif /* HAVE_ED448 */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 09dcd41a4..95dfdb574 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3862,7 +3862,7 @@ static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey #endif /* HAVE_CURVE25519 */ #ifdef HAVE_ED448 -#ifdef HAVE_ED448_SIGN +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT) static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) { @@ -3899,10 +3899,10 @@ static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, return ret; } -#endif /* HAVE_ED448_SIGN */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */ -#ifdef HAVE_ED448_VERIFY +#if defined(HAVE_ED448_VERIFY) && defined(HAVE_ED448_KEY_IMPORT) 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) @@ -3931,7 +3931,7 @@ static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, return ret; } -#endif /* HAVE_ED448_VERIFY */ +#endif /* HAVE_ED448_VERIFY && HAVE_ED448_KEY_IMPORT */ #endif /* HAVE_ED448 */ #ifdef HAVE_CURVE448 @@ -4455,11 +4455,11 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen); wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret); #endif - #ifdef HAVE_ED448 - #ifdef HAVE_ED448_SIGN + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) + #if defined(HAVE_ED448_SIGN) wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign); #endif - #ifdef HAVE_ED448_VERIFY + #if defined(HAVE_ED448_VERIFY) wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify); #endif #endif diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 01af995ba..647796e65 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -580,17 +580,23 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); #ifdef HAVE_ED448 /* private key helpers */ +#ifdef HAVE_ED448_KEY_IMPORT WOLFSSL_API int wc_Ed448PrivateKeyDecode(const byte*, word32*, ed448_key*, word32); +#endif + +#ifdef HAVE_ED448_KEY_EXPORT WOLFSSL_API int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen); WOLFSSL_API int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen); +#endif /* public key helper */ WOLFSSL_API int wc_Ed448PublicKeyDecode(const byte*, word32*, ed448_key*, word32); - #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) + #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) && \ + defined(HAVE_ED448_KEY_EXPORT) WOLFSSL_API int wc_Ed448PublicKeyToDer(ed448_key*, byte* output, word32 inLen, int with_AlgCurve); #endif diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index cb317111e..50818e1f1 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -158,6 +158,8 @@ WOLFSSL_API int wc_ed448_init(ed448_key* key); WOLFSSL_API void wc_ed448_free(ed448_key* key); + +#ifdef HAVE_ED448_KEY_IMPORT WOLFSSL_API int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key); WOLFSSL_API @@ -166,6 +168,9 @@ int wc_ed448_import_private_only(const byte* priv, word32 privSz, WOLFSSL_API int wc_ed448_import_private_key(const byte* priv, word32 privSz, const byte* pub, word32 pubSz, ed448_key* key); +#endif /* HAVE_ED448_KEY_IMPORT */ + +#ifdef HAVE_ED448_KEY_EXPORT WOLFSSL_API int wc_ed448_export_public(ed448_key*, byte* out, word32* outLen); WOLFSSL_API @@ -175,6 +180,7 @@ int wc_ed448_export_private(ed448_key* key, byte* out, word32* outLen); WOLFSSL_API int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz, byte* pub, word32 *pubSz); +#endif /* HAVE_ED448_KEY_EXPORT */ WOLFSSL_API int wc_ed448_check_key(ed448_key* key); From 186ff2b365663539e7222c3193715df63e48c678 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 16 Jul 2021 23:07:28 -0500 Subject: [PATCH 7/7] make -DNO_ED25519_KEY_{IMPORT,EXPORT} buildable, and fix api.c and suites.c so that -DNO_ED*_KEY_{IMPORT,EXPORT} pass make check. --- src/internal.c | 13 +++++-- src/ssl.c | 31 ++++++++++----- tests/api.c | 70 +++++++++++++++++----------------- tests/suites.c | 6 ++- wolfcrypt/src/asn.c | 31 ++++++++------- wolfssl/test.h | 18 ++++----- wolfssl/wolfcrypt/asn_public.h | 9 ++++- wolfssl/wolfcrypt/ed25519.h | 5 +++ 8 files changed, 109 insertions(+), 74 deletions(-) diff --git a/src/internal.c b/src/internal.c index 3bd73b9f2..404d112e7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4728,6 +4728,10 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) */ int Ed25519CheckPubKey(WOLFSSL* ssl) { +#ifndef HAVE_ED25519_KEY_IMPORT + (void)ssl; + return NOT_COMPILED_IN; +#else /* HAVE_ED25519_KEY_IMPORT */ ed25519_key* key = (ed25519_key*)ssl->hsKey; int ret = 0; @@ -4754,6 +4758,7 @@ int Ed25519CheckPubKey(WOLFSSL* ssl) } return ret; +#endif /* HAVE_ED25519_KEY_IMPORT */ } /* Sign the data using EdDSA and key using Ed25519. @@ -12631,7 +12636,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) case ED25519k: { int keyRet = 0; @@ -12684,7 +12689,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->ecdhCurveOID = ECC_X25519_OID; break; } - #endif /* HAVE_ED25519 */ + #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) case ED448k: { @@ -21720,7 +21725,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } } #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) #if !defined(NO_RSA) || defined(HAVE_ECC) FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); #endif @@ -21761,7 +21766,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) goto exit_dpk; } } -#endif /* HAVE_ED25519 */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) #if !defined(NO_RSA) || defined(HAVE_ECC) FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); diff --git a/src/ssl.c b/src/ssl.c index d4b01dcf3..386271e81 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5325,7 +5325,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der #endif } #endif /* HAVE_ECC */ -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED25519k)) { /* make sure Ed25519 key can be used */ #ifdef WOLFSSL_SMALL_STACK @@ -5378,7 +5378,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der XFREE(key, heap, DYNAMIC_TYPE_ED25519); #endif } -#endif /* HAVE_ED25519 */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) { /* make sure Ed448 key can be used */ @@ -47135,7 +47135,14 @@ int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz, (void) pub; (void) pubSz; return WOLFSSL_FAILURE; -#else /* WOLFSSL_KEY_GEN */ +#elif !defined(HAVE_ED25519_KEY_EXPORT) + WOLFSSL_MSG("No ED25519 key export built in"); + (void) priv; + (void) privSz; + (void) pub; + (void) pubSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */ int ret = WOLFSSL_FAILURE; int initTmpRng = 0; WC_RNG *rng = NULL; @@ -47194,7 +47201,7 @@ int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz, #endif return ret; -#endif /* WOLFSSL_KEY_GEN */ +#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */ } /* return 1 if success, 0 if error @@ -47205,11 +47212,13 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz, const unsigned char *priv, unsigned int privSz, unsigned char *sig, unsigned int *sigSz) { -#if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN) +#if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT) #if !defined(HAVE_ED25519_SIGN) WOLFSSL_MSG("No ED25519 sign built in"); #elif !defined(WOLFSSL_KEY_GEN) WOLFSSL_MSG("No Key Gen built in"); +#elif !defined(HAVE_ED25519_KEY_IMPORT) + WOLFSSL_MSG("No ED25519 Key import built in"); #endif (void) msg; (void) msgSz; @@ -47218,7 +47227,7 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz, (void) sig; (void) sigSz; return WOLFSSL_FAILURE; -#else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN */ +#else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */ ed25519_key key; int ret = WOLFSSL_FAILURE; @@ -47251,7 +47260,7 @@ int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz, wc_ed25519_free(&key); return ret; -#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN */ +#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */ } /* return 1 if success, 0 if error @@ -47262,11 +47271,13 @@ 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) { -#if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN) +#if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT) #if !defined(HAVE_ED25519_VERIFY) WOLFSSL_MSG("No ED25519 verify built in"); #elif !defined(WOLFSSL_KEY_GEN) WOLFSSL_MSG("No Key Gen built in"); +#elif !defined(HAVE_ED25519_KEY_IMPORT) + WOLFSSL_MSG("No ED25519 Key import built in"); #endif (void) msg; (void) msgSz; @@ -47275,7 +47286,7 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz, (void) sig; (void) sigSz; return WOLFSSL_FAILURE; -#else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN */ +#else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */ ed25519_key key; int ret = WOLFSSL_FAILURE, check = 0; @@ -47310,7 +47321,7 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz, wc_ed25519_free(&key); return ret; -#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN */ +#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */ } #endif /* OPENSSL_EXTRA && HAVE_ED25519 */ diff --git a/tests/api.c b/tests/api.c index 441d50fdf..5538e0fd7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2603,24 +2603,25 @@ static void test_ECDSA_size_sign(void) static void test_ED25519(void) { -#if defined(HAVE_ED25519) && defined(WOLFSSL_KEY_GEN) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \ + defined(WOLFSSL_KEY_GEN) byte priv[ED25519_PRV_KEY_SIZE]; unsigned int privSz = (unsigned int)sizeof(priv); byte pub[ED25519_PUB_KEY_SIZE]; unsigned int pubSz = (unsigned int)sizeof(pub); -#ifdef HAVE_ED25519_SIGN +#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_IMPORT) 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 */ +#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_IMPORT */ 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 +#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_IMPORT) AssertIntEQ(wolfSSL_ED25519_sign((byte*)msg, msglen, priv, privSz, sig, &sigSz), WOLFSSL_SUCCESS); AssertIntEQ(sigSz, ED25519_SIG_SIZE); @@ -2629,30 +2630,31 @@ static void test_ED25519(void) 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 */ +#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_IMPORT */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT && WOLFSSL_KEY_GEN */ } static void test_ED448(void) { -#if defined(HAVE_ED448) && defined(WOLFSSL_KEY_GEN) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ + defined(WOLFSSL_KEY_GEN) byte priv[ED448_PRV_KEY_SIZE]; unsigned int privSz = (unsigned int)sizeof(priv); byte pub[ED448_PUB_KEY_SIZE]; unsigned int pubSz = (unsigned int)sizeof(pub); -#ifdef HAVE_ED448_SIGN +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT) 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 */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */ 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 +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT) AssertIntEQ(wolfSSL_ED448_sign((byte*)msg, msglen, priv, privSz, sig, &sigSz), WOLFSSL_SUCCESS); AssertIntEQ(sigSz, ED448_SIG_SIZE); @@ -2661,8 +2663,8 @@ static void test_ED448(void) 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 /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT && WOLFSSL_KEY_GEN */ } #endif /* OPENSSL_EXTRA */ @@ -6941,7 +6943,8 @@ static void test_wolfSSL_PKCS8(void) static void test_wolfSSL_PKCS8_ED25519(void) { #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \ - defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED25519) + defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED25519) && \ + defined(HAVE_ED25519_KEY_IMPORT) const byte encPrivKey[] = \ "-----BEGIN ENCRYPTED PRIVATE KEY-----\n" "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAheCGLmWGh7+AICCAAw\n" @@ -6972,7 +6975,8 @@ static void test_wolfSSL_PKCS8_ED25519(void) static void test_wolfSSL_PKCS8_ED448(void) { #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \ - defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED448) + defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED448) && \ + defined(HAVE_ED448_KEY_IMPORT) const byte encPrivKey[] = \ "-----BEGIN ENCRYPTED PRIVATE KEY-----\n" "MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjSbZKnG4EPggICCAAw\n" @@ -18916,8 +18920,10 @@ static int test_wc_ed25519_import_private_key (void) const byte pubKey[] = "Ed25519PublicKeyUnitTest......\n"; word32 privKeySz = sizeof(privKey); word32 pubKeySz = sizeof(pubKey); +#ifdef HAVE_ED25519_KEY_EXPORT byte bothKeys[sizeof(privKey) + sizeof(pubKey)]; word32 bothKeysSz = sizeof(bothKeys); +#endif ret = wc_InitRng(&rng); if (ret != 0) { @@ -19286,8 +19292,8 @@ static int test_wc_Ed25519PublicKeyToDer (void) { int ret = 0; -#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) int tmp; ed25519_key key; byte derBuf[1024]; @@ -24048,8 +24054,8 @@ static int test_wc_DhPublicKeyDecode(void) static int test_wc_Ed25519KeyToDer (void) { int ret = 0; -#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) byte output[ONEK_BUF]; ed25519_key ed25519Key; @@ -24113,8 +24119,8 @@ static int test_wc_Ed25519KeyToDer (void) static int test_wc_Ed25519PrivateKeyToDer (void) { int ret = 0; -#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) byte output[ONEK_BUF]; ed25519_key ed25519PrivKey; @@ -24361,7 +24367,7 @@ static int test_wc_SetSubjectKeyIdFromPublicKey_ex (void) #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) WC_RNG rng; Cert cert; -#if defined(HAVE_ED25519) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) ed25519_key ed25519Key; #endif #if !defined(NO_RSA) && defined(HAVE_RSA) @@ -24371,7 +24377,7 @@ static int test_wc_SetSubjectKeyIdFromPublicKey_ex (void) #if defined(HAVE_ECC) ecc_key eccKey; #endif -#if defined(HAVE_ED448) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) ed448_key ed448Key; #endif @@ -24384,7 +24390,7 @@ static int test_wc_SetSubjectKeyIdFromPublicKey_ex (void) #endif wc_InitCert(&cert); -#if defined(HAVE_ED25519) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) if (ret == 0) { /*ED25519*/ ret = wc_ed25519_init(&ed25519Key); if (ret == 0) { @@ -24421,9 +24427,7 @@ static int test_wc_SetSubjectKeyIdFromPublicKey_ex (void) wc_ecc_free(&eccKey); } #endif -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) - +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) if (ret == 0) { /*ED448*/ ret = wc_ed448_init(&ed448Key); if (ret == 0) { @@ -24452,7 +24456,7 @@ static int test_wc_SetAuthKeyIdFromPublicKey_ex (void) #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) WC_RNG rng; Cert cert; -#if defined(HAVE_ED25519) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) ed25519_key ed25519Key; #endif #if !defined(NO_RSA) && defined(HAVE_RSA) @@ -24462,7 +24466,7 @@ static int test_wc_SetAuthKeyIdFromPublicKey_ex (void) #if defined(HAVE_ECC) ecc_key eccKey; #endif -#if defined(HAVE_ED448) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) ed448_key ed448Key; #endif @@ -24475,7 +24479,7 @@ static int test_wc_SetAuthKeyIdFromPublicKey_ex (void) #endif wc_InitCert(&cert); -#if defined(HAVE_ED25519) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) if (ret == 0) { /*ED25519*/ ret = wc_ed25519_init(&ed25519Key); if (ret == 0) { @@ -24512,9 +24516,7 @@ static int test_wc_SetAuthKeyIdFromPublicKey_ex (void) wc_ecc_free(&eccKey); } #endif -#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) - +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) if (ret == 0) { /*ED448*/ ret = wc_ed448_init(&ed448Key); if (ret == 0) { @@ -28163,7 +28165,7 @@ static void test_wolfSSL_private_keys(void) SSL_CTX_free(ctx); #endif /* end of ECC private key match tests */ -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) #ifndef NO_WOLFSSL_SERVER AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); #else @@ -28189,7 +28191,7 @@ static void test_wolfSSL_private_keys(void) SSL_CTX_free(ctx); #endif /* end of Ed25519 private key match tests */ -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) #ifndef NO_WOLFSSL_SERVER AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); #else diff --git a/tests/suites.c b/tests/suites.c index f827cd00a..88ef27291 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -888,7 +888,8 @@ int SuiteTest(int argc, char** argv) #endif #endif #if defined(HAVE_CURVE25519) && defined(HAVE_ED25519) && \ - defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_VERIFY) + defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_VERIFY) && \ + defined(HAVE_ED25519_KEY_IMPORT) && defined(HAVE_ED25519_KEY_EXPORT) /* add ED25519 certificate cipher suite tests */ strcpy(argv0[1], "tests/test-ed25519.conf"); printf("starting ED25519 extra cipher suite tests\n"); @@ -900,7 +901,8 @@ int SuiteTest(int argc, char** argv) } #endif #if defined(HAVE_CURVE448) && defined(HAVE_ED448) && \ - defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY) + defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY) && \ + defined(HAVE_ED448_KEY_IMPORT) && defined(HAVE_ED448_KEY_EXPORT) /* 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/src/asn.c b/wolfcrypt/src/asn.c index 93b9dc77d..f4df1d63f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3255,7 +3255,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, else #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */ - #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT) + #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (ks == ED25519k) { #ifdef WOLFSSL_SMALL_STACK ed25519_key* key_pair; @@ -3296,7 +3296,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, #endif } else - #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ + #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (ks == ED448k) { @@ -3339,7 +3339,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, #endif } else - #endif /* HAVE_ED448 && !NO_ASN_CRYPT */ + #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */ { ret = 0; } @@ -3534,7 +3534,7 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* HAVE_ECC && !NO_ASN_CRYPT */ -#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (*algoID != RSAk && *algoID != ECDSAk) { ed25519_key *ed25519 = (ed25519_key *)XMALLOC(sizeof *ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER); if (ed25519 == NULL) @@ -3555,7 +3555,7 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, } XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER); } -#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT) if (*algoID != RSAk && *algoID != ECDSAk && *algoID != ED25519k) { ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -7762,7 +7762,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) case ED25519k: { sigCtx->verify = 0; @@ -12607,8 +12607,8 @@ int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve) #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */ -#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \ - defined(WOLFSSL_KEY_GEN)) +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) /* Write a public ECC key to output */ static int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header) @@ -12710,7 +12710,7 @@ int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen, return SetEd25519PublicKey(output, key, withAlg); } -#endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) && \ (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) @@ -13895,7 +13895,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) if (cert->keyType == ED25519_KEY) { if (ed25519Key == NULL) return PUBLIC_KEY_E; @@ -14652,7 +14652,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) if (cert->keyType == ED25519_KEY) { if (ed25519Key == NULL) return PUBLIC_KEY_E; @@ -15116,7 +15116,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, #else (void)ntruKeySz; #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) /* ED25519 public key */ if (ed25519Key != NULL) bufferSz = SetEd25519PublicKey(buf, ed25519Key, 0); @@ -17139,6 +17139,8 @@ int wc_EccKeyToPKCS8(ecc_key* key, byte* output, #ifdef HAVE_ED25519 +#ifdef HAVE_ED25519_KEY_IMPORT + int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx, ed25519_key* key, word32 inSz) { @@ -17239,8 +17241,9 @@ int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx, return 0; } +#endif /* HAVE_ED25519_KEY_IMPORT */ -#ifdef WOLFSSL_KEY_GEN +#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED25519_KEY_EXPORT) /* build DER formatted ED25519 key, * return length on success, negative on error */ @@ -17312,7 +17315,7 @@ int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen) return wc_BuildEd25519KeyDer(key, output, inLen, 0); } -#endif /* WOLFSSL_KEY_GEN */ +#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */ #endif /* HAVE_ED25519 */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 95dfdb574..7d72319ad 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3697,7 +3697,7 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, #endif /* HAVE_ECC */ -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) #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) @@ -3766,7 +3766,7 @@ static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz return ret; } #endif /* HAVE_ED25519_VERIFY */ -#endif /* HAVE_ED25519 */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #ifdef HAVE_CURVE25519 static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key, @@ -3861,8 +3861,8 @@ static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey } #endif /* HAVE_CURVE25519 */ -#ifdef HAVE_ED448 -#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_IMPORT) +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) +#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) { @@ -3899,10 +3899,10 @@ static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, return ret; } -#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */ +#endif /* HAVE_ED448_SIGN */ -#if defined(HAVE_ED448_VERIFY) && defined(HAVE_ED448_KEY_IMPORT) +#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) @@ -3931,8 +3931,8 @@ static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, return ret; } -#endif /* HAVE_ED448_VERIFY && HAVE_ED448_KEY_IMPORT */ -#endif /* HAVE_ED448 */ +#endif /* HAVE_ED448_VERIFY */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */ #ifdef HAVE_CURVE448 static WC_INLINE int myX448KeyGen(WOLFSSL* ssl, curve448_key* key, @@ -4443,7 +4443,7 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) #ifndef NO_DH wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback); #endif - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) #ifdef HAVE_ED25519_SIGN wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign); #endif diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 647796e65..c07c22880 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -562,17 +562,24 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); #ifdef HAVE_ED25519 /* private key helpers */ +#ifdef HAVE_ED25519_KEY_IMPORT WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*, ed25519_key*, word32); +#endif + +#ifdef HAVE_ED25519_KEY_EXPORT WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen); WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen); +#endif /* public key helper */ WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*, ed25519_key*, word32); - #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) + #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) && \ + defined(HAVE_ED25519_KEY_EXPORT) + WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte* output, word32 inLen, int with_AlgCurve); #endif diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index f944d8fec..e1b090f79 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -167,6 +167,7 @@ WOLFSSL_API int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId); WOLFSSL_API void wc_ed25519_free(ed25519_key* key); +#ifdef HAVE_ED25519_KEY_IMPORT WOLFSSL_API int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key); WOLFSSL_API @@ -175,6 +176,9 @@ int wc_ed25519_import_private_only(const byte* priv, word32 privSz, WOLFSSL_API int wc_ed25519_import_private_key(const byte* priv, word32 privSz, const byte* pub, word32 pubSz, ed25519_key* key); +#endif /* HAVE_ED25519_KEY_IMPORT */ + +#ifdef HAVE_ED25519_KEY_EXPORT WOLFSSL_API int wc_ed25519_export_public(ed25519_key*, byte* out, word32* outLen); WOLFSSL_API @@ -185,6 +189,7 @@ WOLFSSL_API int wc_ed25519_export_key(ed25519_key* key, byte* priv, word32 *privSz, byte* pub, word32 *pubSz); +#endif /* HAVE_ED25519_KEY_EXPORT */ WOLFSSL_API int wc_ed25519_check_key(ed25519_key* key);