Subject: Public reset PR

From: Eric Rescorla <[email-masked]>
Date: Wed, 23 Nov 2016 14:36:26 -0800

https://github.com/quicwg/base-drafts/pull/20

Hi folks,

I just posted a PR to flesh out the Public Reset packet, which is
somewhat underspecified in the current document.

First, let me lay out what I think are the desirable properties, with
"requirements" having *s and "desiderata" marked with "+". Opinions
may vary on the line here.

1. Allow one side to lose connection state (e.g., reboot) and still
   terminate the connection (*)
2. Prevent off-path attackers from terminating the connection (*)
3. Don't require a public key operation for each termination (*)
4. Prevent on-path attackers from terminating the connection (+)
5. Allow on-path elements to determine when a connection was (+)
   terminated [I've marked this with "+" but I recognize that
   some might mark it with "-"]

#5 seems like the most questionable property, but here's my rationale.
Because network elements (Firewalls, NATs, etc.) can detect that a
packet is a Public Reset from the header, they may opt to destroy
their internal state upon receiving one. If the Public Reset isn't
verifiable by them, then they may just opt to destroy the state based
on seeing something with the right header.  This opens up an on-path
attack where the attacker forges a Public Reset and thus blocks
traffic at the middlebox even though the connection is still live at the
endpoints.

The design in this PR is based on hash preimages [1]. At the beginning
of the connection the server supplies a Verifier value which is
computed as the Hash of a proof value, like so:

   Verifier = Hash(Proof).

The Verifer is established at the beginning of the connection and
stored with the connection record. When you want to reset a
connection, you simply send a reset packet that contains Proof. The
peer verifies that Hash(Proof) == Verifier and if so tears down the
connection. As is this fulfills 2, 3, and 4 and optionally 5 if you
expose the RVV to on-path elements during the handshake (or even
periodically during the connection).

This isn't completely stateless, but you can get away without
per-connection state by computing the per-connection Proof from the
conn_id and some secret stored on the server. I.e.,

   Proof_conn = PRF(K_m, conn_id)

Note that because Proof_conn does not itself leak K_m, seeing one
connection reset doesn't allow resetting other connections. K_m
can be stored and can survive reboots.

I've tried to mimic the style of the document as best I can but I'm
sure there's some stuff wrong here.

Comments welcome.
-Ekr

[1] Note that the QUIC Design Document and Rationale describes a
slightly simpler mechanis that uses the same state-handling trick I
describe here but uses what sounds like a MAC instead of a hash
preimage. If you think that requirement #5 is a bad requirement then
that's probably a better design. Happy to write this up if it's the WG
consensus.

---

From: Ryan Hamilton <[email-masked]>
Date: Wed, 23 Nov 2016 14:49:07 -0800

Sounds great to me. I agree that having public reset packets visible to
middleboxes but unverifiable by them is problematic.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Nov 2016 09:55:03 +1100

So this seems to only be feasible for a server.  That's something that
needs to be articulated somehow.  That means that clients are unable
to construct a public reset.

FWIW, there is currently no way to carry the verifier value.  We'll
need to work on that.

---

From: Ryan Hamilton <[email-masked]>
Date: Wed, 23 Nov 2016 15:07:12 -0800

> to construct a public reset.

​Currently, public reset packets are only sent from servers to client. But
that being said, if we wanted clients to be able to send public reset
packets, could not the client perform the same operation described here?

---

From: Mike Bishop <[email-masked]>
Date: Wed, 23 Nov 2016 23:10:55 +0000

I semi-disagree with one element of your requirements list.  It seems valuable to enable on-path network infrastructure (indistinguishable from on-path attackers) to notify the peers of an intention to interrupt something about the connection.  At the least, we need to discuss that point rather than assuming it.

Sent from my Windows 10 phone

From: Martin Thomson<mailto:[email-masked]>
Sent: Wednesday, November 23, 2016 5:55 PM
To: Ryan Hamilton<mailto:[email-masked]>
Cc: Eric Rescorla<mailto:[email-masked]>; IETF QUIC WG<mailto:[email-masked]>
Subject: Re: Public reset PR

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 23 Nov 2016 15:22:22 -0800

> packets, could not the client perform the same operation described here?

I think that would work fine, though we would require the client to supply
the Verifier which, as Martin says, is another problem we'd need to solve.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 23 Nov 2016 15:31:40 -0800

On Wed, Nov 23, 2016 at 3:10 PM, Mike Bishop <[email-masked]>
wrote:

> I semi-disagree with one element of your requirements list.  It seems
> valuable to enable on-path network infrastructure (indistinguishable from
> on-path attackers) to notify the peers of an intention to interrupt
> something about the connection.  At the least, we need to discuss that
> point rather than assuming it.
>
As you say, this is a requirements question. It seems like there are three
possible points in
this design space:

- Only allow endpoint resets
- Allow both endpoint and on-path resets but they are distinguishable
- On-path resets are indistinguishable from endpoint resets

So the WG needs to decide on this.

As far as technical design, the way you do an on-path-only reset is to have
it contain
some value that was in the packet being reset and have that be high
entropy. The
good news is that all the encrypted packets are already high entropy (we
may need
to deal with the handshake packets a bit) so you can just include a digest
of the
packet you are rejecting from. If you want to have both kinds of reset and
have
them be distinguishable, you could use a type bit, or have both values
present
but the Proof be all zeroes or something...

-Ekr

> *From: *Martin Thomson <[email-masked]>
> *Sent: *Wednesday, November 23, 2016 5:55 PM
> *To: *Ryan Hamilton <[email-masked]>
> *Cc: *Eric Rescorla <[email-masked]>; IETF QUIC WG <[email-masked]>
> *Subject: *Re: Public reset PR
>
>

---

From: Brian Trammell <[email-masked]>
Date: Thu, 24 Nov 2016 15:44:10 +0100

