Subject: [TLS] TLS Export Channel Binding

From: "Sam Whited" <[email-masked]>
Date: Fri, 01 May 2020 10:12:29 -0400

Hi all,

I'm in need of a channel binding mechanism that works for TLS 1.3, but
as far as I can tell there isn't one. I've thrown together a document
defining a mechanism using RFC 5705 which I believe meets all of the
requirements for good channel binding.

Is anyone aware of work already being done in this area (I saw the token
binding stuff, but that's a lot more complicated and browser-focused
than a simple channel binding mechanism and work appears to have
stalled), and if not would the TLS WG be interested in such a document?

Thanks,
Sam

P.S. Note that I also sent this question to the KITTEN WG because I
     wasn't sure where this would belong.

-- 
Sam Whited

---

From: Jonathan Hoyland <[email-masked]>
Date: Fri, 1 May 2020 17:00:27 +0100

Hi Sam,

I believe TLS Exporters are what you are looking for.
https://www.rfc-editor.org/rfc/rfc8446.html#section-7.5

Exporters allow you to produce a key that is a bound to a particular
channel i.e. TLS session.

Regards,

Jonathan

On Fri, 1 May 2020 at 15:13, Sam Whited <[email-masked]> wrote:

> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: "Sam Whited" <[email-masked]>
Date: Fri, 01 May 2020 12:08:27 -0400

Hi Jonathan,

> https://www.rfc-editor.org/rfc/rfc8446.html#section-7.5

Thanks for the follow up. That is indeed what the channel binding type
I've created uses. Would the TLS working group be interested in
standardizing such a document?

I've gone ahead and uploaded my initial draft that I threw together here
in case you're interested:

https://datatracker.ietf.org/doc/draft-whited-tls-channel-bindings-for-tls13/

—Sam

---

From: Jonathan Hoyland <[email-masked]>
Date: Fri, 1 May 2020 19:08:57 +0100

Hi Sam,

I think the idea is that any unique¹ exporter _is_ an RFC
5056-compliant channel binding.

Maybe I'm missing something, but I don't see what your draft adds?
If someone wants to construct a channel binding then they agree with their
peer on a context and a label, and use that to construct an exporter key.

If they mix that key into the key schedule of some other protocol then that
second protocol is bound to the TLS session².

If they want to pick the label "EXPORTER-Channel-Binding" and the empty
context, then that's already covered by the spec.

Is the idea to reserve the string for some specific use? If so, then the
suggested string is far to general, as it describes _any_ use of the
interface.

What do you see as the difference between an Exporter key and a channel
binding?

Regards,

Jonathan

1. I'm assuming an exporter is unique within a given TLS session iff the
given label and context are unique.
2. Unless the second protocol does something stupid like leak the TLS
session's master secret.

---

From: "Sam Whited" <[email-masked]>
Date: Fri, 01 May 2020 14:16:28 -0400

On Fri, May 1, 2020, at 14:08, Jonathan Hoyland wrote:
> Maybe I'm missing something, but I don't see what your draft adds? If
> someone wants to construct a channel binding then they agree with
> their peer on a context and a label, and use that to construct an
> exporter key.

The draft just registers a method of using it with the IANA Channel
Binding Types registry so that you can negotiate and use exported keying
material in eg. SCRAM based SASL auth. Right now if I wanted to use EKM
for channel binding, what would I negotiate (ie. what would I set the p
field of a gs2 header to in SASL based auth?)

> Is the idea to reserve the string for some specific use? If so, then
> the suggested string is far to general, as it describes _any_ use of
> the interface.

Yes, that's the idea. This registers the "tls-exporter" channel binding
type in the registry, and the label EXPORTER-Channel-Binding to use with
it. This is supposed to be a generic channel binding type that can be
used to negotiate channel binding when multiple are available, eg. if
the server supports both tls-unique (the last TLS finished message) and
exporter data, we need an identifier to decide that we want to use
exporter data. That also means having a label that we can associate with
this context.

I'd be happy to change the name if the consensus is that this is too
general, but I didn't think it made sense to make this SASL or <other
auth system> specific.

