Mercurial > vim
comparison src/blowfish.c @ 6122:18ac55444b37 v7.4.399
updated for version 7.4.399
Problem: Encryption implementation is messy. Blowfish encryption has a
weakness.
Solution: Refactor the encryption, store the state in an allocated struct
instead of using a save/restore mechanism. Introduce the
"blowfish2" method, which does not have the weakness and encrypts
the whole undo file. (largely by David Leadbeater)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sun, 10 Aug 2014 13:38:34 +0200 |
parents | 391e10afccf6 |
children | 1a5d34492798 |
comparison
equal
deleted
inserted
replaced
6121:913d16b4904c | 6122:18ac55444b37 |
---|---|
7 * See README.txt for an overview of the Vim source code. | 7 * See README.txt for an overview of the Vim source code. |
8 * | 8 * |
9 * Blowfish encryption for Vim; in Blowfish cipher feedback mode. | 9 * Blowfish encryption for Vim; in Blowfish cipher feedback mode. |
10 * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh | 10 * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh |
11 * Based on http://www.schneier.com/blowfish.html by Bruce Schneier. | 11 * Based on http://www.schneier.com/blowfish.html by Bruce Schneier. |
12 * | |
13 * There are two variants: | |
14 * - The old one "blowfish" has a flaw which makes it much easier to crack the | |
15 * key. To see this, make a text file with one line of 1000 "x" characters | |
16 * and write it encrypted. Use "xxd" to inspect the bytes in the file. You | |
17 * will see that a block of 8 bytes repeats 8 times. | |
18 * - The new one "blowfish2" is better. It uses an 8 byte CFB to avoid the | |
19 * repeats. | |
12 */ | 20 */ |
13 | 21 |
14 #include "vim.h" | 22 #include "vim.h" |
15 | 23 |
16 #if defined(FEAT_CRYPT) | 24 #if defined(FEAT_CRYPT) || defined(PROTO) |
17 | 25 |
18 #define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0])) | 26 #define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0])) |
19 | 27 |
20 #define BF_BLOCK 8 | 28 #define BF_BLOCK 8 |
21 #define BF_BLOCK_MASK 7 | 29 #define BF_BLOCK_MASK 7 |
22 #define BF_CFB_LEN (8*(BF_BLOCK)) | 30 #define BF_MAX_CFB_LEN (8 * BF_BLOCK) |
23 | 31 |
24 typedef union { | 32 typedef union { |
25 UINT32_T ul[2]; | 33 UINT32_T ul[2]; |
26 char_u uc[8]; | 34 char_u uc[8]; |
27 } block8; | 35 } block8; |
35 error! | 43 error! |
36 Please change this code to define WORDS_BIGENDIAN for big-endian machines. | 44 Please change this code to define WORDS_BIGENDIAN for big-endian machines. |
37 # endif | 45 # endif |
38 #endif | 46 #endif |
39 | 47 |
40 static void bf_e_block __ARGS((UINT32_T *p_xl, UINT32_T *p_xr)); | 48 /* The state of encryption, referenced by cryptstate_T. */ |
41 static void bf_e_cblock __ARGS((char_u *block)); | 49 typedef struct { |
42 static int bf_check_tables __ARGS((UINT32_T a_ipa[18], UINT32_T a_sbi[4][256], UINT32_T val)); | 50 UINT32_T pax[18]; /* P-array */ |
51 UINT32_T sbx[4][256]; /* S-boxes */ | |
52 int randbyte_offset; | |
53 int update_offset; | |
54 char_u cfb_buffer[BF_MAX_CFB_LEN]; /* up to 64 bytes used */ | |
55 int cfb_len; /* size of cfb_buffer actually used */ | |
56 } bf_state_T; | |
57 | |
58 | |
59 static void bf_e_block __ARGS((bf_state_T *state, UINT32_T *p_xl, UINT32_T *p_xr)); | |
60 static void bf_e_cblock __ARGS((bf_state_T *state, char_u *block)); | |
61 static int bf_check_tables __ARGS((UINT32_T pax[18], UINT32_T sbx[4][256], UINT32_T val)); | |
43 static int bf_self_test __ARGS((void)); | 62 static int bf_self_test __ARGS((void)); |
63 static void bf_key_init __ARGS((bf_state_T *state, char_u *password, char_u *salt, int salt_len)); | |
64 static void bf_cfb_init __ARGS((bf_state_T *state, char_u *seed, int seed_len)); | |
44 | 65 |
45 /* Blowfish code */ | 66 /* Blowfish code */ |
46 static UINT32_T pax[18]; | 67 static UINT32_T pax_init[18] = { |
47 static UINT32_T ipa[18] = { | |
48 0x243f6a88u, 0x85a308d3u, 0x13198a2eu, | 68 0x243f6a88u, 0x85a308d3u, 0x13198a2eu, |
49 0x03707344u, 0xa4093822u, 0x299f31d0u, | 69 0x03707344u, 0xa4093822u, 0x299f31d0u, |
50 0x082efa98u, 0xec4e6c89u, 0x452821e6u, | 70 0x082efa98u, 0xec4e6c89u, 0x452821e6u, |
51 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu, | 71 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu, |
52 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u, | 72 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u, |
53 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu | 73 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu |
54 }; | 74 }; |
55 | 75 |
56 static UINT32_T sbx[4][256]; | 76 static UINT32_T sbx_init[4][256] = { |
57 static UINT32_T sbi[4][256] = { | |
58 {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u, | 77 {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u, |
59 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u, | 78 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u, |
60 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u, | 79 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u, |
61 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu, | 80 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu, |
62 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu, | 81 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu, |
312 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu, | 331 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu, |
313 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u | 332 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u |
314 } | 333 } |
315 }; | 334 }; |
316 | 335 |
317 | |
318 #define F1(i) \ | 336 #define F1(i) \ |
319 xl ^= pax[i]; \ | 337 xl ^= bfs->pax[i]; \ |
320 xr ^= ((sbx[0][xl >> 24] + \ | 338 xr ^= ((bfs->sbx[0][xl >> 24] + \ |
321 sbx[1][(xl & 0xFF0000) >> 16]) ^ \ | 339 bfs->sbx[1][(xl & 0xFF0000) >> 16]) ^ \ |
322 sbx[2][(xl & 0xFF00) >> 8]) + \ | 340 bfs->sbx[2][(xl & 0xFF00) >> 8]) + \ |
323 sbx[3][xl & 0xFF]; | 341 bfs->sbx[3][xl & 0xFF]; |
324 | 342 |
325 #define F2(i) \ | 343 #define F2(i) \ |
326 xr ^= pax[i]; \ | 344 xr ^= bfs->pax[i]; \ |
327 xl ^= ((sbx[0][xr >> 24] + \ | 345 xl ^= ((bfs->sbx[0][xr >> 24] + \ |
328 sbx[1][(xr & 0xFF0000) >> 16]) ^ \ | 346 bfs->sbx[1][(xr & 0xFF0000) >> 16]) ^ \ |
329 sbx[2][(xr & 0xFF00) >> 8]) + \ | 347 bfs->sbx[2][(xr & 0xFF00) >> 8]) + \ |
330 sbx[3][xr & 0xFF]; | 348 bfs->sbx[3][xr & 0xFF]; |
331 | |
332 | 349 |
333 static void | 350 static void |
334 bf_e_block(p_xl, p_xr) | 351 bf_e_block(bfs, p_xl, p_xr) |
352 bf_state_T *bfs; | |
335 UINT32_T *p_xl; | 353 UINT32_T *p_xl; |
336 UINT32_T *p_xr; | 354 UINT32_T *p_xr; |
337 { | 355 { |
338 UINT32_T temp, xl = *p_xl, xr = *p_xr; | 356 UINT32_T temp; |
339 | 357 UINT32_T xl = *p_xl; |
340 F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7) | 358 UINT32_T xr = *p_xr; |
341 F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15) | 359 |
342 xl ^= pax[16]; | 360 F1(0) F2(1) |
343 xr ^= pax[17]; | 361 F1(2) F2(3) |
362 F1(4) F2(5) | |
363 F1(6) F2(7) | |
364 F1(8) F2(9) | |
365 F1(10) F2(11) | |
366 F1(12) F2(13) | |
367 F1(14) F2(15) | |
368 xl ^= bfs->pax[16]; | |
369 xr ^= bfs->pax[17]; | |
344 temp = xl; | 370 temp = xl; |
345 xl = xr; | 371 xl = xr; |
346 xr = temp; | 372 xr = temp; |
347 *p_xl = xl; | 373 *p_xl = xl; |
348 *p_xr = xr; | 374 *p_xr = xr; |
349 } | 375 } |
350 | |
351 #if 0 /* not used */ | |
352 static void | |
353 bf_d_block(p_xl, p_xr) | |
354 UINT32_T *p_xl; | |
355 UINT32_T *p_xr; | |
356 { | |
357 UINT32_T temp, xl = *p_xl, xr = *p_xr; | |
358 F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10) | |
359 F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2) | |
360 xl ^= pax[1]; | |
361 xr ^= pax[0]; | |
362 temp = xl; xl = xr; xr = temp; | |
363 *p_xl = xl; *p_xr = xr; | |
364 } | |
365 #endif | |
366 | 376 |
367 | 377 |
368 #ifdef WORDS_BIGENDIAN | 378 #ifdef WORDS_BIGENDIAN |
369 # define htonl2(x) \ | 379 # define htonl2(x) \ |
370 x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \ | 380 x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \ |
372 #else | 382 #else |
373 # define htonl2(x) | 383 # define htonl2(x) |
374 #endif | 384 #endif |
375 | 385 |
376 static void | 386 static void |
377 bf_e_cblock(block) | 387 bf_e_cblock(bfs, block) |
388 bf_state_T *bfs; | |
378 char_u *block; | 389 char_u *block; |
379 { | 390 { |
380 block8 bk; | 391 block8 bk; |
381 | 392 |
382 memcpy(bk.uc, block, 8); | 393 memcpy(bk.uc, block, 8); |
383 htonl2(bk.ul[0]); | 394 htonl2(bk.ul[0]); |
384 htonl2(bk.ul[1]); | 395 htonl2(bk.ul[1]); |
385 bf_e_block(&bk.ul[0], &bk.ul[1]); | 396 bf_e_block(bfs, &bk.ul[0], &bk.ul[1]); |
386 htonl2(bk.ul[0]); | 397 htonl2(bk.ul[0]); |
387 htonl2(bk.ul[1]); | 398 htonl2(bk.ul[1]); |
388 memcpy(block, bk.uc, 8); | 399 memcpy(block, bk.uc, 8); |
389 } | 400 } |
390 | 401 |
391 #if 0 /* not used */ | |
392 void | |
393 bf_d_cblock(block) | |
394 char_u *block; | |
395 { | |
396 block8 bk; | |
397 memcpy(bk.uc, block, 8); | |
398 htonl2(bk.ul[0]); htonl2(bk.ul[1]); | |
399 bf_d_block(&bk.ul[0], &bk.ul[1]); | |
400 htonl2(bk.ul[0]); htonl2(bk.ul[1]); | |
401 memcpy(block, bk.uc, 8); | |
402 } | |
403 #endif | |
404 | |
405 /* | 402 /* |
406 * Initialize the crypt method using "password" as the encryption key and | 403 * Initialize the crypt method using "password" as the encryption key and |
407 * "salt[salt_len]" as the salt. | 404 * "salt[salt_len]" as the salt. |
408 */ | 405 */ |
409 void | 406 static void |
410 bf_key_init(password, salt, salt_len) | 407 bf_key_init(bfs, password, salt, salt_len) |
411 char_u *password; | 408 bf_state_T *bfs; |
412 char_u *salt; | 409 char_u *password; |
413 int salt_len; | 410 char_u *salt; |
411 int salt_len; | |
414 { | 412 { |
415 int i, j, keypos = 0; | 413 int i, j, keypos = 0; |
416 unsigned u; | 414 unsigned u; |
417 UINT32_T val, data_l, data_r; | 415 UINT32_T val, data_l, data_r; |
418 char_u *key; | 416 char_u *key; |
419 int keylen; | 417 int keylen; |
420 | 418 |
421 /* Process the key 1000 times. | 419 /* Process the key 1001 times. |
422 * See http://en.wikipedia.org/wiki/Key_strengthening. */ | 420 * See http://en.wikipedia.org/wiki/Key_strengthening. */ |
423 key = sha256_key(password, salt, salt_len); | 421 key = sha256_key(password, salt, salt_len); |
424 for (i = 0; i < 1000; i++) | 422 for (i = 0; i < 1000; i++) |
425 key = sha256_key(key, salt, salt_len); | 423 key = sha256_key(key, salt, salt_len); |
426 | 424 |
435 { | 433 { |
436 sscanf((char *)&key[i * 2], "%2x", &u); | 434 sscanf((char *)&key[i * 2], "%2x", &u); |
437 key[i] = u; | 435 key[i] = u; |
438 } | 436 } |
439 | 437 |
440 mch_memmove(sbx, sbi, 4 * 4 * 256); | 438 /* Use "key" to initialize the P-array ("pax") and S-boxes ("sbx") of |
439 * Blowfish. */ | |
440 mch_memmove(bfs->sbx, sbx_init, 4 * 4 * 256); | |
441 | 441 |
442 for (i = 0; i < 18; ++i) | 442 for (i = 0; i < 18; ++i) |
443 { | 443 { |
444 val = 0; | 444 val = 0; |
445 for (j = 0; j < 4; ++j) | 445 for (j = 0; j < 4; ++j) |
446 val = (val << 8) | key[keypos++ % keylen]; | 446 val = (val << 8) | key[keypos++ % keylen]; |
447 pax[i] = ipa[i] ^ val; | 447 bfs->pax[i] = pax_init[i] ^ val; |
448 } | 448 } |
449 | 449 |
450 data_l = data_r = 0; | 450 data_l = data_r = 0; |
451 for (i = 0; i < 18; i += 2) | 451 for (i = 0; i < 18; i += 2) |
452 { | 452 { |
453 bf_e_block(&data_l, &data_r); | 453 bf_e_block(bfs, &data_l, &data_r); |
454 pax[i + 0] = data_l; | 454 bfs->pax[i + 0] = data_l; |
455 pax[i + 1] = data_r; | 455 bfs->pax[i + 1] = data_r; |
456 } | 456 } |
457 | 457 |
458 for (i = 0; i < 4; ++i) | 458 for (i = 0; i < 4; ++i) |
459 { | 459 { |
460 for (j = 0; j < 256; j += 2) | 460 for (j = 0; j < 256; j += 2) |
461 { | 461 { |
462 bf_e_block(&data_l, &data_r); | 462 bf_e_block(bfs, &data_l, &data_r); |
463 sbx[i][j + 0] = data_l; | 463 bfs->sbx[i][j + 0] = data_l; |
464 sbx[i][j + 1] = data_r; | 464 bfs->sbx[i][j + 1] = data_r; |
465 } | 465 } |
466 } | 466 } |
467 } | 467 } |
468 | 468 |
469 /* | 469 /* |
470 * BF Self test for corrupted tables or instructions | 470 * Blowfish self-test for corrupted tables or instructions. |
471 */ | 471 */ |
472 static int | 472 static int |
473 bf_check_tables(a_ipa, a_sbi, val) | 473 bf_check_tables(pax, sbx, val) |
474 UINT32_T a_ipa[18]; | 474 UINT32_T pax[18]; |
475 UINT32_T a_sbi[4][256]; | 475 UINT32_T sbx[4][256]; |
476 UINT32_T val; | 476 UINT32_T val; |
477 { | 477 { |
478 int i, j; | 478 int i, j; |
479 UINT32_T c = 0; | 479 UINT32_T c = 0; |
480 | 480 |
481 for (i = 0; i < 18; i++) | 481 for (i = 0; i < 18; i++) |
482 c ^= a_ipa[i]; | 482 c ^= pax[i]; |
483 for (i = 0; i < 4; i++) | 483 for (i = 0; i < 4; i++) |
484 for (j = 0; j < 256; j++) | 484 for (j = 0; j < 256; j++) |
485 c ^= a_sbi[i][j]; | 485 c ^= sbx[i][j]; |
486 return c == val; | 486 return c == val; |
487 } | 487 } |
488 | 488 |
489 typedef struct { | 489 typedef struct { |
490 char_u password[64]; | 490 char_u password[64]; |
518 { | 518 { |
519 int i, bn; | 519 int i, bn; |
520 int err = 0; | 520 int err = 0; |
521 block8 bk; | 521 block8 bk; |
522 UINT32_T ui = 0xffffffffUL; | 522 UINT32_T ui = 0xffffffffUL; |
523 bf_state_T state; | |
524 | |
525 vim_memset(&state, 0, sizeof(bf_state_T)); | |
526 state.cfb_len = BF_MAX_CFB_LEN; | |
523 | 527 |
524 /* We can't simply use sizeof(UINT32_T), it would generate a compiler | 528 /* We can't simply use sizeof(UINT32_T), it would generate a compiler |
525 * warning. */ | 529 * warning. */ |
526 if (ui != 0xffffffffUL || ui + 1 != 0) { | 530 if (ui != 0xffffffffUL || ui + 1 != 0) { |
527 err++; | 531 err++; |
528 EMSG(_("E820: sizeof(uint32_t) != 4")); | 532 EMSG(_("E820: sizeof(uint32_t) != 4")); |
529 } | 533 } |
530 | 534 |
531 if (!bf_check_tables(ipa, sbi, 0x6ffa520a)) | 535 if (!bf_check_tables(pax_init, sbx_init, 0x6ffa520a)) |
532 err++; | 536 err++; |
533 | 537 |
534 bn = ARRAY_LENGTH(bf_test_data); | 538 bn = ARRAY_LENGTH(bf_test_data); |
535 for (i = 0; i < bn; i++) | 539 for (i = 0; i < bn; i++) |
536 { | 540 { |
537 bf_key_init((char_u *)(bf_test_data[i].password), | 541 bf_key_init(&state, (char_u *)(bf_test_data[i].password), |
538 bf_test_data[i].salt, | 542 bf_test_data[i].salt, |
539 (int)STRLEN(bf_test_data[i].salt)); | 543 (int)STRLEN(bf_test_data[i].salt)); |
540 if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum)) | 544 if (!bf_check_tables(state.pax, state.sbx, bf_test_data[i].keysum)) |
541 err++; | 545 err++; |
542 | 546 |
543 /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */ | 547 /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */ |
544 memcpy(bk.uc, bf_test_data[i].plaintxt, 8); | 548 memcpy(bk.uc, bf_test_data[i].plaintxt, 8); |
545 bf_e_cblock(bk.uc); | 549 bf_e_cblock(&state, bk.uc); |
546 if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0) | 550 if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0) |
547 { | 551 { |
548 if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0) | 552 if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0) |
549 EMSG(_("E817: Blowfish big/little endian use wrong")); | 553 EMSG(_("E817: Blowfish big/little endian use wrong")); |
550 err++; | 554 err++; |
552 } | 556 } |
553 | 557 |
554 return err > 0 ? FAIL : OK; | 558 return err > 0 ? FAIL : OK; |
555 } | 559 } |
556 | 560 |
557 /* Cipher feedback mode. */ | 561 /* |
558 static int randbyte_offset = 0; | 562 * CFB: Cipher Feedback Mode. |
559 static int update_offset = 0; | 563 */ |
560 static char_u cfb_buffer[BF_CFB_LEN]; /* 64 bytes */ | 564 |
561 | 565 /* |
562 /* | 566 * Initialize with seed "seed[seed_len]". |
563 * Initialize with seed "iv[iv_len]". | 567 */ |
564 */ | 568 static void |
565 void | 569 bf_cfb_init(bfs, seed, seed_len) |
566 bf_cfb_init(iv, iv_len) | 570 bf_state_T *bfs; |
567 char_u *iv; | 571 char_u *seed; |
568 int iv_len; | 572 int seed_len; |
569 { | 573 { |
570 int i, mi; | 574 int i, mi; |
571 | 575 |
572 randbyte_offset = update_offset = 0; | 576 bfs->randbyte_offset = bfs->update_offset = 0; |
573 vim_memset(cfb_buffer, 0, BF_CFB_LEN); | 577 vim_memset(bfs->cfb_buffer, 0, bfs->cfb_len); |
574 if (iv_len > 0) | 578 if (seed_len > 0) |
575 { | 579 { |
576 mi = iv_len > BF_CFB_LEN ? iv_len : BF_CFB_LEN; | 580 mi = seed_len > bfs->cfb_len ? seed_len : bfs->cfb_len; |
577 for (i = 0; i < mi; i++) | 581 for (i = 0; i < mi; i++) |
578 cfb_buffer[i % BF_CFB_LEN] ^= iv[i % iv_len]; | 582 bfs->cfb_buffer[i % bfs->cfb_len] ^= seed[i % seed_len]; |
579 } | 583 } |
580 } | 584 } |
581 | 585 |
582 #define BF_CFB_UPDATE(c) { \ | 586 #define BF_CFB_UPDATE(bfs, c) { \ |
583 cfb_buffer[update_offset] ^= (char_u)c; \ | 587 bfs->cfb_buffer[bfs->update_offset] ^= (char_u)c; \ |
584 if (++update_offset == BF_CFB_LEN) \ | 588 if (++bfs->update_offset == bfs->cfb_len) \ |
585 update_offset = 0; \ | 589 bfs->update_offset = 0; \ |
586 } | 590 } |
587 | 591 |
588 #define BF_RANBYTE(t) { \ | 592 #define BF_RANBYTE(bfs, t) { \ |
589 if ((randbyte_offset & BF_BLOCK_MASK) == 0) \ | 593 if ((bfs->randbyte_offset & BF_BLOCK_MASK) == 0) \ |
590 bf_e_cblock(&cfb_buffer[randbyte_offset]); \ | 594 bf_e_cblock(bfs, &(bfs->cfb_buffer[bfs->randbyte_offset])); \ |
591 t = cfb_buffer[randbyte_offset]; \ | 595 t = bfs->cfb_buffer[bfs->randbyte_offset]; \ |
592 if (++randbyte_offset == BF_CFB_LEN) \ | 596 if (++bfs->randbyte_offset == bfs->cfb_len) \ |
593 randbyte_offset = 0; \ | 597 bfs->randbyte_offset = 0; \ |
594 } | 598 } |
595 | 599 |
596 /* | 600 /* |
597 * Encrypt "from[len]" into "to[len]". | 601 * Encrypt "from[len]" into "to[len]". |
598 * "from" and "to" can be equal to encrypt in place. | 602 * "from" and "to" can be equal to encrypt in place. |
599 */ | 603 */ |
600 void | 604 void |
601 bf_crypt_encode(from, len, to) | 605 crypt_blowfish_encode(state, from, len, to) |
606 cryptstate_T *state; | |
602 char_u *from; | 607 char_u *from; |
603 size_t len; | 608 size_t len; |
604 char_u *to; | 609 char_u *to; |
605 { | 610 { |
611 bf_state_T *bfs = state->method_state; | |
606 size_t i; | 612 size_t i; |
607 int ztemp, t; | 613 int ztemp, t; |
608 | 614 |
609 for (i = 0; i < len; ++i) | 615 for (i = 0; i < len; ++i) |
610 { | 616 { |
611 ztemp = from[i]; | 617 ztemp = from[i]; |
612 BF_RANBYTE(t); | 618 BF_RANBYTE(bfs, t); |
613 BF_CFB_UPDATE(ztemp); | 619 BF_CFB_UPDATE(bfs, ztemp); |
614 to[i] = t ^ ztemp; | 620 to[i] = t ^ ztemp; |
615 } | 621 } |
616 } | 622 } |
617 | 623 |
618 /* | 624 /* |
619 * Decrypt "ptr[len]" in place. | 625 * Decrypt "from[len]" into "to[len]". |
620 */ | 626 */ |
621 void | 627 void |
622 bf_crypt_decode(ptr, len) | 628 crypt_blowfish_decode(state, from, len, to) |
623 char_u *ptr; | 629 cryptstate_T *state; |
624 long len; | 630 char_u *from; |
625 { | 631 size_t len; |
626 char_u *p; | 632 char_u *to; |
633 { | |
634 bf_state_T *bfs = state->method_state; | |
635 size_t i; | |
627 int t; | 636 int t; |
628 | 637 |
629 for (p = ptr; p < ptr + len; ++p) | 638 for (i = 0; i < len; ++i) |
630 { | 639 { |
631 BF_RANBYTE(t); | 640 BF_RANBYTE(bfs, t); |
632 *p ^= t; | 641 to[i] = from[i] ^ t; |
633 BF_CFB_UPDATE(*p); | 642 BF_CFB_UPDATE(bfs, to[i]); |
634 } | 643 } |
635 } | 644 } |
636 | 645 |
637 /* | |
638 * Initialize the encryption keys and the random header according to | |
639 * the given password. | |
640 */ | |
641 void | 646 void |
642 bf_crypt_init_keys(passwd) | 647 crypt_blowfish_init(state, key, salt, salt_len, seed, seed_len) |
643 char_u *passwd; /* password string with which to modify keys */ | 648 cryptstate_T *state; |
644 { | 649 char_u* key; |
645 char_u *p; | 650 char_u* salt; |
646 | 651 int salt_len; |
647 for (p = passwd; *p != NUL; ++p) | 652 char_u* seed; |
648 { | 653 int seed_len; |
649 BF_CFB_UPDATE(*p); | 654 { |
650 } | 655 bf_state_T *bfs = (bf_state_T *)alloc_clear(sizeof(bf_state_T)); |
651 } | 656 |
652 | 657 state->method_state = bfs; |
653 static int save_randbyte_offset; | 658 |
654 static int save_update_offset; | 659 /* "blowfish" uses a 64 byte buffer, causing it to repeat 8 byte groups 8 |
655 static char_u save_cfb_buffer[BF_CFB_LEN]; | 660 * times. "blowfish2" uses a 8 byte buffer to avoid repeating. */ |
656 static UINT32_T save_pax[18]; | 661 bfs->cfb_len = state->method_nr == CRYPT_M_BF ? BF_MAX_CFB_LEN : BF_BLOCK; |
657 static UINT32_T save_sbx[4][256]; | 662 |
658 | 663 if (blowfish_self_test() == FAIL) |
659 /* | 664 return; |
660 * Save the current crypt state. Can only be used once before | 665 |
661 * bf_crypt_restore(). | 666 bf_key_init(bfs, key, salt, salt_len); |
662 */ | 667 bf_cfb_init(bfs, seed, seed_len); |
663 void | |
664 bf_crypt_save() | |
665 { | |
666 save_randbyte_offset = randbyte_offset; | |
667 save_update_offset = update_offset; | |
668 mch_memmove(save_cfb_buffer, cfb_buffer, BF_CFB_LEN); | |
669 mch_memmove(save_pax, pax, 4 * 18); | |
670 mch_memmove(save_sbx, sbx, 4 * 4 * 256); | |
671 } | |
672 | |
673 /* | |
674 * Restore the current crypt state. Can only be used after | |
675 * bf_crypt_save(). | |
676 */ | |
677 void | |
678 bf_crypt_restore() | |
679 { | |
680 randbyte_offset = save_randbyte_offset; | |
681 update_offset = save_update_offset; | |
682 mch_memmove(cfb_buffer, save_cfb_buffer, BF_CFB_LEN); | |
683 mch_memmove(pax, save_pax, 4 * 18); | |
684 mch_memmove(sbx, save_sbx, 4 * 4 * 256); | |
685 } | 668 } |
686 | 669 |
687 /* | 670 /* |
688 * Run a test to check if the encryption works as expected. | 671 * Run a test to check if the encryption works as expected. |
689 * Give an error and return FAIL when not. | 672 * Give an error and return FAIL when not. |