Skip to content

Commit

Permalink
use openssl for hkdf
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq committed Sep 16, 2024
1 parent 511fe77 commit 7a51229
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 98 deletions.
41 changes: 10 additions & 31 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ md-5 = "0.10.0"
sha2 = "0.10.0"
sha-1 = "0.10.0"
blake3 = { version = "1.5", default-features = false }
hkdf = "0.12"
hex = "0.4.2"
hex-literal = "0.4"
#
Expand Down Expand Up @@ -154,8 +153,8 @@ rustls-pemfile = "2"
tokio-rustls = { version = "0.26", default-features = false, features = ["tls12", "ring"] }
quinn = { version = "0.11", default-features = false, features = ["runtime-tokio"] }
#
openssl = { package = "variant-ssl", version = "0.15.1" }
openssl-sys = { package = "variant-ssl-sys", version = "0.15.1" }
openssl = { package = "variant-ssl", version = "0.15.2" }
openssl-sys = { package = "variant-ssl-sys", version = "0.15.2" }
openssl-probe = "0.1"
#
flume = { version = "0.11", default-features = false }
Expand Down
4 changes: 1 addition & 3 deletions lib/g3-dpi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ fnv.workspace = true
bytes.workspace = true
memchr.workspace = true
fixedbitset.workspace = true
hkdf = { workspace = true, optional = true }
sha2 = { workspace = true, optional = true }
openssl = { workspace = true, optional = true }
g3-types = { workspace = true, features = ["http"] }

Expand All @@ -22,4 +20,4 @@ hex-literal.workspace = true

[features]
default = []
quic = ["dep:hkdf", "dep:sha2", "dep:openssl"]
quic = ["dep:openssl"]
80 changes: 46 additions & 34 deletions lib/g3-dpi/src/parser/quic/packet/hkdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,53 @@
* limitations under the License.
*/

use hkdf::Hkdf;
use sha2::Sha256;
use openssl::error::ErrorStack;
use openssl::md::Md;
use openssl::pkey::Id;
use openssl::pkey_ctx::{HkdfMode, PkeyCtx};

