Re: [TLS] Refactoring the negotiation syntax
Eric Rescorla <ekr@rtfm.com> Wed, 13 July 2016 17:22 UTC
Return-Path: <ekr@rtfm.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 7395C12D16C for <tls@ietfa.amsl.com>; Wed, 13 Jul 2016 10:22:21 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.599
X-Spam-Level:
X-Spam-Status: No, score=-2.599 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=rtfm-com.20150623.gappssmtp.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9WQUt44JlIUT for <tls@ietfa.amsl.com>; Wed, 13 Jul 2016 10:22:19 -0700 (PDT)
Received: from mail-yw0-x233.google.com (mail-yw0-x233.google.com [IPv6:2607:f8b0:4002:c05::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id EA50C12B03C for <tls@ietf.org>; Wed, 13 Jul 2016 10:22:18 -0700 (PDT)
Received: by mail-yw0-x233.google.com with SMTP id i12so49111830ywa.1 for <tls@ietf.org>; Wed, 13 Jul 2016 10:22:18 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rtfm-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=qTuYnYmTIeByBQXqQAwhMpWgNWiWeKYH8MAypHLRVuE=; b=lEGFFvINtfUp7F1DNzClnjq4RjjJNw+COE4G8rNXtrutMzKPO64JBrTjiDESEX1vrN FVXwMRLuZiUNRGuf7oZeTyFtcL+VJyMTkJ5k78AlAfOfEjkq7DvE4mehsiMvNC4eYPzc 5eKXH4Q2eu2vSyOs3dd12/rSquflNpzyZWv3dtEWqkelBUSI/3w5LXS2F1s6p4mP/x3r 7PdgyIDGhQ4CMW9Yh2+HUuwWKnvvTG9ZPTTmjJyZHQLZDvBDb3VXjPYFBjUfyn/Lwm7F eINoJVLoSolUmRa8loszPOeftOQV3VeHNXDNNE2rwm+drnBF6HsQS7jSZYaMllaLJ2yl PLiA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=qTuYnYmTIeByBQXqQAwhMpWgNWiWeKYH8MAypHLRVuE=; b=QLKgyWr34LQ59xKHP8G8rs2Dt+tM5ux/rdpFV2rx3iAp+f4xnpZjaFWbzCTvX3m4dt W5OMIpprfqSps18o9pe4MqgVlKFNVwZyjZlH6YJVkd+YJf9cnXTpnir+8DL8CO3RHxGd +J8TWw4VareH+7DTQj91C45Am0BvzHUtwZ0UPTfidUScTcqyAGkSwelH4U2Uzlg13Z8v acB+F5z2vK7vXQZ0ElX2FrjRcUrr/jz/L3zrcDE+Nj7tNSzSDj/07mXbIrs9nClemNIS xvR0pj54X9eOTZFPmJib5NbINZCR0eZniIeCjvg45xmnzqIgtNGesQQurCorQfH01MX7 VMyw==
X-Gm-Message-State: ALyK8tL7IYrHk/7TstP/ancoQBSrHq63VYI6PddmTDzeRxLKPQ+LmxvgJUQELxsZQDUNBD8GM3X7n1W4tYFs9g==
X-Received: by 10.129.39.200 with SMTP id n191mr7413330ywn.16.1468430537955; Wed, 13 Jul 2016 10:22:17 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.129.152.13 with HTTP; Wed, 13 Jul 2016 10:21:38 -0700 (PDT)
In-Reply-To: <CABcZeBPh+BGtnBb725G+YzZZzdSUh5KtViqh3Z339apSKRpygg@mail.gmail.com>
References: <CABcZeBPh+BGtnBb725G+YzZZzdSUh5KtViqh3Z339apSKRpygg@mail.gmail.com>
From: Eric Rescorla <ekr@rtfm.com>
Date: Wed, 13 Jul 2016 10:21:38 -0700
Message-ID: <CABcZeBOBT+UYj0d-O0mP=ho2ZbhBEDAQqQyNYHJExGKmLZK5dg@mail.gmail.com>
To: "tls@ietf.org" <tls@ietf.org>
Content-Type: multipart/alternative; boundary="001a1141826a97c8fc053787a0d9"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/SErXA_YGM8tlvn5AE7panLT1vXw>
Subject: Re: [TLS] Refactoring the negotiation syntax
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 13 Jul 2016 17:22:21 -0000
Replying to myself: We obviously don't *need* to do this. We have working implementations that use the current syntax, so we know it can be done, and "finished is a feature", so we have to balance against that whether this is a better syntax. OTOH, if you think this is a worse syntax, then it's easy. :) -Ekr On Wed, Jul 13, 2016 at 10:12 AM, Eric Rescorla <ekr@rtfm.com> wrote: > Hi folks, > > There have been a lot of discussions about whether we should try to > refactor cipher-suite negotiation to be less monolithic in the cipher > suite. I've generally been on the "no" side of that on cost/benefit > grounds as well as not quite seeing how it would fit into the rest > of the infrastructure. However, now that we're starting to get full > implementations, and it's becoming clearer how the new elements > (principally PSK-resumption and key_shares) interact with cipher > suites, I've started to think that in fact we may be able to clean > things up. One proposal for this is below [0]. I know this is > pretty late in the process, but if we do want this change it's > better to do it now. > > I'm sure we'll need to discuss this in Berlin, but in the meantime, > fire away. > > > The basic idea here is to factor out the TLS 1.3 negotiation into three > mostly orthogonal axes. > > - Symmetric cipher/PRF -- indicated by the cipher suite list as in TLS 1.2 > - Key exchange -- indicated by the key_shares and pre_shared_key extensions > - Authentication -- indicated the signature_algorithms and pre_shared_key > extensions > > A proposal for how to do this is below. See the end for other options, > caveats, etc. > > > If we take PSK out of the picture, this gives us a very simple structure: > > - The client offers a set of key_shares and the server picks one that it > likes [1]. > - The client offers a list of signature_algorithms and the server picks > a certificate/key that matches that list and signs with it. > > In other words, we just eliminate the redundancy with the cipher suite > indications. This leaves is with the question of how to handle the > existing TLS 1.2 cipher suites. We can either assign new cipher suites > or say that any cipher suite with *_aead_alg_hash means that we > support aead_alg_hash. Matter of taste. > > > PSK is handled by extending the concept of PSK flags that we already > have in NewSessionTicket to also include uses of PSKs where you > indicate the way in which you are using the PSK (or want it to be > used). There a bunch of ways to encode this. I'll give you the one I > mostly prefer below and then a one that's a smaller change but I think > a little less elegant at the end [note #4]. > > First, we replace the flags word of the different KE modes for the > ticket with lists of code points, as below: > > enum { > psk_ke(0), // PSK key exchange > psk_dhe_ke(1), // PSK + DHE key exchange > (255) > } PskKeModes; > > And then add new code points for being able to use the PSK with and > without signatures (from the server). We had pretty rough consensus in > B-A that we needed this mode and [draft-thomson-tls-0rtt-and-certs-01] > is part of the motivation for this idea. > > enum { > psk_auth(0), // PSK only > psk_sign_auth(1), // PSK + a signature (as in draft-thomson) [5] > (255) > } PskAuthModes; > > This gives us the following NewSessionTicket message where we have > replaced the flags word with two (potentially ordered) lists: > > struct { > uint32 ticket_lifetime; > PskAuthModes auth_modes<1..255>; > PskKeModes ke_modes<1..255>; > TicketExtension extensions<2..2^16-2>; > opaque ticket<0..2^16-1>; > } NewSessionTicket; > > We now need a way to indicate that the server will do 0-RTT (previously > in the flags word) so we add a new 0-RTT extension: > > struct { > uint32 ticket_age_add; > } TicketEarlyDataInfo; > > This has two nice properties: > > - You don't need to provide ticket_age_add when you don't do 0-RTT > (and it is silly if you don't). > - It exercises this extension mechanism, which is good for future-proofing. > > > PreSharedKeyExtension becomes: > > struct { > PskAuthMode auth_modes<1..255>; > PskKeModee ke_modes<1..255>; > opaque identity<0..2^16-1>; > } PskIdentity; > > struct { > select (Role) { > case client: > PskIdentity identities<2..2^16-1>; > case server: > PskAuthMode auth_mode; > PskKeMode ke_mode; > uint16 selected_identity; > } > } PreSharedKeyExtension; > > The way to interpret these is as follows: > > - With each identity, the client indicates to the server which modes > it can be used with. > - When the server responds with an identity, it tells you how it > used it. > > You might ask why you need the server to indicate what it did. The > reason is that we would like the client to know in advance (at the > time of the ServerHello) whether the server has sent > Certificate/CertificateVerify rather than having to figure it out from > what messages the server sends. The ke_mode field is redundant > (because you also infer it from the server key_shares) but I added it > for parity. > > I haven't implemented this yet (am going to try to take a crack at that > before Berlin) but I believe based on experience with the NSS > negotiation that it will be simpler. I know it removes a bunch of odd > edge cases which have accumulated over the years, but maybe it adds > others. > > -Ekr > > > BONUS MATERIAL > 0. I've discussed this with and/or borrowed ideas from Richard Barnes, > David Benjamin, Karthik Bhargavan, Dave Garrett, Nick Sullivan, Martin > Thomson, and others. Thanks to those guys, but blame me if you think > this is bad. > > 1. The other major encoding option here is to have dummy > group/signature_algorithm indicators that tell you whether you can use > a pure PSK. When I and others discussed this, the consensus was that > that was less clean. > > 2. One question that comes up at the same time is whether we should > allow multiple key shares to be used, which is a structure that this > makes pretty easy. Basically, the server would just supply as many > counter-shares as it wanted and then we'd need a defined order for how > they were inserted into the key schedule. This feature would be nice > for enabling post-quantum, but probably better to just define > <PQ-Algorithm + Curve> code points. > > 3. Note that because of this PSK-PRF interaction, PSK isn't totally > orthogonal with AEAD/PRF. I.e., you cannot use the same PSK with > HKDF-SHA256 and HKDF-SHA384 if you want to be on the cryptographic > fairway, but I think it should be easy enough to filter out the cipher > suites to make that work. > > 4. The other major alternative is just to use the flags bits. So we > would extend and generalize the flags as shown below. > > enum { > early_data(1), > dhe_psk_ke(2), > psk_ke(4), > psk_auth(8), // New (no server cert) > sig_psk_auth(16) // New (sign with server cert) > } PskUsageFlags; > > These new flags have the expected meaning, namely: > > psk_auth The server will do connections with just > PSK authentication (equivalent to PSK now) > > sig_psk_auth The server will do connections with PSK > plus signature (not currently specified). > > > Then we update the PreSharedKeyExtension as follows: > > struct { > uint32 usage_flags; > opaque identity<0..2^16-1>; > } PskIdentity; > > struct { > select (Role) { > case client: > PskIdentity identities<2..2^16-1>; > case server: > uint32 usage_flags; // New (one from each category) > uint16 selected_identity; > } > } PreSharedKeyExtension; > > The idea here is: > > - The client indicates how each PSK can be used (by flags, which > need to be a subset of the ticket flags). > - The server can pick a PSK and indicate how it was actually > used. > > For instance, if the client wants to do PSK w/ ECDHE it would indicate > dhe_psk_ke. If it only wants PSK it would indicate psk_ke. If it was > willing to do both, it would indicate the bitwise OR. > > Similarly, if the client wants PSK for auth, it would indicate > psk_auth. If it wants the server to sign, it indicates sig_psk_auth, > and so on (indicating neither is silly because it makes the key > unusable). > > By contrast, the server just sets the bits that it actually used. > I.e., if it sets psk_auth, that means it won't be signing and > there is no Certificate/CertificateVerify. OTOH if it sets > sign_psk_auth, that means it will be signing and there will > be a Certificate/CertificateVerify. > > This leaves early data. As above, the client uses the early_data > bit to indicate that the PSK was used to encrypt early data > (obviously, this can just be one key) and the server uses it to > indicate that it accepted early data. ticket_age needs to go in > its own extension, but that's easy enough. > > > 5. Note: this would allow for modes where the server signs over a PSK > handshake with no DHE at all. The resumption_ctx mechanism is intended > to ensure that that is OK, but we'd need to confirm with analysis. > >
- Re: [TLS] Refactoring the negotiation syntax Ilari Liusvaara
- Re: [TLS] Refactoring the negotiation syntax Eric Rescorla
- Re: [TLS] Refactoring the negotiation syntax Kyle Rose
- Re: [TLS] Refactoring the negotiation syntax Ilari Liusvaara
- Re: [TLS] Refactoring the negotiation syntax Kyle Rose
- Re: [TLS] Refactoring the negotiation syntax Ilari Liusvaara
- Re: [TLS] Refactoring the negotiation syntax Ilari Liusvaara
- Re: [TLS] Refactoring the negotiation syntax Eric Rescorla
- Re: [TLS] Refactoring the negotiation syntax Ilari Liusvaara
- Re: [TLS] Refactoring the negotiation syntax Eric Rescorla
- Re: [TLS] Refactoring the negotiation syntax Dave Garrett
- Re: [TLS] Refactoring the negotiation syntax Eric Rescorla
- [TLS] Refactoring the negotiation syntax Eric Rescorla