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