Subject: [TLS] DTLS 1.3 rekeying and the use of epoch values

From: Hannes Tschofenig <[email-masked]>
Date: Fri, 8 Jul 2016 16:21:30 +0200

Hi all,

based on the feedback from Ilari this week I have drafted initial text
that talks about rekeying and the use of the epoch value.

----

8.8.  Epoch Values and Rekeying

   A recipient of a DTLS message needs to select the correct keying
   material in order to process an incoming message.  With the
   possibility of message loss and re-order an identifier is needed to
   determine which cipher state has been used to protect the record
   payload.  The epoch value fulfills this role in DTLS.  In addition to
   the key derivation steps described in Section 9 triggered by the
   states during the handshake a sender may want to rekey at any time
   during the lifetime of the connection and has to have a way to
   indicate that it is updating its sending cryptographic keys.

   The following epoch values are reserved and correspond to phases in
   the handshake and allow identification of the correct cipher state:

   -  epoch value (0) for use with unencrypted messages, namely
      ClientHello, ServerHello, and HelloRetryRequest.

   -  epoch value (1) for the Finished message protected using the 0-RTT
      handshake key.

   -  epoch value (2) for 0-RTT 'Application Data' protected using keys
      derived from the
      early_traffic_secret.

   -  epoch value (3) for messages protected using keys derived from the
      handshake_traffic_secret, namely the EncryptedExtensions to the
      Finished message sent by the client).

   -  epoch value (4) for application data payloads protected using keys
      derived from the initial traffic_secret_0.

   -  epoch value (5 to 2^16-1) for application data payloads protected
      using keys from the traffic_secret_N (N>0).

   Using these reserved epoch values a receiver knows what cipher state
   has been used to encrypt and integrity protect a message.
   Implementations that receive a payload with an epoch value for which
   no corresponding cipher state can be determined MUST generate a fatal
   "unexpected_message" alert.  For example, client incorrectly uses
   epoch value 5 when sending application data in a 0-RTT exchange with
   the first message.  A server will not be able to compute the
   appropriate keys and will therefore have to respond with a fatal
   alert.

   Increasing the epoch value by a sender (starting with value 5
   upwards) corresponds semantically to rekeying using the KeyUpdate
   message in TLS 1.3.  Instead of utilizing an dedicated message in
   DTLS 1.3 the sender uses an increase in the epoch value to signal
   rekeying.  Hence, a sender that decides to increment the epoch value
   (with value starting at 5) MUST send all its traffic using the next
   generation of keys, computed as described in Section 9.2.  Upon
   receiving a payload with such a new epoch value, the receiver MUST
   update their receiving keys and if they have not already updated
   their sending state up to or past the then current receiving
   generation MUST send messages with the new epoch value prior to
   sending any other messages.  For epoch values lower than 5 the key
   schedule described in Section 9.1 is applicable.

   Note that epoch values do not wrap.  If a TLS implementation would
   need to wrap the epoch value, it MUST terminate the connection.

----

Ciao
Hannes

---

From: Ilari Liusvaara <[email-masked]>
Date: Sat, 9 Jul 2016 19:05:43 +0300

> that talks about rekeying and the use of the epoch value.

One maybe workable scheme that occurs to me is: Outside special
epoches reserved for TLS handshaking itself (the first 4?), Both
sides send using the highest epoch they have seen successful
deprotection for or one bigger (both sides start at 4 at end of
handshake).

That would severly limit the frequency of rekeyings in fully
asynchronous usage tho (but fully asynchronous usage of UDP or anything
similar is probably a Bad Idea).

Also, the epoch use window would be sufficiently small to allow epoch
number on wire to wrap around (obviously the actual epoch number would
not wrap. That is, peer that has seen epoch 65535 (0xFFFF) from peer
can send at epoch 65536 (0x0000), which then can be bumped to 65537
(0x0001). 

-Ilari