Subject: [TLS] Channel binding versus keying material exporters

From: Douglas Stebila <[email-masked]>
Date: Fri, 6 Nov 2009 00:23:05 +0800

Can someone comment on the similarities and differences of TLS channel  
binding and TLS keying material exporters?  Is the keying material  
derived from a TLS master key using a keying material exporter  
suitable for channel binding as well, if used for key confirmation?   
If a higher-level application wishes to do additional authentication  
and bind the endpoints of that authentication to the endpoints of the  
TLS connection, should one use key confirmation with keying material  
exporters or something from TLS channel binding?

Thanks,

Douglas

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 5 Nov 2009 10:59:00 -0600

> exporters or something from TLS channel binding?

TLS connections[0] form a secure channel.  They also optionally provide
authentication, and are often run on top of other TLS connections[1].
Therefore there's two ways in which channel binding is interesting for
TLS: a) you should be able to get channel binding information _from_ a
TLS channel to bind into authentication at a higher layer, b) you should
be able to provide channel binding information to TLS to bind into its
handshake.

The two ways in which TLS relates to channel binding are two sides of
the same coin, but we need to look at them separately.

At this point I recommend reading RFC5056.

For (a), see draft-altman-tls-channel-bindings-07.

For (b), see the recent draft-solinas-tls-additional-prf-input-00.

You ask if we could use the TLS exporter to create a channel binding for
TLS, and the answer is: no, or at least not by itself.  You could use
the exporter to construct a channel binding that is sufficiently secure,
but why re-invent the wheel?  You really should use one of the channel
binding types for TLS defined in draft-altman-tls-channel-bindings-07.

The TLS exporter, as defined in draft-ietf-tls-extractor-07, is this:

          PRF(SecurityParameters.master_secret, label,
              SecurityParameters.client_random +
              SecurityParameters.server_random +
              context_value_length + context_value
              )[length]

Compare that to the Finished message computation:

         PRF(master_secret, finished_label, Hash(handshake_messages))
            [0..verify_data_length-1];

Both use the TLS PRF() and master secret.  But only the second
formulation also binds all the handshake messages.  The second
formulation therefore protects all of the negotiation involved
in a TLS exchange, while the first protects only the key
exchange, and that makes the Finished message construction more
appropriate as a channel binding for TLS than the exporter.

This has been much, much discussed in the past in the context of
draft-altman-tls-channel-bindings, including one or more proposals that
we use the TLS PRF instead of Finished messages.  That we need to use a
Finished message or a similar construction is and has been the consensus
for a long time.

[0]  There's been a lot of confusion lately about what is meant when one
     says "TLS connection".  I use it to mean "the TLS state created by
     a TLS hello, handshake and finished message exchange".

[1]  This is called re-negotiation.  The client initiates one TLS
     exchange, then either the client or server initiates a second
     exchange.  This is basically TLS-over-TLS, though to be pedantic,
     the inner connection can replace the outer, so it's not quite
     TLS-over-TLS, but the inner TLS connection's handshake does happen
     with the protection of the outer TLS connection's record layer.

     As you surely know by now, there's no real binding between the
     inner and outer TLS connections -- the only possible binding is for
     the client to enforce that the server uses a cert in both TLS
     connections, and that it uses the _same_ cert in both TLS
     connections.

     From EKR's message about the re-negotiation MITM vulnerability, I
     gather that TLS will be modified to provide a direct channel
     binding that both, the client _and_ server can enforce for the
     nested TLS case.  IMO that's the correct solution, though in the
     very short-term the quickest, most interoperable solution is for
     clients to do as described in above.

Nico
--