home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / SAFER / SAFER.C < prev    next >
Text File  |  1996-09-29  |  19KB  |  558 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                            Safer Encryption Algorithm                         *
  4. *                        Copyright Peter Gutmann 1994-1996                    *
  5. *                                                                            *
  6. ****************************************************************************/
  7.  
  8. /* Code to implement the improved SAFER-SK form of the SAFER cipher,
  9.    originally published as "SAFER K-64: A Byte-Oriented Block-Ciphering
  10.    Algorithm", James L. Massey, "Fast Software Encryption", Lecture Notes in
  11.    Computer Science No. 809, Springer-Verlag 1994, p.1.  This code implements
  12.    the 128-bit key extension designed by the Special Projects Team of the
  13.    Ministry of Home Affairs, Singapore and published as "SAFER K-64: One
  14.    Year Later", James L.Massey, presented at the K. U. Leuven Workshop on
  15.    Algorithms, Leuven, Belgium, 14-16 December, 1994, to appear in "Fast
  16.    Software Encryption II", Lecture Notes in Computer Science,
  17.    Springer-Verlag 1995, along with Lars Knudsen's strengthened key schedule,
  18.    presented in "A Key-Schedule Weakness in SAFER K-64," Lars Knudsen,
  19.    presented at Crypto '95 in Santa Barbara, California.
  20.  
  21.    All parts of the SAFER-SK algorithm are non-proprietary and freely
  22.    available for anyone to use as they see fit */
  23.  
  24. #include <string.h>
  25. #if defined( INC_ALL )
  26.   #include "crypt.h"
  27.   #include "safer.h"
  28. #elif defined( INC_CHILD )
  29.   #include "../crypt.h"
  30.   #include "safer.h"
  31. #else
  32.   #include "crypt.h"
  33.   #include "safer/safer.h"
  34. #endif /* Compiler-specific includes */
  35.  
  36. /* The size of each half key used in the key schedule */
  37.  
  38. #define SAFER_KEYHALF_SIZE        ( SAFER_KEYSIZE / 2 )
  39.  
  40. /* The size of each half key plus the parity byte used in the key schedule */
  41.  
  42. #define SAFER_KEYHALF_P_SIZE    ( SAFER_KEYHALF_SIZE + 1 )
  43.  
  44. /* Define for byte rotates (C isn't quite a high-level assembly language) */
  45.  
  46. #define ROL(x,n)    ( ( ( x << n ) | ( x >> ( 8 - n ) ) ) & 0xFF )
  47.  
  48. /* Exponents and logs, evaluated via the pre-calculated lookup tables */
  49.  
  50. #define EXP(x)    expTable[ x ]
  51. #define LOG(x)    logTable[ x ]
  52.  
  53. /* The two-point Pseudo-Hadamard Transform
  54.  
  55.     b1 = 2a1 + a2
  56.     b2 =  a1 + a2
  57.  
  58.    and inverse two-point Pseudo-Hadamard Transform
  59.  
  60.     a1 =  b1 -  b2
  61.     a2 = -b1 + 2b2
  62.  
  63.    which are used to create a three-dimensional PHT (ie independant
  64.    two-point PHT's in each of three dimensions, which is why there are
  65.    2^3 = 8 bytes in the input and output of the PHT) through a decimation-
  66.    by-two/fanning-out-by-two network.  The PHT provides guaranteed complete
  67.    diffusion within one linear layer */
  68.  
  69. #define PHT(x,y)    { y += x; x += y; }
  70. #define IPHT(x,y)    { x -= y; y -= x; }
  71.  
  72. /* The lookup table for logs and exponents.  These contain the powers of the
  73.    primitive element 45 of GF( 257 ) (ie values of 45^n mod 257) in
  74.    "expTable" with the corresponding logs base 45 stored in "logTable".
  75.    They may be calculated as follows:
  76.  
  77.     exponent = 1;
  78.     for( i = 0; i < 256; i++ )
  79.         {
  80.         int exp = exponent & 0xFF;
  81.  
  82.         expTable[ i ] = exp;
  83.         logTable[ exp ] = i;
  84.         exponent = ( exponent * 45 ) % 257;
  85.         } */
  86.  
  87. static BYTE expTable[] = {
  88.     0x01, 0x2D, 0xE2, 0x93, 0xBE, 0x45, 0x15, 0xAE,
  89.     0x78, 0x03, 0x87, 0xA4, 0xB8, 0x38, 0xCF, 0x3F,
  90.     0x08, 0x67, 0x09, 0x94, 0xEB, 0x26, 0xA8, 0x6B,
  91.     0xBD, 0x18, 0x34, 0x1B, 0xBB, 0xBF, 0x72, 0xF7,
  92.     0x40, 0x35, 0x48, 0x9C, 0x51, 0x2F, 0x3B, 0x55,
  93.     0xE3, 0xC0, 0x9F, 0xD8, 0xD3, 0xF3, 0x8D, 0xB1,
  94.     0xFF, 0xA7, 0x3E, 0xDC, 0x86, 0x77, 0xD7, 0xA6,
  95.     0x11, 0xFB, 0xF4, 0xBA, 0x92, 0x91, 0x64, 0x83,
  96.     0xF1, 0x33, 0xEF, 0xDA, 0x2C, 0xB5, 0xB2, 0x2B,
  97.     0x88, 0xD1, 0x99, 0xCB, 0x8C, 0x84, 0x1D, 0x14,
  98.     0x81, 0x97, 0x71, 0xCA, 0x5F, 0xA3, 0x8B, 0x57,
  99.     0x3C, 0x82, 0xC4, 0x52, 0x5C, 0x1C, 0xE8, 0xA0,
  100.     0x04, 0xB4, 0x85, 0x4A, 0xF6, 0x13, 0x54, 0xB6,
  101.     0xDF, 0x0C, 0x1A, 0x8E, 0xDE, 0xE0, 0x39, 0xFC,
  102.     0x20, 0x9B, 0x24, 0x4E, 0xA9, 0x98, 0x9E, 0xAB,
  103.     0xF2, 0x60, 0xD0, 0x6C, 0xEA, 0xFA, 0xC7, 0xD9,
  104.     0x00, 0xD4, 0x1F, 0x6E, 0x43, 0xBC, 0xEC, 0x53,
  105.     0x89, 0xFE, 0x7A, 0x5D, 0x49, 0xC9, 0x32, 0xC2,
  106.     0xF9, 0x9A, 0xF8, 0x6D, 0x16, 0xDB, 0x59, 0x96,
  107.     0x44, 0xE9, 0xCD, 0xE6, 0x46, 0x42, 0x8F, 0x0A,
  108.     0xC1, 0xCC, 0xB9, 0x65, 0xB0, 0xD2, 0xC6, 0xAC,
  109.     0x1E, 0x41, 0x62, 0x29, 0x2E, 0x0E, 0x74, 0x50,
  110.     0x02, 0x5A, 0xC3, 0x25, 0x7B, 0x8A, 0x2A, 0x5B,
  111.     0xF0, 0x06, 0x0D, 0x47, 0x6F, 0x70, 0x9D, 0x7E,
  112.     0x10, 0xCE, 0x12, 0x27, 0xD5, 0x4C, 0x4F, 0xD6,
  113.     0x79, 0x30, 0x68, 0x36, 0x75, 0x7D, 0xE4, 0xED,
  114.     0x80, 0x6A, 0x90, 0x37, 0xA2, 0x5E, 0x76, 0xAA,
  115.     0xC5, 0x7F, 0x3D, 0xAF, 0xA5, 0xE5, 0x19, 0x61,
  116.     0xFD, 0x4D, 0x7C, 0xB7, 0x0B, 0xEE, 0xAD, 0x4B,
  117.     0x22, 0xF5, 0xE7, 0x73, 0x23, 0x21, 0xC8, 0x05,
  118.     0xE1, 0x66, 0xDD, 0xB3, 0x58, 0x69, 0x63, 0x56,
  119.     0x0F, 0xA1, 0x31, 0x95, 0x17, 0x07, 0x3A, 0x28
  120.     };
  121.  
  122. static BYTE logTable[] = {
  123.     0x80, 0x00, 0xB0, 0x09, 0x60, 0xEF, 0xB9, 0xFD,
  124.     0x10, 0x12, 0x9F, 0xE4, 0x69, 0xBA, 0xAD, 0xF8,
  125.     0xC0, 0x38, 0xC2, 0x65, 0x4F, 0x06, 0x94, 0xFC,
  126.     0x19, 0xDE, 0x6A, 0x1B, 0x5D, 0x4E, 0xA8, 0x82,
  127.     0x70, 0xED, 0xE8, 0xEC, 0x72, 0xB3, 0x15, 0xC3,
  128.     0xFF, 0xAB, 0xB6, 0x47, 0x44, 0x01, 0xAC, 0x25,
  129.     0xC9, 0xFA, 0x8E, 0x41, 0x1A, 0x21, 0xCB, 0xD3,
  130.     0x0D, 0x6E, 0xFE, 0x26, 0x58, 0xDA, 0x32, 0x0F,
  131.     0x20, 0xA9, 0x9D, 0x84, 0x98, 0x05, 0x9C, 0xBB,
  132.     0x22, 0x8C, 0x63, 0xE7, 0xC5, 0xE1, 0x73, 0xC6,
  133.     0xAF, 0x24, 0x5B, 0x87, 0x66, 0x27, 0xF7, 0x57,
  134.     0xF4, 0x96, 0xB1, 0xB7, 0x5C, 0x8B, 0xD5, 0x54,
  135.     0x79, 0xDF, 0xAA, 0xF6, 0x3E, 0xA3, 0xF1, 0x11,
  136.     0xCA, 0xF5, 0xD1, 0x17, 0x7B, 0x93, 0x83, 0xBC,
  137.     0xBD, 0x52, 0x1E, 0xEB, 0xAE, 0xCC, 0xD6, 0x35,
  138.     0x08, 0xC8, 0x8A, 0xB4, 0xE2, 0xCD, 0xBF, 0xD9,
  139.     0xD0, 0x50, 0x59, 0x3F, 0x4D, 0x62, 0x34, 0x0A,
  140.     0x48, 0x88, 0xB5, 0x56, 0x4C, 0x2E, 0x6B, 0x9E,
  141.     0xD2, 0x3D, 0x3C, 0x03, 0x13, 0xFB, 0x97, 0x51,
  142.     0x75, 0x4A, 0x91, 0x71, 0x23, 0xBE, 0x76, 0x2A,
  143.     0x5F, 0xF9, 0xD4, 0x55, 0x0B, 0xDC, 0x37, 0x31,
  144.     0x16, 0x74, 0xD7, 0x77, 0xA7, 0xE6, 0x07, 0xDB,
  145.     0xA4, 0x2F, 0x46, 0xF3, 0x61, 0x45, 0x67, 0xE3,
  146.     0x0C, 0xA2, 0x3B, 0x1C, 0x85, 0x18, 0x04, 0x1D,
  147.     0x29, 0xA0, 0x8F, 0xB2, 0x5A, 0xD8, 0xA6, 0x7E,
  148.     0xEE, 0x8D, 0x53, 0x4B, 0xA1, 0x9A, 0xC1, 0x0E,
  149.     0x7A, 0x49, 0xA5, 0x2C, 0x81, 0xC4, 0xC7, 0x36,
  150.     0x2B, 0x7F, 0x43, 0x95, 0x33, 0xF2, 0x6C, 0x68,
  151.     0x6D, 0xF0, 0x02, 0x28, 0xCE, 0xDD, 0x9B, 0xEA,
  152.     0x5E, 0x99, 0x7C, 0x14, 0x86, 0xCF, 0xE5, 0x42,
  153.     0xB8, 0x40, 0x78, 0x2D, 0x3A, 0xE9, 0x64, 0x1F,
  154.     0x92, 0x90, 0x7D, 0x39, 0x6F, 0xE0, 0x89, 0x30
  155.     };
  156.  
  157. /* Perform a SAFER key schedule */
  158.  
  159. void saferExpandKey( BYTE *key, BYTE *userKey, int noRounds, int useSaferSK )
  160.     {
  161.     int round, i;
  162.     BYTE *keyLow = userKey, *keyHigh = userKey + SAFER_KEYHALF_SIZE;
  163.     BYTE ka[ SAFER_KEYHALF_P_SIZE ], kb[ SAFER_KEYHALF_P_SIZE ];
  164.  
  165.     /* Save the number of rounds as part of the key */
  166.     if( noRounds > SAFER_MAX_ROUNDS )
  167.         noRounds = SAFER_MAX_ROUNDS;
  168.     *key++ = ( BYTE ) noRounds;
  169.  
  170.     /* Copy the user key halves to Ka and Kb */
  171.     for( i = 0; i < SAFER_KEYHALF_SIZE; i++ )
  172.         {
  173.         ka[ i ] = keyLow[ i ];
  174.         kb[ i ] = keyHigh[ i ];
  175.         }
  176.  
  177.     /* Append a parity byte to keys Ka and Kb */
  178.     ka[ SAFER_KEYHALF_SIZE ] = kb[ SAFER_KEYHALF_SIZE ] = 0;
  179.     for( i = 0; i < SAFER_KEYHALF_SIZE; i++ )
  180.         {
  181.         ka[ SAFER_KEYHALF_SIZE ] ^= ka[ i ];
  182.         kb[ SAFER_KEYHALF_SIZE ] ^= kb[ i ];
  183.         }
  184.  
  185.     /* K1 = Kb */
  186.     for( i = 0; i < SAFER_KEYHALF_SIZE; i++ )
  187.         *key++ = kb[ i ];
  188.  
  189.     /* Rotate each byte of Ka right by 3 */
  190.     for( i = 0; i < SAFER_KEYHALF_SIZE + 1; i++ )
  191.         ka[ i ] = ROL( ka[ i ], 5 );
  192.  
  193.     /* Perform the key schedule needed to derive the remaining keys K2, ...
  194.        K2r+1 from the 128 bit input key Ka+Kb */
  195.     for( round = 1; round <= noRounds; round++)
  196.         {
  197.         /* Left rotate each byte of Ka and Kb by 6 */
  198.         for( i = 0; i < SAFER_KEYHALF_P_SIZE; i++ )
  199.             {
  200.             ka[ i ] = ROL( ka[ i ], 6 );
  201.             kb[ i ] = ROL( kb[ i ], 6 );
  202.             }
  203.  
  204.         /* Add the key biases to give K2i-1 and K2i.  The original algorithm
  205.            specification is:
  206.  
  207.             k[ 2 * i, j ] = ka[ ( ( j + 2 * i - 2 ) % 9 ) + 1 ] + \
  208.                             expTable[ expTable[ 18 * i + j ] ];
  209.             k[ 2 * i + 1, j ] = kb[ ( ( j + 2 * i - 1 ) % 9 ) + 1 ] + \
  210.                                 expTable[ expTable[ 18 * i + 9 + j ] ];
  211.  
  212.            however we rearrange this to calculate K2i-1 and K2i seperately
  213.            to eliminate the need to repeatedly evaluate 2i on the LHS */
  214.         for( i = 0; i < SAFER_KEYHALF_SIZE; i++ )
  215.             if( useSaferSK )
  216.                 *key++ = ( ka[ ( i + 2 * round - 1 ) % SAFER_KEYHALF_P_SIZE ] + \
  217.                            expTable[ expTable[ ( SAFER_KEYHALF_P_SIZE * 2 ) * \
  218.                             round + i + 1 ] ] ) & 0xFF;
  219.             else
  220.                 *key++ = ( ka[ i ] + \
  221.                            expTable[ expTable[ ( SAFER_KEYHALF_P_SIZE * 2 ) * \
  222.                             round + i + 1 ] ] ) & 0xFF;
  223.  
  224.         for( i = 0; i < SAFER_KEYHALF_SIZE; i++ )
  225.             if( useSaferSK )
  226.                 *key++ = ( kb[ ( i + 2 * round ) % SAFER_KEYHALF_P_SIZE ] + \
  227.                            expTable[ expTable[ ( SAFER_KEYHALF_P_SIZE * 2 ) * \
  228.                             round + i + ( SAFER_KEYHALF_P_SIZE + 1 ) ] ] ) & 0xFF;
  229.             else
  230.                 *key++ = ( kb[ i ] + \
  231.                            expTable[ expTable[ ( SAFER_KEYHALF_P_SIZE * 2 ) * \
  232.                             round + i + ( SAFER_KEYHALF_P_SIZE + 1 ) ] ] ) & 0xFF;
  233.         }
  234.  
  235.     /* Clean up */
  236.     zeroise( ka, SAFER_BLOCKSIZE );
  237.     zeroise( kb, SAFER_BLOCKSIZE );
  238.     }
  239.  
  240. #ifndef SAFER_ASM
  241.  
  242. /* Encrypt a block of data with SAFER */
  243.  
  244. void saferEncryptBlock( BYTE *data, BYTE *key )
  245.     {
  246.     BYTE a, b, c, d, e, f, g, h, t;
  247.     int rounds = *key++;
  248.  
  249.     /* Copy the input block to local variables */
  250.     a = data[ 0 ];
  251.     b = data[ 1 ];
  252.     c = data[ 2 ];
  253.     d = data[ 3 ];
  254.     e = data[ 4 ];
  255.     f = data[ 5 ];
  256.     g = data[ 6 ];
  257.     h = data[ 7 ];
  258.  
  259.     while( rounds-- )
  260.         {
  261.         /* Perform the mixed xor/byte addition of the round input with the
  262.            subkey K2i-1, combined with the first level of the nonlinear
  263.            layer, either 45^n mod 257 or log45n, and the mixed xor/byte
  264.            addition with the subkey K2i */
  265.         a = EXP( ( a ^ key[ 0 ] ) & 0xFF ) + key[  8 ];
  266.         b = LOG( ( b + key[ 1 ] ) & 0xFF ) ^ key[  9 ];
  267.         c = LOG( ( c + key[ 2 ] ) & 0xFF ) ^ key[ 10 ];
  268.         d = EXP( ( d ^ key[ 3 ] ) & 0xFF ) + key[ 11 ];
  269.         e = EXP( ( e ^ key[ 4 ] ) & 0xFF ) + key[ 12 ];
  270.         f = LOG( ( f + key[ 5 ] ) & 0xFF ) ^ key[ 13 ];
  271.         g = LOG( ( g + key[ 6 ] ) & 0xFF ) ^ key[ 14 ];
  272.         h = EXP( ( h ^ key[ 7 ] ) & 0xFF ) + key[ 15 ];
  273.  
  274.         /* Perform the Pseudo-Hadamard Trasform of the round output.  If
  275.            we were implementing this in assembly language we should
  276.            interleave the order of the two operations in the PHT with those
  277.            of the following PHT to reduce pipeline stalls, but for the C
  278.            version we rely on the compiler to pick this optimization up */
  279.         PHT( a, b );
  280.         PHT( c, d );
  281.         PHT( e, f );
  282.         PHT( g, h );
  283.         PHT( a, c );
  284.         PHT( e, g );
  285.         PHT( b, d );
  286.         PHT( f, h );
  287.         PHT( a, e );
  288.         PHT( b, f );
  289.         PHT( c, g );
  290.         PHT( d, h );
  291.  
  292.         /* Swap the data octets around.  If we unrol the loop we can
  293.            eliminate this step through register renaming */
  294.         t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
  295.         key += 16;
  296.         }
  297.  
  298.     /* Perform the final mixed xor/byte addition output transformation
  299.        using K2r + 1*/
  300.     data[ 0 ] = a ^ key[ 0 ];
  301.     data[ 1 ] = b + key[ 1 ];
  302.     data[ 2 ] = c + key[ 2 ];
  303.     data[ 3 ] = d ^ key[ 3 ];
  304.     data[ 4 ] = e ^ key[ 4 ];
  305.     data[ 5 ] = f + key[ 5 ];
  306.     data[ 6 ] = g + key[ 6 ];
  307.     data[ 7 ] = h ^ key[ 7 ];
  308.     }
  309.  
  310. /* Decrypt a block of data with SAFER */
  311.  
  312. void saferDecryptBlock( BYTE *data, BYTE *key )
  313.     {
  314.     BYTE a, b, c, d, e, f, g, h, t;
  315.     int rounds = *key;
  316.  
  317.     /* Since we're now running throught the algorithm backwards, we move to
  318.        the end of the key and start from there */
  319.     key += SAFER_BLOCKSIZE * ( 1 + 2 * rounds );
  320.  
  321.     /* Perform the initial mixed xor/byte addition input transformation
  322.        using K2r+1 */
  323.     a = data[ 0 ] ^ key[ -7 ];
  324.     b = data[ 1 ] - key[ -6 ];
  325.     c = data[ 2 ] - key[ -5 ];
  326.     d = data[ 3 ] ^ key[ -4 ];
  327.     e = data[ 4 ] ^ key[ -3 ];
  328.     f = data[ 5 ] - key[ -2 ];
  329.     g = data[ 6 ] - key[ -1 ];
  330.     h = data[ 7 ] ^ key[ 0 ];
  331.     key -= 8;
  332.  
  333.     while( rounds-- )
  334.         {
  335.         /* Swap the data octets around.  If we unrol the loop we can
  336.            eliminate this step through register renaming */
  337.         t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
  338.  
  339.         /* Perform the inverse Pseudo-Hadamard Trasform of the round input.
  340.            If we were implementing this in assembly language we should
  341.            interleave the order of the two operations in the PHT with those
  342.            of the following PHT to reduce pipeline stalls, but for the C
  343.            version we rely on the compiler to pick this optimization up */
  344.         IPHT( a, e );
  345.         IPHT( b, f );
  346.         IPHT( c, g );
  347.         IPHT( d, h );
  348.         IPHT( a, c );
  349.         IPHT( e, g );
  350.         IPHT( b, d );
  351.         IPHT( f, h );
  352.         IPHT( a, b );
  353.         IPHT( c, d );
  354.         IPHT( e, f );
  355.         IPHT( g, h );
  356.  
  357.         /* Perform the mixed xor/byte addition of the inverse PHT output with
  358.            the subkey K2r+2-2i, combined with the second level of the
  359.            nonlinear layer, either 45^n mod 257 or log45n, and finally the
  360.            mixed xor/byte addition of the round output with K2r+1-2i */
  361.         h = LOG( ( h - key[  0 ] ) & 0xFF ) ^ key[  -8 ];
  362.         g = EXP( ( g ^ key[ -1 ] ) & 0xFF ) - key[  -9 ];
  363.         f = EXP( ( f ^ key[ -2 ] ) & 0xFF ) - key[ -10 ];
  364.         e = LOG( ( e - key[ -3 ] ) & 0xFF ) ^ key[ -11 ];
  365.         d = LOG( ( d - key[ -4 ] ) & 0xFF ) ^ key[ -12 ];
  366.         c = EXP( ( c ^ key[ -5 ] ) & 0xFF ) - key[ -13 ];
  367.         b = EXP( ( b ^ key[ -6 ] ) & 0xFF ) - key[ -14 ];
  368.         a = LOG( ( a - key[ -7 ] ) & 0xFF ) ^ key[ -15 ];
  369.         key -= 16;
  370.         }
  371.  
  372.     data[ 0 ] = a;
  373.     data[ 1 ] = b;
  374.     data[ 2 ] = c;
  375.     data[ 3 ] = d;
  376.     data[ 4 ] = e;
  377.     data[ 5 ] = f;
  378.     data[ 6 ] = g;
  379.     data[ 7 ] = h;
  380.     }
  381. #endif /* SAFER_ASM */
  382.  
  383. #ifdef TEST_SAFER
  384.  
  385. /* CFB-mode en/decryption routines */
  386.  
  387. void saferEncryptCFB( BYTE *buffer, int noBytes, BYTE *iv, int ivLen, BYTE *key )
  388.     {
  389.     BYTE currentIV[ SAFER_BLOCKSIZE ];
  390.  
  391.     /* Set up the initial IV */
  392.     memset( currentIV, 0, SAFER_BLOCKSIZE );
  393.     memcpy( currentIV, iv, ivLen );
  394.  
  395.     while( noBytes )
  396.         {
  397.         int ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  398.         int i;
  399.  
  400.         /* Encrypt the IV */
  401.         saferEncryptBlock( currentIV, key );
  402.  
  403.         /* XOR the buffer contents with the encrypted IV */
  404.         for( i = 0; i < ivCount; i++ )
  405.             buffer[ i ] ^= currentIV[ i ];
  406.  
  407.         /* Shift the ciphertext into the IV */
  408.         memcpy( currentIV, buffer, ivCount );
  409.  
  410.         /* Move on to next block of data */
  411.         noBytes -= ivCount;
  412.         buffer += ivCount;
  413.         }
  414.     }
  415.  
  416. void saferDecryptCFB( BYTE *buffer, int noBytes, BYTE *iv, int ivLen, BYTE *key )
  417.     {
  418.     BYTE currentIV[ SAFER_BLOCKSIZE ], temp[ SAFER_BLOCKSIZE ];
  419.  
  420.     /* Set up the initial IV */
  421.     memset( currentIV, 0, SAFER_BLOCKSIZE );
  422.     memcpy( currentIV, iv, ivLen );
  423.  
  424.     while( noBytes )
  425.         {
  426.         int ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  427.         int i;
  428.  
  429.         /* Encrypt the IV */
  430.         saferEncryptBlock( currentIV, key );
  431.  
  432.         /* Save the ciphertext */
  433.         memcpy( temp, buffer, ivCount );
  434.  
  435.         /* XOR the buffer contents with the encrypted IV */
  436.         for( i = 0; i < ivCount; i++ )
  437.             buffer[ i ] ^= currentIV[ i ];
  438.  
  439.         /* Shift the ciphertext into the IV */
  440.         memcpy( currentIV, temp, ivCount );
  441.  
  442.         /* Move on to next block of data */
  443.         noBytes -= ivCount;
  444.         buffer += ivCount;
  445.         }
  446.     }
  447.  
  448. /* Test code */
  449.  
  450. #include <stdio.h>
  451. #include <time.h>
  452.  
  453. void _saferEncryptBlock( BYTE *data, BYTE *key );
  454. void _saferDecryptBlock( BYTE *data, BYTE *key );
  455.  
  456. void test8051( void )
  457.     {
  458.     BYTE key[] = { 0x03,
  459.                    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  460.                    0x10, 0x26, 0x8B, 0x5B, 0x46, 0xBE, 0xA8,
  461.                    0xFD, 0xC6, 0x09, 0x81, 0x67, 0xD9, 0xB4,
  462.                    0x7B, 0x8E, 0x88, 0xB9, 0xC4, 0xAF, 0xC5,
  463.                    0x20, 0x1A, 0xC7, 0x3B, 0x99, 0x3A, 0x18,
  464.                    0xAD, 0xE5, 0x35, 0x8C, 0x5B, 0xC9, 0xEA,
  465.                    0x99, 0x5C, 0x8D, 0xF9, 0x1B, 0xF8, 0xA2,
  466.                    0x1C, 0x65, 0x61, 0xFB, 0xB6, 0xF3, 0x0C };
  467.     BYTE plainText[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
  468.     BYTE cipherText[] = { 0xE9, 0xB8, 0xC0, 0xEA, 0xBC, 0x10, 0x99, 0xA1 };
  469.     BYTE plainString[] = "This is a test string which is longer than the blocksize...";
  470.     BYTE cipherString[] = { 0xC1, 0x5B, 0x63, 0xE9, 0xA8, 0x15, 0x74, 0x19,
  471.                             0x88, 0x1B, 0xB6, 0xE4, 0xF3, 0x32, 0x93, 0xC2,
  472.                             0x6F, 0x81, 0x94, 0xA7, 0x69, 0xA6, 0x92, 0x05,
  473.                             0x54, 0xA1, 0x8E, 0x3B, 0xF2, 0x56, 0x28, 0xFF,
  474.                             0x12, 0x02, 0xAB, 0x66, 0xC6, 0xC5, 0xF0, 0xEC,
  475.                             0x65, 0x82, 0xD0, 0x29, 0x92, 0x2B, 0x26, 0x52,
  476.                             0x96, 0x83, 0xB1, 0x21, 0x53, 0x09, 0x02, 0x67,
  477.                             0xD9, 0x6B, 0x2E };
  478.     BYTE cfbIV[] = "1234";
  479.     BYTE data[ SAFER_BLOCKSIZE ];
  480.     BYTE cfbData[ 100 ];
  481.     int length = sizeof( plainString ) - 1;
  482.  
  483.     memcpy( data, plainText, SAFER_BLOCKSIZE );
  484.     saferEncryptBlock( data, key );
  485.     if( memcmp( data, cipherText, SAFER_BLOCKSIZE ) )
  486.         puts( "Bang" );
  487.     saferDecryptBlock( data, key );
  488.  
  489.     memcpy( cfbData, plainString, length );
  490.     saferEncryptCFB( cfbData, sizeof( cfbData ) - 1,
  491.                      cfbIV, sizeof( cfbIV ) - 1, key );
  492.     if( memcmp( cfbData, cipherString, length ) )
  493.         puts( "Bang" );
  494.     saferDecryptCFB( cfbData, sizeof( cfbData ) - 1,
  495.                      cfbIV, sizeof( cfbIV ) - 1, key );
  496.     }
  497.  
  498. void main( void )
  499.     {
  500.     BYTE key1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  501.                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
  502.     BYTE plainText1[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
  503.     BYTE cipherText1[] = { 0x41, 0x4C, 0x54, 0x5A, 0xB6, 0x99, 0x4A, 0xF7 };
  504.     BYTE key2[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  505.                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  506.     BYTE plainText2[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
  507.     BYTE cipherText2[] = { 0xFF, 0x78, 0x11, 0xE4, 0xB3, 0xA7, 0x2E, 0x71 };
  508.     BYTE key3[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  509.                     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
  510.     BYTE plainText3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
  511.     BYTE cipherText3[] = { 0x49, 0xC9, 0x9D, 0x98, 0xA5, 0xBC, 0x59, 0x08 };
  512.     BYTE data[ SAFER_BLOCKSIZE ], key[ SAFER_KEYLEN ];
  513.     BYTE cfbData[] = "This is a test string which is longer than the blocksize";
  514.     BYTE cfbIV[] = "1234";
  515.     time_t secondCount;
  516.     long i;
  517.  
  518.     saferExpandKey( key, key1, SAFER_SK128_ROUNDS, TRUE );
  519.     memcpy( data, plainText1, SAFER_BLOCKSIZE );
  520.     saferEncryptBlock( data, key );
  521.     memcpy( data, plainText1, SAFER_BLOCKSIZE );
  522.     saferEncryptBlock( data, key );
  523.     if( memcmp( data, cipherText1, SAFER_BLOCKSIZE ) )
  524.         puts( "Bang" );
  525.     saferDecryptBlock( data, key );
  526.     saferExpandKey( key, key2, SAFER_SK128_ROUNDS, TRUE );
  527.     memcpy( data, plainText2, SAFER_BLOCKSIZE );
  528.     saferEncryptBlock( data, key );
  529.     if( memcmp( data, cipherText2, SAFER_BLOCKSIZE ) )
  530.         puts( "Bang" );
  531.     saferDecryptBlock( data, key );
  532.     saferExpandKey( key, key3, SAFER_SK128_ROUNDS, TRUE );
  533.     memcpy( data, plainText3, SAFER_BLOCKSIZE );
  534.     saferEncryptBlock( data, key );
  535.     if( memcmp( data, cipherText3, SAFER_BLOCKSIZE ) )
  536.         puts( "Bang" );
  537.     saferDecryptBlock( data, key );
  538.  
  539.     /* CFB mode test */
  540.     saferExpandKey( key, key1, SAFER_SK128_ROUNDS, TRUE );
  541.     saferEncryptCFB( cfbData, sizeof( cfbData ) - 1,
  542.                      cfbIV, sizeof( cfbIV ) - 1, key );
  543.     saferDecryptCFB( cfbData, sizeof( cfbData ) - 1,
  544.                      cfbIV, sizeof( cfbIV ) - 1, key );
  545.  
  546.     test8051();
  547.  
  548.     /* Speed test */
  549.     puts( "Encrypting 5MB of data" );
  550.     secondCount = time( NULL );
  551.     for( i = 0; i < 625000L; i++ )
  552.         saferEncryptBlock( data, key );
  553.     secondCount = time( NULL ) - secondCount;
  554.     printf( "Time = %ld seconds, %ld kbytes/second\n", \
  555.             secondCount, 8 * 625L / secondCount );
  556.     }
  557. #endif /* TEST_SAFER */
  558.