> On 24 Nov 2016, at 00:31, Eric Rescorla <[email-masked]> wrote:
> 
> On Wed, Nov 23, 2016 at 3:10 PM, Mike Bishop <[email-masked]> wrote:
> As you say, this is a requirements question. It seems like there are three possible points in
> this design space:
> 

Note that since an on-path device that's also forwarding packets has the ability to drop the packets, "allow only endpoint resets" simply has the effect of making on-path resets invisible to the endpoints, while increasing the amount of state an on-path device needs to keep in order to "enforce" its reset.

> - On-path resets are indistinguishable from endpoint resets

This seems undesirable.

> As far as technical design, the way you do an on-path-only reset is to have it contain
> some value that was in the packet being reset and have that be high entropy. The
> good news is that all the encrypted packets are already high entropy (we may need
> to deal with the handshake packets a bit) so you can just include a digest of the
> packet you are rejecting from. If you want to have both kinds of reset and have
> them be distinguishable, you could use a type bit, or have both values present

I like this proposal -- it makes on-path and endpoint resets distinguishable as well as making on-path resets verifiable by on-path devices as well as endpoints, without requiring any durable state in the on-path device.

Thanks, cheers,

Brian

> From: Martin Thomson
> To: Ryan Hamilton
> Cc: Eric Rescorla; IETF QUIC WG

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 24 Nov 2016 11:51:56 -0800

On Thu, Nov 24, 2016 at 6:44 AM, Brian Trammell <[email-masked]> wrote:

> Note that since an on-path device that's also forwarding packets has the
> ability to drop the packets, "allow only endpoint resets" simply has the
> effect of making on-path resets invisible to the endpoints, while
> increasing the amount of state an on-path device needs to keep in order to
> "enforce" its reset.
>

This is true for on-path devices that are forwarding, but other devices
(e.g., on wireless networks) can be on-path but not forwarding. For such
devices, making it difficult for them to force a reset might provide some
security benefit to the endpoint.

> > - On-path resets are indistinguishable from endpoint resets

I agree.

> I like this proposal -- it makes on-path and endpoint resets
> distinguishable as well as making on-path resets verifiable by on-path
> devices as well as endpoints, without requiring any durable state in the
> on-path device.
>

I'll await the judgement of the chairs and the editors as to how they want
this PR to look and adjust accordingly.

-Ekr

---

From: "Christian Huitema" <[email-masked]>
Date: Thu, 24 Nov 2016 21:39:47 -1000

On Thursday, November 24, 2016 9:52 AM, Eric Rescorla wrote:
>
> This is true for on-path devices that are forwarding, but other devices (e.g., on wireless 
> networks) can be on-path but not forwarding. For such devices, making it difficult for
> them to force a reset might provide some security benefit to the endpoint.

Yes. The "false reset" denial of service attack from a "man on the side" is a real problem. But then, the flip side of that is the "rebooted server". It just rebooted, it doesn't remember the previous connections, and it receives a QUIC packet for a connection it does not recognize. That's the standard justification for a TCP RST. Notice that in that scenario, the "rebooted server" does not know anything that the "man on the side" does not also know. What do we want? Do we agree that the "rebooted server" is a very rare scenario, which we should not try optimize? 

-- Christian Huitema

---

From: Brian Trammell <[email-masked]>
Date: Fri, 25 Nov 2016 11:05:26 +0100

> On 25 Nov 2016, at 08:39, Christian Huitema <[email-masked]> wrote:
> 
> Yes. The "false reset" denial of service attack from a "man on the side" is a real problem.

The big difference between a man-on-the-side reset in TCP and a man-on-the-side reset with the space of mechanisms we're currently discussing is that in the latter, the endpoint(s) can distinguish a man on the side from an endpoint-initiated reset. This makes endpoint defense against path resets more feasible than in the TCP case (e.g., by quickly re-establishing the session; in a future multipath environment, perhaps on a different interface).

> But then, the flip side of that is the "rebooted server". It just rebooted, it doesn't remember the previous connections, and it receives a QUIC packet for a connection it does not recognize. That's the standard justification for a TCP RST. Notice that in that scenario, the "rebooted server" does not know anything that the "man on the side" does not also know. What do we want? Do we agree that the "rebooted server" is a very rare scenario, which we should not try optimize?

I don't know how rare the rebooted server case is.

But, similar: a server sends a public reset for a spoofed garbage packet. This would be a reflection vector (without amplification), as well as a minor resource DoS on the target (which would need to compute the digest of the garbage packet to generate the public reset). If there's value in an endpoint sending an equivalent-to-on-path public reset, then it would need to have safeguards (rate limiting, etc.) to reduce its usefulness as an attack vector.

Cheers,

Brian

---

From: Alexis La Goutte <[email-masked]>
Date: Fri, 25 Nov 2016 11:23:30 +0100

On Fri, Nov 25, 2016 at 11:05 AM, Brian Trammell <[email-masked]> wrote:

