Mercurial > dropbear
comparison libtomcrypt/src/ciphers/twofish/twofish.c @ 382:0cbe8f6dbf9e
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f)
to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 11 Jan 2007 02:41:05 +0000 |
parents | 1b9e69c058d2 |
children | eef377591301 |
comparison
equal
deleted
inserted
replaced
379:b66a00272a90 | 382:0cbe8f6dbf9e |
---|---|
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | 8 * |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | 9 * Tom St Denis, [email protected], http://libtomcrypt.com |
10 */ | 10 */ |
11 | 11 |
12 /** | 12 /** |
13 @file twofish.c | 13 @file twofish.c |
14 Implementation of Twofish by Tom St Denis | 14 Implementation of Twofish by Tom St Denis |
33 &twofish_ecb_encrypt, | 33 &twofish_ecb_encrypt, |
34 &twofish_ecb_decrypt, | 34 &twofish_ecb_decrypt, |
35 &twofish_test, | 35 &twofish_test, |
36 &twofish_done, | 36 &twofish_done, |
37 &twofish_keysize, | 37 &twofish_keysize, |
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL | 38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL |
39 }; | 39 }; |
40 | 40 |
41 /* the two polynomials */ | 41 /* the two polynomials */ |
42 #define MDS_POLY 0x169 | 42 #define MDS_POLY 0x169 |
43 #define RS_POLY 0x14D | 43 #define RS_POLY 0x14D |
412 | 412 |
413 #ifndef TWOFISH_SMALL | 413 #ifndef TWOFISH_SMALL |
414 /* make the sboxes (large ram variant) */ | 414 /* make the sboxes (large ram variant) */ |
415 if (k == 2) { | 415 if (k == 2) { |
416 for (x = 0; x < 256; x++) { | 416 for (x = 0; x < 256; x++) { |
417 tmpx0 = sbox(0, x); | 417 tmpx0 = (unsigned char)sbox(0, x); |
418 tmpx1 = sbox(1, x); | 418 tmpx1 = (unsigned char)sbox(1, x); |
419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); | 419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); |
420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); | 420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); |
421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); | 421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); |
422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); | 422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); |
423 } | 423 } |
424 } else if (k == 3) { | 424 } else if (k == 3) { |
425 for (x = 0; x < 256; x++) { | 425 for (x = 0; x < 256; x++) { |
426 tmpx0 = sbox(0, x); | 426 tmpx0 = (unsigned char)sbox(0, x); |
427 tmpx1 = sbox(1, x); | 427 tmpx1 = (unsigned char)sbox(1, x); |
428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); | 428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); |
429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); | 429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); |
430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); | 430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); |
431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); | 431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); |
432 } | 432 } |
433 } else { | 433 } else { |
434 for (x = 0; x < 256; x++) { | 434 for (x = 0; x < 256; x++) { |
435 tmpx0 = sbox(0, x); | 435 tmpx0 = (unsigned char)sbox(0, x); |
436 tmpx1 = sbox(1, x); | 436 tmpx1 = (unsigned char)sbox(1, x); |
437 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); | 437 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); |
438 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); | 438 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); |
439 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); | 439 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); |
440 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); | 440 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); |
441 } | 441 } |
465 /** | 465 /** |
466 Encrypts a block of text with Twofish | 466 Encrypts a block of text with Twofish |
467 @param pt The input plaintext (16 bytes) | 467 @param pt The input plaintext (16 bytes) |
468 @param ct The output ciphertext (16 bytes) | 468 @param ct The output ciphertext (16 bytes) |
469 @param skey The key as scheduled | 469 @param skey The key as scheduled |
470 @return CRYPT_OK if successful | |
470 */ | 471 */ |
471 #ifdef LTC_CLEAN_STACK | 472 #ifdef LTC_CLEAN_STACK |
472 static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | 473 static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) |
473 #else | 474 #else |
474 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | 475 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) |
475 #endif | 476 #endif |
476 { | 477 { |
477 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; | 478 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; |
478 int r; | 479 int r; |
479 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) | 480 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) |
519 td = b ^ skey->twofish.K[7]; | 520 td = b ^ skey->twofish.K[7]; |
520 | 521 |
521 /* store output */ | 522 /* store output */ |
522 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); | 523 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); |
523 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); | 524 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); |
524 } | 525 |
525 | 526 return CRYPT_OK; |
526 #ifdef LTC_CLEAN_STACK | 527 } |
527 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | 528 |
528 { | 529 #ifdef LTC_CLEAN_STACK |
529 _twofish_ecb_encrypt(pt, ct, skey); | 530 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) |
531 { | |
532 int err = _twofish_ecb_encrypt(pt, ct, skey); | |
530 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | 533 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); |
534 return err; | |
531 } | 535 } |
532 #endif | 536 #endif |
533 | 537 |
534 /** | 538 /** |
535 Decrypts a block of text with Twofish | 539 Decrypts a block of text with Twofish |
536 @param ct The input ciphertext (16 bytes) | 540 @param ct The input ciphertext (16 bytes) |
537 @param pt The output plaintext (16 bytes) | 541 @param pt The output plaintext (16 bytes) |
538 @param skey The key as scheduled | 542 @param skey The key as scheduled |
543 @return CRYPT_OK if successful | |
539 */ | 544 */ |
540 #ifdef LTC_CLEAN_STACK | 545 #ifdef LTC_CLEAN_STACK |
541 static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | 546 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
542 #else | 547 #else |
543 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | 548 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
544 #endif | 549 #endif |
545 { | 550 { |
546 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; | 551 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; |
547 int r; | 552 int r; |
548 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) | 553 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) |
591 d ^= skey->twofish.K[3]; | 596 d ^= skey->twofish.K[3]; |
592 | 597 |
593 /* store */ | 598 /* store */ |
594 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); | 599 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); |
595 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); | 600 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); |
596 } | 601 return CRYPT_OK; |
597 | 602 } |
598 #ifdef LTC_CLEAN_STACK | 603 |
599 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | 604 #ifdef LTC_CLEAN_STACK |
600 { | 605 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
601 _twofish_ecb_decrypt(ct, pt, skey); | 606 { |
607 int err =_twofish_ecb_decrypt(ct, pt, skey); | |
602 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | 608 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); |
609 return err; | |
603 } | 610 } |
604 #endif | 611 #endif |
605 | 612 |
606 /** | 613 /** |
607 Performs a self-test of the Twofish block cipher | 614 Performs a self-test of the Twofish block cipher |
654 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { | 661 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { |
655 return err; | 662 return err; |
656 } | 663 } |
657 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); | 664 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); |
658 twofish_ecb_decrypt(tmp[0], tmp[1], &key); | 665 twofish_ecb_decrypt(tmp[0], tmp[1], &key); |
659 if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { | 666 if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) { |
667 #if 0 | |
668 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16)); | |
669 #endif | |
660 return CRYPT_FAIL_TESTVECTOR; | 670 return CRYPT_FAIL_TESTVECTOR; |
661 } | 671 } |
662 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | 672 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ |
663 for (y = 0; y < 16; y++) tmp[0][y] = 0; | 673 for (y = 0; y < 16; y++) tmp[0][y] = 0; |
664 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); | 674 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); |
702 | 712 |
703 | 713 |
704 | 714 |
705 | 715 |
706 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ | 716 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ |
707 /* $Revision: 1.8 $ */ | 717 /* $Revision: 1.14 $ */ |
708 /* $Date: 2005/05/05 14:35:58 $ */ | 718 /* $Date: 2006/12/04 21:34:03 $ */ |