Key updates
Martin Thomson <martin.thomson@gmail.com> Mon, 06 August 2018 05:55 UTC
Return-Path: <martin.thomson@gmail.com>
X-Original-To: quic@ietfa.amsl.com
Delivered-To: quic@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id BC977130EC1 for <quic@ietfa.amsl.com>; Sun, 5 Aug 2018 22:55:52 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2
X-Spam-Level:
X-Spam-Status: No, score=-2 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.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 Sfy9T2cw1vyH for <quic@ietfa.amsl.com>; Sun, 5 Aug 2018 22:55:50 -0700 (PDT)
Received: from mail-oi0-x22b.google.com (mail-oi0-x22b.google.com [IPv6:2607:f8b0:4003:c06::22b]) (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 A0130130E8B for <quic@ietf.org>; Sun, 5 Aug 2018 22:55:50 -0700 (PDT)
Received: by mail-oi0-x22b.google.com with SMTP id k12-v6so20072547oiw.8 for <quic@ietf.org>; Sun, 05 Aug 2018 22:55:50 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=iBDfb+eyhQ6fHkMeNW0QFh7tynj+IAinl40i9Am6GKQ=; b=IcsHu266Uv0UKNRrWykT/mcsoNuTIqSdChbRwPjkLCrwpwCthQog0KhMTnRWvsdqmU mpx2TshohgI4+CYF9es09PH64SRIgHaVN5jEMPB2XDBkK03Wq/Y/Wl62z6/E60jGRHjV hr35Z0V4yaAsmdABTrSz/BjmP7M7FFFzHhhBunFrFsJr0UzAKTOViba51fk62FuPyuWC sSAcL7QKqdXGo6gtilUD/g5QYfGXrYX39c2g7w8si8rlyCME8v9PX8WSOFvOwBC2fziD wgjAw8/WzfQx5OZEJ1ibKH3OvhKBuAvXcu4P2/4Py73nXw34D2vsLvebfGu3siM7EzXI YKnA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=iBDfb+eyhQ6fHkMeNW0QFh7tynj+IAinl40i9Am6GKQ=; b=lYrITxAsVzmcHFwkIk4PgTyy5UA81NiQb89Kq55nuv0Ka5lJWxd5/KMTMnDBTJLS9D 54OKOpqqHdUtqxV7Ie7lXeXi38cbAk6NgwuptJE5eDu56aIn42vHau/XaE+WyWBGStSB pi/prfjpc6INwj4oOYbRFltPmzfJP17qFWEit4t/VMf+XXiRsRzQTY/hn535Vhc3GcsE u+RBQbrwgOYvw2bkRd8bW655XPsnpaMSI0DUdl/U9uUqxnrq3rSy22eL2WOHWqA32Vym e39W+F63vEZVb9X4vJfrjnPQ9hQqWz0usSVm89A5RTCq5NwyTU2jsQv/xVc0VeIp497I FFQQ==
X-Gm-Message-State: AOUpUlFiBHZ+0f+hsiQqKskLRWZHIGa5oIZMjM9WW3fDMpHtsjB5+WpC I0/M2/OSLUkR1++lIQaJxe39DHtJPUaYeGr9EGx9ereu
X-Google-Smtp-Source: AAOMgpccL9DVg1g408+m4bSdBs1UnPZQIMdnAHzC8Lm/Lnj0oc3rRbHNi1Z00Tq+oQaclyCA6FyoXXUw0VjiRP/TXt0=
X-Received: by 2002:aca:df42:: with SMTP id w63-v6mr12411553oig.295.1533534949670; Sun, 05 Aug 2018 22:55:49 -0700 (PDT)
MIME-Version: 1.0
From: Martin Thomson <martin.thomson@gmail.com>
Date: Mon, 06 Aug 2018 15:55:39 +1000
Message-ID: <CABkgnnW9-Jn1CH0rSwbtDmMrOZ+jstugVsOpWtShDJgT_KSyOw@mail.gmail.com>
Subject: Key updates
To: QUIC WG <quic@ietf.org>
Content-Type: text/plain; charset="UTF-8"
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic/ShAWc08z1ha_ulNn6zJuUy1vsUU>
X-BeenThere: quic@ietf.org
X-Mailman-Version: 2.1.27
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <quic.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic>, <mailto:quic-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic/>
List-Post: <mailto:quic@ietf.org>
List-Help: <mailto:quic-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic>, <mailto:quic-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 06 Aug 2018 05:55:58 -0000
One of the open items out of the design team work was the interaction between TLS and key updates. As you might know, TLS key updates are synchronous, which works well in TCP, but less well in QUIC, where you need at least two active keys for reception around a key change. As it is, I think that there are two serious options: 1. Use KEY_PHASE to signal a change. This requires that both endpoints are loosely synchronized, which disadvantages asymmetric data exchanges. 2. Use a prepare-commit style. DTLS does this by having each peer send a KeyUpdate message, then requiring that to be acknowledged before they can switch to the new epoch. QUIC could do the same. The change is still signaled in the key phase bit, but only after this signaling exchange. The weakness of the first option is that packets marked with a change of key phase trigger trial decryption. And it requires synchronized changes, where if one endpoint moves to epoch N (epoch == encryption level with fewer characters to type), then the other has to follow before either can move to epoch N+1. The second has more moving parts, but avoids both of these problems. I tend to think that the second is a better design on balance, if only to dispense with the trial decryption, which we've managed to avoid in every other case thus far. The complication might also present some opportunities, which I will explain below, but that's a secondary concern. If we want to use this signaling method, we need to decide who drives key updating, TLS or QUIC: TLS: The DTLS design might work in QUIC, but with the KeyUpdate message hidden in an opaque CRYPTO frame, it could be a little tricky to manage properly. If we let TLS drive the key update, then it will send a KeyUpdate message in a CRYPTO frame and inform QUIC of the change in sending keys. From here, QUIC can keep using old keys until all CRYPTO frames from that epoch are acknowledged. The receiver will inform QUIC of new receive keys when it receives KeyUpdate, which can be installed. QUIC: Here we define a new frame type (KEY_UPDATE, say) that QUIC sends when it wants to update keys. When this is acknowledged, new keys can be installed and used for sending. A new API is needed to TLS to support cranking the key schedule forward. Invoking that API would lead to TLS signaling the availability of new keys. The receive side isn't any different from the TLS option. If this was to have parity with TLS, this would probably need to be two frame types so that a unilateral update could be distinguished from an update that includes a request for a mutual update. In both cases, QUIC will install new receive keys, but retain old receive keys so that it can deal with reordering. A few round trips, an RTO, 2MSL, or whatever we decide for the handshake is probably fine. Sending keys can be discarded immediately. The advantage of having TLS drive is that it uses the same machinery we have for the handshake. And there is no disparity between what TLS and QUIC understand to be current: when TLS wants to send something (a NewSessionTicket message for example), then it asks for an epoch that matches what QUIC is using. The disadvantage of using TLS is that there are more moving parts involved. It fits the rules we have for the handshake neatly: for instance, the CRYPTO frame would be retransmitted using the strict encryption-level rules, reusing that code from the handshake. But those rules aren't really necessary given that the rules for a KEY_UPDATE easily have the same effect. My inclination here is to have TLS drive this. The additional complexity seems to be manageable in the sense that it uses mechanisms that should already exist for the handshake. I also don't think that a new API for this feature is a good way to ensure that it is used. Those who are implementing, I know that key updates are often a long way down the list of priorities, but has anyone spent time considering the options here? (I personally implemented key updates for TLS, but I still haven't managed to find time to do it for DTLS, which might say something...) -- Addendum: Optional Key Phase ? One of the nice things about either prepare-commit design is that it opens a new option for how we use bits in headers. If there is a concern about spending a bit on every packet for the key phase (a whole bit!), we could design an encoding that only included the key phase if a longer packet number encoding was in use. The idea would be that you could use the longer packet number encoding while you have a key update outstanding, so that the key phase was available for the entirety of the changeover. Once packets with the new epoch were acknowledged, you could switch back to a shorter encoding that didn't include a key phase. The receiver would switch to expecting the new epoch after receiving the first packet in the new epoch. That's a saving that might allow endpoints to use the shortest packet number encoding in more cases. Of course, the header design is already complex enough, so maybe we don't actually *want* more options to consider there :)
- Key updates Martin Thomson
- Re: Key updates Mikkel Fahnøe Jørgensen
- Re: Key updates Martin Thomson
- Re: Key updates Mikkel Fahnøe Jørgensen
- Re: Key updates Mikkel Fahnøe Jørgensen
- Re: Key updates Martin Thomson
- Re: Key updates Ian Swett
- Re: Key updates Mirja Kühlewind
- RE: Key updates Nick Banks
- Re: Key updates Martin Thomson
- Re: Key updates Martin Thomson
- Re: Key updates Kazuho Oku
- Re: Key updates Kazuho Oku
- Re: Key updates Martin Thomson
- Re: Key updates Kazuho Oku
- Re: Key updates Martin Thomson
- Re: Key updates Kazuho Oku
- Re: Key updates Martin Thomson
- Re: Key updates Kazuho Oku
- Re: Key updates Dmitri Tikhonov
- Re: Key updates Spencer Dawkins at IETF
- Re: Key updates Mirja Kühlewind