diff --git a/net/Cargo.toml b/net/Cargo.toml index c5f03d2b0..7b22cc7c1 100644 --- a/net/Cargo.toml +++ b/net/Cargo.toml @@ -8,6 +8,6 @@ tracing = "0.1" thiserror = "1" rand = "0.8" # STUN -hmac = "0.12" -sha-1 = "0.10" crc = "3" +openssl = { version = "0.10", features = ["vendored"] } +openssl-sys = "^0.9" diff --git a/net/src/stun.rs b/net/src/stun.rs index 103e33a97..4b69fa75d 100644 --- a/net/src/stun.rs +++ b/net/src/stun.rs @@ -5,10 +5,7 @@ use std::net::SocketAddr; use std::time::Duration; use crc::{Crc, CRC_32_ISO_HDLC}; -use hmac::Hmac; -use hmac::Mac; use rand::random; -use sha1::Sha1; use thiserror::Error; // Consult libwebrtc for default values here. @@ -227,8 +224,9 @@ impl<'a> StunMessage<'a> { pub fn check_integrity(&self, password: &str) -> bool { if let Some(integ) = self.attrs.message_integrity() { - let comp = hmac_sha1(password.as_bytes(), self.integrity); - comp == integ + let mut out = [0; 32]; + hmac_sha1(password.as_bytes(), self.integrity, &mut out); + &out[..20] == integ } else { false } @@ -272,8 +270,9 @@ impl<'a> StunMessage<'a> { let buf = buf.into_inner(); - let hmac = hmac_sha1(password.as_bytes(), &buf[0..i_off]); - buf[i_off + 4..(i_off + 4 + 20)].copy_from_slice(&hmac); + let mut out = [0; 32]; + hmac_sha1(password.as_bytes(), &buf[0..i_off], &mut out); + buf[i_off + 4..(i_off + 4 + 20)].copy_from_slice(&out[..20]); // fill in correct length buf[2..4].copy_from_slice(&(attr_len as u16).to_be_bytes()); @@ -740,13 +739,17 @@ fn decode_xor(buf: &[u8], trans_id: TransId) -> Result { Ok(SocketAddr::new(ip, port)) } -type HmacSha1 = Hmac; +pub fn hmac_sha1(secret: &[u8], payload: &[u8], out: &mut [u8]) { + use openssl::hash::MessageDigest; + use openssl::pkey::PKey; + use openssl::sign::Signer; -pub fn hmac_sha1(secret: &[u8], payload: &[u8]) -> [u8; 20] { - let mut hmac = HmacSha1::new_from_slice(secret).expect("Make HMAC-SHA1"); - hmac.update(payload); - let comp = hmac.finalize().into_bytes(); - comp.into() + let key = PKey::hmac(secret).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha1(), &key).unwrap(); + signer.update(payload).unwrap(); + + signer.sign(out).unwrap(); } impl<'a> fmt::Debug for StunMessage<'a> { diff --git a/rtp/Cargo.toml b/rtp/Cargo.toml index 0b290c732..24817aa6e 100644 --- a/rtp/Cargo.toml +++ b/rtp/Cargo.toml @@ -14,9 +14,6 @@ once_cell = "1" openssl = { version = "0.10", features = ["vendored"] } openssl-sys = "^0.9" # -hmac = "0.12" -sha-1 = "0.10" -# dtls = { path = "../dtls" } net = { path = "../net" } diff --git a/rtp/src/srtp.rs b/rtp/src/srtp.rs index 3182e0a67..3d55e3a2d 100644 --- a/rtp/src/srtp.rs +++ b/rtp/src/srtp.rs @@ -1,10 +1,11 @@ use std::fmt; -use hmac::{Hmac, Mac}; +use openssl::hash::MessageDigest; +use openssl::pkey::{PKey, Private}; +use openssl::sign::Signer; use openssl::symm::{Cipher, Crypter, Mode}; use dtls::KeyingMaterial; -use sha1::Sha1; use crate::header::RtpHeader; @@ -93,7 +94,9 @@ impl SrtpContext { output[..hlen].copy_from_slice(&buf[..hlen]); let hmac_start = buf.len(); - self.rtp.hmac.rtp_hmac(&mut output, srtp_index, hmac_start); + self.rtp + .hmac_key + .rtp_hmac(&mut output, srtp_index, hmac_start); output } @@ -112,7 +115,7 @@ impl SrtpContext { if !self .rtp - .hmac + .hmac_key .rtp_verify(&buf[..hmac_start], srtp_index, &buf[hmac_start..]) { trace!("unprotect_rtp hmac verify fail"); @@ -161,7 +164,7 @@ impl SrtpContext { to[0..4].copy_from_slice(&e_and_si.to_be_bytes()); let hmac_index = output.len() - SRTP_HMAC_LEN; - self.rtcp.hmac.rtcp_hmac(&mut output, hmac_index); + self.rtcp.hmac_key.rtcp_hmac(&mut output, hmac_index); output } @@ -184,7 +187,7 @@ impl SrtpContext { if !self .rtcp - .hmac + .hmac_key .rtcp_verify(&buf[..hmac_start], &buf[hmac_start..]) { trace!("unprotect_rtcp hmac verify fail"); @@ -301,12 +304,10 @@ impl SrtpKey { } } -type HmacSha1 = Hmac; - /// Encryption/decryption derived from the SrtpKey. struct Derived { aes: AesKey, - hmac: HmacSha1, + hmac_key: PKey, salt: RtpSalt, } @@ -324,11 +325,11 @@ impl Derived { // RTP SHA1 HMAC - let rtp_hmac = { + let rtp_hmac_key = { const LABEL_RTP_HMAC: u8 = 1; let mut hmac = [0; 20]; srtp_key.derive(LABEL_RTP_HMAC, &mut hmac[..]); - HmacSha1::new_from_slice(&hmac[..]).expect("RTP hmac") + PKey::hmac(&hmac[..]).expect("RTP hmac key") }; // RTP IV SALT @@ -345,11 +346,11 @@ impl Derived { // RTCP SHA1 HMAC - let rtcp_hmac = { + let rtcp_hmac_key = { const LABEL_RTCP_HMAC: u8 = 4; let mut hmac = [0; 20]; srtp_key.derive(LABEL_RTCP_HMAC, &mut hmac[..]); - HmacSha1::new_from_slice(&hmac[..]).expect("RTCP hmac") + PKey::hmac(&hmac[..]).expect("RTCP hmac key") }; // RTCP IV SALT @@ -360,13 +361,13 @@ impl Derived { let rtp = Derived { aes: rtp_aes, - hmac: rtp_hmac, + hmac_key: rtp_hmac_key, salt: rtp_salt, }; let rtcp = Derived { aes: rtcp_aes, - hmac: rtcp_hmac, + hmac_key: rtcp_hmac_key, salt: rtcp_salt, }; @@ -404,51 +405,47 @@ trait RtpHmac { fn rtcp_verify(&self, buf: &[u8], cmp: &[u8]) -> bool; } -impl RtpHmac for HmacSha1 { - fn rtp_hmac(&self, buf: &mut [u8], srtp_index: u64, hmac_start: usize) { - let mut hmac = self.clone(); +fn sha1(pkey: &PKey, updates: &[&[u8]], out: &mut [u8]) { + let mut hmac = Signer::new(MessageDigest::sha1(), pkey).unwrap(); - let roc = (srtp_index >> 16) as u32; + for u in updates { + hmac.update(u).unwrap(); + } - hmac.update(&buf[..hmac_start]); - hmac.update(&roc.to_be_bytes()); + hmac.sign(out).unwrap(); +} + +impl RtpHmac for PKey { + fn rtp_hmac(&self, buf: &mut [u8], srtp_index: u64, hmac_start: usize) { + let roc = (srtp_index >> 16) as u32; - let tag = hmac.finalize().into_bytes(); + let mut out = [0_u8; 32]; + sha1(&self, &[&buf[..hmac_start], &roc.to_be_bytes()], &mut out); - buf[hmac_start..(hmac_start + SRTP_HMAC_LEN)].copy_from_slice(&tag[0..SRTP_HMAC_LEN]); + buf[hmac_start..(hmac_start + SRTP_HMAC_LEN)].copy_from_slice(&out[0..SRTP_HMAC_LEN]); } fn rtp_verify(&self, buf: &[u8], srtp_index: u64, cmp: &[u8]) -> bool { - let mut hmac = self.clone(); - let roc = (srtp_index >> 16) as u32; - hmac.update(buf); - hmac.update(&roc.to_be_bytes()); + let mut out = [0_u8; 32]; + sha1(&self, &[buf, &roc.to_be_bytes()], &mut out); - let tag = hmac.finalize().into_bytes(); - - &tag[0..SRTP_HMAC_LEN] == cmp + &out[0..SRTP_HMAC_LEN] == cmp } fn rtcp_hmac(&self, buf: &mut [u8], hmac_index: usize) { - let mut hmac = self.clone(); - - hmac.update(&buf[0..hmac_index]); + let mut out = [0_u8; 32]; + sha1(&self, &[&buf[0..hmac_index]], &mut out); - let tag = hmac.finalize().into_bytes(); - - buf[hmac_index..(hmac_index + SRTP_HMAC_LEN)].copy_from_slice(&tag[0..SRTP_HMAC_LEN]); + buf[hmac_index..(hmac_index + SRTP_HMAC_LEN)].copy_from_slice(&out[0..SRTP_HMAC_LEN]); } fn rtcp_verify(&self, buf: &[u8], cmp: &[u8]) -> bool { - let mut hmac = self.clone(); - - hmac.update(buf); - - let tag = hmac.finalize().into_bytes(); + let mut out = [0_u8; 32]; + sha1(&self, &[buf], &mut out); - &tag[0..SRTP_HMAC_LEN] == cmp + &out[0..SRTP_HMAC_LEN] == cmp } }