home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / net / crypt < prev    next >
Internet Message Format  |  1987-02-18  |  8KB

  1. From philip@axis.UUCP Sun Feb 15 14:33:00 1987
  2. Path: beno!seismo!mcvax!inria!axis!philip
  3. From: philip@axis.UUCP
  4. Newsgroups: net.sources
  5. Subject: A crypt program
  6. Keywords: A public domain crypt program
  7. Message-ID: <177@axis.UUCP>
  8. Date: 15 Feb 87 19:33:00 GMT
  9. Organization: Axis Digital, Paris
  10. Lines: 262
  11. Posted: Sun Feb 15 19:33:00 1987
  12.  
  13.  
  14.             Crypt - Decrypt Program
  15.             ~~~~~~~~~~~~~~~~~~~~~~~
  16.  
  17. This program is based upon the German WW2 enigma machine.
  18.  
  19. This worked as follows:
  20.  
  21. The machine contained several (3 or 4, depending upon the service) rotors,
  22. with contacts on each face. Each rotor had a different mapping (ie wiring)
  23. scheme between the contacts.
  24.  
  25. Each contact on the input side of rotor 1 was connected to input keys
  26. (letters and numbers). Pressing the key marked 'A' would pass an electric
  27. current into the corresponding contact on the input rotor, this current would
  28. exit on some other contact on the output side, depending upon the internal
  29. wiring.
  30.  
  31. After each key press, the input rotor would turn one position (thus, pressing
  32. 'A' again, would result in a current flowing out of a different output
  33. contact.
  34.  
  35. After completing one revolution, rotor number two would move one position.
  36.  
  37. The key to this depended upon the order of the rotors, and their starting
  38. positions.
  39.  
  40. To decode, simply reverse the current flow, ie, connect the keyboard to the
  41. output, and replace the input by a series of lamps corresponding to the
  42. keys.
  43.  
  44. This program simulates one of these machines, with several refinements:
  45.  
  46. 1)    Each rotor has 256 positions
  47.  
  48. 2)    The key is not the ordering and starting positions of the rotors,
  49.     since new and different rotors are created for each input key.
  50.  
  51. 3)    The movement of the rotors is not a simple as described above.
  52.     It is basically that, but with rotors selected on a random basis,
  53.     they are advanced a random number of positions.
  54.  
  55. The result is (I believe - not being a Cryptologist), somewhat more
  56. secure than the original machines, and certainly more secure than the
  57. original UNIX crypt - which has a single rotor, with a reciprocal
  58. mapping - ie if an input of 'A' maps to an output of 'Z', then in the
  59. same rotor position, a 'Z' must map to an 'A'.
  60.  
  61. if anyone finds a method of breaking this crypt program, I would be glad
  62. to hear about it.
  63.  
  64. Philip Peake    (philip@axis.uucp)
  65.  
  66. NOTES:
  67.     The program must have two links, one called crypt, and the other
  68.     called decrypt. Passing a crypted document through crypt again,
  69.     even with the same key, will not decrypt it.
  70.  
  71. ===============================================================================
  72. #include <stdio.h>
  73.  
  74. #define    ROTORSIZ    256
  75. #define    MASK        0377
  76. #define    EMPTY        07777
  77. #define    X_SIZE        4099
  78.  
  79. char    *strrchr();
  80.  
  81. unsigned    r1[ROTORSIZ];
  82. unsigned    r2[ROTORSIZ];
  83. unsigned    r3[ROTORSIZ];
  84.  
  85. unsigned char    x[X_SIZE];
  86.  
  87. init(password, decrypt)
  88. char    *password;
  89. int    decrypt;
  90. {
  91.     register int    index;
  92.     register int    i;
  93.     int        pipe_fd[2];
  94.     unsigned    random;
  95.     long        seed = 123L;
  96.     char        buf[13];
  97.  
  98.     strncpy(buf, password, 8);
  99.     while (*password) *password++ = '\0';
  100.     buf[8] = buf[0];
  101.     buf[9] = buf[1];
  102.  
  103.     pipe(pipe_fd);
  104.  
  105.     if (fork() == 0)
  106.     {
  107.         close(0);
  108.         close(1);
  109.         dup(pipe_fd[0]);
  110.         dup(pipe_fd[1]);
  111.         execl("/usr/lib/makekey", "-", 0);
  112.         execl("/lib/makekey", "-", 0);
  113.         exit(1);
  114.     }
  115.  
  116.     write(pipe_fd[1], buf, 10);
  117.     wait((int *) NULL);
  118.  
  119.     if (read(pipe_fd[0], buf, 13) != 13)
  120.     {
  121.         fprintf(stderr, "crypt: cannot generate key\n");
  122.         exit(1);
  123.     }
  124.  
  125.     for (i = 0 ; i < ROTORSIZ; i++) r1[i] = r2[i] = r3[i] = EMPTY;
  126.  
  127.     for (i = 2; i < 13; i++) seed = seed * buf[i] + i;
  128.  
  129.     i = 0;
  130.     while (i < ROTORSIZ)
  131.     {
  132.         seed = (long)(5L * seed + (long)i);
  133.         random = (unsigned)(seed % 65521L);
  134.         index = (int)(random & MASK);
  135.         if (r1[index] == EMPTY)
  136.             r1[index] = i++;
  137.         else
  138.             continue;
  139.     }
  140.  
  141.     i = 0;
  142.     while (i < ROTORSIZ)
  143.     {
  144.         seed = (long)(5L * seed + (long)i);
  145.         random = (unsigned)(seed % 65521L);
  146.         index = (int)(random & MASK);
  147.         if (r2[index] == EMPTY)
  148.             r2[index] = i++;
  149.         else
  150.             continue;
  151.     }
  152.  
  153.     i = 0;
  154.     while (i < ROTORSIZ)
  155.     {
  156.         seed = (long)(5L * seed + (long)i);
  157.         random = (unsigned)(seed % 65521L);
  158.         index = (int)(random & MASK);
  159.         if (r3[index] == EMPTY)
  160.             r3[index] = i++;
  161.         else
  162.             continue;
  163.     }
  164.  
  165.     for (i = 0; i < X_SIZE; i++)
  166.     {
  167.         seed = (long)(5L * seed + (long)i);
  168.         random = (unsigned)(seed % 65521L);
  169.         x[i] = random & 03;
  170.     }
  171.  
  172.     if (decrypt)
  173.     {
  174.         invert(r1);
  175.         invert(r2);
  176.         invert(r3);
  177.     }
  178. }
  179.  
  180. invert(r)
  181. unsigned r[ROTORSIZ];
  182. {
  183.     unsigned    t[ROTORSIZ];
  184.     register int    i;
  185.  
  186.     for (i = 0; i < ROTORSIZ; i++) t[i] = r[i];
  187.     for (i = 0; i < ROTORSIZ; i++) r[t[i]] = i;
  188. }
  189.  
  190. crypt()
  191. {
  192.     register    int        ch;
  193.     register    int        i    = 0;
  194.     register    unsigned    ofs1 = 0;
  195.     register    unsigned    ofs2 = 0;
  196.     register    unsigned    ofs3 = 0;
  197.  
  198.     while ((ch = getchar()) != EOF)
  199.     {
  200.         putchar(r3[r2[r1[ch+ofs1&MASK]+ofs2&MASK]+ofs3&MASK]);
  201.  
  202.         switch (x[i]){
  203.         case 00:
  204.                 ofs1 = ++ofs1 & MASK;
  205.                 break;
  206.         case 01:
  207.                 ofs2 = ++ofs2 & MASK;
  208.                 break;
  209.         case 02:
  210.                 ofs3 = ++ofs3 & MASK;
  211.                 break;
  212.         }
  213.  
  214.         if (ofs1 == 0) ofs2 = ++ofs2 & MASK;
  215.         if (ofs2 == 0) ofs3 = ++ofs3 & MASK;
  216.  
  217.         if (++i == X_SIZE) i = 0;
  218.     }
  219. }
  220.  
  221. decrypt()
  222. {
  223.     register    int        ch;
  224.     register    int        i    = 0;
  225.     register    unsigned    ofs1 = 0;
  226.     register    unsigned    ofs2 = 0;
  227.     register    unsigned    ofs3 = 0;
  228.  
  229.     while ((ch = getchar()) != EOF)
  230.     {
  231.         putchar(r1[r2[r3[ch]-ofs3&MASK]-ofs2&MASK]-ofs1&MASK);
  232.  
  233.         switch (x[i]){
  234.         case 00:
  235.                 ofs1 = ++ofs1 & MASK;
  236.                 break;
  237.         case 01:
  238.                 ofs2 = ++ofs2 & MASK;
  239.                 break;
  240.         case 02:
  241.                 ofs3 = ++ofs3 & MASK;
  242.                 break;
  243.         }
  244.  
  245.         if (ofs1 == 0) ofs2 = ++ofs2 & MASK;
  246.         if (ofs2 == 0) ofs3 = ++ofs3 & MASK;
  247.  
  248.         if (++i == X_SIZE) i = 0;
  249.     }
  250. }
  251.  
  252. main(argc, argv)
  253. int    argc;
  254. char    *argv[];
  255. {
  256.     int    flag;
  257.     char    *p;
  258.  
  259.     p = strrchr(argv[0], '/');
  260.  
  261.     if (p == NULL) p = argv[0];
  262.     else ++p;
  263.  
  264.     if (strcmp(p, "crypt") == 0) flag = 0;
  265.     else                   flag = 1;
  266.  
  267.     if (argc != 2)
  268.         init(getpass("Enter key: "), flag);
  269.     else
  270.         init(argv[1], flag);
  271.  
  272.     if (flag) decrypt();
  273.     else      crypt();
  274. }
  275.  
  276.  
  277. From philip@axis.UUCP Wed Feb 18 06:17:24 1987
  278. Path: beno!seismo!mcvax!inria!axis!philip
  279. From: philip@axis.UUCP
  280. Newsgroups: net.sources
  281. Subject: Crypt program - mods.
  282. Keywords: makekey replacement code
  283. Message-ID: <180@axis.UUCP>
  284. Date: 18 Feb 87 11:17:24 GMT
  285. Organization: Axis Digital, Paris
  286. Lines: 73
  287. Posted: Wed Feb 18 11:17:24 1987
  288.  
  289. In the crypt program I recently posted, there was a call made to a
  290. small program "/usr/lib/makekey". Apparently this does not exist on all
  291. *IX* machines.
  292.  
  293. I really dont see why - it is a 4 or 5 line program which reads a
  294. password on its stdin, and prints the encrypted result on its stdout,
  295. using exactly the same routines as passwd does.
  296.  
  297. Rather than re-write the program, I have made some mods to the crypt source
  298. to make the calls directly.
  299.  
  300. Since the library routine is called 'crypt', the routine within my program
  301. has to change its name, 'encrypt' is also used in the library, so the
  302. final name change is to 'encode'.
  303.  
  304. The following is a diff of the changes required (actually, the source becomes
  305. smaller and simpler .... )
  306.  
  307. ============================================================================
  308.  
  309. 19a20
  310. >     char        *crypt();
  311. 22d22
  312. <     int        pipe_fd[2];
  313. 25c25,27
  314. <     char        buf[13];
  315. ---
  316. >     char        buf[14];
  317. >     char        key[9];
  318. >     char        salt[3];
  319. 27,30c29,32
  320. <     strncpy(buf, password, 8);
  321. <     while (*password) *password++ = '\0';
  322. <     buf[8] = buf[0];
  323. <     buf[9] = buf[1];
  324. ---
  325. >     strncpy(key, password, 8);
  326. >     salt[0] = key[0];
  327. >     salt[1] = key[1];
  328. >     salt[2] = '\0';
  329. 32c34
  330. <     pipe(pipe_fd);
  331. ---
  332. >     strncpy(buf, crypt(key, salt), 13);
  333. 34,53d35
  334. <     if (fork() == 0)
  335. <     {
  336. <         close(0);
  337. <         close(1);
  338. <         dup(pipe_fd[0]);
  339. <         dup(pipe_fd[1]);
  340. <         execl("/usr/lib/makekey", "-", 0);
  341. <         execl("/lib/makekey", "-", 0);
  342. <         exit(1);
  343. <     }
  344. <     write(pipe_fd[1], buf, 10);
  345. <     wait((int *) NULL);
  346. <     if (read(pipe_fd[0], buf, 13) != 13)
  347. <     {
  348. <         fprintf(stderr, "crypt: cannot generate key\n");
  349. <         exit(1);
  350. <     }
  351. 119c101
  352. < crypt()
  353. ---
  354. > encode()
  355. 202c184
  356. <     else      crypt();
  357. ---
  358. >     else      encode();
  359.  
  360.  
  361.