mirror of https://github.com/dirtbags/moth.git
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:
parent
cf282dff48
commit
4d981756ce
|
@ -5,7 +5,7 @@ all: build
|
|||
|
||||
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
|
||||
|
||||
puzzles.cgi: puzzles.cgi.o common.o
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -64,7 +64,7 @@ main(int argc, char *argv[])
|
|||
category[i] = '\0';
|
||||
|
||||
{
|
||||
char line[TEAM_MAX + TOKEN_MAX + 1];
|
||||
char line[200];
|
||||
|
||||
my_snprintf(line, sizeof(line),
|
||||
"%s %s", team, token);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "common.h"
|
||||
#include "xxtea.h"
|
||||
#include "arc4.h"
|
||||
|
||||
#define itokenlen 3
|
||||
|
||||
|
@ -69,11 +69,12 @@ bubblebabble(char *out, char const *in, const size_t inlen)
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char service[50];
|
||||
size_t servicelen;
|
||||
char token[80];
|
||||
size_t tokenlen;
|
||||
uint32_t key[4];
|
||||
char service[50];
|
||||
size_t servicelen;
|
||||
char token[80];
|
||||
size_t tokenlen;
|
||||
uint8_t key[256];
|
||||
size_t keylen;
|
||||
|
||||
/* Seed the random number generator. This ought to be unpredictable
|
||||
enough for a contest. */
|
||||
|
@ -83,7 +84,7 @@ main(int argc, char *argv[])
|
|||
{
|
||||
ssize_t len;
|
||||
|
||||
len = read(0, service, sizeof(service) - 1);
|
||||
len = read(0, service, sizeof(service));
|
||||
for (servicelen = 0;
|
||||
(servicelen < len) && isalnum(service[servicelen]);
|
||||
servicelen += 1);
|
||||
|
@ -91,22 +92,23 @@ main(int argc, char *argv[])
|
|||
|
||||
/* Read in that service's key. */
|
||||
{
|
||||
int fd;
|
||||
size_t len;
|
||||
int fd;
|
||||
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) {
|
||||
write(1, "!nosvc", 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = read(fd, &key, 16);
|
||||
close(fd);
|
||||
|
||||
if (16 != len) {
|
||||
write(1, "!shortkey", 9);
|
||||
ret = read(fd, &key, sizeof(key));
|
||||
if (-1 == ret) {
|
||||
write(1, "!read", 5);
|
||||
return 0;
|
||||
}
|
||||
keylen = (size_t)ret;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Create the token. */
|
||||
|
@ -158,19 +160,14 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
/* Encrypt the token. Note that now tokenlen is in uint32_ts, not
|
||||
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. */
|
||||
/* Encrypt the token. */
|
||||
{
|
||||
tokenlen = (tokenlen + (tokenlen % sizeof(uint32_t))) / sizeof(uint32_t);
|
||||
|
||||
tea_encode(key, (uint32_t *)token, tokenlen);
|
||||
arc4_crypt_buffer(key, keylen, (uint8_t *)token, tokenlen);
|
||||
}
|
||||
|
||||
/* Send it back. If there's an error here, it's okay. Better to have
|
||||
unclaimed tokens than unclaimable ones. */
|
||||
write(1, token, tokenlen * sizeof(uint32_t));
|
||||
write(1, token, tokenlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
"%s %s %ld", team, category, points);
|
||||
|
|
|
@ -19,11 +19,12 @@ longcmp(long *a, long *b)
|
|||
#define PUZZLES_MAX 100
|
||||
|
||||
/** Keeps track of the most points yet awarded in each category */
|
||||
int ncats = 0;
|
||||
struct {
|
||||
char cat[CAT_MAX];
|
||||
long points;
|
||||
} points_by_cat[PUZZLES_MAX];
|
||||
int ncats = 0;
|
||||
|
||||
|
||||
size_t
|
||||
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');
|
||||
points = atol(points_str);
|
||||
|
||||
printf("%s %ld\n", cat, points);
|
||||
|
||||
for (i = 0; i < ncats; i += 1) {
|
||||
if (0 == strcmp(cat, points_by_cat[i].cat)) break;
|
||||
}
|
||||
|
|
51
src/xxtea.c
51
src/xxtea.c
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
Loading…
Reference in New Issue