From 154930d128603b0d7d4e976dff7a87e17b8f2038 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 20 Aug 2019 16:14:37 -0700 Subject: [PATCH 1/4] Added support for older KECCAK256 used by Ethereum. Uses existing hash flag API's. To use add build flag `CFLAGS="-DWOLFSSL_HASH_FLAGS"`. Example: ```c wc_Sha3_SetFlags(&sha, WC_HASH_SHA3_KECCAK256); ``` --- configure.ac | 3 +++ wolfcrypt/src/sha3.c | 8 +++++++- wolfcrypt/test/test.c | 36 +++++++++++++++++++++++++++++++----- wolfssl/wolfcrypt/hash.h | 3 +++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index f943cc6ef..1a4c55f73 100644 --- a/configure.ac +++ b/configure.ac @@ -195,6 +195,9 @@ then # Enable DH const table speedups (eliminates `-lm` math lib dependency) AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DFP_MAX_BITS=8192" + # Enable hash flags support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HASH_FLAGS" + # Enable multiple attribute additions such as DC AM_CFLAGS="-DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS" fi diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index d0cf9b76a..3737411a8 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -637,9 +637,15 @@ static int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l) { byte i; byte *s8 = (byte *)sha3->s; + byte padChar = 0x06; /* NIST SHA-3 */ sha3->t[p * 8 - 1] = 0x00; - sha3->t[ sha3->i] = 0x06; +#ifdef WOLFSSL_HASH_FLAGS + if (p == WC_SHA3_256_COUNT && sha3->flags & WC_HASH_SHA3_KECCAK256) { + padChar = 0x01; + } +#endif + sha3->t[ sha3->i] = padChar; sha3->t[p * 8 - 1] |= 0x80; for (i=sha3->i + 1; i < p * 8 - 1; i++) sha3->t[i] = 0; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 952f18853..fda720192 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -2619,6 +2619,18 @@ static int sha3_256_test(void) int ret = 0; int times = sizeof(test_sha) / sizeof(struct testVector), i; + byte large_input[1024]; + const char* large_digest = + "\xdc\x90\xc0\xb1\x25\xdb\x2c\x34\x81\xa3\xff\xbc\x1e\x2e\x87\xeb" + "\x6d\x70\x85\x61\xe0\xe9\x63\x61\xff\xe5\x84\x4b\x1f\x68\x05\x15"; + +#ifdef WOLFSSL_HASH_FLAGS + /* test vector with hash of empty string */ + const char* Keccak256EmptyOut = + "\xc5\xd2\x46\x01\x86\xf7\x23\x3c\x92\x7e\x7d\xb2\xdc\xc7\x03\xc0" + "\xe5\x00\xb6\x53\xca\x82\x27\x3b\x7b\xfa\xd8\x04\x5d\x85\xa4\x70"; +#endif + a.input = ""; a.output = "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6" "\x62\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8" @@ -2667,11 +2679,6 @@ static int sha3_256_test(void) } /* BEGIN LARGE HASH TEST */ { - byte large_input[1024]; - const char* large_digest = - "\xdc\x90\xc0\xb1\x25\xdb\x2c\x34\x81\xa3\xff\xbc\x1e\x2e\x87\xeb" - "\x6d\x70\x85\x61\xe0\xe9\x63\x61\xff\xe5\x84\x4b\x1f\x68\x05\x15"; - for (i = 0; i < (int)sizeof(large_input); i++) { large_input[i] = (byte)(i & 0xFF); } @@ -2689,6 +2696,25 @@ static int sha3_256_test(void) ERROR_OUT(-2608, exit); } /* END LARGE HASH TEST */ +#ifdef WOLFSSL_HASH_FLAGS + /* Test for Keccak256 */ + ret = wc_Sha3_SetFlags(&sha, WC_HASH_SHA3_KECCAK256); + if (ret != 0) { + ERROR_OUT(-2609, exit); + } + ret = wc_Sha3_256_Update(&sha, (byte*)"", 0); + if (ret != 0) { + ERROR_OUT(-2610, exit); + } + ret = wc_Sha3_256_Final(&sha, hash); + if (ret != 0) { + ERROR_OUT(-2611, exit); + } + if (XMEMCMP(hash, Keccak256EmptyOut, WC_SHA3_256_DIGEST_SIZE) != 0) { + ERROR_OUT(-2612, exit); + } +#endif + exit: wc_Sha3_256_Free(&sha); diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 85983de03..7fbbe3413 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -83,6 +83,9 @@ enum wc_HashFlags { WC_HASH_FLAG_NONE = 0x00000000, WC_HASH_FLAG_WILLCOPY = 0x00000001, /* flag to indicate hash will be copied */ WC_HASH_FLAG_ISCOPY = 0x00000002, /* hash is copy */ +#ifdef WOLFSSL_SHA3 + WC_HASH_SHA3_KECCAK256 =0x00010000, /* Older KECCAK256 */ +#endif }; From a5d222a20ea9c64f838a3a492d6a4a983cec074a Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 20 Aug 2019 16:25:48 -0700 Subject: [PATCH 2/4] Make public the hash set/get flags functions. --- wolfssl/wolfcrypt/hash.h | 4 ++-- wolfssl/wolfcrypt/md5.h | 4 ++-- wolfssl/wolfcrypt/sha.h | 4 ++-- wolfssl/wolfcrypt/sha256.h | 8 ++++---- wolfssl/wolfcrypt/sha3.h | 4 ++-- wolfssl/wolfcrypt/sha512.h | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 7fbbe3413..28b1d4da3 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -166,9 +166,9 @@ WOLFSSL_API int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, WOLFSSL_API int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type); #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, + WOLFSSL_API int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, word32 flags); - WOLFSSL_LOCAL int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, + WOLFSSL_API int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags); #endif diff --git a/wolfssl/wolfcrypt/md5.h b/wolfssl/wolfcrypt/md5.h index 6c27d635f..dcb22c55d 100644 --- a/wolfssl/wolfcrypt/md5.h +++ b/wolfssl/wolfcrypt/md5.h @@ -118,8 +118,8 @@ WOLFSSL_API void wc_Md5SizeSet(wc_Md5* md5, word32 len); #endif #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Md5SetFlags(wc_Md5* md5, word32 flags); - WOLFSSL_LOCAL int wc_Md5GetFlags(wc_Md5* md5, word32* flags); + WOLFSSL_API int wc_Md5SetFlags(wc_Md5* md5, word32 flags); + WOLFSSL_API int wc_Md5GetFlags(wc_Md5* md5, word32* flags); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index b48fc8f85..f3ed2dba3 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -157,8 +157,8 @@ WOLFSSL_API void wc_ShaSizeSet(wc_Sha* sha, word32 len); #endif #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_ShaSetFlags(wc_Sha* sha, word32 flags); - WOLFSSL_LOCAL int wc_ShaGetFlags(wc_Sha* sha, word32* flags); + WOLFSSL_API int wc_ShaSetFlags(wc_Sha* sha, word32 flags); + WOLFSSL_API int wc_ShaGetFlags(wc_Sha* sha, word32* flags); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 5bfcc7cb4..27c89397f 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -189,8 +189,8 @@ WOLFSSL_API void wc_Sha256SizeSet(wc_Sha256*, word32); #endif #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags); - WOLFSSL_LOCAL int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags); + WOLFSSL_API int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags); + WOLFSSL_API int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags); #endif #ifdef WOLFSSL_SHA224 @@ -228,8 +228,8 @@ WOLFSSL_API int wc_Sha224GetHash(wc_Sha224*, byte*); WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst); #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags); - WOLFSSL_LOCAL int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags); + WOLFSSL_API int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags); + WOLFSSL_API int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags); #endif #endif /* WOLFSSL_SHA224 */ diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index cde45b267..5d365aedb 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -137,8 +137,8 @@ WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3*, byte*); WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst); #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags); - WOLFSSL_LOCAL int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags); + WOLFSSL_API int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags); + WOLFSSL_API int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 586289a8d..898032026 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -159,8 +159,8 @@ WOLFSSL_API int wc_Sha512GetHash(wc_Sha512*, byte*); WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst); #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags); - WOLFSSL_LOCAL int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags); + WOLFSSL_API int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags); + WOLFSSL_API int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags); #endif #endif /* WOLFSSL_SHA512 */ @@ -205,8 +205,8 @@ WOLFSSL_API int wc_Sha384GetHash(wc_Sha384*, byte*); WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst); #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) - WOLFSSL_LOCAL int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags); - WOLFSSL_LOCAL int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags); + WOLFSSL_API int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags); + WOLFSSL_API int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags); #endif #endif /* WOLFSSL_SHA384 */ From e298b3290d8e32a5148151d7f52c74ccfe3b7d84 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 21 Aug 2019 06:36:37 -0700 Subject: [PATCH 3/4] Fix to initialize hash flag. --- wolfcrypt/src/md5.c | 3 +++ wolfcrypt/src/port/arm/armv8-sha512.c | 6 ++++++ wolfcrypt/src/sha.c | 3 +++ wolfcrypt/src/sha256.c | 6 ++++++ wolfcrypt/src/sha3.c | 3 +++ wolfcrypt/src/sha512.c | 6 ++++++ 6 files changed, 27 insertions(+) diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index 5adce43d4..ad0ea18f7 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -255,6 +255,9 @@ static int _InitMd5(wc_Md5* md5) md5->buffLen = 0; md5->loLen = 0; md5->hiLen = 0; +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + md5->flags = 0; +#endif return ret; } diff --git a/wolfcrypt/src/port/arm/armv8-sha512.c b/wolfcrypt/src/port/arm/armv8-sha512.c index a272d466e..eab85863d 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512.c +++ b/wolfcrypt/src/port/arm/armv8-sha512.c @@ -61,6 +61,9 @@ static int InitSha512(wc_Sha512* sha512) sha512->buffLen = 0; sha512->loLen = 0; sha512->hiLen = 0; +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha512->flags = 0; +#endif return 0; } @@ -501,6 +504,9 @@ static int InitSha384(wc_Sha384* sha384) sha384->buffLen = 0; sha384->loLen = 0; sha384->hiLen = 0; +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha384->flags = 0; +#endif return 0; } diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 7e2be2576..e35253b1d 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -298,6 +298,9 @@ sha->buffLen = 0; sha->loLen = 0; sha->hiLen = 0; + #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha->flags = 0; + #endif return ret; } diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 059f224a7..ea43f43c0 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -184,6 +184,9 @@ static int InitSha256(wc_Sha256* sha256) sha256->buffLen = 0; sha256->loLen = 0; sha256->hiLen = 0; +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha256->flags = 0; +#endif return ret; } @@ -1198,6 +1201,9 @@ static int InitSha256(wc_Sha256* sha256) /* choose best Transform function under this runtime environment */ Sha256_SetTransform(); #endif + #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha224->flags = 0; + #endif return ret; } diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 3737411a8..9f045426c 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -570,6 +570,9 @@ static int InitSha3(wc_Sha3* sha3) for (i = 0; i < 25; i++) sha3->s[i] = 0; sha3->i = 0; +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha3->flags = 0; +#endif return 0; } diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index f327df978..885200cff 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -224,6 +224,9 @@ static int InitSha512(wc_Sha512* sha512) * whether using HW or SW is detemined at first call of update() */ sha512->ctx.mode = ESP32_SHA_INIT; +#endif +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha512->flags = 0; #endif return 0; } @@ -934,6 +937,9 @@ static int InitSha384(wc_Sha384* sha384) */ sha384->ctx.mode = ESP32_SHA_INIT; +#endif +#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) + sha384->flags = 0; #endif return 0; From 4ec90be4d6328d0a3911cd7c709e803f9729e931 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 27 Aug 2019 13:28:33 -0700 Subject: [PATCH 4/4] Added `--enable-hashflags` option. --- configure.ac | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 1a4c55f73..73628c3c3 100644 --- a/configure.ac +++ b/configure.ac @@ -188,6 +188,7 @@ then enable_scrypt=yes enable_indef=yes enable_enckeys=yes + enable_hashflags=yes # Enable AES Decrypt, AES ECB, Alt Names, DER Load, Keep Certs, CRL IO with Timeout AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB -DWOLFSSL_ALT_NAMES -DWOLFSSL_DER_LOAD -DKEEP_OUR_CERT -DKEEP_PEER_CERT -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT" @@ -195,9 +196,6 @@ then # Enable DH const table speedups (eliminates `-lm` math lib dependency) AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DFP_MAX_BITS=8192" - # Enable hash flags support - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HASH_FLAGS" - # Enable multiple attribute additions such as DC AM_CFLAGS="-DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS" fi @@ -4348,6 +4346,20 @@ then fi +# Enable hash flags support +# Hash flags are useful for runtime options such as SHA3 KECCAK256 selection +AC_ARG_ENABLE([hashflags], + [AS_HELP_STRING([--enable-hashflags],[Enable support for hash flags (default: disabled)])], + [ ENABLED_HASHFLAGS=$enableval ], + [ ENABLED_HASHFLAGS=no ] + ) + +if test "x$ENABLED_HASHFLAGS" != "xno" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HASH_FLAGS" +fi + + # User Settings AC_ARG_ENABLE([usersettings], [AS_HELP_STRING([--enable-usersettings],[Use your own user_settings.h and do not add Makefile CFLAGS (default: disabled)])], @@ -4744,6 +4756,7 @@ AM_CONDITIONAL([BUILD_TRUST_PEER_CERT],[test "x$have_tp" = "xyes"]) AM_CONDITIONAL([BUILD_PKI],[test "x$ENABLED_PKI" = "xyes"]) AM_CONDITIONAL([BUILD_DES3],[test "x$ENABLED_DES3" = "xyes"]) AM_CONDITIONAL([BUILD_PKCS7],[test "x$ENABLED_PKCS7" = "xyes"]) +AM_CONDITIONAL([BUILD_HASHFLAGS],[test "x$ENABLED_HASHFLAGS" = "xyes"]) CREATE_HEX_VERSION