Draft: draft-ietf-mls-protocol

Commentary: Interim 2022 - 05 - 26 : to revert the change that notes Other changes to be handled as editorial .
Paragraph (version A):
MLS supports two ways to tie a new group to an existing group.  Re-
initialization closes one group and creates a new group comprising
the same members with different parameters.  Branching starts a new
group with a subset of the original group's participants (with no
effect on the original group).  In both cases, the new group is
linked to the old group via a resumption PSK.
Paragraph (version B):
MLS supports two ways to tie a new group to an existing group.
Reinitialization closes one group and creates a new group comprising
the same members with different parameters.  Branching starts a new
group with a subset of the original group's participants (with no
effect on the original group).  In both cases, the new group is
linked to the old group via a resumption PSK.
Paragraph (version A):
After generating fresh key material and applying it to ratchet
forward their local tree state as described in the ratchet-tree-
evolution, the generator must broadcast this update to other members
of the group in a Commit message, who apply it to keep their local
views of the tree in sync with the sender's.  More specifically, when
a member commits a change to the tree (e.g., to add or remove a
member), it transmits an UpdatePath containing a set of public keys
and encrypted path secrets for intermediate nodes in the filtered
direct path of its leaf.  The other members of the group use these
values to update their view of the tree, aligning their copy of the
tree to the sender's.
Paragraph (version B):
After generating fresh key material and applying it to ratchet
forward their local tree state as described in the ratchet-tree-
evolution, the generator broadcasts this update to other members of
the group in a Commit message, who apply it to keep their local views
of the tree in sync with the sender's.  More specifically, when a
member commits a change to the tree (e.g., to add or remove a
member), it transmits an UpdatePath containing a set of public keys
and encrypted path secrets for intermediate nodes in the filtered
direct path of its leaf.  The other members of the group use these
values to update their view of the tree, aligning their copy of the
tree to the sender's.
Paragraph (version A):
The injection of one or more PSKs into the key schedule is signaled
in two ways: Existing members are informed via PreSharedKey proposals
covered by a Commit, and new members added in the Commit are informed
via GroupSecrets object in the Welcome message corresponding to the
Commit.  To ensure that existing and new members compute the same PSK
input to the key schedule, the Commit and GroupSecrets objects MUST
indicate the same set of PSKs, in the same order.
Paragraph (version B):
The injection of one or more PSKs into the key schedule is signaled
in two ways: Existing members are informed via PreSharedKey proposals
covered by a Commit, and new members added in the Commit are informed
by the GroupSecrets object in the Welcome message corresponding to
the Commit.  To ensure that existing and new members compute the same
PSK input to the key schedule, the Commit and GroupSecrets objects
MUST indicate the same set of PSKs, in the same order.
Paragraph (version A):
The main MLS key schedule provides an "exporter_secret" which can be
used by an application as the basis to derive new secrets called
"exported_value" outside the MLS layer.
Paragraph (version A):
Each application SHOULD provide a unique label to "MLS-Exporter" that
identifies its use case.  This is to prevent two exported outputs
from being generated with the same values and used for different
functionalities.
Paragraph (version A):
The exported values are bound to the group epoch from which the
"exporter_secret" is derived, hence reflects a particular state of
the group.
Paragraph (version B):
The main MLS key schedule provides an "exporter_secret" which can be
used by an application to derive new secrets for use outside of MLS.
Paragraph (version B):
Applications SHOULD provide a unique label to "MLS-Exporter" that
identifies the secret's intended purpose.  This is to help prevent
the same secret from being generated and used in two different
places.
Paragraph (version B):
The exported values are bound to the group epoch from which the
"exporter_secret" is derived, and hence reflect a particular state of
the group.
Paragraph (version A):
The main MLS key schedule provides a "resumption_psk" that is used as
a PSK to inject entropy from one epoch into another.  This
functionality is used in the reinitialization and branching processes
described in reinitialization and sub-group-branching, but may be
used by applications for other purposes.
Paragraph (version B):
The main MLS key schedule provides a "resumption_psk" that is used as
a PSK to inject entropy from one epoch into another.  This
functionality is used in the reinitialization and branching processes
described in reinitialization and subgroup-branching, but may be used
by applications for other purposes.
Paragraph (version A):
Here, AEAD.Nn and AEAD.Nk denote the lengths in bytes of the nonce
and key for the AEAD scheme defined by the ciphersuite.
Paragraph (version B):
Where "Generation" is encoded as a big endian uint32.
Paragraph (version B):
Here, "AEAD.Nn" and "AEAD.Nk" denote the lengths in bytes of the
nonce and key for the AEAD scheme defined by the ciphersuite.
Paragraph (version A):
KeyPackages are intended to be used only once and SHOULD NOT be
reused except in the case of last resort.  (See keypackage-reuse).
Clients MAY generate and publish multiple KeyPackages to support
multiple ciphersuites.
Paragraph (version B):
KeyPackages are intended to be used only once and SHOULD NOT be
reused except in the case of last resort (see keypackage-reuse).
Clients MAY generate and publish multiple KeyPackages to support
multiple ciphersuites.
Paragraph (version A):
The signature is computed by the function "SignWithLabel" with a
label "KeyPackage" and a content comprising of all of the fields
except for the signature field.
Paragraph (version B):
The signature is computed by the function "SignWithLabel" with a
label "KeyPackageTBS" and a content comprising of all of the fields
except for the signature field.
Paragraph (version A):
A group is always created with a single member, the "creator".  The
other members are added when the creator effectively sends itself an
Add proposal and commits it, then sends the corresponding Welcome
message to the new participants.  These processes are described in
detail in add, commit, and joining-via-welcome-message.
Paragraph (version B):
A group is always created with a single member, the "creator".  The
other members are added when the creator effectively sends itself Add
proposals, commits them, and then sends the corresponding Welcome
message to the new participants.  These processes are described in
detail in add, commit, and joining-via-welcome-message.
Paragraph (version A):
The recipient of a Welcome message processes it as described in
joining-via-welcome-message.  If application context informs the
recipient that the Welcome should reflect the creation of a new group
(for example, due to a branch or reinitialization), then the
recipient MUST verify that the epoch value in the GroupInfo is equal
to 1.
Paragraph (version B):
The recipient of a Welcome message processes it as described in
joining-via-welcome-message.
Paragraph (version A):
This extension lists the extensions, proposals, and credential types
that must be supported by all members of the group.  The "default"
proposal and extension types defined in this document are assumed to
be implemented by all clients, and need not be listed in
RequiredCapabilities in order to be safely used.
Paragraph (version A):
For new members, support for required capabilities is enforced by
existing members during the application of Add commits.  Existing
members should of course be in compliance already.  In order to
ensure this continues to be the case even as the group's extensions
can be updated, a GroupContextExtensions proposal is invalid if it
contains a "required_capabilities" extension that requires non-
default capabilities not supported by all current members.
Paragraph (version B):
This extension lists the extensions, proposals, and credential types
that must be supported by all members of the group.  The "default"
proposal and extension types defined in this document are assumed to
be implemented by all clients, and need not be listed in
RequiredCapabilities in order to be safely used.  Note that this is
not true for credential types.
Paragraph (version B):
For new members, support for required capabilities is enforced by
existing members during the application of Add commits.  Existing
members should of course be in compliance already.  In order to
ensure this continues to be the case even as the group's extensions
are updated, a GroupContextExtensions proposal is deemed invalid if
it contains a "required_capabilities" extension that requires non-
default capabilities not supported by all current members.
Paragraph (version A):
Note that these three steps may be done by the same group member or
different members.  For example, if a group member sends a commit
with an inline ReInit proposal (steps 1 and 2), but then goes
offline, another group member may send the corresponding Welcome.
This flexibility avoids situations where a group gets stuck between
steps 2 and 3.
Paragraph (version B):
Note that these three steps may be done by the same group member or
different members.  For example, if a group member sends a Commit
with an inline ReInit proposal (steps 1 and 2) but then goes offline,
another group member may recreate the group instead.  This
flexibility avoids situations where a group gets stuck between steps
2 and 3.
Paragraph (version A):
Determine a subset of existing members that should be a part of
the sub-group.
Paragraph (version A):
Create a new tree for the sub-group by fetching a new KeyPackage
for each existing member that should be included in the sub-group.
Paragraph (version A):
Create a Welcome message that includes a PreSharedKey of type
"resumption" with usage "branch".
Paragraph (version A):
A client receiving a Welcome including a PreSharedKey of type
"resumption" with usage "branch" MUST verify that the new group
reflects a subgroup branched from the referenced group.
Paragraph (version A):
The "version" and "ciphersuite" values in the Welcome MUST be the
same as those used by the old group.
Paragraph (version B):
Fetch a new KeyPackage for each group member that should be
included in the subgroup.
Paragraph (version B):
Create an initial Commit message that sets up the new group and
contains a PreSharedKey proposal of type "resumption" with usage
"branch".  To avoid key re-use, the "psk_nonce" included in the
"PreSharedKeyID" object MUST be a randomly sampled nonce of length
"KDF.Nh".
Paragraph (version B):
Send the corresponding Welcome message to the subgroup members.
Paragraph (version B):
The "version" and "ciphersuite" values in the Welcome are the same
as those used by the old group.
Paragraph (version A):
Decrypt the "encrypted_group_secrets" using HPKE with the
algorithms indicated by the ciphersuite and the HPKE private key
corresponding to the GroupSecrets.  If a "PreSharedKeyID" is part
of the GroupSecrets and the client is not in possession of the
corresponding PSK, return an error.
Paragraph (version B):
Decrypt the "encrypted_group_secrets" value with the algorithms
indicated by the ciphersuite and the private key corresponding to
"init_key" in the referenced KeyPackage.
Paragraph (version B):
If a "PreSharedKeyID" is part of the GroupSecrets and the client
is not in possession of the corresponding PSK, return an error.
Paragraph (version A):
Verify the signature on the GroupInfo object.  The signature input
comprises all of the fields in the GroupInfo object except the
signature field.  The public key and algorithm are taken from the
credential in the leaf node of the ratchet tree with leaf index
"signer".  If the node is blank or if signature verification
fails, return an error.
Paragraph (version B):
Verify the signature on the GroupInfo object.  The signature input
comprises all of the fields in the GroupInfo object except the
signature field.  The public key is taken from the LeafNode of the
ratchet tree with leaf index "signer".  If the node is blank or if
signature verification fails, return an error.
Paragraph (version A):
Verify that the tree hash of the ratchet tree matches the
"tree_hash" field in the GroupInfo.
Paragraph (version B):
Verify that the tree hash of the ratchet tree matches the
"tree_hash" field in GroupInfo.
Paragraph (version A):
Identify a leaf in the "tree" array (any even-numbered node) whose
LeafNode is identical to the one in the KeyPackage.  If no such
field exists, return an error.  Let "my_leaf" represent this leaf
in the tree.
Paragraph (version B):
Identify a leaf whose LeafNode is identical to the one in the
KeyPackage.  If no such field exists, return an error.  Let
"my_leaf" represent this leaf in the tree.
Paragraph (version A):
By default, a GroupInfo message only provides the joiner with a
commitment to the group's ratchet tree.  In order to process or
generate handshake messages, the joiner will need to get a copy of
the ratchet tree from some other source.  (For example, the DS might
provide a cached copy.)  The inclusion of the tree hash in the
GroupInfo message means that the source of the ratchet tree need not
be trusted to maintain the integrity of tree.
Paragraph (version B):
By default, a GroupInfo message only provides the joiner with a hash
of the group's ratchet tree.  In order to process or generate
handshake messages, the joiner will need to get a copy of the ratchet
tree from some other source.  (For example, the DS might provide a
cached copy.)  The inclusion of the tree hash in the GroupInfo
message means that the source of the ratchet tree need not be trusted
to maintain the integrity of tree.
Paragraph (version A):
Commit messages do not have an extension field because the set of
protocols is extensible.  As discussed in commit, Proposals with a
non-default proposal type MUST NOT be included in a commit unless the
proposal type is supported by all the members of the group that will
process the Commit.
Paragraph (version B):
Commit messages do not have an extension field because the set of
proposals is extensible.  As discussed in commit, Proposals with a
non-default proposal type MUST NOT be included in a commit unless the
proposal type is supported by all the members of the group that will
process the Commit.
Paragraph (version A):
In order to ensure that MLS provides meaningful authentication it is
important that each member is able to authenticate some identity
information for each other member.  Identity information is encoded
in Credentials, so this property is assured by ensuring that members
use compatible credential types.
Paragraph (version B):
In order to ensure that MLS provides meaningful authentication it is
important that each member is able to authenticate some identity
information for each other member.  Identity information is encoded
in Credentials, so this property is provided by ensuring that members
use compatible credential types.
Paragraph (version B):
In future extensions to MLS, it may be useful to allow a member to
present more than one credential.  For example, such credentials
might present different attributes attested by different authorities.
To be consistent with the general principle stated at the beginning
of this section, such an extension would need to ensure that each
member can authenticate some identity for each other member.  For
each pair of members (Alice, Bob), Alice would need to present at
least one credential of a type that Bob supports.
Paragraph (version A):
The extensions populated into a GroupContext object are drawn from
those in the GroupInfo object, according to the definitions of
those extensions.
Paragraph (version A):
This document does not define any way for the parameters of the group
to change once it has been created; such a behavior could be
implemented as an extension.
Paragraph (version A):
Each Commit message is premised on a given starting state, indicated
by the "epoch" field of the enclosing MLSMessageContent.  If the
changes implied by a Commit messages are made starting from a
different state, the results will be incorrect.
Paragraph (version A):
This need for sequencing is not a problem as long as each time a
group member sends a Commit message, it is based on the most current
state of the group.  In practice, however, there is a risk that two
members will generate Commit messages simultaneously, based on the
same state.
Paragraph (version B):
The parameters of a group may be changed by sending a
GroupContextExtensions proposal to enable additional extensions, or
by reinitializing the group as described in reinitialization.
Paragraph (version B):
Each Commit message is premised on a given starting state, indicated
by the "epoch" field of the enclosing MLSMessageContent.  If the
changes implied by a Commit message are made starting from a
different state, the results will be incorrect.
Paragraph (version B):
This need for sequencing is not a problem as long as each time a
group member sends a Commit message, it is based on the most current
state of the group.  In practice, however, there is a risk that two
members will generate Commit messages simultaneously based on the
same state.
Paragraph (version A):
Forward-secrecy between epochs is provided by deleting private keys
from past version of the ratchet tree, as this prevents old group
secrets from being re-derived.  Forward secrecy _within_ an epoch is
provided by deleting message encryption keys once they've been used
to encrypt or decrypt a message.
Paragraph (version B):
Forward-secrecy between epochs is provided by deleting private keys
from past versions of the ratchet tree, as this prevents old group
secrets from being re-derived.  Forward secrecy _within_ an epoch is
provided by deleting message encryption keys once they've been used
to encrypt or decrypt a message.
Paragraph (version A):
An application MAY allow for reuse of a "last resort" KeyPackage in
order to prevent denial of service attacks.  Since a KeyPackage is
needed to add a client to a new group, an attacker could prevent a
client being added to new groups by exhausting all available
KeyPackages.  To prevent such a denial of service attack, the
KeyPackage publication system SHOULD rate limit KeyPackage requests,
especially if not authenticated.
Paragraph (version B):
An application MAY allow for reuse of a "last resort" KeyPackage in
order to prevent denial-of-service attacks.  Since a KeyPackage is
needed to add a client to a new group, an attacker could prevent a
client being added to new groups by exhausting all available
KeyPackages.  To prevent such a denial-of-service attack, the
KeyPackage publication system SHOULD rate-limit KeyPackage requests,
especially if not authenticated.
Paragraph (version A):
It is possible for a malicious member of a group to "fragment" the
group by crafting an invalid UpdatePath.  Recall that an UpdatePath
encrypts a sequence of path secrets to different subtrees of the
group's ratchet trees.  These path secrets should be derived in a
sequence as described in ratchet-tree-evolution, but the UpdatePath
syntax allows the sender to encrypt arbitrary, unrelated secrets.
The syntax also does not guarantee that the encrypted path secret
encrypted for a given node corresponds to the public key provided for
that node.
Paragraph (version B):
It is possible for a malicious member of a group to "fragment" the
group by crafting an invalid UpdatePath.  Recall that an UpdatePath
encrypts a sequence of path secrets to different subtrees of the
group's ratchet trees.  These path secrets should be derived in a
sequence as described in ratchet-tree-evolution, but the UpdatePath
syntax allows the sender to encrypt arbitrary, unrelated secrets.
The syntax also does not guarantee that the encrypted path secret for
a given node corresponds to the public key provided for that node.
Paragraph (version A):
Both of these types of corruption will cause processing of a Commit
to fail for some members of the group.  If the public key for a node
does not match the path secret, then the members that decrypt that
path secret will reject the commit based on this mismatch.  If the
path secret sequence is incorrect at some point, then members that
can decrypt nodes before that point will compute a different public
key for the mismatched node than the one in the UpdatePath, which
also causes the Commit to fail.  Applications SHOULD provide
mechanisms for failed commits to be reported, so that group members
who were not able to recognize the error themselves can reject the
commit and roll back to a previous state if necessary.
Paragraph (version B):
Both of these types of corruption will cause processing of a Commit
to fail for some members of the group.  If the public key for a node
does not match the path secret, then the members that decrypt that
path secret will reject the commit based on this mismatch.  If the
path secret sequence is incorrect at some point, then members that
can decrypt nodes before that point will compute a different public
key for the mismatched node than the one in the UpdatePath, which
also causes the Commit to fail.  Applications SHOULD provide
mechanisms for failed commits to be reported, so that group members
who were not able to recognize the error themselves can reinitialize
the group if necessary.
Paragraph (version A):
Even with such an error reporting mechanism in place, however, it is
still possible for members to get locked out of the group by a
malformed commit.  Since malformed Commits can only be recognized by
certain members of the group, in an asynchronous application, it may
be the case that all members that could detect a fault in a Commit
are offline.  In such a case, the Commit will be accepted by the
group, and the resulting state possibly used as the basis for further
Commits.  When the affected members come back online, they will
reject the first commit, and thus be unable to catch up with the
group.
Paragraph (version B):
Even with such an error reporting mechanism in place, however, it is
still possible for members to get locked out of the group by a
malformed commit.  Since malformed Commits can only be recognized by
certain members of the group, in an asynchronous application, it may
be the case that all members that could detect a fault in a Commit
are offline.  In such a case, the Commit will be accepted by the
group, and the resulting state possibly used as the basis for further
Commits.  When the affected members come back online, they will
reject the first commit, and thus be unable to catch up with the
group.  These members will either need to add themselves back with an
external Commit, or reinitialize the group from scratch.