00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "system.h"
00029 #include "sha256.h"
00030 #include "mp32.h"
00031 #include "endianness.h"
00032 #include "debug.h"
00033
00036
00037 static const uint32 k[64] = {
00038 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00039 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00040 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00041 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00042 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00043 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00044 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00045 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00046 };
00047
00050
00051 static const uint32 hinit[8] = {
00052 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
00053 };
00054
00055
00056 const hashFunction sha256 = { "SHA-256", sizeof(sha256Param), 64, 8 * sizeof(uint32), (hashFunctionReset) sha256Reset, (hashFunctionUpdate) sha256Update, (hashFunctionDigest) sha256Digest };
00057
00058
00059
00060 int sha256Reset(register sha256Param *p)
00061 {
00062 mp32copy(8, p->h, hinit);
00063 mp32zero(64, p->data);
00064 p->length = 0;
00065 p->offset = 0;
00066 return 0;
00067 }
00068
00069
00070 #define R(x,s) ((x) >> (s))
00071 #define S(x,s) ROTR32(x, s)
00072
00073 #define CH(x,y,z) ((x&(y^z))^z)
00074 #define MAJ(x,y,z) (((x|y)&z)|(x&y))
00075 #define SIG0(x) (S(x,2) ^ S(x,13) ^ S(x,22))
00076 #define SIG1(x) (S(x,6) ^ S(x,11) ^ S(x,25))
00077 #define sig0(x) (S(x,7) ^ S(x,18) ^ R(x,3))
00078 #define sig1(x) (S(x,17) ^ S(x,19) ^ R(x,10))
00079
00080 #define ROUND(a,b,c,d,e,f,g,h,w,k) \
00081 temp = h + SIG1(e) + CH(e,f,g) + k + w; \
00082 h = temp + SIG0(a) + MAJ(a,b,c); \
00083 d += temp
00084
00085 #ifndef ASM_SHA256PROCESS
00086
00087 void sha256Process(register sha256Param *p)
00088 {
00089 register uint32 a, b, c, d, e, f, g, h, temp;
00090 register uint32 *w;
00091 register byte t;
00092
00093 #if WORDS_BIGENDIAN
00094 w = p->data + 16;
00095 #else
00096 w = p->data;
00097 t = 16;
00098 while (t--)
00099 {
00100 register uint32 ttemp = swapu32(*w);
00101 *(w++) = ttemp;
00102 }
00103 #endif
00104
00105 t = 48;
00106 while (t--)
00107 {
00108 register uint32 ttemp = sig1(w[-2]) + w[-7] + sig0(w[-15]) + w[-16];
00109 *(w++) = ttemp;
00110 }
00111
00112 w = p->data;
00113
00114 a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
00115 e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
00116
00117 ROUND(a,b,c,d,e,f,g,h,w[ 0],k[ 0]);
00118 ROUND(h,a,b,c,d,e,f,g,w[ 1],k[ 1]);
00119 ROUND(g,h,a,b,c,d,e,f,w[ 2],k[ 2]);
00120 ROUND(f,g,h,a,b,c,d,e,w[ 3],k[ 3]);
00121 ROUND(e,f,g,h,a,b,c,d,w[ 4],k[ 4]);
00122 ROUND(d,e,f,g,h,a,b,c,w[ 5],k[ 5]);
00123 ROUND(c,d,e,f,g,h,a,b,w[ 6],k[ 6]);
00124 ROUND(b,c,d,e,f,g,h,a,w[ 7],k[ 7]);
00125 ROUND(a,b,c,d,e,f,g,h,w[ 8],k[ 8]);
00126 ROUND(h,a,b,c,d,e,f,g,w[ 9],k[ 9]);
00127 ROUND(g,h,a,b,c,d,e,f,w[10],k[10]);
00128 ROUND(f,g,h,a,b,c,d,e,w[11],k[11]);
00129 ROUND(e,f,g,h,a,b,c,d,w[12],k[12]);
00130 ROUND(d,e,f,g,h,a,b,c,w[13],k[13]);
00131 ROUND(c,d,e,f,g,h,a,b,w[14],k[14]);
00132 ROUND(b,c,d,e,f,g,h,a,w[15],k[15]);
00133 ROUND(a,b,c,d,e,f,g,h,w[16],k[16]);
00134 ROUND(h,a,b,c,d,e,f,g,w[17],k[17]);
00135 ROUND(g,h,a,b,c,d,e,f,w[18],k[18]);
00136 ROUND(f,g,h,a,b,c,d,e,w[19],k[19]);
00137 ROUND(e,f,g,h,a,b,c,d,w[20],k[20]);
00138 ROUND(d,e,f,g,h,a,b,c,w[21],k[21]);
00139 ROUND(c,d,e,f,g,h,a,b,w[22],k[22]);
00140 ROUND(b,c,d,e,f,g,h,a,w[23],k[23]);
00141 ROUND(a,b,c,d,e,f,g,h,w[24],k[24]);
00142 ROUND(h,a,b,c,d,e,f,g,w[25],k[25]);
00143 ROUND(g,h,a,b,c,d,e,f,w[26],k[26]);
00144 ROUND(f,g,h,a,b,c,d,e,w[27],k[27]);
00145 ROUND(e,f,g,h,a,b,c,d,w[28],k[28]);
00146 ROUND(d,e,f,g,h,a,b,c,w[29],k[29]);
00147 ROUND(c,d,e,f,g,h,a,b,w[30],k[30]);
00148 ROUND(b,c,d,e,f,g,h,a,w[31],k[31]);
00149 ROUND(a,b,c,d,e,f,g,h,w[32],k[32]);
00150 ROUND(h,a,b,c,d,e,f,g,w[33],k[33]);
00151 ROUND(g,h,a,b,c,d,e,f,w[34],k[34]);
00152 ROUND(f,g,h,a,b,c,d,e,w[35],k[35]);
00153 ROUND(e,f,g,h,a,b,c,d,w[36],k[36]);
00154 ROUND(d,e,f,g,h,a,b,c,w[37],k[37]);
00155 ROUND(c,d,e,f,g,h,a,b,w[38],k[38]);
00156 ROUND(b,c,d,e,f,g,h,a,w[39],k[39]);
00157 ROUND(a,b,c,d,e,f,g,h,w[40],k[40]);
00158 ROUND(h,a,b,c,d,e,f,g,w[41],k[41]);
00159 ROUND(g,h,a,b,c,d,e,f,w[42],k[42]);
00160 ROUND(f,g,h,a,b,c,d,e,w[43],k[43]);
00161 ROUND(e,f,g,h,a,b,c,d,w[44],k[44]);
00162 ROUND(d,e,f,g,h,a,b,c,w[45],k[45]);
00163 ROUND(c,d,e,f,g,h,a,b,w[46],k[46]);
00164 ROUND(b,c,d,e,f,g,h,a,w[47],k[47]);
00165 ROUND(a,b,c,d,e,f,g,h,w[48],k[48]);
00166 ROUND(h,a,b,c,d,e,f,g,w[49],k[49]);
00167 ROUND(g,h,a,b,c,d,e,f,w[50],k[50]);
00168 ROUND(f,g,h,a,b,c,d,e,w[51],k[51]);
00169 ROUND(e,f,g,h,a,b,c,d,w[52],k[52]);
00170 ROUND(d,e,f,g,h,a,b,c,w[53],k[53]);
00171 ROUND(c,d,e,f,g,h,a,b,w[54],k[54]);
00172 ROUND(b,c,d,e,f,g,h,a,w[55],k[55]);
00173 ROUND(a,b,c,d,e,f,g,h,w[56],k[56]);
00174 ROUND(h,a,b,c,d,e,f,g,w[57],k[57]);
00175 ROUND(g,h,a,b,c,d,e,f,w[58],k[58]);
00176 ROUND(f,g,h,a,b,c,d,e,w[59],k[59]);
00177 ROUND(e,f,g,h,a,b,c,d,w[60],k[60]);
00178 ROUND(d,e,f,g,h,a,b,c,w[61],k[61]);
00179 ROUND(c,d,e,f,g,h,a,b,w[62],k[62]);
00180 ROUND(b,c,d,e,f,g,h,a,w[63],k[63]);
00181
00182 p->h[0] += a;
00183 p->h[1] += b;
00184 p->h[2] += c;
00185 p->h[3] += d;
00186 p->h[4] += e;
00187 p->h[5] += f;
00188 p->h[6] += g;
00189 p->h[7] += h;
00190 }
00191
00192 #endif
00193
00194
00195 int sha256Update(register sha256Param *p, const byte *data, int size)
00196 {
00197 register int proclength;
00198
00199 p->length += size;
00200 while (size > 0)
00201 {
00202 proclength = ((p->offset + size) > 64) ? (64 - p->offset) : size;
00203 memmove(((byte *) p->data) + p->offset, data, proclength);
00204 size -= proclength;
00205 data += proclength;
00206 p->offset += proclength;
00207
00208 if (p->offset == 64)
00209 {
00210 sha256Process(p);
00211 p->offset = 0;
00212 }
00213 }
00214 return 0;
00215 }
00216
00217
00220
00221 static void sha256Finish(register sha256Param *p)
00222
00223
00224 {
00225 register byte *ptr = ((byte *) p->data) + p->offset++;
00226
00227 *(ptr++) = 0x80;
00228
00229 if (p->offset > 56)
00230 {
00231 while (p->offset++ < 64)
00232 *(ptr++) = 0;
00233
00234 sha256Process(p);
00235 p->offset = 0;
00236 }
00237
00238 ptr = ((byte *) p->data) + p->offset;
00239 while (p->offset++ < 56)
00240 *(ptr++) = 0;
00241
00242 #if WORDS_BIGENDIAN
00243 p->data[14] = ((uint32)(p->length >> 29));
00244 p->data[15] = ((uint32)((p->length << 3) & 0xffffffff));
00245 #else
00246 p->data[14] = swapu32((uint32)(p->length >> 29));
00247 p->data[15] = swapu32((uint32)((p->length << 3) & 0xffffffff));
00248 #endif
00249
00250 sha256Process(p);
00251 p->offset = 0;
00252 }
00253
00254
00255
00256 int sha256Digest(register sha256Param *p, uint32 *data)
00257 {
00258 sha256Finish(p);
00259 mp32copy(8, data, p->h);
00260 (void) sha256Reset(p);
00261 return 0;
00262 }
00263