—Sam

---

From: Jonathan Hoyland <[email-masked]>
Date: Mon, 4 May 2020 14:14:42 +0100

Hi Sam,

If you wanted to use a SCRAM based SASL auth then you could pick
`p=SCRAM-SHA256-PLUS`, or any other very specific IANA-registered
string, and update the SCRAM RFC to require that string with TLS 1.3.
You actively don't want for the same channel binding to be an input to
multiple different protocols (or even the same protocol but with different
parameters) because it opens the door to confusion attacks.

I've only skimmed the SCRAM RFC, but it might make sense to include
`client-first-message` and `server-first-message` as context to the
exporter interface, because it seems that the channel binding isn't needed
until the `client-final-message`.
The idea is to use the transcript to bind the channel binding to the
negotiation of SCRAM parameters, and thus allow you to define a single
"TLS-SASL-SCRAM" string (or whatever makes sense), rather than have one for
each possible set of parameters.
Obviously you'd need to think some more about whether that was actually
secure, but at first glance it seems like a reasonable approach.

Channel bindings that bind both the underlying channel and the higher-level
protocol make more sense to me that channel bindings that only identify the
underlying channel, because you don't have to worry about the (potentially
pathological) behaviours of other users of the binding.

Regards,

Jonathan

---

From: "Sam Whited" <[email-masked]>
Date: Mon, 04 May 2020 10:39:45 -0400

On Mon, May 4, 2020, at 09:14, Jonathan Hoyland wrote:
> exporter interface, because it seems that the channel binding isn't
> needed until the `client-final-message`. The idea is to use the
> transcript to bind the channel binding to the negotiation of SCRAM
> parameters, and thus allow you to define a single "TLS-SASL-SCRAM"
> string (or whatever makes sense), rather than have one for each
> possible set of parameters. Obviously you'd need to think some more
> about whether that was actually secure, but at first glance it seems
> like a reasonable approach.

I had originally written a long-ish reply about why we couldn't make
this SCRAM specific, but I've just realized after going back and
looking at the spec and one of my own implementations that I was
completely wrong.

This is a great idea, and I believe would be secure since the client-first-
message and server-first-message will contain their respective random
nonces. A malicious client or server *could* slip some arbitrary text
into either message, but if I understand TLS exporters security
properties correctly this should not pose a problem and the export data
should still be indistinguishable from random noise to someone without
the TLS master secret (a sanity check by an expert on this statement
would be appreciated).

I have updated the draft with these changes: https://datatracker.ietf.org/doc/draft-whited-tls-channel-bindings-for-tls13/

I'm still not entirely clear if this would be a better draft for the
KITTEN WG or this one. If we update the SCRAM RFCs I think it may be
better to go through KITTEN, but I'm not sure that they'll want to take
that work on. I'll ask. Any advice here would be appreciated since I
know almost nothing about IETF policy or procedures.

Thanks for your feedback!

—Sam

---

From: Alexey Melnikov <[email-masked]>
Date: Mon, 4 May 2020 16:22:41 +0100

Hi Jonathan,

On 04/05/2020 14:14, Jonathan Hoyland wrote:
> multiple different protocols (or even the same protocol but with 
> different parameters) because it opens the door to confusion attacks.

Can you elaborate on what you are trying to protect from?

Historically channel bindings were constant once TLS negotiation was 
complete (they could change if TLS renegotiation happens). So they never 
depended on what was sent over the protocol above TLS.

> needed until the `client-final-message`.

"the channel binding isn't needed until the `client-final-message`" is 
correct. Can you elaborate on what is problematic with this?

> "TLS-SASL-SCRAM" string (or whatever makes sense), rather than have 
> one for each possible set of parameters.
> Obviously you'd need to think some more about whether that was 
> actually secure, but at first glance it seems like a reasonable approach.
>
> Channel bindings that bind both the underlying channel and the 
> higher-level protocol make more sense to me that channel bindings that 
> only identify the underlying channel, because you don't have to worry 
> about the (potentially pathological) behaviours of other users of the 
> binding.
>
Best Regards,

