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 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <unistd.h> 22 23 #define MINUSKVAR "CrYpTkEy" 24 25 #define ECHO 010 26 #define ROTORSZ 256 27 #define MASK 0377 28 char t1[ROTORSZ]; 29 char t2[ROTORSZ]; 30 char t3[ROTORSZ]; 31 char deck[ROTORSZ]; 32 char buf[13]; 33 34 void shuffle(char *); 35 void setup(char *); 36 37 void 38 setup(char *pw) 39 { 40 int ic, i, k, temp; 41 char salt[3]; 42 unsigned rnd; 43 int32_t seed; 44 45 strlcpy(salt, pw, sizeof(salt)); 46 memcpy(buf, crypt(pw, salt), sizeof(buf)); 47 seed = 123; 48 for (i=0; i<13; i++) 49 seed = seed*buf[i] + i; 50 for(i=0;i<ROTORSZ;i++) { 51 t1[i] = i; 52 deck[i] = i; 53 } 54 for(i=0;i<ROTORSZ;i++) { 55 seed = 5*seed + buf[i%13]; 56 rnd = seed % 65521; 57 k = ROTORSZ-1 - i; 58 ic = (rnd&MASK)%(k+1); 59 rnd >>= 8; 60 temp = t1[k]; 61 t1[k] = t1[ic]; 62 t1[ic] = temp; 63 if(t3[k]!=0) continue; 64 ic = (rnd&MASK) % k; 65 while(t3[ic]!=0) ic = (ic+1) % k; 66 t3[k] = ic; 67 t3[ic] = k; 68 } 69 for(i=0;i<ROTORSZ;i++) 70 t2[t1[i]&MASK] = i; 71 } 72 73 int 74 main(int argc, char *argv[]) 75 { 76 int i, n1, n2, nr1, nr2; 77 int secureflg = 0, kflag = 0; 78 char *cp; 79 80 if (argc > 1 && argv[1][0] == '-') { 81 if (argv[1][1] == 's') { 82 argc--; 83 argv++; 84 secureflg = 1; 85 } else if (argv[1][1] == 'k') { 86 argc--; 87 argv++; 88 kflag = 1; 89 } 90 } 91 if (kflag) { 92 if ((cp = getenv(MINUSKVAR)) == NULL) { 93 fprintf(stderr, "%s not set\n", MINUSKVAR); 94 exit(1); 95 } 96 setup(cp); 97 } else if (argc != 2) { 98 setup(getpass("Enter key:")); 99 } 100 else 101 setup(argv[1]); 102 n1 = 0; 103 n2 = 0; 104 nr2 = 0; 105 106 while((i=getchar()) != -1) { 107 if (secureflg) { 108 nr1 = deck[n1]&MASK; 109 nr2 = deck[nr1]&MASK; 110 } else { 111 nr1 = n1; 112 } 113 i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; 114 putchar(i); 115 n1++; 116 if(n1==ROTORSZ) { 117 n1 = 0; 118 n2++; 119 if(n2==ROTORSZ) n2 = 0; 120 if (secureflg) { 121 shuffle(deck); 122 } else { 123 nr2 = n2; 124 } 125 } 126 } 127 128 return 0; 129 } 130 131 void 132 shuffle(char deckary[]) 133 { 134 int i, ic, k, temp; 135 unsigned rnd; 136 static int32_t seed = 123; 137 138 for(i=0;i<ROTORSZ;i++) { 139 seed = 5*seed + buf[i%13]; 140 rnd = seed % 65521; 141 k = ROTORSZ-1 - i; 142 ic = (rnd&MASK)%(k+1); 143 temp = deckary[k]; 144 deckary[k] = deckary[ic]; 145 deckary[ic] = temp; 146 } 147 } 148