> (e.g., on wireless
> The big difference between a man-on-the-side reset in TCP and a
> man-on-the-side reset with the space of mechanisms we're currently
> discussing is that in the latter, the endpoint(s) can distinguish a man on
> the side from an endpoint-initiated reset. This makes endpoint defense
> against path resets more feasible than in the TCP case (e.g., by quickly
> re-establishing the session; in a future multipath environment, perhaps on
> a different interface).
>
> > But then, the flip side of that is the "rebooted server". It just
> rebooted, it doesn't remember the previous connections, and it receives a
> QUIC packet for a connection it does not recognize. That's the standard
> justification for a TCP RST. Notice that in that scenario, the "rebooted
> server" does not know anything that the "man on the side" does not also
> know. What do we want? Do we agree that the "rebooted server" is a very
> rare scenario, which we should not try optimize?
>
> There is always the case how there is a load balance and send to a another
server not ?

> But, similar: a server sends a public reset for a spoofed garbage packet.
> This would be a reflection vector (without amplification), as well as a
> minor resource DoS on the target (which would need to compute the digest of
> the garbage packet to generate the public reset). If there's value in an
> endpoint sending an equivalent-to-on-path public reset, then it would need
> to have safeguards (rate limiting, etc.) to reduce its usefulness as an
> attack vector.
>
> Cheers,
>
> Brian
>
>
>
> > -- Christian Huitema
> >
> >
> >
> >
>
>

---

From: Brian Trammell <[email-masked]>
Date: Fri, 25 Nov 2016 12:59:59 +0100

hi Alexis,

> On 25 Nov 2016, at 11:23, Alexis La Goutte <[email-masked]> wrote:
> 
> There is always the case how there is a load balance and send to a another server not ?

How QUIC interacts with load balancers is something we'll have to discuss in more detail, but I suppose that the load balancer would have enough information from the 5-tuple and connection ID to not misdirect QUIC packets to servers that don't have appropriate state; i.e. this shouldn't happen in the normal case.

Cheers,

Brian

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 25 Nov 2016 06:16:57 -0800

On Thu, Nov 24, 2016 at 11:39 PM, Christian Huitema <[email-masked]>
wrote:

> Yes. The "false reset" denial of service attack from a "man on the side"
> is a real problem. But then, the flip side of that is the "rebooted
> server". It just rebooted, it doesn't remember the previous connections,
> and it receives a QUIC packet for a connection it does not recognize.
> That's the standard justification for a TCP RST. Notice that in that
> scenario, the "rebooted server" does not know anything that the "man on the
> side" does not also know. What do we want? Do we agree that the "rebooted
> server" is a very rare scenario, which we should not try optimize?
>

As you say, there is a tradeoff here that there doesn't seem to be an ideal
solution for.

This particular design is intended to allow servers to have no
per-connection state and only
a single fixed persistent value, which by hypothesis they already know how
to do because
it can store the private key [0]. So it's an attempt to cater to the
rebooted server case byt
not optimize for it.

-Ekr

[0] Note: there is a solution which *only* requires private key storage,
namely digitally
sign each PR packet, but that obviously has negative performance
consequences. You
can ameliorate this by batching signatures (e.g., by using a Merkle hash
tree) but the
consensus of the group which discussed this previously was that that was
too complicated
for people to actually be willing to implement.

-- Christian Huitema

---

From: "Christian Huitema" <[email-masked]>
Date: Fri, 25 Nov 2016 11:19:14 -1000

On Friday, November 25, 2016 4:17 AM, Eric Rescorla wrote:
>
> As you say, there is a tradeoff here that there doesn't seem to be an ideal solution for.
>
> This particular design is intended to allow servers to have no per-connection state and only
> a single fixed persistent value, which by hypothesis they already know how to do because
> it can store the private key [0]. So it's an attempt to cater to the rebooted server case byt
> not optimize for it.

Your solution works as long as the server receiving the errant packet knows the value sent in the initial handshake. That's probably OK for most use case, but if the same proof is used for multiple connections there is an obvious replay attack.

The other issue that I have with the design is the interaction between handshake protocol and packet layer. I think of the public reset as a connection-wide packet layer message, logically "stream zero". The crypto handshake is on stream 1. The formal API has the handshake logic passing keys to the global "packet layer". Logically, the same API should provision the reset proof.

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 25 Nov 2016 13:54:37 -0800

On Fri, Nov 25, 2016 at 1:19 PM, Christian Huitema <[email-masked]>
wrote:

> Your solution works as long as the server receiving the errant packet
> knows the value sent in the initial handshake. That's probably OK for most
> use case, but if the same proof is used for multiple connections there is
> an obvious replay attack.

Correct. In this case, the Proof is intended to be 1:1 with the connection
ID (using the PRF trick to avoid storing a pile of proof values). So I
believe that this PR has that property as long as connection-IDs are random.

> The other issue that I have with the design is the interaction between
> handshake protocol and packet layer. I think of the public reset as a
> connection-wide packet layer message, logically "stream zero". The crypto
> handshake is on stream 1. The formal API has the handshake logic passing
> keys to the global "packet layer". Logically, the same API should provision
> the reset proof.
>

That was my intent. Namely to have it be in a TLS extension which is then
provided to the packet layer.

-Ekr

---

From: Jim Roskind <[email-masked]>
Date: Sat, 26 Nov 2016 10:26:51 -0800

FWIW: I like the proposal.

The major (ab)use case I was trying to deal with in the QUIC Rationale
involved nation states that could trivially reset connections.  My hope was
that the somewhat authenticated reset packets would "raise the level of
effort" for intermediaries that wanted to deny connection service.

It is obvious that a full-blown intermediary, such as a router, can deny
service by consistently dropping packets, but at least such methodical
dropping was much more effort than a mere TCP RST transmission.  In
addition, a mere RST attack leaves plausible deniability, as it is hard to
tell who sent the RST, and why, while packet dropping can be (more) easily
blamed on a specific node.

I had not considered trying to notify middle boxes of termination, though I
have discussed having "more trusted" middle boxes that could report the
fact that packets in a sequence were missing (never arrived at a way
point).  Given my experiences and experimentation with NATs and such, it
seemed reasonable that the current time-out (LRU?) status quo might well
continue, and QUIC would instead "work around" such unbindings.  Is there a
lot of real world pressure to do better?

I'm trying to understand your 5 listed cases.  Am I correct that in your
terms, "on path" attackers are folks that can listen to traffic, as well as
send, while "off path" attackers must send in the blind?  What do you call
a "full blown intermediary," that can drop or mutate/replace packets?

Thanks,

Jim

Opinions expressed are mine, and not that of my company.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Nov 2016 11:09:50 -0800

On Sat, Nov 26, 2016 at 10:26 AM, Jim Roskind <[email-masked]> wrote:

> I had not considered trying to notify middle boxes of termination, though
> I have discussed having "more trusted" middle boxes that could report the

I'm not sure. I have heard a number of people suggest that this would be a
good idea, but it's not clear whether it really would be. FWIW, that was
not my motivation for property #5. Rather, my motivation was that it seemed
difficult to prevent middleboxes which aren't really attackers (e.g., your
local NAT) from seeing the public reset and deciding to blow away their NAT
bindings even though they can't validate it. So, it seemed better to let
them validate it so that the could keep state if it didn't validate.

