Max Laier wrote: > 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. > */
OK, then you have to perform a commutative operation on source and destination ("xor" or "add"), then run crc32 on the result. > AFAICT, the attached has this property, but I have no idea if it adds > sufficient entropy to the result - it looks like it, though. It's not exactly what I had in mind. You are xor'ing all components with each other first, which makes it easier for an attacker to construct a collision: He just has to generate one 32bit part (e.g. the lower 32 bits of his address) so that the result of the xor stays the same. It's trivial to do that. Then the result of the crc32 will also be the same, of course. You should xor source and destination as a whole, i.e. create an artifical (ip,port) struct that contains the xor'ed source and destination, then call crc32 on the 20 bytes of that struct. The random key can be used as initialization vector for crc32_raw(), like you did in your patch. However, there's still a problem: If the attacker can guess our port number, he can set his port number in a way that it will result in the same xor value. If his and our IP address are also the same, the total result will be the same again. A simple solution is to multiply the port numbers (with a 32bit result) instead of xor'ing them. Multiplication is commutative, but in most cases the attacker won't be able to generate an integer port number P2 in a way that P2 * P1 will equal a certain number, because in most cases that number won't be evenly divisible by P1. Of course there are a few cases left where it is possible to generate such an integer number P2. To defeat the attackers for those few cases, too, you should add another random key to both port numbers before multiplication. OK, to summarize: 1. Calculate src_ip xor dst_ip [result is 16 bytes]. 2. Calculate (src_port + pkey) * (dst_port + pkey) [result is 4 bytes, using 32bit modulo arithmetics]. 3. Run crc32_raw on the resulting 20 bytes, using ckey as initialization vector. pkey and ckey are two different 32bit random values that are generated once at boot. Best regards Oliver -- Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd Any opinions expressed in this message may be personal to the author and may not necessarily reflect the opinions of secnetix in any way. C++: "an octopus made by nailing extra legs onto a dog" -- Steve Taylor, 1998 _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"