Skip to content

Commit 4070845

Browse files
alexlaparainliu
authored andcommitted
optimizations and openssl
1 parent 8a061f9 commit 4070845

File tree

8 files changed

+67
-83
lines changed

8 files changed

+67
-83
lines changed

srtp/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ tokio = { version = "1.19", features = ["full"] }
3636
log = "0.4.16"
3737
aead = { version = "0.4.3", features = ["std"] }
3838
aes-gcm = { version = "0.10.1", features = ["std"] }
39+
openssl = { version = "0.10.45", features = ["vendored"] }
3940

4041
[dev-dependencies]
4142
criterion = { version = "0.4.0", features = ["async_futures"] }

srtp/benches/srtp_bench.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn benchmark_buffer(c: &mut Criterion) {
1616
.unwrap();
1717

1818
let mut pld = BytesMut::new();
19+
1920
for i in 0..1000 {
2021
pld.extend_from_slice(&[i as u8]);
2122
}

srtp/src/cipher/cipher_aes_cm_hmac_sha1.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use std::io::BufWriter;
2-
31
use aes::cipher::generic_array::GenericArray;
4-
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
2+
use byteorder::{BigEndian, ByteOrder};
53
use bytes::{BufMut, Bytes, BytesMut};
64
use ctr::cipher::{NewCipher, StreamCipher, StreamCipherSeek};
75
use hmac::{Hmac, Mac};
@@ -14,6 +12,11 @@ use crate::error::{Error, Result};
1412
use crate::key_derivation::*;
1513
use crate::protection_profile::*;
1614

15+
use openssl::cipher;
16+
use openssl::cipher_ctx::CipherCtx;
17+
use openssl::error::ErrorStack;
18+
use openssl::symm::{Cipher as OpenSslCipher, Crypter, Mode};
19+
1720
type HmacSha1 = Hmac<Sha1>;
1821
type Aes128Ctr = ctr::Ctr128BE<aes::Aes128>;
1922

@@ -28,6 +31,8 @@ pub(crate) struct CipherAesCmHmacSha1 {
2831
srtcp_session_salt: Vec<u8>,
2932
srtcp_session_auth: HmacSha1,
3033
//srtcp_session_auth_tag: Vec<u8>,
34+
35+
ctx: CipherCtx
3136
}
3237

3338
impl CipherAesCmHmacSha1 {
@@ -84,6 +89,11 @@ impl CipherAesCmHmacSha1 {
8489
let srtcp_session_auth = HmacSha1::new_from_slice(&srtcp_session_auth_tag)
8590
.map_err(|e| Error::Other(e.to_string()))?;
8691

92+
let t = openssl::cipher::Cipher::aes_128_ctr();
93+
let mut ctx = CipherCtx::new().expect("a reusable cipher context");
94+
ctx.encrypt_init(Some(t), Some(&srtp_session_key[..]), None)
95+
.expect("enc init");
96+
8797
Ok(CipherAesCmHmacSha1 {
8898
srtp_session_key,
8999
srtp_session_salt,
@@ -93,6 +103,7 @@ impl CipherAesCmHmacSha1 {
93103
srtcp_session_salt,
94104
srtcp_session_auth,
95105
//srtcp_session_auth_tag,
106+
ctx,
96107
})
97108
}
98109

@@ -110,25 +121,19 @@ impl CipherAesCmHmacSha1 {
110121
/// - Authenticated portion of the packet is everything BEFORE MKI
111122
/// - k_a is the session message authentication key
112123
/// - n_tag is the bit-length of the output authentication tag
113-
fn generate_srtp_auth_tag(&mut self, buf: &[u8], roc: u32) -> Result<Vec<u8>> {
124+
fn generate_srtp_auth_tag(&mut self, buf: &[u8], roc: u32) -> Vec<u8> {
114125
self.srtp_session_auth.reset();
115126

116127
self.srtp_session_auth.update(buf);
117128

118129
// For SRTP only, we need to hash the rollover counter as well.
119-
let mut roc_buf: Vec<u8> = vec![];
120-
{
121-
let mut writer = BufWriter::<&mut Vec<u8>>::new(roc_buf.as_mut());
122-
writer.write_u32::<BigEndian>(roc)?;
123-
}
124-
125-
self.srtp_session_auth.update(&roc_buf);
130+
self.srtp_session_auth.update(&roc.to_be_bytes());
126131

127132
let result = self.srtp_session_auth.clone().finalize();
128133
let code_bytes = result.into_bytes();
129134

130135
// Truncate the hash to the first AUTH_TAG_SIZE bytes.
131-
Ok(code_bytes[0..self.auth_tag_len()].to_vec())
136+
code_bytes[0..self.auth_tag_len()].to_vec()
132137
}
133138

134139
/// https://tools.ietf.org/html/rfc3711#section-4.2
@@ -172,34 +177,30 @@ impl Cipher for CipherAesCmHmacSha1 {
172177
header: &rtp::header::Header,
173178
roc: u32,
174179
) -> Result<Bytes> {
180+
let header_len = header.marshal_size();
175181
let mut writer =
176-
BytesMut::with_capacity(header.marshal_size() + payload.len() + self.auth_tag_len());
182+
BytesMut::with_capacity(header_len + payload.len() + self.auth_tag_len());
177183

178184
// Copy the header unencrypted.
179-
let data = header.marshal()?;
180-
writer.extend(data);
181-
182-
// Write the plaintext header to the destination buffer.
183-
writer.extend_from_slice(payload);
184-
185+
writer.extend(header.marshal());
185186
// Encrypt the payload
186-
let counter = generate_counter(
187+
let nonce = generate_counter(
187188
header.sequence_number,
188189
roc,
189190
header.ssrc,
190191
&self.srtp_session_salt,
191-
)?;
192-
let key = GenericArray::from_slice(&self.srtp_session_key);
193-
let nonce = GenericArray::from_slice(&counter);
194-
let mut stream = Aes128Ctr::new(key, nonce);
195-
let payload_offset = header.marshal_size();
196-
stream.apply_keystream(&mut writer[payload_offset..]);
192+
);
193+
194+
writer.put_bytes(0, payload.len());
195+
self.ctx.encrypt_init(None, None, Some(&nonce)).unwrap();
196+
let count = self.ctx.cipher_update(&payload, Some(&mut writer[header_len..])).unwrap();
197+
self.ctx.cipher_final(&mut writer[count..]).unwrap();
197198

198199
// Generate the auth tag.
199-
let auth_tag = self.generate_srtp_auth_tag(&writer, roc)?;
200+
let auth_tag = self.generate_srtp_auth_tag(&writer, roc);
200201
writer.extend(auth_tag);
201202

202-
Ok(writer.freeze())
203+
Ok(Bytes::from(writer))
203204
}
204205

205206
fn decrypt_rtp(
@@ -219,7 +220,7 @@ impl Cipher for CipherAesCmHmacSha1 {
219220
let cipher_text = &encrypted[..encrypted.len() - self.auth_tag_len()];
220221

221222
// Generate the auth tag we expect to see from the ciphertext.
222-
let expected_tag = self.generate_srtp_auth_tag(cipher_text, roc)?;
223+
let expected_tag = self.generate_srtp_auth_tag(cipher_text, roc);
223224

224225
// See if the auth tag actually matches.
225226
// We use a constant time comparison to prevent timing attacks.
@@ -236,7 +237,7 @@ impl Cipher for CipherAesCmHmacSha1 {
236237
roc,
237238
header.ssrc,
238239
&self.srtp_session_salt,
239-
)?;
240+
);
240241

241242
let key = GenericArray::from_slice(&self.srtp_session_key);
242243
let nonce = GenericArray::from_slice(&counter);
@@ -261,7 +262,7 @@ impl Cipher for CipherAesCmHmacSha1 {
261262
(srtcp_index >> 16) as u32,
262263
ssrc,
263264
&self.srtcp_session_salt,
264-
)?;
265+
);
265266

266267
let key = GenericArray::from_slice(&self.srtcp_session_key);
267268
let nonce = GenericArray::from_slice(&counter);
@@ -325,7 +326,7 @@ impl Cipher for CipherAesCmHmacSha1 {
325326
(srtcp_index >> 16) as u32,
326327
ssrc,
327328
&self.srtcp_session_salt,
328-
)?;
329+
);
329330

330331
let key = GenericArray::from_slice(&self.srtcp_session_key);
331332
let nonce = GenericArray::from_slice(&counter);

srtp/src/context/context_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ fn test_valid_packet_counter() -> Result<()> {
109109
ssrc: 4160032510,
110110
..Default::default()
111111
};
112-
let expected_counter = vec![
112+
let expected_counter = [
113113
0xcf, 0x90, 0x1e, 0xa5, 0xda, 0xd3, 0x2c, 0x15, 0x00, 0xa2, 0x24, 0xae, 0xae, 0xaf, 0x00,
114114
0x00,
115115
];
116-
let counter = generate_counter(32846, s.rollover_counter, s.ssrc, &srtp_session_salt)?;
116+
let counter = generate_counter(32846, s.rollover_counter, s.ssrc, &srtp_session_salt);
117117
assert_eq!(
118118
counter, expected_counter,
119119
"Session Key {counter:?} does not match expected {expected_counter:?}",

srtp/src/context/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,14 @@ impl Context {
160160
})
161161
}
162162

163-
fn get_srtp_ssrc_state(&mut self, ssrc: u32) -> Option<&mut SrtpSsrcState> {
163+
fn get_srtp_ssrc_state(&mut self, ssrc: u32) -> &mut SrtpSsrcState {
164164
let s = SrtpSsrcState {
165165
ssrc,
166166
replay_detector: Some((self.new_srtp_replay_detector)()),
167167
..Default::default()
168168
};
169169

170-
self.srtp_ssrc_states.entry(ssrc).or_insert(s);
171-
self.srtp_ssrc_states.get_mut(&ssrc)
170+
self.srtp_ssrc_states.entry(ssrc).or_insert(s)
172171
}
173172

174173
fn get_srtcp_ssrc_state(&mut self, ssrc: u32) -> Option<&mut SrtcpSsrcState> {
@@ -188,9 +187,7 @@ impl Context {
188187

189188
/// set_roc sets SRTP rollover counter value of specified SSRC.
190189
fn set_roc(&mut self, ssrc: u32, roc: u32) {
191-
if let Some(s) = self.get_srtp_ssrc_state(ssrc) {
192-
s.rollover_counter = roc;
193-
}
190+
self.get_srtp_ssrc_state(ssrc).rollover_counter = roc;
194191
}
195192

196193
/// index returns SRTCP index value of specified SSRC.

srtp/src/context/srtp.rs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,26 @@ impl Context {
1212
) -> Result<Bytes> {
1313
let roc;
1414
{
15-
if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
16-
if let Some(replay_detector) = &mut state.replay_detector {
17-
if !replay_detector.check(header.sequence_number as u64) {
18-
return Err(Error::SrtpSsrcDuplicated(
19-
header.ssrc,
20-
header.sequence_number,
21-
));
22-
}
15+
let state = self.get_srtp_ssrc_state(header.ssrc);
16+
if let Some(replay_detector) = &mut state.replay_detector {
17+
if !replay_detector.check(header.sequence_number as u64) {
18+
return Err(Error::SrtpSsrcDuplicated(
19+
header.ssrc,
20+
header.sequence_number,
21+
));
2322
}
24-
25-
roc = state.next_rollover_count(header.sequence_number);
26-
} else {
27-
return Err(Error::SsrcMissingFromSrtp(header.ssrc));
2823
}
24+
25+
roc = state.next_rollover_count(header.sequence_number);
2926
}
3027

3128
let dst = self.cipher.decrypt_rtp(encrypted, header, roc)?;
3229
{
33-
if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
34-
if let Some(replay_detector) = &mut state.replay_detector {
35-
replay_detector.accept();
36-
}
37-
state.update_rollover_count(header.sequence_number);
30+
let state = self.get_srtp_ssrc_state(header.ssrc);
31+
if let Some(replay_detector) = &mut state.replay_detector {
32+
replay_detector.accept();
3833
}
34+
state.update_rollover_count(header.sequence_number);
3935
}
4036

4137
Ok(dst)
@@ -53,24 +49,13 @@ impl Context {
5349
plaintext: &[u8],
5450
header: &rtp::header::Header,
5551
) -> Result<Bytes> {
56-
let roc;
57-
{
58-
if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
59-
roc = state.next_rollover_count(header.sequence_number);
60-
} else {
61-
return Err(Error::SsrcMissingFromSrtp(header.ssrc));
62-
}
63-
}
52+
let roc = self.get_srtp_ssrc_state(header.ssrc).next_rollover_count(header.sequence_number);
6453

6554
let dst = self
6655
.cipher
6756
.encrypt_rtp(&plaintext[header.marshal_size()..], header, roc)?;
6857

69-
{
70-
if let Some(state) = self.get_srtp_ssrc_state(header.ssrc) {
71-
state.update_rollover_count(header.sequence_number);
72-
}
73-
}
58+
self.get_srtp_ssrc_state(header.ssrc).update_rollover_count(header.sequence_number);
7459

7560
Ok(dst)
7661
}

srtp/src/key_derivation.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use std::io::BufWriter;
2-
31
use aes::cipher::generic_array::GenericArray;
42
use aes::cipher::NewBlockCipher;
53
use aes::{Aes128, BlockEncrypt};
6-
use byteorder::{BigEndian, WriteBytesExt};
74

85
use crate::error::{Error, Result};
96

@@ -74,22 +71,24 @@ pub(crate) fn generate_counter(
7471
rollover_counter: u32,
7572
ssrc: u32,
7673
session_salt: &[u8],
77-
) -> Result<Vec<u8>> {
74+
) -> [u8; 16] {
7875
assert!(session_salt.len() <= 16);
7976

80-
let mut counter: Vec<u8> = vec![0; 16];
81-
{
82-
let mut writer = BufWriter::<&mut [u8]>::new(counter[4..].as_mut());
83-
writer.write_u32::<BigEndian>(ssrc)?;
84-
writer.write_u32::<BigEndian>(rollover_counter)?;
85-
writer.write_u32::<BigEndian>((sequence_number as u32) << 16)?;
86-
}
77+
let mut counter = [0; 16];
78+
79+
let ssrc_be = ssrc.to_be_bytes();
80+
let rollover_be = rollover_counter.to_be_bytes();
81+
let seq_be = ((sequence_number as u32) << 16).to_be_bytes();
82+
83+
counter[4..8].copy_from_slice(&ssrc_be);
84+
counter[8..12].copy_from_slice(&rollover_be);
85+
counter[12..16].copy_from_slice(&seq_be);
8786

8887
for i in 0..session_salt.len() {
8988
counter[i] ^= session_salt[i];
9089
}
9190

92-
Ok(counter)
91+
counter
9392
}
9493

9594
#[cfg(test)]

srtp/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn main() {
1818
pld.extend_from_slice(&[i as u8]);
1919
}
2020

21-
for i in 1..=100000u32 {
21+
for i in 1..=10000000u32 {
2222
let pkt = rtp::packet::Packet {
2323
header: rtp::header::Header {
2424
sequence_number: i as u16,

0 commit comments

Comments
 (0)