Crates.io | sframe |
lib.rs | sframe |
version | 1.0.1 |
created_at | 2022-12-16 13:07:50.943625+00 |
updated_at | 2025-08-12 20:01:45.61738+00 |
description | pure rust implementation of SFrame (RFC 9605) |
homepage | |
repository | https://github.com/TobTheRock/sframe-rs |
max_upload_size | |
id | 738807 |
size | 306,700 |
This library is an implementation of Sframe (RFC 9605) and provides and end-to-end encryption mechanism for media frames that is suited for WebRTC conferences. It was forked from the original goto-opensource/secure-frame-rs and is continued here.
Currently two crypto libraries are supported:
ring
openssl
cargo build --features openssl --no-default-features
perl
(and perl-core
), and make
. For further options see the openssl crate documentation.rust-crypto
cargo build --features rust-crypto --no-default-features
Both cannot be enabled at the same time, thus on conflict sframe
issues a compiler error.
The API provides low-level access to encryption and decryption at the frame level.
It allows the use of arbitrary buffers, enabling the creation of views to avoid unnecessary copies:
MediaFrameView
for unencrypted dataEncryptedFrameView
for encrypted dataFor encryption and decryption, a buffer must be provided implementing the FrameBuffer
trait to allocate the necessary memory.
For convenience, this trait has already been implemented for Vec<u8>
.
There is also a variant which allocates the necessary memory and owns the buffers:
MediaFrame
for unencrypted dataEncryptedFrame
for encrypted dataTo convert between MediaFrame(View)
and EncryptedFrame(View)
, an EncryptionKey
or DecryptionKey
is needed,
which needs to be derived from a shared and secret key material.
flowchart TD
subgraph Sender
A[MediaFrame<br/>Payload + Metadata] -->|new/with_metadata| B[MediaFrame/MediaFrameView]
B --> EncryptJunction(( ))
EncryptJunction -->|encrypt/encrypt_into| C[EncryptedFrame/EncryptedFrameView]
FC[FrameCounter] --> EncryptJunction
EK[EncryptionKey] --> EncryptJunction
end
Shared[Key Material<br/>CipherSuite]
Shared -->|derive_from| EK
Shared -->|derive_from| DK
subgraph Receiver
D[Incoming Frame Buffer] -->|try_new/try_with_meta_data| E[EncryptedFrame/EncryptedFrameView]
E --> DecryptJunction(( ))
DecryptJunction -->|decrypt/decrypt_into| F[MediaFrame/MediaFrameView]
DK[DecryptionKey] --> KS[KeyStore]
KS --> DecryptJunction
end
C -.->|Network| D
style Shared fill:#4f46e5
style B fill:#4f46e5
style C fill:#4f46e5
style E fill:#4f46e5
style F fill:#4f46e5
style EK fill:#4f46e5
style DK fill:#4f46e5
style FC fill:#4f46e5
style KS fill:#4f46e5
style EncryptJunction fill:transparent
style DecryptJunction fill:transparent
For example:
use sframe::{
frame::{EncryptedFrameView, MediaFrameView, MonotonicCounter},
key::{DecryptionKey, EncryptionKey},
CipherSuite,
};
let key_id = 42u64;
let enc_key = EncryptionKey::derive_from(CipherSuite::AesGcm256Sha512, key_id, "pw123").unwrap();
let mut counter = MonotonicCounter::default();
let payload = "Something secret";
let mut encrypt_buffer = Vec::new();
let mut decrypt_buffer = Vec::new();
let media_frame = MediaFrameView::new(&mut counter, payload);
let encrypted_frame = media_frame.encrypt_into(&enc_key, &mut encrypt_buffer).unwrap();
let mut dec_key = DecryptionKey::derive_from(CipherSuite::AesGcm256Sha512, key_id, "pw123").unwrap();
let decrypted_media_frame = encrypted_frame
.decrypt_into(&mut dec_key, &mut decrypt_buffer)
.unwrap();
assert_eq!(decrypted_media_frame, media_frame);
Additionally the library provides:
Sender
which encrypts frames Receiver
which decrypts them.FrameBuffer
trait.The criterion
benchmarks located at ./benches currently test
They are tracked continously with a Bencher Perf Page:
Any help in form of descriptive and friendly issues or comprehensive pull requests are welcome!
The Changelog of this library is generated from its commit log, there any commit message must conform with https://www.conventionalcommits.org/en/v1.0.0/. For simplicity you could make your commits with convco.