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
6 changes: 5 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ rustflags = ["-C", "link-args=-ObjC"]
rustflags = ["-C", "link-args=-ObjC"]

[target.aarch64-apple-ios-sim]
rustflags = ["-C", "link-args=-ObjC"]
rustflags = ["-C", "link-args=-ObjC"]

[env]
# DO not merge! WIP change to for custom webrtc-sys build
LK_CUSTOM_WEBRTC = { value = "webrtc-sys/libwebrtc/linux-x64-release", relative = true }
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 @@ -108,10 +108,22 @@ impl From<DisconnectReason> for proto::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
11 changes: 10 additions & 1 deletion livekit/src/room/e2ee/key_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use libwebrtc::native::frame_cryptor as fc;
use libwebrtc::native::frame_cryptor::{self as fc, KeyDerivationAlgorithm};
use std::sync::{
atomic::{AtomicI32, Ordering},
Arc,
Expand All @@ -23,12 +23,15 @@ use crate::id::ParticipantIdentity;
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;

#[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 +40,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: KeyDerivationAlgorithm::PBKDF2,
}
}
}
Expand All @@ -56,6 +61,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 +74,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/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',
"url": 'https://github.com/webrtc-sdk/webrtc.git@duan/hkdf-sha256-key-derivation',
"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