]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - lib/sha256.c
JFFS2: Speed up and fix comparison functions
[karo-tx-uboot.git] / lib / sha256.c
1 /*
2  * FIPS-180-2 compliant SHA-256 implementation
3  *
4  * Copyright (C) 2001-2003  Christophe Devine
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #ifndef USE_HOSTCC
10 #include <common.h>
11 #include <linux/string.h>
12 #else
13 #include <string.h>
14 #endif /* USE_HOSTCC */
15 #include <watchdog.h>
16 #include <u-boot/sha256.h>
17
18 /*
19  * 32-bit integer manipulation macros (big endian)
20  */
21 #ifndef GET_UINT32_BE
22 #define GET_UINT32_BE(n,b,i) {                          \
23         (n) = ( (unsigned long) (b)[(i)    ] << 24 )    \
24             | ( (unsigned long) (b)[(i) + 1] << 16 )    \
25             | ( (unsigned long) (b)[(i) + 2] <<  8 )    \
26             | ( (unsigned long) (b)[(i) + 3]       );   \
27 }
28 #endif
29 #ifndef PUT_UINT32_BE
30 #define PUT_UINT32_BE(n,b,i) {                          \
31         (b)[(i)    ] = (unsigned char) ( (n) >> 24 );   \
32         (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );   \
33         (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );   \
34         (b)[(i) + 3] = (unsigned char) ( (n)       );   \
35 }
36 #endif
37
38 void sha256_starts(sha256_context * ctx)
39 {
40         ctx->total[0] = 0;
41         ctx->total[1] = 0;
42
43         ctx->state[0] = 0x6A09E667;
44         ctx->state[1] = 0xBB67AE85;
45         ctx->state[2] = 0x3C6EF372;
46         ctx->state[3] = 0xA54FF53A;
47         ctx->state[4] = 0x510E527F;
48         ctx->state[5] = 0x9B05688C;
49         ctx->state[6] = 0x1F83D9AB;
50         ctx->state[7] = 0x5BE0CD19;
51 }
52
53 static void sha256_process(sha256_context *ctx, const uint8_t data[64])
54 {
55         uint32_t temp1, temp2;
56         uint32_t W[64];
57         uint32_t A, B, C, D, E, F, G, H;
58
59         GET_UINT32_BE(W[0], data, 0);
60         GET_UINT32_BE(W[1], data, 4);
61         GET_UINT32_BE(W[2], data, 8);
62         GET_UINT32_BE(W[3], data, 12);
63         GET_UINT32_BE(W[4], data, 16);
64         GET_UINT32_BE(W[5], data, 20);
65         GET_UINT32_BE(W[6], data, 24);
66         GET_UINT32_BE(W[7], data, 28);
67         GET_UINT32_BE(W[8], data, 32);
68         GET_UINT32_BE(W[9], data, 36);
69         GET_UINT32_BE(W[10], data, 40);
70         GET_UINT32_BE(W[11], data, 44);
71         GET_UINT32_BE(W[12], data, 48);
72         GET_UINT32_BE(W[13], data, 52);
73         GET_UINT32_BE(W[14], data, 56);
74         GET_UINT32_BE(W[15], data, 60);
75
76 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
77 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
78
79 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
80 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
81
82 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
83 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
84
85 #define F0(x,y,z) ((x & y) | (z & (x | y)))
86 #define F1(x,y,z) (z ^ (x & (y ^ z)))
87
88 #define R(t)                                    \
89 (                                               \
90         W[t] = S1(W[t - 2]) + W[t - 7] +        \
91                 S0(W[t - 15]) + W[t - 16]       \
92 )
93
94 #define P(a,b,c,d,e,f,g,h,x,K) {                \
95         temp1 = h + S3(e) + F1(e,f,g) + K + x;  \
96         temp2 = S2(a) + F0(a,b,c);              \
97         d += temp1; h = temp1 + temp2;          \
98 }
99
100         A = ctx->state[0];
101         B = ctx->state[1];
102         C = ctx->state[2];
103         D = ctx->state[3];
104         E = ctx->state[4];
105         F = ctx->state[5];
106         G = ctx->state[6];
107         H = ctx->state[7];
108
109         P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
110         P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
111         P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
112         P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
113         P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
114         P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
115         P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
116         P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
117         P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
118         P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
119         P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
120         P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
121         P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
122         P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
123         P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
124         P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
125         P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
126         P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
127         P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
128         P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
129         P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
130         P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
131         P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
132         P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
133         P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
134         P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
135         P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
136         P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
137         P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
138         P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
139         P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
140         P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
141         P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
142         P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
143         P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
144         P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
145         P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
146         P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
147         P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
148         P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
149         P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
150         P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
151         P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
152         P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
153         P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
154         P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
155         P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
156         P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
157         P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
158         P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
159         P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
160         P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
161         P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
162         P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
163         P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
164         P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
165         P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
166         P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
167         P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
168         P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
169         P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
170         P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
171         P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
172         P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
173
174         ctx->state[0] += A;
175         ctx->state[1] += B;
176         ctx->state[2] += C;
177         ctx->state[3] += D;
178         ctx->state[4] += E;
179         ctx->state[5] += F;
180         ctx->state[6] += G;
181         ctx->state[7] += H;
182 }
183
184 void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
185 {
186         uint32_t left, fill;
187
188         if (!length)
189                 return;
190
191         left = ctx->total[0] & 0x3F;
192         fill = 64 - left;
193
194         ctx->total[0] += length;
195         ctx->total[0] &= 0xFFFFFFFF;
196
197         if (ctx->total[0] < length)
198                 ctx->total[1]++;
199
200         if (left && length >= fill) {
201                 memcpy((void *) (ctx->buffer + left), (void *) input, fill);
202                 sha256_process(ctx, ctx->buffer);
203                 length -= fill;
204                 input += fill;
205                 left = 0;
206         }
207
208         while (length >= 64) {
209                 sha256_process(ctx, input);
210                 length -= 64;
211                 input += 64;
212         }
213
214         if (length)
215                 memcpy((void *) (ctx->buffer + left), (void *) input, length);
216 }
217
218 static uint8_t 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
225 void sha256_finish(sha256_context * ctx, uint8_t digest[32])
226 {
227         uint32_t last, padn;
228         uint32_t high, low;
229         uint8_t 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         sha256_update(ctx, sha256_padding, padn);
242         sha256_update(ctx, msglen, 8);
243
244         PUT_UINT32_BE(ctx->state[0], digest, 0);
245         PUT_UINT32_BE(ctx->state[1], digest, 4);
246         PUT_UINT32_BE(ctx->state[2], digest, 8);
247         PUT_UINT32_BE(ctx->state[3], digest, 12);
248         PUT_UINT32_BE(ctx->state[4], digest, 16);
249         PUT_UINT32_BE(ctx->state[5], digest, 20);
250         PUT_UINT32_BE(ctx->state[6], digest, 24);
251         PUT_UINT32_BE(ctx->state[7], digest, 28);
252 }
253
254 /*
255  * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
256  * bytes of input processed.
257  */
258 void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
259                 unsigned char *output, unsigned int chunk_sz)
260 {
261         sha256_context ctx;
262 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
263         const unsigned char *end;
264         unsigned char *curr;
265         int chunk;
266 #endif
267
268         sha256_starts(&ctx);
269
270 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
271         curr = (unsigned char *)input;
272         end = input + ilen;
273         while (curr < end) {
274                 chunk = end - curr;
275                 if (chunk > chunk_sz)
276                         chunk = chunk_sz;
277                 sha256_update(&ctx, curr, chunk);
278                 curr += chunk;
279                 WATCHDOG_RESET();
280         }
281 #else
282         sha256_update(&ctx, input, ilen);
283 #endif
284
285         sha256_finish(&ctx, output);
286 }