TLS 1.2 cipher preference in Rebex HTTPS

+1 vote
asked Nov 13, 2020 by mobile653 (730 points)
edited Dec 8, 2020 by mobile653

In TLS 1.2, there is a server-preferred order for the different ciphers, for example:

  1. TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
  2. TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
  3. TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)

Source: SSL Labs report for doc-0s-c8-docs.googleusercontent.com

Using Rebex HTTPS version 2019 R3.6 with SslAllowedSuites set to TlsCipherSuite.Secure, the client-preferred order seems to be following:

  1. TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
  2. TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
  3. TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
  4. TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
  5. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
  6. TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
  7. TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
  8. TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
  9. TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)
  10. TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
  11. TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)
  12. TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
  13. TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
  14. TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
  15. TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
  16. TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
  17. TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
  18. TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
  19. TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)
  20. TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

Source: TLS 1.2 Client Hello, captured using Wireshark

We have three questions here:

  1. Does the client (running the Rebex HTTPS or Rebex HTTPS Legacy library) have to follow the server-preferred order, at least for all ciphers supported?

  2. Is there a relevance of the client-preferred order in the Rebex HTTPS or Rebex HTTPS Legacy library for servers?

  3. Can we control this behaviour in the Rebex HTTPS or Rebex HTTPS Legacy library?

Applies to: Rebex HTTPS, Rebex TLS
commented Dec 2, 2020 by mobile653 (730 points)
There is an interesting addition on the SSL Labs report for the Google Drive endpoint:
(P) This server prefers ChaCha20 suites with clients that don't have AES-NI (e.g., Android devices)

I would like to know how the clients not supporting AES-NI are identified.
commented Dec 3, 2020 by Lukas Pokorny (123,810 points)
Apparently, it works like this: If the Chacha20 suites are higher in client's order of preference, those servers prefer Chacha20 to AES/GCM.
More information:
https://zurgl.com/nginx-how-to-prioritize-chacha20-for-devices-without-hardware-aes-support/
https://trac.nginx.org/nginx/ticket/1445
https://github.com/openssl/openssl/pull/4436
commented Dec 7, 2020 by mobile653 (730 points)
Enlightening, thank you! So with this feature, ngnix DOES respect the client's preferred order (at least concerning ChaCha20), and large platforms like Google Drive behave so by default.

To benefit from this server-side evolution, we would be very happy to see the ChaCha20 ciphers moved to the top of the list in the next Rebex HTTPS Release for .NET CF 3.5 (or a switch to do so), telling nginx and Google our clients prefers those ciphers.

I assume all devices with .NET CF 3.5 support (Windows Mobile 6.5.3 or Windows Embedded Handheld 6.5) lack AES/GCM acceleration and are faster using ChaCha20/Poly1305. Even our latest (and likely fastest) device, the Zebra MC67 Premium with a Dual-Core-OMAP 4 1 GHz processor, is 10 to 25 % faster using ChaCha20/Poly1305 with a 256-bit key (compared to AES/GCM with a 128-bit key).
commented Dec 8, 2020 by Lukas Pokorny (123,810 points)
Yes, this looks like a useful feature to have. We'll add an option to the next release and possibly enable it by default as well. Thanks for bringing this to our attention!
commented Feb 15 by Lukas Pokorny (123,810 points)
This enhancement has been release with Rebex (Legacy) HTTPS 2019 R3.7: https://www.rebex.net/kb/legacy-editions-release-history/#2019R3.7

To move Chacha/Poly ciphers to the top of client’s preference list, use the new SetPreferredSuite method:
var creator = new HttpRequestCreator();
creator.Settings.SetPreferredSuites(
    TlsCipherSuite.ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TlsCipherSuite.ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
    TlsCipherSuite.DHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
commented Feb 15 by mobile653 (730 points)
Thank you very much, this works for us!

Is there a reason to prefer
ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 against ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256?

Having a look on the AES ciphers, the order is:
1. ECDHE_ECDSA_…
2. ECDHE_RSA_…
3. DHE_RSA_…

1 Answer

0 votes
answered Nov 13, 2020 by Lukas Pokorny (123,810 points)

In all versions of TLS protocol, the TLS client provides a list of ciphers it supports (in its preferred order), and the TLS server is free to choose any one of them. The TLS client has no choice but to use to cipher selected by the server. See the relevant sections of RFC 5246.

So to answer your questions:

1) The client is supposed to accept whatever cipher is selected by the server. It does not receive a list of server-side ciphers at all.

2) No. However, to most servers, client's preferred order is irrelevant, so we have not included this option in our API.

3) Since it's the TLS server that gets to choose the cipher, and client-side order of supported ciphers is only advisory, TLS clients only really control whether they announce support for a particular cipher or not.

If the TLS client needs the server to accept the cipher the client prefers, it would have to attempt multiple negotiations, each with a list that only contains a single cipher. If it gets rejected by the server, it would try the next one on order.


(By the way, as an interesting side note - the cipher selection process is very different in SSH, where both sides do transmit a list of ciphers in preferred order, and the one supported by both and preferred by the client is selected.)

...