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.