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 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 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