blob: c24e8b8f83821abaab48640d647e1fe8fcbda29e [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 Moolenaar40e6a712010-05-16 22:32:54 +020026
27#define GET_UINT32(n, b, i) \
28{ \
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020029 (n) = ( (UINT32_T)(b)[(i) ] << 24) \
30 | ( (UINT32_T)(b)[(i) + 1] << 16) \
31 | ( (UINT32_T)(b)[(i) + 2] << 8) \
32 | ( (UINT32_T)(b)[(i) + 3] ); \
Bram Moolenaar40e6a712010-05-16 22:32:54 +020033}
34
35#define PUT_UINT32(n,b,i) \
36{ \
37 (b)[(i) ] = (char_u)((n) >> 24); \
38 (b)[(i) + 1] = (char_u)((n) >> 16); \
39 (b)[(i) + 2] = (char_u)((n) >> 8); \
40 (b)[(i) + 3] = (char_u)((n) ); \
41}
42
Bram Moolenaar55debbe2010-05-23 23:34:36 +020043 void
44sha256_start(ctx)
Bram Moolenaar40e6a712010-05-16 22:32:54 +020045 context_sha256_T *ctx;
46{
47 ctx->total[0] = 0;
48 ctx->total[1] = 0;
49
50 ctx->state[0] = 0x6A09E667;
51 ctx->state[1] = 0xBB67AE85;
52 ctx->state[2] = 0x3C6EF372;
53 ctx->state[3] = 0xA54FF53A;
54 ctx->state[4] = 0x510E527F;
55 ctx->state[5] = 0x9B05688C;
56 ctx->state[6] = 0x1F83D9AB;
57 ctx->state[7] = 0x5BE0CD19;
58}
59
60 static void
61sha256_process(ctx, data)
62 context_sha256_T *ctx;
63 char_u data[64];
64{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020065 UINT32_T temp1, temp2, W[64];
66 UINT32_T A, B, C, D, E, F, G, H;
Bram Moolenaar40e6a712010-05-16 22:32:54 +020067
68 GET_UINT32(W[0], data, 0);
69 GET_UINT32(W[1], data, 4);
70 GET_UINT32(W[2], data, 8);
71 GET_UINT32(W[3], data, 12);
72 GET_UINT32(W[4], data, 16);
73 GET_UINT32(W[5], data, 20);
74 GET_UINT32(W[6], data, 24);
75 GET_UINT32(W[7], data, 28);
76 GET_UINT32(W[8], data, 32);
77 GET_UINT32(W[9], data, 36);
78 GET_UINT32(W[10], data, 40);
79 GET_UINT32(W[11], data, 44);
80 GET_UINT32(W[12], data, 48);
81 GET_UINT32(W[13], data, 52);
82 GET_UINT32(W[14], data, 56);
83 GET_UINT32(W[15], data, 60);
84
85#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
86#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
87
88#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
89#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
90
91#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
92#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
93
94#define F0(x, y, z) ((x & y) | (z & (x | y)))
95#define F1(x, y, z) (z ^ (x & (y ^ z)))
96
97#define R(t) \
98( \
99 W[t] = S1(W[t - 2]) + W[t - 7] + \
100 S0(W[t - 15]) + W[t - 16] \
101)
102
103#define P(a,b,c,d,e,f,g,h,x,K) \
104{ \
105 temp1 = h + S3(e) + F1(e, f, g) + K + x; \
106 temp2 = S2(a) + F0(a, b, c); \
107 d += temp1; h = temp1 + temp2; \
108}
109
110 A = ctx->state[0];
111 B = ctx->state[1];
112 C = ctx->state[2];
113 D = ctx->state[3];
114 E = ctx->state[4];
115 F = ctx->state[5];
116 G = ctx->state[6];
117 H = ctx->state[7];
118
119 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
120 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
121 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
122 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
123 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
124 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
125 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
126 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
127 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
128 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
129 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
130 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
131 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
132 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
133 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
134 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
135 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
136 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
137 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
138 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
139 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
140 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
141 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
142 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
143 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
144 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
145 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
146 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
147 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
148 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
149 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
150 P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
151 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
152 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
153 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
154 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
155 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
156 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
157 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
158 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
159 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
160 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
161 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
162 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
163 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
164 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
165 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
166 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
167 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
168 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
169 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
170 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
171 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
172 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
173 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
174 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
175 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
176 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
177 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
178 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
179 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
180 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
181 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
182 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
183
184 ctx->state[0] += A;
185 ctx->state[1] += B;
186 ctx->state[2] += C;
187 ctx->state[3] += D;
188 ctx->state[4] += E;
189 ctx->state[5] += F;
190 ctx->state[6] += G;
191 ctx->state[7] += H;
192}
193
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200194 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200195sha256_update(ctx, input, length)
196 context_sha256_T *ctx;
197 char_u *input;
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200198 UINT32_T length;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200199{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200200 UINT32_T left, fill;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200201
202 if (length == 0)
203 return;
204
205 left = ctx->total[0] & 0x3F;
206 fill = 64 - left;
207
208 ctx->total[0] += length;
209 ctx->total[0] &= 0xFFFFFFFF;
210
211 if (ctx->total[0] < length)
212 ctx->total[1]++;
213
214 if (left && length >= fill)
215 {
216 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
217 sha256_process(ctx, ctx->buffer);
218 length -= fill;
219 input += fill;
220 left = 0;
221 }
222
223 while (length >= 64)
224 {
225 sha256_process(ctx, input);
226 length -= 64;
227 input += 64;
228 }
229
230 if (length)
231 memcpy((void *)(ctx->buffer + left), (void *)input, length);
232}
233
234static char_u sha256_padding[64] = {
235 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
239};
240
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200241 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200242sha256_finish(ctx, digest)
243 context_sha256_T *ctx;
244 char_u digest[32];
245{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200246 UINT32_T last, padn;
247 UINT32_T high, low;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200248 char_u msglen[8];
249
250 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
251 low = (ctx->total[0] << 3);
252
253 PUT_UINT32(high, msglen, 0);
254 PUT_UINT32(low, msglen, 4);
255
256 last = ctx->total[0] & 0x3F;
257 padn = (last < 56) ? (56 - last) : (120 - last);
258
259 sha256_update(ctx, sha256_padding, padn);
260 sha256_update(ctx, msglen, 8);
261
262 PUT_UINT32(ctx->state[0], digest, 0);
263 PUT_UINT32(ctx->state[1], digest, 4);
264 PUT_UINT32(ctx->state[2], digest, 8);
265 PUT_UINT32(ctx->state[3], digest, 12);
266 PUT_UINT32(ctx->state[4], digest, 16);
267 PUT_UINT32(ctx->state[5], digest, 20);
268 PUT_UINT32(ctx->state[6], digest, 24);
269 PUT_UINT32(ctx->state[7], digest, 28);
270}
Bram Moolenaar80794b12010-06-13 05:20:42 +0200271#endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */
272
273#if defined(FEAT_CRYPT) || defined(PROTO)
274static char_u *sha256_bytes __ARGS((char_u *buf, int buf_len, char_u *salt, int salt_len));
275static unsigned int get_some_time __ARGS((void));
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200276
Bram Moolenaar823a1652010-05-16 23:02:33 +0200277/*
Bram Moolenaar80794b12010-06-13 05:20:42 +0200278 * Returns hex digest of "buf[buf_len]" in a static array.
279 * if "salt" is not NULL also do "salt[salt_len]".
Bram Moolenaar823a1652010-05-16 23:02:33 +0200280 */
281 static char_u *
Bram Moolenaar80794b12010-06-13 05:20:42 +0200282sha256_bytes(buf, buf_len, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200283 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200284 int buf_len;
285 char_u *salt;
286 int salt_len;
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
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200295 sha256_start(&ctx);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200296 sha256_update(&ctx, buf, buf_len);
297 if (salt != NULL)
298 sha256_update(&ctx, salt, salt_len);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200299 sha256_finish(&ctx, sha256sum);
300 for (j = 0; j < 32; j++)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200301 sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200302 hexit[sizeof(hexit) - 1] = '\0';
303 return hexit;
304}
305
306/*
Bram Moolenaar823a1652010-05-16 23:02:33 +0200307 * Returns sha256(buf) as 64 hex chars in static array.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200308 */
Bram Moolenaar823a1652010-05-16 23:02:33 +0200309 char_u *
Bram Moolenaar80794b12010-06-13 05:20:42 +0200310sha256_key(buf, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200311 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200312 char_u *salt;
313 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200314{
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200315 /* No passwd means don't encrypt */
316 if (buf == NULL || *buf == NUL)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200317 return (char_u *)"";
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200318
Bram Moolenaar80794b12010-06-13 05:20:42 +0200319 return sha256_bytes(buf, (int)STRLEN(buf), salt, salt_len);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200320}
321
322/*
323 * These are the standard FIPS-180-2 test vectors
324 */
325
326static char *sha_self_test_msg[] = {
327 "abc",
328 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
329 NULL
330};
331
332static char *sha_self_test_vector[] = {
333 "ba7816bf8f01cfea414140de5dae2223" \
334 "b00361a396177a9cb410ff61f20015ad",
335 "248d6a61d20638b8e5c026930c3e6039" \
336 "a33ce45964ff2167f6ecedd419db06c1",
337 "cdc76e5c9914fb9281a1c7e284d73e67" \
338 "f1809a48a497200e046d39ccc7112cd0"
339};
340
341/*
342 * Perform a test on the SHA256 algorithm.
343 * Return FAIL or OK.
344 */
345 int
346sha256_self_test()
347{
348 int i, j;
349 char output[65];
350 context_sha256_T ctx;
351 char_u buf[1000];
352 char_u sha256sum[32];
353 static int failures = 0;
Bram Moolenaar823a1652010-05-16 23:02:33 +0200354 char_u *hexit;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200355 static int sha256_self_tested = 0;
356
357 if (sha256_self_tested > 0)
358 return failures > 0 ? FAIL : OK;
359 sha256_self_tested = 1;
360
361 for (i = 0; i < 3; i++)
362 {
363 if (i < 2)
364 {
Bram Moolenaar823a1652010-05-16 23:02:33 +0200365 hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
Bram Moolenaar80794b12010-06-13 05:20:42 +0200366 (int)STRLEN(sha_self_test_msg[i]),
367 NULL, 0);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200368 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200369 }
370 else
371 {
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200372 sha256_start(&ctx);
Bram Moolenaar7db5fc82010-05-24 11:59:29 +0200373 vim_memset(buf, 'a', 1000);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200374 for (j = 0; j < 1000; j++)
375 sha256_update(&ctx, (char_u *)buf, 1000);
376 sha256_finish(&ctx, sha256sum);
377 for (j = 0; j < 32; j++)
378 sprintf(output + j * 2, "%02x", sha256sum[j]);
379 }
380 if (memcmp(output, sha_self_test_vector[i], 64))
381 {
382 failures++;
383 output[sizeof(output) - 1] = '\0';
384 /* printf("sha256_self_test %d failed %s\n", i, output); */
385 }
386 }
387 return failures > 0 ? FAIL : OK;
388}
389
390 static unsigned int
391get_some_time()
392{
Bram Moolenaar80794b12010-06-13 05:20:42 +0200393# ifdef HAVE_GETTIMEOFDAY
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200394 struct timeval tv;
395
396 /* Using usec makes it less predictable. */
397 gettimeofday(&tv, NULL);
398 return (unsigned int)(tv.tv_sec + tv.tv_usec);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200399# else
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200400 return (unsigned int)time(NULL);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200401# endif
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200402}
403
404/*
405 * set header = sha2_seed(random_data);
406 */
407 void
Bram Moolenaar80794b12010-06-13 05:20:42 +0200408sha2_seed(header, header_len, salt, salt_len)
409 char_u *header;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200410 int header_len;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200411 char_u *salt;
412 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200413{
414 int i;
415 static char_u random_data[1000];
416 char_u sha256sum[32];
417 context_sha256_T ctx;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200418
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200419 srand(get_some_time());
420
421 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
422 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200423 sha256_start(&ctx);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200424 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
425 sha256_finish(&ctx, sha256sum);
426
Bram Moolenaar80794b12010-06-13 05:20:42 +0200427 /* put first block into header. */
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200428 for (i = 0; i < header_len; i++)
429 header[i] = sha256sum[i % sizeof(sha256sum)];
Bram Moolenaar80794b12010-06-13 05:20:42 +0200430
431 /* put remaining block into salt. */
432 for (i = 0; i < salt_len; i++)
433 salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200434}
435
Bram Moolenaar80794b12010-06-13 05:20:42 +0200436#endif /* FEAT_CRYPT */