With that said, as I write this, it occurs to me that there's an other
alternative. Instead of sending a verifier value in the initial handshake,
just send a high entropy secret value R (128 bits is plenty). In order to
generate a public reset, generate a QUIC encrypted packet which is
formatted correctly but where the payload is:

  R || Pad

Where the Pad is randomly generated and of arbitrary length. Then the
receiver can check the first 16 bytes of each packet against R and if it
matches, then it knows it's a reset [0]. I.e., the algorithm is:

- If first bytes are R, tear down the connection
- If not, decrypt the packet.
  - If decryption is successful, deliver the packet
  - If decryption is unsuccessful, drop the packet.

Note that it might still independently be a good idea to allow middleboxes
to see the public reset, but I think that this demonstrates that that's a
policy choice about the design of the protocol, not something mandated by
limitations in what we can design.

> send, while "off path" attackers must send in the blind?
>

Correct.

> What do you call a "full blown intermediary," that can drop or
> mutate/replace packets?
>

That seems like a special case of on-path attacker. I think your term is
fine.

-Ekr

[0] I had previously considered encrypting the public reset with the shared
key, but this requires trial decryption on the receiver side, which is much
less efficient than this algorithm.

Thanks,

---

From: "Christian Huitema" <[email-masked]>
Date: Sat, 26 Nov 2016 15:30:55 -1000

On Saturday, November 26, 2016 9:10 AM, Eric Rescorla wrote:
>
> ... (discussion of security properties and alternative design)...
>
> Note that it might still independently be a good idea to allow middleboxes to see the 
> public reset, but I think that this demonstrates that that's a policy choice about the 
> design of the protocol, not something mandated by limitations in what we can design.

On limit of the pre-image design is that intermediaries cannot do the verification. Well, they could if the option was sent in clear text, and if they parsed the corresponding packet. But then, attackers could send spoofed handshake messages that contain a fake verifier. They won't fool the client, but they can confuse the intermediaries. I suppose we could try piling turtles to try prevent that, but we are better off assuming that intermediaries won't be able to tell spoofed reset from the true ones. 

Can the client really detect the spoofed reset? Not sure. The attacker can probably play games with TTL so the spoofed packet is dropped before the client sees it. 

The better defense is probably to "qualify" the reset, and tell intermediaries to treat it as a soft signal. Instead of clearing the connection context, intermediaries could just drop the "expiration timer" of the context to a short value. Make that value not too short, at least several RTT. If a new packet from the server arrives at the intermediary, reset the expiration timer to a natural value. If the client receives a spoofed reset, it can send a ping to the server and trigger a response.

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Nov 2016 17:57:41 -0800

On Sat, Nov 26, 2016 at 5:30 PM, Christian Huitema <[email-masked]>
wrote:

> On limit of the pre-image design is that intermediaries cannot do the
> verification. Well, they could if the option was sent in clear text, and if
> they parsed the corresponding packet.

Yes, that's correct; it's the assumption of this design that the would do
so. If you think that they won't then there are much simpler designs (like
the one in the message you are responding to).

-Ekr

> But then, attackers could send spoofed handshake messages that contain a
> fake verifier. They won't fool the client, but they can confuse the
> intermediaries. I suppose we could try piling turtles to try prevent that,
> but we are better off assuming that intermediaries won't be able to tell
> spoofed reset from the true ones.
>
> Can the client really detect the spoofed reset? Not sure. The attacker can
> probably play games with TTL so the spoofed packet is dropped before the
> client sees it.
>
> The better defense is probably to "qualify" the reset, and tell
> intermediaries to treat it as a soft signal. Instead of clearing the
> connection context, intermediaries could just drop the "expiration timer"
> of the context to a short value. Make that value not too short, at least
> several RTT. If a new packet from the server arrives at the intermediary,
> reset the expiration timer to a natural value. If the client receives a
> spoofed reset, it can send a ping to the server and trigger a response.
>

---

From: "Christian Huitema" <[email-masked]>
Date: Sat, 26 Nov 2016 16:17:40 -1000

On Saturday, November 26, 2016 3:58 PM, Eric Rescorla wrote:

> On Sat, Nov 26, 2016 at 5:30 PM, Christian Huitema <mailto:[email-masked]> wrote:
>> On limit of the pre-image design is that intermediaries cannot do the verification. Well, 
>> they could if the option was sent in clear text, and if they parsed the corresponding packet. 
>
> Yes, that's correct; it's the assumption of this design that the would do so. If you think that 
> they won't then there are much simpler designs (like the one in the message you are 
> responding to).

Do we really want to ask intermediaries to go parse options inside the TLS handshake inside stream 1? That does not strike me as too desirable. I am concerned of the potential there for ossification. I have visions of delaying the move to TLS 4.1 a couple years from now because intermediaries really expect TLS 1.3. 

Then, there is the potential for spoofing. If the verifier text is sent in clear text, it can be spoofed. What if the man on the side sends a new Server Hello, with a verifier option of its own choosing? OK, I suppose that if the spoofed packet wins the race with the authentic Server Hello, the client will just fail the connection. The spoofed Server Hello becomes the new weapon of the censors... But even if the spoofed packet does not win the race, how many intermediaries would just be fooled and accept the new verifier, and of course the spoofed public reset that follows?

