rtc_srtp/context/
srtp.rs

1use super::*;
2use shared::{
3    error::Result,
4    marshal::{MarshalSize, Unmarshal},
5};
6
7use bytes::BytesMut;
8
9impl Context {
10    pub fn decrypt_rtp_with_header(
11        &mut self,
12        encrypted: &[u8],
13        header: &rtp::header::Header,
14    ) -> Result<BytesMut> {
15        let roc;
16        {
17            if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
18                if let Some(replay_detector) = &mut state.replay_detector {
19                    if !replay_detector.check(header.sequence_number as u64) {
20                        return Err(Error::SrtpSsrcDuplicated(
21                            header.ssrc,
22                            header.sequence_number,
23                        ));
24                    }
25                }
26
27                roc = state.next_rollover_count(header.sequence_number);
28            } else {
29                return Err(Error::SsrcMissingFromSrtp(header.ssrc));
30            }
31        }
32
33        let dst = self.cipher.decrypt_rtp(encrypted, header, roc)?;
34        {
35            if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
36                if let Some(replay_detector) = &mut state.replay_detector {
37                    replay_detector.accept();
38                }
39                state.update_rollover_count(header.sequence_number);
40            }
41        }
42
43        Ok(dst)
44    }
45
46    /// DecryptRTP decrypts a RTP packet with an encrypted payload
47    pub fn decrypt_rtp(&mut self, encrypted: &[u8]) -> Result<BytesMut> {
48        let mut buf = encrypted;
49        let header = rtp::header::Header::unmarshal(&mut buf)?;
50        self.decrypt_rtp_with_header(encrypted, &header)
51    }
52
53    pub fn encrypt_rtp_with_header(
54        &mut self,
55        plaintext: &[u8],
56        header: &rtp::header::Header,
57    ) -> Result<BytesMut> {
58        let roc;
59        {
60            if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
61                roc = state.next_rollover_count(header.sequence_number);
62            } else {
63                return Err(Error::SsrcMissingFromSrtp(header.ssrc));
64            }
65        }
66
67        let dst = self
68            .cipher
69            .encrypt_rtp(&plaintext[header.marshal_size()..], header, roc)?;
70
71        {
72            if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
73                state.update_rollover_count(header.sequence_number);
74            }
75        }
76
77        Ok(dst)
78    }
79
80    /// EncryptRTP marshals and encrypts an RTP packet, writing to the dst buffer provided.
81    /// If the dst buffer does not have the capacity to hold `len(plaintext) + 10` bytes, a new one will be allocated and returned.
82    pub fn encrypt_rtp(&mut self, plaintext: &[u8]) -> Result<BytesMut> {
83        let mut buf = plaintext;
84        let header = rtp::header::Header::unmarshal(&mut buf)?;
85        self.encrypt_rtp_with_header(plaintext, &header)
86    }
87}