2 releases
Uses new Rust 2024
| 0.3.1 | Feb 7, 2026 |
|---|---|
| 0.3.0 | Feb 7, 2026 |
#1282 in Cryptography
635KB
14K
SLoC
mlspp-sys
AI DISCLAIMER: This project was initially generated by Claude "Opus 4.6" language model. The work were supervised heavily but no warranties express or implied etc etc.
Raw FFI bindings to Cisco mlspp, a C++ implementation of the Messaging Layer Security (MLS) protocol (RFC 9420).
MLS is an end-to-end encryption protocol designed for group messaging. It provides forward secrecy, post-compromise security, and efficient group key management for groups of any size.
Features
| Feature | Default | Description |
|---|---|---|
vendored |
yes | Build mlspp from the vendored source tree via CMake |
system |
no | Link against a system-installed mlspp |
libdave-compat |
no | Enable compatibility with Discord's libdave |
Build requirements
When the vendored feature is enabled (default), building this crate requires:
- A C++17 compiler (GCC 8+, Clang 7+, MSVC 2019+)
- CMake 3.16+
- OpenSSL development headers (or set
OPENSSL_ROOT_DIR)
Installation
Add to your Cargo.toml:
[dependencies]
mlspp-sys = "0.3"
Usage
All functions are unsafe and follow C conventions. Here is a minimal example
that creates a cipher suite and generates a signing key:
use mlspp_sys::*;
use std::ptr;
fn main() {
unsafe {
// Create a cipher suite (MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 = 1)
let cs = mlspp_cipher_suite_create(1);
if cs.is_null() {
let err = mlspp_last_error();
panic!("failed to create cipher suite: {:?}", std::ffi::CStr::from_ptr(err));
}
// Generate a signature key pair
let sig_priv = mlspp_signature_private_key_generate(cs);
assert!(!sig_priv.is_null(), "key generation failed");
// Clean up
mlspp_signature_private_key_free(sig_priv);
mlspp_cipher_suite_free(cs);
}
}
Memory management
The API uses two patterns:
- Opaque handles (
mlspp_state_t,mlspp_session_t, etc.) are heap-allocated pointers. Each has a corresponding_freefunction that must be called exactly once. - Byte buffers (
mlspp_bytes_t) are{data, len}pairs. Free them withmlspp_bytes_free. Do not callfree()on the innerdatapointer directly.
Error handling
Functions that can fail return NULL (for handles) or {NULL, 0} (for byte
buffers). Call mlspp_last_error() to retrieve a thread-local error string.
On success, mlspp_last_error() returns NULL.
API overview
The bindings expose two API levels:
- Low-level (
State) — direct MLS group state management with full control over proposals, commits, and application data protection. - High-level (
Client/Session) — a simplified API that manages key generation and state transitions internally, suited for straightforward group messaging.
Safety
All functions are unsafe. Callers must ensure:
- Pointer arguments are non-null and point to valid, live objects
- Handles are not used after being freed
- Handles are not shared across threads without external synchronization
License
MIT
Dependencies
~0.4–2.6MB
~53K SLoC