blob: 3392fc08e85423cf79ea456064ae663efe81b646 [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
Bram Moolenaar8d4eecc2012-11-20 17:19:01 +010010 * GPL by Christophe Devine, applies to older version.
Bram Moolenaar0bbabe82010-05-17 20:32:55 +020011 * Modified for md5deep, in public domain.
12 * Modified For Vim, Mohsin Ahmed, http://www.cs.albany.edu/~mosh
Bram Moolenaar8d4eecc2012-11-20 17:19:01 +010013 * Mohsin Ahmed states this work is distributed under the VIM License or GPL,
14 * at your choice.
Bram Moolenaar0bbabe82010-05-17 20:32:55 +020015 *
16 * Vim specific notes:
17 * Functions exported by this file:
18 * 1. sha256_key() hashes the password to 64 bytes char string.
19 * 2. sha2_seed() generates a random header.
20 * sha256_self_test() is implicitly called once.
Bram Moolenaar40e6a712010-05-16 22:32:54 +020021 */
22
23#include "vim.h"
24
Bram Moolenaar55debbe2010-05-23 23:34:36 +020025#if defined(FEAT_CRYPT) || defined(FEAT_PERSISTENT_UNDO)
Bram Moolenaar40e6a712010-05-16 22:32:54 +020026
Bram Moolenaar40e6a712010-05-16 22:32:54 +020027static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
Bram Moolenaar40e6a712010-05-16 22:32:54 +020028
29#define GET_UINT32(n, b, i) \
30{ \
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020031 (n) = ( (UINT32_T)(b)[(i) ] << 24) \
32 | ( (UINT32_T)(b)[(i) + 1] << 16) \
33 | ( (UINT32_T)(b)[(i) + 2] << 8) \
34 | ( (UINT32_T)(b)[(i) + 3] ); \
Bram Moolenaar40e6a712010-05-16 22:32:54 +020035}
36
37#define PUT_UINT32(n,b,i) \
38{ \
39 (b)[(i) ] = (char_u)((n) >> 24); \
40 (b)[(i) + 1] = (char_u)((n) >> 16); \
41 (b)[(i) + 2] = (char_u)((n) >> 8); \
42 (b)[(i) + 3] = (char_u)((n) ); \
43}
44
Bram Moolenaar55debbe2010-05-23 23:34:36 +020045 void
46sha256_start(ctx)
Bram Moolenaar40e6a712010-05-16 22:32:54 +020047 context_sha256_T *ctx;
48{
49 ctx->total[0] = 0;
50 ctx->total[1] = 0;
51
52 ctx->state[0] = 0x6A09E667;
53 ctx->state[1] = 0xBB67AE85;
54 ctx->state[2] = 0x3C6EF372;
55 ctx->state[3] = 0xA54FF53A;
56 ctx->state[4] = 0x510E527F;
57 ctx->state[5] = 0x9B05688C;
58 ctx->state[6] = 0x1F83D9AB;
59 ctx->state[7] = 0x5BE0CD19;
60}
61
62 static void
63sha256_process(ctx, data)
64 context_sha256_T *ctx;
65 char_u data[64];
66{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +020067 UINT32_T temp1, temp2, W[64];
68 UINT32_T A, B, C, D, E, F, G, H;
Bram Moolenaar40e6a712010-05-16 22:32:54 +020069
70 GET_UINT32(W[0], data, 0);
71 GET_UINT32(W[1], data, 4);
72 GET_UINT32(W[2], data, 8);
73 GET_UINT32(W[3], data, 12);
74 GET_UINT32(W[4], data, 16);
75 GET_UINT32(W[5], data, 20);
76 GET_UINT32(W[6], data, 24);
77 GET_UINT32(W[7], data, 28);
78 GET_UINT32(W[8], data, 32);
79 GET_UINT32(W[9], data, 36);
80 GET_UINT32(W[10], data, 40);
81 GET_UINT32(W[11], data, 44);
82 GET_UINT32(W[12], data, 48);
83 GET_UINT32(W[13], data, 52);
84 GET_UINT32(W[14], data, 56);
85 GET_UINT32(W[15], data, 60);
86
87#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
88#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
89
90#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
91#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
92
93#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
94#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
95
96#define F0(x, y, z) ((x & y) | (z & (x | y)))
97#define F1(x, y, z) (z ^ (x & (y ^ z)))
98
99#define R(t) \
100( \
101 W[t] = S1(W[t - 2]) + W[t - 7] + \
102 S0(W[t - 15]) + W[t - 16] \
103)
104
105#define P(a,b,c,d,e,f,g,h,x,K) \
106{ \
107 temp1 = h + S3(e) + F1(e, f, g) + K + x; \
108 temp2 = S2(a) + F0(a, b, c); \
109 d += temp1; h = temp1 + temp2; \
110}
111
112 A = ctx->state[0];
113 B = ctx->state[1];
114 C = ctx->state[2];
115 D = ctx->state[3];
116 E = ctx->state[4];
117 F = ctx->state[5];
118 G = ctx->state[6];
119 H = ctx->state[7];
120
121 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
122 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
123 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
124 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
125 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
126 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
127 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
128 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
129 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
130 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
131 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
132 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
133 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
134 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
135 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
136 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
137 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
138 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
139 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
140 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
141 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
142 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
143 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
144 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
145 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
146 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
147 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
148 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
149 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
150 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
151 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
152 P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
153 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
154 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
155 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
156 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
157 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
158 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
159 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
160 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
161 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
162 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
163 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
164 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
165 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
166 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
167 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
168 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
169 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
170 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
171 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
172 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
173 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
174 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
175 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
176 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
177 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
178 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
179 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
180 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
181 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
182 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
183 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
184 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
185
186 ctx->state[0] += A;
187 ctx->state[1] += B;
188 ctx->state[2] += C;
189 ctx->state[3] += D;
190 ctx->state[4] += E;
191 ctx->state[5] += F;
192 ctx->state[6] += G;
193 ctx->state[7] += H;
194}
195
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200196 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200197sha256_update(ctx, input, length)
198 context_sha256_T *ctx;
199 char_u *input;
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200200 UINT32_T length;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200201{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200202 UINT32_T left, fill;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200203
204 if (length == 0)
205 return;
206
207 left = ctx->total[0] & 0x3F;
208 fill = 64 - left;
209
210 ctx->total[0] += length;
211 ctx->total[0] &= 0xFFFFFFFF;
212
213 if (ctx->total[0] < length)
214 ctx->total[1]++;
215
216 if (left && length >= fill)
217 {
218 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
219 sha256_process(ctx, ctx->buffer);
220 length -= fill;
221 input += fill;
222 left = 0;
223 }
224
225 while (length >= 64)
226 {
227 sha256_process(ctx, input);
228 length -= 64;
229 input += 64;
230 }
231
232 if (length)
233 memcpy((void *)(ctx->buffer + left), (void *)input, length);
234}
235
236static char_u sha256_padding[64] = {
237 0x80, 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 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};
242
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200243 void
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200244sha256_finish(ctx, digest)
245 context_sha256_T *ctx;
Bram Moolenaarcc448b32010-07-14 16:52:17 +0200246 char_u digest[32];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200247{
Bram Moolenaarfa7584c2010-05-19 21:57:45 +0200248 UINT32_T last, padn;
249 UINT32_T high, low;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200250 char_u msglen[8];
251
252 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
253 low = (ctx->total[0] << 3);
254
255 PUT_UINT32(high, msglen, 0);
256 PUT_UINT32(low, msglen, 4);
257
258 last = ctx->total[0] & 0x3F;
259 padn = (last < 56) ? (56 - last) : (120 - last);
260
261 sha256_update(ctx, sha256_padding, padn);
262 sha256_update(ctx, msglen, 8);
263
264 PUT_UINT32(ctx->state[0], digest, 0);
265 PUT_UINT32(ctx->state[1], digest, 4);
266 PUT_UINT32(ctx->state[2], digest, 8);
267 PUT_UINT32(ctx->state[3], digest, 12);
268 PUT_UINT32(ctx->state[4], digest, 16);
269 PUT_UINT32(ctx->state[5], digest, 20);
270 PUT_UINT32(ctx->state[6], digest, 24);
271 PUT_UINT32(ctx->state[7], digest, 28);
272}
Bram Moolenaar80794b12010-06-13 05:20:42 +0200273#endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */
274
275#if defined(FEAT_CRYPT) || defined(PROTO)
276static char_u *sha256_bytes __ARGS((char_u *buf, int buf_len, char_u *salt, int salt_len));
277static unsigned int get_some_time __ARGS((void));
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200278
Bram Moolenaar823a1652010-05-16 23:02:33 +0200279/*
Bram Moolenaar80794b12010-06-13 05:20:42 +0200280 * Returns hex digest of "buf[buf_len]" in a static array.
281 * if "salt" is not NULL also do "salt[salt_len]".
Bram Moolenaar823a1652010-05-16 23:02:33 +0200282 */
283 static char_u *
Bram Moolenaar80794b12010-06-13 05:20:42 +0200284sha256_bytes(buf, buf_len, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200285 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200286 int buf_len;
287 char_u *salt;
288 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200289{
290 char_u sha256sum[32];
Bram Moolenaar823a1652010-05-16 23:02:33 +0200291 static char_u hexit[65];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200292 int j;
293 context_sha256_T ctx;
294
295 sha256_self_test();
296
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200297 sha256_start(&ctx);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200298 sha256_update(&ctx, buf, buf_len);
299 if (salt != NULL)
300 sha256_update(&ctx, salt, salt_len);
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 Moolenaar80794b12010-06-13 05:20:42 +0200312sha256_key(buf, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200313 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200314 char_u *salt;
315 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200316{
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200317 /* No passwd means don't encrypt */
318 if (buf == NULL || *buf == NUL)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200319 return (char_u *)"";
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200320
Bram Moolenaar80794b12010-06-13 05:20:42 +0200321 return sha256_bytes(buf, (int)STRLEN(buf), salt, salt_len);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200322}
323
324/*
325 * These are the standard FIPS-180-2 test vectors
326 */
327
328static char *sha_self_test_msg[] = {
329 "abc",
330 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
331 NULL
332};
333
334static 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
348sha256_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;
Bram Moolenaar823a1652010-05-16 23:02:33 +0200356 char_u *hexit;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200357 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 {
Bram Moolenaar823a1652010-05-16 23:02:33 +0200367 hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
Bram Moolenaar80794b12010-06-13 05:20:42 +0200368 (int)STRLEN(sha_self_test_msg[i]),
369 NULL, 0);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200370 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200371 }
372 else
373 {
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200374 sha256_start(&ctx);
Bram Moolenaar7db5fc82010-05-24 11:59:29 +0200375 vim_memset(buf, 'a', 1000);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200376 for (j = 0; j < 1000; j++)
377 sha256_update(&ctx, (char_u *)buf, 1000);
378 sha256_finish(&ctx, sha256sum);
379 for (j = 0; j < 32; j++)
380 sprintf(output + j * 2, "%02x", sha256sum[j]);
381 }
382 if (memcmp(output, sha_self_test_vector[i], 64))
383 {
384 failures++;
385 output[sizeof(output) - 1] = '\0';
386 /* printf("sha256_self_test %d failed %s\n", i, output); */
387 }
388 }
389 return failures > 0 ? FAIL : OK;
390}
391
392 static unsigned int
393get_some_time()
394{
Bram Moolenaar80794b12010-06-13 05:20:42 +0200395# ifdef HAVE_GETTIMEOFDAY
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200396 struct timeval tv;
397
398 /* Using usec makes it less predictable. */
399 gettimeofday(&tv, NULL);
400 return (unsigned int)(tv.tv_sec + tv.tv_usec);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200401# else
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200402 return (unsigned int)time(NULL);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200403# endif
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200404}
405
406/*
Bram Moolenaara8ffcbb2010-06-21 06:15:46 +0200407 * Fill "header[header_len]" with random_data.
408 * Also "salt[salt_len]" when "salt" is not NULL.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200409 */
410 void
Bram Moolenaar80794b12010-06-13 05:20:42 +0200411sha2_seed(header, header_len, salt, salt_len)
412 char_u *header;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200413 int header_len;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200414 char_u *salt;
415 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200416{
417 int i;
418 static char_u random_data[1000];
419 char_u sha256sum[32];
420 context_sha256_T ctx;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200421
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200422 srand(get_some_time());
423
424 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
425 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200426 sha256_start(&ctx);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200427 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
428 sha256_finish(&ctx, sha256sum);
429
Bram Moolenaar80794b12010-06-13 05:20:42 +0200430 /* put first block into header. */
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200431 for (i = 0; i < header_len; i++)
432 header[i] = sha256sum[i % sizeof(sha256sum)];
Bram Moolenaar80794b12010-06-13 05:20:42 +0200433
434 /* put remaining block into salt. */
Bram Moolenaara8ffcbb2010-06-21 06:15:46 +0200435 if (salt != NULL)
436 for (i = 0; i < salt_len; i++)
437 salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200438}
439
Bram Moolenaar80794b12010-06-13 05:20:42 +0200440#endif /* FEAT_CRYPT */