Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
soxr-sys: patch
webrtc-sys: patch
livekit-ffi: minor
livekit-protocol: patch
livekit: minor
livekit-wakeword: patch
livekit-api: patch
imgproc: patch
libwebrtc: minor
webrtc-sys-build: patch
yuv-sys: patch
---

# E2EE: allow setting key_ring_size and key_derivation_algorithm, update webrtc to m144

#921 by @onestacked

This PR uses [this webrtc-sdk PR](https://github.com/webrtc-sdk/webrtc/pull/224) to configure the KDF.

I've tested this with https://codeberg.org/esoteric_programmer/matrix-jukebox and it is compatible with Element Call.

Since this PR needs to use a new webrtc build it also updates webtc to m144. See [this PR](https://github.com/webrtc-sdk/webrtc/pull/217)

Fixed: https://github.com/livekit/rust-sdks/issues/796
19 changes: 19 additions & 0 deletions libwebrtc/src/native/frame_cryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,29 @@ use crate::{

pub type OnStateChange = Box<dyn FnMut(String, EncryptionState) + Send + Sync>;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum KeyDerivationAlgorithm {
PBKDF2,
HKDF,
}
impl Into<sys_fc::ffi::KeyDerivationAlgorithm> for KeyDerivationAlgorithm {
fn into(self) -> sys_fc::ffi::KeyDerivationAlgorithm {
match self {
KeyDerivationAlgorithm::PBKDF2 => sys_fc::ffi::KeyDerivationAlgorithm::PBKDF2,
KeyDerivationAlgorithm::HKDF => sys_fc::ffi::KeyDerivationAlgorithm::HKDF,
}
}
}

#[derive(Debug, Clone)]
pub struct KeyProviderOptions {
pub shared_key: bool,
pub ratchet_window_size: i32,
pub ratchet_salt: Vec<u8>,
pub failure_tolerance: i32,
pub key_ring_size: i32,
pub key_derivation_algorithm: KeyDerivationAlgorithm,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -272,6 +289,8 @@ impl From<KeyProviderOptions> for sys_fc::ffi::KeyProviderOptions {
ratchet_window_size: value.ratchet_window_size,
ratchet_salt: value.ratchet_salt,
failure_tolerance: value.failure_tolerance,
key_ring_size: value.key_ring_size,
key_derivation_algorithm: value.key_derivation_algorithm.into(),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions livekit-ffi/protocol/e2ee.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ message KeyProviderOptions {
required int32 ratchet_window_size = 2;
required bytes ratchet_salt = 3;
required int32 failure_tolerance = 4; // -1 = no tolerance
required int32 key_ring_size = 5;
required KeyDerivationFunction key_derivation_function = 6;
}

enum KeyDerivationFunction {
PBKDF2 = 0;
HKDF = 1;
}

message E2eeOptions {
Expand Down
14 changes: 13 additions & 1 deletion livekit-ffi/src/conversion/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use livekit::{
options::{AudioEncoding, TrackPublishOptions, VideoEncoding},
prelude::*,
webrtc::{
native::frame_cryptor::EncryptionState,
native::frame_cryptor::{EncryptionState, KeyDerivationAlgorithm},
prelude::{ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration},
},
RoomInfo,
Expand Down Expand Up @@ -133,10 +133,22 @@ impl From<proto::DisconnectReason> for DisconnectReason {

impl From<proto::KeyProviderOptions> for KeyProviderOptions {
fn from(value: proto::KeyProviderOptions) -> Self {
let key_derivation_algorithm = value.key_derivation_function().into();
Self {
ratchet_window_size: value.ratchet_window_size,
ratchet_salt: value.ratchet_salt,
failure_tolerance: value.failure_tolerance,
key_ring_size: value.key_ring_size,
key_derivation_algorithm,
}
}
}

impl From<proto::KeyDerivationFunction> for KeyDerivationAlgorithm {
fn from(value: proto::KeyDerivationFunction) -> Self {
match value {
proto::KeyDerivationFunction::Pbkdf2 => KeyDerivationAlgorithm::PBKDF2,
proto::KeyDerivationFunction::Hkdf => KeyDerivationAlgorithm::HKDF,
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions livekit/src/room/e2ee/key_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ use std::sync::{

use crate::id::ParticipantIdentity;

pub use libwebrtc::native::frame_cryptor::KeyDerivationAlgorithm;

const DEFAULT_RATCHET_SALT: &str = "LKFrameEncryptionKey";
const DEFAULT_RATCHET_WINDOW_SIZE: i32 = 16;
const DEFAULT_FAILURE_TOLERANCE: i32 = -1; // no tolerance by default
const DEFAULT_KEY_RING_SIZE: i32 = 16;
const DEFAULT_KEY_DERIVATION_ALGORITHM: KeyDerivationAlgorithm = KeyDerivationAlgorithm::PBKDF2;

#[derive(Clone)]
pub struct KeyProviderOptions {
pub ratchet_window_size: i32,
pub ratchet_salt: Vec<u8>,
pub failure_tolerance: i32,
pub key_ring_size: i32,
pub key_derivation_algorithm: KeyDerivationAlgorithm,
}

impl Default for KeyProviderOptions {
Expand All @@ -37,6 +43,8 @@ impl Default for KeyProviderOptions {
ratchet_window_size: DEFAULT_RATCHET_WINDOW_SIZE,
ratchet_salt: DEFAULT_RATCHET_SALT.to_owned().into_bytes(),
failure_tolerance: DEFAULT_FAILURE_TOLERANCE,
key_ring_size: DEFAULT_KEY_RING_SIZE,
key_derivation_algorithm: DEFAULT_KEY_DERIVATION_ALGORITHM,
}
}
}
Expand All @@ -56,6 +64,8 @@ impl KeyProvider {
ratchet_window_size: options.ratchet_window_size,
ratchet_salt: options.ratchet_salt,
failure_tolerance: options.failure_tolerance,
key_ring_size: options.key_ring_size,
key_derivation_algorithm: options.key_derivation_algorithm,
}),
latest_key_index: Arc::new(AtomicI32::new(0)),
}
Expand All @@ -67,6 +77,8 @@ impl KeyProvider {
ratchet_window_size: options.ratchet_window_size,
ratchet_salt: options.ratchet_salt,
failure_tolerance: options.failure_tolerance,
key_ring_size: options.key_ring_size,
key_derivation_algorithm: options.key_derivation_algorithm,
});
handle.set_shared_key(0, shared_key);
Self { handle, latest_key_index: Arc::new(AtomicI32::new(0)) }
Expand Down
2 changes: 1 addition & 1 deletion webrtc-sys/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use regex::Regex;
use reqwest::StatusCode;

pub const SCRATH_PATH: &str = "livekit_webrtc";
pub const WEBRTC_TAG: &str = "webrtc-0001d84-2";
pub const WEBRTC_TAG: &str = "webrtc-24f6822";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, this is a version that will be released soon webrtc-24f6822-2. You can update to it now. And the m144 upgrade will begin next week.

pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"];

pub fn target_os() -> String {
Expand Down
2 changes: 1 addition & 1 deletion webrtc-sys/libwebrtc/.gclient
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
solutions = [
{
"name": 'src',
"url": 'https://github.com/webrtc-sdk/webrtc.git@m137_release',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert to m137_release here first. We will modify this section again after updating to m144.

"url": 'https://github.com/webrtc-sdk/webrtc.git@m144_release'',
"custom_deps": {},
"deps_file": "DEPS",
"managed": False,
Expand Down
43 changes: 32 additions & 11 deletions webrtc-sys/src/frame_cryptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ webrtc::FrameCryptorTransformer::Algorithm AlgorithmToFrameCryptorAlgorithm(
}
}

webrtc::KeyDerivationAlgorithm
KeyDerivationAlgorithmToFrameCryptorKeyDerivationAlgorithm(
KeyDerivationAlgorithm algorithm) {
switch (algorithm) {
case KeyDerivationAlgorithm::PBKDF2:
return webrtc::KeyDerivationAlgorithm::kPBKDF2;
case KeyDerivationAlgorithm::HKDF:
return webrtc::KeyDerivationAlgorithm::kHKDF;
default:
return webrtc::KeyDerivationAlgorithm::kPBKDF2;
}
}

KeyProvider::KeyProvider(KeyProviderOptions options) {
webrtc::KeyProviderOptions rtc_options;
rtc_options.shared_key = options.shared_key;
Expand All @@ -51,7 +64,10 @@ KeyProvider::KeyProvider(KeyProviderOptions options) {
rtc_options.ratchet_salt = ratchet_salt;
rtc_options.ratchet_window_size = options.ratchet_window_size;
rtc_options.failure_tolerance = options.failure_tolerance;

rtc_options.key_ring_size = options.key_ring_size;
rtc_options.key_derivation_algorithm =
KeyDerivationAlgorithmToFrameCryptorKeyDerivationAlgorithm(
options.key_derivation_algorithm);
impl_ =
new rtc::RefCountedObject<webrtc::DefaultKeyProviderImpl>(rtc_options);
}
Expand Down Expand Up @@ -154,10 +170,12 @@ int32_t FrameCryptor::key_index() const {
return e2ee_transformer_->key_index();
}

DataPacketCryptor::DataPacketCryptor(webrtc::FrameCryptorTransformer::Algorithm algorithm,
webrtc::scoped_refptr<webrtc::KeyProvider> key_provider)
DataPacketCryptor::DataPacketCryptor(
webrtc::FrameCryptorTransformer::Algorithm algorithm,
webrtc::scoped_refptr<webrtc::KeyProvider> key_provider)
: data_packet_cryptor_(
webrtc::make_ref_counted<webrtc::DataPacketCryptor>(algorithm, key_provider)) {}
webrtc::make_ref_counted<webrtc::DataPacketCryptor>(algorithm,
key_provider)) {}

EncryptedPacket DataPacketCryptor::encrypt_data_packet(
const ::rust::String participant_id,
Expand All @@ -167,12 +185,12 @@ EncryptedPacket DataPacketCryptor::encrypt_data_packet(
std::copy(data.begin(), data.end(), std::back_inserter(data_vec));

auto result = data_packet_cryptor_->Encrypt(
std::string(participant_id.data(), participant_id.size()),
key_index,
std::string(participant_id.data(), participant_id.size()), key_index,
data_vec);

if (!result.ok()) {
throw std::runtime_error(std::string("Failed to encrypt data packet: ") + result.error().message());
throw std::runtime_error(std::string("Failed to encrypt data packet: ") +
result.error().message());
}

auto& packet = result.value();
Expand Down Expand Up @@ -202,20 +220,23 @@ rust::Vec<::std::uint8_t> DataPacketCryptor::decrypt_data_packet(
std::copy(encrypted_packet.iv.begin(), encrypted_packet.iv.end(),
std::back_inserter(iv_vec));

auto native_encrypted_packet = webrtc::make_ref_counted<webrtc::EncryptedPacket>(
std::move(data_vec), std::move(iv_vec), encrypted_packet.key_index);
auto native_encrypted_packet =
webrtc::make_ref_counted<webrtc::EncryptedPacket>(
std::move(data_vec), std::move(iv_vec), encrypted_packet.key_index);

auto result = data_packet_cryptor_->Decrypt(
std::string(participant_id.data(), participant_id.size()),
native_encrypted_packet);

if (!result.ok()) {
throw std::runtime_error(std::string("Failed to decrypt data packet: ") + result.error().message());
throw std::runtime_error(std::string("Failed to decrypt data packet: ") +
result.error().message());
}

rust::Vec<uint8_t> decrypted_data;
auto& decrypted = result.value();
std::copy(decrypted.begin(), decrypted.end(), std::back_inserter(decrypted_data));
std::copy(decrypted.begin(), decrypted.end(),
std::back_inserter(decrypted_data));
return decrypted_data;
}

Expand Down
11 changes: 11 additions & 0 deletions webrtc-sys/src/frame_cryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ pub mod ffi {
pub ratchet_window_size: i32,
pub ratchet_salt: Vec<u8>,
pub failure_tolerance: i32,
pub key_ring_size: i32,
pub key_derivation_algorithm: KeyDerivationAlgorithm,
}

#[derive(Debug)]
#[repr(i32)]
pub enum KeyDerivationAlgorithm {
PBKDF2 = 0,
HKDF,
}

#[derive(Debug)]
Expand Down Expand Up @@ -249,6 +258,8 @@ mod tests {
ratchet_window_size: 16,
ratchet_salt: vec![],
failure_tolerance: -1,
key_ring_size: 16,
key_derivation_algorithm: ffi::KeyDerivationAlgorithm::HKDF,
};

let key_provider = ffi::new_key_provider(options);
Expand Down
Loading