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