comparison src/sha256.c @ 2180:f60a0c9cbe6c vim73

Add the blowfish encryption patch from Mohsin Ahmed. Needs more work.
author Bram Moolenaar <bram@vim.org>
date Sun, 16 May 2010 22:32:54 +0200
parents
children 3cb515c62e9c
comparison
equal deleted inserted replaced
2178:c6f1aa1e9f32 2180:f60a0c9cbe6c
1 /* 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
19 typedef unsigned long uint32_t;
20
21 typedef struct {
22 uint32_t total[2];
23 uint32_t state[8];
24 char_u buffer[64];
25 } context_sha256_T;
26
27 static void sha256_starts __ARGS((context_sha256_T *ctx));
28 static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
29 static void sha256_update __ARGS((context_sha256_T *ctx, char_u *input, uint32_t length));
30 static void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32]));
31 static char *sha256_bytes __ARGS((char *buf, int buflen));
32 static 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
52 sha256_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
69 sha256_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
203 sha256_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
242 static 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
250 sha256_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
280 static char *
281 sha256_bytes(buf, buflen)
282 char *buf;
283 int buflen;
284 {
285 char_u sha256sum[32];
286 static char hexit[65];
287 int j;
288 context_sha256_T ctx;
289
290 sha256_self_test();
291
292 sha256_starts(&ctx);
293 sha256_update(&ctx, (char_u *)buf, buflen);
294 sha256_finish(&ctx, sha256sum);
295 for (j = 0; j < 32; j++)
296 sprintf(hexit + j * 2, "%02x", sha256sum[j]);
297 hexit[sizeof(hexit) - 1] = '\0';
298 return hexit;
299 }
300
301 /*
302 * Returns sha256(buf) as 64 hex chars.
303 */
304 char *
305 sha256_key(buf)
306 char *buf;
307 {
308 static char *hexit = 0;
309 int buflen;
310
311 /* No passwd means don't encrypt */
312 if (buf == NULL || *buf == NUL)
313 return "";
314
315 /* if password is "0", reuse previous hash, for user convienience. */
316 if (!strcmp(buf, "0") && hexit)
317 return hexit;
318
319 buflen = strlen(buf);
320 hexit = sha256_bytes(buf, buflen);
321 return hexit;
322 }
323
324 /*
325 * These are the standard FIPS-180-2 test vectors
326 */
327
328 static char *sha_self_test_msg[] = {
329 "abc",
330 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
331 NULL
332 };
333
334 static char *sha_self_test_vector[] = {
335 "ba7816bf8f01cfea414140de5dae2223" \
336 "b00361a396177a9cb410ff61f20015ad",
337 "248d6a61d20638b8e5c026930c3e6039" \
338 "a33ce45964ff2167f6ecedd419db06c1",
339 "cdc76e5c9914fb9281a1c7e284d73e67" \
340 "f1809a48a497200e046d39ccc7112cd0"
341 };
342
343 /*
344 * Perform a test on the SHA256 algorithm.
345 * Return FAIL or OK.
346 */
347 int
348 sha256_self_test()
349 {
350 int i, j;
351 char output[65];
352 context_sha256_T ctx;
353 char_u buf[1000];
354 char_u sha256sum[32];
355 static int failures = 0;
356 char *hexit;
357 static int sha256_self_tested = 0;
358
359 if (sha256_self_tested > 0)
360 return failures > 0 ? FAIL : OK;
361 sha256_self_tested = 1;
362
363 for (i = 0; i < 3; i++)
364 {
365 if (i < 2)
366 {
367 hexit = sha256_bytes(sha_self_test_msg[i],
368 strlen(sha_self_test_msg[i]));
369 strcpy(output, hexit);
370 }
371 else
372 {
373 sha256_starts(&ctx);
374 memset(buf, 'a', 1000);
375 for (j = 0; j < 1000; j++)
376 sha256_update(&ctx, (char_u *)buf, 1000);
377 sha256_finish(&ctx, sha256sum);
378 for (j = 0; j < 32; j++)
379 sprintf(output + j * 2, "%02x", sha256sum[j]);
380 }
381 if (memcmp(output, sha_self_test_vector[i], 64))
382 {
383 failures++;
384 output[sizeof(output) - 1] = '\0';
385 /* printf("sha256_self_test %d failed %s\n", i, output); */
386 }
387 }
388 return failures > 0 ? FAIL : OK;
389 }
390
391 static unsigned int
392 get_some_time()
393 {
394 #ifdef HAVE_GETTIMEOFDAY
395 struct timeval tv;
396
397 /* Using usec makes it less predictable. */
398 gettimeofday(&tv, NULL);
399 return (unsigned int)(tv.tv_sec + tv.tv_usec);
400 #else
401 return (unsigned int)time(NULL);
402 #endif
403 }
404
405 /*
406 * set header = sha2_seed(random_data);
407 */
408 void
409 sha2_seed(header, header_len)
410 char_u header[];
411 int header_len;
412 {
413 int i;
414 static char_u random_data[1000];
415 char_u sha256sum[32];
416 context_sha256_T ctx;
417 srand(get_some_time());
418
419 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
420 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
421 sha256_starts(&ctx);
422 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
423 sha256_finish(&ctx, sha256sum);
424
425 for (i = 0; i < header_len; i++)
426 header[i] = sha256sum[i % sizeof(sha256sum)];
427 }
428
429 #endif /* FEAT_CRYPT */