I like the simpler design in which only the client can tell whether the public reset is authentic.

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Nov 2016 18:23:47 -0800

On Sat, Nov 26, 2016 at 6:17 PM, Christian Huitema <[email-masked]>
wrote:

> verification. Well,
> Do we really want to ask intermediaries to go parse options inside the TLS
> handshake inside stream 1? That does not strike me as too desirable. I am
> concerned of the potential there for ossification. I have visions of
> delaying the move to TLS 4.1 a couple years from now because intermediaries
> really expect TLS 1.3.
>
> Then, there is the potential for spoofing. If the verifier text is sent in
> clear text, it can be spoofed. What if the man on the side sends a new
> Server Hello, with a verifier option of its own choosing? OK, I suppose
> that if the spoofed packet wins the race with the authentic Server Hello,
> the client will just fail the connection. The spoofed Server Hello becomes
> the new weapon of the censors... But even if the spoofed packet does not
> win the race, how many intermediaries would just be fooled and accept the
> new verifier, and of course the spoofed public reset that follows?
>

Hmm... I would ordinarily expect that clients would respond to a bogus CH
(e.g., one that's malformed or that
doesn't cryptographically verify) by hanging up the connection, so I'm not
sure that this would make the situation
that much worse.

I like the simpler design in which only the client can tell whether the
> public reset is authentic.
>

Well, there are actually two designs:

1. The middlebox can see the public reset but not verify it
2. The middlebox cannot distinguish the public reset from other packets.

I am concerned about #1 for the reasons indicated previously and I
originally did not see how to do #2
without fairly significant client-side complexity. Now that I do, it does
seem like it's probably the leading
option absent some convincing policy argument that middleboxes should be
able to see these packets.

-Ekr

---

From: Martin Duke <[email-masked]>
Date: Sat, 26 Nov 2016 19:57:26 -0800

To combine some of the ideas in this thread. I think we should have two
different kinds of Resets:

1) A message that is authenticated/encrypted as coming from the peer
endpoint. The receiver of this kind of reset MUST tear down the connection
immediately, and should only happen with connections that the sender
regards as fully established.

This could be encrypted if it includes whatever mechanism the WG eventually
chooses to signal to middleboxes that CONNECTION_CLOSE is hidden in the
encryption. A much simpler mechanism would be to sign a plaintext Public
Reset with the sender's private key, which might not be too expensive in
the context of an existing connection.

2) An unauthenticated reset, which might be due to a rebooted peer, reset
during initial handshake, generated by a middlebox, etc.

- The receiver of this message MAY (SHOULD?) retain connection state for
some period of time to see if additional non-reset packets arrive from the
peer. Additional incoming resets MUST NOT restart this reset timer.

- I am open to some sort of restriction on continuing to send packets while
retaining state, but there are tradeoffs here.

A middlebox might apply the timer to all public resets. If we choose the
private-key option, it at least has the option of properly verifying the
reset. This is probably a better resource decision than preserving
connection state.

Martin

On Sat, Nov 26, 2016 at 6:23 PM, Eric Rescorla <[email-masked]> wrote:

>> Do we really want to ask intermediaries to go parse options inside the
>> TLS handshake inside stream 1? That does not strike me as too desirable. I
>> am concerned of the potential there for ossification. I have visions of
>> Then, there is the potential for spoofing. If the verifier text is sent
>> in clear text, it can be spoofed. What if the man on the side sends a new

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Nov 2016 20:09:23 -0800

> regards as fully established.

Unless I misunderstand, this is what CONNECTION_CLOSE already is.

> This could be encrypted if it includes whatever mechanism the WG
> eventually chooses to signal to middleboxes that CONNECTION_CLOSE is hidden
> in the encryption. A much simpler mechanism would be to sign a plaintext
> Public Reset with the sender's private key, which might not be too
> expensive in the context of an existing connection.
>

CONNECTION_CLOSE is already covered under the traffic key. This is easier
and more efficient than signing it. It also works from the client to the
server when the client does not have a key pair.

> - I am open to some sort of restriction on continuing to send packets
> while retaining state, but there are tradeoffs here.
>

This seems to implicitly assume that on-path elements should be able to
terminate the connection with a single packet. That seems like an open
policy question for the WG. We should probably try to decide that before
designing mechanisms to achieve it.

-Ekr

>> doesn't cryptographically verify) by hanging up the connection, so I'm
>> not sure that this would make the situation
>> that much worse.
>>
>>

---

From: Martin Duke <[email-masked]>
Date: Sat, 26 Nov 2016 20:23:54 -0800

> Unless I misunderstand, this is what CONNECTION_CLOSE already is.
CONNECTION_CLOSE is only sent, according to the latest draft, when all
streams have been properly closed. It is the equivalent of the FIN flag in
a TCP connection, to the best of my knowledge. It is not the same thing as
the authenticated/encrypted public reset we're discussing here.

> designing mechanisms to achieve it.

As we've already established, an on-path forwarder can already block a
connection by simply dropping packets. This is simply a cleaner way to
handle it.

What the timer does is address eavesdroppers. If I'm at the coffee shop
with you, I can send unauthenticated Public Resets to try to terminate your
connection, but if the real server responds within the timeout these resets
will have no effect. This is a significant improvement on TCP, in my
opinion.

Martin

>>> Hmm... I would ordinarily expect that clients would respond to a bogus
>>> CH (e.g., one that's malformed or that
>>> without fairly significant client-side complexity. Now that I do, it
>>> does seem like it's probably the leading

---

From: Ryan Hamilton <[email-masked]>
Date: Sat, 26 Nov 2016 20:50:19 -0800

> the authenticated/encrypted public reset we're discussing here.

That is definitely not the intent of the spec. If it says that, then we
should fix it :) For example, CONNECTION_CLOSE is sent when an endpoint
detects an error. This causes the connection to be terminated regardless of
the number or status of open streams.​

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Nov 2016 21:39:11 -0800

