blob: d65b72c0f0d3709197b39696a608269332ab9da2 [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 Moolenaarbaaa7e92016-01-29 22:47:03 +010027static void sha256_process(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)
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +0100276static unsigned int get_some_time(void);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200277
Bram Moolenaar823a1652010-05-16 23:02:33 +0200278/*
Bram Moolenaar80794b12010-06-13 05:20:42 +0200279 * Returns hex digest of "buf[buf_len]" in a static array.
280 * if "salt" is not NULL also do "salt[salt_len]".
Bram Moolenaar823a1652010-05-16 23:02:33 +0200281 */
Bram Moolenaaraf9aeb92013-02-13 17:35:04 +0100282 char_u *
Bram Moolenaar80794b12010-06-13 05:20:42 +0200283sha256_bytes(buf, buf_len, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200284 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200285 int buf_len;
286 char_u *salt;
287 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200288{
289 char_u sha256sum[32];
Bram Moolenaar823a1652010-05-16 23:02:33 +0200290 static char_u hexit[65];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200291 int j;
292 context_sha256_T ctx;
293
294 sha256_self_test();
295
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200296 sha256_start(&ctx);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200297 sha256_update(&ctx, buf, buf_len);
298 if (salt != NULL)
299 sha256_update(&ctx, salt, salt_len);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200300 sha256_finish(&ctx, sha256sum);
301 for (j = 0; j < 32; j++)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200302 sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200303 hexit[sizeof(hexit) - 1] = '\0';
304 return hexit;
305}
306
307/*
Bram Moolenaar823a1652010-05-16 23:02:33 +0200308 * Returns sha256(buf) as 64 hex chars in static array.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200309 */
Bram Moolenaar823a1652010-05-16 23:02:33 +0200310 char_u *
Bram Moolenaar80794b12010-06-13 05:20:42 +0200311sha256_key(buf, salt, salt_len)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200312 char_u *buf;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200313 char_u *salt;
314 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200315{
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200316 /* No passwd means don't encrypt */
317 if (buf == NULL || *buf == NUL)
Bram Moolenaar823a1652010-05-16 23:02:33 +0200318 return (char_u *)"";
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200319
Bram Moolenaar80794b12010-06-13 05:20:42 +0200320 return sha256_bytes(buf, (int)STRLEN(buf), salt, salt_len);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200321}
322
323/*
324 * These are the standard FIPS-180-2 test vectors
325 */
326
327static char *sha_self_test_msg[] = {
328 "abc",
329 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
330 NULL
331};
332
333static char *sha_self_test_vector[] = {
334 "ba7816bf8f01cfea414140de5dae2223" \
335 "b00361a396177a9cb410ff61f20015ad",
336 "248d6a61d20638b8e5c026930c3e6039" \
337 "a33ce45964ff2167f6ecedd419db06c1",
338 "cdc76e5c9914fb9281a1c7e284d73e67" \
339 "f1809a48a497200e046d39ccc7112cd0"
340};
341
342/*
343 * Perform a test on the SHA256 algorithm.
344 * Return FAIL or OK.
345 */
346 int
347sha256_self_test()
348{
349 int i, j;
350 char output[65];
351 context_sha256_T ctx;
352 char_u buf[1000];
353 char_u sha256sum[32];
354 static int failures = 0;
Bram Moolenaar823a1652010-05-16 23:02:33 +0200355 char_u *hexit;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200356 static int sha256_self_tested = 0;
357
358 if (sha256_self_tested > 0)
359 return failures > 0 ? FAIL : OK;
360 sha256_self_tested = 1;
361
362 for (i = 0; i < 3; i++)
363 {
364 if (i < 2)
365 {
Bram Moolenaar823a1652010-05-16 23:02:33 +0200366 hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
Bram Moolenaar80794b12010-06-13 05:20:42 +0200367 (int)STRLEN(sha_self_test_msg[i]),
368 NULL, 0);
Bram Moolenaar823a1652010-05-16 23:02:33 +0200369 STRCPY(output, hexit);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200370 }
371 else
372 {
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200373 sha256_start(&ctx);
Bram Moolenaar7db5fc82010-05-24 11:59:29 +0200374 vim_memset(buf, 'a', 1000);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200375 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
392get_some_time()
393{
Bram Moolenaar80794b12010-06-13 05:20:42 +0200394# ifdef HAVE_GETTIMEOFDAY
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200395 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);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200400# else
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200401 return (unsigned int)time(NULL);
Bram Moolenaar80794b12010-06-13 05:20:42 +0200402# endif
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200403}
404
405/*
Bram Moolenaara8ffcbb2010-06-21 06:15:46 +0200406 * Fill "header[header_len]" with random_data.
407 * Also "salt[salt_len]" when "salt" is not NULL.
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200408 */
409 void
Bram Moolenaar80794b12010-06-13 05:20:42 +0200410sha2_seed(header, header_len, salt, salt_len)
411 char_u *header;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200412 int header_len;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200413 char_u *salt;
414 int salt_len;
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200415{
416 int i;
417 static char_u random_data[1000];
418 char_u sha256sum[32];
419 context_sha256_T ctx;
Bram Moolenaar80794b12010-06-13 05:20:42 +0200420
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200421 srand(get_some_time());
422
423 for (i = 0; i < (int)sizeof(random_data) - 1; i++)
424 random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
Bram Moolenaar55debbe2010-05-23 23:34:36 +0200425 sha256_start(&ctx);
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200426 sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
427 sha256_finish(&ctx, sha256sum);
428
Bram Moolenaar80794b12010-06-13 05:20:42 +0200429 /* put first block into header. */
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200430 for (i = 0; i < header_len; i++)
431 header[i] = sha256sum[i % sizeof(sha256sum)];
Bram Moolenaar80794b12010-06-13 05:20:42 +0200432
433 /* put remaining block into salt. */
Bram Moolenaara8ffcbb2010-06-21 06:15:46 +0200434 if (salt != NULL)
435 for (i = 0; i < salt_len; i++)
436 salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)];
Bram Moolenaar40e6a712010-05-16 22:32:54 +0200437}
438
Bram Moolenaar80794b12010-06-13 05:20:42 +0200439#endif /* FEAT_CRYPT */