To be clear on scope: this is about the relative ordering of the 3x AEAD options AES128-GCM, AES256-GCM, and CHACHA20-POLY1305 when all are used with ECDHE -based forward secrecy. These are our top 3 ciphers in terms of modern strength, but a lot of subtlety goes into choices between them, and there's a lot of confusion out there on the Internet about this issue.
I'll start by covering all of the out-of-scope ciphers: We obviously generally order FS ciphers before non-FS ciphers, and ECDHE before DHE within FS sets. We also always prefer the 3 strong ciphers under discussion here over any other alternatives. We only use 128-bit AES in these lesser options, as any client negotiating them has far bigger problems than AES bit-strength issues, and is likely to be a legacy/older devices where crypto CPU utilization matters the most. All of these out-of-scope ciphers are considered legacy and fundamentally-broken, and we only continue to support them because to do otherwise would cut off significant fractions of our real-world users, and these ciphers *do* provide some level of protection against lesser adversaries.
For the 3 in-scope strong ciphers: The great AES128-vs-AES256 debate was covered in depth in a semi-related ticket earlier (see here and beyond: T131908#2545144 ). The bottom line is that in purely security terms, our preference should probably be [chapoly|aes256] are equally-stronger than aes128 (and yes I know you've read differently, and I've even said differently in the past, but please read the earlier ticket link in detail).
On the performance front: clients implementing the strong suites do not universally support AES acceleration at the hardware level. This is especially true for modern browsers running on ancient hardware. For non-AES-accelerating clients, chapoly is both the strongest and the fastest choice, but it's also the newest and least-deployed of the three. For AES-accelerating clients, aes128 is faster than 256 and chapoly is significantly slower than both, but the performance differential for aes256-vs-aes128 is small and we really should just prefer aes256 on them. The real problem is we can't easily identify all AES-accelerating clients at ClientHello time.
We do have one signal about that: Chrome detects AES accleration and re-orders AES/ChaPoly in the client's preference list based on that.
In an ideal world, we'd basically like to prefer AES256 to AES128 for AES-accelerating clients (or possibly all clients), and prefer ChaPoly to AES for clients that implement it but lack AES-NI. Chrom(e|ium) makes this easy for us with their client preference re-ordering. Firefox is currently a problem, though. FF47's current state is that it supports ChaPoly, but has a static preference list which orders AES128 ahead of ChaPoly and doesn't even implement AES256. There are open tickets to address both issues in NSS/Firefox, and it seems at least initially that AES256 will be behind ChaPoly when that lands in FF49 (aes128->chapoly->aes256). I have no idea how their AES acceleration re-ordering will affect their future cipher lists after that.
I think even for non-accelerated clients, though, the AES256 (vs 128) perf hit is relatively-minor. It's there, but it may not be worth significant effort to pursue it.
We have a few basic options at this point in time:
- Stick with the ciphersuites and prefhacks we have. These choose ChaPoly iff it's ahead of the relevant AESGCM options in the client's list, and prefer AES128 to AES256 always, which is what most other major TLS sites are doing now.
- Stick with the ChaPoly prefhack we have now, and universally put AES256 ahead of AES128. This probably slightly slows down some clients (those new enough to support strong ciphers at all, but old enough to have a very slow CPU that lacks AES instructions), but it's probably a negligible slowdown in the net of our perf graphs.
- Use a more-complex prefhack similar to https://gerrit.wikimedia.org/r/#/c/306659/2/debian/patches/chapoly_aes256gcm_prefhacks.patch . This allows us to leave AES128 preferred in the general case, but bump the AES256 priority when the client cipher list indicates AES acceleration by including ChaPoly but de-prioritizing it. If all ChaPoly-capable clients acted the way Chrome does, this would be an ideal solution for the medium-term, looking towards eventually preferring AES256 outright as in (2) later.
Firefox doesn't really work right with any approach we've got, and their future directions are unknowns. I think we can safely assume they'll bump ChaPoly above both AES options for unaccelerated clients when/if NSS starts re-ordering based on acceleration. We probably can't assume they'll rank AES256 above ChaPoly for accelerating clients, though, as they still seem to be in an anti-AES256 mindset over there. The current complex pref hacks patch linked above would choose AES128 for all relevant Firefoxen today, and would choose AES256 for them all when that lands without acceleration re-ordering in FF49.