Conversation
Add deterministic key wrapping under an AES key-encryption key, built on the exposed AES-ECB block primitive: r_cipher_aes_key_wrap / _unwrap for the RFC 3394 (NIST SP 800-38F) whole-64-bit-block form, and the r_cipher_aes_key_wrap_pad / _unwrap_pad RFC 5649 padded form for arbitrary lengths, including the single-block case. Both carry the 64-bit integrity check, so unwrap verifies as it decrypts and fails closed on a wrong key or tampered ciphertext. Needed as the EKT cipher for Encrypted Key Transport (RFC 8870); a reusable primitive on its own. Tested against the RFC 3394 and RFC 5649 vectors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Carry a sender's SRTP master key in-band so a peer (typically a conference focus) can learn and rotate it without separate signalling. Configuring an EKTKey (r_srtp_add_ekt_key: an AES Key Wrap cipher + key, an SPI, and the SRTP suite and master salt the transported keys use) turns EKT framing on for the context. On protect, an EKT field is appended after the SRTP/SRTCP auth tag: a Full field (AES-KW of SRTPMasterKeyLength || key || SSRC || ROC, then SPI || Epoch || Length || 0x02) in a short startup burst, periodically thereafter (r_srtp_set_ekt_full_interval) so a mid-stream joiner can key itself, and a Short field (0x00) otherwise. The field is outside the SRTP-authenticated portion and carries its own AES-KW integrity check. On unprotect, the field is stripped from a zero-copy view before SRTP decoding; a Full field is ingested first -- its SPI selects the EKTKey, the wrapped key is unwrapped, the inner SSRC is matched against the packet, and the recovered key + salt + ROC are installed as the crypto context for that SSRC, so the same packet then decrypts with it. Epoch state is tracked per (SPI, SSRC), outside the stream so it survives a key reinstall, so a Full field whose epoch was already seen -- a burst repeat or a replay, including one that alternates SPIs -- is not re-installed (RFC 8870 4.3.2). r_srtp_update_crypto_context_for_ssrc rolls a sender's own key in place, keeping the packet index continuous; EKT then bumps the epoch and re-announces in a fresh burst. The application decides when to switch encrypting to the new key. Closes #442 Co-Authored-By: Claude Opus 4.8 <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.
Implements RFC 8870 Encrypted Key Transport, closing #442. Two commits: the reusable AES Key Wrap primitive, then EKT layered on it.
AES Key Wrap (RFC 3394 + RFC 5649)
r_cipher_aes_key_wrap/_unwrap(whole-64-bit-block form) and_wrap_pad/_unwrap_pad(arbitrary length, incl. the single-block case), built on the exposed AES-ECB block primitive. Both carry the 64-bit integrity check and fail closed on a wrong key or tampered ciphertext. Tested against the RFC 3394 §4.1 and RFC 5649 §6 vectors plus round-trip and failure cases. A reusable primitive independent of SRTP.EKT (RFC 8870)
Carries a sender's SRTP master key in-band so a peer (typically a conference focus) can learn and rotate it without separate signalling. Configuring an EKTKey (
r_srtp_add_ekt_key— AES Key Wrap cipher + key, SPI, and the SRTP suite + master salt the transported keys use) turns EKT framing on for the context.AES-KW(mklen‖key‖SSRC‖ROC) ‖ SPI ‖ Epoch ‖ Length ‖ 0x02) in a startup burst, periodically thereafter (r_srtp_set_ekt_full_interval) so a mid-stream joiner can key itself, and a Short field (0x00) otherwise. It is outside the SRTP-authenticated portion and carries its own AES-KW integrity check.r_srtp_update_crypto_context_for_ssrcrolls a sender's own key in place, keeping the packet index continuous; EKT bumps the epoch and re-announces. The application decides when to switch encrypting to the new key.Testing
New tests cover the AES-KW RFC vectors + failures, and EKT round-trip (RTP + SRTCP), Full/Short burst, periodic resend, sender rekey, and a multi-SPI replay-downgrade regression — proven load-bearing by neutering the anti-replay and epoch-bump checks. Validated on the linux and ASan tiers (both warning-free); full suite 2345 passed / 0 failed. Reviewed with two rounds of adversarial audit (memory-safety, crypto/protocol, docs), including a fix hardening the epoch anti-replay to per-(SPI, SSRC).
🤖 Generated with Claude Code