113e21a9dSJoerg Wunsch /* 213e21a9dSJoerg Wunsch * "enigma.c" is in file cbw.tar from 313e21a9dSJoerg Wunsch * anonymous FTP host watmsg.waterloo.edu: pub/crypt/cbw.tar.Z 413e21a9dSJoerg Wunsch * 513e21a9dSJoerg Wunsch * A one-rotor machine designed along the lines of Enigma 613e21a9dSJoerg Wunsch * but considerably trivialized. 713e21a9dSJoerg Wunsch * 813e21a9dSJoerg Wunsch * A public-domain replacement for the UNIX "crypt" command. 913e21a9dSJoerg Wunsch * 1013e21a9dSJoerg Wunsch * Upgraded to function properly on 64-bit machines. 1113e21a9dSJoerg Wunsch */ 1213e21a9dSJoerg Wunsch 13a70bac9dSEric Melville #ifndef lint 14a70bac9dSEric Melville static const char rcsid[] = 15a70bac9dSEric Melville "$FreeBSD$"; 16a70bac9dSEric Melville #endif /* not lint */ 17a70bac9dSEric Melville 185dc67cd7SJoerg Wunsch #include <sys/types.h> 195dc67cd7SJoerg Wunsch #include <sys/wait.h> 205dc67cd7SJoerg Wunsch 2113e21a9dSJoerg Wunsch #include <stdio.h> 225dc67cd7SJoerg Wunsch #include <stdlib.h> 235dc67cd7SJoerg Wunsch #include <string.h> 245dc67cd7SJoerg Wunsch #include <unistd.h> 255dc67cd7SJoerg Wunsch 265dc67cd7SJoerg Wunsch #define MINUSKVAR "CrYpTkEy" 275dc67cd7SJoerg Wunsch 285dc67cd7SJoerg Wunsch #define ECHO 010 2913e21a9dSJoerg Wunsch #define ROTORSZ 256 3013e21a9dSJoerg Wunsch #define MASK 0377 3113e21a9dSJoerg Wunsch char t1[ROTORSZ]; 3213e21a9dSJoerg Wunsch char t2[ROTORSZ]; 3313e21a9dSJoerg Wunsch char t3[ROTORSZ]; 3413e21a9dSJoerg Wunsch char deck[ROTORSZ]; 3513e21a9dSJoerg Wunsch char buf[13]; 3613e21a9dSJoerg Wunsch 375dc67cd7SJoerg Wunsch void shuffle(char *); 38461ce74aSDima Dorfman void setup(char *); 3913e21a9dSJoerg Wunsch 4013e21a9dSJoerg Wunsch void 4113e21a9dSJoerg Wunsch setup(pw) 4213e21a9dSJoerg Wunsch char *pw; 4313e21a9dSJoerg Wunsch { 4413e21a9dSJoerg Wunsch int ic, i, k, temp, pf[2], pid; 45461ce74aSDima Dorfman unsigned rnd; 4613e21a9dSJoerg Wunsch long seed; 4713e21a9dSJoerg Wunsch 4813e21a9dSJoerg Wunsch strncpy(buf, pw, 8); 4913e21a9dSJoerg Wunsch while (*pw) 5013e21a9dSJoerg Wunsch *pw++ = '\0'; 5113e21a9dSJoerg Wunsch buf[8] = buf[0]; 5213e21a9dSJoerg Wunsch buf[9] = buf[1]; 5313e21a9dSJoerg Wunsch pipe(pf); 5413e21a9dSJoerg Wunsch if ((pid=fork())==0) { 5513e21a9dSJoerg Wunsch close(0); 5613e21a9dSJoerg Wunsch close(1); 5713e21a9dSJoerg Wunsch dup(pf[0]); 5813e21a9dSJoerg Wunsch dup(pf[1]); 5913e21a9dSJoerg Wunsch execlp("makekey", "-", 0); 6013e21a9dSJoerg Wunsch execl("/usr/libexec/makekey", "-", 0); /* BSDI */ 6113e21a9dSJoerg Wunsch execl("/usr/lib/makekey", "-", 0); 6213e21a9dSJoerg Wunsch execl("/usr/bin/makekey", "-", 0); /* IBM */ 6313e21a9dSJoerg Wunsch execl("/lib/makekey", "-", 0); 6413e21a9dSJoerg Wunsch perror("makekey"); 6513e21a9dSJoerg Wunsch fprintf(stderr, "enigma: cannot execute 'makekey', aborting\n"); 6613e21a9dSJoerg Wunsch exit(1); 6713e21a9dSJoerg Wunsch } 6813e21a9dSJoerg Wunsch write(pf[1], buf, 10); 6913e21a9dSJoerg Wunsch close(pf[1]); 7013e21a9dSJoerg Wunsch i=wait((int *)NULL); 7113e21a9dSJoerg Wunsch if (i<0) perror("enigma: wait"); 7213e21a9dSJoerg Wunsch if (i!=pid) { 7313e21a9dSJoerg Wunsch fprintf(stderr, "enigma: expected pid %d, got pid %d\n", pid, i); 7413e21a9dSJoerg Wunsch exit(1); 7513e21a9dSJoerg Wunsch } 7613e21a9dSJoerg Wunsch if ((i=read(pf[0], buf, 13)) != 13) { 7713e21a9dSJoerg Wunsch fprintf(stderr, "enigma: cannot generate key, read %d\n",i); 7813e21a9dSJoerg Wunsch exit(1); 7913e21a9dSJoerg Wunsch } 8013e21a9dSJoerg Wunsch seed = 123; 8113e21a9dSJoerg Wunsch for (i=0; i<13; i++) 8213e21a9dSJoerg Wunsch seed = seed*buf[i] + i; 8313e21a9dSJoerg Wunsch for(i=0;i<ROTORSZ;i++) { 8413e21a9dSJoerg Wunsch t1[i] = i; 8513e21a9dSJoerg Wunsch deck[i] = i; 8613e21a9dSJoerg Wunsch } 8713e21a9dSJoerg Wunsch for(i=0;i<ROTORSZ;i++) { 8813e21a9dSJoerg Wunsch seed = 5*seed + buf[i%13]; 8913e21a9dSJoerg Wunsch if( sizeof(long) > 4 ) { 9013e21a9dSJoerg Wunsch /* Force seed to stay in 32-bit signed math */ 9113e21a9dSJoerg Wunsch if( seed & 0x80000000 ) 9213e21a9dSJoerg Wunsch seed = seed | (-1L & ~0xFFFFFFFFL); 9313e21a9dSJoerg Wunsch else 9413e21a9dSJoerg Wunsch seed &= 0x7FFFFFFF; 9513e21a9dSJoerg Wunsch } 96461ce74aSDima Dorfman rnd = seed % 65521; 9713e21a9dSJoerg Wunsch k = ROTORSZ-1 - i; 98461ce74aSDima Dorfman ic = (rnd&MASK)%(k+1); 99461ce74aSDima Dorfman rnd >>= 8; 10013e21a9dSJoerg Wunsch temp = t1[k]; 10113e21a9dSJoerg Wunsch t1[k] = t1[ic]; 10213e21a9dSJoerg Wunsch t1[ic] = temp; 10313e21a9dSJoerg Wunsch if(t3[k]!=0) continue; 104461ce74aSDima Dorfman ic = (rnd&MASK) % k; 10513e21a9dSJoerg Wunsch while(t3[ic]!=0) ic = (ic+1) % k; 10613e21a9dSJoerg Wunsch t3[k] = ic; 10713e21a9dSJoerg Wunsch t3[ic] = k; 10813e21a9dSJoerg Wunsch } 10913e21a9dSJoerg Wunsch for(i=0;i<ROTORSZ;i++) 11013e21a9dSJoerg Wunsch t2[t1[i]&MASK] = i; 11113e21a9dSJoerg Wunsch } 11213e21a9dSJoerg Wunsch 1135dc67cd7SJoerg Wunsch int 11413e21a9dSJoerg Wunsch main(argc, argv) 115461ce74aSDima Dorfman int argc; 11613e21a9dSJoerg Wunsch char *argv[]; 11713e21a9dSJoerg Wunsch { 11813e21a9dSJoerg Wunsch register int i, n1, n2, nr1, nr2; 1195dc67cd7SJoerg Wunsch int secureflg = 0, kflag = 0; 1205dc67cd7SJoerg Wunsch char *cp; 12113e21a9dSJoerg Wunsch 1225dc67cd7SJoerg Wunsch if (argc > 1 && argv[1][0] == '-') { 1235dc67cd7SJoerg Wunsch if (argv[1][1] == 's') { 12413e21a9dSJoerg Wunsch argc--; 12513e21a9dSJoerg Wunsch argv++; 12613e21a9dSJoerg Wunsch secureflg = 1; 1275dc67cd7SJoerg Wunsch } else if (argv[1][1] == 'k') { 1285dc67cd7SJoerg Wunsch argc--; 1295dc67cd7SJoerg Wunsch argv++; 1305dc67cd7SJoerg Wunsch kflag = 1; 13113e21a9dSJoerg Wunsch } 1325dc67cd7SJoerg Wunsch } 1335dc67cd7SJoerg Wunsch if (kflag) { 1345dc67cd7SJoerg Wunsch if ((cp = getenv(MINUSKVAR)) == NULL) { 1355dc67cd7SJoerg Wunsch fprintf(stderr, "%s not set\n", MINUSKVAR); 1365dc67cd7SJoerg Wunsch exit(1); 1375dc67cd7SJoerg Wunsch } 1385dc67cd7SJoerg Wunsch setup(cp); 1395dc67cd7SJoerg Wunsch } else if (argc != 2) { 14013e21a9dSJoerg Wunsch setup(getpass("Enter key:")); 14113e21a9dSJoerg Wunsch } 14213e21a9dSJoerg Wunsch else 14313e21a9dSJoerg Wunsch setup(argv[1]); 14413e21a9dSJoerg Wunsch n1 = 0; 14513e21a9dSJoerg Wunsch n2 = 0; 14613e21a9dSJoerg Wunsch nr2 = 0; 14713e21a9dSJoerg Wunsch 1485dc67cd7SJoerg Wunsch while((i=getchar()) != -1) { 14913e21a9dSJoerg Wunsch if (secureflg) { 15013e21a9dSJoerg Wunsch nr1 = deck[n1]&MASK; 15113e21a9dSJoerg Wunsch nr2 = deck[nr1]&MASK; 15213e21a9dSJoerg Wunsch } else { 15313e21a9dSJoerg Wunsch nr1 = n1; 15413e21a9dSJoerg Wunsch } 15513e21a9dSJoerg Wunsch i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; 15613e21a9dSJoerg Wunsch putchar(i); 15713e21a9dSJoerg Wunsch n1++; 15813e21a9dSJoerg Wunsch if(n1==ROTORSZ) { 15913e21a9dSJoerg Wunsch n1 = 0; 16013e21a9dSJoerg Wunsch n2++; 16113e21a9dSJoerg Wunsch if(n2==ROTORSZ) n2 = 0; 16213e21a9dSJoerg Wunsch if (secureflg) { 16313e21a9dSJoerg Wunsch shuffle(deck); 16413e21a9dSJoerg Wunsch } else { 16513e21a9dSJoerg Wunsch nr2 = n2; 16613e21a9dSJoerg Wunsch } 16713e21a9dSJoerg Wunsch } 16813e21a9dSJoerg Wunsch } 1695dc67cd7SJoerg Wunsch 1705dc67cd7SJoerg Wunsch return 0; 17113e21a9dSJoerg Wunsch } 17213e21a9dSJoerg Wunsch 17313e21a9dSJoerg Wunsch void 174461ce74aSDima Dorfman shuffle(deckary) 175461ce74aSDima Dorfman char deckary[]; 17613e21a9dSJoerg Wunsch { 17713e21a9dSJoerg Wunsch int i, ic, k, temp; 178461ce74aSDima Dorfman unsigned rnd; 17913e21a9dSJoerg Wunsch static long seed = 123; 18013e21a9dSJoerg Wunsch 18113e21a9dSJoerg Wunsch for(i=0;i<ROTORSZ;i++) { 18213e21a9dSJoerg Wunsch seed = 5*seed + buf[i%13]; 183461ce74aSDima Dorfman rnd = seed % 65521; 18413e21a9dSJoerg Wunsch k = ROTORSZ-1 - i; 185461ce74aSDima Dorfman ic = (rnd&MASK)%(k+1); 186461ce74aSDima Dorfman temp = deckary[k]; 187461ce74aSDima Dorfman deckary[k] = deckary[ic]; 188461ce74aSDima Dorfman deckary[ic] = temp; 18913e21a9dSJoerg Wunsch } 19013e21a9dSJoerg Wunsch } 191