1160681Sjkim/*-
240767Sjoerg *	"enigma.c" is in file cbw.tar from
340767Sjoerg *	anonymous FTP host watmsg.waterloo.edu: pub/crypt/cbw.tar.Z
440767Sjoerg *
540767Sjoerg *	A one-rotor machine designed along the lines of Enigma
640767Sjoerg *	but considerably trivialized.
740767Sjoerg *
840767Sjoerg *	A public-domain replacement for the UNIX "crypt" command.
940767Sjoerg *
1040767Sjoerg *	Upgraded to function properly on 64-bit machines.
1140767Sjoerg */
1240767Sjoerg
1399112Sobrien#include <sys/cdefs.h>
1499112Sobrien__FBSDID("$FreeBSD$");
1578310Seric
1640769Sjoerg#include <sys/types.h>
1740769Sjoerg
1840769Sjoerg#include <stdio.h>
1940769Sjoerg#include <stdlib.h>
2040769Sjoerg#include <string.h>
2140769Sjoerg#include <unistd.h>
2240769Sjoerg
2340769Sjoerg#define MINUSKVAR "CrYpTkEy"
2440769Sjoerg
2540767Sjoerg#define ECHO 010
2640767Sjoerg#define ROTORSZ 256
2740767Sjoerg#define MASK 0377
28227237Sedstatic char	t1[ROTORSZ];
29227237Sedstatic char	t2[ROTORSZ];
30227237Sedstatic char	t3[ROTORSZ];
31227237Sedstatic char	deck[ROTORSZ];
32227237Sedstatic char	buf[13];
3340767Sjoerg
34227237Sedstatic void	shuffle(char *);
35227237Sedstatic void	setup(char *);
3640767Sjoerg
37227237Sedstatic void
38102944Sdwmalonesetup(char *pw)
3940767Sjoerg{
40120935Stjr	int ic, i, k, temp;
41120935Stjr	char salt[3];
4278781Sdd	unsigned rnd;
43160681Sjkim	int32_t seed;
44231994Skevlo	char *cryptpw;
4540767Sjoerg
46120935Stjr	strlcpy(salt, pw, sizeof(salt));
47231994Skevlo	cryptpw = crypt(pw, salt);
48231994Skevlo	if (cryptpw == NULL) {
49231994Skevlo		fprintf(stderr, "crypt(3) failure\n");
50231994Skevlo		exit(1);
51231994Skevlo	}
52231994Skevlo	memcpy(buf, cryptpw, sizeof(buf));
5340767Sjoerg	seed = 123;
5440767Sjoerg	for (i=0; i<13; i++)
5540767Sjoerg		seed = seed*buf[i] + i;
5640767Sjoerg	for(i=0;i<ROTORSZ;i++) {
5740767Sjoerg		t1[i] = i;
5840767Sjoerg		deck[i] = i;
5940767Sjoerg	}
6040767Sjoerg	for(i=0;i<ROTORSZ;i++) {
6140767Sjoerg		seed = 5*seed + buf[i%13];
6278781Sdd		rnd = seed % 65521;
6340767Sjoerg		k = ROTORSZ-1 - i;
6478781Sdd		ic = (rnd&MASK)%(k+1);
6578781Sdd		rnd >>= 8;
6640767Sjoerg		temp = t1[k];
6740767Sjoerg		t1[k] = t1[ic];
6840767Sjoerg		t1[ic] = temp;
6940767Sjoerg		if(t3[k]!=0) continue;
7078781Sdd		ic = (rnd&MASK) % k;
7140767Sjoerg		while(t3[ic]!=0) ic = (ic+1) % k;
7240767Sjoerg		t3[k] = ic;
7340767Sjoerg		t3[ic] = k;
7440767Sjoerg	}
7540767Sjoerg	for(i=0;i<ROTORSZ;i++)
7640767Sjoerg		t2[t1[i]&MASK] = i;
7740767Sjoerg}
7840767Sjoerg
7940769Sjoergint
80102944Sdwmalonemain(int argc, char *argv[])
8140767Sjoerg{
82102944Sdwmalone	int i, n1, n2, nr1, nr2;
8340769Sjoerg	int secureflg = 0, kflag = 0;
8440769Sjoerg	char *cp;
8540767Sjoerg
8640769Sjoerg	if (argc > 1 && argv[1][0] == '-') {
8740769Sjoerg		if (argv[1][1] == 's') {
8840769Sjoerg			argc--;
8940769Sjoerg			argv++;
9040769Sjoerg			secureflg = 1;
9140769Sjoerg		} else if (argv[1][1] == 'k') {
9240769Sjoerg			argc--;
9340769Sjoerg			argv++;
9440769Sjoerg			kflag = 1;
9540769Sjoerg		}
9640767Sjoerg	}
9740769Sjoerg	if (kflag) {
9840769Sjoerg		if ((cp = getenv(MINUSKVAR)) == NULL) {
9940769Sjoerg			fprintf(stderr, "%s not set\n", MINUSKVAR);
10040769Sjoerg			exit(1);
10140769Sjoerg		}
10240769Sjoerg		setup(cp);
10340769Sjoerg	} else if (argc != 2) {
10440767Sjoerg		setup(getpass("Enter key:"));
10540767Sjoerg	}
10640767Sjoerg	else
10740767Sjoerg		setup(argv[1]);
10840767Sjoerg	n1 = 0;
10940767Sjoerg	n2 = 0;
11040767Sjoerg	nr2 = 0;
11140767Sjoerg
11240769Sjoerg	while((i=getchar()) != -1) {
11340767Sjoerg		if (secureflg) {
11440767Sjoerg			nr1 = deck[n1]&MASK;
11540767Sjoerg			nr2 = deck[nr1]&MASK;
11640767Sjoerg		} else {
11740767Sjoerg			nr1 = n1;
11840767Sjoerg		}
11940767Sjoerg		i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1;
12040767Sjoerg		putchar(i);
12140767Sjoerg		n1++;
12240767Sjoerg		if(n1==ROTORSZ) {
12340767Sjoerg			n1 = 0;
12440767Sjoerg			n2++;
12540767Sjoerg			if(n2==ROTORSZ) n2 = 0;
12640767Sjoerg			if (secureflg) {
12740767Sjoerg				shuffle(deck);
12840767Sjoerg			} else {
12940767Sjoerg				nr2 = n2;
13040767Sjoerg			}
13140767Sjoerg		}
13240767Sjoerg	}
13340769Sjoerg
13440769Sjoerg	return 0;
13540767Sjoerg}
13640767Sjoerg
137227237Sedstatic void
138102944Sdwmaloneshuffle(char deckary[])
13940767Sjoerg{
14040767Sjoerg	int i, ic, k, temp;
14178781Sdd	unsigned rnd;
142160681Sjkim	static int32_t seed = 123;
14340767Sjoerg
14440767Sjoerg	for(i=0;i<ROTORSZ;i++) {
14540767Sjoerg		seed = 5*seed + buf[i%13];
14678781Sdd		rnd = seed % 65521;
14740767Sjoerg		k = ROTORSZ-1 - i;
14878781Sdd		ic = (rnd&MASK)%(k+1);
14978781Sdd		temp = deckary[k];
15078781Sdd		deckary[k] = deckary[ic];
15178781Sdd		deckary[ic] = temp;
15240767Sjoerg	}
15340767Sjoerg}
154