Alexey

---

From: Alexey Melnikov <[email-masked]>
Date: Mon, 4 May 2020 16:25:10 +0100

Hi Sam,

> know almost nothing about IETF policy or procedures.

IETF doesn't really have rules about situations like this.

I think doing this in KITTEN makes more sense, as long as feedback is 
asked on the TLS mailing list. KITTEN is more likely to have interest to 
drive this work to completion. Having said that, if there is strong 
interest in getting this done in TLS, that would be fine with me.

Best Regards,

Alexey

---

From: Alexey Melnikov <[email-masked]>
Date: Mon, 4 May 2020 16:44:41 +0100

Hi Sam,

On 04/05/2020 15:39, Sam Whited wrote:
> I have updated the draft with these changes: 

In the Introduction of your draft you are referencing RFC 5705, which 
can't be used with TLS 1.3. Instead you should reference Section 7.5 of 
RFC 8446.

Best Regards,

Alexey

---

From: "Sam Whited" <[email-masked]>
Date: Mon, 04 May 2020 11:57:20 -0400

On Mon, May 4, 2020, at 11:44, Alexey Melnikov wrote:
> can't be used with TLS 1.3. Instead you should reference Section 7.5
> of RFC 8446.

Fixed on my local copy [1]. Thanks for your feedback!

—Sam

[1]: https://rfcs.samwhited.com/draft-whited-tls-channel-bindings-for-tls13-02.html

---

From: Jonathan Hoyland <[email-masked]>
Date: Mon, 4 May 2020 17:56:38 +0100

Hi Alexey

> Can you elaborate on what you are trying to protect from?
If two protocols use the same channel binding there is a risk that the
messages from one can be confused with the messages from the other.
This might happen accidentally, or an adversary might be able to forge one
from the other.
If you wanted to do a formal analysis of the of the security of TLS 1.3 +
SCRAM then a generic binding means you have to factor in what every other
possible protocol might do.
If you use a unique and specific channel binding then the analysis is far
easier and can be a lot more robust (this assumes a global coordinator of
unique strings, such as IANA).
>From an analysis perspective it's easier to rule out classes of attacks
than to consider all possible interactions between all users of the
interface, some of which you won't know about, or perhaps haven't even been
invented yet.

> depended on what was sent over the protocol above TLS.
Yeah, I think the design in TLS 1.3 is much more robust, especially from a
formal analysis perspective.
By constructing channel bindings based on the parameters negotiated over
the top you get a belt-and-braces design.
If you have a contributive channel binding [1] then if the security of
either the underlying protocol (in this case TLS) or the over-the-top
protocol (in this case SCRAM) fails, then the channel binding guarantees
the authentication still happened properly.
Consider the case where an adversary publishes the server's private key to
twitter.
If you have a contributive channel binding then if the SCRAM handshake
succeeds you could be sure that you were talking to the real server, and
weren't being MITMed.
If you don't base the channel binding on the parameters agreed in the
upper  protocol it's possible (in theory) that an adversary could compute
two SCRAM handshakes that appear to succeed, but that actually agree
different parameters.
In this particular case it's not obvious how that could happen, but it's
easy to think up pathological examples, and [1] has a few concrete examples
too.

> correct. Can you elaborate on what is problematic with this?

Sorry if I was unclear, there's nothing problematic with this per se.
It's just that the channel binding can't be dependent on itself, but
including everything that precedes the channel binding just seems like an
easy win, esp. as (in this case) that includes all parameter negotiation.

Jonathan

[1] Bhargavan, Karthikeyan, Antoine Delignat-Lavaud, and Alfredo Pironti.
"Verified Contributive Channel Bindings for Compound Authentication." *NDSS*.
2015.
https://prosecco.gforge.inria.fr/personal/karthik/pubs/verified-channel-bindings-ndss15.pdf

---

From: "Sam Whited" <[email-masked]>
Date: Sat, 09 May 2020 08:34:17 -0400

Hi all,

