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