diff --git a/configure.ac b/configure.ac index fa066432e..2e134be97 100644 --- a/configure.ac +++ b/configure.ac @@ -1334,6 +1334,19 @@ then fi +# Small Stack +AC_ARG_ENABLE([smallstack], + [ --enable-smallstack Enable Small Stack Usage (default: enabled)], + [ ENABLED_SMALL_STACK=$enableval ], + [ ENABLED_SMALL_STACK=yes ] + ) + +if test "$ENABLED_SMALL_STACK" = "no" +then + AM_CFLAGS="$AM_CFLAGS -DNO_SMALL_STACK" +fi + + #valgrind AC_ARG_ENABLE([valgrind], [ --enable-valgrind Enable valgrind for unit tests (default: disabled)], @@ -1760,6 +1773,7 @@ echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" echo " * All TLS Extensions: $ENABLED_TLSX" echo " * PKCS#7 $ENABLED_PKCS7" echo " * wolfSCEP $ENABLED_WOLFSCEP" +echo " * Small Stack: $ENABLED_SMALL_STACK" echo " * valgrind unit tests: $ENABLED_VALGRIND" echo " * LIBZ: $ENABLED_LIBZ" echo " * Examples: $ENABLED_EXAMPLES" diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index 5dc28e004..2cccd362a 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -623,8 +623,7 @@ void bench_sha256(void) Sha256 hash; byte digest[SHA256_DIGEST_SIZE]; double start, total, persec; - int i; - int ret; + int i, ret; ret = InitSha256(&hash); if (ret != 0) { @@ -735,15 +734,28 @@ void bench_blake2(void) Blake2b b2b; byte digest[64]; double start, total, persec; - int i; + int i, ret; - InitBlake2b(&b2b, 64); + ret = InitBlake2b(&b2b, 64); + if (ret != 0) { + printf("InitBlake2b failed, ret = %d\n", ret); + return; + } start = current_time(1); - for(i = 0; i < numBlocks; i++) - Blake2bUpdate(&b2b, plain, sizeof(plain)); + for(i = 0; i < numBlocks; i++) { + ret = Blake2bUpdate(&b2b, plain, sizeof(plain)); + if (ret != 0) { + printf("Blake2bUpdate failed, ret = %d\n", ret); + return; + } + } - Blake2bFinal(&b2b, digest, 64); + ret = Blake2bFinal(&b2b, digest, 64); + if (ret != 0) { + printf("Blake2bFinal failed, ret = %d\n", ret); + return; + } total = current_time(0) - start; persec = 1 / total * numBlocks; diff --git a/ctaocrypt/src/blake2b.c b/ctaocrypt/src/blake2b.c index a3f4224fb..77b736d22 100644 --- a/ctaocrypt/src/blake2b.c +++ b/ctaocrypt/src/blake2b.c @@ -163,12 +163,25 @@ int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, if( blake2b_init_param( S, P ) < 0 ) return -1; { +#ifndef NO_SMALL_STACK + byte* block; + + block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if ( block == NULL ) return -1; +#else byte block[BLAKE2B_BLOCKBYTES]; +#endif + XMEMSET( block, 0, BLAKE2B_BLOCKBYTES ); XMEMCPY( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */ - /*stack */ + /* memory */ + +#ifndef NO_SMALL_STACK + XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif } return 0; } @@ -176,9 +189,27 @@ int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, static int blake2b_compress( blake2b_state *S, const byte block[BLAKE2B_BLOCKBYTES] ) { + int i; + +#ifndef NO_SMALL_STACK + word64* m; + word64* v; + + m = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if ( m == NULL ) return -1; + + v = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if ( v == NULL ) + { + XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return -1; + } +#else word64 m[16]; word64 v[16]; - int i; +#endif for( i = 0; i < 16; ++i ) m[i] = load64( block + i * sizeof( m[i] ) ); @@ -234,6 +265,12 @@ static int blake2b_compress( blake2b_state *S, #undef G #undef ROUND + +#ifndef NO_SMALL_STACK + XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; } @@ -250,7 +287,9 @@ int blake2b_update( blake2b_state *S, const byte *in, word64 inlen ) XMEMCPY( S->buf + left, in, (word)fill ); /* Fill buffer */ S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); /* Compress */ + + if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */ + XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ S->buflen -= BLAKE2B_BLOCKBYTES; @@ -278,7 +317,9 @@ int blake2b_final( blake2b_state *S, byte *out, byte outlen ) if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); + + if ( blake2b_compress( S, S->buf ) < 0 ) return -1; + S->buflen -= BLAKE2B_BLOCKBYTES; XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (word)S->buflen ); } @@ -287,7 +328,7 @@ int blake2b_final( blake2b_state *S, byte *out, byte outlen ) blake2b_set_lastblock( S ); XMEMSET( S->buf + S->buflen, 0, (word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) ); /* Padding */ - blake2b_compress( S, S->buf ); + if ( blake2b_compress( S, S->buf ) < 0 ) return -1; for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); @@ -318,9 +359,9 @@ int blake2b( byte *out, const void *in, const void *key, const byte outlen, if( blake2b_init( S, outlen ) < 0 ) return -1; } - blake2b_update( S, ( byte * )in, inlen ); - blake2b_final( S, out, outlen ); - return 0; + if ( blake2b_update( S, ( byte * )in, inlen ) < 0) return -1; + + return blake2b_final( S, out, outlen ); } #if defined(BLAKE2B_SELFTEST) @@ -340,7 +381,11 @@ int main( int argc, char **argv ) for( word32 i = 0; i < KAT_LENGTH; ++i ) { byte hash[BLAKE2B_OUTBYTES]; - blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); + if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ) + { + puts( "error" ); + return -1; + } if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) { diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 9afae366d..c383dc0fb 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -103,7 +103,7 @@ static int InitHmac(Hmac* hmac, int type) #ifdef HAVE_BLAKE2 case BLAKE2B_ID: - InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); + ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); break; #endif @@ -238,8 +238,14 @@ int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) XMEMCPY(ip, key, length); } else { - Blake2bUpdate(&hmac->hash.blake2b, key, length); - Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); + ret = Blake2bUpdate(&hmac->hash.blake2b, key, length); + if (ret != 0) + return ret; + + ret = Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); + if (ret != 0) + return ret; + length = BLAKE2B_256; } } @@ -306,8 +312,10 @@ static int HmacKeyInnerHash(Hmac* hmac) #ifdef HAVE_BLAKE2 case BLAKE2B_ID: - Blake2bUpdate(&hmac->hash.blake2b, + ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); + if (ret != 0) + return ret; break; #endif @@ -375,7 +383,9 @@ int HmacUpdate(Hmac* hmac, const byte* msg, word32 length) #ifdef HAVE_BLAKE2 case BLAKE2B_ID: - Blake2bUpdate(&hmac->hash.blake2b, msg, length); + ret = Blake2bUpdate(&hmac->hash.blake2b, msg, length); + if (ret != 0) + return ret; break; #endif @@ -506,13 +516,24 @@ int HmacFinal(Hmac* hmac, byte* hash) #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { - Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, + ret = Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); - Blake2bUpdate(&hmac->hash.blake2b, + if (ret != 0) + return ret; + + ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); - Blake2bUpdate(&hmac->hash.blake2b, + if (ret != 0) + return ret; + + ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); - Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); + if (ret != 0) + return ret; + + ret = Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); + if (ret != 0) + return ret; } break; #endif diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index c499d0728..7e315cec4 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -919,15 +919,23 @@ int blake2b_test(void) Blake2b b2b; byte digest[64]; byte input[64]; - int i; + int i, ret; for (i = 0; i < (int)sizeof(input); i++) input[i] = (byte)i; for (i = 0; i < BLAKE2_TESTS; i++) { - InitBlake2b(&b2b, 64); - Blake2bUpdate(&b2b, input, i); - Blake2bFinal(&b2b, digest, 64); + ret = InitBlake2b(&b2b, 64); + if (ret != 0) + return -4002; + + ret = Blake2bUpdate(&b2b, input, i); + if (ret != 0) + return -4003; + + ret = Blake2bFinal(&b2b, digest, 64); + if (ret != 0) + return -4004; if (memcmp(digest, blake2b_vec[i], 64) != 0) { return -300 - i; @@ -969,15 +977,15 @@ int sha256_test(void) ret = InitSha256(&sha); if (ret != 0) - return -4003; + return -4005; for (i = 0; i < times; ++i) { ret = Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); if (ret != 0) - return -4004; + return -4006; ret = Sha256Final(&sha, hash); if (ret != 0) - return -4005; + return -4007; if (memcmp(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0) return -10 - i;