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