comparison src/blowfish.c @ 2184:5028c4d6d825 vim73

Fixed encryption big/little endian test. Use uint32_t to avoid crash on 64 bit machines. Added error numbers for Blowfish errors. Fixed the tiny version not building.
author Bram Moolenaar <bram@vim.org>
date Mon, 17 May 2010 20:32:55 +0200
parents 3cb515c62e9c
children f9aec8acb188
comparison
equal deleted inserted replaced
2182:3cb515c62e9c 2184:5028c4d6d825
1 /* vi:set ts=8 sts=4 sw=4: 1 /* vi:set ts=8 sts=4 sw=4:
2 * 2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * 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 *
3 * Blowfish encryption for Vim; in Blowfish output feedback mode. 9 * Blowfish encryption for Vim; in Blowfish output feedback mode.
4 * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh 10 * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
5 * Based on http://www.schneier.com/blowfish.html by Bruce Schneier. 11 * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
6 */ 12 */
7 13
8 #include "vim.h" 14 #include "vim.h"
9 15
13 19
14 #define BF_BLOCK 8 20 #define BF_BLOCK 8
15 #define BF_OFB_LEN (8*(BF_BLOCK)) 21 #define BF_OFB_LEN (8*(BF_BLOCK))
16 22
17 typedef union { 23 typedef union {
18 long_u ul[2]; 24 uint32_t ul[2];
19 char_u uc[8]; 25 char_u uc[8];
20 } block8; 26 } block8;
21 27
22 #ifdef __BORLANDC__ 28 #ifdef WIN3264
23 # define LITTLE_ENDIAN 29 /* MS-Windows is always little endian */
24 #else 30 #else
25 # if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) 31 # ifdef HAVE_CONFIG_H
26 # if (('1234' >> 24) == '1') 32 /* in configure.in AC_C_BIGENDIAN() defines WORDS_BIGENDIAN when needed */
27 # define LITTLE_ENDIAN 1 33 # else
28 # else 34 error!
29 # if (('4321' >> 24) == '1') 35 Please change this code to define WORDS_BIGENDIAN for big-endian machines.
30 # define BIG_ENDIAN 1
31 # endif
32 # endif
33 # endif 36 # endif
34 #endif 37 #endif
35 38
36 static void bf_e_block __ARGS((long_u *p_xl, long_u *p_xr)); 39 static void bf_e_block __ARGS((uint32_t *p_xl, uint32_t *p_xr));
37 static void bf_e_cblock __ARGS((char_u *block)); 40 static void bf_e_cblock __ARGS((char_u *block));
38 static int bf_check_tables __ARGS((long_u ipa[18], long_u sbi[4][256], long_u val)); 41 static int bf_check_tables __ARGS((uint32_t ipa[18], uint32_t sbi[4][256], uint32_t val));
39 static int bf_self_test __ARGS((void)); 42 static int bf_self_test __ARGS((void));
40 43
41 // Blowfish code 44 // Blowfish code
42 static long_u pax[18]; 45 static uint32_t pax[18];
43 static long_u ipa[18] = { 46 static uint32_t ipa[18] = {
44 0x243f6a88u, 0x85a308d3u, 0x13198a2eu, 47 0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
45 0x03707344u, 0xa4093822u, 0x299f31d0u, 48 0x03707344u, 0xa4093822u, 0x299f31d0u,
46 0x082efa98u, 0xec4e6c89u, 0x452821e6u, 49 0x082efa98u, 0xec4e6c89u, 0x452821e6u,
47 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu, 50 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu,
48 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u, 51 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u,
49 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu 52 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
50 }; 53 };
51 54
52 static long_u sbx[4][256]; 55 static uint32_t sbx[4][256];
53 static long_u sbi[4][256] = { 56 static uint32_t sbi[4][256] = {
54 {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u, 57 {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
55 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u, 58 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
56 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u, 59 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
57 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu, 60 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu,
58 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu, 61 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu,
326 sbx[3][xr&0xFF]; 329 sbx[3][xr&0xFF];
327 330
328 331
329 static void 332 static void
330 bf_e_block(p_xl, p_xr) 333 bf_e_block(p_xl, p_xr)
331 long_u *p_xl; 334 uint32_t *p_xl;
332 long_u *p_xr; 335 uint32_t *p_xr;
333 { 336 {
334 long_u temp, xl = *p_xl, xr = *p_xr; 337 uint32_t temp, xl = *p_xl, xr = *p_xr;
335 338
336 F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7) 339 F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7)
337 F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15) 340 F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15)
338 xl ^= pax[16]; xr ^= pax[17]; 341 xl ^= pax[16]; xr ^= pax[17];
339 temp = xl; xl = xr; xr = temp; 342 temp = xl; xl = xr; xr = temp;
341 } 344 }
342 345
343 #if 0 /* not used */ 346 #if 0 /* not used */
344 static void 347 static void
345 bf_d_block(p_xl, p_xr) 348 bf_d_block(p_xl, p_xr)
346 long_u *p_xl; 349 uint32_t *p_xl;
347 long_u *p_xr; 350 uint32_t *p_xr;
348 { 351 {
349 long_u temp, xl = *p_xl, xr = *p_xr; 352 uint32_t temp, xl = *p_xl, xr = *p_xr;
350 F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10) 353 F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10)
351 F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2) 354 F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2)
352 xl ^= pax[1]; 355 xl ^= pax[1];
353 xr ^= pax[0]; 356 xr ^= pax[0];
354 temp = xl; xl = xr; xr = temp; 357 temp = xl; xl = xr; xr = temp;
355 *p_xl = xl; *p_xr = xr; 358 *p_xl = xl; *p_xr = xr;
356 } 359 }
357 #endif 360 #endif
358 361
359 362
360 #ifdef BIG_ENDIAN 363 #ifdef WORDS_BIGENDIAN
361 # define htonl2(x) \ 364 # define htonl2(x) \
362 x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \ 365 x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \
363 (((x) & 0xff0000L) >> 8) | (((x) & 0xff000000L) >> 24)) 366 (((x) & 0xff0000L) >> 8) | (((x) & 0xff000000L) >> 24))
364 #else 367 #else
365 # define htonl2(x) 368 # define htonl2(x)
395 398
396 void 399 void
397 bf_key_init(password) 400 bf_key_init(password)
398 char_u *password; 401 char_u *password;
399 { 402 {
400 int i, j, keypos = 0; 403 int i, j, keypos = 0;
401 long_u val, data_l, data_r; 404 uint32_t val, data_l, data_r;
402 char_u *key; 405 char_u *key;
403 int keylen; 406 int keylen;
404 407
405 key = sha256_key(password); 408 key = sha256_key(password);
406 keylen = STRLEN(key); 409 keylen = STRLEN(key);
407 for (i = 0; i < 256; ++i) 410 for (i = 0; i < 256; ++i)
408 { 411 {
442 /* 445 /*
443 * BF Self test for corrupted tables or instructions 446 * BF Self test for corrupted tables or instructions
444 */ 447 */
445 static int 448 static int
446 bf_check_tables(ipa, sbi, val) 449 bf_check_tables(ipa, sbi, val)
447 long_u ipa[18]; 450 uint32_t ipa[18];
448 long_u sbi[4][256]; 451 uint32_t sbi[4][256];
449 long_u val; 452 uint32_t val;
450 { 453 {
451 int i, j; 454 int i, j;
452 long_u c = 0; 455 uint32_t c = 0;
453 456
454 for (i = 0; i < 18; i++) 457 for (i = 0; i < 18; i++)
455 c ^= ipa[i]; 458 c ^= ipa[i];
456 for (i = 0; i < 4; i++) 459 for (i = 0; i < 4; i++)
457 for (j = 0; j < 256; j++) 460 for (j = 0; j < 256; j++)
458 c ^= sbi[i][j]; 461 c ^= sbi[i][j];
459 return c == val; 462 return c == val;
460 } 463 }
461 464
462 typedef struct { 465 typedef struct {
463 char_u password[64]; 466 char_u password[64];
464 char_u plaintxt[8]; 467 char_u plaintxt[8];
465 char_u cryptxt[8]; 468 char_u cryptxt[8];
466 long_u keysum; 469 char_u badcryptxt[8]; /* cryptxt when big/little endian is wrong */
470 uint32_t keysum;
467 } struct_bf_test_data; 471 } struct_bf_test_data;
468 472
469 // Assert bf(password, plaintxt) is cryptxt. 473 // Assert bf(password, plaintxt) is cryptxt.
470 // Assert csum(pax sbx(password)) is keysum. 474 // Assert csum(pax sbx(password)) is keysum.
471 static struct_bf_test_data bf_test_data[] = { 475 static struct_bf_test_data bf_test_data[] = {
472 { 476 {
473 "password", 477 "password",
474 "plaintxt", 478 "plaintxt",
475 #if 0 /* This value doesn't work, why??? */
476 "\x55\xca\x56\x3a\xef\xe1\x9c\x73", /* cryptxt */ 479 "\x55\xca\x56\x3a\xef\xe1\x9c\x73", /* cryptxt */
477 #else 480 "\x47\xd9\x67\x49\x91\xc5\x9a\x95", /* badcryptxt */
478 "\x47\xd9\x67\x49\x91\xc5\x9a\x95", /* cryptxt */
479 #endif
480 0x5de01bdbu, /* keysum */ 481 0x5de01bdbu, /* keysum */
481 }, 482 },
482 }; 483 };
483 484
484 /* 485 /*
503 504
504 /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */ 505 /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
505 memcpy(bk.uc, bf_test_data[i].plaintxt, 8); 506 memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
506 bf_e_cblock(bk.uc); 507 bf_e_cblock(bk.uc);
507 if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0) 508 if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
509 {
510 if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
511 EMSG(_("E817: Blowfish big/little endian use wrong"));
508 err++; 512 err++;
513 }
509 } 514 }
510 515
511 return err > 0 ? FAIL : OK; 516 return err > 0 ? FAIL : OK;
512 } 517 }
513 518
565 int 570 int
566 blowfish_self_test() 571 blowfish_self_test()
567 { 572 {
568 if (sha256_self_test() == FAIL) 573 if (sha256_self_test() == FAIL)
569 { 574 {
570 EMSG2(_("E000: sha256 test failed"),""); 575 EMSG(_("E818: sha256 test failed"));
571 return FAIL; 576 return FAIL;
572 } 577 }
573 if (bf_self_test() == FAIL) 578 if (bf_self_test() == FAIL)
574 { 579 {
575 EMSG2(_("E000: Blowfish test failed"),""); 580 EMSG(_("E819: Blowfish test failed"));
576 return FAIL; 581 return FAIL;
577 } 582 }
578 return OK; 583 return OK;
579 } 584 }
580 585