Internet-Draft | AuthKEM | August 2023 |
Wiggers, et al. | Expires 19 February 2024 | [Page] |
This document gives a construction for a Key Encapsulation Mechanism (KEM)-based authentication mechanism in TLS 1.3. This proposal authenticates peers via a key exchange protocol, using their long-term (KEM) public keys.¶
This note is to be removed before publishing as an RFC.¶
Status information for this document may be found at https://datatracker.ietf.org/doc/draft-celi-wiggers-tls-authkem/.¶
Discussion of this document takes place on the tlswg Working Group mailing list (mailto:[email protected]), which is archived at https://mailarchive.ietf.org/arch/browse/tls/. Subscribe at https://www.ietf.org/mailman/listinfo/tls/.¶
Source for this draft and an issue tracker can be found at https://github.com/kemtls/draft-celi-wiggers-tls-authkem.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 19 February 2024.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Note: This is a work-in-progress draft. We welcome discussion, feedback and contributions through the IETF TLS working group mailing list or directly on GitHub.¶
This document gives a construction for KEM-based authentication in TLS 1.3 [RFC8446]. Authentication happens via asymmetric cryptography by the usage of KEMs advertised as the long-term KEM public keys in the Certificate.¶
TLS 1.3 is in essence a signed key exchange protocol (if using certificate-based authentication). Authentication in TLS 1.3 is achieved by signing the handshake transcript with digital signatures algorithms. KEM-based authentication provides authentication by deriving a shared secret that is encapsulated against the public key contained in the Certificate. Only the holder of the private key corresponding to the certificate's public key can derive the same shared secret and thus decrypt its peer's messages.¶
This approach is appropriate for endpoints that have KEM public keys. Though this is currently rare, certificates can be issued with (EC)DH public keys as specified for instance in [RFC8410], or using a delegation mechanism, such as delegated credentials [I-D.ietf-tls-subcerts].¶
In this proposal, we build on [RFC9180]. This standard currently only covers Diffie-Hellman based KEMs, but the first post-quantum algorithms have already been put forward [I-D.draft-westerbaan-cfrg-hpke-xyber768d00]. This proposal uses Kyber [KYBER] [I-D.draft-cfrg-schwabe-kyber], the first selected algorithm for key exchange in the NIST post-quantum standardization project [NISTPQC].¶
The elliptic-curve and finite-field-based key exchange and signature algorithms that are currently widely used are very similar in sizes for public keys, ciphertexts and signatures. As an example, RSA signatures are famously "just" RSA encryption backwards.¶
This changes in the post-quantum setting. Post-quantum key exchange and signature algorithms have significant differences in implementation, performance characteristics, and key and signature sizes.¶
This also leads to increases in code size: For example, implementing highly efficient polynomial multiplication for post-quantum KEM Kyber and signature scheme Dilithium [DILITHIUM] requires significantly different approaches, even though the algorithms are related [K22].¶
Using the protocol proposed in this draft allows to reduce the amount of data exchanged for handshake authentication. It also allows to re-use the implementation that is used for ephemeral key exchange for authentication, as KEM operations replace signing. This decreases the code size requirements, which is especially relevant to protected implementations. Finally, KEM operations may be more efficient than signing, which might especially affect embedded platforms.¶
Should probably be removed before publishing¶
In the following table, we compare the sizes of TLS 1.3- and AuthKEM-based handshakes. We give the transmission requirements for handshake authentication (public key + signature), and certificate chain (intermediate CA certificate public key and signature + root CA signature). For clarity, we are not listing post-quantum/traditional hybrid algorithms; we also omit mechanisms such as Certificate Transparency [RFC6962] or OCSP stapling [RFC6960]. We use Kyber-768 instead of the smaller Kyber-512 parameterset, as the former is currently used in experimental deployments. For signatures, we use Dilithium, the "primary" algorithm selected by NIST for post-quantum signatures, as well as Falcon [FALCON], the algorithm that offers smaller public key and signature sizes, but which NIST indicates can be used if the implementation requirements can be met.¶
Handshake | HS auth algorithm | HS Auth bytes | Certificate chain bytes | Sum |
---|---|---|---|---|
TLS 1.3 | RSA-2048 | 528 | 784 (RSA-2048) | 1312 |
TLS 1.3 | Dilithium-2 | 3732 | 6152 (Dilithium-2) | 9884 |
TLS 1.3 | Falcon-512 | 1563 | 2229 (Falcon-512) | 3792 |
TLS 1.3 | Dilithium-2 | 3732 | 2229 (Falcon-512) | 5961 |
AuthKEM | Kyber-768 | 2272 | 6152 (Dilithium-2) | 8424 |
AuthKEM | Kyber-768 | 2272 | 2229 (Falcon-512) | 4564 |
Note that although TLS 1.3 with Falcon-512 is the smallest instantiation, Falcon is very challenging to implement: signature generation requires (emulation of) 64-bit floating point operations in constant time. It is also very difficult to protect against other side-channel attacks, as there are no known methods of masking Falcon. In light of these difficulties, use of Falcon-512 in online handshake signatures may not be wise.¶
Using AuthKEM with Falcon-512 in the certificate chain remains an attractive option, however: the certificate issuance process, because it is mostly offline, could perhaps be set up in a way to protect the Falcon implementation against attacks. Falcon signature verification is fast and does not require floating-point arithmetic. Avoiding online usage of Falcon in TLS 1.3 requires two implementations of the signature verification routines, i.e., Dilithium and Falcon, on top of the key exchange algorithm.¶
In all examples, the size of the certificate chain still dominates the TLS handshake, especially if Certificate Transparency SCT statements are included, which is relevant in the context of the WebPKI. However, we believe that if proposals to reduce transmission sizes of the certificate chain in the WebPKI context are implemented, the space savings of AuthKEM naturally become relatively larger and more significant. We discuss this in Section 1.3.2.¶
After a brief introduction to KEMs, we will introduce the AuthKEM authentication mechanism. For clarity, we discuss unilateral and mutual authentication separately. In the remainder of the draft, we will discuss the necessary implementation mechanics, such as code points, extensions, new protocol messages and the new key schedule. The draft concludes with ah extensive discussion of relevant security considerations.¶
A related mechanism for KEM-based PSK-style handshakes is discussed in [I-D.draft-wiggers-tls-authkem-psk].¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The following terms are used as they are in [RFC8446]¶
The endpoint initiating the TLS connection.¶
A transport-layer connection between two endpoints.¶
Either the client or server of the connection.¶
An initial negotiation between client and server that establishes the parameters of their subsequent interactions within TLS.¶
An endpoint. When discussing a particular endpoint, "peer" refers to the endpoint that is not the primary subject of discussion.¶
An endpoint that is receiving records.¶
An endpoint that is transmitting records.¶
The endpoint that responded to the initiation of the TLS connection. i.e. the peer of the client.¶
As this proposal relies heavily on KEMs, which are not originally used by TLS, we will provide a brief overview of this primitive. Other cryptographic operations will be discussed later.¶
A Key Encapsulation Mechanism (KEM) is a cryptographic primitive that defines
the methods Encapsulate
and Decapsulate
. In this draft, we extend these
operations with context separation strings, per HPKE [RFC9180]:¶
Encapsulate(pkR, context_string)
:Takes a public key, and produces a shared secret and encapsulation.¶
Decapsulate(enc, skR, context_string)
:Takes the encapsulation and the private key. Returns the shared secret.¶
We implement these methods through the KEMs defined in [RFC9180] to export shared secrets appropriate for using with the HKDF in TLS 1.3:¶
def Encapsulate(pk, context_string): enc, ctx = HPKE.SetupBaseS(pk, "tls13 auth-kem " + context_string) ss = ctx.Export("", HKDF.Length) return (enc, ss) def Decapsulate(enc, sk, context_string): return HPKE.SetupBaseR(enc, sk, "tls13 auth-kem " + context_string) .Export("", HKDF.Length)¶
Keys are generated and encoded for transmission following the conventions in
[RFC9180]. The values of context_string
are defined in
Section 4.3.2.¶
Figure 1 below shows the basic KEM-authentication (AuthKEM) handshake, without client authentication:¶
Client Server Key ^ ClientHello Exch | + key_share v + signature_algorithms --------> ServerHello ^ Key + key_share v Exch <EncryptedExtensions> <Certificate> ^ <KEMEncapsulation> --------> | {Finished} --------> | Auth [Application Data] --------> | <-------- {Finished} v [Application Data] <-------> [Application Data] + Indicates noteworthy extensions sent in the previously noted message. <> Indicates messages protected using keys derived from a [sender]_handshake_traffic_secret. {} Indicates messages protected using keys derived from a [sender]_authenticated_handshake_traffic_secret. [] Indicates messages protected using keys derived from [sender]_application_traffic_secret_N. Figure 1: Message Flow for KEM-Authentication (KEM-Auth) Handshake without client authentication.¶
This basic handshake captures the core of AuthKEM. Instead of using a signature
to authenticate the handshake, the client encapsulates a shared secret to the
server's certificate public key. Only the server that holds the private key
corresponding to the certificate public key can derive the same shared secret.
This shared secret is mixed into the handshake's key schedule. The client does
not have to wait for the server's Finished
message before it can send data.
The client knows that its message can only be decrypted if the server was able
to derive the authentication shared secret encapsulated in the
KEMEncapsulation
message.¶
Finished
messages are sent as in TLS 1.3, and achieve full explicit
authentication.¶
For client authentication, the server sends the CertificateRequest
message
as in [RFC8446]. This message can not be authenticated in the AuthKEM
handshake: we will discuss the implications below.¶
As in [RFC8446], section 4.4.2, if and only if the client receives
CertificateRequest
, it MUST send a Certificate
message. If the client
has no suitable certificate, it MUST send a Certificate
message containing
no certificates. If the server is satisfied with the provided certificate, it
MUST send back a KEMEncapsulation
message, containing the encapsulation to
the client's certificate. The resulting shared secret is mixed into the key
schedule. This ensures any messages sent using keys derived from it are covered
by the authentication.¶
The AuthKEM handshake with client authentication is given in Figure 2.¶
Client Server Key ^ ClientHello Exch | + key_share v + signature_algorithms --------> ServerHello ^ Key + key_share v Exch <EncryptedExtensions> ^ Server <CertificateRequest> v Params <Certificate> ^ ^ <KEMEncapsulation> | | {Certificate} --------> | Auth | <-------- {KEMEncapsulation} | Auth v {Finished} --------> | [Application Data] --------> | <------- {Finished} v [Application Data] <-------> [Application Data] + Indicates noteworthy extensions sent in the previously noted message. <> Indicates messages protected using keys derived from a [sender]_handshake_traffic_secret. {} Indicates messages protected using keys derived from a [sender]_authenticated_handshake_traffic_secret. [] Indicates messages protected using keys derived from [sender]_application_traffic_secret_N. Figure 2: Message Flow for KEM-Authentication (KEM-Auth) Handshake with client authentication.¶
If the server is not satisfied with the client's certificates, it MAY, at its
discretion, decide to continue or terminate the handshake. If it decides to
continue, it MUST NOT send back a KEMEncapsulation
message and the client
and server MUST compute the encryption keys as in the server-only authenticated
AuthKEM handshake. The Certificate
remains included in the transcript. The
client MUST NOT assume it has been authenticated.¶
Unfortunately, AuthKEM client authentication requires an extra round-trip. Clients that know the server's long-term public KEM key MAY choose to use the abbreviated AuthKEM handshake and opportunistically send the client certificate as a 0-RTT-like message. This mechanism is discussed in [I-D.draft-wiggers-authkem-psk-latest].¶
After the Key Exchange and Server Parameters phase of TLS 1.3 handshake, the client and server exchange implicitly authenticated messages. KEM-based authentication uses the same set of messages every time that certificate-based authentication is needed. Specifically:¶
Certificate
: The certificate of the endpoint and any per-certificate
extensions. This message MUST be omitted by the client if the server did not
send a CertificateRequest
message (thus indicating that the client should
not authenticate with a certificate). For AuthKEM, Certificate
MUST include
the long-term KEM public key. Certificates MUST be handled in accordance with
[RFC8446], section 4.4.2.4.¶
KEMEncapsulation
: A key encapsulation against the certificate's long-term
public key, which yields an implicitly authenticated shared secret.¶
signature_algorithms
for KEMs.¶
KEMEncapsulation
.¶
Certificate
is sent encrypted with a new handshake encryption key.¶
Finished
before the server.¶
Finished
.¶
The data that the client MAY transmit to the server before having received the
server's Finished
is encrypted using ciphersuites chosen based on the
client's and server's advertised preferences in the ClientHello
and
ServerHello
messages. The ServerHello
message can however not be
authenticated before the Finished
message from the server is verified. The
full implications of this are discussed in the Security Considerations section.¶
Upon receiving the client's authentication messages, the server responds with
its Finished
message, which achieves explicit authentication. Upon receiving
the server's Finished
message, the client achieves explicit authentication.
Receiving this message retroactively confirms the server's cryptographic
parameter choices.¶
CertificateRequest
The CertificateRequest
message can not be authenticated during the AuthKEM
handshake; only after the Finished
message from the server has been
processed, it can be proven as authentic. The security implications of this are
discussed later.¶
This is discussed in GitHub issue #16. We would welcome feedback there.¶
Clients MAY choose to only accept post-handshake authentication.¶
TODO: Should they indicate this? TLS Flag?¶
In this section we will discuss the implementation details such as extensions and key schedule.¶
Clients will indicate support for this mode by negotiating it as if it were a
signature scheme (part of the signature_algorithms
extension). We thus add
these new signature scheme values (even though, they are not signature schemes)
for the KEMs defined in [RFC9180] Section 7.1. Note that we will be only
using their internal KEM's API defined there.¶
enum { dhkem_p256_sha256 => TBD, dhkem_p384_sha384 => TBD, dhkem_p521_sha512 => TBD, dhkem_x25519_sha256 => TBD, dhkem_x448_sha512 => TBD, kem_x25519kyber768 => TBD, /*draft-westerbaan-cfrg-hpke-xyber768d00*/ }¶
Please give feedback on which KEMs should be included¶
When present in the signature_algorithms
extension, these values indicate
AuthKEM support with the specified key exchange mode. These values MUST NOT
appear in signature_algorithms_cert
, as this extension specifies the signing
algorithms by which certificates are signed.¶
The handshake protocol is used to negotiate the security parameters of a
connection, as in TLS 1.3. It uses the same messages, expect for the addition of
a KEMEncapsulation
message and does not use the CertificateVerify
one.¶
enum { ... kem_encapsulation(tbd), ... (255) } HandshakeType; struct { HandshakeType msg_type; /* handshake type */ uint24 length; /* remaining bytes in message */ select (Handshake.msg_type) { ... case kem_encapsulation: KEMEncapsulation; ... }; } Handshake;¶
Protocol messages MUST be sent in the order defined in Section 4. A peer which
receives a handshake message in an unexpected order MUST abort the handshake
with a "unexpected_message
" alert.¶
The KEMEncapsulation
message is defined as follows:¶
struct { opaque certificate_request_context<0..2^8-1> opaque encapsulation<0..2^16-1>; } KEMEncapsulation;¶
The encapsulation field is the result of a Encapsulate
function. The
Encapsulate()
function will also result in a shared secret (ssS
or ssC
,
depending on the peer) which is used to derive the AHS
or MS
secrets (See
Section 4.3.1).¶
If the KEMEncapsulation
message is sent by a server, the authentication
algorithm MUST be one offered in the client's signature_algorithms
extension.
Otherwise, the server MUST terminate the handshake with an
"unsupported_certificate
" alert.¶
If sent by a client, the authentication algorithm used in the signature MUST be
one of those present in the supported_signature_algorithms
field of the
signature_algorithms
extension in the CertificateRequest
message.¶
In addition, the authentication algorithm MUST be compatible with the key(s) in the sender's end-entity certificate.¶
The receiver of a KEMEncapsulation
message MUST perform the Decapsulate()
operation by using the sent encapsulation and the private key of the public key
advertised in the end-entity certificate sent. The Decapsulate()
function will
also result on a shared secret (ssS
or ssC
, depending on the Server or
Client executing it respectively) which is used to derive the AHS
or MS
secrets.¶
certificate_request_context
is included to allow the recipient to identify the
certificate against which the encapsulation was generated. It MUST be set to the
value in the Certificate
message to which the encapsulation was computed.¶
The AuthKEM handshake establishes three input secrets which are combined to create the actual working keying material, as detailed below. The key derivation process incorporates both the input secrets and the handshake transcript. Note that because the handshake transcript includes the random values from the Hello messages, any given handshake will have different traffic secrets, even if the same input secrets are used.¶
AuthKEM uses the same HKDF-Extract
and HKDF-Expand
functions as defined by
TLS 1.3, in turn defined by [RFC5869].¶
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.¶
The notable differences are:¶
Authenticated Handshake Secret
and a new set of
handshake traffic encryption keys.¶
SSs
and SSc
(if present) shared secrets as IKM to
Authenticated Handshake Secret
and Main Secret
, respectively.¶
The full key schedule proceeds as follows:¶
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", "") = dHS | v SSs -> HKDF-Extract = Authenticated Handshake Secret | +--> Derive-Secret(., "c ahs traffic", | ClientHello...KEMEncapsulation) | = client_handshake_authenticated_traffic_secret | +--> Derive-Secret(., "s ahs traffic", | ClientHello...KEMEncapsulation) | = server_handshake_authenticated_traffic_secret v Derive-Secret(., "derived", "") = dAHS | v SSc||0 * -> HKDF-Extract = Main 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 *: if client authentication was requested, the `SSc` value should be used. Otherwise, the `0` value is used.¶
The operations to compute SSs
or SSc
from the client are:¶
SSs, encapsulation <- Encapsulate(public_key_server, "server authentication") SSc <- Decapsulate(encapsulation, private_key_client, "client authentication")¶
The operations to compute SSs
or SSc
from the server are:¶
SSs <- Decapsulate(encapsulation, private_key_server "server authentication") SSc, encapsulation <- Encapsulate(public_key_client, "client authentication")¶
AuthKEM upgrades implicit to explicit authentication through the Finished
message. Note that in the full handshake, AuthKEM achieves explicit
authentication only when the server sends the final Finished
message (the
client is only implicitly authenticated when they send their Finished
message).¶
Full downgrade resilience and forward secrecy is achieved once the AuthKEM handshake completes.¶
The key used to compute the Finished
message MUST be computed from the
MainSecret
using HKDF (instead of a key derived from HS as in [RFC8446]).
Specifically:¶
server/client_finished_key = HKDF-Expand-Label(MainSecret, server/client_label, "", Hash.length) server_label = "tls13 server finished" client_label = "tls13 client finished"¶
The verify_data
value is computed as follows. Note that instead of what is
specified in [RFC8446], we use the full transcript for both server and client
Finished messages:¶
server/client_verify_data = HMAC(server/client_finished_key, Transcript-Hash(Handshake Context, Certificate*, KEMEncapsulation*, Finished**)) * Only included if present. ** The party who last sends the finished message in terms of flights includes the other party's Finished message.¶
Any records following a Finished
message MUST be encrypted under the
appropriate application traffic key as described in [RFC8446]. In particular,
this includes any alerts sent by the server in response to client
Certificate
and KEMEncapsulation
messages.¶
See [SSW20] for a full treatment of implicit and explicit authentication.¶
Because preserving a 1/1.5RTT handshake in KEM-Auth requires the client to send
its request in the same flight when the ServerHello
message is received, it
can not yet have explicitly authenticated the server. However, through the
inclusion of the key encapsulated to the server's long-term secret, only an
authentic server should be able to decrypt these messages.¶
However, the client can not have received confirmation that the server's choices
for symmetric encryption, as specified in the ServerHello
message, were
authentic. These are not authenticated until the Finished
message from the
server arrived. This may allow an adversary to downgrade the symmetric
algorithms, but only to what the client is willing to accept. If such an attack
occurs, the handshake will also never successfully complete and no data can be
sent back.¶
If the client trusts the symmetric algorithms advertised in its ClientHello
message, this should not be a concern. A client MUST NOT accept any
cryptographic parameters it does not include in its own ClientHello
message.¶
If client authentication is used, explicit authentication is reached before any application data, on either client or server side, is transmitted.¶
Application Data MUST NOT be sent prior to sending the Finished message, except as specified in Section 2.3 of [RFC8446]. Note that while the client MAY send Application Data prior to receiving the server's last explicit Authentication message, any data sent at that point is, being sent to an implicitly authenticated peer.¶
Due to the implicit authentication of the server's messages during the full
AuthKEM handshake, the CertificateRequest
message can not be authenticated
before the client received Finished
.¶
The key schedule guarantees that the server can not read the client's
certificate message (as discussed above). An active adversary that maliciously
inserts a CertificateRequest
message will also result in a mismatch in
transcript hashes, which will cause the handshake to fail.¶
However, there may be side effects. The adversary might learn that the client has a certificate by observing the length of the messages sent. There may also be side effects, especially in situations where the client is prompted to e.g. approve use or unlock a certificate stored encrypted or on a smart card.¶
client_authenticated_handshake_secret
, which ensures that
only the intended server can read the client's identity.¶
The following are open points for discussion. The corresponding Github issues will be linked.¶
The certificate request message from the server can not be authenticated by the AuthKEM mechanism. This is already somewhat discussed above and under security considerations. We might want to allow clients to refuse client auth for scenarios where this is a concern.¶
In the current state of the draft, we have not yet discussed combining traditional signature-based authentication with KEM-based authentication. One might imagine that the Client has a sigining certificate and the server has a KEM public key.¶
In the current draft, clients MUST use a KEM certificate algorithm if the server negotiated AuthKEM.¶
Early versions of this work were supported by the European Research Council through Starting Grant No. 805031 (EPOQUE).¶