Internet-Draft | MLSAP | October 2024 |
Kohbrok & Robert | Expires 24 April 2025 | [Page] |
The Messaging Layer Security (MLS) protocol allows a group of clients to exchange symmetric keys, agree on group state and send application messages.¶
The main purpose of an MLS group is thus to facilitate agreement on group state and key material between the members of the group. In some cases, however, it is useful to share agreement on the (public) group state, as well as key material with another party that is not a full member of the group.¶
This document describes a safe extension to do just that.¶
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/mls-associated-parties/draft-kohbrok-mls-associated-parties.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-kohbrok-mls-associated-parties/.¶
Discussion of this document takes place on the Messaging Layer Security Working Group mailing list (mailto:[email protected]), 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/mls-associated-parties.¶
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 24 April 2025.¶
Copyright (c) 2024 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.¶
This document outlines a mechanism that allows an MLS group (i.e. the members thereof) to share key material with one or more associated parties such as a server acting as the delivery service.¶
The mechanism provides the following properties:¶
All members of the group agree on the associated parties and their public key material¶
All members of the group agree on the key material shared with the associated parties¶
The mechanism makes the following assumptions:¶
The mechanism sketched in this document is essentially a copy of the MLS key schedule shared with an individual external party (with a distinct key schedule for each such party).¶
The key material of each epoch carries over to the previous epoch, where new key material is injected into the key schedule with each commit.¶
Any party that wants to be eligible as an associated party to an MLS group must publish the key material required.¶
enum { reserved(0), published(1), update(2), (255) } AssociatedPartyEntrySource; struct { HPKEPublicKey encryption_key; SignaturePublicKey signature_key; Credential credential; AssociatedPartyEntrySource source; select (AssociatedPartyEntry.source) { case published: Lifetime lifetime; case update: struct{}; }; } AssociatedPartyEntry struct { HPKEPublicKey encryption_key; SignaturePublicKey signature_key; Credential credential; AssociatedPartyEntrySource source; select (AssociatedPartyEntryTBS.source) { case published: Lifetime lifetime; case update: struct{}; }; select (AssociatedPartyEntryTBS.source) { case published: struct{}; case update: opaque group_id<V>; uint32 leaf_index; }; } AssociatedPartyEntryTBS¶
All published AssociatedPartyEntries MUST have their source
set to
published
.¶
Published AssociatedPartyEntries can be retrieved by MLS group members for use in AddAssociatedParty proposals as described in Section 4.¶
Open Question: Do we want an extension version in these structs?¶
Open Question: Do we want to support AP capabilities? That would allow us to support AP extensions as well.¶
AssociatedParties of a group are listed in the AssociatedParties GroupContext extension.¶
struct { AssociatedPartyEntry associated_parties<V>; } AssociatedParties¶
A group member can add or remove associated parties in the context of a group by sending Add- or RemoveAssociatedParty proposals.¶
struct { AssociatedPartyEntry new_party; } AddAssociatedParty struct { u32 removed_party_index; } RemoveAssociatedParty¶
Any AssociatedPartyEntry in an AddAssociatedParty proposal MUST have source
set to published
.¶
Associated parties act as external senders and can additionally send UpdateAssociatedParty proposals to update their own key material.¶
struct { AssociatedPartyEntry updated_party; } UpdateAssociatedParty¶
Any AssociatedPartyEntry in an UpdateAssociatedParty proposal MUST have source
set to update
.¶
When a group member commits one or more of theses proposals, the AssociatedParties extension is updated accordingly.¶
The associated parties in the removed_party_index
es of all
RemoveAssociatedParty proposals are removed from the associated_parties
vector.¶
The new_party
AssociatedPartyEntry in all AddAssociatedParty proposals are
apended to the associated_parties
vector.¶
The AssociatedPartyEntries in the associated_parties
vector of the senders
of all UpdateAssociatedParty proposals are replaced by the update_party
in
the respective proposal.¶
An associated party key schedule is a key schedule that group members share with an associated party. It follows the same pattern as the main MLS key schedule, where fresh randomness is injected with each epoch and a secret from the old epoch is used to seed the next. Associated party key schedules are separate for each associated party.¶
Whenever a group member creates a commit, it exports the associated_parties_secret
from the group’s epoch_secret
(of the new epoch). The ap_exporter_secret
is
then used to derive the ap_commit_base_secret
for each associated party, where
context
is the AssociatedPartyExportContext with ap_index
as the associated
party's index in the AssociatedParties extension and ap_entry
as the
associated party's AssociatedPartyEntry.¶
associated_parties_secret = DeriveExtensionSecret(epoch_secret, "AP Exporter Secret") struct { u32 ap_index; AssociatedPartyEntry ap_entry; } AssociatedPartyExportContext ap_commit_base_secret = ExpandWithLabel(associated_parties_secret, "AP Commit Base Secret", context, KDF.Nh)¶
From the ap_commit_base_secret
, the committer derives the ap_commit_secret
and the ap_commit_secret_id
.¶
ap_commit_secret = DeriveSecret(ap_commit_base_secret, "AP Commit Secret") ap_commit_secret_id = DeriveSecret(ap_commit_base_secret, "AP Commit Secret ID")¶
The committer then encrypts the ap_commit_base_secret
with an
AssociatedPartyCommitEncryptionContext as context
, where group_context
is
the context of the group's new epoch.¶
struct { opaque label = "AP Commit Secret"; GroupContext group_context; opaque ap_commit_secret_id<V>; } AssociatedPartyCommitEncryptionContext; (kem_output, ciphertext) = SafeEncryptWithContext(0xXXXX, external_pub, context, ap_commit_base_secret)¶
kem_output
, ciphertext
and the ap_commit_secret_id
are sent as a separate
message stapled to the commit. The associated party can decrypt the ciphertext
to get the ap_commit_base_secret
. Other group members receiving the commit
export the ap_commit_base_secret
from the key schedule of the new epoch.¶
Both associated party and all other group members finally derive the
ap_commit_secret_id
and the ap_commit_secret
. They compare the
ap_commit_secret_id
to the one they received along with the ciphertext to
ensure that everyone got the same base secret. The ap_commit_secret
is later
used to compute the new epoch of the associated party key schedule.¶
TODO: We probably want a distinct WireFormat for the message with kem_output
,
ciphertext and
ap_commit_secret_id`. That message should also be authenticated
using a signature.¶
Associated parties can also contribute secret key material to the shared key schedule. An associated party can do so by sampling fresh randomness and HPKE-encrypting it to the public key in the group’s ExternalPub GroupInfo extension (if present). The associated party then includes the resulting HPKE ciphertext in an AssociatedPartySecret proposal and sends it to the group. That secret is injected into the associated party key schedule in the epoch in which it is committed.¶
struct { opaque associated_party_proposal_secret<V>; } AssociatedPartySecret;¶
TODO: Since the ap_commit_secret
s come from the MLS key schedule and any
AssociatedPartySecret proposals are included in the transcript, the group should
always be in agreement on what the AP key schedule looks like. Is additional
binding necessary by injecting something from the AP key schedule back into the
MLS key schedule?¶
In each epoch, the ap_init_secret
of the previous epoch, the
ap_commit_secret
of this epoch, as well as any secrets from
AssociatedPartySecret proposals are used to derive this epoch’s
ap_epoch_secret
as shown in Figure 1. If the associated party was
added in this epoch, the ap_init_secret
of the past epoch is 0. Just like in
the MLS key schedule, the GroupContext is used as context in the operation to
derive the ap_epoch_secret
.¶
The ap_epoch_secret
is used to derive two secrets: The ap_init_secret
of
this epoch and the ap_exporter_secret
. The former is stored until the next
epoch starts. The latter is used to seed a PPRF from which the application or
other extensions can sample further secrets, domain-separated by an
application-provided string or the extension ID.¶
All ap_
-secrets are deleted after use.¶
TODO Security¶
This document registers the AssociatedParties extension with ID 0xXXXX.¶
TODO acknowledge.¶