This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
sha256.c
00001 /* sha256.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 00023 /* code submitted by raphael.huck@efixo.com */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 #include <cyassl/ctaocrypt/settings.h> 00030 00031 #ifndef NO_SHA256 00032 00033 #include <cyassl/ctaocrypt/sha256.h> 00034 #ifdef NO_INLINE 00035 #include <cyassl/ctaocrypt/misc.h> 00036 #else 00037 #include <ctaocrypt/src/misc.c> 00038 #endif 00039 00040 00041 #ifndef min 00042 00043 static INLINE word32 min(word32 a, word32 b) 00044 { 00045 return a > b ? b : a; 00046 } 00047 00048 #endif /* min */ 00049 00050 00051 void InitSha256(Sha256* sha256) 00052 { 00053 sha256->digest[0] = 0x6A09E667L; 00054 sha256->digest[1] = 0xBB67AE85L; 00055 sha256->digest[2] = 0x3C6EF372L; 00056 sha256->digest[3] = 0xA54FF53AL; 00057 sha256->digest[4] = 0x510E527FL; 00058 sha256->digest[5] = 0x9B05688CL; 00059 sha256->digest[6] = 0x1F83D9ABL; 00060 sha256->digest[7] = 0x5BE0CD19L; 00061 00062 sha256->buffLen = 0; 00063 sha256->loLen = 0; 00064 sha256->hiLen = 0; 00065 } 00066 00067 static const word32 K[64] = { 00068 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, 00069 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, 00070 0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, 00071 0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL, 00072 0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L, 00073 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L, 00074 0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, 00075 0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L, 00076 0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L, 00077 0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L, 00078 0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, 00079 0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L, 00080 0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L 00081 }; 00082 00083 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 00084 #define Maj(x,y,z) (((x | y) & z) | (x & y)) 00085 #define S(x, n) rotrFixed(x, n) 00086 #define R(x, n) (((x)&0xFFFFFFFFU)>>(n)) 00087 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 00088 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 00089 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 00090 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 00091 00092 #define RND(a,b,c,d,e,f,g,h,i) \ 00093 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 00094 t1 = Sigma0(a) + Maj(a, b, c); \ 00095 d += t0; \ 00096 h = t0 + t1; 00097 00098 00099 static void Transform(Sha256* sha256) 00100 { 00101 word32 S[8], W[64], t0, t1; 00102 int i; 00103 00104 /* Copy context->state[] to working vars */ 00105 for (i = 0; i < 8; i++) 00106 S[i] = sha256->digest[i]; 00107 00108 for (i = 0; i < 16; i++) 00109 W[i] = sha256->buffer[i]; 00110 00111 for (i = 16; i < 64; i++) 00112 W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16]; 00113 00114 for (i = 0; i < 64; i += 8) { 00115 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); 00116 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); 00117 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); 00118 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); 00119 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); 00120 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); 00121 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); 00122 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); 00123 } 00124 00125 /* Add the working vars back into digest state[] */ 00126 for (i = 0; i < 8; i++) { 00127 sha256->digest[i] += S[i]; 00128 } 00129 } 00130 00131 00132 static INLINE void AddLength(Sha256* sha256, word32 len) 00133 { 00134 word32 tmp = sha256->loLen; 00135 if ( (sha256->loLen += len) < tmp) 00136 sha256->hiLen++; /* carry low to high */ 00137 } 00138 00139 00140 void Sha256Update(Sha256* sha256, const byte* data, word32 len) 00141 { 00142 /* do block size increments */ 00143 byte* local = (byte*)sha256->buffer; 00144 00145 while (len) { 00146 word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); 00147 XMEMCPY(&local[sha256->buffLen], data, add); 00148 00149 sha256->buffLen += add; 00150 data += add; 00151 len -= add; 00152 00153 if (sha256->buffLen == SHA256_BLOCK_SIZE) { 00154 #ifdef LITTLE_ENDIAN_ORDER 00155 ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); 00156 #endif 00157 Transform(sha256); 00158 AddLength(sha256, SHA256_BLOCK_SIZE); 00159 sha256->buffLen = 0; 00160 } 00161 } 00162 } 00163 00164 00165 void Sha256Final(Sha256* sha256, byte* hash) 00166 { 00167 byte* local = (byte*)sha256->buffer; 00168 00169 AddLength(sha256, sha256->buffLen); /* before adding pads */ 00170 00171 local[sha256->buffLen++] = 0x80; /* add 1 */ 00172 00173 /* pad with zeros */ 00174 if (sha256->buffLen > SHA256_PAD_SIZE) { 00175 XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); 00176 sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; 00177 00178 #ifdef LITTLE_ENDIAN_ORDER 00179 ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); 00180 #endif 00181 Transform(sha256); 00182 sha256->buffLen = 0; 00183 } 00184 XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); 00185 00186 /* put lengths in bits */ 00187 sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) + 00188 (sha256->hiLen << 3); 00189 sha256->loLen = sha256->loLen << 3; 00190 00191 /* store lengths */ 00192 #ifdef LITTLE_ENDIAN_ORDER 00193 ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); 00194 #endif 00195 /* ! length ordering dependent on digest endian type ! */ 00196 XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32)); 00197 XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, 00198 sizeof(word32)); 00199 00200 Transform(sha256); 00201 #ifdef LITTLE_ENDIAN_ORDER 00202 ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); 00203 #endif 00204 XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE); 00205 00206 InitSha256(sha256); /* reset state */ 00207 } 00208 00209 00210 #endif /* NO_SHA256 */ 00211
Generated on Tue Jul 12 2022 20:44:51 by 1.7.2