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/src/internal.c b/src/internal.c index e424da276..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. @@ -4771,6 +4776,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 +4831,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 +4849,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 +4909,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 */ @@ -5035,6 +5062,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; @@ -5061,6 +5092,7 @@ int Ed448CheckPubKey(WOLFSSL* ssl) } return ret; +#endif /* HAVE_ED448_KEY_IMPORT */ } /* Sign the data using EdDSA and key using Ed448. @@ -5078,6 +5110,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 +5165,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 +5183,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 +5243,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 */ @@ -12582,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; @@ -12635,8 +12689,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->ecdhCurveOID = ECC_X25519_OID; break; } - #endif /* HAVE_ED25519 */ - #ifdef HAVE_ED448 + #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) case ED448k: { int keyRet = 0; @@ -12688,7 +12742,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; } @@ -21671,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 @@ -21712,8 +21766,8 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) goto exit_dpk; } } -#endif /* HAVE_ED25519 */ -#ifdef HAVE_ED448 +#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); #endif @@ -21756,7 +21810,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 f9c18f1e6..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,8 +5378,8 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der XFREE(key, heap, DYNAMIC_TYPE_ED25519); #endif } -#endif /* HAVE_ED25519 */ -#ifdef HAVE_ED448 +#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 */ #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; } @@ -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,8 +47212,14 @@ 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) || !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; (void) priv; @@ -47214,7 +47227,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 && HAVE_ED25519_KEY_IMPORT */ ed25519_key key; int ret = WOLFSSL_FAILURE; @@ -47247,7 +47260,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 && HAVE_ED25519_KEY_IMPORT */ } /* return 1 if success, 0 if error @@ -47258,8 +47271,14 @@ 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) || !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; (void) pub; @@ -47267,7 +47286,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 && HAVE_ED25519_KEY_IMPORT */ ed25519_key key; int ret = WOLFSSL_FAILURE, check = 0; @@ -47302,7 +47321,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 && HAVE_ED25519_KEY_IMPORT */ } #endif /* OPENSSL_EXTRA && HAVE_ED25519 */ @@ -47468,7 +47487,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; @@ -47527,7 +47553,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 @@ -47538,8 +47564,14 @@ 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) || !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; (void) priv; @@ -47547,7 +47579,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 && HAVE_ED448_KEY_IMPORT */ ed448_key key; int ret = WOLFSSL_FAILURE; @@ -47579,7 +47611,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 && HAVE_ED448_KEY_IMPORT */ } /* return 1 if success, 0 if error @@ -47590,8 +47622,14 @@ 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) || !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; (void) pub; @@ -47599,7 +47637,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 && HAVE_ED448_KEY_IMPORT */ ed448_key key; int ret = WOLFSSL_FAILURE, check = 0; @@ -47634,7 +47672,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..5538e0fd7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2603,54 +2603,68 @@ 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); +#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 && 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); +#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); +#ifdef HAVE_ED25519_VERIFY AssertIntEQ(wolfSSL_ED25519_verify((byte*)msg, msglen, pub, pubSz, sig, sigSz), WOLFSSL_SUCCESS); -#endif /* HAVE_ED25519 && WOLFSSL_KEY_GEN */ +#endif /* HAVE_ED25519_VERIFY */ +#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); +#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 && 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); +#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); +#ifdef HAVE_ED448_VERIFY AssertIntEQ(wolfSSL_ED448_verify((byte*)msg, msglen, pub, pubSz, sig, sigSz), WOLFSSL_SUCCESS); -#endif /* HAVE_ED448 && WOLFSSL_KEY_GEN */ +#endif /* HAVE_ED448_VERIFY */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_IMPORT */ +#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT && WOLFSSL_KEY_GEN */ } #endif /* OPENSSL_EXTRA */ @@ -6929,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" @@ -6960,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" @@ -18723,7 +18739,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 +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) { @@ -18925,6 +18947,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 +18980,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) { @@ -19253,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]; @@ -20514,7 +20553,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 +20741,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) { @@ -20723,6 +20768,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 +20801,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) { @@ -21051,8 +21114,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]; @@ -23991,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; @@ -24056,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; @@ -24122,8 +24185,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; @@ -24187,8 +24250,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; @@ -24304,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) @@ -24314,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 @@ -24327,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) { @@ -24364,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) { @@ -24395,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) @@ -24405,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 @@ -24418,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) { @@ -24455,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) { @@ -28106,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 @@ -28132,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 @@ -39240,28 +39299,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/tests/suites.c b/tests/suites.c index cd554f96e..88ef27291 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -887,7 +887,9 @@ 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) && \ + 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"); @@ -898,7 +900,9 @@ 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) && \ + 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/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/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..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,9 +3296,9 @@ 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(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; @@ -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,8 +3555,8 @@ 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) +#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); 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 */ @@ -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; @@ -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; @@ -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, @@ -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,9 +12710,9 @@ 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)) +#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)) /* 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 @@ -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; @@ -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; @@ -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; } @@ -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; @@ -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; @@ -15116,12 +15116,12 @@ 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); #endif -#ifdef HAVE_ED448 +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) /* ED448 public key */ if (ed448Key != NULL) bufferSz = SetEd448PublicKey(buf, ed448Key, 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,12 +17315,13 @@ 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 */ #ifdef HAVE_ED448 +#ifdef HAVE_ED448_KEY_IMPORT int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx, ed448_key* key, word32 inSz) { @@ -17417,9 +17421,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 +17496,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/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/ed25519.c b/wolfcrypt/src/ed25519.c index 2df7e13b8..9c31699a9 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -56,30 +56,114 @@ 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; + 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; +} +#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */ + +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; +#else + (void)key; +#endif + return wc_Sha512Update(sha, data, len); +} + +static int ed25519_hash_final(ed25519_key* key, wc_Sha512 *sha, byte* 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; - wc_Sha512 sha; - int devId = INVALID_DEVID; +#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 WOLF_CRYPTO_CB - devId = key->devId; +#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_final(key, sha, hash); + +#ifndef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, sha); #endif - 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 +271,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 +280,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 +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; - ret = wc_InitSha512_ex(&sha, NULL, devId); - if (ret != 0) - return ret; - if (type == Ed25519ctx || type == Ed25519ph) { - ret = wc_Sha512Update(&sha, 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 = wc_Sha512Update(&sha, &type, sizeof(type)); + ret = ed25519_hash_update(key, sha, az + ED25519_KEY_SIZE, + ED25519_KEY_SIZE); if (ret == 0) - ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen)); - if (ret == 0 && context != NULL) - ret = wc_Sha512Update(&sha, 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 = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE); - if (ret == 0) - ret = wc_Sha512Update(&sha, in, inLen); - if (ret == 0) - ret = wc_Sha512Final(&sha, nonce); - wc_Sha512Free(&sha); + if (ret != 0) return ret; @@ -269,27 +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 */ - ret = wc_InitSha512_ex(&sha, NULL, devId); - if (ret != 0) - return ret; - if (type == Ed25519ctx || type == Ed25519ph) { - ret = wc_Sha512Update(&sha, 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 = wc_Sha512Update(&sha, &type, sizeof(type)); + ret = ed25519_hash_update(key, sha, out, ED25519_SIG_SIZE/2); if (ret == 0) - ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen)); - if (ret == 0 && context != NULL) - ret = wc_Sha512Update(&sha, 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 = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2); - if (ret == 0) - ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE); - if (ret == 0) - ret = wc_Sha512Update(&sha, in, inLen); - if (ret == 0) - ret = wc_Sha512Final(&sha, hram); - wc_Sha512Free(&sha); + if (ret != 0) return ret; @@ -301,7 +407,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 +493,86 @@ 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 +*/ +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; + + /* 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 */ + +#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, 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, sha, sig, ED25519_SIG_SIZE/2); + if (ret == 0) + ret = ed25519_hash_update(key, sha, 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 +*/ +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, sha, 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) +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]; @@ -408,14 +581,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 +593,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 +600,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, sha, h); if (ret != 0) return ret; @@ -485,16 +624,93 @@ 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; } +#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 + 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; +#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 || + (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 + +#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 = ed25519_verify_msg_update_with_sha(msg, msgLen, key, sha); + if (ret < 0) + return ret; + + return ed25519_verify_msg_final_with_sha(sig, sigLen, res, key, sha); +} + /* sig is array of bytes containing the signature sigLen is the length of sig byte array @@ -508,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); } /* @@ -527,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); } /* @@ -546,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); } /* @@ -572,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 */ @@ -589,13 +805,17 @@ 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 +#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) @@ -609,6 +829,10 @@ void wc_ed25519_free(ed25519_key* key) if (key == NULL) return; +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + ed25519_hash_free(key, &key->sha); +#endif + ForceZero(key, sizeof(ed25519_key)); } @@ -735,8 +959,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 +977,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..cdbb3111b 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -51,6 +51,120 @@ 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; + + 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; +} +#endif /* WOLFSSL_ED448_PERSISTENT_SHA */ + +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; +#else + (void)key; +#endif + return wc_Shake256_Update(sha, data, len); +} + +static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash, + word32 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_final(key, sha, hash, hashLen); + +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif + + return ret; +} + /* Derive the public key for the private key. * * key [in] Ed448 key object. @@ -71,9 +185,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 +243,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 +261,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 +269,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,39 +291,55 @@ 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) { +#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 = wc_InitShake256(&sha, NULL, INVALID_DEVID); + ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); + if (ret == 0) { - ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); + ret = ed448_hash_update(key, sha, &type, sizeof(type)); } if (ret == 0) { - ret = wc_Shake256_Update(&sha, &type, sizeof(type)); - } - if (ret == 0) { - ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); + ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen)); } if ((ret == 0) && (context != NULL)) { - ret = wc_Shake256_Update(&sha, context, contextLen); + ret = ed448_hash_update(key, sha, context, contextLen); } if (ret == 0) { - ret = wc_Shake256_Update(&sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE); + ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE); } if (ret == 0) { - ret = wc_Shake256_Update(&sha, in, inLen); + ret = ed448_hash_update(key, sha, in, inLen); } if (ret == 0) { - ret = wc_Shake256_Final(&sha, nonce, sizeof(nonce)); + ret = ed448_hash_final(key, sha, nonce, sizeof(nonce)); } - wc_Shake256_Free(&sha); +#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 @@ -221,32 +349,32 @@ 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); + + ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); 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, out, 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, in, inLen); - } - if (ret == 0) { - ret = wc_Shake256_Final(&sha, hram, sizeof(hram)); - } - wc_Shake256_Free(&sha); + 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) { @@ -277,7 +405,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 +430,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. @@ -326,10 +454,11 @@ 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)); - ret = wc_Shake256Hash(in, inLen, hash, sizeof(hash)); if (ret == 0) { ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key, context, contextLen); @@ -345,8 +474,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,89 +484,203 @@ 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) + +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; + + /* 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 */ +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + ret = ed448_hash_reset(key); + if (ret < 0) + return ret; +#endif + + ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE); + if (ret == 0) { + 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, sig, ED448_SIG_SIZE/2); + } + if (ret == 0) { + ret = ed448_hash_update(key, sha, 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 +*/ +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, sha, 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. + */ +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]; 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, sha, 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; + } + else { + /* set the verification status */ + *res = 1; } - 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); + return ret; +} - /* 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)); - } +#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); +} - if (ret == 0) { - ge448_to_bytes(rcheck, &R); +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); +} - /* 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; - } - } +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. + * 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; +#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) + 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); + +#ifndef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, sha); +#endif return ret; } @@ -464,7 +705,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 +729,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); } @@ -513,9 +754,10 @@ 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)); - ret = wc_Shake256Hash(msg, msgLen, hash, sizeof(hash)); if (ret == 0) { ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key, context, contextLen); @@ -528,24 +770,40 @@ 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; + if (key == NULL) + return BAD_FUNC_ARG; - if (key == NULL) { - ret = BAD_FUNC_ARG; - } - else { - XMEMSET(key, 0, sizeof(ed448_key)); + XMEMSET(key, 0, sizeof(ed448_key)); - fe448_init(); - } +#ifdef WOLF_CRYPTO_CB + key->devId = devId; +#else + (void)devId; +#endif + key->heap = heap; - return ret; + fe448_init(); + +#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. + * + * 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 +812,9 @@ int wc_ed448_init(ed448_key* key) void wc_ed448_free(ed448_key* key) { if (key != NULL) { +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + ed448_hash_free(key, &key->sha); +#endif ForceZero(key, sizeof(ed448_key)); } } @@ -681,46 +942,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/evp.c b/wolfcrypt/src/evp.c index 8cc68b005..9928699c2 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,44 @@ 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) { + if (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 +4367,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; } @@ -4377,7 +4383,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 */ @@ -5406,8 +5412,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 +5424,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; } 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 0ee9e52f6..d772496b0 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 @@ -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, NULL, - 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, NULL, 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) - XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif +#ifdef WOLFSSL_SMALL_STACK + XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } #endif /* OPENSSL_EXTRA */ @@ -1191,7 +1192,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/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; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 42a05daaa..e11194245 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -25143,6 +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 */ @@ -25501,9 +25504,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 +25521,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 +25553,20 @@ 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) + 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; +#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */ + /* 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 +26251,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 +26367,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 +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 */ @@ -26892,9 +26920,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 +26937,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 +26972,20 @@ 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) + 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; +#endif /* WOLFSSL_ED448_STREAMING_VERIFY */ + /* 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 +30263,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 +37096,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 +37110,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 +37126,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..7d72319ad 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3697,7 +3697,8 @@ 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) { @@ -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,7 +3765,8 @@ static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz return ret; } -#endif /* HAVE_ED25519 */ +#endif /* HAVE_ED25519_VERIFY */ +#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #ifdef HAVE_CURVE25519 static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key, @@ -3857,7 +3861,8 @@ static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey } #endif /* HAVE_CURVE25519 */ -#ifdef HAVE_ED448 +#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) { @@ -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,7 +3931,8 @@ static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, return ret; } -#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, @@ -4435,17 +4443,25 @@ 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 + #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 + #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) + #if defined(HAVE_ED448_SIGN) wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign); + #endif + #if defined(HAVE_ED448_VERIFY) wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify); + #endif #endif #ifdef HAVE_CURVE448 wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen); diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 01af995ba..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 @@ -580,17 +587,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/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 728992363..e1b090f79 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 @@ -89,6 +92,11 @@ struct ed25519_key { #endif #if defined(WOLF_CRYPTO_CB) int devId; +#endif + void *heap; +#ifdef WOLFSSL_ED25519_PERSISTENT_SHA + wc_Sha512 sha; + int sha_clean_flag; #endif }; @@ -98,6 +106,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 +126,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 +147,19 @@ 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); +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 /* WOLFSSL_ED25519_STREAMING_VERIFY */ +#endif /* HAVE_ED25519_VERIFY */ + WOLFSSL_API int wc_ed25519_init(ed25519_key* key); @@ -143,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 @@ -151,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 @@ -161,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); diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index d45585a3f..50818e1f1 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 @@ -62,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, @@ -86,6 +90,14 @@ struct ed448_key { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif +#if defined(WOLF_CRYPTO_CB) + int devId; +#endif + void *heap; +#ifdef WOLFSSL_ED448_PERSISTENT_SHA + wc_Shake sha; + int sha_clean_flag; +#endif }; @@ -94,6 +106,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 +115,30 @@ 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); +#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); +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); +#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, @@ -117,10 +151,15 @@ 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 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 @@ -129,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 @@ -138,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); 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