After thinking about this a little more, I think we should keep the
draft generic and not make it SCRAM specific. While I generally agree
with Jonathan's defense-in-depth strategy, there is also value in having
a direct replacement for tls-unique that can be substituted in
everywhere tls-unique is used to make the upgrade path easier. If we do
that, we can always add a SCRAM specific channel binding type later on
and slowly start the process of upgrading the n-places that use tls-
unique with protocol specific binding types.

Thoughts?

—Sam

On Mon, May 4, 2020, at 12:56, Jonathan Hoyland wrote:
> Hi Alexey
>
> On Mon, 4 May 2020 at 16:23, Alexey Melnikov
> <[email-masked]> wrote:
> > Hi Jonathan,
> >
> >  > string, and update the SCRAM RFC to require that string with TLS
> >  > 1.3. You actively don't want for the same channel binding to be
> >  >      an input to multiple different protocols (or even the same
> >  >      protocol but with different parameters) because it opens the
> >  >      door to confusion attacks.
> >
> This might happen accidentally, or an adversary might be able to forge
> one from the other. If you wanted to do a formal analysis of the of
> the security of TLS 1.3
> + SCRAM then a generic binding means you have to factor in what every
>   other possible protocol might do. If you use a unique and specific
>   channel binding then the analysis is far easier and can be a lot
>   more robust (this assumes a global coordinator of unique strings,
>   such as IANA). From an analysis perspective it's easier to rule out
>   classes of attacks than to consider all possible interactions
>   between all users of the interface, some of which you won't know
>   about, or perhaps haven't even been invented yet.
>
> >  Historically channel bindings were constant once TLS negotiation
> >  was complete (they could change if TLS renegotiation happens). So
> >  they never depended on what was sent over the protocol above TLS.
> >
>
> Yeah, I think the design in TLS 1.3 is much more robust, especially
> from a formal analysis perspective. By constructing channel bindings
> based on the parameters negotiated over the top you get a belt-and-
> braces design. If you have a contributive channel binding [1] then if
> the security of either the underlying protocol (in this case TLS) or
> the over-the-top protocol (in this case SCRAM) fails, then the channel
> binding guarantees the authentication still happened properly.
> Consider the case where an adversary publishes the server's private
> key to twitter. If you have a contributive channel binding then if the
> SCRAM handshake succeeds you could be sure that you were talking to
> the real server, and weren't being MITMed. If you don't base the
> channel binding on the parameters agreed in the upper protocol it's
> possible (in theory) that an adversary could compute two SCRAM
> handshakes that appear to succeed, but that actually agree different
> parameters. In this particular case it's not obvious how that could
> happen, but it's easy to think up pathological examples, and [1] has a
> few concrete examples too.
> >  > I've only skimmed the SCRAM RFC, but it might make sense to
> >  > include `client-first-message` and `server-first-message` as
> >  > context to the exporter interface, because it seems that the
> >  > channel binding isn't needed until the `client-final-message`.
> >
> >  "the channel binding isn't needed until the `client-final-message`"
> >  is correct. Can you elaborate on what is problematic with this?
>
> including everything that precedes the channel binding just seems like
> an easy win, esp. as (in this case) that includes all parameter
> negotiation.
>
> >
> >  > The idea is to use the transcript to bind the channel binding to
> >  > the negotiation of SCRAM parameters, and thus allow you to define
> >  > a single "TLS-SASL-SCRAM" string (or whatever makes sense),
> >  > rather than have one for each possible set of parameters.
> >  > higher-level protocol make more sense to me that channel bindings
> >  > that only identify the underlying channel, because you don't have
> >  > to worry about the (potentially pathological) behaviours of other
> >  > users of the binding.
> >  >
> >  Best Regards,
> >
> >  Alexey
> >
> Regards,
>
> Jonathan
>
> [1] Bhargavan, Karthikeyan, Antoine Delignat-Lavaud, and Alfredo
>     Pironti. "Verified Contributive Channel Bindings for Compound
>     Authentication." *NDSS*. 2015.

-- 
Sam Whited