1 Introduction
1.1 Development and Standardization of TLS 1.3
1.2 Security Analyses of TLS
1.3 Our Contributions
-
Authentication: whether a stage key is unauthenticated, unilaterally authenticated, or mutually authenticated. We further extend the multi-stage model to capture upgradable authentication: a stage’s key may be considered, say, unauthenticated at the time it is accepted, but the authentication level of this key may be “raised” to unilaterally authenticated or, potentially in a second step, mutually authenticated after some later operations, such as verification of a signature in a later message.
-
Forward secrecy: whether a stage key is meant to provide forward secrecy, namely that it remains secure after compromise of a long-term secret involved in its derivation.
-
Key usage: whether a stage key is meant to be used internally within the protocol (for example, to encrypt later handshake messages), or externally (for example, composed with a symmetric encryption scheme to protect application messages or used in some other external symmetric-key protocol).
-
Replayability: whether it is guaranteed that a stage key is not established in result of a replay attack; early stages of the 0-RTT modes do not have this guarantee.
draft
-05
, which has the same basic signed-Diffie–Hellman structure but a simplified key schedule compared to the final version, and an alternative proposal called draft
-dh
incorporating ideas from the OPTLS design [77], in which servers could have a semi-static DH key share. In [39], we updated our analysis to draft
-10
and added an analysis of the, by then revised, pre-shared-key handshake mode. In [53], a subset of us analyzed the 0-RTT pre-shared key and PSK-(EC)DHE mode in draft
-14
, as well as the later deprecated Diffie–Hellman-based 0-RTT mode using semi-static DH key shares in draft
-12
, which introduced the notion of replayable stages into the multi-stage key exchange security model. In a PhD thesis [47], one of us updated the work from [39] to address the full, PSK, and PSK-(EC)DHE handshakes in draft
-16
; in another PhD thesis [61], another of us unified the MSKE model and the aforementioned results on the full and PSK handshakes of draft
-10
and the 0-RTT handshakes of draft
-12
and draft
-14
.2 Preliminaries
2.1 Notation
2.2 Collision-Resistant Hash Functions
2.3 HMAC and HKDF
0x5c
and 0x36
, respectively.2.4 Dual PRF Security and the PRF-ODH Assumption
3 The TLS 1.3 Handshake Protocol
Hello
messages to indicate support for different cryptographic options and use the selected parameters to generate key exchange material; and an authentication phase, where the client and the server exchange CertificateVerify
and Finished
messages, authenticating each other using long-term asymmetric (or symmetric) values. Figure 2 illustrates the key schedule of TLS 1.3, Table 1 lists abbreviations for messages and keys used throughout the paper, and Table 2 details some of the computations and inputs.
3.1 Key-Exchange Phase
3.2 Authentication Phase
Message | Derived key or value | ||
---|---|---|---|
\(\texttt {CH} \) | \(\texttt {ClientHello} \) | \(\mathrm {BK}\) | Binder Key |
\(\texttt {CKS} \) | \(\texttt {ClientKeyShare} \) | \(\mathrm {CHTS}\)/\(\mathrm {SHTS}\) | Client/Server Handshake Traffic Secret |
\(\texttt {CPSK} \) | \(\texttt {ClientPreSharedKey} \) | \(\mathrm {CATS}\)/\(\mathrm {SATS}\) | Client/Server Application Traffic Secret |
\(\texttt {SH} \) | \(\texttt {ServerHello} \) | \(\mathrm {dES}\)/\(\mathrm {dHS}\) | Derived Early/Handshake Secret |
\(\texttt {SKS} \) | \(\texttt {ServerKeyShare} \) | \(\mathrm {ES}\)/\(\mathrm {HS}\)/\(\mathrm {MS}\) | Early/Handshake/Master Secret |
\(\texttt {SPSK} \) | \(\texttt {ServerPreSharedKey} \) | \(\mathrm {ETS}\) | Early Traffic Secret |
\(\texttt {EE} \) | \(\texttt {EncryptedExtensions} \) | \(\mathrm {EEMS}\)/\(\mathrm {EMS}\) | (Early) Exporter Master Secret |
\(\texttt {CR} \) | \(\texttt {CertificateRequest} \) | \(\mathrm {fk}_{B}\)/\(\mathrm {fk}_{C}\)/\(\mathrm {fk}_{S}\) | Binder/Client/Server Finished Key |
\(\texttt {SCRT} \) | \(\texttt {ServerCertificate} \) | \(\mathrm {RMS}\) | Resumption Master Secret |
\(\texttt {SCV} \) | \(\texttt {ServerCertificateVerify} \) | \(\mathrm {tk}_{\text {eapp}}\) | Early Application Traffic Key |
\(\texttt {SF} \) | \(\texttt {ServerFinished} \) | \(\mathrm {tk}_{\text {chs}}\)/\(\mathrm {tk}_{\text {shs}}\) | Client/Server Handshake Traffic Key |
\(\texttt {CCRT} \) | \(\texttt {ClientCertificate} \) | \(\mathrm {tk}_{\text {capp}}\)/\(\mathrm {tk}_{\text {sapp}}\) | Client/Server Application Traffic Key |
\(\texttt {CCV} \) | \(\texttt {ClientCertificateVerify} \) | ||
\(\texttt {CF} \) | \(\texttt {ClientFinished} \) |
3.3 NewSessionTicket
-
\(\texttt {ticket} \texttt {\_} \texttt {nonce} \), which is used by the client as the salt value to derive the pre-shared key to be used in future handshake for resumption: \(\mathrm {PSK}\leftarrow \textsf {HKDF} .\) \(\textsf {Expand} (\mathrm {RMS},\) “\(\texttt {resumption} \)”, \(\texttt {ticket} \texttt {\_} \texttt {nonce} )\).
-
\(\texttt {ticket} \), which is an opaque label used to publicly refer to the associated pre-shared key in future \(\texttt {PreSharedKey} \) messages. In our notation used in Fig. 1, the pre-shared key identifier \(pskid = \texttt {ticket} \).
Secret | Context input | Label input |
---|---|---|
\(\mathrm {BK}\) | \(H_{0} = H(\texttt {``''} )\) | \(\texttt {Label} _{0} =\) “ext binder” / “res binder” |
\(\mathrm {fk}_{B}\) | \(H_{\varepsilon } = \texttt {``''} \) | \(\texttt {Label} _{6} =\) “finished” |
\(\mathrm {ETS}\) | \(H_{1} = H(\texttt {ClientHello} )\) | \(\texttt {Label} _{1} =\) “c e traffic” |
\(\mathrm {EEMS}\) | \(H_{1} = H(\texttt {ClientHello} )\) | \(\texttt {Label} _{2} =\) “e exp master” |
\(\mathrm {dES}\) | \(H_{0} = H(\texttt {``''} )\) | \(\texttt {Label} _{3} =\) “derived” |
\(\mathrm {CHTS}\) | \(H_{2} = H(\texttt {ClientHello} \Vert \texttt {ServerHello} )\) | \(\texttt {Label} _{4} =\) “c hs traffic” |
\(\mathrm {SHTS}\) | \(H_{2} = H(\texttt {ClientHello} \Vert \texttt {ServerHello} )\) | \(\texttt {Label} _{5} =\) “s hs traffic” |
\(\mathrm {fk}_{S}\) | \(H_{\varepsilon } = \texttt {``''} \) | \(\texttt {Label} _{6} =\) “finished” |
\(\mathrm {dHS}\) | \(H_{0} = H(\texttt {``''} )\) | \(\texttt {Label} _{3} =\) “derived” |
\(\mathrm {CATS}\) | \(H_{3} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ServerFinished} )\) | \(\texttt {Label} _{7} =\) “c ap traffic” |
\(\mathrm {SATS}\) | \(H_{3} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ServerFinished} )\) | \(\texttt {Label} _{8} =\) “s ap traffic” |
\(\mathrm {EMS}\) | \(H_{3} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ServerFinished} )\) | \(\texttt {Label} _{9} =\) “exp master” |
\(\mathrm {fk}_{C}\) | \(H_{\varepsilon } = \texttt {``''} \) | \(\texttt {Label} _{6} =\) “finished” |
\(\mathrm {RMS}\) | \(H_{4} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ClientFinished} )\) | \(\texttt {Label} _{10} =\) “res master” |
Auth. value | Context input | Context string (for signatures only) |
---|---|---|
\(\textit{binder}\) | \(H_{5} = H(\texttt {ClientHello} ^{\dagger })\) | |
\(\texttt {SCV} \) | \(H_{6} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ServerCert} )\) | \(\texttt {Label} _{11} =\) “TLS 1.3, server CertificateVerify” |
\(\texttt {SF} \) | \(H_{7} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ServerCertVfy} )\) | |
\(\texttt {CCV} \) | \(H_{8} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ClientCert} )\) | \(\texttt {Label} _{12} =\) “TLS 1.3, client CertificateVerify” |
\(\texttt {CF} \) | \(H_{9} = H(\texttt {ClientHello} \Vert \ldots \Vert \texttt {ClientCertVfy} ^*)\) |
Traffic key calculation | ||
---|---|---|
\(\mathrm {tk}_{\text {eapp}}/\mathrm {tk}_{\text {chs}}/\mathrm {tk}_{\text {shs}}/\mathrm {tk}_{\text {capp}}/\mathrm {tk}_{\text {sapp}}= (key, iv) = \textsf {DeriveTK} (\mathrm {ETS}/\mathrm {CHTS}/\mathrm {SHTS}/\mathrm {CATS}/\mathrm {SATS})\) where \(\textsf {DeriveTK} (\mathrm {Secret}) = (\textsf {HKDF} .\textsf {Expand} (\mathrm {Secret}, \texttt {``key''} , H(\texttt {``''} ), L_{k}), \textsf {HKDF} .\textsf {Expand} (\mathrm {Secret}, \texttt {``iv''} , H(\texttt {``''} ), L_{iv}))\) with \(L_{k}\)/\(L_{iv}\) indicating the key/iv length of the negotiated AEAD scheme |
4 Multi-Stage Key Exchange Security Model
-
Long-term keys (such as the signing keys of the server or client, but also their pre-shared keys), since long-term values have the potential to be compromised, and this is necessary to model forward secrecy; it is captured in our model by the \(\textsf {Corrupt} \) query.
-
Session keys (such as the various traffic encryption keys or the derived resumption or exporter secrets), since these are outputs of the key exchange and are used beyond this protocol for encryption, later resumption, or exporting of keying material; this is modeled by the \(\textsf {Reveal} \) query.
-
Ephemeral secrets / randomness (such as the randomness in a signature algorithm or ephemeral Diffie–Hellman exponents); this is disallowed since TLS 1.3 is not designed to be secure if these values are compromised.
-
Internal values / session state (e.g., internally computed master secrets or MAC keys); this is disallowed since TLS 1.3 is not designed to be secure if these values are compromised.
4.1 Syntax
-
\(\textsf {M} \in \mathbb {N}\): the number of stages (i.e., the number of keys derived). (We fix a maximum stage \(\textsf {M} \) only for ease of notation. Note that \(\textsf {M} \) can be arbitrarily large in order to cover protocols where the number of stages is not bounded a-priori. Also note that stages and session key derivations may be “back to back,” without further protocol interactions between parties.)
-
\(\textsf {AUTH} \subseteq \{((u_{1},m_{1}),\dots ,(u_{\textsf {M} },m_{\textsf {M} })) \mid u_{j}, m_{j} \in \{1, \dots , \textsf {M} , \infty \} \}\): a set of vectors of pairs, each vector encoding a supported scheme for authentication and authentication upgrades, for each stage. For example, the i-th entry \((u_{i},m_{i})\) in a vector says that the session key in stage i initially has the default unauthenticated level, i.e., provides no authentication for either communication partner, then at stage \(u_{i}\) becomes unilaterally authenticated and thus authenticates only the responder (server), and becomes mutually authenticated to authenticate both communication partners at stage \(m_{j}\). Note that we allow for example \(u_{i}=i\) (or even \(u_{i} = m_{i} = i\)) such that the session key is immediately unilaterally (resp. mutually) authenticated when derived. Entries in each pair must be non-decreasing, and \(u_{i} = \infty \) or \(m_{i} = \infty \) denotes that unilateral, resp. mutual, authentication is never reached for stage i.
-
\(\textsf {FS} \in \{1,\dots ,\textsf {M} ,\infty \}\): the stage \(j = \textsf {FS} \) from which on keys are forward secret (or \(\infty \) in case of no forward secrecy). (A more general multi-stage key exchange model could have a vector tracking specifically which subset of stage keys have forward secrecy. We do not need such generality since forward secrecy is monotonic in TLS 1.3.)
-
\(\textsf {USE} \in \{\textsf {internal} , \textsf {external} \}^{\textsf {M} }\): the usage indicator for each stage, where \(\textsf {USE} _{i}\) indicates the usage of the stage-i key. Here, an internal key is used within the key exchange protocol (but possibly also externally), whereas an external key must not be used within the protocol, making the latter potentially amenable to generic composition (cf. Sect. 7.3). As shorthand notation, we, e.g., write \(\textsf {USE} = (\textsf {internal} : \{1,4\}, \textsf {external} : \{2,3,5\})\) to indicate that usage of keys in stage 1 and 4 is internal, and external for the other stages.
-
\(\textsf {REPLAY} \in \{\textsf {replayable} , \textsf {nonreplayable} \}^{\textsf {M} }\): the replayability indicator for each stage, where \(\textsf {REPLAY} _{i}\) indicates whether the i-th stage is replayable in the sense that an adversary can easily force identical communication and thus identical session identifiers and keys in this stage (e.g., by re-sending the same data in \(\text {0-RTT} \) stages). Note that the adversary, however, should still not be able to distinguish such a replayed key from a random one. We remark that, from a security viewpoint, the usage of replayable stages should ideally be limited, although such stages usually come with an efficiency benefit. We use the same shorthand notation as for \(\textsf {USE} \); e.g., \(\textsf {REPLAY} = (\textsf {nonreplayable} : \{1,2,3\})\) indicates that all three stages are non-replayable.
-
\(\textsf {label} \in \textsf {LABELS} \): the unique (administrative) session label
-
\(\textsf {id} \in \mathcal {U}\): the identity of the session owner
-
\(\textsf {pid} \in \mathcal {U}\cup \{*\}\): the identity of the intended communication partner, where the distinct wildcard symbol ‘\(*\)’ stands for “currently unknown identity” but can be later set to a specific identity in \(\mathcal {U}\) once by the protocol
-
\(\textsf {role} \in \{\textsf {initiator} , \textsf {responder} \}\): the session owner’s role in this session
-
\(\textsf {auth} \in \textsf {AUTH} \): the intended authentication type vector from the set of supported authentication properties \(\textsf {AUTH} \), where \(\textsf {auth} _{i}\) indicates the authentication level pair for stage i, and \(\textsf {auth} _{i,j}\) its j-th entry
-
\(\textsf {pssid} \in \{0,1\}^* \cup \{\bot \}\): In the pre-shared secret (sMSKE) variant the identifier for the pre-shared secret (i.e., \(\textsf {pss} _{\textsf {id} ,\textsf {pid} }\) if \(\textsf {role} = \textsf {initiator} \), else \(\textsf {pss} _{\textsf {pid} ,\textsf {id} }\)) to be used in the session; can be initialized with \(\bot \) if \(\textsf {pid} = *\) is unknown and then must be set (once) when \(\textsf {pid} \) is set
-
\(\textsf {st} _{\textsf {exec} }\in (\textsf {RUNNING} \cup \textsf {ACCEPTED} \cup \textsf {REJECTED} )\): the state of execution [\(\textsf {running} _{0}\)], where \(\textsf {RUNNING} = \{\textsf {running} _{i} \mid i \in \mathbb {N}\cup \{0\}\}\), \(\textsf {ACCEPTED} = \{\textsf {accepted} _{i} \mid i \in \mathbb {N}\}\), \(\textsf {REJECTED} = \{\textsf {rejected} _{i} \mid i \in \mathbb {N}\}\); set to \(\textsf {accepted} _{i}\) in the moment a session accepts the i-th key, to \(\textsf {rejected} _{i}\) when the session rejects that key (a session may continue after rejecting in a stage (this models, e.g., servers rejecting 0-RTT data from a client, but continuing with the remaining handshake)), and to \(\textsf {running} _{i}\) when a session continues after accepting the i-th key
-
\(\textsf {stage} \in \{0, \dots , \textsf {M} \}\): the current stage [0], where \(\textsf {stage} \) is incremented to i when \(\textsf {st} _{\textsf {exec} }\) reaches \(\textsf {accepted} _{i}\) resp. \(\textsf {rejected} _{i}\)
-
\(\textsf {sid} \in (\{0,1\}^* \cup \{\bot \})^{\textsf {M} }\): \(\textsf {sid} _{i}\) [\(\bot \)] indicates the session identifier in stage i, set once (and only) upon acceptance in that stage
-
\(\textsf {cid} \in (\{0,1\}^* \cup \{\bot \})^{\textsf {M} }\): \(\textsf {cid} _{i}\) [\(\bot \)] indicates the contributive identifier in stage i, may be set several times until acceptance in that stage
-
\(\textsf {key} \in (\{0,1\}^* \cup \{\bot \})^{\textsf {M} }\): \(\textsf {key} _{i}\) [\(\bot \)] indicates the established session key in stage i, set once upon acceptance in that stage
-
\(\textsf {st} _{\textsf {key} }\in \{\textsf {fresh} , \textsf {revealed} \}^{\textsf {M} }\): \(\textsf {st} _{\textsf {key} ,i}\) [\(\textsf {fresh} \)] indicates the state of the session key in stage i
-
\(\textsf {tested} \in \{\textsf {true} , \textsf {false} \}^{\textsf {M} }\): test indicator \(\textsf {tested} _{i}\) [\(\textsf {false} \)], where \(\textsf {true} \) means that \(\textsf {key} _{i}\) has been tested
-
\(\textsf {corrupted} \in \{0, \dots , \textsf {M} , \infty \}\): corruption indicator [\(\infty \)] holding the stage the session was in when a \(\textsf {Corrupt} \) was issued to its owner or intended partner, including the value 0 if the corruption had taken place before the session started, and \(\infty \) if none of the parties is corrupted
-
for pMSKE, the session’s owner \(\textsf {label} .\textsf {id} \) or intended communication partner \(\textsf {label} .\textsf {pid} \) is corrupted (i.e., \(\{\textsf {label} .\textsf {id} , \textsf {label} .\textsf {pid} \} \cap \textsf {corrupted} \ne \emptyset \)), resp.
-
for sMSKE, the used pre-shared secret is corrupted (i.e., \((\textsf {label} .\textsf {id} , \textsf {label} .\textsf {pid} , \textsf {label} .\) \(\textsf {pssid} ) \in \textsf {corrupted} \), the set of corrupted users) if \(\textsf {label} .\textsf {role} = \textsf {initiator} \), resp. \((\textsf {label} .\textsf {pid} , \textsf {label} .\textsf {id} , \textsf {label} .\textsf {pssid} ) \in \textsf {corrupted} \) if \(\textsf {label} .\textsf {role} = \textsf {responder} \).
4.2 Adversary Model
-
\(\textsf {NewSecret} (U,V,\textsf {pssid} )\): This query is only available in the pre-shared secret (sMSKE) variant. Generates a fresh secret with identifier \(\textsf {pssid} \) shared between parties U and V, to be used by U in the initiator role and by V in the responder role. If \(\textsf {pss} _{U,V}(\textsf {pssid} )\) is already set, return \(\bot \) to ensure uniqueness of \(\textsf {pssid} \) identifiers between two parties in these roles. Otherwise, sample uniformly at random from the protocol’s pre-shared secret space \(\mathcal {P}\) and define \(\textsf {pss} _{U,V}(\textsf {pssid} ) := \textsf {pss} \).
-
\(\textsf {NewSession} (U, V, \textsf {role} , \textsf {auth} {} [, \textsf {pssid} ])\): Creates a new session with a (unique) new label \(\textsf {label} \) for owner identity \(\textsf {id} = U\) with role \(\textsf {role} \), having \(\textsf {pid} = V\) as intended partner (potentially unspecified, indicated by \(V = *\)) and aiming at authentication type \(\textsf {auth} \). In the pre-shared secret (sMSKE) variant, the additional parameter \(\textsf {pssid} \) identifies the pre-shared secret to be used, namely \(\textsf {pss} _{U,V}(\textsf {pssid} )\) if \(\textsf {role} = \textsf {initiator} \), resp. \(\textsf {pss} _{V,U}(\textsf {pssid} )\) if \(\textsf {role} = \textsf {responder} \). The identifier might be unspecified at this point (indicated by \(\textsf {pssid} = \bot \)) and may then be set later by the protocol once. Add \((\textsf {label} ,U,V,\textsf {role} ,\textsf {auth} )\), resp. \((\textsf {label} ,U,V,\textsf {role} ,\textsf {auth} ,\textsf {pssid} )\), to \(\textsf {List} _{\textsf {S} }\). If \(\textsf {label} \) is corrupted, set \(\textsf {label} .\textsf {corrupted} \leftarrow 0\). This encodes the information that the session is corrupt right from the beginning. Return \(\textsf {label} \).
-
\(\textsf {Send} (\textsf {label} , m)\): Sends a message m to the session with label \(\textsf {label} \). If there is no tuple with label \(\textsf {label} \) in \(\textsf {List} _{\textsf {S} }\), return \(\bot \). Otherwise, run the protocol on behalf of U on message m and return the response and the updated state of execution \(\textsf {label} .\textsf {st} _{\textsf {exec} }\). As a special case, if \(\textsf {label} .\textsf {role} = \textsf {initiator} \) and \(m = \textsf {init} \), the protocol is initiated (without any input message). If, during the protocol execution, the state of execution changes to \(\textsf {accepted} _{i}\), the protocol execution is immediately suspended and \(\textsf {accepted} _{i}\) is returned as result to the adversary. The adversary can later trigger the resumption of the protocol execution by issuing a special \(\textsf {Send} (\textsf {label} , \textsf {continue} )\) query. For such a query, the protocol continues as specified, with the party creating the next protocol message and handing it over to the adversary together with the resulting state of execution \(\textsf {st} _{\textsf {exec} }\). We note that this is necessary to allow the adversary to test an internal key, before it may be used immediately in the response and thus cannot be tested anymore to prevent trivial distinguishing attacks. It furthermore allows the adversary to corrupt long-term keys in a fine-grained manner after any acceptance of a key. If the state of execution changes to \(\textsf {label} .\textsf {st} _{\textsf {exec} }= \textsf {accepted} _{i}\) for some i and there is a partnered session \(\textsf {label} ' \ne \textsf {label} \) in \(\textsf {List} _{\textsf {S} }\) (i.e., \(\textsf {label} .\textsf {sid} _{i} = \textsf {label} '.\textsf {sid} _{i}\)) with \(\textsf {label} '.\textsf {tested} _{i} = \textsf {true} \), then set \(\textsf {label} .\textsf {tested} _{i} \leftarrow \textsf {true} \) and (only if \(\textsf {USE} _{i} = \textsf {internal} \)) \(\textsf {label} .\textsf {key} _{i} \leftarrow \textsf {label} '.\textsf {key} _{i}\). This ensures that, if the partnered session has been tested before, subsequent \(\textsf {Test} \) queries for the session are answered accordingly and, in case it is used internally, this session’s key \(\textsf {key} _{i}\) is set consistently. (Note that for internal keys this implicitly assumes the following property of the later-defined \(\textsf {Match} \) security: whenever two partnered sessions both accept a key in some stage, these keys will be equal.) If the state of execution changes to \(\textsf {label} .\textsf {st} _{\textsf {exec} }= \textsf {accepted} _{i}\) for some i and the session \(\textsf {label} \) is corrupted, then set \(\textsf {label} .\textsf {st} _{\textsf {key} ,i} \leftarrow \textsf {revealed} \).
-
\(\textsf {Reveal} (\textsf {label} , i)\): Reveals the session key \(\textsf {label} .\textsf {key} _{i}\) of stage i in the session with label \(\textsf {label} \). If there is no session with label \(\textsf {label} \) in \(\textsf {List} _{\textsf {S} }\) or \(\textsf {label} .\textsf {stage} < i\), then return \(\bot \). Otherwise, set \(\textsf {label} .\textsf {st} _{\textsf {key} ,i}\) to \(\textsf {revealed} \) and provide the adversary with \(\textsf {label} .\textsf {key} _{i}\).
-
\(\textsf {Corrupt} (U)\) or \(\textsf {Corrupt} (U, V, \textsf {pssid} )\): The first query is only used in the public-key (pMSKE) variant, the second query only in the pre-shared secret (sMSKE) variant. Provide the adversary with the corresponding long-term secret, i.e., \(\textsf {sk} _{U}\) (pMSKE), resp. \(\textsf {pss} _{U,V}(\textsf {pssid} )\) (sMSKE). Add to the set of corrupted entities \(\textsf {corrupted} \) the user U (for pMSKE), resp. (for sMSKE) the global pre-shared secret identifier \((U, V, \textsf {pssid} )\). Record the time of corruption in each session \(\textsf {label} \) with \(\textsf {label} .\textsf {id} = U\) or \(\textsf {label} .\textsf {pid} = U\) (pMSKE), resp. with \(\textsf {label} .(\textsf {role} ,\textsf {id} ,\textsf {pid} ,\textsf {pssid} ) \in \{(\textsf {initiator} , U, V, \textsf {pssid} ),\) \((\textsf {responder} , V, U, \textsf {pssid} )\}\) (sMSKE), by setting \(\textsf {label} .\textsf {corrupted} \leftarrow \textsf {label} .\textsf {stage} \) (unless \(\textsf {label} .\textsf {corrupted} \ne \infty \) already, in which case corruption had taken place earlier such that we leave the value unchanged). In the non-forward-secret case, for each such session \(\textsf {label} \) and for all \(i \in \{1, \dots , \textsf {M} \}\), set \(\textsf {label} .\textsf {st} _{\textsf {key} ,i}\) to \(\textsf {revealed} \). I.e., all (previous and future) session keys are considered to be disclosed. In the case of stage-j forward secrecy, \(\textsf {st} _{\textsf {key} ,i}\) of each such session \(\textsf {label} \) is instead set to revealed only if \(i < j\) or if \(i > \textsf {stage} \). This means that session keys before the j-th stage (where forward secrecy kicks in) as well as keys that have not yet been established are potentially disclosed.
-
\(\textsf {Test} (\textsf {label} , i)\): Tests the session key of stage i in the session with label \(\textsf {label} \). In the security game this oracle is given a uniformly random test bit \(b_{\textsf {test} }\) as state which is fixed throughout the game. If there is no session with label \(\textsf {label} \) in \(\textsf {List} _{\textsf {S} }\) or if \(\textsf {label} .\textsf {st} _{\textsf {exec} }\ne \textsf {accepted} _{i}\) or \(\textsf {label} .\textsf {tested} _{i} = \textsf {true} \), return \(\bot \). If stage i is internal (i.e., \(\textsf {USE} ^i = \textsf {internal} \)) and there is a partnered session \(\textsf {label} '\) in \(\textsf {List} _{\textsf {S} }\) (i.e., \(\textsf {label} .\textsf {sid} _{i} = \textsf {label} '.\textsf {sid} _{i}\)) with \(\textsf {label} '.\textsf {st} _{\textsf {exec} }\ne \textsf {accepted} _{i}\), set the ‘lost’ flag to \(\textsf {lost} \leftarrow \textsf {true} \). This ensures that keys can only be tested once and, in case of internal keys, if they have just been accepted but not used yet, ensuring also that any partnered session that may have already established this key has not used it. If \(\textsf {label} .{ \textsf {rect\_auth} _{i}} = \textsf {unauth} \), or if \(\textsf {label} .{ \textsf {rect\_auth} _{i}} = \textsf {unilateral} \) and \(\textsf {label} .\textsf {role} = \textsf {responder} \), but there is no session \(\textsf {label} '\) (for \(\textsf {label} \ne \textsf {label} '\)) in \(\textsf {List} _{\textsf {S} }\) with \(\textsf {label} .\textsf {cid} _{i} = \textsf {label} '.\textsf {cid} _{i}\), then set \(\textsf {lost} \leftarrow \textsf {true} \). This ensures that having an honest contributive partner is a prerequisite for testing unauthenticated stages, resp. the responder sessions in a unilaterally authenticated stage. (Note that \(\textsf {List} _{\textsf {S} }\) entries are only created for honest sessions, i.e., sessions generated by \(\textsf {NewSession} \) queries.) The check is based on the uncorrupted authentication level \( \textsf {rect\_auth} _{i}\) in order to take corruptions between authentication upgrades into account. Otherwise, set \(\textsf {label} .\textsf {tested} _{i}\) to \(\textsf {true} \). If the test bit \(b_{\textsf {test} }\) is 0, sample a key at random from the session key distribution \(\mathcal {D}\). If \(b_{\textsf {test} }= 1\), let \(K \leftarrow \textsf {label} .\textsf {key} _{i}\) be the real session key. If \(\textsf {USE} _{i} = \textsf {internal} \) (i.e., the tested i-th key is indicated as being used internally), set \(\textsf {label} .\textsf {key} _{i} \leftarrow K\); in other words, when \(b_{\textsf {test} }= 0\), we replace an internally used session key by the random and independent test key K which is also used for consistent future usage within the key exchange protocol. In contrast, externally used session keys are not replaced by random ones, the adversary only receives the real (in case \(b_{\textsf {test} }=1\)) or random (in case \(b_{\textsf {test} }=0\)) key. This distinction between internal and external keys for \(\textsf {Test} \) queries emphasizes that external keys are not supposed to be used within the key exchange (and hence there is no need to register the tested random key in the protocol’s session key field), while internal keys will be used (and hence the tested random key must be deployed in the remaining protocol steps for consistency). Moreover, if there exists a partnered session \(\textsf {label} '\) which has also just accepted the i-th key (i.e., \(\textsf {label} .\textsf {sid} _{i} = \textsf {label} '.\textsf {sid} _{i}\) and \(\textsf {label} .\textsf {st} _{\textsf {exec} }= \textsf {label} '.\textsf {st} _{\textsf {exec} }= \textsf {accepted} _{i}\)), then also set \(\textsf {label} '.\textsf {tested} _{i} \leftarrow \textsf {true} \) and (only if \(\textsf {USE} _{i} = \textsf {internal} \)) \(\textsf {label} '.\textsf {key} _{i} \leftarrow \textsf {label} .\textsf {key} _{i}\) to ensure consistency (of later tests and (internal) key usage) in the special case that both \(\textsf {label} \) and \(\textsf {label} '\) are in state \(\textsf {accepted} _{i}\) and, hence, either of them can be tested first. Return K.
4.3 Security of Multi-Stage Key Exchange Protocols
4.3.1 Match Security
-
\(\textsf {label} .\textsf {auth} _{j,1} \le i\) (unilateral authentication), but \(\textsf {label} .\textsf {pid} \ne \textsf {label} '.\textsf {id} \), or
-
\(\textsf {label} .\textsf {auth} _{j,2} \le i\) (mutual authentication), but \(\textsf {label} .\textsf {id} \ne \textsf {label} '.\textsf {pid} \) or (only for sMSKE) \(\textsf {label} .\textsf {pssid} \ne \textsf {label} '.\textsf {pssid} \).(Different intended authenticated partner or (only sMSKE) different key identifiers in mutual authentication.)
4.3.2 Multi-Stage Security
5 Security Analysis of the TLS 1.3 Full 1-RTT Handshake
-
\(\textsf {M} = 6\): The full 1-RTT handshake consists of six stages deriving, in order: the client and server handshake traffic keys \(\mathrm {tk}_{\text {chs}}\) and \(\mathrm {tk}_{\text {shs}}\), the client and server application traffic secrets \(\mathrm {CATS}\) and \(\mathrm {SATS}\), the exporter master secret \(\mathrm {EMS}\), and the resumption master secret \(\mathrm {RMS}\). As shown in Fig. 1, we consider all stages’ keys being derived on either side as soon as the relevant main secret (\(\mathrm {ES}\), \(\mathrm {HS}\), \(\mathrm {MS}\)) becomes available, despite client/server keys derived in parallel might become active with some delay based on the flow direction.
-
\(\textsf {AUTH} = \big \{ ((3,m), (3,m), (3,m), (4,m), (5,m), (6,m)) \mid m \in \{6, \infty \} \big \}\): The handshake traffic keys \(\mathrm {tk}_{\text {chs}}\)/\(\mathrm {tk}_{\text {shs}}\) are initially unauthenticated and all keys are unilaterally authenticated after stage 3 is reached. With (optional) client authentication, all keys furthermore become mutually authenticated with stage \(m=6\); otherwise they never reach this level, \(m=\infty \).
-
\(\textsf {FS} = 1\): The full 1-RTT handshake ensures forward secrecy for all keys derived.
-
\(\textsf {USE} = (\textsf {internal} : \{1,2\}, \textsf {external} : \{3,4,5,6\})\): The handshake traffic keys are used internally to encrypt the second part of the handshake; all other keys are external.
-
\(\textsf {REPLAY} = (\textsf {nonreplayable} : \{1,2,3,4,5,6\})\): The keys of all stages are non-replayable in the full 1-RTT handshake.
5.1 Match Security
TLS1.3
-full
- 1RTT
). The TLS 1.3 full 1-RTT handshake is \(\textsf {Match} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. For any efficient adversary \(\mathcal {A}\), we haveTLS1.3
-full
-1RTT
, The security bound arises as the birthday bound for two honest sessions choosing the same nonce and group element; this not happening ensures at most two partners share the same session identifier.5.2 Multi-Stage Security
TLS1.3
-full
-1RTT
). The TLS 1.3 full 1-RTT handshake is \(\textsf {Multi} \text {-}\textsf {Stage} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. Formally, for any efficient adversary \(\mathcal {A}\) against the \(\textsf {Multi} \text {-}\textsf {Stage} \) security there exist efficient algorithms \(\mathcal {B}_{1}\), ..., \(\mathcal {B}_{7}\) such that6 Security Analysis of the TLS 1.3 PSK/PSK-(EC)DHE (with Optional 0-RTT) Handshakes
-
\(\textsf {M} = 8\): The PSK handshakes with optional 0-RTT consist of eight stages deriving, in order: the early traffic secret \(\mathrm {ETS}\) and early exporter master secret \(\mathrm {EEMS}\) (both only in 0-RTT mode), the client and server handshake traffic keys \(\mathrm {tk}_{\text {chs}}\) and \(\mathrm {tk}_{\text {shs}}\), the client and server application traffic secrets \(\mathrm {CATS}\) and \(\mathrm {SATS}\), the exporter master secret \(\mathrm {EMS}\), and the resumption master secret \(\mathrm {RMS}\).
-
The authentication properties \(\textsf {AUTH} \) differ between the PSK(-only) and the PSK-(EC)DHE (0-RTT) handshakes:
-
– for PSK (0-RTT), \(\textsf {AUTH} = \big \{((1,1), (2,2), \ldots , (8,8))\big \}\): All keys are immediately mutually authenticated (from the pre-shared key).
-
– for PSK-(EC)DHE (0-RTT), \(\textsf {AUTH} = \big \{ ((1,1),(2,2),(5,8),(5,8),(5,8),(6,8),(7,8),(8,8)) \big \}\): The 0-RTT keys \(\mathrm {ETS}\)/\(\mathrm {EEMS}\) are always mutually authenticated, the handshake traffic keys \(\mathrm {tk}_{\text {chs}}\)/\(\mathrm {tk}_{\text {shs}}\) are initially unauthenticated, all non-0-RTT keys reach unilateral authentication with stage 5 and mutual authentication with stage 8. (It is not straightforward to see why some PSK-(EC)DHE keys are not considered to be immediately mutually authenticated, in contrast to keys from the PSK-only handshake. Consider the handshake traffic keys in the PSK-(EC)DHE handshake: in the model, the adversary \(\mathcal {A}\) could send its own \(g^x\) share to a server session; the server will derive the handshake traffic keys from \(\mathrm {PSK}\) and \(\mathrm {DHE}\). Those keys should now be considered forward secret (due to the ephemeral DH shares); however, when \(\mathcal {A}\) corrupts \(\mathrm {PSK}\), it can compute the handshake traffic keys. Hence, these keys cannot be treated as forward secret and mutually authenticated at the same time.
-
-
Forward secrecy of the PSK handshake depends on whether an ephemeral Diffie–Hellman key exchange is performed:
-
– for PSK-only, \(\textsf {FS} = \infty \): The PSK-only handshake does not provide any forward secrecy.
-
– for PSK-(EC)DHE, \(\textsf {FS} = 3\): The PSK-(EC)DHE handshake provides forward secrecy for all non–0-RTT keys.
-
-
\(\textsf {USE} = (\textsf {internal} : \{3,4\}, \textsf {external} : \{1,2,5,6,7,8\})\): The handshake traffic keys are used internally to encrypt the second part of the handshake; all other keys are external.
-
\(\textsf {REPLAY} = (\textsf {replayable} : \{1,2\}, \textsf {nonreplayable} : \{3,4,5,6,7,8\})\): The 0-RTT keys \(\mathrm {ETS}\) and \(\mathrm {EEMS}\) are replayable, all other stages’ keys are not.
6.1 TLS 1.3 PSK-only (0-RTT optional)
6.1.1 Match Security
TLS1.3
-PSK
-0RTT
). The TLS 1.3 PSK-only 0-RTT handshake is \(\textsf {Match} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. For any efficient adversary \(\mathcal {A}\), there exists an efficient algorithm \(\mathcal {B}\) such thatTLS1.3
-full
-1RTT
, the security bound arises as the birthday bound for two honest sessions choosing the same nonce; this not happening ensures at most two partners share the same session identifier.6.1.2 Multi-Stage Security
TLS1.3
-PSK
-0RTT
). The TLS 1.3 PSK 0-RTT handshake is \(\textsf {Multi} \text {-}\textsf {Stage} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. Formally, for any efficient adversary \(\mathcal {A}\) against the \(\textsf {Multi} \text {-}\textsf {Stage} \) security there exist efficient algorithms \(\mathcal {B}_{1}\), ..., \(\mathcal {B}_{8}\) such that6.2 TLS 1.3 PSK-(EC)DHE (0-RTT optional)
6.2.1 Match Security
TLS1.3
-PSK
-(EC)DHE
-0RTT
). The TLS 1.3 PSK-(EC)DHE 0-RTT handshake is \(\textsf {Match} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. For any efficient adversary \(\mathcal {A}\), there exists an efficient algorithm \(\mathcal {B}\) such that6.2.2 Multi-Stage Security
TLS1.3
-PSK
-(EC)DHE
-0RTT
). The TLS 1.3 PSK-(EC)DHE 0-RTT handshake is \(\textsf {Multi} \text {-}\textsf {Stage} \)-secure with properties \((\textsf {M} ,\textsf {AUTH} ,\textsf {FS} ,\textsf {USE} ,\textsf {REPLAY} )\) given above. Formally, for any efficient adversary \(\mathcal {A}\) against the \(\textsf {Multi} \text {-}\textsf {Stage} \) security there exist efficient algorithms \(\mathcal {B}_{1}\), ..., \(\mathcal {B}_{16}\) such that7 Discussion and Conclusions
7.1 Technical Differences from Our Earlier Work
draft
-05
in [38], draft
-10
and draft
-dh
in [39], and draft
-14
in [53], compared to the final version of TLS 1.3 analyzed in this paper. We focus on three main aspects: the stages identified for the multi-stage analysis, the session identifiers of those stages, and the assumptions used in the security proofs. For the stages and session identifiers, the changes across our series of works are directly related to how the protocol flows and key schedule evolved.draft
-dh
and \(\texttt {draft} \text {-}\texttt {10} \text {-}\texttt {(EC)DHE} \) added the exporter master secret \(\mathrm {EMS}\). In this paper we have 6 stages capturing the final RFC’s main handshake: handshake traffic keys \(\mathrm {tk}_{\text {chs}}\) and \(\mathrm {tk}_{\text {shs}}\); application traffic secrets \(\mathrm {CATS}\) and \(\mathrm {SATS}\); and \(\mathrm {EMS}\) and \(\mathrm {RMS}\). The main reason this paper has 2 stages for the handshake traffic keys and 2 stages for the application traffic secrets is a change to the key schedule: the earlier drafts had 4 secrets (client write key, client write IV, server write key, server write IV) derived from each of two secrets (handshake traffic key and application traffic key), whereas TLS 1.3 has 2 secrets (write key, write IV) derived from each of four secrets (\(\mathrm {tk}_{\text {chs}}, \mathrm {tk}_{\text {shs}}, \mathrm {CATS}, \mathrm {SATS}\)).draft
-dh
, \(\texttt {draft} \text {-}\texttt {10} \text {-}\texttt {(EC)DHE} \), and this paper remain the same. (In early papers we used the notation \(\textsf {PRF} \text { -}\textsf {ODH} \) rather than the newer notation \({\textsf {snPRF} \text {-}\textsf {ODH} }\) introduced by [17], but the actual assumption was the same.)draft
-05
, no (EC)DHE variant of the PSK handshake was present (then called “session resumption handshake”), so the proof of \(\texttt {draft} \text {-}\texttt {05} \text {-}\texttt {SR} \) relied solely on symmetric-key assumptions. \(\texttt {draft} \text {-}\texttt {10} \text {-}\texttt {PSK} \) relied on the same assumptions as \(\texttt {draft} \text {-}\texttt {05} \text {-}\texttt {SR} \), whereas \(\texttt {draft} \text {-}\texttt {10} \text {-}\texttt {PSK} \text {-}\texttt {(EC)DHE} \) added an \({\textsf {EUF} \text {-}\textsf {CMA} }\) assumption on \(\textsf {HMAC} \) as well as the \(\textsf {PRF} \text { -}\textsf {ODH} \) assumption. \(\texttt {draft} \text {-}\texttt {14} \text {-}\texttt {PSK} \text {-}\texttt {0RTT} \) and \(\texttt {draft} \text {-}\texttt {14} \text {-}\texttt {PSK} \text {-}\texttt {(EC)DHE} \text {-}\texttt {0RTT} \) added a randomness assumption on \(\textsf {HMAC} \), which in the analysis of the final RFC’s \(\texttt {TLS1.3} \text {-}\texttt {PSK} \text {-}\texttt {0RTT} \) and \(\texttt {TLS1.3} \text {-}\texttt {PSK} \text {-}\texttt {(EC)DHE} \text {-}\texttt {0RTT} \) in this paper is superseded by a \({\textsf {dual} \text {-}\textsf {PRF} \text {-}\textsf {sec} }\) assumption on \(\textsf {HKDF} .\textsf {Extract} \) in the multi-stage security bounds. The latter more explicitly indicates those places where \(\textsf {HKDF} .\textsf {Extract} \) is keyed through the second argument, which were treated more implicitly in the theorem statements of earlier versions.7.2 Comments on the TLS 1.3 Design
draft
-05
, each exported key was derived directly from the master secret \(\mathrm {MS}\). Since \(\mathrm {MS}\) was also used to derive other keys, it could not be considered as an output stage key, so every exported key had to be included directly in the main analysis. Contrast this with the final approach in which an exporter master secret \(\mathrm {EMS}\) is derived from \(\mathrm {MS}\), and then all exported keys are derived from \(\mathrm {EMS}\): we can treat \(\mathrm {EMS}\) as an output stage key, and consider the derivation of exported keys as a symmetric protocol using \(\mathrm {EMS}\) that is composed with the TLS 1.3 handshake protocol.)tls-unique
[8] and proposed tls-unique-prf
[65] TLS channel binding methods do not use keys directly for binding, the low cost of including the session hash seems worth it in case an application developer decides to use keying material directly for binding.draft
-13
in favor of performance and structural simplification.