Skip to content

refactor: remove length-prefixed logic for PQ key shares - #6041

Open
FreezB11 wants to merge 5 commits into
aws:mainfrom
FreezB11:leng_pref_logic_for_pq_removal
Open

refactor: remove length-prefixed logic for PQ key shares#6041
FreezB11 wants to merge 5 commits into
aws:mainfrom
FreezB11:leng_pref_logic_for_pq_removal

Conversation

@FreezB11

Copy link
Copy Markdown
Contributor

Problem

s2n-tls has supported multiple draft revisions of the PQ hybrid TLS 1.3
key share format while PQ standards were still in flux. Early drafts
required each sub-share (ECC + PQ) inside the combined KeyShareEntry to
carry its own 2-byte length prefix. This was only ever needed for draft
standards; s2n-tls has committed to supporting drafts (tls13_pq_hybrid_draft_revision < 5)
only through the end of 2025.

Draft revision 5 — the format used for ML-KEM support — dropped the
inner length prefixing entirely, since share sizes are fixed per named
group and the outer TLS 1.3 KeyShareEntry length is already sufficient
to parse the blob.

Solution

This PR removes the len_prefixed field from s2n_kem_params and all
logic that branches on it, since s2n-tls now only needs to support
draft revision 5 going forward.

Source changes:

  • tls/s2n_kem.h — remove the len_prefixed field
  • tls/s2n_kem.c — collapse the length-prefix branches in
    s2n_kem_send_public_key, s2n_kem_recv_public_key,
    s2n_kem_send_ciphertext, and s2n_kem_recv_ciphertext down to the
    unprefixed (revision 5) behavior
  • tls/extensions/s2n_key_share.[ch] — drop the len_prefixed
    parameter from s2n_ecdhe_send_public_key
  • tls/extensions/s2n_client_key_share.c /
    tls/extensions/s2n_server_key_share.c — remove the logic that set
    or inferred len_prefixed for TLS 1.3 negotiation
  • tls/s2n_kem_preferences.[ch] — remove
    s2n_tls13_client_must_use_hybrid_kem_length_prefix and related
    plumbing

Out of scope / explicitly preserved:

  • TLS 1.2 PQ key exchange (tls/s2n_client_key_exchange.c,
    tls/s2n_server_key_exchange.c) is unconditionally length-prefixed
    and is a separate wire format from the TLS 1.3 draft cleanup this
    issue targets. That behavior is preserved as-is and not touched by
    this PR.

Test changes:

  • tests/unit/s2n_server_key_share_extension_test.c — remove the
    len_prefixed loop, test only the unprefixed path
  • tests/unit/s2n_client_key_share_extension_pq_test.c — same, plus
    update s2n_copy_pq_share and s2n_generate_pq_hybrid_key_share_for_test
    helpers to drop the prefix parameter
  • tests/unit/s2n_kem_test.c — remove length-prefixed assertions from
    send/recv public key and ciphertext tests
  • tests/unit/s2n_tls13_pq_handshake_test.c — remove
    len_prefix_expected from test vectors and handshake assertions
  • tests/unit/s2n_pq_mlkem_policies_test.c — replace the
    length-prefix check with an assertion that ML-KEM policies use draft
    revision 5

Testing

  • s2n_pq_mlkem_policies_test: 725 assertions pass
  • s2n_server_key_share_extension_test: 353 assertions pass
  • s2n_client_key_share_extension_pq_test: 39 assertions pass
  • s2n_kem_test: 167 assertions pass
  • s2n_tls13_pq_handshake_test: compiles and passes (pre-existing,
    unrelated cert-path failure not introduced by this change)
  • grep -rn "len_prefixed" tls/ tests/ returns no results

Resolves #5606

s2n-tls supported multiple draft revisions of the PQ hybrid TLS 1.3
key share wire format. Early drafts required each sub-share (ECC and
PQ) to carry its own 2-byte length prefix inside the combined
KeyShareEntry blob. Draft revision 5, which is what ML-KEM support
uses, dropped this since sizes are fixed per named group and the
outer KeyShareEntry length is already sufficient.

Since s2n-tls only supports draft revision 5 going forward, the
len_prefixed field and all logic branching on it can be removed.

- Remove `len_prefixed` from `s2n_kem_params` (tls/s2n_kem.h)
- Collapse all `if (len_prefixed)` branches in s2n_kem.c to the
  unprefixed behavior
- Drop the `len_prefixed` parameter from `s2n_ecdhe_send_public_key`
  and update its call sites
- Remove length-prefix send/detect logic from client and server key
  share extension handling
- Remove `s2n_tls13_client_must_use_hybrid_kem_length_prefix` and
  related kem_preferences plumbing
- TLS 1.2 PQ key exchange, which is unconditionally length-prefixed
  and unrelated to the TLS 1.3 draft-revision cleanup, is unaffected
- Strip length-prefixed test paths from the key share and KEM unit
  tests (s2n_server_key_share_extension_test.c,
  s2n_client_key_share_extension_pq_test.c, s2n_kem_test.c,
  s2n_tls13_pq_handshake_test.c, s2n_pq_mlkem_policies_test.c)

Resolves aws#5606
@alexw91
alexw91 self-requested a review August 17, 2026 17:09
@alexw91

alexw91 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Thanks for this! Can you also remove .tls13_pq_hybrid_draft_revision everywhere too? That variable should only ever contain 0 or 5, and was the value that would be branched on to decide whether to length prefix or not. Now that we're no longer supporting length prefixing, we don't need that variable either.

@FreezB11

Copy link
Copy Markdown
Contributor Author

@alexw91 sure i can

@FreezB11 FreezB11 changed the title Remove length-prefixed logic for PQ key shares refactor: remove length-prefixed logic for PQ key shares Aug 17, 2026
@CarolYeh910
CarolYeh910 self-requested a review August 17, 2026 21:32
@FreezB11

Copy link
Copy Markdown
Contributor Author

thanks for running the actions the issue earlier was the aws-lc i recreated it on my machine and then fixed it, now will go ahead with removing tls13_pq_hybrid_draft_revision

@FreezB11

Copy link
Copy Markdown
Contributor Author

@alexw91 @CarolYeh910 would love some review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove the length-prefixed logic for PQ key shares

2 participants