> connection by simply dropping packets. This is simply a cleaner way to

I think the policy question is whether we wish to have a cleaner way to
handle it or whether we want to require on-path attackers to drop every
packet.

> will have no effect. This is a significant improvement on TCP, in my

Unless I'm missing something, the mechanism I proposed earlier today
(having a secret per-connection reset token which you use in place of the
ciphertext) also addresses this problem:

- No endpoint will accept a bogus public reset
- There is no externally visible signal of a public reset for innocent
middleboxes to process.

-Ekr

>>>> On Sat, Nov 26, 2016 at 6:17 PM, Christian Huitema <[email-masked]
>>>> > wrote:
>>>>
>>>>> Then, there is the potential for spoofing. If the verifier text is
>>>>> sent in clear text, it can be spoofed. What if the man on the side sends a
>>>>> new Server Hello, with a verifier option of its own choosing? OK, I suppose
>>>> option absent some convincing policy argument that middleboxes should
>>>> be able to see these packets.
>>>>
>>>> -Ekr
>>>>
>>>>
>>>>>
>>>>> -- Christian Huitema
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>

---

From: Martin Duke <[email-masked]>
Date: Sat, 26 Nov 2016 22:20:48 -0800

> handle it or whether we want to require on-path attackers to drop every
Merely dropping packets seems *more* malicious than resetting, because it
consumes more endpoint resources than it takes to drop the packets. The
purpose of the reset is to allow "legitimate" middlebox connection droppers
to free those resources while not enabling eavesdroppers or (of course)
off-path DoS.

> - There is no externally visible signal of a public reset for innocent

I guess I'm a little unclear as to the conditions of "the high entropy
secret value R". Perhaps you could confirm the order of operations, which I
construe as follows:

1) Endpoint computes a random secret for all connections for some period of
time, and stores this somewhere that will survive reboots.
2) For a new connection, the endpoint performs some operation with the
secret and the connection ID and includes the result R in an encrypted
handshake message.
3) Endpoint reboots.
4) When the peer sends another packet, the endpoint uses the connection ID
and its secret to figure R and make it the first 16 bytes of the cipher
text.
5) Peer has the original connection state and can correctly interpret the
reset.

Is that accurate?

>>>>> On Sat, Nov 26, 2016 at 6:17 PM, Christian Huitema <
>>>>> [email-masked]> wrote:
>>>>>
>>>>>> Do we really want to ask intermediaries to go parse options inside
>>>>>> the TLS handshake inside stream 1? That does not strike me as too
>>>>>> desirable. I am concerned of the potential there for ossification. I have
>>>>>> visions of delaying the move to TLS 4.1 a couple years from now because
>>>>>> intermediaries really expect TLS 1.3.
>>>>>>

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 27 Nov 2016 06:12:19 -0800

> to free those resources while not enabling eavesdroppers or (of course)

There is some debate about whether we in fact wish to have such a mechanism.

> 1) Endpoint computes a random secret for all connections for some period
> of time, and stores this somewhere that will survive reboots.

Yes.

-Ekr

>>>>>> Hmm... I would ordinarily expect that clients would respond to a
>>>>>> bogus CH (e.g., one that's malformed or that
>>>>>> doesn't cryptographically verify) by hanging up the connection, so
>>>>>> I'm not sure that this would make the situation
>>>>>> that much worse.
>>>>>>
>>>>>>

---

From: Kyle Rose <[email-masked]>
Date: Sun, 27 Nov 2016 10:19:44 -0500

> able to see these packets.

The problem with #2 (and related proposals to hide all connection state
from path elements) is that it will encourage middleboxes to continue
dropping all UDP state with a short timeout, requiring frequent keepalives
that (e.g.) consume battery in mobile devices.

Can not the TTL games Christian suggested for spoofed public resets be
avoided by a middlebox detecting smaller TTLs than previously seen for a
flow? If only packets likely to reach the destination were able to trigger
short state timeouts on middleboxes, then keepalive responses from the
destination seem like they would be sufficient to cover both off-path cases
and the man-on-the-side.

Kyle

---

From: "Christian Huitema" <[email-masked]>
Date: Sun, 27 Nov 2016 11:36:22 -1000

On Sunday, November 27, 2016 5:20 AM, Kyle Rose wrote:

> On Sat, Nov 26, 2016 at 9:23 PM, Eric Rescorla <mailto:[email-masked]> wrote:
>> I am concerned about #1 for the reasons indicated previously and I originally did not see how to do #2
>> without fairly significant client-side complexity. Now that I do, it does seem like it's probably the leading
>> option absent some convincing policy argument that middleboxes should be able to see these packets.

Responding to Eric: I am not sure that I understand how the second option works for the "rebooted server" scenario. Sure, the rebooted server can use a persistent secret to compose the magic prefix of the encrypted payload. But what about the sequence number? If it is not within the range that the client expect, the packet will be dropped before processing the encrypted payload.

> The problem with #2 (and related proposals to hide all connection state from path 
> elements) is that it will encourage middleboxes to continue dropping all UDP state 
> with a short timeout, requiring frequent keepalives that (e.g.) consume battery in 
> mobile devices.

This is the SPUD/PLUS argument. But then, there is a long history of protocols designed with high hopes of cooperation with middle boxes, without an actual result. So at a minimum we have to ensure that whatever solution is proposed does not introduce new attacks, or undue complexity.

> Can not the TTL games Christian suggested for spoofed public resets be avoided by 
> a middlebox detecting smaller TTLs than previously seen for a flow? If only packets 
> likely to reach the destination were able to trigger short state timeouts on 
> middleboxes, then keepalive responses from the destination seem like they would be
> sufficient to cover both off-path cases and the man-on-the-side.

