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 #pragma ident "%Z%%M% %I% %E% SMI"
32 /*
33 * A one-rotor machine designed along the lines of Enigma
34 * but considerably trivialized.
35 */
36
37 /* EXPORT DELETE START */
38 #define ECHO 010
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <crypt.h>
44 #include <errno.h>
45
46 #define ROTORSZ 256
47 #define MASK 0377
48 char t1[ROTORSZ];
49 char t2[ROTORSZ];
50 char t3[ROTORSZ];
51
52 static void
setup(pw)53 setup(pw)
54 char *pw;
55 {
56 int ic, i, k, temp;
57 unsigned random;
58 char buf[13];
59 long seed;
60 char *ret;
61 int err;
62
63 (void) strncpy(buf, pw, 8);
64 buf[8] = buf[0];
65 buf[9] = buf[1];
66 errno = 0;
67 ret = des_crypt(buf, &buf[8]);
68 if (ret == NULL) {
69 err = errno;
70 (void) fprintf(stderr, "crypt: setup failed, unable to"
71 " initialize rotors: %s\n", strerror(err));
72 exit(1);
73 }
74 (void) strncpy(buf, ret, 13);
75 seed = 123;
76 for (i = 0; i < 13; i++)
77 seed = seed*buf[i] + i;
78 for (i = 0; i < ROTORSZ; i++) {
79 t1[i] = i;
80 t3[i] = 0;
81 }
82 for (i = 0; i < ROTORSZ; i++) {
83 seed = 5*seed + buf[i%13];
84 random = seed % 65521;
85 k = ROTORSZ-1 - i;
86 ic = (random&MASK)%(k+1);
87 random >>= 8;
88 temp = t1[k];
89 t1[k] = t1[ic];
90 t1[ic] = temp;
91 if (t3[k] != 0) continue;
92 ic = (random&MASK) % k;
93 while (t3[ic] != 0) ic = (ic+1) % k;
94 t3[k] = ic;
95 t3[ic] = k;
96 }
97 for (i = 0; i < ROTORSZ; i++)
98 t2[t1[i]&MASK] = i;
99 }
100 /* EXPORT DELETE END */
101
102 int
main(int argc,char ** argv)103 main(int argc, char **argv)
104 {
105 /* EXPORT DELETE START */
106 extern int optind;
107 char *p1;
108 int i, n1, n2, nchar;
109 int c;
110 struct {
111 long offset;
112 unsigned int count;
113 } header;
114 int pflag = 0;
115 int kflag = 0;
116 char *buf;
117 char key[8];
118 char *keyvar = "CrYpTkEy=XXXXXXXX";
119 char *s;
120
121 if (argc < 2) {
122 if ((buf = (char *)getpass("Enter key:")) == NULL) {
123 (void) fprintf(stderr, "Cannot open /dev/tty\n");
124 exit(1);
125 }
126 setup(buf);
127 } else {
128 while ((c = getopt(argc, argv, "pk")) != EOF)
129 switch (c) {
130 case 'p':
131 /* notify editor that exec has succeeded */
132 if (write(1, "y", 1) != 1)
133 exit(1);
134 if (read(0, key, 8) != 8)
135 exit(1);
136 setup(key);
137 pflag = 1;
138 break;
139 case 'k':
140 if ((s = getenv("CrYpTkEy")) == (char *)NULL) {
141 (void) fprintf(stderr,
142 "CrYpTkEy not set.\n");
143 exit(1);
144 }
145 (void) strncpy(key, s, 8);
146 setup(key);
147 kflag = 1;
148 break;
149 case '?':
150 (void) fprintf(stderr,
151 "usage: crypt [ -k ] [ key]\n");
152 exit(2);
153 }
154 if (pflag == 0 && kflag == 0) {
155 (void) strncpy(keyvar+9, argv[optind], 8);
156 (void) putenv(keyvar);
157 (void) execlp("crypt", "crypt", "-k", 0);
158 }
159 }
160 if (pflag)
161 for (;;) {
162 if ((nchar = read(0, (char *)&header, sizeof (header)))
163 != sizeof (header))
164 exit(nchar);
165 n1 = (int)(header.offset&MASK);
166 n2 = (int)((header.offset >> 8) &MASK);
167 nchar = header.count;
168 buf = (char *)malloc(nchar);
169 p1 = buf;
170 if (read(0, buf, nchar) != nchar)
171 exit(1);
172 while (nchar--) {
173 *p1 = t2[(t3[(t1[(*p1 + n1)&MASK]+
174 n2)&MASK] - n2)&MASK] - n1;
175 n1++;
176 if (n1 == ROTORSZ) {
177 n1 = 0;
178 n2++;
179 if (n2 == ROTORSZ) n2 = 0;
180 }
181 p1++;
182 }
183 nchar = header.count;
184 if (write(1, buf, nchar) != nchar)
185 exit(1);
186 free(buf);
187 }
188
189 n1 = 0;
190 n2 = 0;
191
192 while ((i = getchar()) >= 0) {
193 i = t2[(t3[(t1[(i+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1;
194 (void) putchar(i);
195 n1++;
196 if (n1 == ROTORSZ) {
197 n1 = 0;
198 n2++;
199 if (n2 == ROTORSZ) n2 = 0;
200 }
201 }
202 return (0);
203 /* EXPORT DELETE END */
204 }
205