Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify AEAD-based protection of cleartext packets #693

Closed
ekr opened this issue Jul 21, 2017 · 49 comments
Closed

Specify AEAD-based protection of cleartext packets #693

ekr opened this issue Jul 21, 2017 · 49 comments
Assignees

Comments

@ekr
Copy link
Collaborator

ekr commented Jul 21, 2017

Based on discussion in Prague:

  • (Provisionally) algorithm is AES-GCM
  • Key should be derived from (1) client connection ID and (2) a fixed key baked into the QUIC version
  • Otherwise standard AEAD
@ianswett
Copy link
Contributor

I think this obsoletes #554

@mikkelfj
Copy link
Contributor

I have no major issue with AES-GCM and the benefit is that it is already there - but please also consider AES-CMAC - it is much lighter and does the job for clear text - and would thus be more version neutral - e.g. implementations are not forced to carry GCM machinery if they want other crypto in a specific version. Notably, middle-boxes would have an easier time.

https://tools.ietf.org/html/rfc4493
https://tools.ietf.org/html/rfc4494

@ekr
Copy link
Collaborator Author

ekr commented Jul 21, 2017

The rationale for GCM was that Ian wanted to encrypt the plaintext.

@ianswett
Copy link
Contributor

Yes, I'm worried about the day when QUIC version N+1 wants to support TLS > 1.3 and I don't want to deal with all the old middleboxes that have ossified QUIC==TLS 1.3.

@mikkelfj
Copy link
Contributor

ah I see

@huitema
Copy link
Contributor

huitema commented Jul 30, 2017

How does this apply to the Version Negotiation packet?

@ekr
Copy link
Collaborator Author

ekr commented Jul 30, 2017

I had in mind the same way. You would use the client's version there too

@ekr
Copy link
Collaborator Author

ekr commented Jul 30, 2017

This is assigned to me, but I'm waiting on doing it until @martinthomson does some refactoring. Trying to avoid merge conflicts

@huitema
Copy link
Contributor

huitema commented Jul 30, 2017

So for version negotiation, we would have:

  1. Client sends an Initial packet with version unknown to server.
  2. Server sees only the header and cannot decrypt the content because it does not know the version specific key.
  3. Server replies with version negotiation packet, which is not encrypted.

Correct?

@ekr
Copy link
Collaborator Author

ekr commented Jul 30, 2017

Ian was suggesting that the version-specific key be predictable from the version, so no, you would just decrypt it.

@davidben
Copy link

If it's predictable, won't the middleboxes just derive the key, decrypt it, and then do their usual ossifying thing?

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Jul 30, 2017 via email

@huitema
Copy link
Contributor

huitema commented Jul 31, 2017

I don't see the point of going to AEAD encryption if the key is entirely predictable from the packet. Doing so would not allow us to replace AES-GCM by something else in the future. It would also be a mere speed bump for ossifying NATs. I would rather stick to FNV1A-64.

I see the point of a key that is specified as part of the document specifying a specific version. That mean that a NAT developer could not decrypt the data for version X without having read the spec for version X. It is not an iron-proof guarantee, because the NAT developers may decide to just read the part of the spec that specifies the key and ignore the other parts. But people who do that can be pointed out as misbehaving. The document that specifies the version would also specify the algorithm, which will allow for evolution.

But then, that means that servers receiving an packet with the wrong version will only be able to understand the packet header.

@martinthomson
Copy link
Member

The idea here is to make the key (and algorithm) version-specific. Then you absolutely can't pretend to support a version you don't understand.

The risk, as always, is that NATs latch on to one version and block all other versions. But that's preferable to the range of subtle and noxious stuff that they might otherwise do.

@ekr, if the server sends a Version Negotiation packet, it can't know which version to choose - the only version it knows that the client supports is one that it doesn't. If I'm right, then Version Negotiation has to be unencrypted. I think that for consistency we should define version 0 for this purpose with a fixed algorithm, which might be f(x)=x.

@huitema
Copy link
Contributor

huitema commented Jul 31, 2017

@martinthomson, I think we agree. But I don't think we need the version 0 hack. The base spec says that the clear text packets are integrity protected, but it does not mention anything of the kind for the version negotiation packet. The way I read the spec, the version negotiation packets are not protected at all.

This means that the version can be spoofed. But then, the transport parameters repeat the content and results of the renegotiation, and the spoofing will be detected. So we are probably fine without any protection.

@martinthomson
Copy link
Member

:) The only hazard here is what you get when the Version Negotiation is indistinguishable from Internet-noise. I think that we can and should just decide that we're comfortable with that.

@huitema
Copy link
Contributor

huitema commented Jul 31, 2017

Yes, we should be OK with the "Internet Noise" issue. Version Negotiation is sent to clients. It will only be accepted if the connection ID and Sequence Number match what the client expects. That, and the IP source address and UDP source port...

@ekr
Copy link
Collaborator Author

ekr commented Jul 31, 2017

