Internet-Draft MLS App API December 2024
Alwen, et al. Expires 15 June 2025 [Page]
Workgroup:
Messaging Layer Security
Internet-Draft:
draft-barnes-mls-appsync-01
Published:
Intended Status:
Informational
Expires:
Authors:
J. Alwen
Amazon
R. Barnes
Cisco
R. Mahy
Rohan Mahy Consulting Services
M. Mularczyk
Amazon

A Safe Application Interface to Messaging Layer Security

Abstract

The Messaging Layer Security protocol enables a group of participants to negotiate a common cryptographic state. While the primary function of MLS is to establish shared secret state for the group, an MLS group also captures authentication information for group participants and information on which the group has confirmed agreement. This document defines an interface interface by which multiple uncoordinated application functions may safely reuse the cryptographic state of an MLS group for application purposes.

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://bifurcation.github.io/mls-appsync/draft-barnes-mls-appsync.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-barnes-mls-appsync/.

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/bifurcation/mls-appsync.

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 15 June 2025.

Table of Contents

1. Introduction

The Messaging Layer Security protocol (MLS) is designed to be integrated into applications, in order to provide security services that the application requires [RFC9420]. There are two questions to answer when designing such an integration:

  1. How does the application provide the services that MLS requires?

  2. How does the application use MLS to get security benefits?

The MLS Architecture describes the requirements for the first of these questions [I-D.mls-architecture], namely the structure of the Delivery Service and Authentication Service that MLS requires. This document is focused on the second question.

MLS itself offers some basic functions that applications can use, such as the secure message encapsulation (PrivateMessage), the MLS exporter, and the epoch authenticator. Current MLS applications make use of these mechanisms to acheive a variety of confidentiality and authentication properties.

As application designers become more familiar with MLS, there is increasing interest in leveraging other cryptographic tools that an MLS group provides:

There is also interest in exposing an MLS group to multiple loosely-coordinated components of an application. To accommodate such cases, the above mechanisms need to be exposed in such a way that different components' usage will not conflict with each other, or with MLS itself.

This document defines a set of mechanisms that application components can use to ensure that their use of these facilities is properly domain-separated from MLS itself, and from other application components that might be using the same MLS group.

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.

We make heavy use of the terminology in the MLS specification [RFC9420].

Application:

The system that instantiates, manages, and uses an MLS group. Each MLS group is used by exactly one application, but an application may maintain multiple groups.

Application component:

A subsystem of an application that has access to an MLS group.

Component ID:

An identifier for an application component. These identifiers are assigned by the application.

3. Protocol Overview

The mechansms in this document take MLS mechanisms that are either not inherently designed to be used by applications, or not inherently designed to be used by multiple application components, and adds a domain separator that separates application usage from MLS usage, and application components' usage from each other:

We also define new general mechanisms that allow applications to take advantage of the extensibility mechanisms of MLS without having to define extensions themselves:

As with the above, information carried in these proposals and extension marked as belonging to a specific application component, so that components can manage their information independently.

The separation between components is acheived by the application assigning each component a unique component ID number. These numbers are then incorporated into the appopriate calculations in the protocol to achieve the required separation.

3.1. Component IDs

A component ID is a four-byte value that uniquely identifies a component within the scope of an application.

uint32 ComponentID;

  • TODO: What are the uniqueness requirements on these? It seems like the more diversity, the better. For example, if a ComponentID is reused across applications (e.g., via an IANA registry), then there will be a risk of replay across applications. Maybe we should include a binder to the group/epoch as well, something derived from the key schedule.

  • TODO: It might be better to frame these in terms of "data types" instead of components, to avoid presuming software architecture. Though that makes less sense for the more "active" portions of the API, e.g., signing and encryption.

When a label is required for an operation, the following data structure is used. The label field identifies the operation being performed. The component_id field identifies the component performing the operation. The context field is specified by the operation in question.

struct {
  opaque label<V>;
  ComponentID component_id;
  opaque context<V>;
} ComponentOperationLabel;

4. Hybrid Public Key Encryption (HPKE) Keys

This component of the API allows components to make use of the HPKE key pairs generated by MLS. An component identified by an CompnentID can use any HPKE key pair for any operation defined in [RFC9180], such as encryption, exporting keys and the PSK mode, as long as the info input to Setup<MODE>S and Setup<MODE>R is set to ComponentOperationLabel with component_id set to the appopriate ComponentID. The context can be set to an arbitrary Context specified by the application designer and can be empty if not needed. For example, a component can use a key pair PublicKey, PrivateKey to encrypt data as follows:

