blob: 0f9585623e4c436cb998b561b1ab0650608c4564 [file] [log] [blame]
Bram Moolenaar40e6a712010-05-16 22:32:54 +02001/* vi:set ts=8 sts=4 sw=4:
2 *
Bram Moolenaar0bbabe82010-05-17 20:32:55 +02003 * VIM - Vi IMproved by Bram Moolenaar
Bram Moolenaar40e6a712010-05-16 22:32:54 +02004 *
Bram Moolenaar0bbabe82010-05-17 20:32:55 +02005 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 *
9 * FIPS-180-2 compliant SHA-256 implementation
10 * GPL by Christophe Devine.
11 * Modified for md5deep, in public domain.
12 * Modified For Vim, Mohsin Ahmed, http://www.cs.albany.edu/~mosh
13 *
14 * Vim specific notes:
15 * Functions exported by this file:
16 * 1. sha256_key() hashes the password to 64 bytes char string.
17 * 2. sha2_seed() generates a random header.
18 * sha256_self_test() is implicitly called once.
Bram Moolenaar40e6a712010-05-16 22:32:54 +020019 */
20
21#include "vim.h"
22
Bram Moolenaar55debbe2010-05-23 23:34:36 +020023#if defined(FEAT_CRYPT) || defined(FEAT_PERSISTENT_UNDO)
Bram Moolenaar40e6a712010-05-16 22:32:54 +020024
Bram Moolenaar40e6a712010-05-16 22:32:54 +020025static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
Bram Moolenaar823a1652010-05-16 23:02:33 +020026static char_u *sha256_bytes __ARGS((char_u *buf, int buflen));
Bram Moolenaar40e6a712010-05-16 22:32:54 +020027static unsigned int get_some_time __ARGS((void));
28
29
30#define GET_UINT32(n, b, i) \
31{ \
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020032 (n) = ( (UINT32_T)(b)[(i) ] << 24) \
33 | ( (UINT32_T)(b)[(i) + 1] << 16) \
34 | ( (UINT32_T)(b)[(i) + 2] << 8) \
35 | ( (UINT32_T)(b)[(i) + 3] ); \
Bram Moolenaar40e6a712010-05-16 22:32:54 +020036}
37
38#define PUT_UINT32(n,b,i) \
39{ \
40 (b)[(i) ] = (char_u)((n) >> 24); \
41 (b)[(i) + 1] = (char_u)((n) >> 16); \
42 (b)[(i) + 2] = (char_u)((n) >> 8); \
43 (b)[(i) + 3] = (char_u)((n) ); \
44}
45
Bram Moolenaar55debbe2010-05-23 23:34:36 +020046 void
47sha256_start(ctx)
Bram Moolenaar40e6a712010-05-16 22:32:54 +020048 context_sha256_T *ctx;
49{
50 ctx->total[0] = 0;
51 ctx->total[1] = 0;
52
53 ctx->state[0] = 0x6A09E667;
54 ctx->state[1] = 0xBB67AE85;
55 ctx->state[2] = 0x3C6EF372;
56 ctx->state[3] = 0xA54FF53A;
57 ctx->state[4] = 0x510E527F;
58 ctx->state[5] = 0x9B05688C;
59 ctx->state[6] = 0x1F83D9AB;
60 ctx->state[7] = 0x5BE0CD19;
61}
62
63 static void
64sha256_process(ctx, data)
65 context_sha256_T *ctx;
66 char_u data[64];
67{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020068 UINT32_T temp1, temp2, W[64];
69 UINT32_T A, B, C, D, E, F, G, H;
Bram Moolenaar40e6a712010-05-16 22:32:54 +020070
71 GET_UINT32(W[0], data, 0);
72 GET_UINT32(W[1], data, 4);
73 GET_UINT32(W[2], data, 8);
74 GET_UINT32(W[3], data, 12);
75 GET_UINT32(W[4], data, 16);
76 GET_UINT32(W[5], data, 20);
77 GET_UINT32(W[6], data, 24);
78 GET_UINT32(W[7], data, 28);
79 GET_UINT32(W[8], data, 32);
80 GET_UINT32(W[9], data, 36);
81 GET_UINT32(W[10], data, 40);
82 GET_UINT32(W[11], data, 44);
83 GET_UINT32(W[12], data, 48);
84 GET_UINT32(W[13], data, 52);
85 GET_UINT32(W[14], data, 56);
86 GET_UINT32(W[15], data, 60);
87
88#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
89#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
90
91#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
92#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
93
94#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
95#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
96
97#define F0(x, y, z) ((x & y) | (z & (x | y)))
98#define F1(x, y, z) (z ^ (x & (y ^ z)))
99
100#define R(t) \
101( \
102 W[t] = S1(W[t - 2]) + W[t - 7] + \
103 S0(W[t - 15]) + W[t - 16] \
104)
105
106#define P(a,b,c,d,e,f,g,h,x,K) \
107{ \
108 temp1 = h + S3(e) + F1(e, f, g) + K + x; \
109 temp2 = S2(a) + F0(a, b, c); \
110 d += temp1; h = temp1 + temp2; \
111}
112
113 A = ctx->state[0];
114 B = ctx->state[1];
115 C = ctx->state[2];
116 D = ctx->state[3];
117 E = ctx->state[4];
118 F = ctx->state[5];
119 G = ctx->state[6];
120 H = ctx->state[7];
121
122 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
123 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
124 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
125 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
126 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
127 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
128 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
129 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
130 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
131 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
132 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
133 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
134 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
135 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
136 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
137 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
138 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
139 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
140 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
141 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
142 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
143 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
144 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
145 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
146 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
147 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
148 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
149 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
150 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
151 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
152 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
153 P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
154 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
155 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
156 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
157 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
158 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
159 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
160 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
161 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
162 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
163 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
164 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
165 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
166 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
167 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
168 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
169 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
170 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
171 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
172 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
173 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
174 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
175 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
176 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
177 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
178 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
179 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
180 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
181 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
182 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
183 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
184 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
185 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
186
187 ctx->state[0] += A;
188 ctx->state[1] += B;
189 ctx->state[2] += C;
190 ctx->state[3] += D;
191 ctx->state[4] += E;
192 ctx->state[5] += F;
193 ctx->state[6] += G;
194 ctx->state[7] += H;
195}
196
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200197 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200198sha256_update(ctx, input, length)
199 context_sha256_T *ctx;
200 char_u *input;
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200201 UINT32_T length;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200202{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200203 UINT32_T left, fill;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200204
205 if (length == 0)
206 return;
207
208 left = ctx->total[0] & 0x3F;
209 fill = 64 - left;
210
211 ctx->total[0] += length;
212 ctx->total[0] &= 0xFFFFFFFF;
213
214 if (ctx->total[0] < length)
215 ctx->total[1]++;
216
217 if (left && length >= fill)
218 {
219 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
220 sha256_process(ctx, ctx->buffer);
221 length -= fill;
222 input += fill;
223 left = 0;
224 }
225
226 while (length >= 64)
227 {
228 sha256_process(ctx, input);
229 length -= 64;
230 input += 64;
231 }
232
233 if (length)
234 memcpy((void *)(ctx->buffer + left), (void *)input, length);
235}
236
237static char_u sha256_padding[64] = {
238 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
242};
243
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200244 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200245sha256_finish(ctx, digest)
246 context_sha256_T *ctx;
247 char_u digest[32];
248{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200249 UINT32_T last, padn;
250 UINT32_T high, low;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200251 char_u msglen[8];
252
253 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
254 low = (ctx->total[0] << 3);
255
256 PUT_UINT32(high, msglen, 0);
257 PUT_UINT32(low, msglen, 4);
258
259 last = ctx->total[0] & 0x3F;
260 padn = (last < 56) ? (56 - last) : (120 - last);
261
262 sha256_update(ctx, sha256_padding, padn);
263 sha256_update(ctx, msglen, 8);
264
265 PUT_UINT32(ctx->state[0], digest, 0);
266 PUT_UINT32(ctx->state[1], digest, 4);
267 PUT_UINT32(ctx->state[2], digest, 8);
268 PUT_UINT32(ctx->state[3], digest, 12);
269 PUT_UINT32(ctx->state[4], digest, 16);
270 PUT_UINT32(ctx->state[5], digest, 20);
271 PUT_UINT32(ctx->state[6], digest, 24);
272 PUT_UINT32(ctx->state[7], digest, 28);
273}
274
Bram Moolenaar823a1652010-05-16 23:02:33 +0200275/*
276 * Returns hex digest of "buf[buflen]" in a static array.
277 */
278 static char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200279sha256_bytes(buf, buflen)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200280 char_u *buf;
281 int buflen;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200282{
283 char_u sha256sum[32];
Bram Moolenaar823a1652010-05-16 23:02:33 +0200284 static char_u hexit[65];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200285 int j;
286 context_sha256_T ctx;
287
288 sha256_self_test();
289
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200290 sha256_start(&ctx);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200291 sha256_update(&ctx, buf, buflen);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200292 sha256_finish(&ctx, sha256sum);
293 for (j = 0; j < 32; j++)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200294 sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200295 hexit[sizeof(hexit) - 1] = '\0';
296 return hexit;
297}
298
299/*
Bram Moolenaar823a1652010-05-16 23:02:33 +0200300 * Returns sha256(buf) as 64 hex chars in static array.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200301 */
Bram Moolenaar823a1652010-05-16 23:02:33 +0200302 char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200303sha256_key(buf)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200304 char_u *buf;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200305{
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200306 /* No passwd means don't encrypt */
307 if (buf == NULL || *buf == NUL)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200308 return (char_u *)"";
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200309
Bram Moolenaar442b4222010-05-24 21:34:22 +0200310 return sha256_bytes(buf, (int)STRLEN(buf));
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200311}
312
313/*
314 * These are the standard FIPS-180-2 test vectors
315 */
316
317static char *sha_self_test_msg[] = {
318 "abc",
319 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
320 NULL
321};
322
323static char *sha_self_test_vector[] = {
324 "ba7816bf8f01cfea414140de5dae2223" \
325 "b00361a396177a9cb410ff61f20015ad",
326 "248d6a61d20638b8e5c026930c3e6039" \
327 "a33ce45964ff2167f6ecedd419db06c1",
328 "cdc76e5c9914fb9281a1c7e284d73e67" \
329 "f1809a48a497200e046d39ccc7112cd0"
330};
331
332/*
333 * Perform a test on the SHA256 algorithm.
334 * Return FAIL or OK.
335 */
336 int
337sha256_self_test()
338{
339 int i, j;
340 char output[65];
341 context_sha256_T ctx;
342 char_u buf[1000];
343 char_u sha256sum[32];
344 static int failures = 0;
Bram Moolenaar823a1652010-05-16 23:02:33 +0200345 char_u *hexit;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200346 static int sha256_self_tested = 0;
347
348 if (sha256_self_tested > 0)
349 return failures > 0 ? FAIL : OK;
350 sha256_self_tested = 1;
351
352 for (i = 0; i < 3; i++)
353 {
354 if (i < 2)
355 {
Bram Moolenaar823a1652010-05-16 23:02:33 +0200356 hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
Bram Moolenaar442b4222010-05-24 21:34:22 +0200357 (int)STRLEN(sha_self_test_msg[i]));
Bram Moolenaar823a1652010-05-16 23:02:33 +0200358 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200359 }
360 else
361 {
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200362 sha256_start(&ctx);
Bram Moolenaar7db5fc82010-05-24 11:59:29 +0200363 vim_memset(buf, 'a', 1000);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200364 for (j = 0; j < 1000; j++)
365 sha256_update(&ctx, (char_u *)buf, 1000);
366 sha256_finish(&ctx, sha256sum);
367 for (j = 0; j < 32; j++)
368 sprintf(output + j * 2, "%02x", sha256sum[j]);
369 }
370 if (memcmp(output, sha_self_test_vector[i], 64))
371 {
372 failures++;
373 output[sizeof(output) - 1] = '\0';
374 /* printf("sha256_self_test %d failed %s\n", i, output); */
375 }
376 }
377 return failures > 0 ? FAIL : OK;
378}
379
380 static unsigned int
381get_some_time()
382{
383#ifdef HAVE_GETTIMEOFDAY
384 struct timeval tv;
385
386 /* Using usec makes it less predictable. */
387 gettimeofday(&tv, NULL);
388 return (unsigned int)(tv.tv_sec + tv.tv_usec);
389#else
390 return (unsigned int)time(NULL);
391#endif
392}
393
394/*
395 * set header = sha2_seed(random_data);
396 */
397 void
398sha2_seed(header, header_len)
399 char_u header[];
400 int header_len;
401{
402 int i;
403 static char_u random_data[1000];
404 char_u sha256sum[32];
405 context_sha256_T ctx;
406 srand(get_some_time());
407
408 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
409 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200410 sha256_start(&ctx);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200411 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
412 sha256_finish(&ctx, sha256sum);
413
414 for (i = 0; i < header_len; i++)
415 header[i] = sha256sum[i % sizeof(sha256sum)];
416}
417
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200418#endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */