Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 63 additions & 48 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1327,19 +1327,28 @@ <h3>
</section>
</section>
<section id="rtp-header-extension-encryption">
<h3>RTP Header Extension Encryption</h3>
<h3>RTP Header Encryption</h3>
<section id="rtp-header-extension-encryption-policy">
<h3>
<dfn>RTCRtpHeaderEncryptionPolicy</dfn> Enum
</h3>
<p>
RTP header extension encryption policy affects whether RTP header extension
encryption is negotiated if the remote endpoint does not support [[RFC9335]].
If the remote endpoint supports [[RFC9335]], all media streams are sent
utilizing [[RFC9335]].
[[RFC9335]], also known as cryptex, defines a mechanism for encrypting the RTP
header extensions and the contributing source (CSRC) identifiers of an RTP packet,
both of which are left in the clear by [[RFC3711]]. It is signaled with the
"a=cryptex" SDP attribute, whose presence in an offer or an answer indicates that
the endpoint is capable of receiving RTP packets encrypted with cryptex. Once both
endpoints have indicated that capability, a sender decides on a per-packet basis
whether to apply cryptex.
</p>
<p>
The RTP header encryption policy determines whether the user agent indicates that
capability, and whether it is willing to continue with a remote endpoint which has
not indicated it.
</p>
<div>
<pre id="target-rtp-header-encryption-policy" class="idl">enum RTCRtpHeaderEncryptionPolicy {
"disable",
"negotiate",
"require"
};</pre>
Expand All @@ -1350,68 +1359,52 @@ <h3>
<th colspan="2">Enumeration description (non-normative)</th>
</tr>
<tr>
<td><dfn data-idl>negotiate</dfn></td>
<td><dfn data-idl>disable</dfn></td>
<td>
<p>
Negotiate RTP header extension encryption as defined in [[RFC9335]].
If encryption cannot be negotiated, RTP header extensions are sent in
the clear.
Do not use RTP header encryption. The "a=cryptex" attribute is not
included in offers or answers and not acted upon when present in the
remote description. RTP header extensions and CSRCs are sent in the clear.
</p>
</td>
</tr>
<tr>
<td><dfn data-idl>negotiate</dfn></td>
<td>
<p>
Negotiate RTP header encryption as defined in [[RFC9335]]. If the remote
endpoint does not indicate that it is capable of receiving RTP packets
encrypted with cryptex, RTP header extensions and CSRCs are sent in the
clear. If the remote endpoint indicates support for cryptex, the user
agent may use cryptex for endcrypting RTP header extensions and CSRCS
as described in [[RFC9335]] Section 4.
</p>
</td>
</tr>
<tr>
<td><dfn data-idl>require</dfn></td>
<td>
<p>
Require RTP header extension encryption. In [[WEBRTC]] Section 4.4.1.5, add the
Require RTP header encryption. In [[WEBRTC]] Section 4.4.1.5, add the
following check after Step 4.4.4:
If <var>remote</var> is <code>true</code>, the <var>connection</var>'s
{{RTCRtpHeaderEncryptionPolicy}} is {{RTCRtpHeaderEncryptionPolicy/require}}
and the description does not support [[RFC9335]], then [= reject =] <var>p</var>
{{RTCConfiguration/rtpHeaderEncryptionPolicy}} is
{{RTCRtpHeaderEncryptionPolicy/require}} and the description does not
indicate that the remote endpoint is capable of receiving RTP packets
encrypted with cryptex, then [= reject =] <var>p</var>
with a newly [= exception/created =] {{InvalidAccessError}} and abort these steps.
</p>
<p>
In addition, the user agent MUST consider the use of [[RFC9335]]
mandatory, as described in [[RFC9335]] Section 5.2. Received RTP packets
which are not encrypted with cryptex are not processed further.

@youennf youennf Jul 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it clear how these dropped packets would appear on webrtc-stats? Will they even appear?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't have a SRTP unprotect failure counter so they would be dropped silently. Might be a useful thing to have regardless (I am looking at you error=9)

