]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/enigma/enigma.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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 char    t1[ROTORSZ];
29 char    t2[ROTORSZ];
30 char    t3[ROTORSZ];
31 char    deck[ROTORSZ];
32 char    buf[13];
33
34 void    shuffle(char *);
35 void    setup(char *);
36
37 void
38 setup(char *pw)
39 {
40         int ic, i, k, temp;
41         char salt[3];
42         unsigned rnd;
43         int32_t seed;
44
45         strlcpy(salt, pw, sizeof(salt));
46         memcpy(buf, crypt(pw, salt), sizeof(buf));
47         seed = 123;
48         for (i=0; i<13; i++)
49                 seed = seed*buf[i] + i;
50         for(i=0;i<ROTORSZ;i++) {
51                 t1[i] = i;
52                 deck[i] = i;
53         }
54         for(i=0;i<ROTORSZ;i++) {
55                 seed = 5*seed + buf[i%13];
56                 rnd = seed % 65521;
57                 k = ROTORSZ-1 - i;
58                 ic = (rnd&MASK)%(k+1);
59                 rnd >>= 8;
60                 temp = t1[k];
61                 t1[k] = t1[ic];
62                 t1[ic] = temp;
63                 if(t3[k]!=0) continue;
64                 ic = (rnd&MASK) % k;
65                 while(t3[ic]!=0) ic = (ic+1) % k;
66                 t3[k] = ic;
67                 t3[ic] = k;
68         }
69         for(i=0;i<ROTORSZ;i++)
70                 t2[t1[i]&MASK] = i;
71 }
72
73 int
74 main(int argc, char *argv[])
75 {
76         int i, n1, n2, nr1, nr2;
77         int secureflg = 0, kflag = 0;
78         char *cp;
79
80         if (argc > 1 && argv[1][0] == '-') {
81                 if (argv[1][1] == 's') {
82                         argc--;
83                         argv++;
84                         secureflg = 1;
85                 } else if (argv[1][1] == 'k') {
86                         argc--;
87                         argv++;
88                         kflag = 1;
89                 }
90         }
91         if (kflag) {
92                 if ((cp = getenv(MINUSKVAR)) == NULL) {
93                         fprintf(stderr, "%s not set\n", MINUSKVAR);
94                         exit(1);
95                 }
96                 setup(cp);
97         } else if (argc != 2) {
98                 setup(getpass("Enter key:"));
99         }
100         else
101                 setup(argv[1]);
102         n1 = 0;
103         n2 = 0;
104         nr2 = 0;
105
106         while((i=getchar()) != -1) {
107                 if (secureflg) {
108                         nr1 = deck[n1]&MASK;
109                         nr2 = deck[nr1]&MASK;
110                 } else {
111                         nr1 = n1;
112                 }
113                 i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1;
114                 putchar(i);
115                 n1++;
116                 if(n1==ROTORSZ) {
117                         n1 = 0;
118                         n2++;
119                         if(n2==ROTORSZ) n2 = 0;
120                         if (secureflg) {
121                                 shuffle(deck);
122                         } else {
123                                 nr2 = n2;
124                         }
125                 }
126         }
127
128         return 0;
129 }
130
131 void
132 shuffle(char deckary[])
133 {
134         int i, ic, k, temp;
135         unsigned rnd;
136         static int32_t seed = 123;
137
138         for(i=0;i<ROTORSZ;i++) {
139                 seed = 5*seed + buf[i%13];
140                 rnd = seed % 65521;
141                 k = ROTORSZ-1 - i;
142                 ic = (rnd&MASK)%(k+1);
143                 temp = deckary[k];
144                 deckary[k] = deckary[ic];
145                 deckary[ic] = temp;
146         }
147 }