Skip to content

Commit

Permalink
quic: v2 support per rfc 9369
Browse files Browse the repository at this point in the history
Ticket: #4968
  • Loading branch information
catenacyber authored and victorjulien committed Oct 3, 2023
1 parent 96a0e70 commit 9157070
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
40 changes: 30 additions & 10 deletions rust/src/quic/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ pub const AES128_IV_LEN: usize = 12;
pub struct HeaderProtectionKey(Aes128);

impl HeaderProtectionKey {
fn new(secret: &[u8]) -> Self {
fn new(secret: &[u8], version: u32) -> Self {
let hk = Hkdf::<Sha256>::from_prk(secret).unwrap();
let mut secret = [0u8; AES128_KEY_LEN];
hkdf_expand_label(&hk, b"quic hp", &mut secret, AES128_KEY_LEN as u16);
let quichp = if version == 0x6b3343cf {
b"quicv2 hp" as &[u8]
} else {
b"quic hp" as &[u8]
};
hkdf_expand_label(&hk, quichp, &mut secret, AES128_KEY_LEN as u16);
return Self(Aes128::new(GenericArray::from_slice(&secret)));
}

Expand Down Expand Up @@ -70,17 +75,27 @@ pub struct PacketKey {
}

impl PacketKey {
fn new(secret: &[u8]) -> Self {
fn new(secret: &[u8], version: u32) -> Self {
let hk = Hkdf::<Sha256>::from_prk(secret).unwrap();
let mut secret = [0u8; AES128_KEY_LEN];
hkdf_expand_label(&hk, b"quic key", &mut secret, AES128_KEY_LEN as u16);
let quickey = if version == 0x6b3343cf {
b"quicv2 key" as &[u8]
} else {
b"quic key" as &[u8]
};
hkdf_expand_label(&hk, quickey, &mut secret, AES128_KEY_LEN as u16);
let key = Aes128Gcm::new(GenericArray::from_slice(&secret));

let mut r = PacketKey {
key,
iv: [0u8; AES128_IV_LEN],
};
hkdf_expand_label(&hk, b"quic iv", &mut r.iv, AES128_IV_LEN as u16);
let quiciv = if version == 0x6b3343cf {
b"quicv2 iv" as &[u8]
} else {
b"quic iv" as &[u8]
};
hkdf_expand_label(&hk, quiciv, &mut r.iv, AES128_IV_LEN as u16);
return r;
}

Expand Down Expand Up @@ -111,10 +126,10 @@ pub struct DirectionalKeys {
}

impl DirectionalKeys {
fn new(secret: &[u8]) -> Self {
fn new(secret: &[u8], version: u32) -> Self {
Self {
header: HeaderProtectionKey::new(secret),
packet: PacketKey::new(secret),
header: HeaderProtectionKey::new(secret, version),
packet: PacketKey::new(secret, version),
}
}
}
Expand Down Expand Up @@ -163,6 +178,11 @@ pub fn quic_keys_initial(version: u32, client_dst_connection_id: &[u8]) -> Optio
0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
],
0x6b3343cf => &[
// https://www.rfc-editor.org/rfc/rfc9369.html#section-3.3.1
0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
],
_ => {
return None;
}
Expand All @@ -174,7 +194,7 @@ pub fn quic_keys_initial(version: u32, client_dst_connection_id: &[u8]) -> Optio
hkdf_expand_label(&hk, b"server in", &mut server_secret, 32);

return Some(QuicKeys {
local: DirectionalKeys::new(&server_secret),
remote: DirectionalKeys::new(&client_secret),
local: DirectionalKeys::new(&server_secret, version),
remote: DirectionalKeys::new(&client_secret, version),
});
}
13 changes: 13 additions & 0 deletions rust/src/quic/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl QuicVersion {
pub const Q044: QuicVersion = QuicVersion(0x51303434);
pub const Q045: QuicVersion = QuicVersion(0x51303435);
pub const Q046: QuicVersion = QuicVersion(0x51303436);
pub const V2: QuicVersion = QuicVersion(0x6b3343cf);

fn is_gquic(&self) -> bool {
*self == QuicVersion::Q043
Expand All @@ -61,6 +62,7 @@ impl From<QuicVersion> for String {
QuicVersion(0x51303434) => "Q044".to_string(),
QuicVersion(0x51303435) => "Q045".to_string(),
QuicVersion(0x51303436) => "Q046".to_string(),
QuicVersion(0x6b3343cf) => "v2".to_string(),
QuicVersion(x) => format!("{:x}", x),
}
}
Expand Down Expand Up @@ -286,7 +288,18 @@ impl QuicHeader {
return Err(nom7::Err::Error(QuicError::InvalidPacket));
}
}
} else if version == QuicVersion::V2 {
match (first & 0x30) >> 4 {
0x01 => QuicType::Initial,
0x02 => QuicType::ZeroRTT,
0x03 => QuicType::Handshake,
0x00 => QuicType::Retry,
_ => {
return Err(nom7::Err::Error(QuicError::InvalidPacket));
}
}
} else {
// consider as Quic version 1 (and latest drafts)
match (first & 0x30) >> 4 {
0x00 => QuicType::Initial,
0x01 => QuicType::ZeroRTT,
Expand Down

0 comments on commit 9157070

Please sign in to comment.