From e20bea39b272eb0b592bb7b85c880ed7784a565e Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 18 Mar 2011 19:21:45 -0600 Subject: [PATCH] Gussy up arc4.c --- src/Makefile | 4 +- src/arc4.c | 207 ++++++++++++++++++++++++++++++++++----------------- src/arc4.h | 17 +++++ src/rand.c | 65 ---------------- src/rand.h | 11 --- src/tea.c | 106 -------------------------- src/xxtea.c | 52 ------------- src/xxtea.h | 9 --- 8 files changed, 157 insertions(+), 314 deletions(-) delete mode 100644 src/rand.c delete mode 100644 src/rand.h delete mode 100644 src/tea.c delete mode 100644 src/xxtea.c delete mode 100644 src/xxtea.h diff --git a/src/Makefile b/src/Makefile index 3d2d790..da8b6ec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,10 +1,8 @@ -TARGETS = bubblebabble arc4 tea +TARGETS = bubblebabble arc4 all: $(TARGETS) arc4: CFLAGS=-DARC4_MAIN -tea: tea.o xxtea.o - clean: rm -f *.o $(TARGETS) \ No newline at end of file diff --git a/src/arc4.c b/src/arc4.c index f1ac244..611e129 100644 --- a/src/arc4.c +++ b/src/arc4.c @@ -1,15 +1,9 @@ #include #include +#include +#include #include "arc4.h" -#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args) -#define DUMP() DUMPf("") -#define DUMP_d(v) DUMPf("%s = %d", #v, v) -#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v) -#define DUMP_s(v) DUMPf("%s = %s", #v, v) -#define DUMP_c(v) DUMPf("%s = '%c' (0x%02x)", #v, v, v) -#define DUMP_p(v) DUMPf("%s = %p", #v, v) - #define swap(a, b) do {uint8_t _swap=a; a=b, b=_swap;} while (0) void @@ -50,16 +44,6 @@ arc4_crypt(struct arc4_ctx *ctx, } } -void -arc4_crypt_buffer(const uint8_t *key, size_t keylen, - uint8_t *buf, size_t buflen) -{ - struct arc4_ctx ctx; - - arc4_init(&ctx, key, keylen); - arc4_crypt(&ctx, buf, buf, buflen); -} - /* Create a nonce as an arc4 stream with key=seed */ void arc4_nonce(uint8_t *nonce, size_t noncelen, @@ -75,24 +59,135 @@ arc4_nonce(uint8_t *nonce, size_t noncelen, } -#ifdef ARC4_MAIN +/*************************************************** + * + * Psuedo Random Number Generation + * + */ +static struct arc4_ctx prng_ctx; +static int prng_initialized = 0; -#include -#include -#include -#include -#include -#include +void +arc4_rand_seed(const uint8_t *seed, size_t seedlen) +{ + arc4_init(&prng_ctx, seed, seedlen); + prng_initialized = 1; +} + +static void +arc4_rand_autoseed() +{ + if (! prng_initialized) { + uint8_t key[ARC4_KEYLEN]; + FILE *urandom; + + /* Open /dev/urandom or die trying */ + urandom = fopen("/dev/urandom", "r"); + if (! urandom) { + perror("Opening /dev/urandom"); + abort(); + } + setbuf(urandom, NULL); + fread(&key, sizeof(key), 1, urandom); + fclose(urandom); + + arc4_rand_seed(key, sizeof(key)); + } +} + +uint8_t +arc4_rand8() +{ + arc4_rand_autoseed(); + return arc4_out(&prng_ctx); +} + +uint32_t +arc4_rand32() +{ + arc4_rand_autoseed(); + return ((arc4_out(&prng_ctx) << 0) | + (arc4_out(&prng_ctx) << 8) | + (arc4_out(&prng_ctx) << 16) | + (arc4_out(&prng_ctx) << 24)); +} + +/***************************************** + * + * Stream operations + * + */ + +ssize_t +arc4_encrypt_stream(FILE *out, FILE *in, + const uint8_t *key, size_t keylen) +{ + struct arc4_ctx ctx; + uint32_t seed = arc4_rand32(); + uint8_t nonce[ARC4_KEYLEN]; + ssize_t written = 0; + int i; + + fwrite("arc4", 4, 1, out); + fwrite(&seed, sizeof(seed), 1, out); + + arc4_nonce(nonce, sizeof(nonce), &seed, sizeof(seed)); + for (i = 0; i < keylen; i += 1) { + nonce[i] ^= key[i]; + } + arc4_init(&ctx, nonce, sizeof(nonce)); + + while (1) { + int c = fgetc(in); + + if (EOF == c) break; + fputc((uint8_t)c ^ arc4_out(&ctx), out); + written += 1; + } + + return written; +} int -usage(const char *prog) +arc4_decrypt_stream(FILE *out, FILE *in, + const uint8_t *key, size_t keylen) { - fprintf(stderr, "Usage: %s [-e] +#include + int main(int argc, char *argv[]) { @@ -100,7 +195,6 @@ main(int argc, char *argv[]) uint8_t key[ARC4_KEYLEN] = {0}; size_t keylen; uint8_t nonce[ARC4_KEYLEN]; - time_t seed; int i; /* Read key and initialize context */ @@ -111,48 +205,25 @@ main(int argc, char *argv[]) keylen = strlen(ekey); memcpy(key, ekey, keylen); } else { - FILE *f = fdopen(3, "r"); - - if (NULL == f) { - return usage(argv[0]); - } - - keylen = fread(key, 1, ARC4_KEYLEN, f); - fclose(f); + keylen = read(3, key, sizeof(key)); } } - if (argv[1] && (0 == strcmp(argv[1], "-e"))) { - seed = time(NULL) * getpid(); - fwrite("arc4", 1, 4, stdout); - fwrite(&seed, sizeof(seed), 1, stdout); - } else if (argv[1]) { - return usage(argv[0]); - } else { - char sig[4]; - - fread(&sig, sizeof(sig), 1, stdin); - if (memcmp(sig, "arc4", 4)) { - fprintf(stderr, "%s: error: Input is not arc4-encrypted.", argv[0]); + if (! argv[1]) { + if (-1 == arc4_decrypt_stream(stdout, stdin, key, keylen)) { + perror("decrypting"); return 1; } - fread(&seed, sizeof(seed), 1, stdin); - } - - arc4_nonce(nonce, sizeof(nonce), &seed, sizeof(seed)); - - /* Xor key with nonce */ - for (i = 0; i < sizeof(key); i += 1) { - key[i] ^= nonce[i]; - } - - arc4_init(&ctx, key, sizeof(key)); - - while (1) { - int c = getchar(); - - if (EOF == c) break; - putchar(c ^ arc4_out(&ctx)); + } else if (0 == strcmp(argv[1], "-e")) { + if (-1 == arc4_encrypt_stream(stdout, stdin, key, keylen)) { + perror("encrypting"); + return 1; + } + } else { + fprintf(stderr, "Usage: %s [-e] -#include -#include -#include -#include -#include -#include "arc4.h" - -/* - * - * Random numbers - * - */ - -void -urandom(uint8_t *buf, size_t buflen) -{ - static int initialized = 0; - static struct arc4_ctx ctx; - - if (! initialized) { - int fd = open("/dev/urandom", O_RDONLY); - - if (-1 == fd) { - struct { - time_t time; - pid_t pid; - } bits; - - bits.time = time(NULL); - bits.pid = getpid(); - arc4_init(&ctx, (uint8_t *)&bits, sizeof(bits)); - } else { - uint8_t key[256]; - - read(fd, key, sizeof(key)); - close(fd); - arc4_init(&ctx, key, sizeof(key)); - } - - initialized = 1; - } - - while (buflen--) { - *(buf++) = arc4_out(&ctx); - } -} - -int32_t -rand32() -{ - int32_t ret; - - urandom((uint8_t *)&ret, sizeof(ret)); - return ret; -} - -uint32_t -randu32() -{ - uint32_t ret; - - urandom((uint8_t *)&ret, sizeof(ret)); - return ret; -} diff --git a/src/rand.h b/src/rand.h deleted file mode 100644 index 02fc019..0000000 --- a/src/rand.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __RAND_H__ -#define __RAND_H__ - -#include -#include - -void urandom(void *buf, size_t buflen); -int32_t rand32(); -uint32_t randu32(); - -#endif /* __RAND_H__ */ diff --git a/src/tea.c b/src/tea.c deleted file mode 100644 index 669cdf6..0000000 --- a/src/tea.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "xxtea.h" - -#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args) -#define DUMP() DUMPf("") -#define DUMP_d(v) DUMPf("%s = %d", #v, v) -#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v) -#define DUMP_s(v) DUMPf("%s = %s", #v, v) -#define DUMP_c(v) DUMPf("%s = '%c' (0x%02x)", #v, v, v) -#define DUMP_p(v) DUMPf("%s = %p", #v, v) - -#define min(a,b) (((a)<(b))?(a):(b)) - -int -main(int argc, char *argv[]) -{ - uint8_t *buf = NULL; - size_t len = 0; - uint32_t key[4] = {0}; - int encode = 0; - - /* Parse args */ - { - int opt; - - while ((opt = getopt(argc, argv, "e")) != -1) { - switch (opt) { - case 'e': - encode = 1; - break; - default: - fprintf(stderr, "Usage: %s [-e] 0) { - buf[len++] = 0; - } - - tea_encode(key, (uint32_t *)buf, len/4); - } else { - if (len % 4) { - fprintf(stderr, "Incorrect padding.\n"); - return 1; - } - tea_decode(key, (uint32_t *)buf, len/4); - - /* Remove padding. If your input had trailing NULs, you shouldn't - use this. */ - while (0 == buf[len-1]) { - len -= 1; - } - } - write(1, buf, len); - - return 0; -} diff --git a/src/xxtea.c b/src/xxtea.c deleted file mode 100644 index c70624a..0000000 --- a/src/xxtea.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include "xxtea.h" - -#define DELTA 0x9e3779b9 -#define MX ((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z)); - -void -btea(uint32_t *v, int n, uint32_t const k[4]) -{ - uint32_t y, z, sum; - unsigned p, rounds, e; - - if (n > 1) { /* Coding Part */ - rounds = 6 + 52/n; - sum = 0; - z = v[n-1]; - do { - sum += DELTA; - e = (sum >> 2) & 3; - for (p=0; p> 2) & 3; - for (p=n-1; p>0; p--) - z = v[p-1], y = v[p] -= MX; - z = v[n-1]; - y = v[0] -= MX; - } while ((sum -= DELTA) != 0); - } -} - -void -tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen) -{ - btea(buf, buflen, key); -} - -void -tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen) -{ - btea(buf, -buflen, key); -} - diff --git a/src/xxtea.h b/src/xxtea.h deleted file mode 100644 index a9c207c..0000000 --- a/src/xxtea.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __XXTEA_H__ -#define __XXTEA_H__ - -#include - -void tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen); -void tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen); - -#endif