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.5 2004/07/31 11:18:43 eirikn 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 void shuffle(char *); 36 void setup(char *); 37 38 void 39 setup(char *pw) 40 { 41 int ic, i, k, temp; 42 char salt[3]; 43 unsigned rnd; 44 long seed; 45 46 strncpy(salt, pw, sizeof(salt)); 47 memcpy(buf, crypt(pw, salt), sizeof(buf)); 48 seed = 123; 49 for (i=0; i<13; i++) 50 seed = seed*buf[i] + i; 51 for(i=0;i<ROTORSZ;i++) { 52 t1[i] = i; 53 deck[i] = i; 54 } 55 for(i=0;i<ROTORSZ;i++) { 56 seed = 5*seed + buf[i%13]; 57 if( sizeof(long) > 4 ) { 58 /* Force seed to stay in 32-bit signed math */ 59 if( seed & 0x80000000 ) 60 seed = seed | (-1L & ~0xFFFFFFFFL); 61 else 62 seed &= 0x7FFFFFFF; 63 } 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 register 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 void 140 shuffle(char *deckary) 141 { 142 int i, ic, k, temp; 143 unsigned rnd; 144 static long 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