I would rather not rely on middleboxes playing whack-a-mole with attackers. If we do anything at all, we should have some prescriptive behavior based for example on "shorter timer after reset".

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 27 Nov 2016 14:13:25 -0800

On Sun, Nov 27, 2016 at 1:36 PM, Christian Huitema <[email-masked]>
wrote:

> Responding to Eric: I am not sure that I understand how the second option
> works for the "rebooted server" scenario. Sure, the rebooted server can use
> a persistent secret to compose the magic prefix of the encrypted payload.
> But what about the sequence number? If it is not within the range that the
> client expect, the packet will be dropped before processing the encrypted
> payload.
>

Christian, can you elaborate on this? You are referring to the range of the
server's sequence numbers, right? If so, it seems like that's fixed by
modifying my algorithm to check the prefix as the first thing on an
incoming packet. But maybe I've missed something.

Thanks,
-Ekr

> from path
> This is the SPUD/PLUS argument. But then, there is a long history of
> protocols designed with high hopes of cooperation with middle boxes,
> without an actual result. So at a minimum we have to ensure that whatever
> solution is proposed does not introduce new attacks, or undue complexity.
>
> avoided by
> I would rather not rely on middleboxes playing whack-a-mole with
> attackers. If we do anything at all, we should have some prescriptive
> behavior based for example on "shorter timer after reset".
>
> -- Christian Huitema
>
>
>
>

---

From: "Christian Huitema" <[email-masked]>
Date: Sun, 27 Nov 2016 14:35:45 -1000

On Sunday, November 27, 2016 12:13 PM, Eric Rescorla wrote:
> On Sun, Nov 27, 2016 at 1:36 PM, Christian Huitema <mailto:[email-masked]> wrote:
>> ...
>> Responding to Eric: I am not sure that I understand how the second option works 
>> for the "rebooted server" scenario. Sure, the rebooted server can use a persistent 
>> secret to compose the magic prefix of the encrypted payload. But what about the 
>> sequence number? If it is not within the range that the client expect, the packet 
>> will be dropped before processing the encrypted payload.
>
> Christian, can you elaborate on this? You are referring to the range of the server's 
> sequence numbers, right?

Yes. If the rebooted server makes up a sequence number for the PR, the packet could be rejected by sequence number testing prior to the decryption attempt. Also, if a middlebox keeps track of sequence numbers it will discover that the PR is out of sequence, which somehow breaks the design goal that "The middlebox cannot distinguish the public reset from other packets."

> If so, it seems like that's fixed by modifying my algorithm to check the prefix as the
> first thing on an incoming packet. But maybe I've missed something.

That will work for the client, but an overactive middlebox could decide that "this packet does not look to have the right sequence number" and drop it. I suppose that we could work around that with a creative use of sequence number compression. Mostly.

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 27 Nov 2016 16:43:22 -0800

On Sun, Nov 27, 2016 at 4:35 PM, Christian Huitema <[email-masked]>
wrote:

> Yes. If the rebooted server makes up a sequence number for the PR, the
> packet could be rejected by sequence number testing prior to the decryption
> attempt. Also, if a middlebox keeps track of sequence numbers it will
> discover that the PR is out of sequence, which somehow breaks the design
> goal that "The middlebox cannot distinguish the public reset from other
> packets."
>
> That will work for the client, but an overactive middlebox could decide
> that "this packet does not look to have the right sequence number" and drop
> it. I suppose that we could work around that with a creative use of
> sequence number compression. Mostly.
>

Good point. So it's not totally indistinguishable. Ugh.

-Ekr

---

From: Martin Duke <[email-masked]>
Date: Sun, 27 Nov 2016 22:10:09 -0800

>> 4) When the peer sends another packet, the endpoint uses the connection
>> ID and its secret to figure R and make it the first 16 bytes of the cipher
>> text.

Alright, I think this is a good start but I have some concerns:

1) The scheme's security is dependent on truly random connection IDs,
because otherwise I can probe servers with garbage packets and certain
likely connection IDs and obtain the corresponding R values. In particular,
the current Chromium stateless reject model uses a server-recommended
connection ID for the next connection, so a eavesdropper could in theory
attack these connections. I have no idea if that "feature" will survive to
the final spec.

2) Someone raised the load balancer question earlier but I don't think it
ever got a satisfactory reply. There are many load balancer architectures,
but a common one assigns connections to servers based on some strategy
which is not necessarily a hash of the 4-tuple or 5-tuple.

This sets up pretty simple scenarios for failure: the server behind the
load balancer aborts the connection, which erases the state at the load
balancer, but the public reset is lost in the network. The next client
packet is assigned to a different server, which has a different secret and
cannot send a valid reset.

All that said, I don't have an alternative proposal that is not expensive
(e.g. signing with the private key).

Martin

---

From: Martin Duke <[email-masked]>
Date: Sun, 27 Nov 2016 22:15:47 -0800

Public Reset Packets do not have Packet Numbers. There would be no way for
a rebooted server to infer the correct packet number (as for sequence
number in TCP) because the ACK frame is encrypted, and may not be present
at all.

The draft format does include the number of the packet that triggered the
reset. This offers some protection against off-path attackers, but none
against eavesdroppers. My understanding was this field was not in the
proposal we are discussing.

Martin

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Nov 2016 01:25:59 -0500

On Mon, Nov 28, 2016 at 1:10 AM, Martin Duke <[email-masked]>
wrote:

>>> 5) Peer has the original connection state and can correctly interpret
>>> the reset.
>>>
>>> Is that accurate?
>>>
>>
>> Yes.
>>
>> -Ekr
>>
>
>

Good point. This requires the server to dictate at least part of the
connection ID and that it not be repeated. I think I'd just forgotten that
that was an undecided issue.
It does not require that it be random, however.

> cannot send a valid reset.

The assumption here is that all the devices behind the load balancer share
a seed for generating the reset secret.

-Ekr

