Home | History | Annotate | Download | only in crypt
      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