Re: Stream0 Design Team Proposal

Eric Rescorla <> Tue, 29 May 2018 14:40 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id C87A712E957 for <>; Tue, 29 May 2018 07:40:04 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.608
X-Spam-Status: No, score=-2.608 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, T_DKIMWL_WL_MED=-0.01, URIBL_BLOCKED=0.001] 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 J8WGiCcLxNkl for <>; Tue, 29 May 2018 07:40:02 -0700 (PDT)
Received: from ( [IPv6:2607:f8b0:4003:c06::22a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 8810F12E899 for <>; Tue, 29 May 2018 07:40:02 -0700 (PDT)
Received: by with SMTP id 14-v6so5234852oie.3 for <>; Tue, 29 May 2018 07:40:02 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=qgXCrrfgyjX1bH7A4ba9Sn/6QJCN7we54xLKFE/rYro=; b=tba7yFO9r8EeyG3DkjGtJWKyZTEDCmw/9qy2HEIqIxeb79JYcEKXlxX14WHifxondQ 9z4LS80w8efisqus+PYeDavO1JunaxnWGm4u41H3ZkvwA5rpODx2jmEXFobQLvoshpZv 5t6B814obgqMKS2Ltt7i1aP0AGRYw+AX0KuIRA+p8ew8lilU3qY7ifTDN1/HpDPU2YNI wgZht4zHxkk7RSvOA0py8pquyUHSnmIZ/a1TiObLTAq3Ap+58CQtO5y1OMKjnf9AaZ1s QGef97hAfdD+vvqAYXjpPkf6S3PzX/M+rWcWiEv6RVmhFbsdSzo840hAZXffYJYYdeyF zGeg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=qgXCrrfgyjX1bH7A4ba9Sn/6QJCN7we54xLKFE/rYro=; b=EKVV1hqy0YFqAFZCOYXnoXNYgWjoStVnTusWaJDVtAr2YZ4eX4IqlAmXW6iCfWon36 ni99JsYrl/RhdW0rGPlh9FCHAd9vH+P500I6RtRI7EpAjmaLCR/UxDMRVcIMzJRa1pSt DoaqMZwuuEhAY2tJtplz1ICrBRSMDuE1RFJ9PwhVFlO7ezVtQ4ti5Pcg98mBFGp5YLR2 fa6wCMS3Vv2hoHbcsRLACycHXxUB0mFd8SJncAe6K/rdIY3Jj3oQ7dnN2xBm+LWPUkap jbXNclrRTPw949OQ2+lJ82ATBrbC0nVDoSCd/7tpV9Gfnjo7/klWJ82ibeUPxBnA9iTG d01Q==
X-Gm-Message-State: ALKqPwfjG0Y5ybiq5gojljKCTaIFZ/hzmWVQipjsX+Iuj1JbpBVGzETl uLzX5v/wgbhakaQXpoX1BuYlCVQnBMjvPSc1AvUFOA==
X-Google-Smtp-Source: ADUXVKJG1T1Pwk4nPDsd8Jnn2rE8LDWHQVhYlldk4xhb6isc9YhW5VXQDu/ndFF/p4SAP7lDX06h9SvzgME4VSfa/1k=
X-Received: by 2002:aca:1c3:: with SMTP id 186-v6mr5318193oib.174.1527604800694; Tue, 29 May 2018 07:40:00 -0700 (PDT)
MIME-Version: 1.0
Received: by 2002:ac9:66:0:0:0:0:0 with HTTP; Tue, 29 May 2018 07:39:20 -0700 (PDT)
In-Reply-To: <>
References: <> <>
From: Eric Rescorla <>
Date: Tue, 29 May 2018 07:39:20 -0700
Message-ID: <>
Subject: Re: Stream0 Design Team Proposal
To: Kazuho Oku <>
Cc: Ian Swett <>, Eric Rescorla <>, IETF QUIC WG <>
Content-Type: multipart/alternative; boundary="00000000000080c126056d59351a"
Archived-At: <>
X-Mailman-Version: 2.1.22
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: Tue, 29 May 2018 14:40:05 -0000

Hi folks,

I have implemented the proposal from the Stream 0 DT in Minq, and have
interop with Quicly in the 1-RTT mode. This went in quite cleanly at
the cost of probably a day of programming. The code size is about
the same (slight reduction but that's before I cleand up old code
and added some things I know I need).

Mint already had a separated record layer, so on the Mint side, this
was mostly a matter of making that API public, i.e.,

- Making it a Golang interface so I could have multiple
- Cleaning up the interface a bit (mostly removing APIs that only DTLS
- Adding a way for Minq to add its own record layer implementation
- Adding an API to override the TLS HKDF label prefix

Here's the definition of RecordLayer, with some unnecessary APIs that
I haven't cleaned up yet removed.

  type RecordLayer interface {
        // Install a new TLS key at the record layer
      Rekey(epoch Epoch, factory AeadFactory, key []byte, iv []byte) error

        // Reset back to the "cleartext" record layer
      ResetClear(seq uint64)

        // I'm never going to want to read at this level again
      DiscardReadKey(epoch Epoch)

        // Read a record
      ReadRecord() (*TLSPlaintext, error)

        // Write a record
      WriteRecord(pt *TLSPlaintext) error

        // What is the current Epoch (saves bookkeeping in Mint)
      Epoch() Epoch

The way this works is that Minq installs two RecordLayer objects, one
in each direction [0]. Each one has one active epoch that it expects
to read or write from, and the epoch has an associated queue.

So, for instance, on the server side when Minq receives an Initial
packet, it decrypts it and then stuffs the CRYPTO_HS frames into the
queue associated with epoch 0. It then calls Mint.handshake() which

  Rx: ReadRecord() -> ClientHello
  Tx: WriteRecord(ServerHello)
  Tx: Rekey(epoch = 2 [Handshake)
  Tx: WriteRecord(EncryptedExtensions)
  Tx: WriteRecord(Certificate)
  Tx: WriteRecord(CertificateVerify)
  Tx: WriteRecord(Finished)
  Tx: Rekey(epoch = 3 [Application Data])
  Rx: Rekey(epoch = 2 [Handshake)

This queues up two "flows" of data, corresponding to the Initial and
Handshake encryption levels. Minq is then responsible for sending
these flows in their own packet types with the appropriate keys. When
Mint calls ReadRecord() again, it's reading out of the Handshake input
queue (due to the Rekey that's the last operation).

This is still a bit too messy to put up on Github, but I should have
something up in time for Kista.


[0] One might want to have ReadRecordLayer and WriteRecordLayer, but I
was lazy.

On Tue, May 22, 2018 at 9:57 PM, Kazuho Oku <> wrote:

> FWIW, I am happy to tell you that I have a working PoC code for the
> proposed approach.
> On the QUIC side, I saw 2% (124 lines) increase in code size (more on
> that below). On the TLS side, I also saw 2% (175 lines) increase.
> However please look at the code size change especially on the QUIC
> side with grain of salt, as it is just a PoC.
> As expected, the key and encryption-level management on the QUIC side
> became very clean. Following are some of the design decisions I made
> as well as the outcomes:
> * All the interaction between picotls and quicly are accompanied by
> "epoch". Handshake messages are attributed with their epochs so that
> they do not get protected by the wrong key, or so that octets received
> under an incorrect encryption context cannot be misused.
> * All the traffic keys are governed by quicly (managing some traffic
> keys in TLS while managing PNE key in QUIC seems messy).
> * The Initial key is setup by quicly, wheeras other traffic keys are
> installed by picotls by calling a callback named
> update_traffic_key_cb. The callback accepts and installs 6 keys in
> total: for three levels (i.e. 0-RTT, handshake, 1-RTT) in two
> directions (send-side and receive-side).
> * Three PN spaces have their own AEAD encryption key. Initial PN and
> Handshake PN spaces have one aead decryption key each. Application PN
> space has up to two decryption keys: either for 0-RTT and 1-RTT or for
> two 1-RTT keys during key update.
> It was a pain to have a dedicated frame encoding for CRYPTO_HS, even
> though we can reuse (and I reused) the retransmission and reassembly
> logic of QUIC streams for the handshake flows. About a half of the
> code size increase comes from that (the other half comes from the
> added abstraction for having two contexts for the handshake). I would
> prefer reusing the STREAM frame encoding for the handshake data. We
> could possibly use a different base offset (i.e. for CRYPTO_HS frames
> we could use 0b00011XXX, whereas the STREAM frames use 0b00010XXX), as
> well as omitting the Stream ID field.
> Overall, now that I have a PoC, I am more confident that the proposed
> approach is the correct path forward. It *simplifies* the QUIC stack
> at the same time giving us better security properties as well as
> fixing various issues in the current design (as discussed in the
> design doc).
> 2018-05-23 10:30 GMT+09:00 Ian Swett <
> >:
> > Dear QUIC WG,
> >
> >
> > On behalf of the Stream 0 Design Team, I am pleased to report that we
> have
> > consensus on a proposed approach to share with the WG. The DT's proposal
> > will make QUIC and TLS work closer together and incorporates ideas from
> > DTLS, but it does not use the DTLS protocol itself.
> >
> >
> > The DT believes this solves the important open Stream 0 issues. The
> proposal
> > will be a bit more invasive in TLS, but we believe it is the right
> long-term
> > direction and several TLS stacks (BoringSSL, PicoTLS, NSS, and Mint) are
> > willing and able to do the work necessary.. A number of stacks are
> currently
> > working on implementations of this new approach, which we hope to have in
> > time for the Interim meeting.
> >
> >
> > A design document describing the overall approach can be found at:
> >
> >
> bflDRV6auojfJLkxddT93j6SwHY8/edit
> >
> >
> > A PR making the changes to the QUIC documents can be found at:
> >
> >
> >
> >
> > A few design details did not have clear consensus, but it was felt it
> would
> > be better to discuss those in the wider WG than delay the design team.  A
> > consistent choice was made in the PR and these issues are mentioned in
> > Appendix B of the design doc.
> >
> >
> > As always, comments and questions welcome. That said, this is a big PR
> and
> > we recognize that some editorial work is going to be needed before
> merging.
> > In the interest of letting people follow along, and to keep github from
> > falling over, we ask people to keep discussion on the mailing list and
> > refrain from making PR comments.
> >
> >
> > See you in Kista!
> >
> >
> > Ian and Eric
> --
> Kazuho Oku