home *** CD-ROM | disk | FTP | other *** search
/ PCMania 10 / Pcmania_Ep2_10_CD-01.iso / ARTICULOS / tecnologia / DLOCK2.ZIP / DLOCK2.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-21  |  22.4 KB  |  751 lines

  1. /* DLOCK2.CPP -- Diamond2 Block Cipher Demonstration program.
  2.  
  3. This program is used to test and validate the implementation of the
  4. Diamond2 Block Cipher in software.  It can also encrypt or decrypt
  5. files using ten round Diamond2 in cyphertext feedback mode and a key
  6. from a command line parameter, environment variable, or keyboard.
  7.  
  8. There are lots of ways to improve upon this program:  (1) add key
  9. management, (2) use more clever chaining methods, (3) add header
  10. information to the encrypted file to allow the decryption program to
  11. automatically determine the proper algorithm(s) needed to decrypt and
  12. decompress, (4) add data compression and/or noise addition, (5)
  13. improve the user interface, (6) allow selection of other algorithms,
  14. and (7) probably more that I haven't mentioned.  In spite of the lack
  15. of the above possible improvements, I think this program is useful to
  16. (1) demonstrate and test Diamond2 Block Cipher implementations, and
  17. (2) encrypt some data where manual key management is acceptable and
  18. the file length must be preserved.
  19.  
  20. DLOCK2.CPP is Copyright (C) 1995 Michael Paul Johnson.
  21. All rights reserved.  No warranty.
  22.  
  23. This program is free software; you can redistribute it and/or modify
  24. it provided that the origin of this software is not misrepresented,
  25. and provided that all differences between the author's distribution
  26. and yours are clearly documented, and provided that you retain this
  27. copyright notice in the source code.
  28.  
  29. This program is distributed in the hope that it will be useful,
  30. but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  32.  
  33. You are responsible for compliance with all applicable law that may
  34. pertain to the use, distribution, and export of this program.  This
  35. program might be considered a munition by the U. S. Department of
  36. state, so please handle it with care.  Don't break any export laws.
  37.  
  38. Caution: this program has been know to exist in both matter and
  39. energy states.  Since the conversion of matter to energy can be quite
  40. hazardous, and sometims results in widespread devastation, you must
  41. promise not to destroy any cities with this program.
  42.  
  43. If you don't agree to all of the above terms, you are required to
  44. destroy all of your copies of this program.
  45.  
  46. The author can be reached at m.p.johnson@ieee.org, mpj@csn.net,
  47. mpj@netcom.com, CompuServe 71331,2332, or at PO BOX 1151, LONGMONT CO
  48. 80502-1151, USA.
  49.  
  50. */
  51.  
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <fcntl.h>
  55. #include <sys/stat.h>
  56. #include <string.h>
  57. #ifdef UNIX
  58. #include <memory.h>
  59. #include <termio.h>
  60. #include <unistd.h>
  61. #include <sys/types.h>
  62. #include <sys/uio.h>
  63. #define O_BINARY 0
  64. #else
  65. #include <conio.h>
  66. #include <io.h>
  67. #include <mem.h>
  68. #endif
  69. #include "def.h"
  70. #include "diamond2.h"
  71. #include "crc.h"
  72.  
  73. #define PATHSIZE 82
  74. #define PASS_SIZE 256
  75. #define CHUNK 16384
  76. /* CHUNK must be a multiple of 16.  CHUNK is the number of bytes read from
  77. disk or written to disk at a time when encrypting or decrypting a file. */
  78.  
  79. static byte encryption_key[32] =
  80.     {0xE8, 0x34, 0xFD, 0xB9, 0x33, 0xC5, 0x02, 0x92,
  81.      0x3D, 0x92, 0xBC, 0x9E, 0x14, 0x36, 0x8E, 0x70,
  82.      0xD4, 0x1C, 0x66, 0xCB, 0xDF, 0x36, 0x15, 0x50,
  83.      0x33, 0xA6, 0x6E, 0x07, 0xE6, 0xCC, 0x6D, 0x8D};
  84.  
  85. static uint keysize;    /* Number of bytes of key to use. */
  86. static uint rounds;     /* Number of rounds to use with Diamond2. */
  87. #ifdef MPJs_Copy
  88. static uint literounds; /* Number of rounds to use with Diamond2 Lite. */
  89. #endif
  90. static int blocksize;   /* Block size=8 for Diamond2 Lite or 16 for Diamond2. */
  91.  
  92. static byte seed[16] = {0x5A, 0x8D, 0x87, 0x2D, 0x31, 0xEE, 0xDD, 0xE6,
  93.                         0x3F, 0xC4, 0x6F, 0x6C, 0x36, 0x45, 0x6D, 0x8E};
  94.  
  95. static byte ciphertext[16];
  96. static byte plaintext[16];
  97.  
  98. static boolean generate, end_of_file, validate_file, startpass, encryptit,
  99.     decryptit, verbose;
  100. static char testfilename[] = "DIAMOND2.DAT";
  101.  
  102. static char infilename[PATHSIZE] = "";
  103. static char outfilename[PATHSIZE] = "";
  104. static byte passphrase[PASS_SIZE];
  105.  
  106. FILE *f;
  107.  
  108. #ifdef MPJs_Copy
  109. void generate_test_data(void)
  110.     {
  111.     int i;
  112.  
  113.     f = fopen(testfilename, "wt");
  114.     if (!f)
  115.         {
  116.         printf("Can't open %s for writing.\n", testfilename);
  117.         exit(2);
  118.         }
  119.     fprintf(f, "# Diamond2/Diamond2 lite validation data file.\n"
  120.         "# Format:\n"
  121.         "#    Everything between # and end of line is a comment.\n"
  122.         "#    Numbers are all in hexadecimal (using upper case letters).\n"
  123.         "#    Data sets are in groups of 6 numbers, separated by white space:\n"
  124.         "#    Block size (10 or 8), rounds, key size, key, plain text, cipher text.\n\n");
  125.  
  126.     rounds = 15;
  127.     literounds = 30;
  128.     for (keysize = 32; keysize >= 8; keysize--)
  129.         {
  130.  
  131.         /* Generate Diamond2 Lite test data. */
  132.  
  133.         blocksize = 8;
  134.         set_diamond2_key(encryption_key, keysize, literounds, true, blocksize);
  135.         fprintf(f, "%02X %02X %02X ", blocksize, literounds, keysize);
  136.         printf("Block size: %02X  Rounds: %02X  Key size: %02X\n",
  137.             blocksize, literounds, keysize);
  138.         for (i=0; i < keysize; i++)
  139.             fprintf(f, "%02X", encryption_key[i]);
  140.         fprintf(f, "\n   ");
  141.         for (i=0; i < blocksize; i++)
  142.             fprintf(f, "%02X", seed[i]);
  143.         fprintf(f, " ");
  144.         lite2_encrypt_block(seed, ciphertext);
  145.         lite2_decrypt_block(ciphertext, plaintext);
  146.         for (i = 0; i < blocksize; i++)
  147.             {
  148.             fprintf(f, "%02X", ciphertext[i]);
  149.             if (plaintext[i] != seed[i])
  150.                 {
  151.                 printf("Reversal failure!\n");
  152.                 fputs("\nReversal failure!", f);
  153.                 fclose(f);
  154.                 exit(4);
  155.                 }
  156.             }
  157.         fputs("\n", f);
  158.  
  159.         /* Generate Diamond2 test data. */
  160.  
  161.         blocksize = 16;
  162.         set_diamond2_key(encryption_key, keysize, rounds, true, blocksize);
  163.         fprintf(f, "%02X %02X %02X ", blocksize, rounds, keysize);
  164.         printf("Block size: %02X  Rounds: %02X  Key size: %02X\n",
  165.             blocksize, rounds, keysize);
  166.         for (i=0; i < keysize; i++)
  167.             fprintf(f, "%02X", encryption_key[i]);
  168.         fprintf(f, "\n   ");
  169.         for (i=0; i < blocksize; i++)
  170.             fprintf(f, "%02X", seed[i]);
  171.         fprintf(f, " ");
  172.         diamond2_encrypt_block(seed, ciphertext);
  173.         diamond2_decrypt_block(ciphertext, plaintext);
  174.         for (i = 0; i < blocksize; i++)
  175.             {
  176.             fprintf(f, "%02X", ciphertext[i]);
  177.             if (plaintext[i] != seed[i])
  178.                 {
  179.                 printf("Reversal failure!\n");
  180.                 fputs("\nReversal failure!", f);
  181.                 fclose(f);
  182.                 exit(4);
  183.                 }
  184.             }
  185.         fputs("\n\n", f);
  186.  
  187.         /* Set up for next set of data. */
  188.  
  189.         diamond2_encrypt_block(ciphertext, seed);
  190.         diamond2_encrypt_block(encryption_key, encryption_key);
  191.         diamond2_encrypt_block(encryption_key+16, encryption_key+16);
  192.         rounds -= 3;
  193.         if (rounds < 5) rounds += 11;
  194.         literounds -= 3;
  195.         if (literounds < 4) literounds += 13;
  196.         }
  197.     fclose(f);
  198.     }
  199. #endif
  200.  
  201. int read_hex_char(void)
  202.     {
  203.     static int saved_char = 0;
  204.     static int white_space = 1;
  205.     int ch;
  206.  
  207.     if (saved_char)
  208.         {
  209.         ch = saved_char;
  210.         saved_char = 0;
  211.         }
  212.     else if (white_space)
  213.         {
  214.         do  /* Skip leading white space and uninteresting characters. */
  215.             {
  216.             ch = fgetc(f);
  217.             if (ch == '#')
  218.                 {   /* Skip comment line. */
  219.                 do
  220.                     {
  221.                     ch = fgetc(f);
  222.                     }
  223.                 while ((ch != EOF) && (ch != '\n') && (ch != '\r'));
  224.                 }
  225.             }
  226.         while ((ch != EOF) && ((ch < '0') || (ch > 'F') || ((ch > '9') && (ch < 'A'))));
  227.         white_space = 0;
  228.         }
  229.     else
  230.         {
  231.         ch = fgetc(f);
  232.         if (ch == '#')
  233.             {   /* Skip comment line. */
  234.             do
  235.                 {
  236.                 ch = fgetc(f);
  237.                 }
  238.             while ((ch != EOF) && (ch != '\n') && (ch != '\r'));
  239.             }
  240.         if ((ch < '0') || (ch > 'F') || ((ch > '9') && (ch < 'A')))
  241.             {
  242.             ch = 0;
  243.             white_space = 1;
  244.             }
  245.         }
  246.     if (ch == EOF)
  247.         {
  248.         end_of_file = true;
  249.         ch = 0;
  250.         }
  251.     return ch;
  252.     }
  253.  
  254. uint from_hex(int hex_character)
  255.     {
  256.     hex_character -= '0';
  257.     if (hex_character > 9)
  258.         hex_character -= 7;
  259.     return (uint)hex_character;
  260.     }
  261.  
  262. uint read_uint(void)
  263.     {
  264.     int ch, i;
  265.     uint u;
  266.  
  267.     u = 0;
  268.     i = 0;
  269.     do
  270.         {
  271.         ch = read_hex_char();
  272.         if (ch)
  273.             {
  274.             u = (u << 4) + from_hex(ch);
  275.             }
  276.         if (++i > 5)
  277.             {
  278.             puts("Unexpected character reading unsigned integer.");
  279.             exit(6);
  280.             }
  281.         }
  282.     while (ch && (!end_of_file));
  283.     return u;
  284.     }
  285.  
  286. void read_hex_block(byte *dest, uint numbytes)
  287.     {
  288.     uint u;
  289.     int ch;
  290.  
  291.     for (u = 0; u < numbytes; u++)
  292.         {
  293.         dest[u] = from_hex(read_hex_char());
  294.         dest[u] = (dest[u] << 4) + from_hex(read_hex_char());
  295.         }
  296.     ch = read_hex_char();
  297.     if ((ch != 0) && (ch != EOF))
  298.         {
  299.         puts("Unexpected input.");
  300.         exit(7);
  301.         }
  302.     }
  303.  
  304. void validate_test_data(void)
  305.     {
  306.     int i;
  307.  
  308.     end_of_file = false;
  309.     f = fopen(testfilename, "rt");
  310.     if (!f)
  311.         {
  312.         printf("Unable to open %s\n", testfilename);
  313.         exit(5);
  314.         }
  315.     while (!end_of_file)
  316.         {
  317.         blocksize = read_uint();
  318.         if (end_of_file) return;
  319.         rounds = read_uint();
  320.         keysize = read_uint();
  321.         read_hex_block(encryption_key, keysize);
  322.         read_hex_block(plaintext, blocksize);
  323.         read_hex_block(ciphertext, blocksize);
  324.         if (blocksize == 8)
  325.             {
  326.             printf("Testing Diamond2 Lite");
  327.             }
  328.         else if (blocksize ==  16)
  329.             {
  330.             printf("Testing Diamond2");
  331.             }
  332.         else
  333.             {
  334.             puts("Unexected data.");
  335.             exit(9);
  336.             }
  337.         printf(" with %u rounds, %u byte key.\n", rounds, keysize);
  338.         set_diamond2_key(encryption_key, keysize, rounds, true, blocksize);
  339.         if (blocksize == 16)
  340.             {
  341.             diamond2_encrypt_block(plaintext, seed);
  342.             for (i=0; i<blocksize; i++)
  343.                 {
  344.                 if (seed[i] != ciphertext[i])
  345.                     {
  346.                     puts("Encryption error.");
  347.                     exit(8);
  348.                     }
  349.                 }
  350.             diamond2_decrypt_block(ciphertext, seed);
  351.             for (i=0; i<blocksize; i++)
  352.                 {
  353.                 if (seed[i] != plaintext[i])
  354.                     {
  355.                     puts("Decryption error.");
  356.                     exit(8);
  357.                     }
  358.                 }
  359.             }
  360.         else
  361.             {
  362.             lite2_encrypt_block(plaintext, seed);
  363.             for (i=0; i<blocksize; i++)
  364.                 {
  365.                 if (seed[i] != ciphertext[i])
  366.                     {
  367.                     puts("Encryption error.");
  368.                     exit(8);
  369.                     }
  370.                 }
  371.             lite2_decrypt_block(ciphertext, seed);
  372.             for (i=0; i<blocksize; i++)
  373.                 {
  374.                 if (seed[i] != plaintext[i])
  375.                     {
  376.                     puts("Decryption error.");
  377.                     exit(8);
  378.                     }
  379.                 }
  380.             }
  381.         }
  382.     fclose(f);
  383.     }
  384.  
  385. static void get_pass_phrase(char *key, uint maxlength)
  386.     {
  387.     int ch;
  388.     uint keypos;
  389.     char check_pw[PASS_SIZE];
  390.  
  391.     puts("Please enter your pass phrase (case sensitive):");
  392.     keypos = 0;
  393.     key[0] = 0;
  394.     do
  395.         {
  396. #ifdef UNIX
  397.         ch = getchar();
  398. #else
  399.         ch = getch();
  400.         if (!ch) ch = 0x100 + getch();
  401. #endif
  402.         if (((ch == 8) || (ch == 127)) && keypos)
  403.             {
  404.             key[--keypos] = 0;
  405.             printf("\x08 \x08");
  406.             }
  407.         else if ((ch == 27) || (ch == 3))
  408.             {
  409.             key[0] = 0;
  410.             }
  411.         else if ((ch != 13) && (ch != 10) && (ch != 8) && (ch != 127))
  412.             {
  413.             printf("*");
  414.             key[keypos++] = (char) ch;
  415.             key[keypos] = 0;
  416.             }
  417.         }
  418.     while ((ch != 13) && (ch != 10) && (ch != 3) && (ch != 27) && (keypos < (maxlength-1)));
  419.     puts("\r                                                                              ");
  420.     if (encryptit)
  421.         {
  422.         puts("Please verify your pass phrase (case sensitive):");
  423.         keypos = 0;
  424.         check_pw[0] = 0;
  425.         do
  426.             {
  427. #ifdef UNIX
  428.             ch = getchar();
  429. #else
  430.             ch = getch();
  431.             if (!ch) ch = 0x100 + getch();
  432. #endif
  433.             if (((ch == 8) || (ch == 127)) && keypos)
  434.                 {
  435.                 check_pw[--keypos] = 0;
  436.                 printf("\x08 \x08");
  437.                 }
  438.             else if ((ch == 27) || (ch == 3))
  439.                 {
  440.                 check_pw[0] = 0;
  441.                 }
  442.             else if ((ch != 13) && (ch != 10) && (ch != 8) && (ch != 127))
  443.                 {
  444.                 printf("*");
  445.                 check_pw[keypos++] = (char) ch;
  446.                 check_pw[keypos] = 0;
  447.                 }
  448.             }
  449.         while ((ch != 13) && (ch != 10) && (ch != 3) && (ch != 27) && (keypos < (maxlength-1)));
  450.         puts("\r                                                                              \r");
  451.         if (strcmp(check_pw, key))
  452.             {
  453.             puts("Pass phrases didn't match.  Please try again.");
  454.             key[0] = 0;
  455.             }
  456.         memset(check_pw,0,PASS_SIZE);
  457.         }
  458.     }
  459.  
  460. void help(void)
  461.     {
  462.     puts("\nCopyright (C) 1995 Michael Paul Johnson.\n"
  463.         "All rights reserved.  No warranty.\n\n"
  464.         "To test Diamond2 and Diamond2 Lite against validation data:\n"
  465.         "  DLOCK2 /T\n"
  466. #ifdef MPJs_Copy
  467.         "To generate new validation data set:\n"
  468.         "  DLOCK2 /G\n"
  469. #endif
  470.         "To encrypt a file:\n"
  471.         "  DLOCK2 /E [/S] infilename outfilename [/Ppass phrase | /Kkeyfile]\n"
  472.         "To decrypt a file:\n"
  473.         "  DLOCK2 /D [/S] infilename outfilename [/Ppass phrase | /Kkeyfile]\n"
  474.         "/S = Silent mode (minimal screen output).\n");
  475.     exit(1);
  476.     }
  477.  
  478. int encrypt_file(char *inname, char *outname, uint keysize, byte *key)
  479.     {
  480.     int infile, outfile, bytesinbuf, i, blockpos;
  481.     byte *buf;
  482.     byte lastciphertext[16];
  483.     ulong bytesdone;
  484.  
  485.     buf = (byte*) malloc(CHUNK);
  486.     if (!buf)
  487.         {
  488.         puts("Out of memory.");
  489.         return(3);
  490.         }
  491.     infile = open(inname, O_RDONLY | O_BINARY);
  492.     if (infile < 0)
  493.         {
  494.         printf("Can't open %s\n", inname);
  495.         return(13);
  496.         }
  497.     outfile = open(outname,O_WRONLY|O_EXCL|O_CREAT|O_BINARY,S_IREAD|S_IWRITE);
  498.     if (outfile < 0)
  499.         {
  500.         printf("Can't open %s\n", outname);
  501.         puts("Output file cannot already exist.");
  502.         return(14);
  503.         }
  504.     bytesdone = 0;
  505.     set_diamond2_key(key, keysize, 10, false, 16);
  506.     memset(lastciphertext, 0, 16);
  507.     diamond2_encrypt_block(lastciphertext, lastciphertext);
  508.     blockpos = 0;
  509.     do
  510.         {
  511.         bytesinbuf = read(infile, (char *)buf, CHUNK);
  512.         for (i = 0; i<bytesinbuf; i++)
  513.             {
  514.             buf[i] ^= lastciphertext[blockpos++];
  515.             if (blockpos >= 16)
  516.                 {
  517.                 blockpos = 0;
  518.                 diamond2_encrypt_block(buf + i - 15, lastciphertext);
  519.                 }
  520.             }
  521.         if (bytesinbuf)
  522.             {
  523.             if (write(outfile, (char *)buf, bytesinbuf) != bytesinbuf)
  524.                 {
  525.                 printf("Error writing to %s\n", outname);
  526.                 return(15);
  527.                 }
  528.             bytesdone += bytesinbuf;
  529.             if (verbose) printf("\r%lu bytes encrypted.  ", bytesdone);
  530.             }
  531.         }
  532.     while (bytesinbuf == CHUNK);
  533.     if (close(outfile)) printf("Error closing %s\n", outname);
  534.     close(infile);
  535.     diamond2_done();
  536.     if (verbose) puts("");
  537.     return 0;
  538.     }
  539.  
  540. int decrypt_file(char *inname, char *outname, uint keysize, byte *key)
  541.     {
  542.     int infile, outfile, bytesinbuf, i, blockpos;
  543.     byte *buf;
  544.     byte lastciphertext[16];
  545.     byte thisciphertext[16];
  546.     ulong bytesdone;
  547.  
  548.     buf = (byte*) malloc(CHUNK);
  549.     if (!buf)
  550.         {
  551.         puts("Out of memory.");
  552.         return(3);
  553.         }
  554.     infile = open(inname, O_RDONLY | O_BINARY);
  555.     if (infile < 0)
  556.         {
  557.         printf("Can't open %s\n", inname);
  558.         return(13);
  559.         }
  560.     outfile = open(outname,O_WRONLY|O_EXCL|O_CREAT|O_BINARY,S_IREAD|S_IWRITE);
  561.     if (outfile < 0)
  562.         {
  563.         printf("Can't open %s\n", outname);
  564.         puts("Output file cannot already exist.");
  565.         return(14);
  566.         }
  567.     bytesdone = 0;
  568.     set_diamond2_key(key, keysize, 10, false, 16);
  569.     memset(lastciphertext, 0, 16);
  570.     diamond2_encrypt_block(lastciphertext, lastciphertext);
  571.     blockpos = 0;
  572.     do
  573.         {
  574.         bytesinbuf = read(infile, (char *)buf, CHUNK);
  575.         for (i = 0; i<bytesinbuf; i++)
  576.             {
  577.             thisciphertext[blockpos] = buf[i];
  578.             buf[i] ^= lastciphertext[blockpos++];
  579.             if (blockpos >= 16)
  580.                 {
  581.                 blockpos = 0;
  582.                 diamond2_encrypt_block(thisciphertext, lastciphertext);
  583.                 }
  584.             }
  585.         if (bytesinbuf)
  586.             {
  587.             if (write(outfile, (char *)buf, bytesinbuf) != bytesinbuf)
  588.                 {
  589.                 printf("Error writing to %s\n", outname);
  590.                 return(15);
  591.                 }
  592.             bytesdone += bytesinbuf;
  593.             printf("\r%lu bytes decrypted.  ", bytesdone);
  594.             }
  595.         }
  596.     while (bytesinbuf == CHUNK);
  597.     if (close(outfile)) printf("Error closing %s\n", outname);
  598.     close(infile);
  599.     diamond2_done();
  600.     if (verbose) puts("");
  601.     return 0;
  602.     }
  603.  
  604. int main(int argc, char** argv)
  605.     {
  606.     int i, c, keyfile;
  607.     uint keysize;
  608.     char *p;
  609.     char keyfilename[PATHSIZE];
  610.  
  611.     generate = validate_file = startpass = encryptit = decryptit = false;
  612.     verbose = true;
  613.     keysize = 0;
  614.     keyfilename[0] = 0;
  615.     passphrase[0] = 0;
  616.  
  617.     for (i=1;i<argc;i++)
  618.         {
  619.         if ((!startpass) && (argv[i][0] == '-') || (argv[i][0] == '/'))
  620.             {
  621.             c = argv[i][1] | 0x20;
  622.             switch (c)
  623.                 {
  624.                 case 'd':
  625.                     decryptit = true;
  626.                     encryptit = false;
  627.                     break;
  628.                 case 'e':
  629.                     decryptit = false;
  630.                     encryptit = true;
  631.                     break;
  632. #ifdef MPJs_Copy
  633.                 case 'g':
  634.                     generate = true;
  635.                     break;
  636. #endif
  637.                 case 'k':
  638.                     strcpy(keyfilename, argv[i] + 2);
  639.                     break;
  640.                 case 'p':
  641.                     startpass = true;
  642.                     strcpy((char *) passphrase, argv[i] + 2);
  643.                     keysize = strlen((char *)passphrase);
  644.                     break;
  645.                 case 's':
  646.                     verbose = false;
  647.                     break;
  648.                 case 't':
  649.                     validate_file = true;
  650.                     break;
  651.                 default:
  652.                     help();
  653.                     break;
  654.                 }
  655.             }
  656.         else if (startpass)
  657.             {
  658.             strcat((char *) passphrase, " ");
  659.             strcat((char *) passphrase, argv[i]);
  660.             keysize = strlen((char *)passphrase);
  661.             }
  662.         else if (infilename[0] == 0)
  663.             {
  664.             strcpy(infilename, argv[i]);
  665.             }
  666.         else if (outfilename[0] == 0)
  667.             {
  668.             strcpy(outfilename, argv[i]);
  669.             }
  670.         else
  671.             {
  672.             help();
  673.             }
  674.         }
  675.     if (!(generate || validate_file || encryptit || decryptit))
  676.         help();
  677. #ifdef MPJs_Copy
  678.     if (generate) generate_test_data();
  679. #endif
  680.     if (generate || validate_file) validate_test_data();
  681.     if (encryptit || decryptit)
  682.         {
  683.         if (!outfilename[0])
  684.             help();
  685.         if (keysize)
  686.             {
  687.             if (verbose)
  688.                 puts("Using pass phrase from command line.");
  689.             }
  690.         else if (keyfilename[0])
  691.             {
  692.             keyfile = open(keyfilename, O_RDONLY|O_BINARY);
  693.             if (keyfile >= 0)
  694.                 {
  695.                 keysize = read(keyfile, (char *)passphrase, PASS_SIZE);
  696.                 close(keyfile);
  697.                 if (verbose)
  698.                     {
  699.                     if (keysize)
  700.                         printf("Using pass phrase from %s\n", keyfilename);
  701.                     else
  702.                         printf("No key read from file %s\n", keyfilename);
  703.                     }
  704.                 }
  705.             else
  706.                 {
  707.                 printf("Can't open %s\n", keyfilename);
  708.                 }
  709.             }
  710.         if (!keysize)
  711.             {
  712.             p = getenv("DLOCK_KEY");
  713.             if (p)
  714.                 {
  715.                 strcpy((char *) passphrase, p);
  716.                 keysize = strlen((char *)passphrase);
  717.                 if (verbose)
  718.                     puts("Using pass phrase from DLOCK_KEY environment variable.");
  719.                 }
  720.             else
  721.                 {
  722.                 get_pass_phrase((char *) passphrase, PASS_SIZE);
  723.                 keysize = strlen((char *)passphrase);
  724.                 }
  725.             }
  726.         if (!keysize)
  727.             {
  728.             puts("Pass phrase required to encrypt or decrypt.");
  729.             return(10);
  730.             }
  731.         if ((keysize < 6) && encryptit)
  732.             {
  733.             puts("WARNING: PASS PHRASE IS TOO SHORT FOR SECURITY!");
  734.             }
  735.         if (encryptit)
  736.             {
  737.             if (verbose)
  738.                 printf("Encrypting %s to %s\n", infilename, outfilename);
  739.             return(encrypt_file(infilename, outfilename, keysize, passphrase));
  740.             }
  741.         else
  742.             {
  743.             if (verbose)
  744.                 printf("Decrypting %s to %s\n", infilename, outfilename);
  745.             return(decrypt_file(infilename, outfilename, keysize, passphrase));
  746.             }
  747.         }
  748.     return 0;
  749.     }
  750.  
  751.