1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*
32 * A one-rotor machine designed along the lines of Enigma
33 * but considerably trivialized.
34 */
35
36 #define ECHO 010
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <string.h>
41 #include <crypt.h>
42 #include <errno.h>
43
44 #define ROTORSZ 256
45 #define MASK 0377
46 char t1[ROTORSZ];
47 char t2[ROTORSZ];
48 char t3[ROTORSZ];
49
50 static void
setup(pw)51 setup(pw)
52 char *pw;
53 {
54 int ic, i, k, temp;
55 unsigned random;
56 char buf[13];
57 long seed;
58 char *ret;
59 int err;
60
61 (void) strncpy(buf, pw, 8);
62 buf[8] = buf[0];
63 buf[9] = buf[1];
64 errno = 0;
65 ret = des_crypt(buf, &buf[8]);
66 if (ret == NULL) {
67 err = errno;
68 (void) fprintf(stderr, "crypt: setup failed, unable to"
69 " initialize rotors: %s\n", strerror(err));
70 exit(1);
71 }
72 (void) strncpy(buf, ret, 13);
73 seed = 123;
74 for (i = 0; i < 13; i++)
75 seed = seed*buf[i] + i;
76 for (i = 0; i < ROTORSZ; i++) {
77 t1[i] = i;
78 t3[i] = 0;
79 }
80 for (i = 0; i < ROTORSZ; i++) {
81 seed = 5*seed + buf[i%13];
82 random = seed % 65521;
83 k = ROTORSZ-1 - i;
84 ic = (random&MASK)%(k+1);
85 random >>= 8;
86 temp = t1[k];
87 t1[k] = t1[ic];
88 t1[ic] = temp;
89 if (t3[k] != 0) continue;
90 ic = (random&MASK) % k;
91 while (t3[ic] != 0) ic = (ic+1) % k;
92 t3[k] = ic;
93 t3[ic] = k;
94 }
95 for (i = 0; i < ROTORSZ; i++)
96 t2[t1[i]&MASK] = i;
97 }
98
99 int
main(int argc,char ** argv)100 main(int argc, char **argv)
101 {
102 extern int optind;
103 char *p1;
104 int i, n1, n2, nchar;
105 int c;
106 struct {
107 long offset;
108 unsigned int count;
109 } header;
110 int pflag = 0;
111 int kflag = 0;
112 char *buf;
113 char key[8];
114 char keyvar[] = "CrYpTkEy=XXXXXXXX";
115 char *s;
116
117 if (argc < 2) {
118 if ((buf = (char *)getpass("Enter key:")) == NULL) {
119 (void) fprintf(stderr, "Cannot open /dev/tty\n");
120 exit(1);
121 }
122 setup(buf);
123 } else {
124 while ((c = getopt(argc, argv, "pk")) != EOF)
125 switch (c) {
126 case 'p':
127 /* notify editor that exec has succeeded */
128 if (write(1, "y", 1) != 1)
129 exit(1);
130 if (read(0, key, 8) != 8)
131 exit(1);
132 setup(key);
133 pflag = 1;
134 break;
135 case 'k':
136 if ((s = getenv("CrYpTkEy")) == (char *)NULL) {
137 (void) fprintf(stderr,
138 "CrYpTkEy not set.\n");
139 exit(1);
140 }
141 (void) strncpy(key, s, 8);
142 setup(key);
143 kflag = 1;
144 break;
145 case '?':
146 (void) fprintf(stderr,
147 "usage: crypt [ -k ] [ key]\n");
148 exit(2);
149 }
150 if (pflag == 0 && kflag == 0) {
151 (void) strncpy(keyvar+9, argv[optind], 8);
152 (void) putenv(keyvar);
153 (void) execlp("crypt", "crypt", "-k", 0);
154 }
155 }
156 if (pflag)
157 for (;;) {
158 if ((nchar = read(0, (char *)&header, sizeof (header)))
159 != sizeof (header))
160 exit(nchar);
161 n1 = (int)(header.offset&MASK);
162 n2 = (int)((header.offset >> 8) &MASK);
163 nchar = header.count;
164 buf = (char *)malloc(nchar);
165 p1 = buf;
166 if (read(0, buf, nchar) != nchar)
167 exit(1);
168 while (nchar--) {
169 *p1 = t2[(t3[(t1[(*p1 + n1)&MASK]+
170 n2)&MASK] - n2)&MASK] - n1;
171 n1++;
172 if (n1 == ROTORSZ) {
173 n1 = 0;
174 n2++;
175 if (n2 == ROTORSZ) n2 = 0;
176 }
177 p1++;
178 }
179 nchar = header.count;
180 if (write(1, buf, nchar) != nchar)
181 exit(1);
182 free(buf);
183 }
184
185 n1 = 0;
186 n2 = 0;
187
188 while ((i = getchar()) >= 0) {
189 i = t2[(t3[(t1[(i+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1;
190 (void) putchar(i);
191 n1++;
192 if (n1 == ROTORSZ) {
193 n1 = 0;
194 n2++;
195 if (n2 == ROTORSZ) n2 = 0;
196 }
197 }
198 return (0);
199 }
200