Repository navigation
Fix E2EE decryption for H.264/H.265 frames with 3-byte start codes - #2144
Merged
Merged
Conversation
Some H.264/H.265 encoders (e.g. Intel Quick Sync on Windows) emit 3-byte start codes (00 00 01). WebRTC's depacketizer always reconstructs NALUs with 4-byte start codes, so the unencrypted header authenticated as AES-GCM additionalData on the sender no longer matched on the receiver and every frame failed to decrypt. The sender now rewrites 3-byte start codes to 4-byte in the unencrypted header before encrypting and sends that header. Frames that already use 4-byte start codes are byte-identical on the wire, so receivers need no change. Fixes #2140 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 1c9819e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
size-limit report 📦
|
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lukasIO
reviewed
Oct 9, 2026
lukasIO
approved these changes
Oct 9, 2026
Co-authored-by: lukasIO <mail@lukasseiler.de>
Indent and prettier-format the applied review suggestion, use an indexed for loop instead of forEach to match the rest of naluUtils.ts, and note that the zero-filled result array supplies each inserted leading 00. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
This pull request was LLM generated and has only been lightly reviewed by a human.
A more thorough review of this needs to occur before it could be merged.
Fixes #2140.
Problem
Some H.264/H.265 encoders, notably Intel Quick Sync on Windows Chrome, emit Annex B frames with 3-byte start codes (
00 00 01). WebRTC's packetizer strips start codes and the receiving depacketizer always rebuilds NALUs with 4-byte start codes (00 00 00 01).For H.264/H.265 the E2EE unencrypted header covers everything up to the first slice NALU (SPS/PPS/SEI plus the slice's own start code) and is authenticated as AES-GCM
additionalData. With 3-byte start codes, the header the sender authenticated differs from the header the receiver reconstructs, so every frame from such an encoder fails withOperationError. This affects delta frames too, not only keyframes, because the slice's start code is inside the header.Fix
Option 1 from the issue: in
encryptFrame, when NALU processing applies, rewrite 3-byte start codes in the unencrypted header to 4-byte (normalizeAnnexBStartCodesinnaluUtils.ts). The normalized header is used both asadditionalDataand as the header bytes sent in the frame, so it matches what any receiver's depacketizer produces.00 00 01can only be a start code, so the rewrite is safe.Tests
naluUtils.test.ts: exact input/output byte sequences for all-3-byte, mixed 3/4-byte, already-4-byte (same instance returned) and extra-leading-zero cases.FrameCryptor.test.ts: encrypts H.264 keyframes and delta frames and asserts the exact unencrypted header bytes on the wire use 4-byte start codes, then decrypts that output. Includes a 4-byte case that checks the header stays unchanged. The two 3-byte tests fail without the fix.🤖 Generated with Claude Code