Internet-Draft 2PMLS July 2026
Kohbrok & Robert Expires 31 January 2027 [Page]
Workgroup:
Messaging Layer Security
Internet-Draft:
draft-kohbrok-mls-two-party-profile-01
Published:
Intended Status:
Informational
Expires:
Authors:
K. Kohbrok
Phoenix R&D
R. Robert
Phoenix R&D

A two-party profile for MLS

Abstract

TODO Abstract

About This Document

This note is to be removed before publishing as an RFC.

The latest revision of this draft can be found at https://kkohbrok.github.io/draft-kohbrok-mls-two-party-profile/draft-kohbrok-mls-two-party-profile.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-kohbrok-mls-two-party-profile/.

Discussion of this document takes place on the Messaging Layer Security Working Group mailing list (mailto:mls@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/mls/. Subscribe at https://www.ietf.org/mailman/listinfo/mls/.

Source for this draft and an issue tracker can be found at https://github.com/kkohbrok/draft-kohbrok-mls-two-party-profile.

Status of This Memo

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 31 January 2027.

Table of Contents

1. Introduction

Messaging Layer Security (MLS) [RFC9420] is primarily designed to be a continuous group key agreement (and messaging) protocol. This document explores the special case of groups of two and thus MLS's use as a (non-group) continuous key agreement protocol with a focus on the use in synchronous scenarios.

The two-party profile of MLS described in this document can, for example, be used as a replacement for other key exchange protocols that don't provide post-compromise security and/or post-quantum security. Post-quantum security is available when the profile is used with a suitable post-quantum cipher suite, such as one defined in [I-D.ietf-mls-pq-ciphersuites]. This is the case with the key exchange components for many secure channel protocols today.

TODO: For now, this document specifies a simple two party profile based on vanilla MLS that assumes synchronous communication and a reliable transport. In the future, we should explore the asynchronous case and add a more specialized version that trims unnecessary things like signatures in key update messages, etc.

2. Conventions and Definitions

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.

This document uses the TLS presentation language as modified by Section 2.1 of [RFC9420] to describe the structure of protocol messages.

2.1. Two-party profile component

This document defines the two_party_profile application component using the Safe Application Interface of [I-D.ietf-mls-extensions]. Its component ID is TBD1 (see Section 8). The component is used with Safe Additional Authenticated Data (AAD) and MAY be used with the safe exporter.

An implementation using this profile MUST include the two_party_profile component ID in the ComponentsList values of both the app_components and safe_aad components in the app_data_dictionary extension of every LeafNode it uses with this profile. The group creator MUST include an app_data_dictionary extension in the GroupContext and MUST include the two_party_profile component ID in the ComponentsList values of both its app_components and safe_aad components.

A client processing a KeyPackage for this profile MUST verify that its LeafNode advertises these component requirements. A client joining a group MUST verify that the GroupContext requires them. A member processing a Commit with an UpdatePath MUST verify that the UpdatePath LeafNode continues to advertise them.

The following values identify the post-establishment messages defined by this profile:

enum {
  reserved(0),
  connection_update(1),
  resumption_request(2),
  resumption_response(3),
  epoch_key_update(4),
  (255)
} TwoPartyMessageType;

Each MLSMessage created for a ConnectionUpdate, ResumptionRequest, or ResumptionResponse, as well as each EpochKeyUpdate application message, MUST contain a SafeAADItem for the two_party_profile component. The aad_item_data of that item MUST contain the TLS presentation language encoding of the TwoPartyMessageType value corresponding to the purpose for which the MLSMessage was created. A receiver MUST verify the value before processing the message. This allows a receiver to distinguish messages whose MLS payloads otherwise have the same encoding.

The message type is authenticated as part of the MLSMessage and identifies the purpose for which that MLSMessage was created. It MUST NOT be changed when a pending MLSMessage is retransmitted during resumption. Section 6 defines how this rule applies to a pending MLSMessage carried in a ResumptionRequest.

3. Protocol overview

The synchronous case assumes that both parties are online. The protocol additionally assumes that the underlying transport delivers messages reliably and in order while a connection is active, and that messages sent over an interrupted connection are no longer delivered once resumption of that connection has begun. How the parties detect an interruption is out of scope for this document and typically depends on the transport.

The party sending the first message is the initiator and the other party the responder. The protocol can be split into three phases.

  1. Initial key agreement

  2. Continuous key agreement

  3. Resumption

In Phase 1, the initiator and responder exchange messages until they agree on a shared key and thus enter Phase 2.

In Phase 2, both parties can perform key-updates to achieve forward-secrecy (FS) and post-compromise security (PCS). To avoid de-synchronization, both parties have to await confirmation of each update by the other party before they can perform another one. This phase continues until the connection between the parties is interrupted.

Phase 3 allows either party to resume the connection. During resumption, initiator and responder exchange messages to renew their key material before they (re-)enter Phase 2.

The initiator and responder roles are assigned during Phase 1 and re-assigned whenever the connection is resumed in Phase 3. The roles assigned during Phase 1 are additionally referred to as the initial initiator and the initial responder. Both parties MUST persist their initial role for the lifetime of the group, since it is used to resolve message collisions during resumption (see Section 6).

While the synchronous two-party case is significantly simpler when it comes to the responsibilities of the MLS Delivery Service, it still requires both parties to interface with an Authentication Service (AS) to validate both initial credentials and any credential updates.

A higher-level protocol using this profile MAY export key material with the MLS exporter defined in Section 8.5 of [RFC9420] or with the safe exporter defined in [I-D.ietf-mls-extensions]. The higher-level protocol is responsible for defining the exporter inputs and how the resulting key material is used. See Section 8.5 of [RFC9420] for guidance on the use of exported key material.

3.1. Protocol states and error handling

At any point in the protocol, each party is in one of the following states:

Awaiting ClientHello:

The responder has accepted a connection and waits for a ClientHello. It has not yet created group state.

Awaiting ServerHello:

The initiator has sent a ClientHello and waits for the corresponding ServerHello.

Synced:

The party has no pending commit and may send a new ConnectionUpdate. Its peer may still be in the previous epoch while waiting to receive an EpochKeyUpdate that this party sent.

Awaiting EpochKeyUpdate:

The party has sent a commit as part of a ConnectionUpdate or a ResumptionResponse and waits for the corresponding EpochKeyUpdate.

Awaiting ResumptionResponse:

The party has sent a ResumptionRequest and waits for the corresponding ResumptionResponse.

Section 4, Section 5, and Section 6 define how a party in a given state processes each message. If a party receives a message that those sections do not explicitly permit in its current state, or if it fails to validate a received message, this is a fatal error. The party MUST terminate the connection and delete any group state associated with it. Group state discarded due to a fatal error MUST NOT be used for resumption. Communication can only be re-established through a new run of the initial key agreement.

Appendix A shows the resulting state machine in graphical form.

4. Initial key agreement

struct {
  MLSMessage key_package;
} ClientHello;

struct {
  MLSMessage welcome;
} ServerHello;

The initiator starts the key agreement part of the protocol by creating a KeyPackage and sending a ClientHello to the responder. It then enters the Awaiting ServerHello state, in which the ServerHello is the only permitted message.

The responder starts in the Awaiting ClientHello state, in which the ClientHello is the only permitted message.

The responder MUST validate the KeyPackage as specified in Section 10.1 of [RFC9420]. It MUST verify that the KeyPackage advertises the component requirements in Section 2.1. It then checks whether it supports the offered cipher suite and whether the initiator has sufficient capabilities to support the connection.

The responder MUST interface with the AS to ensure that the credential in the KeyPackage is valid.

The responder then locally creates an MLS group and commits to an Add proposal containing the initiator's KeyPackage. The responder sends the resulting Welcome message back to the initiator as part of a ServerHello message and enters the Synced state.

The initiator uses the Welcome to create its local group state. The initiator then inspects the group state. It MUST verify that the group contains exactly two non-blank leaves, that one leaf corresponds to the KeyPackage it sent, and that the other leaf belongs to the responder. It MUST also verify that the GroupContext contains the component requirements in Section 2.1 and interface with the AS to ensure that the credential of the responder is valid. The initiator then enters the Synced state.

If the connection is interrupted before the initial key agreement completes, the parties MUST abandon the partial exchange and delete any group state created solely for it. Communication can only be re-established through a new run of the initial key agreement starting with a new ClientHello.

5. Continuous key agreement

struct {
  MLSMessage update;
} ConnectionUpdate;

struct {
  uint64 epoch;
} EpochKeyUpdate;

An EpochKeyUpdate is encoded as the application_data of an MLS application message. The application message is sent in the new epoch and carries the epoch_key_update message type in Safe AAD as specified in Section 2.1.

After the initial key agreement phase, both parties can send an MLS commit with UpdatePath to update their key material. To ensure that both agree on the order of such commits and thus on the currently used key material, they must follow the following rules. The initiator and responder roles referenced in these rules are the current roles, i.e. the roles assigned during the most recent run of Phase 1 or Phase 3.

Every Commit sent as part of a ConnectionUpdate, ResumptionRequest, or ResumptionResponse MUST contain an empty proposals vector and a populated UpdatePath. A receiver MUST reject a Commit that does not satisfy these requirements.

In addition, a party in the Synced or Awaiting EpochKeyUpdate state may receive a ResumptionRequest at any time. Its processing is defined in Section 6.

OPEN QUESTION: How should we constrain the inclusion of commits? Some proposal types like Re-Init would need to be integrated into the state machine.

6. Resumption

Either party may resume a previously interrupted protocol session based on that session's group state. The party initiating the resumption becomes the initiator for the resumed session and the other party the responder. The initial roles (see Section 3) remain unchanged.

struct {
  MLSMessage commit;
} ResumptionRequest;

struct {
  MLSMessage commit;
} ResumptionResponse;

The initiator creates a ResumptionRequest, sends it to the responder, and enters the Awaiting ResumptionResponse state. If the initiator has a pending commit, i.e. if it was in the Awaiting EpochKeyUpdate or Awaiting ResumptionResponse state when the connection was interrupted, the commit field MUST contain that pending commit. Otherwise, the commit field MUST contain a fresh commit with UpdatePath. A fresh commit carries the resumption_request message type in Safe AAD. A pending commit retains its original message type: connection_update, resumption_request, or resumption_response.

The parties do not need to agree on whether the connection was interrupted: a party may receive a ResumptionRequest in the Synced, Awaiting EpochKeyUpdate, or Awaiting ResumptionResponse state. A party that receives a ResumptionRequest MUST treat the previous connection as interrupted and MUST NOT send any further messages over it.

Before processing the commit in a ResumptionRequest in any state, a party MUST verify that its Safe AAD message type is resumption_request, connection_update, or resumption_response. The latter two values identify a pending ConnectionUpdate or ResumptionResponse retransmitted for resumption.

A party that receives a ResumptionRequest in the Synced or Awaiting EpochKeyUpdate state MUST process the commit in the ResumptionRequest as follows:

To recognize the first case, both parties MUST retain the last commit message they applied, or a collision-resistant hash of it.

If a party receives a ResumptionRequest in the Awaiting ResumptionResponse state, it has a pending commit from its own ResumptionRequest. It MUST classify the received commit before resolving a collision:

Whenever a receiver processes a ResumptionRequest rather than ignoring it, the receiver MUST create a fresh commit with UpdatePath, carrying the resumption_response message type in Safe AAD, and send it as part of a ResumptionResponse. Since this commit requires confirmation like any other, the receiver enters the Awaiting EpochKeyUpdate state and the rules of Section 5 apply from there.

A party that receives a ResumptionResponse in the Awaiting ResumptionResponse state MUST first apply its pending commit, i.e. the commit it sent as part of its ResumptionRequest. It MUST then validate and apply the commit in the ResumptionResponse and respond with an EpochKeyUpdate, where epoch is the group's new epoch. It then enters the Synced state.

As a result, if both parties initiate a resumption at the same time and their commits conflict, the resumed session continues with the initial initiator as the current initiator and the initial responder as the current responder.

After ignoring a ResumptionRequest, the initial initiator may be waiting for a ResumptionResponse that never arrives, for example if its own ResumptionRequest or the corresponding ResumptionResponse was lost in a further interruption. Recovery from this situation relies on the initial initiator detecting the interruption and initiating resumption again.

7. Security Considerations

TODO: A future version of this document will provide a more complete security analysis.

7.1. EpochKeyUpdate authentication

An EpochKeyUpdate is an MLS application message sent under the new epoch's keys. Its Safe AAD identifies it as an EpochKeyUpdate for this profile. The sender of the Commit authenticates and decrypts the message using the group state resulting from its pending Commit before making that state current. This binds the acknowledgement to the new epoch and prevents a party that does not know the new epoch's keys from forging it.

8. IANA Considerations

IANA is requested to register the following entry in the "MLS Component Types" registry defined by [I-D.ietf-mls-extensions]:

Value:

TBD1

Name:

two_party_profile

Where:

AD, ES

Recommended:

N

Reference:

This document

9. References

9.1. Normative References

[I-D.ietf-mls-extensions]
Robert, R., "The Messaging Layer Security (MLS) Extensions", Work in Progress, Internet-Draft, draft-ietf-mls-extensions-10, , <https://datatracker.ietf.org/doc/html/draft-ietf-mls-extensions-10>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC9420]
Barnes, R., Beurdouche, B., Robert, R., Millican, J., Omara, E., and K. Cohn-Gordon, "The Messaging Layer Security (MLS) Protocol", RFC 9420, DOI 10.17487/RFC9420, , <https://www.rfc-editor.org/rfc/rfc9420>.

9.2. Informative References

[I-D.ietf-mls-pq-ciphersuites]
Mahy, R. and R. Barnes, "ML-KEM and Hybrid Cipher Suites for Messaging Layer Security", Work in Progress, Internet-Draft, draft-ietf-mls-pq-ciphersuites-06, , <https://datatracker.ietf.org/doc/html/draft-ietf-mls-pq-ciphersuites-06>.

Appendix A. Protocol state machine

This appendix shows the protocol as a state machine. It is informative. The normative rules are those in Section 4, Section 5, and Section 6. Transitions are labeled with the triggering event and, after a slash, the resulting actions. Transitions that only apply to the party holding a particular role are marked with that role in parentheses. Fatal errors (Section 3.1) are omitted from the diagrams: in every state, receiving a message that no transition of that state covers terminates the connection.

Figure 1 shows the initial key agreement (Section 4) and continuous key agreement (Section 5) phases.

START send ClientHello accept connection AWAITING AWAITING SERVERHELLO CLIENTHELLO recv ServerHello recv ClientHello / send ServerHello SYNCED recv ConnectionUpdate / send EpochKeyUpdate send recv recv Connection- EpochKeyUpdate ConnectionUpdate Update / apply (as responder) / pending commit drop pending commit, apply commit, send EpochKeyUpdate AWAITING EPOCHKEYUPDATE recv ConnectionUpdate (as initiator) / ignore
Figure 1: Initial and continuous key agreement

The transitions that abandon an interrupted initial key agreement and return to START are omitted from Figure 1.

Figure 2 shows the resumption phase (Section 6). The Synced and Awaiting EpochKeyUpdate states are the same states as in Figure 1, and the transitions shown there remain available. The transition labels are listed below the diagram.

SYNCED (1) AWAITING EPOCHKEYUPDATE (1) (2) (2) (3) AWAITING RESUMPTIONRESPONSE (4), (6) (5)
Figure 2: Resumption
(1)

recv ResumptionRequest / process the commit as described in Section 6, send ResumptionResponse

(2)

connection interrupted / send ResumptionRequest containing the pending commit, or a fresh commit if there is none

(3)

recv ResumptionRequest / process the commit as described in Section 6, send ResumptionResponse

(4)

recv conflicting ResumptionRequest (as initial initiator) / ignore

(5)

recv ResumptionResponse / apply pending commit, apply commit in the ResumptionResponse, send EpochKeyUpdate

(6)

connection interrupted / retransmit ResumptionRequest containing the pending commit

Acknowledgments

TODO acknowledge.

Contributors

Russ Housley
Vigil Security

Authors' Addresses

Konrad Kohbrok
Phoenix R&D
Raphael Robert
Phoenix R&D