Closed Bug 1166338 Opened 9 years ago Closed 2 years ago

Don't reuse ECDHE key by default

Categories

(NSS :: Libraries, defect)

3.18
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: hkario, Assigned: rrelyea)

Details

Attachments

(2 files)

User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0
Build ID: 20150416103852

Steps to reproduce:

1. Start NSS based TLS server, like selfserv, configured with support of ECDHE ciphers
2. connect to it with client supportin ECDHE ciphers
3. Look at public value in Server Key Exchange message


Actual results:

The public value for all connections is the same


Expected results:

All public values should be different.

The expected behaviour for ECDHE ciphers is to provide Forward Secrecy (PFS) by default, the performance gains of this default are negligible for any more complex application like a web server, while if the server process is long lived (months at a time) it effectively removes Forward Secrecy.
Status: UNCONFIRMED → NEW
Ever confirmed: true
In other words, please change default of SSL_REUSE_SERVER_ECDHE_KEY setting for false
As in the DH case, I prefer a counter. A counter with 100 or 1000 uses gets you most of the security without incuring the added performance cost of the extra public key op.
(In reply to Robert Relyea from comment #2)
> As in the DH case, I prefer a counter. A counter with 100 or 1000 uses gets
> you most of the security without incuring the added performance cost of the
> extra public key op.

A counter doesn't work well for a server that doesn't get many connections or for a server that gets many connections.

Please see http://www.ietf.org/mail-archive/web/cfrg/current/msg04924.html, starting at "As I explained in a previous message."

Also note that ECC keygen is very fast, especially compared to non-ECC DHE keygen.
1) If you don't get that many connections, you also aren't likely a target. Bernstein isn't talking about a use counter, he's talking about complicated systems they try to tie reuse to the same session or connection (which is a silly idea because your are likely to be restarting those sessions anyway). He's playing off various time bases systems. His 1 second is equivalent to 100 uses on a big server, and you only get the win if you have that many connections. (NOTE: he is *NOT* advocating everytime reuse like you claim).

2) ECC keygen is exactly the same cost as an ECDH operation. If you always regen, you increase the cost of ECDHE by 30% (which is already 50% slower than ECDH)

3) While it's not that relevant, the comparison between DH and ECDH keygen is relative. On very small machines with small arithmetic units (like 16 bits), ECC is faster than DH at lower key strengths. On big servers with wide arithmetic units (particularly wide multiplies), that cross over point happens at the higher key strengths. Last time I measured, RSA/ECC cross over point was 2K RSA == 224 bit ECC on a modern intel machine (with 128bit multiplies). There is still some slop there. DH with a full length x is twice as slow as an RSA operation (which uses CRT), but DH x's are often smaller so that's probably a wash.

The point is it's a 30% hit to your connection setup. A 100 use counter cuts that to 3%.

If we don't do the counter, a 10 second reuse would be fine. On fully loaded servers that means about 100-1000 reuses, on an unloaded server the 30% extra cost doesn't matter (it's not the overall connection time we are worried about here, its the throttled throughput).

bob
(In reply to Robert Relyea from comment #4)
> 2) ECC keygen is exactly the same cost as an ECDH operation. If you always
> regen, you increase the cost of ECDHE by 30% (which is already 50% slower
> than ECDH)

30% slower of less than 1% of total server load is still less than anybody cares.
mod_nss already defaults SSL_REUSE_SERVER_ECDHE_KEY setting to false, with no
user option to change that back

if you can't take 30% longer keygen on a server you're already running on
awfully underpowered hardware

> 3) While it's not that relevant, the comparison between DH and ECDH keygen
> is relative. On very small machines with small arithmetic units (like 16
> bits), ECC is faster than DH at lower key strengths. On big servers with
> wide arithmetic units (particularly wide multiplies), that cross over point
> happens at the higher key strengths. Last time I measured, RSA/ECC cross
> over point was 2K RSA == 224 bit ECC on a modern intel machine (with 128bit
> multiplies). There is still some slop there. DH with a full length x is
> twice as slow as an RSA operation (which uses CRT), but DH x's are often
> smaller so that's probably a wash.

I measured on Atom D525 @ 1.8GHz, 1024 bit DHE was slower (~11%) than 256 bit ECDHE,
and that code wasn't even using the new hand optimised implementation in
OpenSSL for the nist-p256 curve.

> The point is it's a 30% hit to your connection setup. A 100 use counter cuts
> that to 3%.

I'm of opinion that this is premature optimisation. For a typical server (be it
web server, LDAP server or mail server) the crypto is small part of the total
computational load needed to render the page, search through database or run
spam filters, in general: to serve the request.

> If we don't do the counter, a 10 second reuse would be fine. On fully loaded
> servers that means about 100-1000 reuses, on an unloaded server the 30%
> extra cost doesn't matter (it's not the overall connection time we are
> worried about here, its the throttled throughput).

IMHO that just adds more complexity to security critical code for imperceptible
performance gains. Code that will be hard to get right for multithreaded environments.
How could this be driven towards a decision, whether the default should be kept or changed?
Assignee: nobody → rrelyea
Flags: needinfo?(rrelyea)
I'm not sure. Firefox uses ephemeral keys so this is principally an issue for servers. I would prefer to have it be purely ephemeral but as long as there is a pref I can survive.
The default should be changed, but it should come with some reuse. Re Eric: the real kicker here is Firefox doesn't have control of the how the keys are reused in the ephemeral case (for all firefox knows it could be a set of escrowed keys!).

The ephemeral keys here provide 2 things: 
    1) protection against subpoena access to your data (they website can't be coerced into decrypting your data stream for a government actor because the web owner doesn't have the keys). We pretty much protect against this. Once our server restarts that key is lost for ever.
    2) protection agains subpoena access to your live data (the government can't subpoena the server's keys to snoop on you live).
    3) reducing the attack value of the key by reducing the number of connections a compromise can cause.

We protect against 1 and 2, but 1 isn't that useful (the government can usually subpoena the actual data on the server), and 2 is a sham (the government could subpoena a post-SSL wire tap, or could require the server to use escrowed ephemeral keys).

We provide some benefit for 3 without changing the default, but you get more the less connections you use with a given key.

Given that 3 is the only real protections we get from the ephemeral ciphers, then it says we should provide some movement toward less reuse of the key.

Upshot we should implement a counter or timer and regenerate the key on the fly.
Flags: needinfo?(rrelyea)
(NOTE: to be really safe, we should regenerate p and g as well. Once p is compromised classically, then all keys with the same p are compromised. The problem is generating p is *really* expensive (potentially minutes).

bob
NSS is not alone in doing this [1]. That doesn't make it good practice.
This patch only changes the default to disable reuse.

[1] https://jhalderm.com/pub/papers/forward-secrecy-imc16.pdf
Attachment #8810536 - Flags: review?(rrelyea)

Given that Racoon attack showed that even very small differences in timing can be exploited when the server reuses the key share, I don't think NSS should aim to reuse a key share, even if it's for short time or few connections.

Flags: needinfo?(bbeurdouche)
Flags: needinfo?(bbeurdouche)

looks like John has fixed this. marking fixed.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: