enigma.c revision 40767
1/* 2 * "enigma.c" is in file cbw.tar from 3 * anonymous FTP host watmsg.waterloo.edu: pub/crypt/cbw.tar.Z 4 * 5 * A one-rotor machine designed along the lines of Enigma 6 * but considerably trivialized. 7 * 8 * A public-domain replacement for the UNIX "crypt" command. 9 * 10 * Upgraded to function properly on 64-bit machines. 11 */ 12 13#define ECHO 010 14#include <stdio.h> 15#define ROTORSZ 256 16#define MASK 0377 17char t1[ROTORSZ]; 18char t2[ROTORSZ]; 19char t3[ROTORSZ]; 20char deck[ROTORSZ]; 21char *getpass(); 22char buf[13]; 23 24void shuffle(); 25void puth(); 26 27void 28setup(pw) 29char *pw; 30{ 31 int ic, i, k, temp, pf[2], pid; 32 unsigned random; 33 long seed; 34 35 strncpy(buf, pw, 8); 36 while (*pw) 37 *pw++ = '\0'; 38 buf[8] = buf[0]; 39 buf[9] = buf[1]; 40 pipe(pf); 41 if ((pid=fork())==0) { 42 close(0); 43 close(1); 44 dup(pf[0]); 45 dup(pf[1]); 46 execlp("makekey", "-", 0); 47 execl("/usr/libexec/makekey", "-", 0); /* BSDI */ 48 execl("/usr/lib/makekey", "-", 0); 49 execl("/usr/bin/makekey", "-", 0); /* IBM */ 50 execl("/lib/makekey", "-", 0); 51 perror("makekey"); 52 fprintf(stderr, "enigma: cannot execute 'makekey', aborting\n"); 53 exit(1); 54 } 55 write(pf[1], buf, 10); 56 close(pf[1]); 57 i=wait((int *)NULL); 58 if (i<0) perror("enigma: wait"); 59 if (i!=pid) { 60 fprintf(stderr, "enigma: expected pid %d, got pid %d\n", pid, i); 61 exit(1); 62 } 63 if ((i=read(pf[0], buf, 13)) != 13) { 64 fprintf(stderr, "enigma: cannot generate key, read %d\n",i); 65 exit(1); 66 } 67 seed = 123; 68 for (i=0; i<13; i++) 69 seed = seed*buf[i] + i; 70 for(i=0;i<ROTORSZ;i++) { 71 t1[i] = i; 72 deck[i] = i; 73 } 74 for(i=0;i<ROTORSZ;i++) { 75 seed = 5*seed + buf[i%13]; 76 if( sizeof(long) > 4 ) { 77 /* Force seed to stay in 32-bit signed math */ 78 if( seed & 0x80000000 ) 79 seed = seed | (-1L & ~0xFFFFFFFFL); 80 else 81 seed &= 0x7FFFFFFF; 82 } 83 random = seed % 65521; 84 k = ROTORSZ-1 - i; 85 ic = (random&MASK)%(k+1); 86 random >>= 8; 87 temp = t1[k]; 88 t1[k] = t1[ic]; 89 t1[ic] = temp; 90 if(t3[k]!=0) continue; 91 ic = (random&MASK) % k; 92 while(t3[ic]!=0) ic = (ic+1) % k; 93 t3[k] = ic; 94 t3[ic] = k; 95 } 96 for(i=0;i<ROTORSZ;i++) 97 t2[t1[i]&MASK] = i; 98} 99 100main(argc, argv) 101char *argv[]; 102{ 103 register int i, n1, n2, nr1, nr2; 104 int secureflg = 0; 105 106 if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 's') { 107 argc--; 108 argv++; 109 secureflg = 1; 110 } 111 if (argc != 2){ 112 setup(getpass("Enter key:")); 113 } 114 else 115 setup(argv[1]); 116 n1 = 0; 117 n2 = 0; 118 nr2 = 0; 119 120 while((i=getchar()) >=0) { 121 if (secureflg) { 122 nr1 = deck[n1]&MASK; 123 nr2 = deck[nr1]&MASK; 124 } else { 125 nr1 = n1; 126 } 127 i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; 128 putchar(i); 129 n1++; 130 if(n1==ROTORSZ) { 131 n1 = 0; 132 n2++; 133 if(n2==ROTORSZ) n2 = 0; 134 if (secureflg) { 135 shuffle(deck); 136 } else { 137 nr2 = n2; 138 } 139 } 140 } 141} 142 143void 144shuffle(deck) 145 char deck[]; 146{ 147 int i, ic, k, temp; 148 unsigned random; 149 static long seed = 123; 150 151 for(i=0;i<ROTORSZ;i++) { 152 seed = 5*seed + buf[i%13]; 153 random = seed % 65521; 154 k = ROTORSZ-1 - i; 155 ic = (random&MASK)%(k+1); 156 temp = deck[k]; 157 deck[k] = deck[ic]; 158 deck[ic] = temp; 159 } 160} 161 162void 163puth( title, cp, len ) 164char *title; 165char *cp; 166int len; 167{ 168 fprintf( stderr, "%s = ", title); 169 while( len-- > 0 ) { 170 fprintf(stderr, "%2.2x ", (*cp++) & 0xFF ); 171 } 172 fprintf(stderr,"\n"); 173} 174