enigma.c revision 227237
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: head/usr.bin/enigma/enigma.c 227237 2011-11-06 18:49:23Z ed $");
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;
4440767Sjoerg
45120935Stjr	strlcpy(salt, pw, sizeof(salt));
46120935Stjr	memcpy(buf, crypt(pw, salt), sizeof(buf));
4740767Sjoerg	seed = 123;
4840767Sjoerg	for (i=0; i<13; i++)
4940767Sjoerg		seed = seed*buf[i] + i;
5040767Sjoerg	for(i=0;i<ROTORSZ;i++) {
5140767Sjoerg		t1[i] = i;
5240767Sjoerg		deck[i] = i;
5340767Sjoerg	}
5440767Sjoerg	for(i=0;i<ROTORSZ;i++) {
5540767Sjoerg		seed = 5*seed + buf[i%13];
5678781Sdd		rnd = seed % 65521;
5740767Sjoerg		k = ROTORSZ-1 - i;
5878781Sdd		ic = (rnd&MASK)%(k+1);
5978781Sdd		rnd >>= 8;
6040767Sjoerg		temp = t1[k];
6140767Sjoerg		t1[k] = t1[ic];
6240767Sjoerg		t1[ic] = temp;
6340767Sjoerg		if(t3[k]!=0) continue;
6478781Sdd		ic = (rnd&MASK) % k;
6540767Sjoerg		while(t3[ic]!=0) ic = (ic+1) % k;
6640767Sjoerg		t3[k] = ic;
6740767Sjoerg		t3[ic] = k;
6840767Sjoerg	}
6940767Sjoerg	for(i=0;i<ROTORSZ;i++)
7040767Sjoerg		t2[t1[i]&MASK] = i;
7140767Sjoerg}
7240767Sjoerg
7340769Sjoergint
74102944Sdwmalonemain(int argc, char *argv[])
7540767Sjoerg{
76102944Sdwmalone	int i, n1, n2, nr1, nr2;
7740769Sjoerg	int secureflg = 0, kflag = 0;
7840769Sjoerg	char *cp;
7940767Sjoerg
8040769Sjoerg	if (argc > 1 && argv[1][0] == '-') {
8140769Sjoerg		if (argv[1][1] == 's') {
8240769Sjoerg			argc--;
8340769Sjoerg			argv++;
8440769Sjoerg			secureflg = 1;
8540769Sjoerg		} else if (argv[1][1] == 'k') {
8640769Sjoerg			argc--;
8740769Sjoerg			argv++;
8840769Sjoerg			kflag = 1;
8940769Sjoerg		}
9040767Sjoerg	}
9140769Sjoerg	if (kflag) {
9240769Sjoerg		if ((cp = getenv(MINUSKVAR)) == NULL) {
9340769Sjoerg			fprintf(stderr, "%s not set\n", MINUSKVAR);
9440769Sjoerg			exit(1);
9540769Sjoerg		}
9640769Sjoerg		setup(cp);
9740769Sjoerg	} else if (argc != 2) {
9840767Sjoerg		setup(getpass("Enter key:"));
9940767Sjoerg	}
10040767Sjoerg	else
10140767Sjoerg		setup(argv[1]);
10240767Sjoerg	n1 = 0;
10340767Sjoerg	n2 = 0;
10440767Sjoerg	nr2 = 0;
10540767Sjoerg
10640769Sjoerg	while((i=getchar()) != -1) {
10740767Sjoerg		if (secureflg) {
10840767Sjoerg			nr1 = deck[n1]&MASK;
10940767Sjoerg			nr2 = deck[nr1]&MASK;
11040767Sjoerg		} else {
11140767Sjoerg			nr1 = n1;
11240767Sjoerg		}
11340767Sjoerg		i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1;
11440767Sjoerg		putchar(i);
11540767Sjoerg		n1++;
11640767Sjoerg		if(n1==ROTORSZ) {
11740767Sjoerg			n1 = 0;
11840767Sjoerg			n2++;
11940767Sjoerg			if(n2==ROTORSZ) n2 = 0;
12040767Sjoerg			if (secureflg) {
12140767Sjoerg				shuffle(deck);
12240767Sjoerg			} else {
12340767Sjoerg				nr2 = n2;
12440767Sjoerg			}
12540767Sjoerg		}
12640767Sjoerg	}
12740769Sjoerg
12840769Sjoerg	return 0;
12940767Sjoerg}
13040767Sjoerg
131227237Sedstatic void
132102944Sdwmaloneshuffle(char deckary[])
13340767Sjoerg{
13440767Sjoerg	int i, ic, k, temp;
13578781Sdd	unsigned rnd;
136160681Sjkim	static int32_t seed = 123;
13740767Sjoerg
13840767Sjoerg	for(i=0;i<ROTORSZ;i++) {
13940767Sjoerg		seed = 5*seed + buf[i%13];
14078781Sdd		rnd = seed % 65521;
14140767Sjoerg		k = ROTORSZ-1 - i;
14278781Sdd		ic = (rnd&MASK)%(k+1);
14378781Sdd		temp = deckary[k];
14478781Sdd		deckary[k] = deckary[ic];
14578781Sdd		deckary[ic] = temp;
14640767Sjoerg	}
14740767Sjoerg}
148