1 unstable release
Uses new Rust 2024
| 0.1.0 | Sep 22, 2025 |
|---|
#1070 in Cryptography
175KB
3.5K
SLoC
A pure rust implementation of Secure Real-time Transport Protocol (SRTP)
This crate implements RFC 3711, RFC 6188 and RFC 7714
Features
This library supports all the mandatory features from RFC 3711, RFC 6188 and RFC 7714. The following optional features are not supported:
- key derivation rates
- AES in f8 mode
- master key selection based on packet index
This library aims to support the same set of features supported by Cisco's SRTP C library libsrtp.
Features list
- Support for protection profiles:
- Null Cipher with full auth tag. RFC 3711
- AES128 Counter mode - with no, short or full auth tag. RFC 3711
- AES192/256 Counter mode - with no, short or full auth tag. RFC6188
- AES128/256 GCM with 16 bytes auth tag. RFC7714
- Notes:
- for RTCP, short or no auth tag is not supported as specified in RFC 3711
- auth tag only is not supported for GCM. The only way avoid encryption while authenticating is to use the NullCipherHmacSha180 profile.
- Master Key Identifier (MKI)
- Replay protection (default window size is 128) - opt out possible on RTP sending side
- Keys lifetime
- keys lifetime can be set on a master key basis. The default values are 2^48 for RTP and 2^31 for RTCP, they can only be lowered.
- keys lifetime is decreased on a stream/master key base, even for stream spawned from template and thus sharing the master key. Each templated stream gets it own life count, one for each mki(when used).
- Any key reaching its end of life(on RTP or RCTP) will disable all keys derived from the same master key including:
- the other component of the stream: RTP end of life disables RTCP, RTCP end of life disables RTP
- the other streams spwaned from the same master key if any
- when using mki, keys derived from others master key are not affected
- Index rollback
- due to re-keying (which does not reset RTP nor RTCP indexes), a key end of life does not necessarily happens on index rollback.
- RTCP index rollback is supported: after sending 2^31 RTCP packets, provided several mkis were used, the next RTCP packet index will roll back to 0.
- RTP index being on 48 bits, a rollback seem very unlikely in real life and is not supported.
- Key limit alert
- When provided, a key limit handler is called when a key life is nearing the end (2^16 lives left by default) or is over.
- When a key reaches its end of life, any operation using it will:
- call the key limit handler
- fail returning a KeyLimit error
- Multithreading
- full support for multithreading operations
- sessions can be shared among different thread, so each stream can run in its own thread
Non supported features list
The following features are supported by Cisco's libsrtp but not yet by this library:
- Encryption of Header Extensions RFC 6904
- Completely Encrypting RTP Header Extensions and Contributing Sources RFC 9335
Implementation note
The base cryptographic operations (HMAC-SHA1, AES-CTR, AES-GCM) are provided by RustCrypto crates.
Testing
Testing requires helpers crates found on this repository
Interoperability test with cisco's libsrtp are provided in a dedicated crate
Example
use libsrtp::{MasterKey, ProtectionProfile, RecvSession, SendSession, SrtpError, StreamConfig};
# fn main() {
# let master_key = vec![
# 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde,
# 0x41, 0x39,
# ];
# let master_salt = vec![
# 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6,
# ];
# let mut packet = vec![
# 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab,
# 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
# ];
# let ssrc : u32 = 0xcafebabe;
// create a stream configuration
// master_key and master_salt must be Vec<u8> of size matching the selected profiles
let config = StreamConfig::new(
// we use one master key, no mki
vec![MasterKey::new(&master_key, &master_salt, &None)],
// RTP and RTCP protection profiles are set to AES128CM with HmacSha1-80 authentication
&ProtectionProfile::Aes128CmHmacSha180,
&ProtectionProfile::Aes128CmHmacSha180,
);
/************ Sender Side *************************/
// create a sender session and add a stream to it
// this stream is added specifying its SSRC.
// It will process only the packets with this SSRC in their header
let mut s = SendSession::new();
s.add_stream(Some(ssrc), &config).unwrap();
// encrypt and authenticate the packet
// the encryption is performed in place (get and give back the ownership)
// packet is a Vec<u8> holding the whole RTP packet - header included
packet = s.rtp_protect(packet).unwrap();
/************ Receiver Side ***********************/
// create a receiver session and add a stream to it
// in a real context this would be performed on the other endpoint
let mut r = RecvSession::new();
// this stream is added without specifying a SSRC, it is a template stream
// upon decryption of a packet with an unknown SSRC, it will spawn a stream for it
r.add_stream(None, &config).unwrap();
// authenticate and decrypt the packet
// decryption is performed in place
packet = r.rtp_unprotect(packet).unwrap();
# }
License
This library is distributed under either of:
Copyright (c) 2025 Johan Pascal
Dependencies
~1.9–2.5MB
~53K SLoC