A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.
Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
Revision 6:cf58d49e1a86, committed 2015-03-23
- Comitter:
- Mike Fiore
- Date:
- Mon Mar 23 16:51:07 2015 -0500
- Parent:
- 5:d6c3db3c2459
- Commit message:
- fix whitespace in sha512.c
Changed in this revision
ctaocrypt/src/sha512.c | Show annotated file Show diff for this revision Revisions of this file |
diff -r d6c3db3c2459 -r cf58d49e1a86 ctaocrypt/src/sha512.c --- a/ctaocrypt/src/sha512.c Mon Mar 23 16:46:11 2015 -0500 +++ b/ctaocrypt/src/sha512.c Mon Mar 23 16:51:07 2015 -0500 @@ -18,29 +18,41 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + #ifdef HAVE_CONFIG_H #include <config.h> #endif + #include <cyassl/ctaocrypt/settings.h> + #ifdef CYASSL_SHA512 + #ifdef HAVE_FIPS /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ #define FIPS_NO_WRAPPERS #endif + #include <cyassl/ctaocrypt/sha512.h> #include <cyassl/ctaocrypt/logging.h> #include <cyassl/ctaocrypt/error-crypt.h> + #ifdef NO_INLINE #include <cyassl/ctaocrypt/misc.h> #else #include <ctaocrypt/src/misc.c> #endif + + #ifndef min + static INLINE word32 min(word32 a, word32 b) { return a > b ? b : a; } + #endif /* min */ + + int InitSha512(Sha512* sha512) { sha512->digest[0] = W64LIT(0x6a09e667f3bcc908); @@ -51,11 +63,15 @@ sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f); sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b); sha512->digest[7] = W64LIT(0x5be0cd19137e2179); + sha512->buffLen = 0; sha512->loLen = 0; sha512->hiLen = 0; + return 0; } + + static const word64 K512[80] = { W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), @@ -99,6 +115,7 @@ W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) }; + #define blk0(i) (W[i] = sha512->buffer[i]) #define blk2(i) (W[i&15] += s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])+0) @@ -130,21 +147,27 @@ d(i)+=h(i);\ h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + static int Transform(Sha512* sha512) { const word64* K = K512; + word32 j; word64 T[8]; + #ifdef CYASSL_SMALL_STACK word64* W; + W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) return MEMORY_E; #else word64 W[16]; #endif + /* Copy digest to working vars */ XMEMCPY(T, sha512->digest, sizeof(T)); + #ifdef USE_SLOW_SHA2 /* over twice as small, but 50% slower */ /* 80 operations, not unrolled */ @@ -163,7 +186,9 @@ R(12); R(13); R(14); R(15); } #endif /* USE_SLOW_SHA2 */ + /* Add the working vars back into digest */ + sha512->digest[0] += a(0); sha512->digest[1] += b(0); sha512->digest[2] += c(0); @@ -172,32 +197,43 @@ sha512->digest[5] += f(0); sha512->digest[6] += g(0); sha512->digest[7] += h(0); + /* Wipe variables */ XMEMSET(W, 0, sizeof(word64) * 16); XMEMSET(T, 0, sizeof(T)); + #ifdef CYASSL_SMALL_STACK XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + return 0; } + + static INLINE void AddLength(Sha512* sha512, word32 len) { word32 tmp = sha512->loLen; if ( (sha512->loLen += len) < tmp) sha512->hiLen++; /* carry low to high */ } + + int Sha512Update(Sha512* sha512, const byte* data, word32 len) { /* do block size increments */ byte* local = (byte*)sha512->buffer; + while (len) { word32 add = min(len, SHA512_BLOCK_SIZE - sha512->buffLen); XMEMCPY(&local[sha512->buffLen], data, add); + sha512->buffLen += add; data += add; len -= add; + if (sha512->buffLen == SHA512_BLOCK_SIZE) { int ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_BLOCK_SIZE); @@ -205,28 +241,36 @@ ret = Transform(sha512); if (ret != 0) return ret; + AddLength(sha512, SHA512_BLOCK_SIZE); sha512->buffLen = 0; } } return 0; } + + int Sha512Final(Sha512* sha512, byte* hash) { byte* local = (byte*)sha512->buffer; int ret; + AddLength(sha512, sha512->buffLen); /* before adding pads */ + local[sha512->buffLen++] = 0x80; /* add 1 */ + /* pad with zeros */ if (sha512->buffLen > SHA512_PAD_SIZE) { XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE -sha512->buffLen); sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE); #endif ret = Transform(sha512); if (ret != 0) return ret; + sha512->buffLen = 0; } XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen); @@ -235,6 +279,7 @@ sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) + (sha512->hiLen << 3); sha512->loLen = sha512->loLen << 3; + /* store lengths */ #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_PAD_SIZE); @@ -242,15 +287,20 @@ /* ! length ordering dependent on digest endian type ! */ sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen; sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen; + ret = Transform(sha512); if (ret != 0) return ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE); #endif XMEMCPY(hash, sha512->digest, SHA512_DIGEST_SIZE); + return InitSha512(sha512); /* reset state */ } + + int Sha512Hash(const byte* data, word32 len, byte* hash) { int ret = 0; @@ -259,6 +309,7 @@ #else Sha512 sha512[1]; #endif + #ifdef CYASSL_SMALL_STACK sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sha512 == NULL) @@ -281,7 +332,10 @@ return ret; } + + #ifdef CYASSL_SHA384 + int InitSha384(Sha384* sha384) { sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8); @@ -292,30 +346,38 @@ sha384->digest[5] = W64LIT(0x8eb44a8768581511); sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7); sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4); + sha384->buffLen = 0; sha384->loLen = 0; sha384->hiLen = 0; + return 0; } + + static int Transform384(Sha384* sha384) { const word64* K = K512; + word32 j; word64 T[8]; + #ifdef CYASSL_SMALL_STACK word64* W; + W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) return MEMORY_E; #else word64 W[16]; #endif + /* Copy digest to working vars */ XMEMCPY(T, sha384->digest, sizeof(T)); + #ifdef USE_SLOW_SHA2 /* over twice as small, but 50% slower */ /* 80 operations, not unrolled */ - for (j = 0; j < 80; j += 16) { int m; for (m = 0; m < 16; m++) { /* braces needed for macros {} */ @@ -331,7 +393,9 @@ R2(12); R2(13); R2(14); R2(15); } #endif /* USE_SLOW_SHA2 */ + /* Add the working vars back into digest */ + sha384->digest[0] += a(0); sha384->digest[1] += b(0); sha384->digest[2] += c(0); @@ -340,33 +404,43 @@ sha384->digest[5] += f(0); sha384->digest[6] += g(0); sha384->digest[7] += h(0); - + /* Wipe variables */ XMEMSET(W, 0, sizeof(word64) * 16); XMEMSET(T, 0, sizeof(T)); + #ifdef CYASSL_SMALL_STACK XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + return 0; } + + static INLINE void AddLength384(Sha384* sha384, word32 len) { word32 tmp = sha384->loLen; if ( (sha384->loLen += len) < tmp) sha384->hiLen++; /* carry low to high */ } + + int Sha384Update(Sha384* sha384, const byte* data, word32 len) { /* do block size increments */ byte* local = (byte*)sha384->buffer; + while (len) { word32 add = min(len, SHA384_BLOCK_SIZE - sha384->buffLen); XMEMCPY(&local[sha384->buffLen], data, add); + sha384->buffLen += add; data += add; len -= add; + if (sha384->buffLen == SHA384_BLOCK_SIZE) { int ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_BLOCK_SIZE); @@ -374,28 +448,36 @@ ret = Transform384(sha384); if (ret != 0) return ret; + AddLength384(sha384, SHA384_BLOCK_SIZE); sha384->buffLen = 0; } } return 0; } + + int Sha384Final(Sha384* sha384, byte* hash) { byte* local = (byte*)sha384->buffer; int ret; + AddLength384(sha384, sha384->buffLen); /* before adding pads */ + local[sha384->buffLen++] = 0x80; /* add 1 */ + /* pad with zeros */ if (sha384->buffLen > SHA384_PAD_SIZE) { XMEMSET(&local[sha384->buffLen], 0, SHA384_BLOCK_SIZE -sha384->buffLen); sha384->buffLen += SHA384_BLOCK_SIZE - sha384->buffLen; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->buffer,sha384->buffer,SHA384_BLOCK_SIZE); #endif ret = Transform384(sha384); if (ret != 0) return ret; + sha384->buffLen = 0; } XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen); @@ -404,6 +486,7 @@ sha384->hiLen = (sha384->loLen >> (8*sizeof(sha384->loLen) - 3)) + (sha384->hiLen << 3); sha384->loLen = sha384->loLen << 3; + /* store lengths */ #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_PAD_SIZE); @@ -411,15 +494,20 @@ /* ! length ordering dependent on digest endian type ! */ sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen; sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen; + ret = Transform384(sha384); if (ret != 0) return ret; + #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE); #endif XMEMCPY(hash, sha384->digest, SHA384_DIGEST_SIZE); + return InitSha384(sha384); /* reset state */ } + + int Sha384Hash(const byte* data, word32 len, byte* hash) { int ret = 0; @@ -428,11 +516,13 @@ #else Sha384 sha384[1]; #endif + #ifdef CYASSL_SMALL_STACK sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sha384 == NULL) return MEMORY_E; #endif + if ((ret = InitSha384(sha384)) != 0) { CYASSL_MSG("InitSha384 failed"); } @@ -442,10 +532,14 @@ else if ((ret = Sha384Final(sha384, hash)) != 0) { CYASSL_MSG("Sha384Final failed"); } + #ifdef CYASSL_SMALL_STACK XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + return ret; } + #endif /* CYASSL_SHA384 */ -#endif /* CYASSL_SHA512 */ \ No newline at end of file + +#endif /* CYASSL_SHA512 */