target = "https://tools.ietf.org/rfc/rfc8446#section-7.1"

# 7.1.  Key Schedule
#
# The key derivation process makes use of the HKDF-Extract and
# HKDF-Expand functions as defined for HKDF [RFC5869], as well as the
# functions defined below:
# 
#     HKDF-Expand-Label(Secret, Label, Context, Length) =
#          HKDF-Expand(Secret, HkdfLabel, Length)
# 
#     Where HkdfLabel is specified as:
# 
#     struct {
#         uint16 length = Length;
#         opaque label<7..255> = "tls13 " + Label;
#         opaque context<0..255> = Context;
#     } HkdfLabel;
# 
#     Derive-Secret(Secret, Label, Messages) =
#          HKDF-Expand-Label(Secret, Label,
#                            Transcript-Hash(Messages), Hash.length)
# 
# The Hash function used by Transcript-Hash and HKDF is the cipher
# suite hash algorithm.  Hash.length is its output length in bytes.
# Messages is the concatenation of the indicated handshake messages,
# including the handshake message type and length fields, but not
# including record layer headers.  Note that in some cases a zero-
# length Context (indicated by "") is passed to HKDF-Expand-Label.  The
# labels specified in this document are all ASCII strings and do not
# include a trailing NUL byte.
# 
# Note: With common hash functions, any label longer than 12 characters
# requires an additional iteration of the hash function to compute.
# The labels in this specification have all been chosen to fit within
# this limit.
# 
# Keys are derived from two input secrets using the HKDF-Extract and
# Derive-Secret functions.  The general pattern for adding a new secret
# is to use HKDF-Extract with the Salt being the current secret state
# and the Input Keying Material (IKM) being the new secret to be added.
# In this version of TLS 1.3, the two input secrets are:
# 
# -  PSK (a pre-shared key established externally or derived from the
#    resumption_master_secret value from a previous connection)
# 
# -  (EC)DHE shared secret (Section 7.4)
# 
# This produces a full key derivation schedule shown in the diagram
# below.  In this diagram, the following formatting conventions apply:
# 
# -  HKDF-Extract is drawn as taking the Salt argument from the top and
#    the IKM argument from the left, with its output to the bottom and
#    the name of the output on the right.
# 
# -  Derive-Secret's Secret argument is indicated by the incoming
#    arrow.  For instance, the Early Secret is the Secret for
#    generating the client_early_traffic_secret.
# 
# -  "0" indicates a string of Hash.length bytes set to zero.
# 
#           0
#           |
#           v
# PSK ->  HKDF-Extract = Early Secret
#           |
#           +-----> Derive-Secret(., "ext binder" | "res binder", "")
#           |                     = binder_key
#           |
#           +-----> Derive-Secret(., "c e traffic", ClientHello)
#           |                     = client_early_traffic_secret
#           |
#           +-----> Derive-Secret(., "e exp master", ClientHello)
#           |                     = early_exporter_master_secret
#           v
#     Derive-Secret(., "derived", "")
#           |
#           v
# (EC)DHE -> HKDF-Extract = Handshake Secret
#           |
#           +-----> Derive-Secret(., "c hs traffic",
#           |                     ClientHello...ServerHello)
#           |                     = client_handshake_traffic_secret
#           |
#           +-----> Derive-Secret(., "s hs traffic",
#           |                     ClientHello...ServerHello)
#           |                     = server_handshake_traffic_secret
#           v
#     Derive-Secret(., "derived", "")
#           |
#           v
# 0 -> HKDF-Extract = Master Secret
#           |
#           +-----> Derive-Secret(., "c ap traffic",
#           |                     ClientHello...server Finished)
#           |                     = client_application_traffic_secret_0
#           |
#           +-----> Derive-Secret(., "s ap traffic",
#           |                     ClientHello...server Finished)
#           |                     = server_application_traffic_secret_0
#           |
#           +-----> Derive-Secret(., "exp master",
#           |                     ClientHello...server Finished)
#           |                     = exporter_master_secret
#           |
#           +-----> Derive-Secret(., "res master",
#                                 ClientHello...client Finished)
#                                 = resumption_master_secret
# 
# The general pattern here is that the secrets shown down the left side
# of the diagram are just raw entropy without context, whereas the
# secrets down the right side include Handshake Context and therefore
# can be used to derive working keys without additional context.  Note
# that the different calls to Derive-Secret may take different Messages
# arguments, even with the same secret.  In a 0-RTT exchange,
# Derive-Secret is called with four distinct transcripts; in a
# 1-RTT-only exchange, it is called with three distinct transcripts.
# 
# If a given secret is not available, then the 0-value consisting of a
# string of Hash.length bytes set to zeros is used.  Note that this
# does not mean skipping rounds, so if PSK is not in use, Early Secret
# will still be HKDF-Extract(0, 0).  For the computation of the
# binder_key, the label is "ext binder" for external PSKs (those
# provisioned outside of TLS) and "res binder" for resumption PSKs
# (those provisioned as the resumption master secret of a previous
# handshake).  The different labels prevent the substitution of one
# type of PSK for the other.
# 
# There are multiple potential Early Secret values, depending on which
# PSK the server ultimately selects.  The client will need to compute
# one for each potential PSK; if no PSK is selected, it will then need
# to compute the Early Secret corresponding to the zero PSK.
# 
# Once all the values which are to be derived from a given secret have
# been computed, that secret SHOULD be erased.

[[spec]]
level = "SHOULD"
quote = '''
Once all the values which are to be derived from a given secret have
been computed, that secret SHOULD be erased.
'''

