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