blake2b: blake2b_init_key and blake2b_compress refactory to reduce stack usage: (384 bytes - pointer sizes) moved to the heap.

--- block variable moved to the heap; (128 bytes)
--- m and w variables moved to the heap; (256 bytes)
--- chain of dependency updated to propagate the error.
This commit is contained in:
Moisés Guimarães
2014-04-15 12:46:43 -03:00
parent 8d8fca67c3
commit 69890dd023
5 changed files with 132 additions and 32 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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 ) )
{

View File

@ -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

View File

@ -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;