libsrtp

Crates.iolibsrtp
lib.rslibsrtp
version0.1.0
created_at2025-09-22 07:42:18.433439+00
updated_at2025-09-22 07:42:18.433439+00
descriptiona pure rust implementation of SRTP
homepagehttps://github.com/jeannotlapin/libsrtp-rs/tree/master/libsrtp
repositoryhttps://github.com/jeannotlapin/libsrtp-rs
max_upload_size
id1849633
size242,516
Johan Pascal (jeannotlapin)

documentation

https://docs.rs/libsrtp

README

Crates.io Docs.rs CI Maintenance License: MIT/Apache-2.0

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

Commit count: 1

cargo fmt