SafeEncryptWithContext(ComponentID, PublicKey, Context, Plaintext) =
    SealBase(PublicKey, ComponentOperationLabel, "", Plaintext)

SafeDecryptWithContext(ComponentID, PrivateKey, Context, KEMOutput, Ciphertext) =
    OpenBase(KEMOutput, PrivateKey, ComponentOperationLabel, "", Ciphertext)

Where the fields of ComponentOperationLabel are set to

label = "MLS 1.0 Application"
component_id = ComponentID
context = Context

For operations involving the secret key, ComponentID MUST be set to the ComponentID of the component performing the operation, and not to the ID of any other component. In particular, this means that a component cannot decrypt data meant for another component, while components can encrypt data that other components can decrypt.

In general, a ciphertext encrypted with a PublicKey can be decrypted by any entity who has the corresponding PrivateKey at a given point in time according to the MLS protocol (or application component). For convenience, the following list summarizes lifetimes of MLS key pairs.

5. Signature Keys

MLS session states contain a number of signature keys including the ones in the LeafNode structs. Application components can safely sign content and verify signatures using these keys via the SafeSignWithLabel and SafeVerifyWithLabel functions, respectively, much like how the basic MLS protocol uses SignWithLabel and VerifyWithLabel.

In more detail, a component identified by ComponentID should sign and verify using:

SafeSignWithLabel(ComponentID, SignatureKey, Label, Content) =
    SignWithLabel(SignatureKey, "ComponentOperationLabel", ComponentOperationLabel)

SafeVerifyWithLabel(ComponentID, VerificationKey, Label, Content, SignatureValue) =
    VerifyWithLabel(VerificationKey, "ComponentOperationLabel", ComponentOperationLabel, SignatureValue)

Where the fields of ComponentOperationLabel are set to

label = Label
component_id = ComponentID
context = Content

For signing operations, the ComponentID MUST be set to the ComponentID of the component performing the signature, and not to the ID of any other component. This means that a component cannot produce signatures in place of other component. However, components can verify signatures computed by other components. Domain separation is ensured by explicitly including the ComponentID with every operation.

6. Pre-Shared Keys

PSKs represent key material that is injected into the MLS key schedule when creating or processing a commit as defined in Section 8.4 of [RFC9420]. Its injection into the key schedule means that all group members have to agree on the value of the PSK.

While PSKs are typically cryptographic keys which due to their properties add to the overall security of the group, the PSK mechanism can also be used to ensure that all members of a group agree on arbitrary pieces of data represented as octet strings (without the necessity of sending the data itself over the wire). For example, a component can use the PSK mechanism to enforce that all group members have access to and agree on a password or a shared file.

This is achieved by creating a new epoch via a PSK proposal. Transitioning to the new epoch requires using the information agreed upon.

To facilitate using PSKs in a safe way, this document defines a new PSKType for application components. This provides domain separation between pre-shared keys used by the core MLS protocol and applications, and between those used by different components.

enum {
  // ...
  application(3),
  (255)
} PSKType;

struct {
  PSKType psktype;
  select (PreSharedKeyID.psktype) {
    // ...
    case application:
      ComponentID component_id;
      opaque psk_id<V>;
  };
  opaque psk_nonce<V>;
} PreSharedKeyID;

7. Exported Secrets

An application component can use MLS as a group key agreement protocol by exporting symmetric keys. Such keys can be exported (i.e. derived from MLS key material) in two phases per epoch: Either at the start of the epoch, or during the epoch. Derivation at the start of the epoch has the added advantage that the source key material is deleted after use, allowing the derived key material to be deleted later even during the same MLS epoch to achieve forward secrecy. The following protocol secrets can be used to derive key from for use by application components:

The application_export_secret is an additional secret derived from the epoch_secret at the beginning of the epoch in the same way as the other secrets listed in Table 4 of [RFC9420] using the label "application_export".

Any derivation performed by an application component either from the exporter_secret or the application_export_secret has to use the following function:

DeriveApplicationSecret(Secret, Label) =
  ExpandWithLabel(Secret, "ApplicationExport " + ComponentID + " " + Label)

Where ExpandWithLabel is defined in Section 8 of [RFC9420] and where ComponentID MUST be set to the ComponentID of the component performing the export.

8. Attaching Application Data to MLS Messages

The MLS GroupContext, LeafNode, KeyPackage, and GroupInfo objects each have an extensions field that can carry additional data not defined by the MLS specification. The application_data extension provides a generic container that applications can use to attach application data to these messages. Each usage of the extension serves a slightly different purpose:

