-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there any benefit in including the P-384 curve in the Modern suite? #190
Comments
Is there some reason to favor P-384 over P-256? |
I assume bigger numbers are better? I have no more robust reasoning than that 😅 |
Its same reason most browsers prefer cipher suites with AES-128 first and then try AES-256. Performance/battery usage, balanced approach |
I suggest you look over https://safecurves.cr.yp.to/ In short, they are both potentially unsafe for exactly the same reasons:
|
@shamelesscookie: yes, i'm aware of these points but they're not really relevant to the question at hand here, which is whether we should support P-384 for clients we're already going to use NIST curves for (probably because they don't support any non-NIST EC at all). In addition, point 4 is not applicable to TLS, because the TLS handshake negotiates the curve being used in the clear. |
to answer the question in the subject: in the current openssl (1.1.1) P-256 (aka prime256v1, aka secp256r1) is over an order of magnitude faster than P-384 for Diffie-Hellman: 18535 op/s vs 1333 op/s (on a 4GHz frequency locked i7 4790K); P-521 is actually faster than P-384 now, it manages 3008 op/s; but P-521 support is not as widespread as P-384 at the same time, there are no attacks that have significantly weakened P-256, it still is considered to be at the full 128 bit level of security (2^128 work factor) the same one as AES-128 and SHA-256 are then we have the problem of long-term secrets, even if CAs have root certificates with P-384 curve, intermediate certificates are P-256, so using anything bigger doesn't really increase security so to reiterate ekr's question: are there any reasons to remove P-256 and replace it with P-384? |
Given the rationale above it sounds like there's not an appetite for this change |
Thank you everyone who contributed to the discussion, there's lots of really good info here! Given the points made above I think the original question is maybe not the most pertinent now. Given the points that P-256 is secure enough, and that P-384 is an order of magnitude slower, I think the relevant question might now be: Is there any benefit in including the P-384 curve in the Modern suite? The discussion here really answered well the question of whether P-384 should be used over P-256 in theory, but I want to draw attention to the fact that in practice, browsers are picking 384 when both are available (at least according to SSL Labs' simulation of handshakes). If P-256 is good enough, and significantly faster than P-384, would it make sense to remove P-384 from the list so that browsers pick P-256 instead? |
because P-384 is part of the (deprecated, but enshrined in code) Suite B so it is the most widely deployed curve other than P-256. If it is widely deployed and enabled, in case of ECC breakthrough that significantly weakens those curves, but does not break them completely, we have a way to switch to the more secure curve right away - it won't require configuration changes on both servers and clients to align before we'll be able to switch to it. |
That makes sense to me. Thanks! On the very original point:
This was due to having the protocols in the wrong order – I think that means this is settled after all? Thanks again everyone who contributed. |
Previously, the NixOS ACME module defaulted to using P-384 for TLS certificates. I believe that this is a mistake, and that we should use P-256 instead, despite it being theoretically cryptographically weaker. The security margin of a 256-bit elliptic curve cipher is substantial; beyond a certain level, more bits in the key serve more to slow things down than add meaningful protection. It's much more likely that ECDSA will be broken entirely, or some fatal flaw will be found in the NIST curves that makes them all insecure, than that the security margin will be reduced enough to put P-256 at risk but not P-384. It's also inconsistent to target a curve with a 192-bit security margin when our recommended nginx TLS configuration allows 128-bit AES. [This Stack Exchange answer][pornin] by cryptographer Thomas Pornin conveys the general attitude among experts: > Use P-256 to minimize trouble. If you feel that your manhood is > threatened by using a 256-bit curve where a 384-bit curve is > available, then use P-384: it will increases your computational and > network costs (a factor of about 3 for CPU, a few extra dozen bytes > on the network) but this is likely to be negligible in practice (in a > SSL-powered Web server, the heavy cost is in "Web", not "SSL"). [pornin]: https://security.stackexchange.com/a/78624 While the NIST curves have many flaws (see [SafeCurves][safecurves]), P-256 and P-384 are no different in this respect; SafeCurves gives them the same rating. The only NIST curve Bernstein [thinks better of, P-521][bernstein] (see "Other standard primes"), isn't usable for Web PKI (it's [not supported by BoringSSL by default][boringssl] and hence [doesn't work in Chromium/Chrome][chromium], and Let's Encrypt [don't support it either][letsencrypt]). [safecurves]: https://safecurves.cr.yp.to/ [bernstein]: https://blog.cr.yp.to/20140323-ecdsa.html [boringssl]: https://boringssl.googlesource.com/boringssl/+/e9fc3e547e557492316932b62881c3386973ceb2 [chromium]: https://bugs.chromium.org/p/chromium/issues/detail?id=478225 [letsencrypt]: https://letsencrypt.org/docs/integration-guide/#supported-key-algorithms So there's no real benefit to using P-384; what's the cost? In the Stack Exchange answer I linked, Pornin estimates a factor of 3× CPU usage, which wouldn't be so bad; unfortunately, this is wildly optimistic in practice, as P-256 is much more common and therefore much better optimized. [This GitHub comment][openssl] measures the performance differential for raw Diffie-Hellman operations with OpenSSL 1.1.1 at a whopping 14× (even P-521 fares better!); [Caddy disables P-384 by default][caddy] due to Go's [lack of accelerated assembly implementations][crypto/elliptic] for it, and the difference there seems even more extreme: [this golang-nuts post][golang-nuts] measures the key generation performance differential at 275×. It's unlikely to be the bottleneck for anyone, but I still feel kind of bad for anyone having lego generate hundreds of certificates and sign challenges with them with performance like that... [openssl]: mozilla/server-side-tls#190 (comment) [caddy]: https://github.com/caddyserver/caddy/blob/2cab475ba516fa725d012f53ca417c3e039607de/modules/caddytls/values.go#L113-L124 [crypto/elliptic]: https://github.com/golang/go/tree/2910c5b4a01a573ebc97744890a07c1a3122c67a/src/crypto/elliptic [golang-nuts]: https://groups.google.com/forum/#!topic/golang-nuts/nlnJkBMMyzk In conclusion, there's no real reason to use P-384 in general: if you don't care about Web PKI compatibility and want to use a nicer curve, then Ed25519 or P-521 are better options; if you're a NIST-fearing paranoiac, you should use good old RSA; but if you're a normal person running a web server, then you're best served by just using P-256. Right now, NixOS makes an arbitrary decision between two equally-mediocre curves that just so happens to slow down ECDH key agreement for every TLS connection by over an order of magnitude; this commit fixes that. Unfortunately, it seems like existing P-384 certificates won't get migrated automatically on renewal without manual intervention, but that's a more general problem with the existing ACME module (see NixOS#81634; I know @yegortimoshenko is working on this). To migrate your certificates manually, run: $ sudo find /var/lib/acme/.lego/certificates -type f -delete $ sudo find /var/lib/acme -name '*.pem' -delete $ sudo systemctl restart 'acme-*.service' nginx.service (No warranty. If it breaks, you get to keep both pieces. But it worked for me.)
Previously, the NixOS ACME module defaulted to using P-384 for TLS certificates. I believe that this is a mistake, and that we should use P-256 instead, despite it being theoretically cryptographically weaker. The security margin of a 256-bit elliptic curve cipher is substantial; beyond a certain level, more bits in the key serve more to slow things down than add meaningful protection. It's much more likely that ECDSA will be broken entirely, or some fatal flaw will be found in the NIST curves that makes them all insecure, than that the security margin will be reduced enough to put P-256 at risk but not P-384. It's also inconsistent to target a curve with a 192-bit security margin when our recommended nginx TLS configuration allows 128-bit AES. [This Stack Exchange answer][pornin] by cryptographer Thomas Pornin conveys the general attitude among experts: > Use P-256 to minimize trouble. If you feel that your manhood is > threatened by using a 256-bit curve where a 384-bit curve is > available, then use P-384: it will increases your computational and > network costs (a factor of about 3 for CPU, a few extra dozen bytes > on the network) but this is likely to be negligible in practice (in a > SSL-powered Web server, the heavy cost is in "Web", not "SSL"). [pornin]: https://security.stackexchange.com/a/78624 While the NIST curves have many flaws (see [SafeCurves][safecurves]), P-256 and P-384 are no different in this respect; SafeCurves gives them the same rating. The only NIST curve Bernstein [thinks better of, P-521][bernstein] (see "Other standard primes"), isn't usable for Web PKI (it's [not supported by BoringSSL by default][boringssl] and hence [doesn't work in Chromium/Chrome][chromium], and Let's Encrypt [don't support it either][letsencrypt]). [safecurves]: https://safecurves.cr.yp.to/ [bernstein]: https://blog.cr.yp.to/20140323-ecdsa.html [boringssl]: https://boringssl.googlesource.com/boringssl/+/e9fc3e547e557492316932b62881c3386973ceb2 [chromium]: https://bugs.chromium.org/p/chromium/issues/detail?id=478225 [letsencrypt]: https://letsencrypt.org/docs/integration-guide/#supported-key-algorithms So there's no real benefit to using P-384; what's the cost? In the Stack Exchange answer I linked, Pornin estimates a factor of 3× CPU usage, which wouldn't be so bad; unfortunately, this is wildly optimistic in practice, as P-256 is much more common and therefore much better optimized. [This GitHub comment][openssl] measures the performance differential for raw Diffie-Hellman operations with OpenSSL 1.1.1 at a whopping 14× (even P-521 fares better!); [Caddy disables P-384 by default][caddy] due to Go's [lack of accelerated assembly implementations][crypto/elliptic] for it, and the difference there seems even more extreme: [this golang-nuts post][golang-nuts] measures the key generation performance differential at 275×. It's unlikely to be the bottleneck for anyone, but I still feel kind of bad for anyone having lego generate hundreds of certificates and sign challenges with them with performance like that... [openssl]: mozilla/server-side-tls#190 (comment) [caddy]: https://github.com/caddyserver/caddy/blob/2cab475ba516fa725d012f53ca417c3e039607de/modules/caddytls/values.go#L113-L124 [crypto/elliptic]: https://github.com/golang/go/tree/2910c5b4a01a573ebc97744890a07c1a3122c67a/src/crypto/elliptic [golang-nuts]: https://groups.google.com/forum/#!topic/golang-nuts/nlnJkBMMyzk In conclusion, there's no real reason to use P-384 in general: if you don't care about Web PKI compatibility and want to use a nicer curve, then Ed25519 or P-521 are better options; if you're a NIST-fearing paranoiac, you should use good old RSA; but if you're a normal person running a web server, then you're best served by just using P-256. Right now, NixOS makes an arbitrary decision between two equally-mediocre curves that just so happens to slow down ECDH key agreement for every TLS connection by over an order of magnitude; this commit fixes that. Unfortunately, it seems like existing P-384 certificates won't get migrated automatically on renewal without manual intervention, but that's a more general problem with the existing ACME module (see NixOS#81634; I know @yegortimoshenko is working on this). To migrate your certificates manually, run: $ sudo find /var/lib/acme/.lego/certificates -type f -delete $ sudo find /var/lib/acme -name '*.pem' -delete $ sudo systemctl restart 'acme-*.service' nginx.service (No warranty. If it breaks, you get to keep both pieces. But it worked for me.) (cherry picked from commit 62e34d1)
I am using the recommended settings of the modern suite, and testing via SSLLabs there isn't a single client that can connect and uses prime256v1 – everything either isn't connecting at all or uses secp384r1 or secp521r1.
Is there any client of note that supports TLS 1.2 and the ciphers in the Modern suite but doesn't support secp384r1?
The text was updated successfully, but these errors were encountered: