1 /*
2  *  Original code is derived from the author:
3  *  Allan Saddi
4  */
5 
6 #include <inttypes.h>
7 #include <string.h>
8 #include "sha256.h"
9 
10 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
11 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
12 
13 #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
14 #define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
15 #define SIGMA0(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22))
16 #define SIGMA1(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25))
17 #define sigma0(x) (ROTR((x), 7) ^ ROTR((x), 18) ^ ((x) >> 3))
18 #define sigma1(x) (ROTR((x), 17) ^ ROTR((x), 19) ^ ((x) >> 10))
19 
20 #define DO_ROUND() { \
21   t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
22   t2 = SIGMA0(a) + Maj(a, b, c); \
23   h = g; \
24   g = f; \
25   f = e; \
26   e = d + t1; \
27   d = c; \
28   c = b; \
29   b = a; \
30   a = t1 + t2; \
31 }
32 
33 static const uint32_t K[64] = {
34   0x428a2f98L, 0x71374491L, 0xb5c0fbcfL, 0xe9b5dba5L,
35   0x3956c25bL, 0x59f111f1L, 0x923f82a4L, 0xab1c5ed5L,
36   0xd807aa98L, 0x12835b01L, 0x243185beL, 0x550c7dc3L,
37   0x72be5d74L, 0x80deb1feL, 0x9bdc06a7L, 0xc19bf174L,
38   0xe49b69c1L, 0xefbe4786L, 0x0fc19dc6L, 0x240ca1ccL,
39   0x2de92c6fL, 0x4a7484aaL, 0x5cb0a9dcL, 0x76f988daL,
40   0x983e5152L, 0xa831c66dL, 0xb00327c8L, 0xbf597fc7L,
41   0xc6e00bf3L, 0xd5a79147L, 0x06ca6351L, 0x14292967L,
42   0x27b70a85L, 0x2e1b2138L, 0x4d2c6dfcL, 0x53380d13L,
43   0x650a7354L, 0x766a0abbL, 0x81c2c92eL, 0x92722c85L,
44   0xa2bfe8a1L, 0xa81a664bL, 0xc24b8b70L, 0xc76c51a3L,
45   0xd192e819L, 0xd6990624L, 0xf40e3585L, 0x106aa070L,
46   0x19a4c116L, 0x1e376c08L, 0x2748774cL, 0x34b0bcb5L,
47   0x391c0cb3L, 0x4ed8aa4aL, 0x5b9cca4fL, 0x682e6ff3L,
48   0x748f82eeL, 0x78a5636fL, 0x84c87814L, 0x8cc70208L,
49   0x90befffaL, 0xa4506cebL, 0xbef9a3f7L, 0xc67178f2L
50 };
51 
52 #ifndef RUNTIME_ENDIAN
53 
54 #ifdef WORDS_BIGENDIAN
55 
56 #define BYTESWAP(x) (x)
57 #define BYTESWAP64(x) (x)
58 
59 #else /* WORDS_BIGENDIAN */
60 
61 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
62 		     (ROTL((x), 8) & 0x00ff00ffL))
63 #define BYTESWAP64(x) _byteswap64(x)
64 
_byteswap64(uint64_t x)65 static inline uint64_t _byteswap64(uint64_t x)
66 {
67   uint32_t a = x >> 32;
68   uint32_t b = (uint32_t) x;
69   return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
70 }
71 
72 #endif /* WORDS_BIGENDIAN */
73 
74 #else /* !RUNTIME_ENDIAN */
75 
76 static int littleEndian;
77 
78 #define BYTESWAP(x) _byteswap(x)
79 #define BYTESWAP64(x) _byteswap64(x)
80 
81 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
82 		      (ROTL((x), 8) & 0x00ff00ffL))
83 #define _BYTESWAP64(x) __byteswap64(x)
84 
__byteswap64(uint64_t x)85 static inline uint64_t __byteswap64(uint64_t x)
86 {
87   uint32_t a = x >> 32;
88   uint32_t b = (uint32_t) x;
89   return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
90 }
91 
_byteswap(uint32_t x)92 static inline uint32_t _byteswap(uint32_t x)
93 {
94   if (!littleEndian)
95     return x;
96   else
97     return _BYTESWAP(x);
98 }
99 
_byteswap64(uint64_t x)100 static inline uint64_t _byteswap64(uint64_t x)
101 {
102   if (!littleEndian)
103     return x;
104   else
105     return _BYTESWAP64(x);
106 }
107 
setEndian(void)108 static inline void setEndian(void)
109 {
110   union {
111     uint32_t w;
112     uint8_t b[4];
113   } endian;
114 
115   endian.w = 1L;
116   littleEndian = endian.b[0] != 0;
117 }
118 
119 #endif /* !RUNTIME_ENDIAN */
120 
121 static const uint8_t padding[64] = {
122   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
130 };
131 
132 void
SHA256Init(SHA256Context * sc)133 SHA256Init (SHA256Context *sc)
134 {
135 #ifdef RUNTIME_ENDIAN
136   setEndian ();
137 #endif /* RUNTIME_ENDIAN */
138 
139   sc->totalLength = 0LL;
140   sc->hash[0] = 0x6a09e667L;
141   sc->hash[1] = 0xbb67ae85L;
142   sc->hash[2] = 0x3c6ef372L;
143   sc->hash[3] = 0xa54ff53aL;
144   sc->hash[4] = 0x510e527fL;
145   sc->hash[5] = 0x9b05688cL;
146   sc->hash[6] = 0x1f83d9abL;
147   sc->hash[7] = 0x5be0cd19L;
148   sc->bufferLength = 0L;
149 }
150 
151 static void
burnStack(int size)152 burnStack (int size)
153 {
154   char buf[128];
155 
156   memset (buf, 0, sizeof (buf));
157   size -= sizeof (buf);
158   if (size > 0)
159     burnStack (size);
160 }
161 
162 static void
SHA256Guts(SHA256Context * sc,const uint32_t * cbuf)163 SHA256Guts (SHA256Context *sc, const uint32_t *cbuf)
164 {
165   uint32_t buf[64];
166   uint32_t *W, *W2, *W7, *W15, *W16;
167   uint32_t a, b, c, d, e, f, g, h;
168   uint32_t t1, t2;
169   const uint32_t *Kp;
170   int i;
171 
172   W = buf;
173 
174   for (i = 15; i >= 0; i--) {
175     *(W++) = BYTESWAP(*cbuf);
176     cbuf++;
177   }
178 
179   W16 = &buf[0];
180   W15 = &buf[1];
181   W7 = &buf[9];
182   W2 = &buf[14];
183 
184   for (i = 47; i >= 0; i--) {
185     *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
186     W2++;
187     W15++;
188   }
189 
190   a = sc->hash[0];
191   b = sc->hash[1];
192   c = sc->hash[2];
193   d = sc->hash[3];
194   e = sc->hash[4];
195   f = sc->hash[5];
196   g = sc->hash[6];
197   h = sc->hash[7];
198 
199   Kp = K;
200   W = buf;
201 
202 #ifndef SHA256_UNROLL
203 #define SHA256_UNROLL 1
204 #endif /* !SHA256_UNROLL */
205 
206 #if SHA256_UNROLL == 1
207   for (i = 63; i >= 0; i--)
208     DO_ROUND();
209 #elif SHA256_UNROLL == 2
210   for (i = 31; i >= 0; i--) {
211     DO_ROUND(); DO_ROUND();
212   }
213 #elif SHA256_UNROLL == 4
214   for (i = 15; i >= 0; i--) {
215     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
216   }
217 #elif SHA256_UNROLL == 8
218   for (i = 7; i >= 0; i--) {
219     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
220     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
221   }
222 #elif SHA256_UNROLL == 16
223   for (i = 3; i >= 0; i--) {
224     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
225     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
226     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
227     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
228   }
229 #elif SHA256_UNROLL == 32
230   for (i = 1; i >= 0; i--) {
231     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
232     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
233     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
234     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
235     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
236     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
237     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
238     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
239   }
240 #elif SHA256_UNROLL == 64
241   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
242   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
243   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
244   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
245   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
246   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
247   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
248   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
249   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
250   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
251   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
252   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
253   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
254   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
255   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
256   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
257 #else
258 #error "SHA256_UNROLL must be 1, 2, 4, 8, 16, 32, or 64!"
259 #endif
260 
261   sc->hash[0] += a;
262   sc->hash[1] += b;
263   sc->hash[2] += c;
264   sc->hash[3] += d;
265   sc->hash[4] += e;
266   sc->hash[5] += f;
267   sc->hash[6] += g;
268   sc->hash[7] += h;
269 }
270 
271 void
SHA256Update(SHA256Context * sc,const void * data,uint32_t len)272 SHA256Update (SHA256Context *sc, const void *data, uint32_t len)
273 {
274   uint32_t bufferBytesLeft;
275   uint32_t bytesToCopy;
276   int needBurn = 0;
277 
278   if (sc->bufferLength) {
279     bufferBytesLeft = 64L - sc->bufferLength;
280 
281     bytesToCopy = bufferBytesLeft;
282     if (bytesToCopy > len)
283       bytesToCopy = len;
284 
285     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
286 
287     sc->totalLength += bytesToCopy * 8L;
288 
289     sc->bufferLength += bytesToCopy;
290     data += sizeof(uint8_t *) * bytesToCopy;
291     len -= bytesToCopy;
292 
293     if (sc->bufferLength == 64L) {
294       SHA256Guts (sc, sc->buffer.words);
295       needBurn = 1;
296       sc->bufferLength = 0L;
297     }
298   }
299 
300   while (len > 63L) {
301     sc->totalLength += 512L;
302 
303     SHA256Guts (sc, data);
304     needBurn = 1;
305 
306     data += sizeof(uint8_t *) * 64L;
307     len -= 64L;
308   }
309 
310   if (len) {
311     memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
312 
313     sc->totalLength += len * 8L;
314 
315     sc->bufferLength += len;
316   }
317 
318   if (needBurn)
319     burnStack (sizeof (uint32_t[74]) + sizeof (uint32_t *[6]) + sizeof (int));
320 }
321 
322 void
SHA256Final(SHA256Context * sc,uint8_t hash[SHA256_HASH_SIZE])323 SHA256Final (SHA256Context *sc, uint8_t hash[SHA256_HASH_SIZE])
324 {
325   uint32_t bytesToPad;
326   uint64_t lengthPad;
327   int i;
328 
329   bytesToPad = 120L - sc->bufferLength;
330   if (bytesToPad > 64L)
331     bytesToPad -= 64L;
332 
333   lengthPad = BYTESWAP64(sc->totalLength);
334 
335   SHA256Update (sc, padding, bytesToPad);
336   SHA256Update (sc, &lengthPad, 8L);
337 
338   if (hash) {
339     for (i = 0; i < SHA256_HASH_WORDS; i++) {
340       *((uint32_t *) hash) = BYTESWAP(sc->hash[i]);
341       hash += 4;
342     }
343   }
344 }
345