diff --git a/include/arc4.c b/include/arc4.c deleted file mode 100644 index 8f13423..0000000 --- a/include/arc4.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include "arc4.h" - -#define swap(a, b) do {int _swap=a; a=b, b=_swap;} while (0) - -void -arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen) -{ - int i; - int j = 0; - - for (i = 0; i < 256; i += 1) { - ctx->S[i] = i; - } - - for (i = 0; i < 256; i += 1) { - j = (j + ctx->S[i] + key[i % keylen]) % 256; - swap(ctx->S[i], ctx->S[j]); - } - ctx->i = 0; - ctx->j = 0; -} - -uint8_t -arc4_out(struct arc4_ctx *ctx) -{ - ctx->i = (ctx->i + 1) % 256; - ctx->j = (ctx->j + ctx->S[ctx->i]) % 256; - swap(ctx->S[ctx->i], ctx->S[ctx->j]); - return ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; -} - -void -arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, const uint8_t *ibuf, size_t buflen) -{ - size_t k; - - for (k = 0; k < buflen; k += 1) { - obuf[k] = ibuf[k] ^ arc4_out(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); -} - - -#ifdef ARC4_MAIN - -#include -#include -#include - -int -main(int argc, char *argv[]) -{ - struct arc4_ctx ctx; - - /* Read key and initialize context */ - { - uint8_t key[256]; - size_t keylen = 0; - char *ekey = getenv("KEY"); - FILE *f; - - if (argc == 2) { - if (! (f = fopen(argv[1], "r"))) { - perror(argv[0]); - } - } else { - f = fdopen(3, "r"); - } - - if (f) { - keylen = fread(key, 1, sizeof(key), f); - fclose(f); - } else if (ekey) { - keylen = strlen(ekey); - if (keylen > sizeof(key)) { - keylen = sizeof(key); - } - memcpy(key, ekey, keylen); - } - - if (0 == keylen) { - fprintf(stderr, "Usage: %s [KEYFILE] /* for memcpy() */ -#include -#include -#include "md5.h" - -void md5_transform(uint32_t buf[4], uint32_t in[16]); - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(uint8_t *buf, size_t words) -{ - uint32_t t; - do { - t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32_t *) buf = t; - buf += 4; - } while (--words); -} -#endif - - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void md5_init(struct md5_context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void md5_update(struct md5_context *ctx, - const uint8_t *buf, - size_t len) -{ - uint32_t t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - md5_transform(ctx->buf, (uint32_t *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - md5_transform(ctx->buf, (uint32_t *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void md5_final(struct md5_context *ctx, uint8_t *digest) -{ - unsigned int count; - uint8_t *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - md5_transform(ctx->buf, (uint32_t *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32_t *) ctx->in)[14] = ctx->bits[0]; - ((uint32_t *) ctx->in)[15] = ctx->bits[1]; - - md5_transform(ctx->buf, (uint32_t *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define md5_step(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void md5_transform(uint32_t buf[4], uint32_t in[16]) -{ - register uint32_t a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - md5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - md5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - md5_step(F1, c, d, a, b, in[2] + 0x242070db, 17); - md5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - md5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - md5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - md5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17); - md5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22); - md5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7); - md5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - md5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - md5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - md5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7); - md5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12); - md5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17); - md5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - md5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - md5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9); - md5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - md5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - md5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - md5_step(F2, d, a, b, c, in[10] + 0x02441453, 9); - md5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - md5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - md5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - md5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - md5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - md5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - md5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - md5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - md5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - md5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - md5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - md5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11); - md5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - md5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - md5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - md5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - md5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - md5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - md5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - md5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - md5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - md5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23); - md5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - md5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - md5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - md5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - md5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6); - md5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10); - md5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - md5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - md5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - md5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - md5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - md5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - md5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - md5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - md5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15); - md5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - md5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - md5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - md5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - md5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -void -md5_digest(const uint8_t *buf, size_t buflen, uint8_t *digest) -{ - struct md5_context ctx; - - md5_init(&ctx); - md5_update(&ctx, buf, buflen); - md5_final(&ctx, digest); -} - -void -md5_hexdigest(const uint8_t *buf, size_t buflen, char *hexdigest) -{ - uint8_t digest[MD5_DIGEST_LEN]; - int i; - - md5_digest(buf, buflen, digest); - - for (i = 0; i < MD5_DIGEST_LEN; i += 1) { - sprintf(hexdigest + (i*2), "%02x", digest[i]); - } -} diff --git a/include/md5.h b/include/md5.h deleted file mode 100644 index 63c7936..0000000 --- a/include/md5.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef MD5_H -#define MD5_H - -#include - -/* The following tests optimise behaviour on little-endian - machines, where there is no need to reverse the byte order - of 32 bit words in the MD5 computation. By default, - HIGHFIRST is defined, which indicates we're running on a - big-endian (most significant byte first) machine, on which - the byteReverse function in md5.c must be invoked. However, - byteReverse is coded in such a way that it is an identity - function when run on a little-endian machine, so calling it - on such a platform causes no harm apart from wasting time. - If the platform is known to be little-endian, we speed - things up by undefining HIGHFIRST, which defines - byteReverse as a null macro. Doing things in this manner - insures we work on new platforms regardless of their byte - order. */ - -#define HIGHFIRST - -#ifdef __i386__ -#undef HIGHFIRST -#endif - -#define MD5_DIGEST_LEN 16 -#define MD5_HEXDIGEST_LEN (MD5_DIGEST_LEN * 2) - -struct md5_context { - uint32_t buf[4]; - uint32_t bits[2]; - uint8_t in[64]; -}; - -void md5_init(struct md5_context *ctx); -void md5_update(struct md5_context *ctx, const uint8_t *buf, size_t len); -void md5_final(struct md5_context *ctx, uint8_t *digest); -void md5_digest(const uint8_t *buf, size_t buflen, uint8_t *digest); -void md5_hexdigest(const uint8_t *buf, size_t buflen, char *hexdigest); - -#endif /* !MD5_H */ diff --git a/include/test.c b/include/test.c deleted file mode 100644 index 0301a26..0000000 --- a/include/test.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include "rand.h" -#include "md5.h" -#include "token.h" - -int -main() -{ - int i; - uint8_t zeroes[64] = {0}; - uint8_t digest[MD5_DIGEST_LEN]; - - for (i = 0; i < 10; i += 1) { - printf("%d ", randu32() % 10); - } - - printf("\n4ae71336e44bf9bf79d2752e234818a5\n"); - - md5_digest(zeroes, 16, digest); - for (i = 0; i < sizeof(digest); i += 1) { - printf("%02x", digest[i]); - } - printf("\n"); - - { - char hd[MD5_HEXDIGEST_LEN + 1] = {0}; - - md5_hexdigest(zeroes, 16, hd); - printf("%s\n", hd); - } - - { - ssize_t len; - char token[TOKEN_MAX]; - - len = read_token("foo", 0, 4, token, sizeof(token)); - if (-1 != len) { - printf("rut roh\n"); - } else { - printf("Good.\n"); - } - } - - return 0; -} diff --git a/include/token.c b/include/token.c deleted file mode 100644 index 9fbe6d3..0000000 --- a/include/token.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CTF_BASE -#define CTF_BASE "/var/lib/ctf" -#endif - -/* - * - * ARC-4 stuff - * - */ - -struct arc4_ctx { - uint8_t S[256]; - uint8_t i; - uint8_t j; -}; - -#define swap(a, b) do {int _swap=a; a=b, b=_swap;} while (0) - -void -arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen) -{ - int i; - int j = 0; - - for (i = 0; i < 256; i += 1) { - ctx->S[i] = i; - } - - for (i = 0; i < 256; i += 1) { - j = (j + ctx->S[i] + key[i % keylen]) % 256; - swap(ctx->S[i], ctx->S[j]); - } - ctx->i = 0; - ctx->j = 0; -} - -uint8_t -arc4_out(struct arc4_ctx *ctx) -{ - ctx->i = (ctx->i + 1) % 256; - ctx->j = (ctx->j + ctx->S[ctx->i]) % 256; - swap(ctx->S[ctx->i], ctx->S[ctx->j]); - return ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; -} - -void -arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, const uint8_t *ibuf, size_t buflen) -{ - size_t k; - - for (k = 0; k < buflen; k += 1) { - obuf[k] = ibuf[k] ^ arc4_out(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); -} - -/* - * - */ - - - -ssize_t -read_token_fd(int fd, - uint8_t const *key, size_t keylen, - char *buf, size_t buflen) -{ - ssize_t ret; - - ret = read(fd, buf, buflen); - if (-1 != ret) { - arc4_crypt_buffer(key, keylen, (uint8_t *)buf, (size_t)ret); - } - return ret; -} - - -ssize_t -read_token(char const *name, - uint8_t const *key, size_t keylen, - char *buf, size_t buflen) -{ - char path[PATH_MAX]; - int pathlen; - int fd; - ssize_t ret; - - pathlen = snprintf(path, sizeof(path) - 1, - CTF_BASE "/tokens/%s", name); - path[pathlen] = '\0'; - - fd = open(path, O_RDONLY); - if (-1 == fd) return -1; - ret = read_token_fd(fd, key, keylen, buf, buflen); - close(fd); - return ret; -} diff --git a/include/token.h b/include/token.h deleted file mode 100644 index 4034254..0000000 --- a/include/token.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __TOKEN_H__ -#define __TOKEN_H__ - -#include -#include -#include - -#define TOKEN_MAX 80 - -/* ARC4 functions, in case anybody wants 'em */ - -ssize_t read_token_fd(int fd, - uint8_t const *key, size_t keylen, - char *buf, size_t buflen); - -ssize_t read_token(char const *name, - uint8_t const *key, size_t keylen, - char *buf, size_t buflen); - -#endif diff --git a/src/Makefile b/src/Makefile index 6128f8d..da8b6ec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,2 +1,8 @@ -all: bubblebabble +TARGETS = bubblebabble arc4 +all: $(TARGETS) + +arc4: CFLAGS=-DARC4_MAIN + +clean: + rm -f *.o $(TARGETS) \ No newline at end of file diff --git a/src/arc4.c b/src/arc4.c new file mode 100644 index 0000000..f1ac244 --- /dev/null +++ b/src/arc4.c @@ -0,0 +1,161 @@ +#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 +arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen) +{ + int i; + int j = 0; + + for (i = 0; i < 256; i += 1) { + ctx->S[i] = i; + } + + for (i = 0; i < 256; i += 1) { + j = (j + ctx->S[i] + key[i % keylen]) % 256; + swap(ctx->S[i], ctx->S[j]); + } + ctx->i = 0; + ctx->j = 0; +} + +uint8_t +arc4_out(struct arc4_ctx *ctx) +{ + ctx->i = (ctx->i + 1) % 256; + ctx->j = (ctx->j + ctx->S[ctx->i]) % 256; + swap(ctx->S[ctx->i], ctx->S[ctx->j]); + return ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; +} + +void +arc4_crypt(struct arc4_ctx *ctx, + uint8_t *obuf, const uint8_t *ibuf, size_t buflen) +{ + size_t k; + + for (k = 0; k < buflen; k += 1) { + obuf[k] = ibuf[k] ^ arc4_out(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, + void *seed, size_t seedlen) +{ + struct arc4_ctx ctx; + int i; + + arc4_init(&ctx, seed, seedlen); + for (i = 0; i < noncelen; i += 1) { + nonce[i] = arc4_out(&ctx); + } +} + + +#ifdef ARC4_MAIN + +#include +#include +#include +#include +#include +#include + +int +usage(const char *prog) +{ + fprintf(stderr, "Usage: %s [-e] #include +#define ARC4_KEYLEN 256 + struct arc4_ctx { uint8_t S[256]; uint8_t i; @@ -16,4 +18,5 @@ void arc4_crypt(struct arc4_ctx *ctx, uint8_t *obuf, const uint8_t *ibuf, size_t buflen); void arc4_crypt_buffer(const uint8_t *key, size_t keylen, uint8_t *buf, size_t buflen); +void arc4_nonce(uint8_t *nonce, size_t noncelen, void *seed, size_t seedlen); #endif diff --git a/include/rand.c b/src/rand.c similarity index 100% rename from include/rand.c rename to src/rand.c diff --git a/include/rand.h b/src/rand.h similarity index 100% rename from include/rand.h rename to src/rand.h