Code change:
3.2.3. <del> The sending client maps the outgoing streams and give them unique indices: 0, 1,.. etc.  As mentioned above SFrame supports up to 16 outgoing stream.  After encoding the frame and before packetizing it, the necessary media metadata will be moved out of the encoded frame buffer, to be used later in the RTP header extension.  The encoded frame, the metadata buffer and the stream index are passed to SFrame encryptor which internally keeps track of the number of frames encrypted so far for that stream.  The encryptor constructs SFrame header using the stream index and frame counter and derive the encryption IV.  The frame is encrypted using the encryption key and the header, encrypted frame and the media metadata are authenticated using the authentication key.  The authentication tag is then truncated (If supported by the cipher suite) and prepended at the end of the ciphertext. </del> <ins> After encoding the frame and before packetizing it, the necessary media metadata will be moved out of the encoded frame buffer, to be used later in the RTP header extension.  The encoded frame and the metadata buffer are passed to SFrame encryptor which internally keeps track of the number of frames encrypted so far.  The encryptor constructs SFrame header using frame counter and key id and derive the encryption IV.  The frame is encrypted using the encryption key and the header, encrypted frame and the media metadata are authenticated using the authentication key.  The authentication tag is then truncated (If supported by the cipher suite) and prepended at the end of the ciphertext. </ins> The encrypted payload is then passed to a generic RTP packetized to construct the RTP packets and encrypts it using SRTP keys for the

Related discussion:
text: LGTM
I have a doubt about why an SRC for the CTR is needed at all and if a global counter for all streams would be equally secure in terms forming the IV or was due to implementation details to be able to have different context for each streams?
Because the key is used to encrypt all outgoing stream, we need a global counter for the IV to avoid counter reuse. If we use the frame counter only, then each stream will have their own counter and IV will collide
If the frame counter is global for the participant instead that per stream, i.e. increased whenever a new frame is encoded regarding the media stream, there would be no IV collision.
Correct. But I imagine this will be more complex to implement, having a single global counter across all media sources including audio and video
Prepared a PR to change it to a global counter, however I want to make sure I understand how the counter is maintained globally, If the frame N is encrypted in 3 different layers, they will have different counter values right? One potential benefit of having a global counter it will free up some bits in the header which we can use as a keyId (up to 16 keys) which is nice
Yes, each call to the frame encryptor which would require to atomically increment the counter. In the case of the simulcast, the same input image will produce N different encoded frames which would have their unique counter. Regarding the free bits, I was thinking in something like this: If x=0 then K is the key id ( 0-7) if x=1 then K is the length of the key that is inserted before the This would allow to avoid the extra byte for conferences with less than 9 participants. Another option would be to always use the KLEN/KEYID and reserve that bit for extensions in the future.
I like it :-)