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