Move from xxtea to arc4

arc4 has known attacks, but you need a lot of data first.  More data
that we'll have tokens.
This commit is contained in:
Neale Pickett 2010-09-16 23:18:16 -06:00
parent cf282dff48
commit 4d981756ce
9 changed files with 98 additions and 82 deletions

View File

@ -5,7 +5,7 @@ all: build
build: $(TARGETS) build: $(TARGETS)
in.tokend: in.tokend.o xxtea.o common.o in.tokend: in.tokend.o arc4.o common.o
pointscli: pointscli.o common.o pointscli: pointscli.o common.o
puzzles.cgi: puzzles.cgi.o common.o puzzles.cgi: puzzles.cgi.o common.o

54
src/arc4.c Normal file
View File

@ -0,0 +1,54 @@
#include <stdint.h>
#include <stdlib.h>
#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;
}
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);
}

19
src/arc4.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __ARC4_H__
#define __ARC4_H__
#include <stdint.h>
#include <stdlib.h>
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);
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);
#endif

View File

@ -64,7 +64,7 @@ main(int argc, char *argv[])
category[i] = '\0'; category[i] = '\0';
{ {
char line[TEAM_MAX + TOKEN_MAX + 1]; char line[200];
my_snprintf(line, sizeof(line), my_snprintf(line, sizeof(line),
"%s %s", team, token); "%s %s", team, token);

View File

@ -10,7 +10,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "common.h" #include "common.h"
#include "xxtea.h" #include "arc4.h"
#define itokenlen 3 #define itokenlen 3
@ -69,11 +69,12 @@ bubblebabble(char *out, char const *in, const size_t inlen)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char service[50]; char service[50];
size_t servicelen; size_t servicelen;
char token[80]; char token[80];
size_t tokenlen; size_t tokenlen;
uint32_t key[4]; uint8_t key[256];
size_t keylen;
/* Seed the random number generator. This ought to be unpredictable /* Seed the random number generator. This ought to be unpredictable
enough for a contest. */ enough for a contest. */
@ -83,7 +84,7 @@ main(int argc, char *argv[])
{ {
ssize_t len; ssize_t len;
len = read(0, service, sizeof(service) - 1); len = read(0, service, sizeof(service));
for (servicelen = 0; for (servicelen = 0;
(servicelen < len) && isalnum(service[servicelen]); (servicelen < len) && isalnum(service[servicelen]);
servicelen += 1); servicelen += 1);
@ -91,22 +92,23 @@ main(int argc, char *argv[])
/* Read in that service's key. */ /* Read in that service's key. */
{ {
int fd; int fd;
size_t len; int ret;
fd = open(srv_path("token.keys/%s", service), O_RDONLY); fd = open(srv_path("token.keys/%*s", servicelen, service), O_RDONLY);
if (-1 == fd) { if (-1 == fd) {
write(1, "!nosvc", 6); write(1, "!nosvc", 6);
return 0; return 0;
} }
len = read(fd, &key, 16); ret = read(fd, &key, sizeof(key));
close(fd); if (-1 == ret) {
write(1, "!read", 5);
if (16 != len) {
write(1, "!shortkey", 9);
return 0; return 0;
} }
keylen = (size_t)ret;
close(fd);
} }
/* Create the token. */ /* Create the token. */
@ -158,19 +160,14 @@ main(int argc, char *argv[])
} }
} }
/* Encrypt the token. Note that now tokenlen is in uint32_ts, not /* Encrypt the token. */
chars! Also remember that token must be big enough to hold a
multiple of 4 chars, since tea will go ahead and jumble them up for
you. If the compiler aligns words this shouldn't be a problem. */
{ {
tokenlen = (tokenlen + (tokenlen % sizeof(uint32_t))) / sizeof(uint32_t); arc4_crypt_buffer(key, keylen, (uint8_t *)token, tokenlen);
tea_encode(key, (uint32_t *)token, tokenlen);
} }
/* Send it back. If there's an error here, it's okay. Better to have /* Send it back. If there's an error here, it's okay. Better to have
unclaimed tokens than unclaimable ones. */ unclaimed tokens than unclaimable ones. */
write(1, token, tokenlen * sizeof(uint32_t)); write(1, token, tokenlen);
return 0; return 0;
} }

View File

@ -68,7 +68,7 @@ main(int argc, char *argv[])
} }
{ {
char line[TEAM_MAX + CAT_MAX + sizeof(points_str) + 2]; char line[200];
my_snprintf(line, sizeof(line), my_snprintf(line, sizeof(line),
"%s %s %ld", team, category, points); "%s %s %ld", team, category, points);

View File

@ -19,11 +19,12 @@ longcmp(long *a, long *b)
#define PUZZLES_MAX 100 #define PUZZLES_MAX 100
/** Keeps track of the most points yet awarded in each category */ /** Keeps track of the most points yet awarded in each category */
int ncats = 0;
struct { struct {
char cat[CAT_MAX]; char cat[CAT_MAX];
long points; long points;
} points_by_cat[PUZZLES_MAX]; } points_by_cat[PUZZLES_MAX];
int ncats = 0;
size_t size_t
read_until_char(FILE *f, char *buf, size_t buflen, char delim) read_until_char(FILE *f, char *buf, size_t buflen, char delim)
@ -70,8 +71,6 @@ main(int argc, char *argv[])
read_until_char(f, points_str, sizeof(points_str), '\n'); read_until_char(f, points_str, sizeof(points_str), '\n');
points = atol(points_str); points = atol(points_str);
printf("%s %ld\n", cat, points);
for (i = 0; i < ncats; i += 1) { for (i = 0; i < ncats; i += 1) {
if (0 == strcmp(cat, points_by_cat[i].cat)) break; if (0 == strcmp(cat, points_by_cat[i].cat)) break;
} }

View File

@ -1,51 +0,0 @@
#include <stdint.h>
#include <stddef.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<n-1; p++)
y = v[p+1], z = v[p] += MX;
y = v[0];
z = v[n-1] += MX;
} while (--rounds);
} else if (n < -1) { /* Decoding Part */
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do {
e = (sum >> 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);
}

View File

@ -1,2 +0,0 @@
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);