Skip to content
Closed
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
4 changes: 2 additions & 2 deletions net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
29 changes: 16 additions & 13 deletions net/src/stun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -740,13 +739,17 @@ fn decode_xor(buf: &[u8], trans_id: TransId) -> Result<SocketAddr, StunError> {
Ok(SocketAddr::new(ip, port))
}

type HmacSha1 = Hmac<Sha1>;
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> {
Expand Down
3 changes: 0 additions & 3 deletions rtp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }

Expand Down
81 changes: 39 additions & 42 deletions rtp/src/srtp.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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
}
Expand All @@ -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");
Expand Down Expand Up @@ -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
}
Expand All @@ -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");
Expand Down Expand Up @@ -301,12 +304,10 @@ impl SrtpKey {
}
}

type HmacSha1 = Hmac<Sha1>;

/// Encryption/decryption derived from the SrtpKey.
struct Derived {
aes: AesKey,
hmac: HmacSha1,
hmac_key: PKey<Private>,
salt: RtpSalt,
}

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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,
};

Expand Down Expand Up @@ -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<Private>, 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<Private> {
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
}
}

Expand Down