Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/enigma/enigma.c
Show All 9 Lines | |||||
* Upgraded to function properly on 64-bit machines. | * Upgraded to function properly on 64-bit machines. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <err.h> | |||||
#include <readpassphrase.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#define MINUSKVAR "CrYpTkEy" | /* Copied from src/lib/libcrypt/crypt.c */ | ||||
#define DES_SALT_ALPHABET \ | |||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |||||
#define CRYPTKEY_ENV "CrYpTkEy" | |||||
#define PASSBUF_SIZE 129 | |||||
#define ROTORSZ 256 | #define ROTORSZ 256 | ||||
#define MASK 0377 | #define MASK 0377 | ||||
static char t1[ROTORSZ]; | |||||
static char t2[ROTORSZ]; | |||||
static char t3[ROTORSZ]; | |||||
static char deck[ROTORSZ]; | |||||
static char buf[13]; | |||||
static void shuffle(char *); | static char t1[ROTORSZ] = { 0 }; | ||||
static char t2[ROTORSZ] = { 0 }; | |||||
static char t3[ROTORSZ] = { 0 }; | |||||
static char deck[ROTORSZ] = { 0 }; | |||||
static char buf[13] = { 0 }; | |||||
pstef: I see no reason to initialize these. | |||||
static void shuffle(void); | |||||
static void setup(char *); | static void setup(char *); | ||||
static void usage(void) __dead2; | |||||
static void | static void | ||||
setup(char *pw) | setup(char *pw) | ||||
{ | { | ||||
int ic, i, k, temp; | int ic, i, k; | ||||
char salt[3]; | static int32_t seed = 123; | ||||
unsigned rnd; | unsigned rnd; | ||||
int32_t seed; | char salt[3], *cryptpw, temp; | ||||
char *cryptpw; | |||||
if (crypt_set_format("des") == 0) { | if (crypt_set_format("des") == 0) | ||||
fprintf(stderr, "crypt_set_format(\"des\") failed.\n"); | errx(1, "crypt_set_format() failure"); | ||||
exit(1); | |||||
} | |||||
strlcpy(salt, pw, sizeof(salt)); | strlcpy(salt, pw, sizeof(salt)); | ||||
cryptpw = crypt(pw, salt); | if ((cryptpw = crypt(pw, salt)) == NULL) | ||||
if (cryptpw == NULL) { | errx(1, "crypt() failure"); | ||||
fprintf(stderr, "crypt(3) failure\n"); | |||||
exit(1); | |||||
} | |||||
memcpy(buf, cryptpw, sizeof(buf)); | memcpy(buf, cryptpw, sizeof(buf)); | ||||
seed = 123; | explicit_bzero(pw, sizeof(pw)); | ||||
explicit_bzero(salt, sizeof(salt)); | |||||
explicit_bzero(cryptpw, sizeof(cryptpw)); | |||||
for (i=0; i<13; i++) | for (i = 0; i < 13; i++) | ||||
seed = seed*buf[i] + i; | seed = seed * buf[i] + i; | ||||
for (i = 0; i < ROTORSZ; i++) | |||||
t1[i] = deck[i] = i; | |||||
for(i=0;i<ROTORSZ;i++) { | for (i = 0; i < ROTORSZ; i++) { | ||||
t1[i] = i; | |||||
deck[i] = i; | |||||
} | |||||
for(i=0;i<ROTORSZ;i++) { | |||||
seed = 5*seed + buf[i%13]; | seed = 5 * seed + buf[i % 13]; | ||||
rnd = seed % 65521; | rnd = seed % 65521; | ||||
k = ROTORSZ-1 - i; | k = ROTORSZ - 1 - i; | ||||
ic = (rnd&MASK)%(k+1); | ic = (rnd & MASK) % (k + 1); | ||||
rnd >>= 8; | rnd >>= 8; | ||||
temp = t1[k]; | temp = t1[k]; | ||||
t1[k] = t1[ic]; | t1[k] = t1[ic]; | ||||
t1[ic] = temp; | t1[ic] = temp; | ||||
if(t3[k]!=0) continue; | |||||
if (t3[k] != 0) | |||||
continue; | |||||
ic = (rnd&MASK) % k; | ic = (rnd & MASK) % k; | ||||
while(t3[ic]!=0) ic = (ic+1) % k; | while (t3[ic] != 0) | ||||
ic = (ic + 1) % k; | |||||
t3[k] = ic; | t3[k] = ic; | ||||
t3[ic] = k; | t3[ic] = k; | ||||
} | } | ||||
for(i=0;i<ROTORSZ;i++) | for (i = 0; i < ROTORSZ; i++) | ||||
t2[t1[i]&MASK] = i; | t2[t1[i] & MASK] = i; | ||||
} | } | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char **argv) | ||||
{ | { | ||||
int i, n1, n2, nr1, nr2; | int i, n1, n2, nr1, nr2, ch; | ||||
int secureflg = 0, kflag = 0; | int kflag = 0, sflag = 0; | ||||
char *cp; | char *cryptkey, passbuf[PASSBUF_SIZE]; | ||||
if (argc > 1 && argv[1][0] == '-') { | while ((ch = getopt(argc, argv, "ks")) != -1) { | ||||
if (argv[1][1] == 's') { | switch (ch) { | ||||
argc--; | case 'k': | ||||
argv++; | |||||
secureflg = 1; | |||||
} else if (argv[1][1] == 'k') { | |||||
argc--; | |||||
argv++; | |||||
kflag = 1; | kflag = 1; | ||||
break; | |||||
case 's': | |||||
sflag = 1; | |||||
break; | |||||
case 'h': | |||||
default: | |||||
usage(); | |||||
} | } | ||||
} | } | ||||
argc -= optind; | |||||
argv += optind; | |||||
if (kflag) { | if (kflag) { | ||||
if ((cp = getenv(MINUSKVAR)) == NULL) { | if ((cryptkey = getenv(CRYPTKEY_ENV)) == NULL) | ||||
fprintf(stderr, "%s not set\n", MINUSKVAR); | errx(1, "%s is unset", CRYPTKEY_ENV); | ||||
exit(1); | } else if (argc != 1) { | ||||
if (readpassphrase("Enter Key: ", passbuf, sizeof(passbuf), | |||||
RPP_REQUIRE_TTY) == NULL) | |||||
errx(1, "unable to read password"); | |||||
cryptkey = passbuf; | |||||
} else { | |||||
cryptkey = argv[0]; | |||||
} | } | ||||
setup(cp); | |||||
} else if (argc != 2) { | |||||
setup(getpass("Enter key:")); | |||||
} | |||||
else | |||||
setup(argv[1]); | |||||
n1 = 0; | |||||
n2 = 0; | |||||
nr2 = 0; | |||||
while((i=getchar()) != -1) { | /* | ||||
if (secureflg) { | * The first two bytes of the key are used as the salt, | ||||
* and since we skip the salt check with crypt_set_format(), | |||||
* we should check it here. | |||||
*/ | |||||
if (strspn(cryptkey, DES_SALT_ALPHABET) != strlen(cryptkey)) | |||||
errx(1, "key contains invalid characters"); | |||||
setup(cryptkey); | |||||
n1 = n2 = nr2 = 0; | |||||
while ((i = getchar()) != EOF) { | |||||
if (sflag) { | |||||
nr1 = deck[n1]&MASK; | nr1 = deck[n1] & MASK; | ||||
nr2 = deck[nr1]&MASK; | nr2 = deck[nr1] & MASK; | ||||
} else { | } else { | ||||
nr1 = n1; | nr1 = n1; | ||||
} | } | ||||
i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; | i = t2[(t3[(t1[(i+nr1)&MASK]+nr2)&MASK]-nr2)&MASK]-nr1; | ||||
putchar(i); | if (putchar(i) == EOF) | ||||
err(1, "putchar"); | |||||
n1++; | n1++; | ||||
if(n1==ROTORSZ) { | if (n1 == ROTORSZ) { | ||||
n1 = 0; | n1 = 0; | ||||
n2++; | n2++; | ||||
if(n2==ROTORSZ) n2 = 0; | |||||
if (secureflg) { | if (n2 == ROTORSZ) | ||||
shuffle(deck); | n2 = 0; | ||||
} else { | |||||
if (sflag) | |||||
shuffle(); | |||||
else | |||||
nr2 = n2; | nr2 = n2; | ||||
} | } | ||||
} | } | ||||
} | |||||
explicit_bzero(buf, sizeof(buf)); | |||||
if (ferror(stdin)) | |||||
err(1, "ferror"); | |||||
if (fclose(stdout) == EOF) | |||||
err(1, "stdout"); | |||||
return 0; | return 0; | ||||
} | } | ||||
static void | static void | ||||
shuffle(char deckary[]) | usage(void) | ||||
{ | { | ||||
int i, ic, k, temp; | |||||
fprintf(stderr, "usage: %s [-ks] password\n", getprogname()); | |||||
exit(1); | |||||
} | |||||
static void | |||||
shuffle(void) | |||||
{ | |||||
int i, ic, k; | |||||
unsigned rnd; | unsigned rnd; | ||||
static int32_t seed = 123; | static int32_t seed = 123; | ||||
char temp; | |||||
for(i=0;i<ROTORSZ;i++) { | for (i = 0; i < ROTORSZ; i++) { | ||||
seed = 5*seed + buf[i%13]; | seed = 5 * seed + buf[i % 13]; | ||||
emasteUnsubmitted Not Done Inline Actionsit's hard to review when functional changes are combined with whitespace changes. I would suggest submiting a change to fix style(9) issues first followed by functional changes emaste: it's hard to review when functional changes are combined with whitespace changes. I would… | |||||
rnd = seed % 65521; | rnd = seed % 65521; | ||||
k = ROTORSZ-1 - i; | k = ROTORSZ - 1 - i; | ||||
ic = (rnd&MASK)%(k+1); | ic = (rnd & MASK) % (k + 1); | ||||
temp = deckary[k]; | |||||
deckary[k] = deckary[ic]; | temp = deck[k]; | ||||
deckary[ic] = temp; | deck[k] = deck[ic]; | ||||
deck[ic] = temp; | |||||
} | } | ||||
} | } |
I see no reason to initialize these.