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

  1. /****************************************************************************
  2. *                                                                            *
  3. *                        cryptlib DES Encryption Routines                    *
  4. *                        Copyright Peter Gutmann 1992-1996                    *
  5. *                                                                            *
  6. ****************************************************************************/
  7.  
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include "crypt.h"
  14. #ifdef INC_ALL
  15.   #include "des.h"
  16. #else
  17.   #include "libdes/des.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /* The DES block size */
  21.  
  22. #define DES_BLOCKSIZE            8
  23.  
  24. /* A structure to hold the keyscheduled DES keys */
  25.  
  26. typedef struct {
  27.     Key_schedule desKey;            /* The DES key */
  28.     BOOLEAN isDESX;                    /* Whether it's DES or DESX */
  29.     } DES_KEY;
  30.  
  31. /* The size of the keyscheduled DES key */
  32.  
  33. #define DES_EXPANDED_KEYSIZE    sizeof( DES_KEY )
  34.  
  35. /****************************************************************************
  36. *                                                                            *
  37. *                            DES Self-test Routines                            *
  38. *                                                                            *
  39. ****************************************************************************/
  40.  
  41. #include "testdes.h"
  42.  
  43. /* Test the DES implementation against the test vectors given in NBS Special
  44.    Publication 500-20, 1980.  We need to perform the tests at a very low
  45.    level since the encryption library hasn't been intialized yet */
  46.  
  47. static int desTestLoop( DES_TEST *testData, int iterations, int operation )
  48.     {
  49.     BYTE temp[ DES_BLOCKSIZE ];
  50.     BYTE key[ DES_EXPANDED_KEYSIZE ];
  51.     int i;
  52.  
  53.     for( i = 0; i < iterations; i++ )
  54.         {
  55.         memcpy( temp, testData[ i ].plaintext, DES_BLOCKSIZE );
  56.         key_sched( ( C_Block * ) testData[ i ].key,
  57.                    *( ( Key_schedule * ) key ) );
  58.         des_ecb_encrypt( ( C_Block * ) temp, ( C_Block * ) temp,
  59.                          *( ( Key_schedule * ) key ), operation );
  60.         if( memcmp( testData[ i ].ciphertext, temp, DES_BLOCKSIZE ) )
  61.             return( CRYPT_ERROR );
  62.         }
  63.  
  64.     return( CRYPT_OK );
  65.     }
  66.  
  67. int desSelfTest( void )
  68.     {
  69.     UNUSED( testIPname );
  70.     UNUSED( testVPname );
  71.     UNUSED( testKPname );
  72.     UNUSED( testRSname );
  73.     UNUSED( testDPname );
  74.     UNUSED( testSBname );
  75.  
  76. #if defined( __WIN16__ ) && defined( _MSC_VER )
  77.     /* Bypass 16-bit Visual C bug */
  78.     des_check_key = FALSE;
  79. #endif /* __WIN16__ && _MSC_VER */
  80.  
  81.     /* Check the DES test vectors */
  82.     if( ( desTestLoop( testIP, sizeof( testIP ) / sizeof( DES_TEST ),
  83.                        DES_ENCRYPT ) != CRYPT_OK ) || \
  84.         ( desTestLoop( testVP, sizeof( testVP ) / sizeof( DES_TEST ),
  85.                        DES_ENCRYPT ) != CRYPT_OK ) || \
  86.         ( desTestLoop( testKP, sizeof( testKP ) / sizeof( DES_TEST ),
  87.                        DES_ENCRYPT ) != CRYPT_OK ) || \
  88.         ( desTestLoop( testRS, sizeof( testRS ) / sizeof( DES_TEST ),
  89.                        DES_DECRYPT ) != CRYPT_OK ) || \
  90.         ( desTestLoop( testDP, sizeof( testDP ) / sizeof( DES_TEST ),
  91.                        DES_ENCRYPT ) != CRYPT_OK ) || \
  92.         ( desTestLoop( testSB, sizeof( testSB ) / sizeof( DES_TEST ),
  93.                        DES_ENCRYPT ) != CRYPT_OK ) )
  94.         return( CRYPT_SELFTEST );
  95.  
  96.     /* Turn on checking for key parity errors and weak keys.  Note that we
  97.        have do this after the self-test since the self-test uses weak keys */
  98.     des_check_key = TRUE;
  99.  
  100.     return( CRYPT_OK );
  101.     }
  102.  
  103. /****************************************************************************
  104. *                                                                            *
  105. *                            Init/Shutdown Routines                            *
  106. *                                                                            *
  107. ****************************************************************************/
  108.  
  109. /* Perform auxiliary init and shutdown actions on an encryption context */
  110.  
  111. int desInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
  112.     {
  113.     CRYPT_INFO_DES *cryptInfoExPtr = ( CRYPT_INFO_DES * ) cryptInfoEx;
  114.     int status;
  115.  
  116.     /* Allocate memory for the keyscheduled key */
  117.     if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
  118.         return( CRYPT_INITED );
  119.     if( ( status = secureMalloc( &cryptInfo->key, DES_EXPANDED_KEYSIZE ) ) != CRYPT_OK )
  120.         return( status );
  121.     if( cryptInfoExPtr->isDESX == CRYPT_USE_DEFAULT )
  122.         {
  123.         cryptInfo->privateUseDefaults = TRUE;
  124.         setDESinfo( cryptInfo, FALSE );
  125.         }
  126.     else
  127.         setDESinfo( cryptInfo, ( BOOLEAN ) cryptInfoExPtr->isDESX );
  128.     cryptInfo->keyLength = DES_EXPANDED_KEYSIZE;
  129.  
  130.     return( CRYPT_OK );
  131.     }
  132.  
  133. int desInit( CRYPT_INFO *cryptInfo )
  134.     {
  135.     CRYPT_INFO_DES cryptInfoEx;
  136.  
  137.     /* Use standard 2-key EDE triple DES */
  138.     memset( &cryptInfoEx, 0, sizeof( CRYPT_INFO_DES ) );
  139.     cryptInfoEx.isDESX = CRYPT_USE_DEFAULT;
  140.  
  141.     /* Pass through to the extended setup routine */
  142.     return( desInitEx( cryptInfo, &cryptInfoEx ) );
  143.     }
  144.  
  145. int desEnd( CRYPT_INFO *cryptInfo )
  146.     {
  147.     /* Free any allocated memory */
  148.     secureFree( &cryptInfo->key );
  149.  
  150.     return( CRYPT_OK );
  151.     }
  152.  
  153. /****************************************************************************
  154. *                                                                            *
  155. *                            DES En/Decryption Routines                        *
  156. *                                                                            *
  157. ****************************************************************************/
  158.  
  159. /* Encrypt/decrypt data in ECB mode */
  160.  
  161. int desEncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  162.     {
  163.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  164.     int blockCount = noBytes / DES_BLOCKSIZE;
  165.  
  166.     /* Make sure the data length is a multiple of the block size */
  167.     if( noBytes % DES_BLOCKSIZE )
  168.         return( CRYPT_BADPARM3 );
  169.  
  170.     while( blockCount-- )
  171.         {
  172.         /* Encrypt a block of data */
  173.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  174.                          desKey->desKey, DES_ENCRYPT );
  175.  
  176.         /* Move on to next block of data */
  177.         buffer += DES_BLOCKSIZE;
  178.         }
  179.  
  180.     return( CRYPT_OK );
  181.     }
  182.  
  183. int desDecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  184.     {
  185.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  186.     int blockCount = noBytes / DES_BLOCKSIZE;
  187.  
  188.     /* Make sure the data length is a multiple of the block size */
  189.     if( noBytes % DES_BLOCKSIZE )
  190.         return( CRYPT_BADPARM3 );
  191.  
  192.     while( blockCount-- )
  193.         {
  194.         /* Decrypt a block of data */
  195.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  196.                          desKey->desKey, DES_DECRYPT );
  197.  
  198.         /* Move on to next block of data */
  199.         buffer += DES_BLOCKSIZE;
  200.         }
  201.  
  202.     return( CRYPT_OK );
  203.     }
  204.  
  205. /* Encrypt/decrypt data in CBC mode */
  206.  
  207. int desEncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  208.     {
  209.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  210.     int blockCount = noBytes / DES_BLOCKSIZE;
  211.  
  212.     /* Make sure the data length is a multiple of the block size */
  213.     if( noBytes % DES_BLOCKSIZE )
  214.         return( CRYPT_BADPARM3 );
  215.  
  216.     while( blockCount-- )
  217.         {
  218.         int i;
  219.  
  220.         /* XOR the buffer contents with the IV */
  221.         for( i = 0; i < DES_BLOCKSIZE; i++ )
  222.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  223.  
  224.         /* Encrypt a block of data */
  225.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  226.                          desKey->desKey, DES_ENCRYPT );
  227.  
  228.         /* Shift ciphertext into IV */
  229.         memcpy( cryptInfo->currentIV, buffer, DES_BLOCKSIZE );
  230.  
  231.         /* Move on to next block of data */
  232.         buffer += DES_BLOCKSIZE;
  233.         }
  234.  
  235.     return( CRYPT_OK );
  236.     }
  237.  
  238. int desDecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  239.     {
  240.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  241.     BYTE temp[ DES_BLOCKSIZE ];
  242.     int blockCount = noBytes / DES_BLOCKSIZE;
  243.  
  244.     /* Make sure the data length is a multiple of the block size */
  245.     if( noBytes % DES_BLOCKSIZE )
  246.         return( CRYPT_BADPARM3 );
  247.  
  248.     while( blockCount-- )
  249.         {
  250.         int i;
  251.  
  252.         /* Save the ciphertext */
  253.         memcpy( temp, buffer, DES_BLOCKSIZE );
  254.  
  255.         /* Decrypt a block of data */
  256.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  257.                          desKey->desKey, DES_DECRYPT );
  258.  
  259.         /* XOR the buffer contents with the IV */
  260.         for( i = 0; i < DES_BLOCKSIZE; i++ )
  261.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  262.  
  263.         /* Shift the ciphertext into the IV */
  264.         memcpy( cryptInfo->currentIV, temp, DES_BLOCKSIZE );
  265.  
  266.         /* Move on to next block of data */
  267.         buffer += DES_BLOCKSIZE;
  268.         }
  269.  
  270.     /* Clear the temporary buffer */
  271.     zeroise( temp, DES_BLOCKSIZE );
  272.  
  273.     return( CRYPT_OK );
  274.     }
  275.  
  276. /* Encrypt/decrypt data in CFB mode */
  277.  
  278. int desEncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  279.     {
  280.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  281.     int i, ivCount = cryptInfo->ivCount;
  282.  
  283.     /* If there's any encrypted material left in the IV, use it now */
  284.     if( ivCount )
  285.         {
  286.         int bytesToUse;
  287.  
  288.         /* Find out how much material left in the encrypted IV we can use */
  289.         bytesToUse = DES_BLOCKSIZE - ivCount;
  290.         if( noBytes < bytesToUse )
  291.             bytesToUse = noBytes;
  292.  
  293.         /* Encrypt the data */
  294.         for( i = 0; i < bytesToUse; i++ )
  295.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  296.         memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
  297.  
  298.         /* Adjust the byte count and buffer position */
  299.         noBytes -= bytesToUse;
  300.         buffer += bytesToUse;
  301.         ivCount += bytesToUse;
  302.         }
  303.  
  304.     while( noBytes )
  305.         {
  306.         ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
  307.  
  308.         /* Encrypt the IV */
  309.         des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
  310.                          ( C_Block * ) cryptInfo->currentIV,
  311.                          desKey->desKey, DES_ENCRYPT );
  312.  
  313.         /* XOR the buffer contents with the encrypted IV */
  314.         for( i = 0; i < ivCount; i++ )
  315.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  316.  
  317.         /* Shift the ciphertext into the IV */
  318.         memcpy( cryptInfo->currentIV, buffer, ivCount );
  319.  
  320.         /* Move on to next block of data */
  321.         noBytes -= ivCount;
  322.         buffer += ivCount;
  323.         }
  324.  
  325.     /* Remember how much of the IV is still available for use */
  326.     cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
  327.  
  328.     return( CRYPT_OK );
  329.     }
  330.  
  331. int desDecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  332.     {
  333.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  334.     BYTE temp[ DES_BLOCKSIZE ];
  335.     int i, ivCount = cryptInfo->ivCount;
  336.  
  337.     /* If there's any encrypted material left in the IV, use it now */
  338.     if( ivCount )
  339.         {
  340.         int bytesToUse;
  341.  
  342.         /* Find out how much material left in the encrypted IV we can use */
  343.         bytesToUse = DES_BLOCKSIZE - ivCount;
  344.         if( noBytes < bytesToUse )
  345.             bytesToUse = noBytes;
  346.  
  347.         /* Decrypt the data */
  348.         memcpy( temp, buffer, bytesToUse );
  349.         for( i = 0; i < bytesToUse; i++ )
  350.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  351.         memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
  352.  
  353.         /* Adjust the byte count and buffer position */
  354.         noBytes -= bytesToUse;
  355.         buffer += bytesToUse;
  356.         ivCount += bytesToUse;
  357.         }
  358.  
  359.     while( noBytes )
  360.         {
  361.         ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
  362.  
  363.         /* Encrypt the IV */
  364.         des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
  365.                          ( C_Block * ) cryptInfo->currentIV,
  366.                          desKey->desKey, DES_ENCRYPT );
  367.  
  368.         /* Save the ciphertext */
  369.         memcpy( temp, buffer, ivCount );
  370.  
  371.         /* XOR the buffer contents with the encrypted IV */
  372.         for( i = 0; i < ivCount; i++ )
  373.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  374.  
  375.         /* Shift the ciphertext into the IV */
  376.         memcpy( cryptInfo->currentIV, temp, ivCount );
  377.  
  378.         /* Move on to next block of data */
  379.         noBytes -= ivCount;
  380.         buffer += ivCount;
  381.         }
  382.  
  383.     /* Remember how much of the IV is still available for use */
  384.     cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
  385.  
  386.     /* Clear the temporary buffer */
  387.     zeroise( temp, DES_BLOCKSIZE );
  388.  
  389.     return( CRYPT_OK );
  390.     }
  391.  
  392. /* Encrypt/decrypt data in OFB mode */
  393.  
  394. int desEncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  395.     {
  396.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  397.     int i, ivCount = cryptInfo->ivCount;
  398.  
  399.     /* If there's any encrypted material left in the IV, use it now */
  400.     if( ivCount )
  401.         {
  402.         int bytesToUse;
  403.  
  404.         /* Find out how much material left in the encrypted IV we can use */
  405.         bytesToUse = DES_BLOCKSIZE - ivCount;
  406.         if( noBytes < bytesToUse )
  407.             bytesToUse = noBytes;
  408.  
  409.         /* Encrypt the data */
  410.         for( i = 0; i < bytesToUse; i++ )
  411.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  412.  
  413.         /* Adjust the byte count and buffer position */
  414.         noBytes -= bytesToUse;
  415.         buffer += bytesToUse;
  416.         ivCount += bytesToUse;
  417.         }
  418.  
  419.     while( noBytes )
  420.         {
  421.         ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
  422.  
  423.         /* Encrypt the IV */
  424.         des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
  425.                          ( C_Block * ) cryptInfo->currentIV,
  426.                          desKey->desKey, DES_ENCRYPT );
  427.  
  428.         /* XOR the buffer contents with the encrypted IV */
  429.         for( i = 0; i < ivCount; i++ )
  430.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  431.  
  432.         /* Move on to next block of data */
  433.         noBytes -= ivCount;
  434.         buffer += ivCount;
  435.         }
  436.  
  437.     /* Remember how much of the IV is still available for use */
  438.     cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
  439.  
  440.     return( CRYPT_OK );
  441.     }
  442.  
  443. int desDecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  444.     {
  445.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  446.     int i, ivCount = cryptInfo->ivCount;
  447.  
  448.     /* If there's any encrypted material left in the IV, use it now */
  449.     if( ivCount )
  450.         {
  451.         int bytesToUse;
  452.  
  453.         /* Find out how much material left in the encrypted IV we can use */
  454.         bytesToUse = DES_BLOCKSIZE - ivCount;
  455.         if( noBytes < bytesToUse )
  456.             bytesToUse = noBytes;
  457.  
  458.         /* Decrypt the data */
  459.         for( i = 0; i < bytesToUse; i++ )
  460.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  461.  
  462.         /* Adjust the byte count and buffer position */
  463.         noBytes -= bytesToUse;
  464.         buffer += bytesToUse;
  465.         ivCount += bytesToUse;
  466.         }
  467.  
  468.     while( noBytes )
  469.         {
  470.         ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
  471.  
  472.         /* Encrypt the IV */
  473.         des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
  474.                          ( C_Block * ) cryptInfo->currentIV,
  475.                          desKey->desKey, DES_ENCRYPT );
  476.  
  477.         /* XOR the buffer contents with the encrypted IV */
  478.         for( i = 0; i < ivCount; i++ )
  479.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  480.  
  481.         /* Move on to next block of data */
  482.         noBytes -= ivCount;
  483.         buffer += ivCount;
  484.         }
  485.  
  486.     /* Remember how much of the IV is still available for use */
  487.     cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
  488.  
  489.     return( CRYPT_OK );
  490.     }
  491.  
  492. /* Encrypt/decrypt data in PCBC mode.  We have to carry along the previous
  493.    block's plaintext as well as the IV so we store it after the IV in the
  494.    buffer allocated for IV storage.  Initially the plaintextChain value will
  495.    be null as the IV buffer is zeroed on init, so we don't need to worry
  496.    about the special case of the first ciphertext block */
  497.  
  498. int desEncryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  499.     {
  500.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  501.     BYTE *plaintextChain = cryptInfo->currentIV + DES_BLOCKSIZE;
  502.     BYTE temp[ DES_BLOCKSIZE ];
  503.     int blockCount = noBytes / DES_BLOCKSIZE;
  504.  
  505.     /* Make sure the data length is a multiple of the block size */
  506.     if( noBytes % DES_BLOCKSIZE )
  507.         return( CRYPT_BADPARM3 );
  508.  
  509.     while( blockCount-- )
  510.         {
  511.         int i;
  512.  
  513.         /* Remember the previous block's plaintext and copy the current
  514.            plaintext for chaining in the next iteration */
  515.         memcpy( temp, plaintextChain, DES_BLOCKSIZE );
  516.         memcpy( plaintextChain, buffer, DES_BLOCKSIZE );
  517.  
  518.         /* XOR the buffer contents with the IV and previous plaintext */
  519.         for( i = 0; i < DES_BLOCKSIZE; i++ )
  520.             buffer[ i ] ^= cryptInfo->currentIV[ i ] ^ temp[ i ];
  521.  
  522.         /* Encrypt a block of data */
  523.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  524.                          desKey->desKey, DES_ENCRYPT );
  525.  
  526.         /* Shift ciphertext into IV */
  527.         memcpy( cryptInfo->currentIV, buffer, DES_BLOCKSIZE );
  528.  
  529.         /* Move on to next block of data */
  530.         buffer += DES_BLOCKSIZE;
  531.         }
  532.  
  533.     /* Clear the temporary buffer */
  534.     zeroise( temp, DES_BLOCKSIZE );
  535.  
  536.     return( CRYPT_OK );
  537.     }
  538.  
  539. int desDecryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  540.     {
  541.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  542.     BYTE *plaintextChain = cryptInfo->currentIV + DES_BLOCKSIZE;
  543.     BYTE temp[ DES_BLOCKSIZE ];
  544.     int blockCount = noBytes / DES_BLOCKSIZE;
  545.  
  546.     /* Make sure the data length is a multiple of the block size */
  547.     if( noBytes % DES_BLOCKSIZE )
  548.         return( CRYPT_BADPARM3 );
  549.  
  550.     while( blockCount-- )
  551.         {
  552.         int i;
  553.  
  554.         /* Save the ciphertext */
  555.         memcpy( temp, buffer, DES_BLOCKSIZE );
  556.  
  557.         /* Decrypt a block of data */
  558.         des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
  559.                          desKey->desKey, DES_DECRYPT );
  560.  
  561.         /* XOR the buffer contents with the IV and previous plaintext */
  562.         for( i = 0; i < DES_BLOCKSIZE; i++ )
  563.             buffer[ i ] ^= cryptInfo->currentIV[ i ] ^ plaintextChain[ i ];
  564.  
  565.         /* Shift the ciphertext into the IV and copy the current plaintext
  566.            for chaining in the next iteration */
  567.         memcpy( cryptInfo->currentIV, temp, DES_BLOCKSIZE );
  568.         memcpy( plaintextChain, buffer, DES_BLOCKSIZE );
  569.  
  570.         /* Move on to next block of data */
  571.         buffer += DES_BLOCKSIZE;
  572.         }
  573.  
  574.     /* Clear the temporary buffer */
  575.     zeroise( temp, DES_BLOCKSIZE );
  576.  
  577.     return( CRYPT_OK );
  578.     }
  579.  
  580. /****************************************************************************
  581. *                                                                            *
  582. *                            DES Key Management Routines                        *
  583. *                                                                            *
  584. ****************************************************************************/
  585.  
  586. /* Get/set algorithm-specific parameters */
  587.  
  588. BOOLEAN getDESinfo( const CRYPT_INFO *cryptInfo )
  589.     {
  590.     return( ( ( DES_KEY * ) cryptInfo->key )->isDESX );
  591.     }
  592.  
  593. void setDESinfo( CRYPT_INFO *cryptInfo, const BOOLEAN isDESX )
  594.     {
  595.     ( ( DES_KEY * ) cryptInfo->key )->isDESX = isDESX;
  596.     }
  597.  
  598. int desGetKeysize( CRYPT_INFO *cryptInfo )
  599.     {
  600.     return( ( ( ( DES_KEY * ) cryptInfo->key )->isDESX ) ? \
  601.             bitsToBytes( 64 + 64 + 64 ) : bitsToBytes( 64 ) );
  602.     }
  603.  
  604. /* Key schedule a DES key */
  605.  
  606. int desInitKey( CRYPT_INFO *cryptInfo )
  607.     {
  608.     DES_KEY *desKey = ( DES_KEY * ) cryptInfo->key;
  609.  
  610.     /* If it's a long key, make sure we're using DESX */
  611.     if( cryptInfo->userKeyLength > bitsToBytes( 64 ) && !desKey->isDESX )
  612.         return( CRYPT_BADPARM3 );
  613.  
  614.     /* Call the libdes key schedule code.  Returns with -1 if the key parity
  615.        is wrong (which never occurs since we force the correct parity) or -2
  616.        if a weak key is used */
  617.     des_set_odd_parity( ( C_Block * ) cryptInfo->userKey );
  618.     if( key_sched( ( C_Block * ) cryptInfo->userKey,
  619.                    *( ( Key_schedule * ) cryptInfo->key ) ) )
  620.         return( CRYPT_BADPARM );
  621.     if( desKey->isDESX )
  622.         {
  623.         /* DESX isn't implemented yet - need test vectors before using it */
  624.         return( CRYPT_ERROR );    /*!!!!!!!!!!!!!!!!*/
  625.         }
  626.  
  627.     return( CRYPT_OK );
  628.     }
  629.