jbp.io Archive
09 September 2013

TLS128: A secure profile for TLS

Current deployments of TLS have a number of ongoing security problems, mostly arising from the vast complexity in the TLS standard, past poor design decisions and configuration errors.

Note: this post should be considered a work-in-progress until this notice is removed.

Rationale

We’d like to be able to describe, implement and use a secure channel. What TLS instead provides is a vast and complex toolkit with which you could build a secure channel, but only if you make the correct choice for every option it gives.

TLS128, then, cuts down this to a single profile. Adherance with this profile can be (to a large extent) tested for automatically. Rationale is provided for every important choice1.

TLS128 has the following security aims:

TLS128 deliberately does not aim for compatibility with existing TLS deployments: we prefer no connection to one which does not meet the required security level. It is therefore best suited for deployments where you can influence both endpoints.

Related work

draft-sheffer-tls-bcp gives a list of TLS reccommendations along similar lines to this profile, and was written roughly contemperously with an early version of this blog post.

RFC6460 is a TLS profile designed to use only Suite B crypto.

Trust model

Our trust model is similar to SSH; endpoint keys are either:

This is a flexible arrangement, and allows us to easily plug in signed assertions from other systems like Convergence.

In concrete terms, this means that in the TLS protocol endpoints send self-signed certificates for server and client authentication. No certificates are present anywhere which have basicConstraints CA:true. The trade-off is the manual public key verification, or key establishment, or integration of a system which provides these facilities.

Ciphersuite selection

Round one: taking out the trash

TLS currently has around 360 different ciphersuites defined or proposed. We’ll select suitable ciphersuites by exclusion of those unsuitable:

First let’s disregard all the ciphersuites which are obviously rubbish (like export-strength, DES, RC2, etc. – coloured in red4), or are merely unsuitable: they don’t fit our trust model (black) or don’t provide forward secrecy (blue).

Round two: known attacks

This leaves us with the following candidates:

Next, let’s remove the ciphersuites which are known to be impossibly hard to convincingly implement without timing side channels (all CBC mac-then-encrypt suites – in red), those which use RC4 (which has significant statistical biases – in blue).

Round three: security levels

We are left with:

Depending on whose analysis you read, achieving a 128-bit security level would require using an RSA modulus of somewhere between 3072 and 6144 bits in length, a DSA group of a similar size modulus and 256-bit subgroup, and a similar DH group. In contrast, using ECC would only need a curve with a 256-bit group order.

So, for reasons of efficiency, we discard all the ciphersuites using ephemeral DH for PFS, RSA for authenticity or DSA for authenticity.

Discarding RSA at this point also means we don’t have to deal with a later horror: that TLS continues to require use of RSA PKCS#1 signatures which are very much discredited in favour of PSS.

This unfortunately has the side effect of also discarding all the ciphersuites which use CCM. These would otherwise be good candidates.

Side note: The way ciphersuites are communicated in TLS is of particularly poor design: the set of ciphersuites must be the power set of all available bulk transport mechanisms (which themselves could be all-in-one AEAD constructions, or the power set of possible confidentiality and authenticity algorithms), authenticity mechanisms, key exchange mechanisms, and hash functions. Unfortunately it isn’t, so we don’t get to select TLS_ECDHE_ECDSA_WITH_AES_256_CCM or even TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA512.

Round four: block cipher choice

Disappointingly, we are left with 6 ciphersuites from which to choose:

ARIA is a block cipher of very similar internal structure to AES, standardised by the Korean Internet Security Agency. Camellia is also a block cipher very similar to AES, designed by NTT and Mitsubishi in Japan.

Both of these ciphers are probably OK choices, but we choose AES for the additional academic attention it has received in the past, and should receive in the future. Hardware acceleration for AES and GHASH is also present in modern Intel processors; ARIA and Camellia are unlikely to gain similar traction.

Finally, we discard TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 because use of AES-256 and SHA-384 would exceed our security target.

This leaves use with a single ciphersuite which meets our needs: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.

EC curve selection

The curves we could choose that are approximately strong enough are:

At this point, we borrow the analysis of Daniel J. Bernstein and Tanja Lange.

