From 25ef762973f98c9045bab331abf4a872aa27c694 Mon Sep 17 00:00:00 2001 From: Marcus Asteborg Date: Wed, 23 Oct 2024 12:08:18 -0700 Subject: [PATCH] Make sha1 crate optional and a feature --- .github/workflows/cargo.yml | 23 +++++++++++++++++++++++ Cargo.toml | 8 ++++++-- src/crypto/mod.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 3b01cf14..96b9378e 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -35,6 +35,29 @@ jobs: with: command: test + rust-crypto: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + rust: [stable, beta, 1.65.0] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + - uses: Swatinem/rust-cache@v1 + - uses: actions-rs/cargo@v1 + with: + command: build + - uses: actions-rs/cargo@v1 + with: + command: test --features sha1 + lint: runs-on: ubuntu-latest steps: diff --git a/Cargo.toml b/Cargo.toml index 74c93dfb..810ef87b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ rust-version = "1.65" [features] default = ["openssl"] openssl = ["dep:openssl", "dep:openssl-sys", "dep:libc"] +sha1 = ["dep:sha1"] _internal_dont_use_log_stats = [] _internal_test_exports = [] @@ -38,14 +39,17 @@ hmac = "0.12.1" crc = "3.0.0" serde = { version = "1.0.152", features = ["derive"] } +# The sha1 crate is disabled by default, and openssl is used. However, for potential +# performance improvements or if you prefer to use str0m without openssl, +# you can enable the sha1 feature flag. [target.'cfg(unix)'.dependencies] -sha1 = { version = "0.10.6", features = ["asm"] } +sha1 = { version = "0.10.6", features = ["asm"], optional = true } # Don't use `asm` on Windows until https://github.com/RustCrypto/asm-hashes/issues/45 is fixed. # The `asm` feature isn't compatible with `windows-msvc` toolchain and `openssl` breaks if we want to use `windows-gnu`. # Thus, don't use `asm` feature on Windows. [target.'cfg(windows)'.dependencies] -sha1 = { version = "0.10.6" } +sha1 = { version = "0.10.6" , optional = true} [dev-dependencies] rouille = { version = "3.5.0", features = ["ssl"] } diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 52cd3e7a..f6ce8e04 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -19,7 +19,13 @@ mod srtp; pub use srtp::{aead_aes_128_gcm, aes_128_cm_sha1_80, new_aead_aes_128_gcm}; pub use srtp::{new_aes_128_cm_sha1_80, srtp_aes_128_ecb_round, SrtpProfile}; +/// Ensure that either `openssl` or `sha1` feature is enabled. +#[cfg(not(any(feature = "openssl", feature = "sha1")))] +compile_error!("Either feature \"openssl\" or \"sha1\" must be enabled for HMAC functionality."); + /// SHA1 HMAC as used for STUN and older SRTP. +/// If sha1 feature is enabled, it uses `rust-crypto` crate. +#[cfg(feature = "sha1")] pub fn sha1_hmac(key: &[u8], payloads: &[&[u8]]) -> [u8; 20] { use hmac::Hmac; use hmac::Mac; @@ -34,6 +40,26 @@ pub fn sha1_hmac(key: &[u8], payloads: &[&[u8]]) -> [u8; 20] { hmac.finalize().into_bytes().into() } +/// SHA1 HMAC as used for STUN and older SRTP. +/// If openssl is enabled and sha1 is not, it uses `openssl` crate. +#[cfg(all(feature = "openssl", not(feature = "sha1")))] +pub fn sha1_hmac(key: &[u8], payloads: &[&[u8]]) -> [u8; 20] { + use openssl::hash::MessageDigest; + use openssl::pkey::PKey; + use openssl::sign::Signer; + + let key = PKey::hmac(key).expect("valid hmac key"); + let mut signer = Signer::new(MessageDigest::sha1(), &key).expect("valid signer"); + + for payload in payloads { + signer.update(payload).expect("signer update"); + } + + let mut hash = [0u8; 20]; + signer.sign(&mut hash).expect("sign to array"); + hash +} + /// Errors that can arise in DTLS. #[derive(Debug, Error)] pub enum CryptoError {