RFC 4771 ROC in-band support - #814
Conversation
|
@volovolov , if you rebase on main then the wolfssl build failures should be fixed. |
a35ff96 to
07ca20e
Compare
@pabuhler Thank you, it's done now! |
|
@volovolov , looks like something else broke :( ... it is at least not related to your changes, I will follow it up |
pabuhler
left a comment
There was a problem hiding this comment.
Just an initial review, have not fully reviewed the main change yet.
| } | ||
| } | ||
|
|
||
| /* |
There was a problem hiding this comment.
This is a duplicate block of code, one should be deleted.
This validation should also maybe be done as part of srtp_policy_validate().
There was a problem hiding this comment.
Thanks, makes sense indeed to move the validation into srtp_policy_validate(), did that.
pabuhler
left a comment
There was a problem hiding this comment.
Hi,
Sorry for the delay in reviewing, I had some concerns regarding srtp_protect_rcc & srtp_unprotect_rcc and needed the time to look into it properly.
I was concerned that the new functions duplicates a lot of code and would increase maintenance overhead, but I understand that it would be alot of work to refactor the original code to support both and that it is maybe better done afterwards in small steps.
It also looks like there is no replay protection of ROC caring packets in mode 1&2, this means that when a ROC caring packet is received it always succeeds and reset the replay index. The ROC caring packet should only be accepted if it advances the replay index, otherwise it is possible to replay an older sequence.
Also if the ROC caring packet is aa new packet but false with in the current tracked window it should just update the window and not reset it.
If need I can help provide test case that show these problems.
| * which reads the sender's ROC from the authentication tag. | ||
| */ | ||
| if (stream->rcc_mode != srtp_rcc_mode_none && | ||
| stream != ctx->stream_template) { |
There was a problem hiding this comment.
Why this check? Looking at the tests there are none for ssrc_any_inbound, is that meant to be supported?
If it is a template stream and the ROC is already greater than 1 think it will always fail authentication?
Maybe need to add the stream duplication code in srtp_unprotect_rcc ?
I think it would work for the GCM case but not here.
|
@pabuhler Thank you for your latest feedback! I tried to address all of it, please have a look. There a no longer dedicated srtp_protect_rcc / srtp_unprotect_rcc, and issues concerning cases of ssrc_any_inbound and replay protection in modes 1-3 should be addressed, with new tests adding respective coverage. Best regards, Volodymyr |
Add RFC 4771 Roll-over Counter Carrying (RCC) support — modes 1, 2 and 3
Summary
This PR implements the RFC 4771 Roll-over Counter (ROC) Carrying integrity transform for SRTP. It lets a sender periodically embed its 32-bit ROC in the SRTP authentication tag of selected packets, so a late-joining or re-synchronizing receiver can recover the correct ROC without having to guess it from the RTP sequence number. All three RFC 4771 modes are supported, with mode 3 layered on top of the AES-GCM AEAD transform per RFC 7714 §8.2.
RCC is opt-in and fully backward compatible: streams that do not enable it (
srtp_rcc_mode_none, the default) behave exactly as before and use the standard RFC 3711 implicit-ROC transform.Motivation
Under RFC 3711 the ROC is never transmitted; a receiver infers it from the RTP sequence number. A receiver that joins mid-stream, loses synchronization, or misses a sequence-number wrap can end up with the wrong ROC and fail authentication on every subsequent packet. RFC 4771 solves this by carrying the ROC in-band on a configurable subset of packets ("ROC-carrying" packets, those whose RTP sequence number is
≡ 0 (mod R)).What's implemented
For a ROC-carrying packet in modes 1/2, the tag is built as:
where
MAC_tris the(auth_tag_len - 4)most-significant octets of the HMAC-SHA1. This requiresauth_tag_len >= 5.Packet layout
Modes 1/2 (AES-CM + HMAC-SHA1), ROC-carrying packet:
Mode 3 (AES-GCM, RFC 7714 §8.2), ROC-carrying packet:
The 4-octet ROC is the SRTP authentication-tag field and is placed after the MKI. It is not part of the GCM AAD (AAD remains the RTP header only); instead the ROC feeds the GCM IV, so any tampering with the carried ROC produces a wrong IV and a GCM authentication failure — giving implicit integrity protection of the ROC.
API changes
New public enum and function in
include/srtp.h:roc_tx_rate(R) is the transmission rate;R == 1carries the ROC in every packet. Must be>= 1when RCC is enabled.auth_tag_len >= 5; mode 3 requires an AES-GCM profile. Inconsistent combinations are rejected bysrtp_create()/ policy validation.Implementation notes
srtp_protect_rcc()/srtp_unprotect_rcc()paths insrtp/srtp.c.srtp_protect_aead()/srtp_unprotect_aead(), since GCM dispatch happens ahead of the RCC dispatch.srtp_rdbx_set_roc_seq()+ re-anchoring the replay index); non-carrying packets use the normal estimated packet index and replay check.srtp_len - 4for ROC-carrying packets so the existing "MKI is last" lookup still locates the MKI correctly. Carry-packet detection uses onlyseq % R == 0and the configured mode (no session keys required).Testing
Added
test/rcc_test.ccovering:srtp_err_status_auth_fail).All tests pass. Mode 3 tests require a build with GCM enabled (
-DENABLE_OPENSSL=ON).Backward compatibility
srtp_rcc_mode_nonestreams use the standard RFC 3711 transform.Limitations / open items