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

  1. /****************************************************************************
  2. *                                                                            *
  3. *                        cryptlib Safer 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 "safer.h"
  16. #else
  17.   #include "safer/safer.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /* The size of the expanded SAFER keys */
  21.  
  22. #define SAFER_EXPANDED_KEYSIZE        SAFER_KEYLEN
  23.  
  24. /****************************************************************************
  25. *                                                                            *
  26. *                            SAFER Self-test Routines                        *
  27. *                                                                            *
  28. ****************************************************************************/
  29.  
  30. #include "testsafr.h"
  31.  
  32. /* Test the SAFER-SK code against the test vectors from the ETH reference
  33.    implementation */
  34.  
  35. int saferSelfTest( void )
  36.     {
  37.     BYTE temp[ SAFER_BLOCKSIZE ];
  38.     BYTE key[ SAFER_KEYLEN ];
  39.     int i;
  40.  
  41.     for( i = 0; i < sizeof( testSafer ) / sizeof( SAFER_TEST ); i++ )
  42.         {
  43.         memcpy( temp, testSafer[ i ].plaintext, SAFER_BLOCKSIZE );
  44.         if( testSafer[ i ].rounds == SAFER_K64_ROUNDS )
  45.             /* We always do a 128-bit key schedule internally so if we're
  46.                using a 64-bit key we mirror the first 64 bits into the second
  47.                64 bits */
  48.             memcpy( testSafer[ i ].key + bitsToBytes( 64 ),
  49.                     testSafer[ i ].key, bitsToBytes( 64 ) );
  50.         saferExpandKey( key, testSafer[ i ].key, testSafer[ i ].rounds, TRUE );
  51.         saferEncryptBlock( temp, key );
  52.         if( memcmp( testSafer[ i ].ciphertext, temp, SAFER_BLOCKSIZE ) )
  53.             return( CRYPT_ERROR );
  54.         }
  55.  
  56.     return( CRYPT_OK );
  57.     }
  58.  
  59. /****************************************************************************
  60. *                                                                            *
  61. *                            Init/Shutdown Routines                            *
  62. *                                                                            *
  63. ****************************************************************************/
  64.  
  65. /* Perform auxiliary init and shutdown actions on an encryption context */
  66.  
  67. int saferInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
  68.     {
  69.     CRYPT_INFO_SAFER *cryptInfoExPtr = ( CRYPT_INFO_SAFER * ) cryptInfoEx;
  70.     int status;
  71.  
  72.     /* Allocate memory for the key and the algorithm-specific data within
  73.        the crypt context and set up any pointers we need.  We don't process
  74.        cryptInfoExPtr->rounds at this point since we set things up when we
  75.        perform the saferInitKey() function, as the number of rounds is key-
  76.        dependant */
  77.     if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
  78.         return( CRYPT_INITED );
  79.     if( ( status = secureMalloc( &cryptInfo->key, SAFER_EXPANDED_KEYSIZE ) ) != CRYPT_OK )
  80.         return( status );
  81.     if( cryptInfoExPtr->rounds == CRYPT_USE_DEFAULT && \
  82.         cryptInfoExPtr->useSaferSK == CRYPT_USE_DEFAULT )
  83.         cryptInfo->privateUseDefaults = TRUE;
  84.     if( ( status = secureMalloc( &cryptInfo->privateData, sizeof( CRYPT_INFO_SAFER ) ) ) != CRYPT_OK )
  85.         {
  86.         secureFree( &cryptInfo->key );
  87.         return( status );
  88.         }
  89.     if( cryptInfoExPtr->useSaferSK == CRYPT_USE_DEFAULT )
  90.         setSaferInfo( cryptInfo, FALSE, cryptInfoExPtr->rounds );
  91.     else
  92.         setSaferInfo( cryptInfo, ( BOOLEAN ) cryptInfoExPtr->useSaferSK,
  93.                       cryptInfoExPtr->rounds );
  94.     cryptInfo->keyLength = SAFER_EXPANDED_KEYSIZE;
  95.  
  96.     return( CRYPT_OK );
  97.     }
  98.  
  99. int saferInit( CRYPT_INFO *cryptInfo )
  100.     {
  101.     CRYPT_INFO_SAFER cryptInfoEx;
  102.  
  103.     /* Use the default number of rounds and the non-enhanced SAFER */
  104.     memset( &cryptInfoEx, 0, sizeof( CRYPT_INFO_SAFER ) );
  105.     cryptInfoEx.rounds = CRYPT_USE_DEFAULT;
  106.     cryptInfoEx.useSaferSK = CRYPT_USE_DEFAULT;
  107.  
  108.     /* Pass through to the extended setup routine */
  109.     return( saferInitEx( cryptInfo, &cryptInfoEx ) );
  110.     }
  111.  
  112. int saferEnd( CRYPT_INFO *cryptInfo )
  113.     {
  114.     /* Free any allocated memory */
  115.     secureFree( &cryptInfo->key );
  116.     secureFree( &cryptInfo->privateData );
  117.  
  118.     return( CRYPT_OK );
  119.     }
  120.  
  121. /****************************************************************************
  122. *                                                                            *
  123. *                            SAFER En/Decryption Routines                        *
  124. *                                                                            *
  125. ****************************************************************************/
  126.  
  127. /* Encrypt/decrypt data in ECB mode */
  128.  
  129. int saferEncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  130.     {
  131.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  132.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  133.  
  134.     /* Make sure the data length is a multiple of the block size */
  135.     if( noBytes % SAFER_BLOCKSIZE )
  136.         return( CRYPT_BADPARM3 );
  137.  
  138.     while( blockCount-- )
  139.         {
  140.         /* Encrypt a block of data */
  141.         saferEncryptBlock( buffer, saferKey );
  142.  
  143.         /* Move on to next block of data */
  144.         buffer += SAFER_BLOCKSIZE;
  145.         }
  146.  
  147.     return( CRYPT_OK );
  148.     }
  149.  
  150. int saferDecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  151.     {
  152.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  153.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  154.  
  155.     /* Make sure the data length is a multiple of the block size */
  156.     if( noBytes % SAFER_BLOCKSIZE )
  157.         return( CRYPT_BADPARM3 );
  158.  
  159.     while( blockCount-- )
  160.         {
  161.         /* Decrypt a block of data */
  162.         saferDecryptBlock( buffer, saferKey );
  163.  
  164.         /* Move on to next block of data */
  165.         buffer += SAFER_BLOCKSIZE;
  166.         }
  167.  
  168.     return( CRYPT_OK );
  169.     }
  170.  
  171. /* Encrypt/decrypt data in CBC mode */
  172.  
  173. int saferEncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  174.     {
  175.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  176.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  177.  
  178.     /* Make sure the data length is a multiple of the block size */
  179.     if( noBytes % SAFER_BLOCKSIZE )
  180.         return( CRYPT_BADPARM3 );
  181.  
  182.     while( blockCount-- )
  183.         {
  184.         int i;
  185.  
  186.         /* XOR the buffer contents with the IV */
  187.         for( i = 0; i < SAFER_BLOCKSIZE; i++ )
  188.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  189.  
  190.         /* Encrypt a block of data */
  191.         saferEncryptBlock( buffer, saferKey );
  192.  
  193.         /* Shift ciphertext into IV */
  194.         memcpy( cryptInfo->currentIV, buffer, SAFER_BLOCKSIZE );
  195.  
  196.         /* Move on to next block of data */
  197.         buffer += SAFER_BLOCKSIZE;
  198.         }
  199.  
  200.     return( CRYPT_OK );
  201.     }
  202.  
  203. int saferDecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  204.     {
  205.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  206.     BYTE temp[ SAFER_BLOCKSIZE ];
  207.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  208.  
  209.     /* Make sure the data length is a multiple of the block size */
  210.     if( noBytes % SAFER_BLOCKSIZE )
  211.         return( CRYPT_BADPARM3 );
  212.  
  213.     while( blockCount-- )
  214.         {
  215.         int i;
  216.  
  217.         /* Save the ciphertext */
  218.         memcpy( temp, buffer, SAFER_BLOCKSIZE );
  219.  
  220.         /* Decrypt a block of data */
  221.         saferDecryptBlock( buffer, saferKey );
  222.  
  223.         /* XOR the buffer contents with the IV */
  224.         for( i = 0; i < SAFER_BLOCKSIZE; i++ )
  225.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  226.  
  227.         /* Shift the ciphertext into the IV */
  228.         memcpy( cryptInfo->currentIV, temp, SAFER_BLOCKSIZE );
  229.  
  230.         /* Move on to next block of data */
  231.         buffer += SAFER_BLOCKSIZE;
  232.         }
  233.  
  234.     /* Clear the temporary buffer */
  235.     zeroise( temp, SAFER_BLOCKSIZE );
  236.  
  237.     return( CRYPT_OK );
  238.     }
  239.  
  240. /* Encrypt/decrypt data in CFB mode */
  241.  
  242. int saferEncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  243.     {
  244.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  245.     int i, ivCount = cryptInfo->ivCount;
  246.  
  247.     /* If there's any encrypted material left in the IV, use it now */
  248.     if( ivCount )
  249.         {
  250.         int bytesToUse;
  251.  
  252.         /* Find out how much material left in the encrypted IV we can use */
  253.         bytesToUse = SAFER_BLOCKSIZE - ivCount;
  254.         if( noBytes < bytesToUse )
  255.             bytesToUse = noBytes;
  256.  
  257.         /* Encrypt the data */
  258.         for( i = 0; i < bytesToUse; i++ )
  259.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  260.         memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
  261.  
  262.         /* Adjust the byte count and buffer position */
  263.         noBytes -= bytesToUse;
  264.         buffer += bytesToUse;
  265.         ivCount += bytesToUse;
  266.         }
  267.  
  268.     while( noBytes )
  269.         {
  270.         ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  271.  
  272.         /* Encrypt the IV */
  273.         saferEncryptBlock( cryptInfo->currentIV, saferKey );
  274.  
  275.         /* XOR the buffer contents with the encrypted IV */
  276.         for( i = 0; i < ivCount; i++ )
  277.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  278.  
  279.         /* Shift the ciphertext into the IV */
  280.         memcpy( cryptInfo->currentIV, buffer, ivCount );
  281.  
  282.         /* Move on to next block of data */
  283.         noBytes -= ivCount;
  284.         buffer += ivCount;
  285.         }
  286.  
  287.     /* Remember how much of the IV is still available for use */
  288.     cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
  289.  
  290.     return( CRYPT_OK );
  291.     }
  292.  
  293. /* Decrypt data in CFB mode.  Note that the transformation can be made
  294.    faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
  295.    all in one loop */
  296.  
  297. int saferDecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  298.     {
  299.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  300.     BYTE temp[ SAFER_BLOCKSIZE ];
  301.     int i, ivCount = cryptInfo->ivCount;
  302.  
  303.     /* If there's any encrypted material left in the IV, use it now */
  304.     if( ivCount )
  305.         {
  306.         int bytesToUse;
  307.  
  308.         /* Find out how much material left in the encrypted IV we can use */
  309.         bytesToUse = SAFER_BLOCKSIZE - ivCount;
  310.         if( noBytes < bytesToUse )
  311.             bytesToUse = noBytes;
  312.  
  313.         /* Decrypt the data */
  314.         memcpy( temp, buffer, bytesToUse );
  315.         for( i = 0; i < bytesToUse; i++ )
  316.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  317.         memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
  318.  
  319.         /* Adjust the byte count and buffer position */
  320.         noBytes -= bytesToUse;
  321.         buffer += bytesToUse;
  322.         ivCount += bytesToUse;
  323.         }
  324.  
  325.     while( noBytes )
  326.         {
  327.         ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  328.  
  329.         /* Encrypt the IV */
  330.         saferEncryptBlock( cryptInfo->currentIV, saferKey );
  331.  
  332.         /* Save the ciphertext */
  333.         memcpy( temp, buffer, ivCount );
  334.  
  335.         /* XOR the buffer contents with the encrypted IV */
  336.         for( i = 0; i < ivCount; i++ )
  337.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  338.  
  339.         /* Shift the ciphertext into the IV */
  340.         memcpy( cryptInfo->currentIV, temp, ivCount );
  341.  
  342.         /* Move on to next block of data */
  343.         noBytes -= ivCount;
  344.         buffer += ivCount;
  345.         }
  346.  
  347.     /* Remember how much of the IV is still available for use */
  348.     cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
  349.  
  350.     /* Clear the temporary buffer */
  351.     zeroise( temp, SAFER_BLOCKSIZE );
  352.  
  353.     return( CRYPT_OK );
  354.     }
  355.  
  356. /* Encrypt/decrypt data in OFB mode */
  357.  
  358. int saferEncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  359.     {
  360.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  361.     int i, ivCount = cryptInfo->ivCount;
  362.  
  363.     /* If there's any encrypted material left in the IV, use it now */
  364.     if( ivCount )
  365.         {
  366.         int bytesToUse;
  367.  
  368.         /* Find out how much material left in the encrypted IV we can use */
  369.         bytesToUse = SAFER_BLOCKSIZE - ivCount;
  370.         if( noBytes < bytesToUse )
  371.             bytesToUse = noBytes;
  372.  
  373.         /* Encrypt the data */
  374.         for( i = 0; i < bytesToUse; i++ )
  375.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  376.  
  377.         /* Adjust the byte count and buffer position */
  378.         noBytes -= bytesToUse;
  379.         buffer += bytesToUse;
  380.         ivCount += bytesToUse;
  381.         }
  382.  
  383.     while( noBytes )
  384.         {
  385.         ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  386.  
  387.         /* Encrypt the IV */
  388.         saferEncryptBlock( cryptInfo->currentIV, saferKey );
  389.  
  390.         /* XOR the buffer contents with the encrypted IV */
  391.         for( i = 0; i < ivCount; i++ )
  392.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  393.  
  394.         /* Move on to next block of data */
  395.         noBytes -= ivCount;
  396.         buffer += ivCount;
  397.         }
  398.  
  399.     /* Remember how much of the IV is still available for use */
  400.     cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
  401.  
  402.     return( CRYPT_OK );
  403.     }
  404.  
  405. /* Decrypt data in OFB mode */
  406.  
  407. int saferDecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  408.     {
  409.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  410.     int i, ivCount = cryptInfo->ivCount;
  411.  
  412.     /* If there's any encrypted material left in the IV, use it now */
  413.     if( ivCount )
  414.         {
  415.         int bytesToUse;
  416.  
  417.         /* Find out how much material left in the encrypted IV we can use */
  418.         bytesToUse = SAFER_BLOCKSIZE - ivCount;
  419.         if( noBytes < bytesToUse )
  420.             bytesToUse = noBytes;
  421.  
  422.         /* Decrypt the data */
  423.         for( i = 0; i < bytesToUse; i++ )
  424.             buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
  425.  
  426.         /* Adjust the byte count and buffer position */
  427.         noBytes -= bytesToUse;
  428.         buffer += bytesToUse;
  429.         ivCount += bytesToUse;
  430.         }
  431.  
  432.     while( noBytes )
  433.         {
  434.         ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
  435.  
  436.         /* Encrypt the IV */
  437.         saferEncryptBlock( cryptInfo->currentIV, saferKey );
  438.  
  439.         /* XOR the buffer contents with the encrypted IV */
  440.         for( i = 0; i < ivCount; i++ )
  441.             buffer[ i ] ^= cryptInfo->currentIV[ i ];
  442.  
  443.         /* Move on to next block of data */
  444.         noBytes -= ivCount;
  445.         buffer += ivCount;
  446.         }
  447.  
  448.     /* Remember how much of the IV is still available for use */
  449.     cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
  450.  
  451.     return( CRYPT_OK );
  452.     }
  453.  
  454. /* Encrypt/decrypt data in PCBC mode.  We have to carry along the previous
  455.    block's plaintext as well as the IV so we store it after the IV in the
  456.    buffer allocated for IV storage.  Initially the plaintextChain value will
  457.    be null as the IV buffer is zeroed on init, so we don't need to worry
  458.    about the special case of the first ciphertext block */
  459.  
  460. int saferEncryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  461.     {
  462.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  463.     BYTE *plaintextChain = cryptInfo->currentIV + SAFER_BLOCKSIZE;
  464.     BYTE temp[ SAFER_BLOCKSIZE ];
  465.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  466.  
  467.     /* Make sure the data length is a multiple of the block size */
  468.     if( noBytes % SAFER_BLOCKSIZE )
  469.         return( CRYPT_BADPARM3 );
  470.  
  471.     while( blockCount-- )
  472.         {
  473.         int i;
  474.  
  475.         /* Remember the previous block's plaintext and copy the current
  476.            plaintext for chaining in the next iteration */
  477.         memcpy( temp, plaintextChain, SAFER_BLOCKSIZE );
  478.         memcpy( plaintextChain, buffer, SAFER_BLOCKSIZE );
  479.  
  480.         /* XOR the buffer contents with the IV and previous plaintext */
  481.         for( i = 0; i < SAFER_BLOCKSIZE; i++ )
  482.             buffer[ i ] ^= cryptInfo->currentIV[ i ] ^ temp[ i ];
  483.  
  484.         /* Encrypt a block of data */
  485.         saferEncryptBlock( buffer, saferKey );
  486.  
  487.         /* Shift ciphertext into IV */
  488.         memcpy( cryptInfo->currentIV, buffer, SAFER_BLOCKSIZE );
  489.  
  490.         /* Move on to next block of data */
  491.         buffer += SAFER_BLOCKSIZE;
  492.         }
  493.  
  494.     /* Clear the temporary buffer */
  495.     zeroise( temp, SAFER_BLOCKSIZE );
  496.  
  497.     return( CRYPT_OK );
  498.     }
  499.  
  500. int saferDecryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
  501.     {
  502.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  503.     BYTE *plaintextChain = cryptInfo->currentIV + SAFER_BLOCKSIZE;
  504.     BYTE temp[ SAFER_BLOCKSIZE ];
  505.     int blockCount = noBytes / SAFER_BLOCKSIZE;
  506.  
  507.     /* Make sure the data length is a multiple of the block size */
  508.     if( noBytes % SAFER_BLOCKSIZE )
  509.         return( CRYPT_BADPARM3 );
  510.  
  511.     while( blockCount-- )
  512.         {
  513.         int i;
  514.  
  515.         /* Save the ciphertext */
  516.         memcpy( temp, buffer, SAFER_BLOCKSIZE );
  517.  
  518.         /* Decrypt a block of data */
  519.         saferDecryptBlock( buffer, saferKey );
  520.  
  521.         /* XOR the buffer contents with the IV and previous plaintext */
  522.         for( i = 0; i < SAFER_BLOCKSIZE; i++ )
  523.             buffer[ i ] ^= cryptInfo->currentIV[ i ] ^ plaintextChain[ i ];
  524.  
  525.         /* Shift the ciphertext into the IV and copy the current plaintext
  526.            for chaining in the next iteration */
  527.         memcpy( cryptInfo->currentIV, temp, SAFER_BLOCKSIZE );
  528.         memcpy( plaintextChain, buffer, SAFER_BLOCKSIZE );
  529.  
  530.         /* Move on to next block of data */
  531.         buffer += SAFER_BLOCKSIZE;
  532.         }
  533.  
  534.     /* Clear the temporary buffer */
  535.     zeroise( temp, SAFER_BLOCKSIZE );
  536.  
  537.     return( CRYPT_OK );
  538.     }
  539.  
  540.  
  541. /****************************************************************************
  542. *                                                                            *
  543. *                            SAFER Key Management Routines                    *
  544. *                                                                            *
  545. ****************************************************************************/
  546.  
  547. /* Get/set algorithm-specific parameters */
  548.  
  549. int getSaferInfo( const CRYPT_INFO *cryptInfo, BOOLEAN *useSaferSK )
  550.     {
  551.     CRYPT_INFO_SAFER *cryptInfoEx = ( CRYPT_INFO_SAFER * ) cryptInfo->privateData;
  552.  
  553.     *useSaferSK = ( BOOLEAN ) cryptInfoEx->useSaferSK;
  554.     return( cryptInfoEx->rounds );
  555.     }
  556.  
  557. void setSaferInfo( CRYPT_INFO *cryptInfo, const BOOLEAN useSaferSK,
  558.                    const int rounds )
  559.     {
  560.     CRYPT_INFO_SAFER *cryptInfoEx = ( CRYPT_INFO_SAFER * ) cryptInfo->privateData;
  561.  
  562.     cryptInfoEx->useSaferSK = ( int ) useSaferSK;
  563.     cryptInfoEx->rounds = rounds;
  564.     }
  565.  
  566. int saferGetKeysize( CRYPT_INFO *cryptInfo )
  567.     {
  568.     /* This is tricky, since we dynamically adjust the key type to 64 or 128
  569.        bits depending on how much keying data we've been passed by the user,
  570.        but we can't tell in advance how much this will be.  We get around
  571.        this by taking advantage of the fact that when the library queries the
  572.        key size for an encryption context with no key loaded, it always wants
  573.        to know the maximum amount of data it can use for a key, so we just
  574.        return the maximum value */
  575.     if( cryptInfo->userKeyLength == 0 )
  576.         return( bitsToBytes( 128 ) );
  577.  
  578.     /* If the key has already been set up, just return the type of key we're
  579.        using */
  580.     return( ( cryptInfo->userKeyLength <= bitsToBytes( 64 ) ) ? \
  581.             bitsToBytes( 64 ) : bitsToBytes( 128 ) );
  582.     }
  583.  
  584. /* Key schedule a SAFER key */
  585.  
  586. int saferInitKey( CRYPT_INFO *cryptInfo )
  587.     {
  588.     CRYPT_INFO_SAFER *cryptInfoEx = ( CRYPT_INFO_SAFER * ) cryptInfo->privateData;
  589.     BYTE *saferKey = ( BYTE * ) cryptInfo->key;
  590.     BOOLEAN shortKey = cryptInfo->userKeyLength <= bitsToBytes( 64 );
  591.     int currentRounds;
  592.  
  593.     /* If the number of rounds has been preset, use this value */
  594.     if( cryptInfoEx->rounds != CRYPT_USE_DEFAULT )
  595.         currentRounds = cryptInfoEx->rounds;
  596.     else
  597.         /* Determine the number of rounds to use based on the key size */
  598.         if( cryptInfoEx->useSaferSK )
  599.             currentRounds = ( shortKey ) ? SAFER_SK64_ROUNDS : SAFER_SK128_ROUNDS;
  600.         else
  601.             currentRounds = ( shortKey ) ? SAFER_K64_ROUNDS : SAFER_K128_ROUNDS;
  602.  
  603.     /* Generate an expanded SAFER key */
  604.     if( shortKey )
  605.         /* We always do a 128-bit key schedule internally so if we're using a
  606.            64-bit key we mirror the first 64 bits into the second 64 bits */
  607.         memcpy( cryptInfo->userKey + bitsToBytes( 64 ), cryptInfo->userKey,
  608.                 bitsToBytes( 64 ) );
  609.     saferExpandKey(    saferKey, cryptInfo->userKey, currentRounds,
  610.                     cryptInfoEx->useSaferSK );
  611.  
  612.     return( CRYPT_OK );
  613.     }
  614.