blob: e157255288d8f8fdd1246e4116ba3e6b7e215782 [file] [log] [blame]
Bram Moolenaar40e6a712010-05-16 22:32:54 +02001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * FIPS-180-2 compliant SHA-256 implementation
4 * GPL by Christophe Devine.
5 * Modified for md5deep, in public domain.
6 * Modified For Vim, GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
7 *
8 * Vim specific notes:
9 * Functions exported by this file:
10 * 1. sha256_key() hashes the password to 64 bytes char string.
11 * 2. sha2_seed() generates a random header.
12 * sha256_self_test() is implicitly called once.
13 */
14
15#include "vim.h"
16
17#ifdef FEAT_CRYPT
18
19typedef unsigned long uint32_t;
20
21typedef struct {
22 uint32_t total[2];
23 uint32_t state[8];
24 char_u buffer[64];
25} context_sha256_T;
26
27static void sha256_starts __ARGS((context_sha256_T *ctx));
28static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
29static void sha256_update __ARGS((context_sha256_T *ctx, char_u *input, uint32_t length));
30static void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32]));
Bram Moolenaar823a1652010-05-16 23:02:33 +020031static char_u *sha256_bytes __ARGS((char_u *buf, int buflen));
Bram Moolenaar40e6a712010-05-16 22:32:54 +020032static unsigned int get_some_time __ARGS((void));
33
34
35#define GET_UINT32(n, b, i) \
36{ \
37 (n) = ( (uint32_t)(b)[(i) ] << 24) \
38 | ( (uint32_t)(b)[(i) + 1] << 16) \
39 | ( (uint32_t)(b)[(i) + 2] << 8) \
40 | ( (uint32_t)(b)[(i) + 3] ); \
41}
42
43#define PUT_UINT32(n,b,i) \
44{ \
45 (b)[(i) ] = (char_u)((n) >> 24); \
46 (b)[(i) + 1] = (char_u)((n) >> 16); \
47 (b)[(i) + 2] = (char_u)((n) >> 8); \
48 (b)[(i) + 3] = (char_u)((n) ); \
49}
50
51 static void
52sha256_starts(ctx)
53 context_sha256_T *ctx;
54{
55 ctx->total[0] = 0;
56 ctx->total[1] = 0;
57
58 ctx->state[0] = 0x6A09E667;
59 ctx->state[1] = 0xBB67AE85;
60 ctx->state[2] = 0x3C6EF372;
61 ctx->state[3] = 0xA54FF53A;
62 ctx->state[4] = 0x510E527F;
63 ctx->state[5] = 0x9B05688C;
64 ctx->state[6] = 0x1F83D9AB;
65 ctx->state[7] = 0x5BE0CD19;
66}
67
68 static void
69sha256_process(ctx, data)
70 context_sha256_T *ctx;
71 char_u data[64];
72{
73 uint32_t temp1, temp2, W[64];
74 uint32_t A, B, C, D, E, F, G, H;
75
76 GET_UINT32(W[0], data, 0);
77 GET_UINT32(W[1], data, 4);
78 GET_UINT32(W[2], data, 8);
79 GET_UINT32(W[3], data, 12);
80 GET_UINT32(W[4], data, 16);
81 GET_UINT32(W[5], data, 20);
82 GET_UINT32(W[6], data, 24);
83 GET_UINT32(W[7], data, 28);
84 GET_UINT32(W[8], data, 32);
85 GET_UINT32(W[9], data, 36);
86 GET_UINT32(W[10], data, 40);
87 GET_UINT32(W[11], data, 44);
88 GET_UINT32(W[12], data, 48);
89 GET_UINT32(W[13], data, 52);
90 GET_UINT32(W[14], data, 56);
91 GET_UINT32(W[15], data, 60);
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
118 A = ctx->state[0];
119 B = ctx->state[1];
120 C = ctx->state[2];
121 D = ctx->state[3];
122 E = ctx->state[4];
123 F = ctx->state[5];
124 G = ctx->state[6];
125 H = ctx->state[7];
126
127 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
128 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
129 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
130 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
131 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
132 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
133 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
134 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
135 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
136 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
137 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
138 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
139 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
140 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
141 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
142 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
143 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
144 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
145 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
146 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
147 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
148 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
149 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
150 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
151 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
152 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
153 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
154 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
155 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
156 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
157 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
158 P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
159 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
160 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
161 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
162 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
163 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
164 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
165 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
166 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
167 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
168 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
169 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
170 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
171 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
172 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
173 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
174 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
175 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
176 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
177 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
178 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
179 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
180 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
181 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
182 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
183 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
184 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
185 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
186 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
187 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
188 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
189 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
190 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
191
192 ctx->state[0] += A;
193 ctx->state[1] += B;
194 ctx->state[2] += C;
195 ctx->state[3] += D;
196 ctx->state[4] += E;
197 ctx->state[5] += F;
198 ctx->state[6] += G;
199 ctx->state[7] += H;
200}
201
202 static void
203sha256_update(ctx, input, length)
204 context_sha256_T *ctx;
205 char_u *input;
206 uint32_t length;
207{
208 uint32_t left, fill;
209
210 if (length == 0)
211 return;
212
213 left = ctx->total[0] & 0x3F;
214 fill = 64 - left;
215
216 ctx->total[0] += length;
217 ctx->total[0] &= 0xFFFFFFFF;
218
219 if (ctx->total[0] < length)
220 ctx->total[1]++;
221
222 if (left && length >= fill)
223 {
224 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
225 sha256_process(ctx, ctx->buffer);
226 length -= fill;
227 input += fill;
228 left = 0;
229 }
230
231 while (length >= 64)
232 {
233 sha256_process(ctx, input);
234 length -= 64;
235 input += 64;
236 }
237
238 if (length)
239 memcpy((void *)(ctx->buffer + left), (void *)input, length);
240}
241
242static char_u sha256_padding[64] = {
243 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
247};
248
249 static void
250sha256_finish(ctx, digest)
251 context_sha256_T *ctx;
252 char_u digest[32];
253{
254 uint32_t last, padn;
255 uint32_t high, low;
256 char_u msglen[8];
257
258 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
259 low = (ctx->total[0] << 3);
260
261 PUT_UINT32(high, msglen, 0);
262 PUT_UINT32(low, msglen, 4);
263
264 last = ctx->total[0] & 0x3F;
265 padn = (last < 56) ? (56 - last) : (120 - last);
266
267 sha256_update(ctx, sha256_padding, padn);
268 sha256_update(ctx, msglen, 8);
269
270 PUT_UINT32(ctx->state[0], digest, 0);
271 PUT_UINT32(ctx->state[1], digest, 4);
272 PUT_UINT32(ctx->state[2], digest, 8);
273 PUT_UINT32(ctx->state[3], digest, 12);
274 PUT_UINT32(ctx->state[4], digest, 16);
275 PUT_UINT32(ctx->state[5], digest, 20);
276 PUT_UINT32(ctx->state[6], digest, 24);
277 PUT_UINT32(ctx->state[7], digest, 28);
278}
279
Bram Moolenaar823a1652010-05-16 23:02:33 +0200280/*
281 * Returns hex digest of "buf[buflen]" in a static array.
282 */
283 static char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200284sha256_bytes(buf, buflen)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200285 char_u *buf;
286 int buflen;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200287{
288 char_u sha256sum[32];
Bram Moolenaar823a1652010-05-16 23:02:33 +0200289 static char_u hexit[65];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200290 int j;
291 context_sha256_T ctx;
292
293 sha256_self_test();
294
295 sha256_starts(&ctx);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200296 sha256_update(&ctx, buf, buflen);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200297 sha256_finish(&ctx, sha256sum);
298 for (j = 0; j < 32; j++)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200299 sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200300 hexit[sizeof(hexit) - 1] = '\0';
301 return hexit;
302}
303
304/*
Bram Moolenaar823a1652010-05-16 23:02:33 +0200305 * Returns sha256(buf) as 64 hex chars in static array.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200306 */
Bram Moolenaar823a1652010-05-16 23:02:33 +0200307 char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200308sha256_key(buf)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200309 char_u *buf;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200310{
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200311 /* No passwd means don't encrypt */
312 if (buf == NULL || *buf == NUL)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200313 return (char_u *)"";
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200314
Bram Moolenaar823a1652010-05-16 23:02:33 +0200315 return sha256_bytes(buf, STRLEN(buf));
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200316}
317
318/*
319 * These are the standard FIPS-180-2 test vectors
320 */
321
322static char *sha_self_test_msg[] = {
323 "abc",
324 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
325 NULL
326};
327
328static char *sha_self_test_vector[] = {
329 "ba7816bf8f01cfea414140de5dae2223" \
330 "b00361a396177a9cb410ff61f20015ad",
331 "248d6a61d20638b8e5c026930c3e6039" \
332 "a33ce45964ff2167f6ecedd419db06c1",
333 "cdc76e5c9914fb9281a1c7e284d73e67" \
334 "f1809a48a497200e046d39ccc7112cd0"
335};
336
337/*
338 * Perform a test on the SHA256 algorithm.
339 * Return FAIL or OK.
340 */
341 int
342sha256_self_test()
343{
344 int i, j;
345 char output[65];
346 context_sha256_T ctx;
347 char_u buf[1000];
348 char_u sha256sum[32];
349 static int failures = 0;
Bram Moolenaar823a1652010-05-16 23:02:33 +0200350 char_u *hexit;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200351 static int sha256_self_tested = 0;
352
353 if (sha256_self_tested > 0)
354 return failures > 0 ? FAIL : OK;
355 sha256_self_tested = 1;
356
357 for (i = 0; i < 3; i++)
358 {
359 if (i < 2)
360 {
Bram Moolenaar823a1652010-05-16 23:02:33 +0200361 hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
362 STRLEN(sha_self_test_msg[i]));
363 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200364 }
365 else
366 {
367 sha256_starts(&ctx);
368 memset(buf, 'a', 1000);
369 for (j = 0; j < 1000; j++)
370 sha256_update(&ctx, (char_u *)buf, 1000);
371 sha256_finish(&ctx, sha256sum);
372 for (j = 0; j < 32; j++)
373 sprintf(output + j * 2, "%02x", sha256sum[j]);
374 }
375 if (memcmp(output, sha_self_test_vector[i], 64))
376 {
377 failures++;
378 output[sizeof(output) - 1] = '\0';
379 /* printf("sha256_self_test %d failed %s\n", i, output); */
380 }
381 }
382 return failures > 0 ? FAIL : OK;
383}
384
385 static unsigned int
386get_some_time()
387{
388#ifdef HAVE_GETTIMEOFDAY
389 struct timeval tv;
390
391 /* Using usec makes it less predictable. */
392 gettimeofday(&tv, NULL);
393 return (unsigned int)(tv.tv_sec + tv.tv_usec);
394#else
395 return (unsigned int)time(NULL);
396#endif
397}
398
399/*
400 * set header = sha2_seed(random_data);
401 */
402 void
403sha2_seed(header, header_len)
404 char_u header[];
405 int header_len;
406{
407 int i;
408 static char_u random_data[1000];
409 char_u sha256sum[32];
410 context_sha256_T ctx;
411 srand(get_some_time());
412
413 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
414 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
415 sha256_starts(&ctx);
416 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
417 sha256_finish(&ctx, sha256sum);
418
419 for (i = 0; i < header_len; i++)
420 header[i] = sha256sum[i % sizeof(sha256sum)];
421}
422
423#endif /* FEAT_CRYPT */