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.
| @@ -0,0 +1,605 @@ | |||
| /* | |||
There was a problem hiding this comment.
Great that you have added these tests, some feedback though.
This test is not run any where, it needs to be added as a test target for at least cmake builds, but ideally also autotools and mason.
The style of tests in this file does not match either srtp_driver.c or test_srtp_policy.c , it would be good to not add a new test style. My preference would be to do it in the same way as test_srtp_policy.c
There was a problem hiding this comment.
I tried to do all of that, please review the latest changes in rcc_test.c
| } | ||
| } | ||
|
|
||
| /* |
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.
| if (policy == NULL) { | ||
| return srtp_err_status_bad_param; | ||
| } | ||
|
|
There was a problem hiding this comment.
should you check that roc_tx_rate >= 1 when mode != none ?
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.
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