diff --git a/Makefile b/Makefile index bef9f96..19afd28 100644 --- a/Makefile +++ b/Makefile @@ -19,4 +19,4 @@ clean: packages-clean scrub: clean rm -rf $(CACHE) -include packages/packages.mk +-include */*.mk diff --git a/include/isaac.c b/include/isaac.c deleted file mode 100644 index e095d94..0000000 --- a/include/isaac.c +++ /dev/null @@ -1,156 +0,0 @@ -/* ------------------------------------------------------------------------------- -rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain. -MODIFIED: - 960327: Creation (addition of randinit, really) - 970719: use context, not global variables, for internal state - 980324: added main (ifdef'ed out), also rearranged randinit() - 010626: Note that this is public domain ------------------------------------------------------------------------------- -*/ -#include -#include "rand.h" - -#define ind(mm,x) (*(uint32_t *)((uint8_t *)(mm) + ((x) & ((RANDSIZ-1)<<2)))) -#define rngstep(mix,a,b,mm,m,m2,r,x) \ -{ \ - x = *m; \ - a = (a^(mix)) + *(m2++); \ - *(m++) = y = ind(mm,x) + a + b; \ - *(r++) = b = ind(mm,y>>RANDSIZL) + x; \ -} - -void isaac(struct randctx *ctx) -{ - register uint32_t a, b, x, y, *m, *mm, *m2, *r, *mend; - mm = ctx->randmem; - r = ctx->randrsl; - a = ctx->randa; - b = ctx->randb + (++ctx->randc); - for (m = mm, mend = m2 = m + (RANDSIZ / 2); m < mend;) { - rngstep(a << 13, a, b, mm, m, m2, r, x); - rngstep(a >> 6, a, b, mm, m, m2, r, x); - rngstep(a << 2, a, b, mm, m, m2, r, x); - rngstep(a >> 16, a, b, mm, m, m2, r, x); - } - for (m2 = mm; m2 < mend;) { - rngstep(a << 13, a, b, mm, m, m2, r, x); - rngstep(a >> 6, a, b, mm, m, m2, r, x); - rngstep(a << 2, a, b, mm, m, m2, r, x); - rngstep(a >> 16, a, b, mm, m, m2, r, x); - } - ctx->randb = b; - ctx->randa = a; -} - - -#define mix(a,b,c,d,e,f,g,h) \ -{ \ - a^=b<<11; d+=a; b+=c; \ - b^=c>>2; e+=b; c+=d; \ - c^=d<<8; f+=c; d+=e; \ - d^=e>>16; g+=d; e+=f; \ - e^=f<<10; h+=e; f+=g; \ - f^=g>>4; a+=f; g+=h; \ - g^=h<<8; b+=g; h+=a; \ - h^=a>>9; c+=h; a+=b; \ -} - -/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */ -void randinit(struct randctx *ctx, uint_fast8_t flag) -{ - uint_fast32_t i; - uint32_t a, b, c, d, e, f, g, h; - uint32_t *m, *r; - ctx->randa = ctx->randb = ctx->randc = 0; - m = ctx->randmem; - r = ctx->randrsl; - a = b = c = d = e = f = g = h = 0x9e3779b9; /* the golden ratio */ - - for (i = 0; i < 4; ++i) { /* scramble it */ - mix(a, b, c, d, e, f, g, h); - } - - if (flag) { - /* initialize using the contents of r[] as the seed */ - for (i = 0; i < RANDSIZ; i += 8) { - a += r[i]; - b += r[i + 1]; - c += r[i + 2]; - d += r[i + 3]; - e += r[i + 4]; - f += r[i + 5]; - g += r[i + 6]; - h += r[i + 7]; - mix(a, b, c, d, e, f, g, h); - m[i] = a; - m[i + 1] = b; - m[i + 2] = c; - m[i + 3] = d; - m[i + 4] = e; - m[i + 5] = f; - m[i + 6] = g; - m[i + 7] = h; - } - /* do a second pass to make all of the seed affect all of m */ - for (i = 0; i < RANDSIZ; i += 8) { - a += m[i]; - b += m[i + 1]; - c += m[i + 2]; - d += m[i + 3]; - e += m[i + 4]; - f += m[i + 5]; - g += m[i + 6]; - h += m[i + 7]; - mix(a, b, c, d, e, f, g, h); - m[i] = a; - m[i + 1] = b; - m[i + 2] = c; - m[i + 3] = d; - m[i + 4] = e; - m[i + 5] = f; - m[i + 6] = g; - m[i + 7] = h; - } - } else { - /* fill in m[] with messy stuff */ - for (i = 0; i < RANDSIZ; i += 8) { - mix(a, b, c, d, e, f, g, h); - m[i] = a; - m[i + 1] = b; - m[i + 2] = c; - m[i + 3] = d; - m[i + 4] = e; - m[i + 5] = f; - m[i + 6] = g; - m[i + 7] = h; - } - } - - isaac(ctx); /* fill in the first set of results */ - ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */ -} - - -#ifdef NEVER - -#include - -int main() -{ - uint32_t i, j; - struct randctx ctx; - ctx.randa = ctx.randb = ctx.randc = (uint32_t) 0; - for (i = 0; i < 256; ++i) - ctx.randrsl[i] = (uint32_t) 0; - randinit(&ctx, 1); - for (i = 0; i < 2; ++i) { - isaac(&ctx); - for (j = 0; j < 256; ++j) { - printf("%.8x", ctx.randrsl[j]); - if ((j & 7) == 7) - printf("\n"); - } - } -} -#endif diff --git a/include/isaac.h b/include/isaac.h deleted file mode 100644 index 14e9adb..0000000 --- a/include/isaac.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ------------------------------------------------------------------------------- -rand.h: definitions for a random number generator -By Bob Jenkins, 1996, Public Domain -MODIFIED: - 960327: Creation (addition of randinit, really) - 970719: use context, not global variables, for internal state - 980324: renamed seed to flag - 980605: recommend RANDSIZL=4 for noncryptography. - 010626: note this is public domain - 101005: update to C99 (neale@lanl.gov) ------------------------------------------------------------------------------- -*/ - -#ifndef __ISAAC_H__ -#define __ISAAC_H__ - -#include - -#define RANDSIZL (8) -#define RANDSIZ (1<randcnt-- ? \ - (isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \ - (r)->randrsl[(r)->randcnt]) - -#endif /* RAND */ - - -#endif /* __ISAAC_H__ */ diff --git a/include/token.c b/include/token.c deleted file mode 100644 index 4edd897..0000000 --- a/include/token.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CTF_BASE -#define CTF_BASE "/var/lib/ctf" -#endif - -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; -} - -void -arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, uint8_t const *ibuf, size_t buflen) -{ - int i = ctx->i; - int j = ctx->j; - size_t k; - - for (k = 0; k < buflen; k += 1) { - uint8_t mask; - - i = (i + 1) % 256; - j = (j + ctx->S[i]) % 256; - swap(ctx->S[i], ctx->S[j]); - mask = ctx->S[(ctx->S[i] + ctx->S[j]) % 256]; - obuf[k] = ibuf[k] ^ mask; - } - ctx->i = i; - ctx->j = j; -} - -void -arc4_crypt_buffer(uint8_t const *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/arc4.c b/libctf/arc4.c similarity index 82% rename from include/arc4.c rename to libctf/arc4.c index 63306ad..33b97ed 100644 --- a/include/arc4.c +++ b/libctf/arc4.c @@ -23,7 +23,7 @@ arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen) } uint8_t -arc4_pad(struct arc4_ctx *ctx) +arc4_out(struct arc4_ctx *ctx) { ctx->i = (ctx->i + 1) % 256; ctx->j = (ctx->j + ctx->S[ctx->i]) % 256; @@ -33,17 +33,17 @@ arc4_pad(struct arc4_ctx *ctx) void arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, uint8_t const *ibuf, size_t buflen) + 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_pad(ctx); + obuf[k] = ibuf[k] ^ arc4_out(ctx); } } void -arc4_crypt_buffer(uint8_t const *key, size_t keylen, +arc4_crypt_buffer(const uint8_t *key, size_t keylen, uint8_t *buf, size_t buflen) { struct arc4_ctx ctx; diff --git a/include/arc4.h b/libctf/arc4.h similarity index 50% rename from include/arc4.h rename to libctf/arc4.h index 7aa7428..f1ef379 100644 --- a/include/arc4.h +++ b/libctf/arc4.h @@ -4,17 +4,18 @@ #include #include +#define ARC4_HASHLEN 16 + struct arc4_ctx { uint8_t S[256]; uint8_t i; uint8_t j; }; -void arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen); -uint8_t arc4_pad(struct arc4_ctx *ctx); +void arc4_init(struct arc4_ctx *ctx, const uint8_t *key, size_t keylen); +uint8_t arc4_out(struct arc4_ctx *ctx); void arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, uint8_t const *ibuf, size_t buflen); -void arc4_crypt_buffer(uint8_t const *key, size_t keylen, + 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); - #endif diff --git a/libctf/libctf.mk b/libctf/libctf.mk new file mode 100644 index 0000000..10c50e8 --- /dev/null +++ b/libctf/libctf.mk @@ -0,0 +1,9 @@ +libctf: libctf/libctf.a +libctf/libctf.a: libctf/libctf.a(libctf/md5.o) +libctf/libctf.a: libctf/libctf.a(libctf/arc4.o) +libctf/libctf.a: libctf/libctf.a(libctf/rand.o) +libctf/libctf.a: libctf/libctf.a(libctf/token.o) + +clean: libctf-clean +libctf-clean: + rm -f libctf/*.o libctf/libctf.a diff --git a/libctf/md5.c b/libctf/md5.c new file mode 100644 index 0000000..036c900 --- /dev/null +++ b/libctf/md5.c @@ -0,0 +1,280 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* Brutally hacked by John Walker back from ANSI C to K&R (no + prototypes) to maintain the tradition that Netfone will compile + with Sun's original "cc". */ + +#include /* 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/libctf/md5.h b/libctf/md5.h new file mode 100644 index 0000000..63c7936 --- /dev/null +++ b/libctf/md5.h @@ -0,0 +1,42 @@ +#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/libctf/rand.c b/libctf/rand.c new file mode 100644 index 0000000..3f03634 --- /dev/null +++ b/libctf/rand.c @@ -0,0 +1,65 @@ +#include +#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/libctf/rand.h b/libctf/rand.h new file mode 100644 index 0000000..02fc019 --- /dev/null +++ b/libctf/rand.h @@ -0,0 +1,11 @@ +#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/libctf/test.c b/libctf/test.c new file mode 100644 index 0000000..0301a26 --- /dev/null +++ b/libctf/test.c @@ -0,0 +1,46 @@ +#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/libctf/token.c b/libctf/token.c new file mode 100644 index 0000000..3f388ed --- /dev/null +++ b/libctf/token.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CTF_BASE +#define CTF_BASE "/var/lib/ctf" +#endif + +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/libctf/token.h similarity index 58% rename from include/token.h rename to libctf/token.h index ac4f95b..4034254 100644 --- a/include/token.h +++ b/libctf/token.h @@ -8,13 +8,6 @@ #define TOKEN_MAX 80 /* ARC4 functions, in case anybody wants 'em */ -struct arc4_ctx; -void arc4_init(struct arc4_ctx *ctx, - uint8_t const *key, size_t keylen); -void arc4_crypt(struct arc4_ctx *ctx, - uint8_t *obuf, uint8_t const *ibuf, size_t buflen); -void arc4_crypt_buffer(uint8_t const *key, size_t keylen, - uint8_t *buf, size_t buflen); ssize_t read_token_fd(int fd, uint8_t const *key, size_t keylen,