made siphash more generic and finished cookie calculation code
This commit is contained in:
parent
d158318625
commit
7d78a26857
166
src/siphash24.c
166
src/siphash24.c
@ -4,6 +4,7 @@
|
||||
<jeanphilippe.aumasson@gmail.com>
|
||||
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
|
||||
Copyright (c) 2016 Maximilian Muenchow <maximilian.muenchow@teamspeak.com>
|
||||
Copyright (c) 2016 Niels Werensteijn <niels.werensteijn@teamspeak.com>
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
@ -13,7 +14,7 @@
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "siphash24.h"
|
||||
|
||||
|
||||
/* default: SipHash-2-4 */
|
||||
@ -58,57 +59,129 @@
|
||||
#define TRACE
|
||||
#endif
|
||||
|
||||
// it is assumed that every parameter is in LE
|
||||
int ts3init_siphash(u64 *out, const u8 *in, u64 inlen, u64 k0, u64 k1) {
|
||||
void ts3init_siphash_setup(struct ts3init_siphash_state* state, u64 k0, u64 k1)
|
||||
{
|
||||
/* "somepseudorandomlygeneratedbytes" */
|
||||
u64 v0 = 0x736f6d6570736575ULL;
|
||||
u64 v1 = 0x646f72616e646f6dULL;
|
||||
u64 v2 = 0x6c7967656e657261ULL;
|
||||
u64 v3 = 0x7465646279746573ULL;
|
||||
u64 b;
|
||||
u64 m;
|
||||
int i;
|
||||
const u8 *end = in + inlen - (inlen % sizeof(u64));
|
||||
const int left = inlen & 7;
|
||||
state->v0 = 0x736f6d6570736575ULL;
|
||||
state->v1 = 0x646f72616e646f6dULL;
|
||||
state->v2 = 0x6c7967656e657261ULL;
|
||||
state->v3 = 0x7465646279746573ULL;
|
||||
state->len= 0;
|
||||
k0 = le64_to_cpu(k0);
|
||||
k1 = le64_to_cpu(k1);
|
||||
b = ((u64)inlen) << 56;
|
||||
v3 ^= k1;
|
||||
v2 ^= k0;
|
||||
v1 ^= k1;
|
||||
v0 ^= k0;
|
||||
state->v3 ^= k1;
|
||||
state->v2 ^= k0;
|
||||
state->v1 ^= k1;
|
||||
state->v0 ^= k0;
|
||||
}
|
||||
|
||||
for (; in != end; in += 8) {
|
||||
m = U8TO64_LE(in);
|
||||
v3 ^= m;
|
||||
void ts3init_siphash_update(struct ts3init_siphash_state* state, const u8 *in, size_t inlen)
|
||||
{
|
||||
size_t next_byte = state->len % 8;
|
||||
size_t left;
|
||||
const u8* end = in + inlen;
|
||||
int i;
|
||||
u64 m, v0, v1, v2, v3;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < cROUNDS; ++i)
|
||||
SIPROUND;
|
||||
state->len += inlen;
|
||||
m = state->m;
|
||||
v0 = state->v0;
|
||||
v1 = state->v1;
|
||||
v2 = state->v2;
|
||||
v3 = state->v3;
|
||||
|
||||
switch (next_byte)
|
||||
{
|
||||
case 1:
|
||||
m |= ((u64)(*in++)) << 8;
|
||||
if (in==end) goto __exit_update;
|
||||
case 2:
|
||||
m |= ((u64)(*in++)) << 16;
|
||||
if (in==end) goto __exit_update;
|
||||
case 3:
|
||||
m |= ((u64)(*in++)) << 24;
|
||||
if (in==end) goto __exit_update;
|
||||
case 4:
|
||||
m |= ((u64)(*in++)) << 32;
|
||||
if (in==end) goto __exit_update;
|
||||
case 5:
|
||||
m |= ((u64)(*in++)) << 40;
|
||||
if (in==end) goto __exit_update;
|
||||
case 6:
|
||||
m |= ((u64)(*in++)) << 48;
|
||||
if (in==end) goto __exit_update;
|
||||
case 7:
|
||||
m |= ((u64)(*in++)) << 56;
|
||||
|
||||
v3 ^= m;
|
||||
|
||||
v0 ^= m;
|
||||
}
|
||||
TRACE;
|
||||
for (i = 0; i < cROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
switch (left) {
|
||||
case 7:
|
||||
b |= ((u64)in[6]) << 48;
|
||||
case 6:
|
||||
b |= ((u64)in[5]) << 40;
|
||||
case 5:
|
||||
b |= ((u64)in[4]) << 32;
|
||||
case 4:
|
||||
b |= ((u64)in[3]) << 24;
|
||||
case 3:
|
||||
b |= ((u64)in[2]) << 16;
|
||||
case 2:
|
||||
b |= ((u64)in[1]) << 8;
|
||||
case 1:
|
||||
b |= ((u64)in[0]);
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
v0 ^= m;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
left = (end-in) % 8;
|
||||
end -= left;
|
||||
|
||||
for (; in != end; in += 8)
|
||||
{
|
||||
m = U8TO64_LE(in);
|
||||
v3 ^= m;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < cROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
v0 ^= m;
|
||||
}
|
||||
|
||||
m=0;
|
||||
switch(left)
|
||||
{
|
||||
case 7:
|
||||
m |= ((u64)(in[6])) << 48;
|
||||
case 6:
|
||||
m |= ((u64)(in[5])) << 40;
|
||||
case 5:
|
||||
m |= ((u64)(in[4])) << 32;
|
||||
case 4:
|
||||
m |= ((u64)(in[3])) << 24;
|
||||
case 3:
|
||||
m |= ((u64)(in[2])) << 16;
|
||||
case 2:
|
||||
m |= ((u64)(in[1])) << 8;
|
||||
case 1:
|
||||
m |= ((u64)(in[0]));
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
__exit_update:
|
||||
state->m = m;
|
||||
state->v0 = v0;
|
||||
state->v1 = v1;
|
||||
state->v2 = v2;
|
||||
state->v3 = v3;
|
||||
}
|
||||
|
||||
u64 ts3init_siphash_finalize(struct ts3init_siphash_state* state)
|
||||
{
|
||||
u64 b = state->len << 56;
|
||||
u64 v0, v1, v2, v3;
|
||||
int i;
|
||||
|
||||
b |= state->m;
|
||||
|
||||
|
||||
v0 = state->v0;
|
||||
v1 = state->v1;
|
||||
v2 = state->v2;
|
||||
v3 = state->v3;
|
||||
|
||||
v3 ^= b;
|
||||
|
||||
TRACE;
|
||||
@ -123,9 +196,6 @@ int ts3init_siphash(u64 *out, const u8 *in, u64 inlen, u64 k0, u64 k1) {
|
||||
SIPROUND;
|
||||
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
*out = cpu_to_le64(b);
|
||||
|
||||
|
||||
return 0;
|
||||
return cpu_to_le64(b);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "siphash24.h"
|
||||
#include "ts3init_cookie.h"
|
||||
|
||||
static void check_update_seed_cache(time_t time, __u8 index,
|
||||
@ -80,7 +82,7 @@ __u64* ts3init_get_cookie_seed(time_t current_time, __u8 packet_index,
|
||||
/* get cache time of packet */
|
||||
current_cache_time = current_time & ~((time_t)3);
|
||||
packet_cache_time = current_cache_time
|
||||
- ((current_cache_index ^ packet_cache_index)*4);
|
||||
- ((current_cache_index ^ packet_cache_index)*4);
|
||||
|
||||
/* make sure the cache is up-to-date */
|
||||
check_update_seed_cache(packet_cache_time, packet_cache_index, cache,
|
||||
@ -90,3 +92,41 @@ __u64* ts3init_get_cookie_seed(time_t current_time, __u8 packet_index,
|
||||
return cache->seed64 + ((SIP_KEY_SIZE/sizeof(__u64)) * packet_index );
|
||||
}
|
||||
|
||||
int ts3init_calculate_cookie(const struct sk_buff *skb, struct xt_action_param *par, struct udphdr *udp, u64 k0, u64 k1, __u64* out)
|
||||
{
|
||||
int addr_offset;
|
||||
int addr_len;
|
||||
void* addr_data;
|
||||
__u8 addr_buf[2*16];
|
||||
struct ts3init_siphash_state hash_state;
|
||||
|
||||
switch (par->family)
|
||||
{
|
||||
case NFPROTO_IPV4:
|
||||
addr_offset = 12; /*offset to src and dst address in ipv4 header */
|
||||
addr_len = 2*4; /*size of ipv4 address is 4 bytes */
|
||||
break;
|
||||
|
||||
case NFPROTO_IPV6:
|
||||
addr_offset = 8; /*offset to src and dst address in ipv6 header */
|
||||
addr_len = 2*16; /*size of ipv6 address is 16 bytes */
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR KBUILD_MODNAME ": invalid family\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr_data = skb_header_pointer(skb, skb->network_header+addr_offset, addr_len, addr_buf);
|
||||
if (!addr_data)
|
||||
{
|
||||
printk(KERN_ERR KBUILD_MODNAME ": could not load ip addresses\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ts3init_siphash_setup(&hash_state, k0, k1);
|
||||
ts3init_siphash_update(&hash_state, (u8 *)addr_data, addr_len);
|
||||
ts3init_siphash_update(&hash_state, (u8 *)&udp->source, 4);
|
||||
*out = ts3init_siphash_finalize(&hash_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,4 +20,8 @@ __u64* ts3init_get_cookie_seed(time_t current_time, __u8 packet_index,
|
||||
struct xt_ts3init_cookie_cache* cache,
|
||||
const __u8* cookie_seed);
|
||||
|
||||
int ts3init_calculate_cookie(const struct sk_buff *skb,
|
||||
struct xt_action_param *par, struct udphdr *udp,
|
||||
u64 k0, u64 k1, __u64* out);
|
||||
|
||||
#endif /* _TS3INIT_COOKIE_H */
|
||||
|
@ -190,6 +190,7 @@ ts3init_get_puzzle_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
struct ts3init_cache_t* cache;
|
||||
struct ts3_init_header* ts3_header = header_data.ts3_header;
|
||||
__u64* cookie_seed, cookie_seed0, cookie_seed1;
|
||||
__u64 cookie, packet_cookie;
|
||||
|
||||
unsigned long jifs;
|
||||
time_t current_unix_time;
|
||||
@ -218,12 +219,18 @@ ts3init_get_puzzle_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
|
||||
/* use cookie_seed and ipaddress and port to create a hash
|
||||
* (cookie) for this connection */
|
||||
/* TODO: implement using sipHash */
|
||||
if (ts3init_calculate_cookie(skb, par, header_data.udp, cookie_seed0, cookie_seed1, &cookie))
|
||||
return false; /*something went wrong*/
|
||||
|
||||
/* compare cookie with payload bytes 0-7. if equal, cookie
|
||||
* is valid */
|
||||
/*if (memcmp(cookie, ts3_header->payload, 8) != 0) return false;*/
|
||||
|
||||
|
||||
packet_cookie = (((u64)((ts3_header->payload)[0])) | ((u64)((ts3_header->payload)[1]) << 8) |
|
||||
((u64)((ts3_header->payload)[2]) << 16) | ((u64)((ts3_header->payload)[3]) << 24) |
|
||||
((u64)((ts3_header->payload)[4]) << 32) | ((u64)((ts3_header->payload)[5]) << 40) |
|
||||
((u64)((ts3_header->payload)[6]) << 48) | ((u64)((ts3_header->payload)[7]) << 56));
|
||||
|
||||
if (packet_cookie != cookie) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user