Skip to main content

rtc_srtp/context/
srtp.rs

1use super::*;
2use shared::{
3    error::{Error, Result},
4    marshal::{MarshalSize, Unmarshal},
5};
6
7use bytes::BytesMut;
8
9impl Context {
10    /// Decrypts an SRTP packet whose header has already been parsed.
11    ///
12    /// Saves re-parsing when the caller needed the header to route the packet. The header must
13    /// be the one belonging to `encrypted`.
14    ///
15    /// # Errors
16    ///
17    /// Fails if authentication fails, if the packet is a replay, or if it is too short to hold
18    /// the profile's auth tag.
19    pub fn decrypt_rtp_with_header(
20        &mut self,
21        encrypted: &[u8],
22        header: &rtp::Header,
23    ) -> Result<BytesMut> {
24        let auth_tag_len = self.cipher.rtp_auth_tag_len();
25        if encrypted.len() < header.marshal_size() + auth_tag_len {
26            return Err(Error::ErrTooShortRtp);
27        }
28
29        let state = self.get_srtp_ssrc_state(header.ssrc);
30        let (roc, diff, _) = state.next_rollover_count(header.sequence_number);
31        if let Some(replay_detector) = &mut state.replay_detector
32            && !replay_detector.check(header.sequence_number as u64)
33        {
34            return Err(Error::SrtpSsrcDuplicated(
35                header.ssrc,
36                header.sequence_number,
37            ));
38        }
39
40        let dst = self.cipher.decrypt_rtp(encrypted, header, roc)?;
41        {
42            let state = self.get_srtp_ssrc_state(header.ssrc);
43            if let Some(replay_detector) = &mut state.replay_detector {
44                replay_detector.accept();
45            }
46            state.update_rollover_count(header.sequence_number, diff);
47        }
48
49        Ok(dst)
50    }
51
52    /// DecryptRTP decrypts a RTP packet with an encrypted payload
53    pub fn decrypt_rtp(&mut self, encrypted: &[u8]) -> Result<BytesMut> {
54        let mut buf = encrypted;
55        let header = rtp::Header::unmarshal(&mut buf)?;
56        self.decrypt_rtp_with_header(encrypted, &header)
57    }
58
59    /// Encrypts an RTP payload, using an already-parsed header.
60    ///
61    /// Saves re-parsing when the caller has just built the header. Returns the full protected
62    /// packet, header included.
63    ///
64    /// # Errors
65    ///
66    /// Fails if the SRTP context has no key for this SSRC or the cipher rejects the input.
67    pub fn encrypt_rtp_with_header(
68        &mut self,
69        plaintext: &[u8],
70        header: &rtp::Header,
71    ) -> Result<BytesMut> {
72        let (roc, diff, ovf) = self
73            .get_srtp_ssrc_state(header.ssrc)
74            .next_rollover_count(header.sequence_number);
75        if ovf {
76            // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key
77            // (whichever occurs before), the key management MUST be called to provide new master key(s)
78            // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated.
79            // https://www.rfc-editor.org/rfc/rfc3711#section-9.2
80            return Err(Error::ErrExceededMaxPackets);
81        }
82
83        let dst = self.cipher.encrypt_rtp(plaintext, header, roc)?;
84
85        self.get_srtp_ssrc_state(header.ssrc)
86            .update_rollover_count(header.sequence_number, diff);
87
88        Ok(dst)
89    }
90
91    /// EncryptRTP marshals and encrypts an RTP packet, writing to the dst buffer provided.
92    /// If the dst buffer does not have the capacity to hold `len(plaintext) + 10` bytes, a new one will be allocated and returned.
93    pub fn encrypt_rtp(&mut self, plaintext: &[u8]) -> Result<BytesMut> {
94        let mut buf = plaintext;
95        let header = rtp::Header::unmarshal(&mut buf)?;
96        self.encrypt_rtp_with_header(plaintext, &header)
97    }
98}