NIST P-256 (and the other NIST prime curves) was originated by Jerome A. Solinas of the NSA. There is some concern that the curve was chosen such that it has a weakness known to the NSA. It seems foolhardy at this point to specify use of such a curve, even though it is well-supported in existing implementations.

We are left with choosing between Curve25519 and Brainpool P256t1. The Brainpool curve comes out badly in the safecurves analysis (not as bad as NIST P-256, though). On the other hand the RFC4492 standard which specifies how to use ECC in TLS does not support explicitly encoding Montgomery or Edwards curves, or the short public key encoding offered by Curve25519, and TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 clearly does not support the Ed25519 signature scheme which is a natural bedfellow of a cryptosystem which uses Curve25519 for DH.

So we are in a corner: the TLS standards are not flexible in the curves they support, and the curves they do support are known to be hard to securely implement. We have to make do with the Brainpool curve, or expend effort squeezing Curve25519 into TLS. We grudgingly select the former option: Brainpool P256t1 according to RFC7027.

A note about ECDSA

ECDSA signatures require a high quality entropy source. The failure mode is dire: the private key is leaked if two signatures reuse the same k value, or one signature has a known k, or a small number of signatures with partially attacker-predictable ks. This is a particularly sharp edge of ECDSA (and DSA, for that matter).

Fortunately, RFC6979 provides an alternate entropy source by reuseing the entropy already (necessarily) present in the key material. Therefore: all TLS128 implementations must use an RFC6979-compliant ECDSA implementation.

This covers both signing of ephemeral ECDH keys during key exchange, and self-signing of certificates.

Authentication keys

Authentication keys (as quoted in the self-signed certificates) must be ECDSA keys on the right curve.

Compression

No TLS-level (or above) protocol compression is allowed5. At the TLS handshake level, the client-offered compressions must contain one value: null (0).

Renegotiation

Renegotiation is a particular area of incorrect design in the protocol, with several vulnerabilities resulting and jury rigged (RFC5746 and draft-bhargavan-tls-session-hash-00, notably).

TLS128 clients and servers must not support renegotation. It’s typically only used for fixing TLS’s lack of privacy features when doing client authentication, anyway.

Forward secrecy in practice

Achieving forward secrecy is not just a case of choosing a ciphersuite which supports it. A few TLS features can effectively and quietly break forward secrecy:

Session resumption

TLS ClientHello and ServerHello handshake messages include a SessionID value.

On a new connection, a client can supply a session ID to attempt to resume that session, where the session ID was obtained from the server on a previous occasion. Resumption in this case is valuable, because it allows the new connection to commence without a fresh key exchange (which can be slow both in terms of computation and network latency.)

Supporting session resumption means the server inevitably stores the secrets related to old connections for some time (perhaps indefinitely). This is bad for forward secrecy, if your attack model includes the server being compromised or seized by LEA.

TLS128 handshakes must always have empty session IDs: session resumption must not be supported.

Session tickets

Session tickets are a different way of achieving the same end as session resumption, with the advantage that the server encrypts the session state and sends it to the client for storage (and later presentation). This means the server only needs to manage the keys for that encryption.

Unfortunately RFC5077 is extremely vague and noncommittal when it comes to avoiding damage to forward secrecy, ensuring the ticket is protected to the same level as the session itself, and a concrete rules for managing the keys which protect tickets.

Coming up with a concrete and verifiable ticket format and key management scheme is a good area for future work.

For now, though, TLS128 clients should not send SessionTicket extensions, and TLS128 servers should not send NewSessionTicket handshake messages.

Mandatory TLS extensions list

TBC: Here, write a list of all the TLS extensions which should be present in ClientHello and ServerHello, with acceptable values. This forms part of the verifier.

Constraints on handshake messages

A big list of other things to check in the verifier.

  1. Rationale is presented in footnotes like so. 

  2. We’d like to have good assurance of security against well equipped adversaries (say, Governments and botnet owners), and be confident that this situation will continue at least for the next decade. 

  3. HTTPS as currently deployed requires simultaneously trusting all ~613 top level and subordinate CAs. This is an extensive attack surface, a number of previous and current CAs have been unable to secure their systems, and CAs do not publish their actions for public scrutiny. 

  4. None of these choices meet our target security level. 

  5. This is to avoid the CRIME/BREACH attacks, where plaintext information leaks through the ciphertext length side channel.