1 #include "core_sha256.h"
2
3 #define MINI_SHA256_SMALLER
4 #define SHA256_KEY_IOPAD_SIZE (64)
5 #define SHA256_DIGEST_SIZE (32)
6
7 /*
8 * 32-bit integer manipulation macros (big endian)
9 */
10 #ifndef GET_UINT32_BE
11 #define GET_UINT32_BE(n,b,i) \
12 do { \
13 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
14 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
15 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
16 | ( (uint32_t) (b)[(i) + 3] ); \
17 } while( 0 )
18 #endif
19
20 #ifndef PUT_UINT32_BE
21 #define PUT_UINT32_BE(n,b,i) \
22 do { \
23 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
24 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
25 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
26 (b)[(i) + 3] = (unsigned char) ( (n) ); \
27 } while( 0 )
28 #endif
29
30
utils_sha256_zeroize(void * v,uint32_t n)31 static void utils_sha256_zeroize(void *v, uint32_t n)
32 {
33 volatile unsigned char *p = v;
34 while (n--) {
35 *p++ = 0;
36 }
37 }
38
core_sha256_init(core_sha256_context_t * ctx)39 void core_sha256_init(core_sha256_context_t *ctx)
40 {
41 memset(ctx, 0, sizeof(core_sha256_context_t));
42 }
43
core_sha256_free(core_sha256_context_t * ctx)44 void core_sha256_free(core_sha256_context_t *ctx)
45 {
46 if (NULL == ctx) {
47 return;
48 }
49
50 utils_sha256_zeroize(ctx, sizeof(core_sha256_context_t));
51 }
52
core_sha256_starts(core_sha256_context_t * ctx)53 void core_sha256_starts(core_sha256_context_t *ctx)
54 {
55 uint8_t is224 = 0;
56 ctx->total[0] = 0;
57 ctx->total[1] = 0;
58
59 if (is224 == 0) {
60 /* SHA-256 */
61 ctx->state[0] = 0x6A09E667;
62 ctx->state[1] = 0xBB67AE85;
63 ctx->state[2] = 0x3C6EF372;
64 ctx->state[3] = 0xA54FF53A;
65 ctx->state[4] = 0x510E527F;
66 ctx->state[5] = 0x9B05688C;
67 ctx->state[6] = 0x1F83D9AB;
68 ctx->state[7] = 0x5BE0CD19;
69 }
70
71 ctx->is224 = is224;
72 }
73
74 static const uint32_t K[] = {
75 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
76 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
77 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
78 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
79 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
80 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
81 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
82 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
83 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
84 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
85 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
86 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
87 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
88 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
89 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
90 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
91 };
92
93 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
94 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
95
96 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
97 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
98
99 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
100 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
101
102 #define F0(x,y,z) ((x & y) | (z & (x | y)))
103 #define F1(x,y,z) (z ^ (x & (y ^ z)))
104
105 #define R(t) \
106 ( \
107 W[t] = S1(W[t - 2]) + W[t - 7] + \
108 S0(W[t - 15]) + W[t - 16] \
109 )
110
111 #define P(a,b,c,d,e,f,g,h,x,K) \
112 { \
113 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
114 temp2 = S2(a) + F0(a,b,c); \
115 d += temp1; h = temp1 + temp2; \
116 }
117
core_sha256_process(core_sha256_context_t * ctx,const unsigned char data[64])118 void core_sha256_process(core_sha256_context_t *ctx, const unsigned char data[64])
119 {
120 uint32_t temp1, temp2, W[64];
121 uint32_t A[8];
122 unsigned int i;
123
124 for (i = 0; i < 8; i++) {
125 A[i] = ctx->state[i];
126 }
127
128 #if defined(MINI_SHA256_SMALLER)
129 for (i = 0; i < 64; i++) {
130 if (i < 16) {
131 GET_UINT32_BE(W[i], data, 4 * i);
132 } else {
133 R(i);
134 }
135
136 P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i]);
137
138 temp1 = A[7];
139 A[7] = A[6];
140 A[6] = A[5];
141 A[5] = A[4];
142 A[4] = A[3];
143 A[3] = A[2];
144 A[2] = A[1];
145 A[1] = A[0];
146 A[0] = temp1;
147 }
148 #else /* MINI_SHA256_SMALLER */
149 for (i = 0; i < 16; i++) {
150 GET_UINT32_BE(W[i], data, 4 * i);
151 }
152
153 for (i = 0; i < 16; i += 8) {
154 P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0]);
155 P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1]);
156 P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2]);
157 P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3]);
158 P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4]);
159 P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5]);
160 P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6]);
161 P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7]);
162 }
163
164 for (i = 16; i < 64; i += 8) {
165 P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0]);
166 P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1]);
167 P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2]);
168 P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3]);
169 P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4]);
170 P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5]);
171 P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6]);
172 P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7]);
173 }
174 #endif /* MINI_SHA256_SMALLER */
175
176 for (i = 0; i < 8; i++) {
177 ctx->state[i] += A[i];
178 }
179 }
core_sha256_update(core_sha256_context_t * ctx,const unsigned char * input,uint32_t ilen)180 void core_sha256_update(core_sha256_context_t *ctx, const unsigned char *input, uint32_t ilen)
181 {
182 size_t fill;
183 uint32_t left;
184
185 if (ilen == 0) {
186 return;
187 }
188
189 left = ctx->total[0] & 0x3F;
190 fill = 64 - left;
191
192 ctx->total[0] += (uint32_t) ilen;
193 ctx->total[0] &= 0xFFFFFFFF;
194
195 if (ctx->total[0] < (uint32_t) ilen) {
196 ctx->total[1]++;
197 }
198
199 if (left && ilen >= fill) {
200 memcpy((void *)(ctx->buffer + left), input, fill);
201 core_sha256_process(ctx, ctx->buffer);
202 input += fill;
203 ilen -= fill;
204 left = 0;
205 }
206
207 while (ilen >= 64) {
208 core_sha256_process(ctx, input);
209 input += 64;
210 ilen -= 64;
211 }
212
213 if (ilen > 0) {
214 memcpy((void *)(ctx->buffer + left), input, ilen);
215 }
216 }
217
218 static const unsigned char sha256_padding[64] = {
219 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
223 };
224
core_sha256_finish(core_sha256_context_t * ctx,uint8_t output[32])225 void core_sha256_finish(core_sha256_context_t *ctx, uint8_t output[32])
226 {
227 uint32_t last, padn;
228 uint32_t high, low;
229 unsigned char msglen[8];
230
231 high = (ctx->total[0] >> 29)
232 | (ctx->total[1] << 3);
233 low = (ctx->total[0] << 3);
234
235 PUT_UINT32_BE(high, msglen, 0);
236 PUT_UINT32_BE(low, msglen, 4);
237
238 last = ctx->total[0] & 0x3F;
239 padn = (last < 56) ? (56 - last) : (120 - last);
240
241 core_sha256_update(ctx, sha256_padding, padn);
242 core_sha256_update(ctx, msglen, 8);
243
244 PUT_UINT32_BE(ctx->state[0], output, 0);
245 PUT_UINT32_BE(ctx->state[1], output, 4);
246 PUT_UINT32_BE(ctx->state[2], output, 8);
247 PUT_UINT32_BE(ctx->state[3], output, 12);
248 PUT_UINT32_BE(ctx->state[4], output, 16);
249 PUT_UINT32_BE(ctx->state[5], output, 20);
250 PUT_UINT32_BE(ctx->state[6], output, 24);
251
252 if (ctx->is224 == 0) {
253 PUT_UINT32_BE(ctx->state[7], output, 28);
254 }
255 }
256
core_sha256(const uint8_t * input,uint32_t ilen,uint8_t output[32])257 void core_sha256(const uint8_t *input, uint32_t ilen, uint8_t output[32])
258 {
259 core_sha256_context_t ctx;
260
261 core_sha256_init(&ctx);
262 core_sha256_starts(&ctx);
263 core_sha256_update(&ctx, input, ilen);
264 core_sha256_finish(&ctx, output);
265 core_sha256_free(&ctx);
266 }
267
core_hmac_sha256(const uint8_t * msg,uint32_t msg_len,const uint8_t * key,uint32_t key_len,uint8_t output[32])268 void core_hmac_sha256(const uint8_t *msg, uint32_t msg_len, const uint8_t *key, uint32_t key_len, uint8_t output[32])
269 {
270 core_sha256_context_t context;
271 uint8_t k_ipad[SHA256_KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
272 uint8_t k_opad[SHA256_KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
273 int32_t i;
274
275 if ((NULL == msg) || (NULL == key) || (NULL == output)) {
276 return;
277 }
278
279 if (key_len > SHA256_KEY_IOPAD_SIZE) {
280 return;
281 }
282
283 /* start out by storing key in pads */
284 memset(k_ipad, 0, sizeof(k_ipad));
285 memset(k_opad, 0, sizeof(k_opad));
286 memcpy(k_ipad, key, key_len);
287 memcpy(k_opad, key, key_len);
288
289 /* XOR key with ipad and opad values */
290 for (i = 0; i < SHA256_KEY_IOPAD_SIZE; i++) {
291 k_ipad[i] ^= 0x36;
292 k_opad[i] ^= 0x5c;
293 }
294
295 /* perform inner SHA */
296 core_sha256_init(&context); /* init context for 1st pass */
297 core_sha256_starts(&context); /* setup context for 1st pass */
298 core_sha256_update(&context, k_ipad, SHA256_KEY_IOPAD_SIZE); /* start with inner pad */
299 core_sha256_update(&context, msg, msg_len); /* then text of datagram */
300 core_sha256_finish(&context, output); /* finish up 1st pass */
301
302 /* perform outer SHA */
303 core_sha256_init(&context); /* init context for 2nd pass */
304 core_sha256_starts(&context); /* setup context for 2nd pass */
305 core_sha256_update(&context, k_opad, SHA256_KEY_IOPAD_SIZE); /* start with outer pad */
306 core_sha256_update(&context, output, SHA256_DIGEST_SIZE); /* then results of 1st hash */
307 core_sha256_finish(&context, output); /* finish up 2nd pass */
308 }
309
310