]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.bin/enigma/enigma.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.bin / enigma / enigma.c
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 }