On Wednesday 15 November 2006 12:26, Oliver Fromme wrote: > Max Laier wrote: > > David Malone wrote: > > > Assuming you don't want to use one of the standard cryptographic > > > ones (which I can imagine being a bit slow for something done > > > per-packet), then one option might be to use a simpler hash that > > > is keyed. Choose the key at boot/module load time and make it hard > > > to produce collisions unless you know the key. > > > > That's exactly what I am looking for ... now I need someone[tm] - > > with better Math-Knowledge than mine - to write such a thing down in > > a simple formula :-) i.e. take those bits from there and there and > > XOR them with your canary yada-yada-yada ... > > In that case, simply use crc32 (available from libkern.h) > and xor with a random key generated at boot time. crc32 > is fast to calculate and has the properties that you need.
Oops, I missed one requirement: /* * IMPORTANT: the hash function for dynamic rules must be commutative * in source and destination (ip,port), because rules are bidirectional * and we want to find both in the same bucket. */ AFAICT, the attached has this property, but I have no idea if it adds sufficient entropy to the result - it looks like it, though. -- /"\ Best regards, | [EMAIL PROTECTED] \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | [EMAIL PROTECTED] / \ ASCII Ribbon Campaign | Against HTML Mail and News
Index: ip_fw2.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.153
diff -u -r1.153 ip_fw2.c
--- ip_fw2.c 6 Nov 2006 13:42:04 -0000 1.153
+++ ip_fw2.c 15 Nov 2006 12:36:34 -0000
@@ -230,6 +230,7 @@
static ipfw_dyn_rule **ipfw_dyn_v = NULL;
static u_int32_t dyn_buckets = 256; /* must be power of 2 */
static u_int32_t curr_dyn_buckets = 256; /* must be power of 2 */
+static u_int32_t hash_nonce = 0;
static struct mtx ipfw_dyn_mtx; /* mutex guarding dynamic rules */
#define IPFW_DYN_LOCK_INIT() \
@@ -642,12 +643,19 @@
hash_packet6(struct ipfw_flow_id *id)
{
u_int32_t i;
- i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
+
+ i = (id->dst_ip6.__u6_addr.__u6_addr32[0]) ^
+ (id->dst_ip6.__u6_addr.__u6_addr32[1]) ^
+ (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
(id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
+ (id->src_ip6.__u6_addr.__u6_addr32[0]) ^
+ (id->src_ip6.__u6_addr.__u6_addr32[1]) ^
(id->src_ip6.__u6_addr.__u6_addr32[2]) ^
(id->src_ip6.__u6_addr.__u6_addr32[3]) ^
(id->dst_port) ^ (id->src_port);
- return i;
+ i = crc32_raw(&i, sizeof(i), hash_nonce);
+
+ return (i);
}
static int
@@ -4360,6 +4368,7 @@
uma_zdestroy(ipfw_dyn_rule_zone);
return (error);
}
+ hash_nonce = arc4random();
ip_fw_ctl_ptr = ipfw_ctl;
ip_fw_chk_ptr = ipfw_chk;
callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL);
pgpkc5EmS5WoQ.pgp
Description: PGP signature

