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