/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * A one-rotor machine designed along the lines of Enigma * but considerably trivialized. */ #define ECHO 010 #include #include #include #include #include #include #define ROTORSZ 256 #define MASK 0377 char t1[ROTORSZ]; char t2[ROTORSZ]; char t3[ROTORSZ]; static void setup(pw) char *pw; { int ic, i, k, temp; unsigned random; char buf[13]; long seed; char *ret; int err; (void) strncpy(buf, pw, 8); buf[8] = buf[0]; buf[9] = buf[1]; errno = 0; ret = des_crypt(buf, &buf[8]); if (ret == NULL) { err = errno; (void) fprintf(stderr, "crypt: setup failed, unable to" " initialize rotors: %s\n", strerror(err)); exit(1); } (void) strncpy(buf, ret, 13); seed = 123; for (i = 0; i < 13; i++) seed = seed*buf[i] + i; for (i = 0; i < ROTORSZ; i++) { t1[i] = i; t3[i] = 0; } for (i = 0; i < ROTORSZ; i++) { seed = 5*seed + buf[i%13]; random = seed % 65521; k = ROTORSZ-1 - i; ic = (random&MASK)%(k+1); random >>= 8; temp = t1[k]; t1[k] = t1[ic]; t1[ic] = temp; if (t3[k] != 0) continue; ic = (random&MASK) % k; while (t3[ic] != 0) ic = (ic+1) % k; t3[k] = ic; t3[ic] = k; } for (i = 0; i < ROTORSZ; i++) t2[t1[i]&MASK] = i; } int main(int argc, char **argv) { extern int optind; char *p1; int i, n1, n2, nchar; int c; struct { long offset; unsigned int count; } header; int pflag = 0; int kflag = 0; char *buf; char key[8]; char keyvar[] = "CrYpTkEy=XXXXXXXX"; char *s; if (argc < 2) { if ((buf = (char *)getpass("Enter key:")) == NULL) { (void) fprintf(stderr, "Cannot open /dev/tty\n"); exit(1); } setup(buf); } else { while ((c = getopt(argc, argv, "pk")) != EOF) switch (c) { case 'p': /* notify editor that exec has succeeded */ if (write(1, "y", 1) != 1) exit(1); if (read(0, key, 8) != 8) exit(1); setup(key); pflag = 1; break; case 'k': if ((s = getenv("CrYpTkEy")) == (char *)NULL) { (void) fprintf(stderr, "CrYpTkEy not set.\n"); exit(1); } (void) strncpy(key, s, 8); setup(key); kflag = 1; break; case '?': (void) fprintf(stderr, "usage: crypt [ -k ] [ key]\n"); exit(2); } if (pflag == 0 && kflag == 0) { (void) strncpy(keyvar+9, argv[optind], 8); (void) putenv(keyvar); (void) execlp("crypt", "crypt", "-k", 0); } } if (pflag) for (;;) { if ((nchar = read(0, (char *)&header, sizeof (header))) != sizeof (header)) exit(nchar); n1 = (int)(header.offset&MASK); n2 = (int)((header.offset >> 8) &MASK); nchar = header.count; buf = (char *)malloc(nchar); p1 = buf; if (read(0, buf, nchar) != nchar) exit(1); while (nchar--) { *p1 = t2[(t3[(t1[(*p1 + n1)&MASK]+ n2)&MASK] - n2)&MASK] - n1; n1++; if (n1 == ROTORSZ) { n1 = 0; n2++; if (n2 == ROTORSZ) n2 = 0; } p1++; } nchar = header.count; if (write(1, buf, nchar) != nchar) exit(1); free(buf); } n1 = 0; n2 = 0; while ((i = getchar()) >= 0) { i = t2[(t3[(t1[(i+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; (void) putchar(i); n1++; if (n1 == ROTORSZ) { n1 = 0; n2++; if (n2 == ROTORSZ) n2 = 0; } } return (0); }