blob: de3211a92f4484424f88ee969f3468f59fc704e9 [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
23#ifdef FEAT_CRYPT
24
Bram Moolenaar40e6a712010-05-16 22:32:54 +020025typedef struct {
26 uint32_t total[2];
27 uint32_t state[8];
28 char_u buffer[64];
29} context_sha256_T;
30
31static void sha256_starts __ARGS((context_sha256_T *ctx));
32static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
33static void sha256_update __ARGS((context_sha256_T *ctx, char_u *input, uint32_t length));
34static void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32]));
Bram Moolenaar823a1652010-05-16 23:02:33 +020035static char_u *sha256_bytes __ARGS((char_u *buf, int buflen));
Bram Moolenaar40e6a712010-05-16 22:32:54 +020036static unsigned int get_some_time __ARGS((void));
37
38
39#define GET_UINT32(n, b, i) \
40{ \
41 (n) = ( (uint32_t)(b)[(i) ] << 24) \
42 | ( (uint32_t)(b)[(i) + 1] << 16) \
43 | ( (uint32_t)(b)[(i) + 2] << 8) \
44 | ( (uint32_t)(b)[(i) + 3] ); \
45}
46
47#define PUT_UINT32(n,b,i) \
48{ \
49 (b)[(i) ] = (char_u)((n) >> 24); \
50 (b)[(i) + 1] = (char_u)((n) >> 16); \
51 (b)[(i) + 2] = (char_u)((n) >> 8); \
52 (b)[(i) + 3] = (char_u)((n) ); \
53}
54
55 static void
56sha256_starts(ctx)
57 context_sha256_T *ctx;
58{
59 ctx->total[0] = 0;
60 ctx->total[1] = 0;
61
62 ctx->state[0] = 0x6A09E667;
63 ctx->state[1] = 0xBB67AE85;
64 ctx->state[2] = 0x3C6EF372;
65 ctx->state[3] = 0xA54FF53A;
66 ctx->state[4] = 0x510E527F;
67 ctx->state[5] = 0x9B05688C;
68 ctx->state[6] = 0x1F83D9AB;
69 ctx->state[7] = 0x5BE0CD19;
70}
71
72 static void
73sha256_process(ctx, data)
74 context_sha256_T *ctx;
75 char_u data[64];
76{
77 uint32_t temp1, temp2, W[64];
78 uint32_t A, B, C, D, E, F, G, H;
79
80 GET_UINT32(W[0], data, 0);
81 GET_UINT32(W[1], data, 4);
82 GET_UINT32(W[2], data, 8);
83 GET_UINT32(W[3], data, 12);
84 GET_UINT32(W[4], data, 16);
85 GET_UINT32(W[5], data, 20);
86 GET_UINT32(W[6], data, 24);
87 GET_UINT32(W[7], data, 28);
88 GET_UINT32(W[8], data, 32);
89 GET_UINT32(W[9], data, 36);
90 GET_UINT32(W[10], data, 40);
91 GET_UINT32(W[11], data, 44);
92 GET_UINT32(W[12], data, 48);
93 GET_UINT32(W[13], data, 52);
94 GET_UINT32(W[14], data, 56);
95 GET_UINT32(W[15], data, 60);
96
97#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
98#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
99
100#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
101#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
102
103#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
104#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
105
106#define F0(x, y, z) ((x & y) | (z & (x | y)))
107#define F1(x, y, z) (z ^ (x & (y ^ z)))
108
109#define R(t) \
110( \
111 W[t] = S1(W[t - 2]) + W[t - 7] + \
112 S0(W[t - 15]) + W[t - 16] \
113)
114
115#define P(a,b,c,d,e,f,g,h,x,K) \
116{ \
117 temp1 = h + S3(e) + F1(e, f, g) + K + x; \
118 temp2 = S2(a) + F0(a, b, c); \
119 d += temp1; h = temp1 + temp2; \
120}
121
122 A = ctx->state[0];
123 B = ctx->state[1];
124 C = ctx->state[2];
125 D = ctx->state[3];
126 E = ctx->state[4];
127 F = ctx->state[5];
128 G = ctx->state[6];
129 H = ctx->state[7];
130
131 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
132 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
133 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
134 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
135 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
136 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
137 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
138 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
139 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
140 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
141 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
142 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
143 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
144 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
145 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
146 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
147 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
148 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
149 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
150 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
151 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
152 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
153 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
154 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
155 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
156 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
157 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
158 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
159 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
160 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
161 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
162 P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
163 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
164 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
165 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
166 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
167 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
168 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
169 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
170 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
171 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
172 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
173 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
174 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
175 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
176 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
177 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
178 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
179 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
180 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
181 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
182 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
183 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
184 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
185 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
186 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
187 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
188 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
189 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
190 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
191 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
192 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
193 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
194 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
195
196 ctx->state[0] += A;
197 ctx->state[1] += B;
198 ctx->state[2] += C;
199 ctx->state[3] += D;
200 ctx->state[4] += E;
201 ctx->state[5] += F;
202 ctx->state[6] += G;
203 ctx->state[7] += H;
204}
205
206 static void
207sha256_update(ctx, input, length)
208 context_sha256_T *ctx;
209 char_u *input;
210 uint32_t length;
211{
212 uint32_t left, fill;
213
214 if (length == 0)
215 return;
216
217 left = ctx->total[0] & 0x3F;
218 fill = 64 - left;
219
220 ctx->total[0] += length;
221 ctx->total[0] &= 0xFFFFFFFF;
222
223 if (ctx->total[0] < length)
224 ctx->total[1]++;
225
226 if (left && length >= fill)
227 {
228 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
229 sha256_process(ctx, ctx->buffer);
230 length -= fill;
231 input += fill;
232 left = 0;
233 }
234
235 while (length >= 64)
236 {
237 sha256_process(ctx, input);
238 length -= 64;
239 input += 64;
240 }
241
242 if (length)
243 memcpy((void *)(ctx->buffer + left), (void *)input, length);
244}
245
246static char_u sha256_padding[64] = {
247 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
251};
252
253 static void
254sha256_finish(ctx, digest)
255 context_sha256_T *ctx;
256 char_u digest[32];
257{
258 uint32_t last, padn;
259 uint32_t high, low;
260 char_u msglen[8];
261
262 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
263 low = (ctx->total[0] << 3);
264
265 PUT_UINT32(high, msglen, 0);
266 PUT_UINT32(low, msglen, 4);
267
268 last = ctx->total[0] & 0x3F;
269 padn = (last < 56) ? (56 - last) : (120 - last);
270
271 sha256_update(ctx, sha256_padding, padn);
272 sha256_update(ctx, msglen, 8);
273
274 PUT_UINT32(ctx->state[0], digest, 0);
275 PUT_UINT32(ctx->state[1], digest, 4);
276 PUT_UINT32(ctx->state[2], digest, 8);
277 PUT_UINT32(ctx->state[3], digest, 12);
278 PUT_UINT32(ctx->state[4], digest, 16);
279 PUT_UINT32(ctx->state[5], digest, 20);
280 PUT_UINT32(ctx->state[6], digest, 24);
281 PUT_UINT32(ctx->state[7], digest, 28);
282}
283
Bram Moolenaar823a1652010-05-16 23:02:33 +0200284/*
285 * Returns hex digest of "buf[buflen]" in a static array.
286 */
287 static char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200288sha256_bytes(buf, buflen)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200289 char_u *buf;
290 int buflen;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200291{
292 char_u sha256sum[32];
Bram Moolenaar823a1652010-05-16 23:02:33 +0200293 static char_u hexit[65];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200294 int j;
295 context_sha256_T ctx;
296
297 sha256_self_test();
298
299 sha256_starts(&ctx);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200300 sha256_update(&ctx, buf, buflen);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200301 sha256_finish(&ctx, sha256sum);
302 for (j = 0; j < 32; j++)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200303 sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200304 hexit[sizeof(hexit) - 1] = '\0';
305 return hexit;
306}
307
308/*
Bram Moolenaar823a1652010-05-16 23:02:33 +0200309 * Returns sha256(buf) as 64 hex chars in static array.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200310 */
Bram Moolenaar823a1652010-05-16 23:02:33 +0200311 char_u *
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200312sha256_key(buf)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200313 char_u *buf;
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 Moolenaar823a1652010-05-16 23:02:33 +0200319 return sha256_bytes(buf, STRLEN(buf));
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],
366 STRLEN(sha_self_test_msg[i]));
367 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200368 }
369 else
370 {
371 sha256_starts(&ctx);
372 memset(buf, 'a', 1000);
373 for (j = 0; j < 1000; j++)
374 sha256_update(&ctx, (char_u *)buf, 1000);
375 sha256_finish(&ctx, sha256sum);
376 for (j = 0; j < 32; j++)
377 sprintf(output + j * 2, "%02x", sha256sum[j]);
378 }
379 if (memcmp(output, sha_self_test_vector[i], 64))
380 {
381 failures++;
382 output[sizeof(output) - 1] = '\0';
383 /* printf("sha256_self_test %d failed %s\n", i, output); */
384 }
385 }
386 return failures > 0 ? FAIL : OK;
387}
388
389 static unsigned int
390get_some_time()
391{
392#ifdef HAVE_GETTIMEOFDAY
393 struct timeval tv;
394
395 /* Using usec makes it less predictable. */
396 gettimeofday(&tv, NULL);
397 return (unsigned int)(tv.tv_sec + tv.tv_usec);
398#else
399 return (unsigned int)time(NULL);
400#endif
401}
402
403/*
404 * set header = sha2_seed(random_data);
405 */
406 void
407sha2_seed(header, header_len)
408 char_u header[];
409 int header_len;
410{
411 int i;
412 static char_u random_data[1000];
413 char_u sha256sum[32];
414 context_sha256_T ctx;
415 srand(get_some_time());
416
417 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
418 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
419 sha256_starts(&ctx);
420 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
421 sha256_finish(&ctx, sha256sum);
422
423 for (i = 0; i < header_len; i++)
424 header[i] = sha256sum[i % sizeof(sha256sum)];
425}
426
427#endif /* FEAT_CRYPT */