home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / cryptext.exe / decrypt.c < prev    next >
C/C++ Source or Header  |  1997-03-04  |  5KB  |  228 lines

  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include "sha.h"
  5. #include "rc4.h"
  6.  
  7. #define BUFFERSIZE 16384
  8. #define KEYSIZE 20
  9.  
  10. union SHAKEY
  11. {
  12.     DWORD    keyW [KEYSIZE / sizeof (DWORD)];
  13.     BYTE    keyB [KEYSIZE];
  14. };
  15.  
  16. typedef struct tagIV
  17. {
  18.     FILETIME    fileTime;
  19.     int            rand;
  20. } IV, *LPIV;
  21.  
  22. union unionIV
  23. {
  24.     IV        iv;
  25.     BYTE    byteIV [sizeof (IV)];
  26. };
  27.  
  28.  
  29. // functions
  30. void    LoadIV (HANDLE, LPBYTE);
  31. BOOL    CheckKeyIsValid (LPSTR, LPBYTE);
  32. void    CreateUniqueKey (LPDWORD, LPBYTE, LPIV);
  33.  
  34. int main (int argc, char *argv[])
  35. {
  36.     union unionIV iv;
  37.     union SHAKEY key, uniqueKey;
  38.     rc4Key         streamKey;
  39.     DWORD        nBytesSoFar;
  40.     DWORD        nBytesRead, nBytesWritten;
  41.     HANDLE         hFile;
  42.     char        szFile [_MAX_PATH];
  43.     char        szNewFile [_MAX_PATH];
  44.     char        szPass [_MAX_PATH];
  45.     BYTE        lpFileBuffer [BUFFERSIZE];
  46.  
  47.     // check parameters
  48.     // must be two parameters
  49.     if (argc != 3)
  50.     {
  51.         printf ("\nInvalid parameters. Command line must be:"
  52.             "\n\tDECRYPT \"<passphrase>\" <filename>"
  53.             "\n e.g.\tDECRYPT \"goggomobile\", C:\\TEMP\\TEST.TXT.$#!\n");
  54.         return 1;
  55.     }
  56.     // get passphrase and filename
  57.     lstrcpy (szPass, argv[1]);
  58.     lstrcpy (szFile, argv[2]);
  59.  
  60.     // check for validity of passphrase
  61.     if (!CheckKeyIsValid (szPass, key.keyB))
  62.         return 1;
  63.     
  64.     // open the file
  65.     hFile = CreateFile (szFile,
  66.         GENERIC_READ | GENERIC_WRITE, 0, NULL,
  67.         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  68.  
  69.     if (hFile == INVALID_HANDLE_VALUE)
  70.     {
  71.         printf ("\nError opening %s\n", szFile);
  72.            return 1;
  73.     }
  74.  
  75.     // Load the iv
  76.     LoadIV (hFile, iv.byteIV);
  77.  
  78.     // use the iv to create a unique key for this file
  79.     CreateUniqueKey (uniqueKey.keyW, key.keyB, &(iv.iv));
  80.  
  81.     // do RC4 setup
  82.     rc4Setup (uniqueKey.keyB, KEYSIZE, &streamKey);
  83.  
  84.     // decrypt the file
  85.     nBytesSoFar = 0;
  86.     do
  87.     {
  88.         // fill the buffer from the file
  89.         ReadFile (hFile, lpFileBuffer, BUFFERSIZE, &nBytesRead, NULL);
  90.         if (nBytesRead)
  91.         {
  92.             // encrypt or decrypt as required
  93.             rc4 (lpFileBuffer, nBytesRead, &streamKey);
  94.             // reset the file pointer for the write
  95.             SetFilePointer (hFile,
  96.                 nBytesSoFar,        // offset into file
  97.                 NULL,                // only using files < 2^32 in size
  98.                 FILE_BEGIN);        // starting point for offset
  99.             // write the buffer
  100.             WriteFile (hFile, lpFileBuffer, nBytesRead,
  101.                 &nBytesWritten, NULL);
  102.             // increment byte count
  103.             nBytesSoFar += nBytesRead;
  104.         }
  105.     } while (nBytesRead);
  106.  
  107.     // close the file
  108.     CloseHandle (hFile);
  109.     // rename the file to remove the encryption extension
  110.     lstrcpyn (szNewFile, szFile, lstrlen (szFile) - 3);
  111.     MoveFile (szFile, szNewFile);
  112.     // finish
  113.     return 0;
  114. }
  115.  
  116.  
  117. void
  118. LoadIV (HANDLE hFile, LPBYTE ivAsBytes)
  119. {
  120.     DWORD    nBytesRead;
  121.     
  122.     // set the pointer to the beginning of the iv
  123.     SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
  124.  
  125.     // read the iv
  126.     ReadFile (hFile, ivAsBytes, sizeof (IV), &nBytesRead, NULL);
  127.  
  128.     // set the pointer to the last real byte in the file
  129.     SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
  130.  
  131.     // set the new EOF
  132.     SetEndOfFile (hFile);
  133.  
  134.     // reset file pointer to the beginning of the file
  135.     SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
  136.  
  137.     return;
  138. }
  139.  
  140.  
  141. BOOL
  142. CheckKeyIsValid (LPSTR szPass, LPBYTE lpKey)
  143. {
  144.     LONG    dwErrorCode;
  145.     DWORD    dwSize;
  146.     HKEY    hKey;
  147.     union SHAKEY hashedKey, testKey;
  148.     char    szKey [KEYSIZE*2+1];
  149.     char    szTemp [_MAX_PATH+KEYSIZE+1];
  150.  
  151.     // open the app key
  152.     dwErrorCode = RegOpenKeyEx (HKEY_CURRENT_USER,
  153.         "Software\\Cryptext\\Configuration",
  154.         0,
  155.         KEY_ALL_ACCESS,
  156.         &hKey);
  157.  
  158.     // succeeded?
  159.     if (dwErrorCode != ERROR_SUCCESS)
  160.     {
  161.         printf ("\nPassword checksum not found in registry\n");
  162.         return FALSE;
  163.     }
  164.     else
  165.     {
  166.         // get the hashed encryption key from the registry
  167.         dwSize = KEYSIZE;
  168.         dwErrorCode = RegQueryValueEx (hKey,
  169.             "HashedKey",
  170.             NULL,
  171.             NULL,
  172.             hashedKey.keyB,
  173.             &dwSize);
  174.  
  175.         // close the registry key
  176.         RegCloseKey (hKey);
  177.     }
  178.  
  179.     // encryption key not found or key not 160 bits long
  180.     if (dwErrorCode != ERROR_SUCCESS || dwSize != KEYSIZE)
  181.     {
  182.         printf ("\nPassword checksum not found or invalid\n");
  183.         return FALSE;
  184.     }
  185.     
  186.     sha_memory ((LPBYTE)szPass, lstrlen (szPass), testKey.keyW);
  187.     
  188.     // copy the key
  189.     CopyMemory (lpKey, testKey.keyB, KEYSIZE);
  190.  
  191.     // convert it to ASCII representation
  192.     wsprintf (szKey, "%08lx%08lx%08lx%08lx%08lx",
  193.         testKey.keyW[0], testKey.keyW[1], testKey.keyW[2], testKey.keyW[3], testKey.keyW[4]);
  194.  
  195.     // add the hash to the password
  196.     wsprintf (szTemp, "%s%s", szPass, szKey);
  197.  
  198.     // hash again
  199.     sha_memory ((LPBYTE)szTemp, lstrlen (szTemp), testKey.keyW);
  200.  
  201.     // now verify against the stored hashed key
  202.     if (hashedKey.keyW[0] != testKey.keyW[0] ||
  203.         hashedKey.keyW[1] != testKey.keyW[1] ||
  204.         hashedKey.keyW[2] != testKey.keyW[2] ||
  205.         hashedKey.keyW[3] != testKey.keyW[3] ||
  206.         hashedKey.keyW[4] != testKey.keyW[4])
  207.     {
  208.         printf ("\nInvalid passphrase\n");
  209.         return FALSE;
  210.     }
  211.  
  212.     return TRUE;
  213. }
  214.  
  215.  
  216. void
  217. CreateUniqueKey (LPDWORD uniqueKey, LPBYTE lpKey, LPIV lpiv)
  218. {
  219.     BYTE    buffer [KEYSIZE + sizeof (IV)];
  220.  
  221.     // copy hash of passphrase
  222.     CopyMemory (buffer, lpKey, KEYSIZE);
  223.     // copy date/time
  224.     CopyMemory (buffer+KEYSIZE, lpiv, sizeof (IV));
  225.     // hash to create key for rc4
  226.     sha_memory (buffer, KEYSIZE + sizeof (IV), uniqueKey);
  227. }
  228.