</p>
</td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="rtp-header-extension-encryption-transceiver-interface">
<h3>
{{RTCRtpTransceiver}} interface extensions
</h3>
<p>
{{RTCRtpTransceiver/rtpHeaderEncryptionNegotiated}} defines whether
the transceiver is sending enrypted RTP header extensions as defined in
[[RFC9335]].
</p>
<pre class="idl">
partial interface RTCRtpTransceiver {
readonly attribute boolean rtpHeaderEncryptionNegotiated;
};</pre>
<section>
<h2>
Attributes
</h2>
<dl data-link-for="RTCRtpTransceiver" data-dfn-for=
"RTCRtpTransceiver" class="attributes">
<dt>
<dfn id="dom-rtptransceiver-rtpHeaderEncryptionNegotiated">rtpHeaderEncryptionNegotiated</dfn> of type <span class=
"idlAttrType">Boolean</span>, readonly, nullable
</dt>
<dd>
<p>
The {{rtpHeaderEncryptionNegotiated}} attribute indicates whether [[RFC9335]] has been
negotiated. On getting, the attribute MUST
return the value of the {{RTCRtpTransceiver/[[RtpHeaderEncryptionNegotiated]]}} slot.
In [[WEBRTC]] Section 5.4, add the following step to "create an {{RTCRtpTransceiver}}":
Let <var>transceiver</var> have a <dfn data-dfn-for="RTCRtpTransceiver">[[\RtpHeaderEncryptionNegotiated]]</dfn>
internal slot, initialized to <code>false</code>.
</p>
</dd>
</dl>
</section>
</section>
<section id="configuration">
<h3>
{{RTCConfiguration}} extensions
Expand All @@ -1436,6 +1429,28 @@ <h2>
</dt>
<dd>
<p class="needs-test">
The {{RTCConfiguration/rtpHeaderEncryptionPolicy}} applies to the
{{RTCPeerConnection}} as a whole. The "a=cryptex" attribute is assigned to
the TRANSPORT category [[RFC8859]], so when BUNDLE is in use it is either
present on every RTP-based m= section of a bundle group or on none of them,
as required by [[RFC9335]] Section 4.
</p>
<p class="needs-test">
{{RTCConfiguration/rtpHeaderEncryptionPolicy}} can only be set when
constructing the {{RTCPeerConnection}} and cannot be changed afterwards.
In the <a data-cite="WEBRTC#set-the-configuration">set the configuration</a>
algorithm, add a step after the step saying
"If the value of configuration.rtcpMuxPolicy differs from oldConfig.rtcpMuxPolicy, then fail."
saying
"If the value of configuration.{{RTCConfiguration/rtpHeaderEncryptionPolicy}} differs from
oldConfig.{{RTCConfiguration/rtpHeaderEncryptionPolicy}}, then fail."
</p>
<p>
In setConfiguration in [[RTCWEB-JSEP]] section 4.1.18, replace
"The bundle and RTCP-multiplexing policies MUST NOT be changed after the construction of the PeerConnection."
with
"The bundle policy, the RTCP-multiplexing policy and the RTP header encryption policy
MUST NOT be changed after the construction of the PeerConnection."
Comment on lines +1449 to +1453

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need to modify JSEP to add an additional restriction. Might it suffice to say:

Suggested change
In setConfiguration in [[RTCWEB-JSEP]] section 4.1.18, replace
"The bundle and RTCP-multiplexing policies MUST NOT be changed after the construction of the PeerConnection."
with
"The bundle policy, the RTCP-multiplexing policy and the RTP header encryption policy
MUST NOT be changed after the construction of the PeerConnection."
This spec adds the following restriction above and beyond what is described for
setConfiguration in [[RTCWEB-JSEP]] section 4.1.18:
"The RTP header encryption policy MUST NOT be changed after the construction of the PeerConnection."

Either way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

</p>
<div class="issue atrisk">
<p>
Expand Down
Loading