pub struct QuicInitialHkdf {
inner: Hkdf<Sha256>,
hkdf_label_buf: Vec<u8>,
fn build_info_from_label(label: &[u8], output_len: u16) -> Vec<u8> {
let label_len = 6 + label.len() as u8;
let mut info = Vec::with_capacity(2 + 1 + label_len as usize + 1);
let l_bytes = output_len.to_be_bytes();
info.extend_from_slice(&l_bytes);
info.push(label_len);
info.extend_from_slice(b"tls13 ");
info.extend_from_slice(&label[..label_len as usize - 6]);
info.push(0); // no context
info
}

impl QuicInitialHkdf {
pub fn new(initial_salt: &[u8], cid: &[u8]) -> Self {
let inner = Hkdf::new(Some(initial_salt), cid);
QuicInitialHkdf {
inner,
hkdf_label_buf: Vec::with_capacity(32),
}
}

pub fn set_prk(&mut self, prk: &[u8]) {
if let Ok(hk) = Hkdf::<Sha256>::from_prk(prk) {
self.inner = hk;
}
}

pub fn expand_label(&mut self, label: &[u8], output: &mut [u8]) {
self.hkdf_label_buf.clear();
let len = output.len() as u16;
let l_bytes = len.to_be_bytes();
self.hkdf_label_buf.extend_from_slice(&l_bytes);
let label_len = 6 + label.len() as u8;
self.hkdf_label_buf.push(label_len);
self.hkdf_label_buf.extend_from_slice(b"tls13 ");
self.hkdf_label_buf
.extend_from_slice(&label[..label_len as usize - 6]);
self.hkdf_label_buf.push(0); // no context

let _ = self.inner.expand(&self.hkdf_label_buf, output);
}
pub fn quic_hkdf_extract_expand(
salt: &[u8],
ikm: &[u8],
label: &[u8],
output: &mut [u8],
) -> Result<(), ErrorStack> {
let mut pkey_ctx = PkeyCtx::new_id(Id::HKDF)?;
pkey_ctx.derive_init()?;
pkey_ctx.set_hkdf_mode(HkdfMode::EXTRACT_THEN_EXPAND)?;
pkey_ctx.set_hkdf_md(Md::sha256())?;
pkey_ctx.set_hkdf_salt(salt)?;
pkey_ctx.set_hkdf_key(ikm)?;

let info = build_info_from_label(label, output.len() as u16);
pkey_ctx.add_hkdf_info(&info)?;

pkey_ctx.derive(Some(output))?;
Ok(())
}

pub fn quic_hkdf_expand(prk: &[u8], label: &[u8], output: &mut [u8]) -> Result<(), ErrorStack> {
let mut pkey_ctx = PkeyCtx::new_id(Id::HKDF)?;
pkey_ctx.derive_init()?;
pkey_ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY)?;
pkey_ctx.set_hkdf_md(Md::sha256())?;
pkey_ctx.set_hkdf_key(prk)?;

let info = build_info_from_label(label, output.len() as u16);
pkey_ctx.add_hkdf_info(&info)?;

pkey_ctx.derive(Some(output))?;
Ok(())
}
2 changes: 1 addition & 1 deletion lib/g3-dpi/src/parser/quic/packet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use thiserror::Error;
use super::{AckFrame, CryptoFrame, FrameConsume, FrameParseError, VarInt};

mod hkdf;
use hkdf::QuicInitialHkdf;
use hkdf::{quic_hkdf_expand, quic_hkdf_extract_expand};

mod aes;

Expand Down
29 changes: 16 additions & 13 deletions lib/g3-dpi/src/parser/quic/packet/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

use super::{Header, PacketParseError, QuicInitialHkdf};
use openssl::error::ErrorStack;

use super::{Header, PacketParseError};
use crate::parser::quic::VarInt;

const INITIAL_SALT: &[u8] = &[
Expand Down Expand Up @@ -96,7 +98,7 @@ impl InitialPacketV1 {
let pn_offset = offset;
let sample = &left[4..20];

let secrets = ClientSecrets::new(INITIAL_SALT, dst_cid);
let secrets = ClientSecrets::new(dst_cid)?;
let mask = super::aes::aes_ecb_mask(&secrets.hp, sample)?;
let header = Header::decode_long(byte1, mask, left)?;

Expand Down Expand Up @@ -126,24 +128,25 @@ struct ClientSecrets {
}

impl ClientSecrets {
pub fn new(initial_salt: &[u8], cid: &[u8]) -> Self {
let mut hk = QuicInitialHkdf::new(initial_salt, cid);

pub fn new(cid: &[u8]) -> Result<Self, ErrorStack> {
let mut client_initial_secret = [0u8; 32];
hk.expand_label(b"client in", &mut client_initial_secret);

hk.set_prk(&client_initial_secret);
super::quic_hkdf_extract_expand(
INITIAL_SALT,
cid,
b"client in",
&mut client_initial_secret,
)?;

let mut key = [0u8; 16];
hk.expand_label(b"quic key", &mut key);
super::quic_hkdf_expand(&client_initial_secret, b"quic key", &mut key)?;

let mut iv = [0u8; 12];
hk.expand_label(b"quic iv", &mut iv);
super::quic_hkdf_expand(&client_initial_secret, b"quic iv", &mut iv)?;

let mut hp = [0u8; 16];
hk.expand_label(b"quic hp", &mut hp);
super::quic_hkdf_expand(&client_initial_secret, b"quic hp", &mut hp)?;

ClientSecrets { key, iv, hp }
Ok(ClientSecrets { key, iv, hp })
}
}

Expand All @@ -159,7 +162,7 @@ mod tests {
let iv = hex!("fa044b2f42a3fd3b46fb255c");
let hp = hex!("9f50449e04a0e810283a1e9933adedd2");

let secrets = ClientSecrets::new(INITIAL_SALT, &cid);
let secrets = ClientSecrets::new(&cid).unwrap();
assert_eq!(secrets.key, key);
assert_eq!(secrets.iv, iv);
assert_eq!(secrets.hp, hp);
Expand Down
29 changes: 16 additions & 13 deletions lib/g3-dpi/src/parser/quic/packet/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

use super::{Header, PacketParseError, QuicInitialHkdf};
use openssl::error::ErrorStack;

use super::{Header, PacketParseError};
use crate::parser::quic::VarInt;

const INITIAL_SALT: &[u8] = &[
Expand Down Expand Up @@ -96,7 +98,7 @@ impl InitialPacketV2 {
let pn_offset = offset;
let sample = &left[4..20];

let secrets = ClientSecrets::new(INITIAL_SALT, dst_cid);
let secrets = ClientSecrets::new(dst_cid)?;
let mask = super::aes::aes_ecb_mask(&secrets.hp, sample)?;
let header = Header::decode_long(byte1, mask, left)?;

Expand Down Expand Up @@ -126,24 +128,25 @@ struct ClientSecrets {
}

impl ClientSecrets {
pub fn new(initial_salt: &[u8], cid: &[u8]) -> Self {
let mut hk = QuicInitialHkdf::new(initial_salt, cid);

pub fn new(cid: &[u8]) -> Result<Self, ErrorStack> {
let mut client_initial_secret = [0u8; 32];
hk.expand_label(b"client in", &mut client_initial_secret);

hk.set_prk(&client_initial_secret);
super::quic_hkdf_extract_expand(
INITIAL_SALT,
cid,
b"client in",
&mut client_initial_secret,
)?;

let mut key = [0u8; 16];
hk.expand_label(b"quicv2 key", &mut key);
super::quic_hkdf_expand(&client_initial_secret, b"quicv2 key", &mut key)?;

let mut iv = [0u8; 12];
hk.expand_label(b"quicv2 iv", &mut iv);
super::quic_hkdf_expand(&client_initial_secret, b"quicv2 iv", &mut iv)?;

let mut hp = [0u8; 16];
hk.expand_label(b"quicv2 hp", &mut hp);
super::quic_hkdf_expand(&client_initial_secret, b"quicv2 hp", &mut hp)?;

ClientSecrets { key, iv, hp }
Ok(ClientSecrets { key, iv, hp })
}
}

Expand All @@ -159,7 +162,7 @@ mod tests {
let iv = hex!("91f73e2351d8fa91660e909f");
let hp = hex!("45b95e15235d6f45a6b19cbcb0294ba9");

let secrets = ClientSecrets::new(INITIAL_SALT, &cid);
let secrets = ClientSecrets::new(&cid).unwrap();
assert_eq!(secrets.key, key);
assert_eq!(secrets.iv, iv);
assert_eq!(secrets.hp, hp);
Expand Down

0 comments on commit 7a51229

Please sign in to comment.