From 329cd0b2411742843ef9b68f8ed5cee8bc1f8343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Guimar=C3=A3es?= Date: Thu, 3 Apr 2014 12:34:54 -0300 Subject: [PATCH] sha256: XTRANSFORM refactory to reduce stack usage: (256 bytes - pointer size) moved to the heap. --- W variable moved to the heap; --- return type changed to int, returning 0 for success; --- chain of dependency updated to propagate the error in Sha256Update and Sha256Final functions. sha512: Transform and Transform384 refactory to reduce stack usage: (128 bytes - pointer size) moved to the heap in each function --- W variable moved to the heap; --- return type changed to int, returning 0 for success; --- chain of dependency updated to propagate the error in Sha512Update, Sha512Final, Sha384Update and Sha384Final functions. --- ctaocrypt/src/sha256.c | 51 ++++++++++++++++++++++++++------- ctaocrypt/src/sha512.c | 65 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 94 insertions(+), 22 deletions(-) diff --git a/ctaocrypt/src/sha256.c b/ctaocrypt/src/sha256.c index 2a751f0f2..30f639efb 100644 --- a/ctaocrypt/src/sha256.c +++ b/ctaocrypt/src/sha256.c @@ -42,6 +42,7 @@ #endif #include +#include #ifdef NO_INLINE #include #else @@ -50,12 +51,8 @@ #ifdef FREESCALE_MMCAU #include "cau_api.h" - #define XTRANSFORM(S,B) cau_sha256_hash_n((B), 1, ((S))->digest) -#else - #define XTRANSFORM(S,B) Transform((S)) #endif - #ifndef min static INLINE word32 min(word32 a, word32 b) @@ -88,7 +85,18 @@ int InitSha256(Sha256* sha256) return 0; } -#ifndef FREESCALE_MMCAU +#ifdef FREESCALE_MMCAU + #define XTRANSFORM(S,B) Transform((S), (B)) + +static int Transform(Sha256* sha256, byte* buf) +{ + cau_sha256_hash_n(buf, 1, sha256->digest); + + return 0; +} + +#else + #define XTRANSFORM(S,B) Transform((S)) static const word32 K[64] = { 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, @@ -122,11 +130,16 @@ static const word32 K[64] = { h = t0 + t1; -static void Transform(Sha256* sha256) +static int Transform(Sha256* sha256) { - word32 S[8], W[64], t0, t1; + word32 S[8], t0, t1; + word32* W; int i; + W = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (W == NULL) + return MEMORY_E; + /* Copy context->state[] to working vars */ for (i = 0; i < 8; i++) S[i] = sha256->digest[i]; @@ -152,6 +165,10 @@ static void Transform(Sha256* sha256) for (i = 0; i < 8; i++) { sha256->digest[i] += S[i]; } + + XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return 0; } #endif /* FREESCALE_MMCAU */ @@ -179,11 +196,17 @@ int Sha256Update(Sha256* sha256, const byte* data, word32 len) len -= add; if (sha256->buffLen == SHA256_BLOCK_SIZE) { + int ret; + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE); #endif - XTRANSFORM(sha256, local); + + ret = XTRANSFORM(sha256, local); + if (ret != 0) + return ret; + AddLength(sha256, SHA256_BLOCK_SIZE); sha256->buffLen = 0; } @@ -196,6 +219,7 @@ int Sha256Update(Sha256* sha256, const byte* data, word32 len) int Sha256Final(Sha256* sha256, byte* hash) { byte* local = (byte*)sha256->buffer; + int ret; AddLength(sha256, sha256->buffLen); /* before adding pads */ @@ -209,7 +233,11 @@ int Sha256Final(Sha256* sha256, byte* hash) #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE); #endif - XTRANSFORM(sha256, local); + + ret = XTRANSFORM(sha256, local); + if (ret != 0) + return ret; + sha256->buffLen = 0; } XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); @@ -235,7 +263,10 @@ int Sha256Final(Sha256* sha256, byte* hash) 2 * sizeof(word32)); #endif - XTRANSFORM(sha256, local); + ret = XTRANSFORM(sha256, local); + if (ret != 0) + return ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); #endif diff --git a/ctaocrypt/src/sha512.c b/ctaocrypt/src/sha512.c index 6a2f61857..81595b8d0 100644 --- a/ctaocrypt/src/sha512.c +++ b/ctaocrypt/src/sha512.c @@ -33,6 +33,7 @@ #endif #include +#include #ifdef NO_INLINE #include #else @@ -142,13 +143,17 @@ static const word64 K512[80] = { d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) -static void Transform(Sha512* sha512) +static int Transform(Sha512* sha512) { const word64* K = K512; word32 j; - word64 W[16]; word64 T[8]; + word64* W; + + W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (W == NULL) + return MEMORY_E; /* Copy digest to working vars */ XMEMCPY(T, sha512->digest, sizeof(T)); @@ -184,8 +189,12 @@ static void Transform(Sha512* sha512) sha512->digest[7] += h(0); /* Wipe variables */ - XMEMSET(W, 0, sizeof(W)); + XMEMSET(W, 0, sizeof(word64) * 16); XMEMSET(T, 0, sizeof(T)); + + XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return 0; } @@ -211,11 +220,16 @@ int Sha512Update(Sha512* sha512, const byte* data, word32 len) len -= add; if (sha512->buffLen == SHA512_BLOCK_SIZE) { + int ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_BLOCK_SIZE); #endif - Transform(sha512); + ret = Transform(sha512); + if (ret != 0) + return ret; + AddLength(sha512, SHA512_BLOCK_SIZE); sha512->buffLen = 0; } @@ -227,6 +241,7 @@ int Sha512Update(Sha512* sha512, const byte* data, word32 len) int Sha512Final(Sha512* sha512, byte* hash) { byte* local = (byte*)sha512->buffer; + int ret; AddLength(sha512, sha512->buffLen); /* before adding pads */ @@ -240,7 +255,10 @@ int Sha512Final(Sha512* sha512, byte* hash) #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE); #endif - Transform(sha512); + ret = Transform(sha512); + if (ret != 0) + return ret; + sha512->buffLen = 0; } XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen); @@ -258,7 +276,10 @@ int Sha512Final(Sha512* sha512, byte* hash) sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen; sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen; - Transform(sha512); + ret = Transform(sha512); + if (ret != 0) + return ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE); #endif @@ -290,13 +311,17 @@ int InitSha384(Sha384* sha384) } -static void Transform384(Sha384* sha384) +static int Transform384(Sha384* sha384) { const word64* K = K512; word32 j; - word64 W[16]; word64 T[8]; + word64* W; + + W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (W == NULL) + return MEMORY_E; /* Copy digest to working vars */ XMEMCPY(T, sha384->digest, sizeof(T)); @@ -332,8 +357,12 @@ static void Transform384(Sha384* sha384) sha384->digest[7] += h(0); /* Wipe variables */ - XMEMSET(W, 0, sizeof(W)); + XMEMSET(W, 0, sizeof(word64) * 16); XMEMSET(T, 0, sizeof(T)); + + XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return 0; } @@ -359,11 +388,16 @@ int Sha384Update(Sha384* sha384, const byte* data, word32 len) len -= add; if (sha384->buffLen == SHA384_BLOCK_SIZE) { + int ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_BLOCK_SIZE); #endif - Transform384(sha384); + ret = Transform384(sha384); + if (ret != 0) + return ret; + AddLength384(sha384, SHA384_BLOCK_SIZE); sha384->buffLen = 0; } @@ -375,6 +409,7 @@ int Sha384Update(Sha384* sha384, const byte* data, word32 len) int Sha384Final(Sha384* sha384, byte* hash) { byte* local = (byte*)sha384->buffer; + int ret; AddLength384(sha384, sha384->buffLen); /* before adding pads */ @@ -388,7 +423,10 @@ int Sha384Final(Sha384* sha384, byte* hash) #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->buffer,sha384->buffer,SHA384_BLOCK_SIZE); #endif - Transform384(sha384); + ret = Transform384(sha384); + if (ret != 0) + return ret; + sha384->buffLen = 0; } XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen); @@ -406,7 +444,10 @@ int Sha384Final(Sha384* sha384, byte* hash) sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen; sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen; - Transform384(sha384); + ret = Transform384(sha384); + if (ret != 0) + return ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE); #endif