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