Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1543746 > unrolled thread
| Started by | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| First post | 2016-12-16 22:00 +0100 |
| Last post | 2016-12-16 23:50 +0100 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF "Jason A. Donenfeld" <Jason@zx2c4.com> - 2016-12-16 22:00 +0100
Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF "George Spelvin" <linux@sciencehorizons.net> - 2016-12-16 22:30 +0100
Re: [kernel-hardening] Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF "Jason A. Donenfeld" <Jason@zx2c4.com> - 2016-12-16 22:40 +0100
Re: [kernel-hardening] Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF "George Spelvin" <linux@sciencehorizons.net> - 2016-12-16 23:50 +0100
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2016-12-16 22:00 +0100 |
| Subject | Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF |
| Message-ID | <sP7LH-5f-9@gated-at.bofh.it> |
On Fri, Dec 16, 2016 at 9:17 PM, George Spelvin <linux@sciencehorizons.net> wrote: > My (speaking enerally; I should walk through every hash table you've > converted) opinion is that: > > - Hash tables, even network-facing ones, can all use hsiphash as long > as an attacker can only see collisions, i.e. ((H(x) ^ H(y)) & bits) == > 0, and the consequences of a successful attack is only more collisions > (timing). While the attack is only 2x the cost (two hashes rather than > one to test a key), the knowledge of the collision is statistical, > especially for network attackers, which raises the cost of guessing > beyond an even more brute-force attack. > - When the hash value directly visible (e.g. included in a network > packet), full SipHash should be the default. > - Syncookies *could* use hsiphash, especially as there are > two keys in there. Not sure if we need the performance. > - For TCP ISNs, I'd prefer to use full SipHash. I know this is > a very hot path, and if that's a performance bottleneck, > we can work harder on it. > > In particular, TCP ISNs *used* to rotate the key periodically, > limiting the time available to an attacker to perform an > attack before the secret goes stale and is useless. commit > 6e5714eaf77d79ae1c8b47e3e040ff5411b717ec upgraded to md5 and dropped > the key rotation. While I generally agree with this analysis for the most part, I do think we should use SipHash and not HalfSipHash for syncookies. Although the security risk is lower than with sequence numbers, it previously used full MD5 for this, which means performance is not generally a bottleneck and we'll get massive speedups no matter what, whether using SipHash or HalfSipHash. In addition, using SipHash means that the 128-bit key gives a larger margin and can be safe longterm. So, I think we should err on the side of caution and stick with SipHash in all cases in which we're upgrading from MD5. In other words, only current jhash users should be potentially eligible for hsiphash. > Current code uses a 64 ns tick for the ISN, so it counts 2^24 per second. > (32 bits wraps every 4.6 minutes.) A 4-bit counter and 28-bit hash > (or even 3+29) would work as long as the key is regenerated no more > than once per minute. (Just using the 4.6-minute ISN wrap time is the > obvious simple implementation.) > > (Of course, I defer to DaveM's judgement on all network-related issues.) I saw that jiffies addition in there and was wondering what it was all about. It's currently added _after_ the siphash input, not before, to keep with how the old algorithm worked. I'm not sure if this is correct or if there's something wrong with that, as I haven't studied how it works. If that jiffies should be part of the siphash input and not added to the result, please tell me. Otherwise I'll keep things how they are to avoid breaking something that seems to be working.
[toc] | [next] | [standalone]
| From | "George Spelvin" <linux@sciencehorizons.net> |
|---|---|
| Date | 2016-12-16 22:30 +0100 |
| Message-ID | <sP8eJ-w9-9@gated-at.bofh.it> |
| In reply to | #1543746 |
Jason A. Donenfeld wrote: > I saw that jiffies addition in there and was wondering what it was all > about. It's currently added _after_ the siphash input, not before, to > keep with how the old algorithm worked. I'm not sure if this is > correct or if there's something wrong with that, as I haven't studied > how it works. If that jiffies should be part of the siphash input and > not added to the result, please tell me. Otherwise I'll keep things > how they are to avoid breaking something that seems to be working. Oh, geez, I didn't realize you didn't understand this code. Full details at https://en.wikipedia.org/wiki/TCP_sequence_prediction_attack But yes, the sequence number is supposed to be (random base) + (timestamp). In the old days before Canter & Siegel when the internet was a nice place, people just used a counter that started at boot time. But then someone observed that I can start a connection to host X, see the sequence number it gives back to me, and thereby learn the seauence number it's using on its connections to host Y. And I can use that to inject forged data into an X-to-Y connection, without ever seeing a single byte of the traffic! (If I *can* observe the traffic, of course, none of this makes the slightest difference.) So the random base was made a keyed hash of the endpoint identifiers. (Practically only the hosts matter, but generally the ports are thrown in for good measure.) That way, the ISN that host X sends to me tells me nothing about the ISN it's using to talk to host Y. Now the only way to inject forged data into the X-to-Y connection is to send 2^32 bytes, which is a little less practical.
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2016-12-16 22:40 +0100 |
| Subject | Re: [kernel-hardening] Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF |
| Message-ID | <sP8oq-zl-21@gated-at.bofh.it> |
| In reply to | #1543760 |
Hi George, On Fri, Dec 16, 2016 at 10:25 PM, George Spelvin <linux@sciencehorizons.net> wrote: > But yes, the sequence number is supposed to be (random base) + (timestamp). > In the old days before Canter & Siegel when the internet was a nice place, > people just used a counter that started at boot time. > > But then someone observed that I can start a connection to host X, > see the sequence number it gives back to me, and thereby learn the > seauence number it's using on its connections to host Y. > > And I can use that to inject forged data into an X-to-Y connection, > without ever seeing a single byte of the traffic! (If I *can* observe > the traffic, of course, none of this makes the slightest difference.) > > So the random base was made a keyed hash of the endpoint identifiers. > (Practically only the hosts matter, but generally the ports are thrown > in for good measure.) That way, the ISN that host X sends to me > tells me nothing about the ISN it's using to talk to host Y. Now the > only way to inject forged data into the X-to-Y connection is to > send 2^32 bytes, which is a little less practical. Oh, okay, that is exactly what I thought was going on. I just thought you were implying that jiffies could be moved inside the hash, which then confused my understanding of how things should be. In any case, thanks for the explanation. Jason
[toc] | [prev] | [next] | [standalone]
| From | "George Spelvin" <linux@sciencehorizons.net> |
|---|---|
| Date | 2016-12-16 23:50 +0100 |
| Subject | Re: [kernel-hardening] Re: [PATCH v5 1/4] siphash: add cryptographically secure PRF |
| Message-ID | <sP9u9-1bb-5@gated-at.bofh.it> |
| In reply to | #1543764 |
An idea I had which mght be useful: You could perhaps save two rounds in siphash_*u64. The final word with the length (called "b" in your implementation) only needs to be there if the input is variable-sized. If every use of a given key is of a fixed-size input, you don't need a length suffix. When the input is an even number of words, that can save you two rounds. This requires an audit of callers (e.g. you have to use different keys for IPv4 and IPv6 ISNs), but can save time. (This is crypto 101; search "MD-strengthening" or see the remark on p. 101 on Damgaard's 1989 paper "A design principle for hash functions" at http://saluc.engr.uconn.edu/refs/algorithms/hashalg/damgard89adesign.pdf but I'm sure that Ted, Jean-Philippe, and/or DJB will confirm if you'd like.) Jason A. Donenfeld wrote: > Oh, okay, that is exactly what I thought was going on. I just thought > you were implying that jiffies could be moved inside the hash, which > then confused my understanding of how things should be. In any case, > thanks for the explanation. No, the rekeying procedure is cleverer. The thing is, all that matters is that the ISN increments fast enough, but not wrap too soon. It *is* permitted to change the random base, as long as it only increases, and slower than the timestamp does. So what you do is every few minutes, you increment the high 4 bits of the random base and change the key used to generate the low 28 bits. The base used for any particular host might change from 0x10000000 to 0x2fffffff, or from 0x1fffffff to 0x20000000, but either way, it's increasing, and not too fast. This has the downside that an attacker can see 4 bits of the base, so only needs to send send 2^28 = 256 MB to flood the connection, but the upside that the key used to generate the low bits changes faster than it can be broken.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web