There are two objectives here:

  1. Preventing off-path attackers from being able to inject packets. AEADing all packets with a key derived from the client CONN_ID does this (regardless of whether or not you mix in some version-specific key). It also doesn't actually matter for this whether you encrypt, but it's convenient because it means no new transform.

  2. Preventing middleboxes from trying to read the content of versions they don't know. Having a strong defense against this obviously requires an unpredictable per-version key, but Ian seemed to think there was some value in a predictable key and I'm fine with going along, but i'm also fine not doing this at all.

WRT to the various suggestions made above:
It's important that VN be protected from off-path attackers as well because otherwise attackers can inject it and cause connection failure just as with other packets (remember: all of this is about protecting injection of packets pre-crypto, because we need to have a negotiation protocol that protects against full on-path attackers). Thus, it needs to also be tied to the ClientInitial and the whole point of this issue is to do that in a generic way rather than in a per-packet specific way, as @huitema proposes directly above. Hence, the AEAD (or, as I originally proposed, HMAC). So, I don't think it can be unprotected.

I think the right approach here is a variant of @martinthomson's suggestion above.

  1. Use a version-specific key label that's unpredictable and baked into the version when it's published. I.e., Key = HKDF(ConnID, version_label)
  2. VN always uses some predictable label (say, all 0s)

The impact of this would be that:

  1. VN is integrity protected, as expected and you can always send VN
  2. Servers which receive packets for versions they totally don't know will send VN even if the packet is actually invalid. this seems acceptable because any attacker can produce valid packets and elicit a VN.

@huitema
Copy link
Contributor

huitema commented Jul 31, 2017

Works for me.

@janaiyengar
Copy link
Contributor

I like ekr's proposed approach. The VN packet currently echoes pieces of the client packet, which seems unnecessary with the "encrypted" VN. We could clean that up too if we want, but that should be a separate issue to deal with once this one is done..

@martinthomson
Copy link
Member

I agree with Jana, adding Server Stateless Retry to that bucket of things that we might re-examine after this.

@MikeBishop
Copy link
Contributor

The risk of an encrypted VN packet is that it moves the specifics of encrypting at least that packet into the "can't change between versions" realm. Do we want to codify something that requires keeping old moldy crypto around just to express what QUIC versions you support that no longer use that crypto?

Whatever we do, Version Negotiation winds up being a one-off -- if we're consistent now, then it's a one-off when we eventually change. If we don't encrypt, it's a one-off from the start, which might be more honest. Though I agree the protection against off-path attackers is also interesting.

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Aug 2, 2017 via email

@janaiyengar
Copy link
Contributor

Mike, Ryan: Are you suggesting that we treat VN as a special snowflake (which it undoubtedly is) and leave it unencrypted with an FNV-128a hash? We have nominal protection against off-path attackers already with a connection ID echo, so that's covered without the encryption.

I am sympathetic to the idea of not wanting to have old crypto sitting around just to handle VN packets. I'd be happy to treat VN packets as special, and leave them unencrypted. I don't think I care enough about bit flips with the VN packet to need an FNV hash for this alone... we'll still have the (weak) UDP checksum to cover that.

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Aug 2, 2017 via email

@janaiyengar
Copy link
Contributor

SGTM.

@ekr
Copy link
Collaborator Author

ekr commented Aug 3, 2017 via email

@janaiyengar
Copy link
Contributor

janaiyengar commented Aug 4, 2017 via email

@ekr
Copy link
Collaborator Author

ekr commented Aug 4, 2017 via email

@janaiyengar
Copy link
Contributor

Sorry - I thought I had responded to this, but I dropped it. Yes, your plan SGTM.

@martinthomson martinthomson added -transport design An issue that affects the design of the protocol; resolution requires consensus. labels Aug 14, 2017
@martinthomson martinthomson added this to Handshake in QUIC Aug 31, 2017
@janaiyengar janaiyengar added the needs-discussion An issue that needs more discussion before we can resolve it. label Sep 13, 2017
@janaiyengar
Copy link
Contributor

From discussion in Seattle: AEAD protect all cleartext packet types, leave Stateless Reset and Version Negotiation as they are. EKR to produce PR for AEAD protection.

@janaiyengar janaiyengar added editor-ready and removed design An issue that affects the design of the protocol; resolution requires consensus. needs-discussion An issue that needs more discussion before we can resolve it. labels Oct 5, 2017
@larseggert
Copy link
Member

Could @ekr in the process also add some text that makes it clear(er) that Stateless Reset and Version Negotiation are special? See #840.

martinthomson added a commit that referenced this issue Oct 10, 2017
@mcmanus
Copy link
Contributor

mcmanus commented Oct 10, 2017 via email

@RyanTheOptimist
Copy link
Contributor

RyanTheOptimist commented Oct 10, 2017 via email

@huitema
Copy link
Contributor

huitema commented Oct 10, 2017

But if we remove packet number randomization, do we start with SN=0 or SN=1?

@ianswett
Copy link
Contributor

  1. We really should ban 0. It's a pain.

@janaiyengar
Copy link
Contributor

Ha, interesting. Removing randomization SGTM. And yes, please, please SN=1. 0 is special.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests