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 * $FreeBSD: src/usr.bin/enigma/enigma.c,v 1.2.6.3 2001/08/01 23:51:34 obrien Exp $ 13 * $DragonFly: src/usr.bin/enigma/enigma.c,v 1.4 2003/11/04 16:36:35 drhodus Exp $ 14 */ 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 int main(int, char *[]); 36 void shuffle(char *); 37 void setup(char *); 38 39 void 40 setup(char *pw) 41 { 42 int ic, i, k, temp; 43 char salt[3]; 44 unsigned rnd; 45 long seed; 46 47 strncpy(salt, pw, sizeof(salt)); 48 memcpy(buf, crypt(pw, salt), sizeof(buf)); 49 seed = 123; 50 for (i=0; i<13; i++) 51 seed = seed*buf[i] + i; 52 for(i=0;i<ROTORSZ;i++) { 53 t1[i] = i; 54 deck[i] = i; 55 } 56 for(i=0;i<ROTORSZ;i++) { 57 seed = 5*seed + buf[i%13]; 58 if( sizeof(long) > 4 ) { 59 /* Force seed to stay in 32-bit signed math */ 60 if( seed & 0x80000000 ) 61 seed = seed | (-1L & ~0xFFFFFFFFL); 62 else 63 seed &= 0x7FFFFFFF; 64 } 65 rnd = seed % 65521; 66 k = ROTORSZ-1 - i; 67 ic = (rnd&MASK)%(k+1); 68 rnd >>= 8; 69 temp = t1[k]; 70 t1[k] = t1[ic]; 71 t1[ic] = temp; 72 if(t3[k]!=0) continue; 73 ic = (rnd&MASK) % k; 74 while(t3[ic]!=0) ic = (ic+1) % k; 75 t3[k] = ic; 76 t3[ic] = k; 77 } 78 for(i=0;i<ROTORSZ;i++) 79 t2[t1[i]&MASK] = i; 80 } 81 82 int 83 main(int argc, char **argv) 84 { 85 register int i, n1, n2, nr1, nr2; 86 int secureflg = 0, kflag = 0; 87 char *cp; 88 89 if (argc > 1 && argv[1][0] == '-') { 90 if (argv[1][1] == 's') { 91 argc--; 92 argv++; 93 secureflg = 1; 94 } else if (argv[1][1] == 'k') { 95 argc--; 96 argv++; 97 kflag = 1; 98 } 99 } 100 if (kflag) { 101 if ((cp = getenv(MINUSKVAR)) == NULL) { 102 fprintf(stderr, "%s not set\n", MINUSKVAR); 103 exit(1); 104 } 105 setup(cp); 106 } else if (argc != 2) { 107 setup(getpass("Enter key:")); 108 } 109 else 110 setup(argv[1]); 111 n1 = 0; 112 n2 = 0; 113 nr2 = 0; 114 115 while((i=getchar()) != -1) { 116 if (secureflg) { 117 nr1 = deck[n1]&MASK; 118 nr2 = deck[nr1]&MASK; 119 } else { 120 nr1 = n1; 121 } 122 i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; 123 putchar(i); 124 n1++; 125 if(n1==ROTORSZ) { 126 n1 = 0; 127 n2++; 128 if(n2==ROTORSZ) n2 = 0; 129 if (secureflg) { 130 shuffle(deck); 131 } else { 132 nr2 = n2; 133 } 134 } 135 } 136 137 return 0; 138 } 139 140 void 141 shuffle(char *deckary) 142 { 143 int i, ic, k, temp; 144 unsigned rnd; 145 static long seed = 123; 146 147 for(i=0;i<ROTORSZ;i++) { 148 seed = 5*seed + buf[i%13]; 149 rnd = seed % 65521; 150 k = ROTORSZ-1 - i; 151 ic = (rnd&MASK)%(k+1); 152 temp = deckary[k]; 153 deckary[k] = deckary[ic]; 154 deckary[ic] = temp; 155 } 156 } 157