Re: Key updates

Ian Swett <> Mon, 06 August 2018 12:43 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id C866F130DC3 for <>; Mon, 6 Aug 2018 05:43:57 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -17.51
X-Spam-Status: No, score=-17.51 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, ENV_AND_HDR_SPF_MATCH=-0.5, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_DKIMWL_WL_MED=-0.01, USER_IN_DEF_DKIM_WL=-7.5, USER_IN_DEF_SPF_WL=-7.5] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id YUFTNg-kGgRo for <>; Mon, 6 Aug 2018 05:43:55 -0700 (PDT)
Received: from ( [IPv6:2607:f8b0:4002:c09::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id EC24E130934 for <>; Mon, 6 Aug 2018 05:43:54 -0700 (PDT)
Received: by with SMTP id f10-v6so1652216ybk.13 for <>; Mon, 06 Aug 2018 05:43:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=V+8i+SP5FAA9bQ7xiZfP2WtCexHigwhC/ijrTUMojwk=; b=p/hzpYXQ/zIWta+iPMLBL4hHq3GmwC1PIMvRTOFa7fbWlQlhRlLDSQ4xA2YtQBTDGs ZYYS9sVY8dHBA19X8rONZ0EC4zbWbRHdumvUR7d/4VgA6YKITcFpSIaCPbVWdGfYj6lW rknqZqa/gjOzvW74C5PpUs6X4EpEUNu7JtqD30wLb0jgWsnezU7wZjfk7vgO250uGIzQ GTYDmCB3ev72OqvX61J8l51nn18JvHcu6Dj0brpzGKj5MIGa+DaijFKl1HqEbdt6Mq/4 f+gqUzwGnT0+Qz0W2mUajHzoJrgfe4fCsLeA87J8O678OAyhaunpQwGfP6UYciby0pPA 7L1w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=V+8i+SP5FAA9bQ7xiZfP2WtCexHigwhC/ijrTUMojwk=; b=kUV+ZndeFfwweQGjJZmhOOkSNRX3fJkRIy8+RYCMAiNH8rxtqtUhq56DzjO8ZBqQ5W AVEQP1z30tCu40mfLQNBuvnZAXLLfrrNk2V+cZT6+HjlqYmpV+uzSG3WZEzqZ91d+RrY k2kd8Wl6M4sOgUTshcVN6/dZNTR8/1J4OLKANEjvaEtNwR9AeqcJ9WFBSxYgbY+K/iEL 5SCphT5T91FKADfyr1wbsZEngUE4+Dy5HeVJfCUw/H7OWJXPoYQYYVG+Y331V/QoUKKZ 4AHnbgDA585DNF4PNm32i3WSbmc2g8rYL2HBu2mAuo48u5WfSbJky2TKGiXzYRggWoQq 7ctw==
X-Gm-Message-State: AOUpUlEUKcmyBjlTt4v9IvxiubrAIDVRbUTc9GaSKmMvsBUVyelT8wVE oUNClA07UL/owC5hjBaeDBUFrD7FuVlM1yrvx8CaJw==
X-Google-Smtp-Source: AAOMgpfNLYTpbUddgoo4+oNaRdP79jn0IjhPBcLv5sg56n3ELIq7NhTanH6MV9oXhz0u3R9JuKZE3rL/ZICrIiyNLCk=
X-Received: by 2002:a25:c07:: with SMTP id 7-v6mr7591649ybm.178.1533559433714; Mon, 06 Aug 2018 05:43:53 -0700 (PDT)
MIME-Version: 1.0
References: <>
In-Reply-To: <>
From: Ian Swett <>
Date: Mon, 6 Aug 2018 08:43:09 -0400
Message-ID: <>
Subject: Re: Key updates
To: Martin Thomson <>
Content-Type: multipart/alternative; boundary="0000000000004ab29f0572c3a1ee"
Archived-At: <>
X-Mailman-Version: 2.1.27
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 06 Aug 2018 12:43:58 -0000

On Mon, Aug 6, 2018 at 1:56 AM Martin Thomson <>

> 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...)

I think we seriously considered the option of "Close the connection and
0RTT a new one".

As a related point, I've seen a few use cases for QUIC where it was useful
to have different keys for different connection IDs for a longish period of
time.  The first is pairing multicast + unicast, but I think there was
another.  That makes me attracted to the idea of punting on this for QUIC
v1 and tackling this at the same time as multipath?

> --
> 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 :)