The content of the application_data extension is a serialized ApplicationDataDictionary object:

struct {
    ComponentID component_id;
    opaque data<V>;
} ComponentData;

struct {
    ComponentData component_data<V>;
} ApplicationDataDictionary;

The entries in the component_data MUST be sorted by component_id, and there MUST be at most one entry for each component_id.

An application_data extension in a LeafNode, KeyPackage, or GroupInfo can be set when the object is created. An application_data extension in the GroupContext needs to be manage using the tools available to update GroupContext extensions: The creator of the group can set extensions unilaterally, and thereafter, the GroupContextExtensions proposal can be used to update extensions. The ApplicationDataUpdate proposal described in Section 9 provides a more efficient way to update the application_data extension.

9. Updating Application Data in the GroupContext

Updating the application_data with a GroupContextExtensions proposal is cumbersome. The application data needs to be transmitted in its entirety, along with any other extensions, whether or not they are being changed. And a GroupContextExtensions proposal always requires an UpdatePath, which updating application state never should.

The ApplicationDataUpdate proposal allows the application_data extension to be updated without these costs. Instead of sending the whole value of the extension, it sends only an update, which is interpreted by the application to provide the new content for the application_data extension. No other extensions are sent or updated, and no UpdatePath is required.

``` enum { invalid(0), update(1), remove(2), (255) } ApplicationDataUpdateOperation;

struct { ComponentID component_id; ApplicationDataUpdateOperation op;

select (ApplicationDataUpdate.op) {
    case update: opaque update<V>;
    case remove: struct{}
} } ApplicationDataUpdate; ```

An ApplicationDataUpdate proposal is invalid if its component_id references a component that is not known to the application, or if it specifies the removal of state for a component_id that has no state present. A proposal list is invalid if it includes multiple ApplicationDataUpdate proposals that remove state for the same component_id, or proposals that both update and remove state for the same component_id. In other words, for a given component_id, a proposal list is valid only if it contains (a) a single remove operation or (b) one or more update operation.

ApplicationDataUpdate proposals are processed after any default proposals (i.e., those defined in [RFC9420]), and any ApplicationData proposals.

A client applies ApplicationDataUpdate proposals by component ID. For each component_id field that appears in an ApplicationDataUpdate proposal in the Commit, the client assembles a list of ApplicationDataUpdate proposals with that component_id, in the order in which they appear in the Commit, and processes them in the following way:

10. Attaching Application Data to a Commit

The ApplicationData proposal type allows an application component to associate application data to a Commit, so that the member processing the Commit knows that all other group members will be processing the same data. ApplicationData proposals are ephemeral in the sense that they do not change any persistent state related to MLS, aside from their appearance in the transcript hash.

The content of an ApplicationData proposal is the same as an application_data extension. The proposal type is set in Section 12.

struct {
    ComponentID component_id;
    opaque data<V>;
} ApplicationData;

An ApplicationData proposal is invalid if it contains a component_id that is unknown to the application, or if the application_data field contains any ComponentData entry whose data field is considered invalid by the application logic registered to the indicated component_id.

ApplicationData proposals MUST be processed after any default proposals (i.e., those defined in [RFC9420]), but before any ApplicationDataUpdate proposals.

A client applies an ApplicationData proposal by providing the contents of the application_data field to the component identified by the component_id. If a Commit references more than one ApplicationData proposal for the same component_id value, then they MUST be processed in the order in which they are specified in the Commit.

11. Security Considerations

The API defined in this document provides the following security guarantee: If an application uses MLS and all its components use this API, then the security guarantees of the base MLS protocol and the security guarantees of the components, each analyzed in isolation, still hold for the composed protocol. In other words, the API protects applications from careless component developers. As long as all the components use this API, it is not possible that some combination of components (the developers of which did not know about each other) impedes the security of the base MLS protocol or any used component. No further analysis of the combination is necessary. This also means that any security vulnerabilities introduced by one component do not spread to other component or the base MLS protocol.

12. IANA Considerations

TODO:

13. References

13.1. Normative References

[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>.
[RFC9180]
Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180, , <https://www.rfc-editor.org/rfc/rfc9180>.
[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>.

13.2. Informative References

[I-D.mls-architecture]
"*** BROKEN REFERENCE ***".

Acknowledgments

Authors' Addresses

Joel Alwen
Amazon
Richard Barnes
Cisco
Rohan Mahy
Rohan Mahy Consulting Services
Marta Mularczyk
Amazon