crypto/tls: deprecate PreferServerCipherSuites and CipherSuites ordering · Issue #45430 · golang/go (original) (raw)

Background

Cipher suite ordering and selection is complex, nuanced, and security relevant. Mechanically, the client sends a list of cipher suites in preference order, and the server picks one arbitrarily. In Go, Config.CipherSuites is in preference order, and PreferServerCipherSuites (default false) dictates whether on the server-side we prioritize the client's or the server's preferences.

There are two reasons to manipulate cipher suite setting: one is for filtering, to add off-by-default suites or turn off on-by-default ones; the other is for ordering, which has security and sometimes performance reasons. Filtering sets the minimum security bar: it's a statement of the kind "I am not willing to make a connection with less than these security properties". Ordering is particularly nuanced and has security semantics, because if implemented correctly it guarantees that peers will benefit from the highest security they support, thanks to downgrade protection. Properly implemented ordering influences filtering, because i.e. 3DES might be acceptable as a last resort only if it can be guaranteed that peers that support better options won't end up using 3DES.

The ordering logic is already not very linear: if we get to choose, we'll prioritize AES only if both sides (seem to) support hardware AES instructions, because software AES is slow and unsafe. Due to Sweet32 attacks (#41476) we would also like to put 3DES at the end of the list, so it only affects connections that would have broken otherwise. Expecting applications to implement all this logic and stay up to date on it is unreasonable.

The other angle is an ecosystem angle. Historically, clients were the ones that would know best, so a default behavior of deferring to the client's preference had the ecosystem benefit that clients could keep less secure cipher suites enabled as a fallback, counting on the server to pick their higher preferences. Servers were expected to have fossilized cipher suite preference lists, not informed by the latest attacks. We can do much better in Go if we are always in charge of ordering: we can fix the logic in security releases based on the latest attack. This also serves better legacy clients like old devices that can't get security updates anymore.

This proposal would finally solve the problem of how to expose our order logic so that applications can replicate it with a different filtering logic: we don't need to, as applications can now configure filtering without affecting ordering.

Proposal

I propose that we deprecate Config.PreferServerCipherSuites, effectively considering it always true, and remove the ordering semantics from Config.CipherSuites, considering it only a filtering list specifying which cipher suites to enable.

Ordering of client-advertised ciphersuites and server ciphersuite selection will be automatically handled by crypto/tls with logic evolving based on the changes in the ecosystem.