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