From 58a9054f3240adf134c2141e63c02054910035d2 Mon Sep 17 00:00:00 2001 From: Mark Xue Date: Thu, 24 Sep 2026 17:20:39 -0700 Subject: [PATCH 1/2] =?UTF-8?q?State=20the=20=C2=A7A.1=20reply's=20MLSMess?= =?UTF-8?q?age=20framing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The book was silent on whether the welcome halves and return key package are bare structs or MLSMessages. The deployed engine emits and requires MLSMessages. Co-Authored-By: Claude Opus 5.5 --- .changeset/book-a1-envelope-framing.md | 4 ++++ book/src/wire-format.md | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/book-a1-envelope-framing.md diff --git a/.changeset/book-a1-envelope-framing.md b/.changeset/book-a1-envelope-framing.md new file mode 100644 index 0000000..d7d0464 --- /dev/null +++ b/.changeset/book-a1-envelope-framing.md @@ -0,0 +1,4 @@ +--- +--- + +Book-only: state that the §A.1 reply's welcome halves and return key package are MLSMessages; nothing ships. diff --git a/book/src/wire-format.md b/book/src/wire-format.md index e041f2f..74a86c2 100644 --- a/book/src/wire-format.md +++ b/book/src/wire-format.md @@ -119,6 +119,9 @@ only AFTER HPKE-open, by the authenticated leading tag of the plaintext: - `ESTABLISHMENT_VECTOR_TAG` (`0x07`) → the establishment reply — four u32-LE length-prefixed sections `[app_payload][welcome][return_key_package][stapled_message]`. + Each half of the `welcome` section's `APQWelcome` is an RFC 9420 `MLSMessage` + (`wire_format = mls_welcome`), and `return_key_package` is an `MLSMessage` + (`mls_key_package`), not the bare structs: the form the deployed engine emits and requires. - `PQ_BOOTSTRAP_KP_TAG` (`0x13`) → the parallel-delivered A.3 bootstrap KP frame, carried verbatim (`[0x13][KP′]`) — the same side-band frame steady-state A.3 uses, only its outer framing differs (HPKE envelope here vs. header-sealed side-band later). From 30d8dcbecd046ef0e611da14b053ff1491c80f60 Mon Sep 17 00:00:00 2001 From: Mark Xue Date: Thu, 24 Sep 2026 17:31:44 -0700 Subject: [PATCH 2/2] Ground the MLSMessage framing in RFC 9420, and scope the deviation The spec states intended behavior, so justify the envelope on RFC terms, and record in the draft-02 conformance section that every APQWelcome and APQKeyPackage element travels as an MLSMessage. Co-Authored-By: Claude Opus 5.5 --- .changeset/book-a1-envelope-framing.md | 2 +- book/src/wire-format.md | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.changeset/book-a1-envelope-framing.md b/.changeset/book-a1-envelope-framing.md index d7d0464..af8ad7b 100644 --- a/.changeset/book-a1-envelope-framing.md +++ b/.changeset/book-a1-envelope-framing.md @@ -1,4 +1,4 @@ --- --- -Book-only: state that the §A.1 reply's welcome halves and return key package are MLSMessages; nothing ships. +Book-only: state that draft-02 pair elements (APQWelcome and APQKeyPackage halves) and the §A.1 return key package travel as RFC 9420 MLSMessages; nothing ships. diff --git a/book/src/wire-format.md b/book/src/wire-format.md index 74a86c2..ac6224e 100644 --- a/book/src/wire-format.md +++ b/book/src/wire-format.md @@ -119,9 +119,10 @@ only AFTER HPKE-open, by the authenticated leading tag of the plaintext: - `ESTABLISHMENT_VECTOR_TAG` (`0x07`) → the establishment reply — four u32-LE length-prefixed sections `[app_payload][welcome][return_key_package][stapled_message]`. - Each half of the `welcome` section's `APQWelcome` is an RFC 9420 `MLSMessage` - (`wire_format = mls_welcome`), and `return_key_package` is an `MLSMessage` - (`mls_key_package`), not the bare structs: the form the deployed engine emits and requires. + Each half of the `welcome` section's `APQWelcome` and the `return_key_package` travel in + their RFC 9420 `MLSMessage` envelope (`wire_format = mls_welcome` and `mls_key_package`), + which describes its own protocol version and content type (see + [Draft-02 conformance](#draft-02-conformance-inside-the-frames)). - `PQ_BOOTSTRAP_KP_TAG` (`0x13`) → the parallel-delivered A.3 bootstrap KP frame, carried verbatim (`[0x13][KP′]`) — the same side-band frame steady-state A.3 uses, only its outer framing differs (HPKE envelope here vs. header-sealed side-band later). @@ -286,9 +287,9 @@ move. ## Draft-02 conformance inside the frames The Germ tags above are the *transport* envelope; inside them the MLS payloads carry -the `draft-ietf-mls-combiner-02` structures directly. The apq crate conforms to the -draft, and the Germ frames **enclose** the draft-02 wire shapes rather than replacing -them. +the `draft-ietf-mls-combiner-02` structures. The apq crate conforms to the draft, and the +Germ frames **enclose** the draft-02 wire shapes rather than replacing them, with one +deviation in how a pair's elements travel (the last bullet below). - **APQInfo** — a GroupContext extension (type `0xF0A1`) present in both halves of each APQ group and carried automatically in every Welcome's GroupInfo. It names both group @@ -300,7 +301,15 @@ them. agree and match the actual post-commit epochs before any app data is decrypted. - **Combiner key package** — the `CombinerKeyPackage` payload adopts the draft's §7 `APQKeyPackage { t_key_package, pq_key_package }` TLS encoding inside Germ's version - framing. A key package that does not carry this encoding is rejected outright. + framing (`[v=3]`), each half an `opaque` vector. A key package that does not carry + this encoding is rejected outright. +- **Pair elements travel as `MLSMessage`s** — where a draft-02 §7 pair declares a bare + `Welcome` or `KeyPackage` field (`APQWelcome`, `APQKeyPackage`), Germ carries each + element as its RFC 9420 `MLSMessage` instead (`wire_format = mls_welcome` or + `mls_key_package`), which describes its own protocol version and content type. This + covers both halves of the combiner key package, each half of every `APQWelcome`, and the + §A.1 reply's return key package. Draft-02 does not specify how these structures are + transmitted, so this is Germ's choice of the RFC's transport envelope. Every occupied leaf must advertise the `APQInfo` extension (`0xF0A1`) and the `AppDataUpdate` proposal (`0x0008`) types; a leaf that cannot support them is rejected