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 #include <sys/cdefs.h> 14 __FBSDID("$FreeBSD$"); 15 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #define MINUSKVAR "CrYpTkEy" 25 26 #define ECHO 010 27 #define ROTORSZ 256 28 #define MASK 0377 29 char t1[ROTORSZ]; 30 char t2[ROTORSZ]; 31 char t3[ROTORSZ]; 32 char deck[ROTORSZ]; 33 char buf[13]; 34 35 void shuffle(char *); 36 void setup(char *); 37 38 void 39 setup(pw) 40 char *pw; 41 { 42 int ic, i, k, temp, pf[2], pid; 43 unsigned rnd; 44 long seed; 45 46 strncpy(buf, pw, 8); 47 while (*pw) 48 *pw++ = '\0'; 49 buf[8] = buf[0]; 50 buf[9] = buf[1]; 51 pipe(pf); 52 if ((pid=fork())==0) { 53 close(0); 54 close(1); 55 dup(pf[0]); 56 dup(pf[1]); 57 execlp("makekey", "-", (char *)0); 58 execl("/usr/libexec/makekey", "-", (char *)0); /* BSDI */ 59 execl("/usr/lib/makekey", "-", (char *)0); 60 execl("/usr/bin/makekey", "-", (char *)0); /* IBM */ 61 execl("/lib/makekey", "-", (char *)0); 62 perror("makekey"); 63 fprintf(stderr, "enigma: cannot execute 'makekey', aborting\n"); 64 exit(1); 65 } 66 write(pf[1], buf, 10); 67 close(pf[1]); 68 i=wait((int *)NULL); 69 if (i<0) perror("enigma: wait"); 70 if (i!=pid) { 71 fprintf(stderr, "enigma: expected pid %d, got pid %d\n", pid, i); 72 exit(1); 73 } 74 if ((i=read(pf[0], buf, 13)) != 13) { 75 fprintf(stderr, "enigma: cannot generate key, read %d\n",i); 76 exit(1); 77 } 78 seed = 123; 79 for (i=0; i<13; i++) 80 seed = seed*buf[i] + i; 81 for(i=0;i<ROTORSZ;i++) { 82 t1[i] = i; 83 deck[i] = i; 84 } 85 for(i=0;i<ROTORSZ;i++) { 86 seed = 5*seed + buf[i%13]; 87 if( sizeof(long) > 4 ) { 88 /* Force seed to stay in 32-bit signed math */ 89 if( seed & 0x80000000 ) 90 seed = seed | (-1L & ~0xFFFFFFFFL); 91 else 92 seed &= 0x7FFFFFFF; 93 } 94 rnd = seed % 65521; 95 k = ROTORSZ-1 - i; 96 ic = (rnd&MASK)%(k+1); 97 rnd >>= 8; 98 temp = t1[k]; 99 t1[k] = t1[ic]; 100 t1[ic] = temp; 101 if(t3[k]!=0) continue; 102 ic = (rnd&MASK) % k; 103 while(t3[ic]!=0) ic = (ic+1) % k; 104 t3[k] = ic; 105 t3[ic] = k; 106 } 107 for(i=0;i<ROTORSZ;i++) 108 t2[t1[i]&MASK] = i; 109 } 110 111 int 112 main(argc, argv) 113 int argc; 114 char *argv[]; 115 { 116 register int i, n1, n2, nr1, nr2; 117 int secureflg = 0, kflag = 0; 118 char *cp; 119 120 if (argc > 1 && argv[1][0] == '-') { 121 if (argv[1][1] == 's') { 122 argc--; 123 argv++; 124 secureflg = 1; 125 } else if (argv[1][1] == 'k') { 126 argc--; 127 argv++; 128 kflag = 1; 129 } 130 } 131 if (kflag) { 132 if ((cp = getenv(MINUSKVAR)) == NULL) { 133 fprintf(stderr, "%s not set\n", MINUSKVAR); 134 exit(1); 135 } 136 setup(cp); 137 } else if (argc != 2) { 138 setup(getpass("Enter key:")); 139 } 140 else 141 setup(argv[1]); 142 n1 = 0; 143 n2 = 0; 144 nr2 = 0; 145 146 while((i=getchar()) != -1) { 147 if (secureflg) { 148 nr1 = deck[n1]&MASK; 149 nr2 = deck[nr1]&MASK; 150 } else { 151 nr1 = n1; 152 } 153 i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; 154 putchar(i); 155 n1++; 156 if(n1==ROTORSZ) { 157 n1 = 0; 158 n2++; 159 if(n2==ROTORSZ) n2 = 0; 160 if (secureflg) { 161 shuffle(deck); 162 } else { 163 nr2 = n2; 164 } 165 } 166 } 167 168 return 0; 169 } 170 171 void 172 shuffle(deckary) 173 char deckary[]; 174 { 175 int i, ic, k, temp; 176 unsigned rnd; 177 static long seed = 123; 178 179 for(i=0;i<ROTORSZ;i++) { 180 seed = 5*seed + buf[i%13]; 181 rnd = seed % 65521; 182 k = ROTORSZ-1 - i; 183 ic = (rnd&MASK)%(k+1); 184 temp = deckary[k]; 185 deckary[k] = deckary[ic]; 186 deckary[ic] = temp; 187 } 188 } 189