>>>>>>>> without fairly significant client-side complexity. Now that I do,
>>>>>>>> it does seem like it's probably the leading

---

From: Jana Iyengar <[email-masked]>
Date: Mon, 28 Nov 2016 01:22:26 -0800

(Just catching up on this thread after my vacation.)

I really liked ekr's proposal for a completely private reset packet, until
Christian pointed out the hole in it. It seems clear now that you cannot
construct a (private) reset packet at a server when the server has no state
about the connection.

Given that, the best solution at this point seems to be the originally
proposed one, where the client is the only one that can tell that the reset
is authentic. Since the design leaves us with the possibility of spoofable
packets that could still confuse intermediaries, I like Christian's
suggestion of recommending a soft response of using a reduced timeout on a
reset packet (say, 5 seconds.)

As has been noted earlier, we do lose the ability to generate reset packets
when the connection ID is not present in the received packet, but that
seems reasonable since connection ID length is negotiated. If a peer wants
to be able to generate a reset packet, it SHOULD negotiate a full-length
connection ID on packets being sent to it.

Intermediary-generated reset packets are quite a different beast and should
be discussed separately, I think.

- jana

On Mon, Nov 28, 2016 at 3:25 PM, Eric Rescorla <[email-masked]> wrote:

>>>> 1) Endpoint computes a random secret for all connections for some
>>>> period of time, and stores this somewhere that will survive reboots.
>>>>>>>>>> Do we really want to ask intermediaries to go parse options
>>>>>>>>>> inside the TLS handshake inside stream 1? That does not strike me as too
>>>>>>>>>> Then, there is the potential for spoofing. If the verifier text
>>>>>>>>>> is sent in clear text, it can be spoofed. What if the man on the side sends
>>>>>>>>>> a new Server Hello, with a verifier option of its own choosing? OK, I
>>>>>>>>>> suppose that if the spoofed packet wins the race with the authentic Server
>>>>>>>>>> Hello, the client will just fail the connection. The spoofed Server Hello
>>>>>>>>>> becomes the new weapon of the censors... But even if the spoofed packet
>>>>>>>>>> does not win the race, how many intermediaries would just be fooled and
>>>>>>>>>> accept the new verifier, and of course the spoofed public reset that
>>>>>>>>>> follows?
>>>>>>>>>>
>>>>>>>>>

---

From: Brian Trammell <[email-masked]>
Date: Mon, 28 Nov 2016 10:40:59 +0100

> On 27 Nov 2016, at 22:36, Christian Huitema <[email-masked]> wrote:
> 
> This is the SPUD/PLUS argument. But then, there is a long history of protocols designed with high hopes of cooperation with middle boxes, without an actual result.

The difference here is that, unlike the litany of proposals in this "long history", the path-verifiable reset proposal (as in PR #20 and EKR's mail of 22:37 UTC on 23 Nov) is a design that interacts with very widely deployed behaviors: a verifiable endpoint-initiated connection termination provides equivalent assurance to an in-window FIN or RST in TCP that a connection is actually going away (depending on how many bits of the verifier are exposed), to move a NAT binding or firewall pinhole from "long-timeout" to "short-timeout" state.

This involves firewall and NAT vendors updating their boxes to use this new signal to drive behaviors already deployed, not to enable the deployment of entirely new behaviors. I suspect that a world with a quarter of the Web's traffic running over QUIC, not at all an unrealistic near-term scenario, would provide an incentive to update these devices. The main win for the endpoints here is, as Kyle and the -statefulness draft note, reducing the need over time for unproductive keepalive traffic or state-reestablishment logic. The main win for middlebox vendors is that their devices work better with QUIC.

> So at a minimum we have to ensure that whatever solution is proposed does not introduce new attacks, or undue complexity.

The proposal (in the PR) is IMO not unduly complex.

The most interesting attacks here are, as you noted, man-on-the-side attacks. Using 128 bits for the verifier and proof values make these impractical, though future versions will have to use more bits to defend against potential precomputation.

Cheers,

Brian

---

From: Martin Thomson <[email-masked]>
Date: Mon, 28 Nov 2016 20:47:45 +1100

> reset packet (say, 5 seconds.)

The downside there being that a spoofed reset will demand a
(semi-)urgent response if the endpoint wants to avoid the intermediary
timer from being reset.  That is, assuming that we don't go with a
design that can be verified by the intermediary.

I think that the ekr's design allows for an unspoofable reset without
the need to transition to short timer state if we accept that the
intermediary can validate the reset as well.  Sure, we can't hide it
(thanks Christian), but all we need is for the reset commitment to be
in the clear and an intermediary can choose to remember the value.

On 28 November 2016 at 20:40, Brian Trammell <[email-masked]> wrote:
> future versions will have to use more bits to defend against potential precomputation.

I am not aware of any method of precomputation, short of a complete
rainbow table, for hash preimages.

---

From: Kyle Rose <[email-masked]>
Date: Mon, 28 Nov 2016 11:09:14 -0500

> in the clear and an intermediary can choose to remember the value.

That's a lot of additional state to remember (128+ bits), and (if we're
talking about the public reset including the verifier preimage) a lot of
computation for boxes that normally just track NAT bindings and forward
packets to perform under an attack scenario. It seems unlikely middlebox
vendors are going to bother with the complexity or want to expose the
additional attack surface of CPU usage: they'll just keep the timeout short
all the time, which leaves us with the status quo around keepalives.

It seems like the burden should be on the endpoint being attacked to
mitigate the impact of public reset attacks, which the "no, I'm actually
still here" response does. Combined with BCP 38, actual off-path spoofed
public resets should be manageable; man-on-the-side results in increased
traffic in responses (potentially mitigated by an indication by the
endpoint of how long public resets should be ignored for that flow) instead
of increased CPU usage in verifying public reset packets at every middlebox
along the path; and on-path continues to be subject to every problem
on-path attackers can cause.

Kyle