/src/quiche/quiche/src/packet.rs
Line | Count | Source |
1 | | // Copyright (C) 2018-2019, Cloudflare, Inc. |
2 | | // All rights reserved. |
3 | | // |
4 | | // Redistribution and use in source and binary forms, with or without |
5 | | // modification, are permitted provided that the following conditions are |
6 | | // met: |
7 | | // |
8 | | // * Redistributions of source code must retain the above copyright notice, |
9 | | // this list of conditions and the following disclaimer. |
10 | | // |
11 | | // * Redistributions in binary form must reproduce the above copyright |
12 | | // notice, this list of conditions and the following disclaimer in the |
13 | | // documentation and/or other materials provided with the distribution. |
14 | | // |
15 | | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
16 | | // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
17 | | // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
19 | | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 | | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 | | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
22 | | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
23 | | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
24 | | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | |
27 | | use std::fmt::Display; |
28 | | |
29 | | use std::ops::Index; |
30 | | use std::ops::IndexMut; |
31 | | use std::ops::RangeInclusive; |
32 | | |
33 | | use std::time::Instant; |
34 | | |
35 | | use crate::Error; |
36 | | use crate::Result; |
37 | | use crate::DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS; |
38 | | |
39 | | use crate::crypto; |
40 | | use crate::rand; |
41 | | use crate::ranges; |
42 | | use crate::recovery; |
43 | | use crate::stream; |
44 | | |
45 | | const FORM_BIT: u8 = 0x80; |
46 | | const FIXED_BIT: u8 = 0x40; |
47 | | const KEY_PHASE_BIT: u8 = 0x04; |
48 | | |
49 | | const TYPE_MASK: u8 = 0x30; |
50 | | const PKT_NUM_MASK: u8 = 0x03; |
51 | | |
52 | | pub const MAX_CID_LEN: u8 = 20; |
53 | | |
54 | | pub const MAX_PKT_NUM_LEN: usize = 4; |
55 | | |
56 | | const SAMPLE_LEN: usize = 16; |
57 | | |
58 | | // Set the min skip skip interval to 2x the default number of initial packet |
59 | | // count. |
60 | | const MIN_SKIP_COUNTER_VALUE: u64 = |
61 | | DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS as u64 * 2; |
62 | | |
63 | | const RETRY_AEAD_ALG: crypto::Algorithm = crypto::Algorithm::AES128_GCM; |
64 | | |
65 | | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] |
66 | | pub enum Epoch { |
67 | | Initial = 0, |
68 | | Handshake = 1, |
69 | | Application = 2, |
70 | | } |
71 | | |
72 | | static EPOCHS: [Epoch; 3] = |
73 | | [Epoch::Initial, Epoch::Handshake, Epoch::Application]; |
74 | | |
75 | | impl Epoch { |
76 | | /// Returns an ordered slice containing the `Epoch`s that fit in the |
77 | | /// provided `range`. |
78 | 10.6M | pub fn epochs(range: RangeInclusive<Epoch>) -> &'static [Epoch] { |
79 | 10.6M | &EPOCHS[*range.start() as usize..=*range.end() as usize] |
80 | 10.6M | } |
81 | | |
82 | 0 | pub const fn count() -> usize { |
83 | 0 | 3 |
84 | 0 | } |
85 | | } |
86 | | |
87 | | impl Display for Epoch { |
88 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
89 | 0 | write!(f, "{}", usize::from(*self)) |
90 | 0 | } |
91 | | } |
92 | | |
93 | | impl From<Epoch> for usize { |
94 | 179M | fn from(e: Epoch) -> Self { |
95 | 179M | e as usize |
96 | 179M | } |
97 | | } |
98 | | |
99 | | impl<T> Index<Epoch> for [T] |
100 | | where |
101 | | T: Sized, |
102 | | { |
103 | | type Output = T; |
104 | | |
105 | 120M | fn index(&self, index: Epoch) -> &Self::Output { |
106 | 120M | self.index(usize::from(index)) |
107 | 120M | } <[quiche::packet::PktNumSpace] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 449k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 449k | self.index(usize::from(index)) | 107 | 449k | } |
<[quiche::packet::CryptoContext] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 125k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 125k | self.index(usize::from(index)) | 107 | 125k | } |
<[quiche::packet::PktNumSpace] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 34.1M | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 34.1M | self.index(usize::from(index)) | 107 | 34.1M | } |
<[quiche::packet::CryptoContext] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 46.3M | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 46.3M | self.index(usize::from(index)) | 107 | 46.3M | } |
<[quiche::packet::PktNumSpace] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 704k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 704k | self.index(usize::from(index)) | 107 | 704k | } |
<[quiche::packet::CryptoContext] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 685k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 685k | self.index(usize::from(index)) | 107 | 685k | } |
Unexecuted instantiation: <[quiche::recovery::gcongestion::recovery::RecoveryEpoch] as core::ops::index::Index<quiche::packet::Epoch>>::index <[quiche::recovery::congestion::recovery::RecoveryEpoch] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 37.1M | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 37.1M | self.index(usize::from(index)) | 107 | 37.1M | } |
<[quiche::packet::PktNumSpace] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 648k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 648k | self.index(usize::from(index)) | 107 | 648k | } |
<[quiche::packet::CryptoContext] as core::ops::index::Index<quiche::packet::Epoch>>::index Line | Count | Source | 105 | 177k | fn index(&self, index: Epoch) -> &Self::Output { | 106 | 177k | self.index(usize::from(index)) | 107 | 177k | } |
|
108 | | } |
109 | | |
110 | | impl<T> IndexMut<Epoch> for [T] |
111 | | where |
112 | | T: Sized, |
113 | | { |
114 | 58.6M | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { |
115 | 58.6M | self.index_mut(usize::from(index)) |
116 | 58.6M | } <[quiche::packet::PktNumSpace] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 586k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 586k | self.index_mut(usize::from(index)) | 116 | 586k | } |
<[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 127k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 127k | self.index_mut(usize::from(index)) | 116 | 127k | } |
<[quiche::packet::PktNumSpace] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 27.5M | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 27.5M | self.index_mut(usize::from(index)) | 116 | 27.5M | } |
<[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 16.1M | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 16.1M | self.index_mut(usize::from(index)) | 116 | 16.1M | } |
<[quiche::packet::PktNumSpace] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 752k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 752k | self.index_mut(usize::from(index)) | 116 | 752k | } |
<[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 510k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 510k | self.index_mut(usize::from(index)) | 116 | 510k | } |
Unexecuted instantiation: <[quiche::recovery::gcongestion::recovery::RecoveryEpoch] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut <[quiche::recovery::congestion::recovery::RecoveryEpoch] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 12.0M | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 12.0M | self.index_mut(usize::from(index)) | 116 | 12.0M | } |
Unexecuted instantiation: <[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut <[quiche::packet::PktNumSpace] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 875k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 875k | self.index_mut(usize::from(index)) | 116 | 875k | } |
<[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 138k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 138k | self.index_mut(usize::from(index)) | 116 | 138k | } |
<[quiche::packet::CryptoContext] as core::ops::index::IndexMut<quiche::packet::Epoch>>::index_mut Line | Count | Source | 114 | 19.0k | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output { | 115 | 19.0k | self.index_mut(usize::from(index)) | 116 | 19.0k | } |
|
117 | | } |
118 | | |
119 | | /// QUIC packet type. |
120 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
121 | | pub enum Type { |
122 | | /// Initial packet. |
123 | | Initial, |
124 | | |
125 | | /// Retry packet. |
126 | | Retry, |
127 | | |
128 | | /// Handshake packet. |
129 | | Handshake, |
130 | | |
131 | | /// 0-RTT packet. |
132 | | ZeroRTT, |
133 | | |
134 | | /// Version negotiation packet. |
135 | | VersionNegotiation, |
136 | | |
137 | | /// 1-RTT short header packet. |
138 | | Short, |
139 | | } |
140 | | |
141 | | impl Type { |
142 | 4.32M | pub(crate) fn from_epoch(e: Epoch) -> Type { |
143 | 4.32M | match e { |
144 | 3.09M | Epoch::Initial => Type::Initial, |
145 | | |
146 | 28.1k | Epoch::Handshake => Type::Handshake, |
147 | | |
148 | 1.20M | Epoch::Application => Type::Short, |
149 | | } |
150 | 4.32M | } |
151 | | |
152 | 10.9M | pub(crate) fn to_epoch(self) -> Result<Epoch> { |
153 | 10.9M | match self { |
154 | 5.10M | Type::Initial => Ok(Epoch::Initial), |
155 | | |
156 | 4.86k | Type::ZeroRTT => Ok(Epoch::Application), |
157 | | |
158 | 79.9k | Type::Handshake => Ok(Epoch::Handshake), |
159 | | |
160 | 5.79M | Type::Short => Ok(Epoch::Application), |
161 | | |
162 | 0 | _ => Err(Error::InvalidPacket), |
163 | | } |
164 | 10.9M | } |
165 | | |
166 | | #[cfg(feature = "qlog")] |
167 | | pub(crate) fn to_qlog(self) -> qlog::events::quic::PacketType { |
168 | | match self { |
169 | | Type::Initial => qlog::events::quic::PacketType::Initial, |
170 | | |
171 | | Type::Retry => qlog::events::quic::PacketType::Retry, |
172 | | |
173 | | Type::Handshake => qlog::events::quic::PacketType::Handshake, |
174 | | |
175 | | Type::ZeroRTT => qlog::events::quic::PacketType::ZeroRtt, |
176 | | |
177 | | Type::VersionNegotiation => |
178 | | qlog::events::quic::PacketType::VersionNegotiation, |
179 | | |
180 | | Type::Short => qlog::events::quic::PacketType::OneRtt, |
181 | | } |
182 | | } |
183 | | } |
184 | | |
185 | | /// A QUIC connection ID. |
186 | | pub struct ConnectionId<'a>(ConnectionIdInner<'a>); |
187 | | |
188 | | enum ConnectionIdInner<'a> { |
189 | | Vec(Vec<u8>), |
190 | | Ref(&'a [u8]), |
191 | | } |
192 | | |
193 | | impl<'a> ConnectionId<'a> { |
194 | | /// Creates a new connection ID from the given vector. |
195 | | #[inline] |
196 | 28.3M | pub const fn from_vec(cid: Vec<u8>) -> Self { |
197 | 28.3M | Self(ConnectionIdInner::Vec(cid)) |
198 | 28.3M | } |
199 | | |
200 | | /// Creates a new connection ID from the given slice. |
201 | | #[inline] |
202 | 23.2M | pub const fn from_ref(cid: &'a [u8]) -> Self { |
203 | 23.2M | Self(ConnectionIdInner::Ref(cid)) |
204 | 23.2M | } |
205 | | |
206 | | /// Returns a new owning connection ID from the given existing one. |
207 | | #[inline] |
208 | 54.8k | pub fn into_owned(self) -> ConnectionId<'static> { |
209 | 54.8k | ConnectionId::from_vec(self.into()) |
210 | 54.8k | } |
211 | | } |
212 | | |
213 | | impl Default for ConnectionId<'_> { |
214 | | #[inline] |
215 | 1.55M | fn default() -> Self { |
216 | 1.55M | Self::from_vec(Vec::new()) |
217 | 1.55M | } |
218 | | } |
219 | | |
220 | | impl From<Vec<u8>> for ConnectionId<'_> { |
221 | | #[inline] |
222 | 5.08M | fn from(v: Vec<u8>) -> Self { |
223 | 5.08M | Self::from_vec(v) |
224 | 5.08M | } |
225 | | } |
226 | | |
227 | | impl From<ConnectionId<'_>> for Vec<u8> { |
228 | | #[inline] |
229 | 54.8k | fn from(id: ConnectionId<'_>) -> Self { |
230 | 54.8k | match id.0 { |
231 | 0 | ConnectionIdInner::Vec(cid) => cid, |
232 | 54.8k | ConnectionIdInner::Ref(cid) => cid.to_vec(), |
233 | | } |
234 | 54.8k | } |
235 | | } |
236 | | |
237 | | impl PartialEq for ConnectionId<'_> { |
238 | | #[inline] |
239 | 1.86M | fn eq(&self, other: &Self) -> bool { |
240 | 1.86M | self.as_ref() == other.as_ref() |
241 | 1.86M | } |
242 | | } |
243 | | |
244 | | impl Eq for ConnectionId<'_> {} |
245 | | |
246 | | impl AsRef<[u8]> for ConnectionId<'_> { |
247 | | #[inline] |
248 | 47.8M | fn as_ref(&self) -> &[u8] { |
249 | 47.8M | match &self.0 { |
250 | 46.2M | ConnectionIdInner::Vec(v) => v.as_ref(), |
251 | 1.56M | ConnectionIdInner::Ref(v) => v, |
252 | | } |
253 | 47.8M | } |
254 | | } |
255 | | |
256 | | impl std::hash::Hash for ConnectionId<'_> { |
257 | | #[inline] |
258 | | fn hash<H: std::hash::Hasher>(&self, state: &mut H) { |
259 | | self.as_ref().hash(state); |
260 | | } |
261 | | } |
262 | | |
263 | | impl std::ops::Deref for ConnectionId<'_> { |
264 | | type Target = [u8]; |
265 | | |
266 | | #[inline] |
267 | 25.4M | fn deref(&self) -> &[u8] { |
268 | 25.4M | match &self.0 { |
269 | 1.12M | ConnectionIdInner::Vec(v) => v.as_ref(), |
270 | 24.3M | ConnectionIdInner::Ref(v) => v, |
271 | | } |
272 | 25.4M | } |
273 | | } |
274 | | |
275 | | impl Clone for ConnectionId<'_> { |
276 | | #[inline] |
277 | 21.6M | fn clone(&self) -> Self { |
278 | 21.6M | Self::from_vec(self.as_ref().to_vec()) |
279 | 21.6M | } |
280 | | } |
281 | | |
282 | | impl std::fmt::Debug for ConnectionId<'_> { |
283 | | #[inline] |
284 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
285 | 0 | for c in self.as_ref() { |
286 | 0 | write!(f, "{c:02x}")?; |
287 | | } |
288 | | |
289 | 0 | Ok(()) |
290 | 0 | } |
291 | | } |
292 | | |
293 | | /// A QUIC packet's header. |
294 | | #[derive(Clone, PartialEq, Eq)] |
295 | | pub struct Header<'a> { |
296 | | /// The type of the packet. |
297 | | pub ty: Type, |
298 | | |
299 | | /// The version of the packet. |
300 | | pub version: u32, |
301 | | |
302 | | /// The destination connection ID of the packet. |
303 | | pub dcid: ConnectionId<'a>, |
304 | | |
305 | | /// The source connection ID of the packet. |
306 | | pub scid: ConnectionId<'a>, |
307 | | |
308 | | /// The packet number. It's only meaningful after the header protection is |
309 | | /// removed. |
310 | | pub(crate) pkt_num: u64, |
311 | | |
312 | | /// The length of the packet number. It's only meaningful after the header |
313 | | /// protection is removed. |
314 | | pub(crate) pkt_num_len: usize, |
315 | | |
316 | | /// The address verification token of the packet. Only present in `Initial` |
317 | | /// and `Retry` packets. |
318 | | pub token: Option<Vec<u8>>, |
319 | | |
320 | | /// The list of versions in the packet. Only present in |
321 | | /// `VersionNegotiation` packets. |
322 | | pub versions: Option<Vec<u32>>, |
323 | | |
324 | | /// The key phase bit of the packet. It's only meaningful after the header |
325 | | /// protection is removed. |
326 | | pub(crate) key_phase: bool, |
327 | | } |
328 | | |
329 | | impl<'a> Header<'a> { |
330 | | /// Parses a QUIC packet header from the given buffer. |
331 | | /// |
332 | | /// The `dcid_len` parameter is the length of the destination connection ID, |
333 | | /// required to parse short header packets. |
334 | | /// |
335 | | /// ## Examples: |
336 | | /// |
337 | | /// ```no_run |
338 | | /// # const LOCAL_CONN_ID_LEN: usize = 16; |
339 | | /// # let mut buf = [0; 512]; |
340 | | /// # let mut out = [0; 512]; |
341 | | /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap(); |
342 | | /// let (len, src) = socket.recv_from(&mut buf).unwrap(); |
343 | | /// |
344 | | /// let hdr = quiche::Header::from_slice(&mut buf[..len], LOCAL_CONN_ID_LEN)?; |
345 | | /// # Ok::<(), quiche::Error>(()) |
346 | | /// ``` |
347 | | #[inline] |
348 | | pub fn from_slice<'b>( |
349 | | buf: &'b mut [u8], dcid_len: usize, |
350 | | ) -> Result<Header<'a>> { |
351 | | let mut b = octets::OctetsMut::with_slice(buf); |
352 | | Header::from_bytes(&mut b, dcid_len) |
353 | | } |
354 | | |
355 | 7.57M | pub(crate) fn from_bytes<'b>( |
356 | 7.57M | b: &'b mut octets::OctetsMut, dcid_len: usize, |
357 | 7.57M | ) -> Result<Header<'a>> { |
358 | 7.57M | let first = b.get_u8()?; |
359 | | |
360 | 7.57M | if !Header::is_long(first) { |
361 | | // Decode short header. |
362 | 3.61M | let dcid = b.get_bytes(dcid_len)?; |
363 | | |
364 | 1.51M | return Ok(Header { |
365 | 1.51M | ty: Type::Short, |
366 | 1.51M | version: 0, |
367 | 1.51M | dcid: dcid.to_vec().into(), |
368 | 1.51M | scid: ConnectionId::default(), |
369 | 1.51M | pkt_num: 0, |
370 | 1.51M | pkt_num_len: 0, |
371 | 1.51M | token: None, |
372 | 1.51M | versions: None, |
373 | 1.51M | key_phase: false, |
374 | 1.51M | }); |
375 | 3.95M | } |
376 | | |
377 | | // Decode long header. |
378 | 3.95M | let version = b.get_u32()?; |
379 | | |
380 | 2.23M | let ty = if version == 0 { |
381 | 47.6k | Type::VersionNegotiation |
382 | | } else { |
383 | 2.18M | match (first & TYPE_MASK) >> 4 { |
384 | 1.91M | 0x00 => Type::Initial, |
385 | 10.6k | 0x01 => Type::ZeroRTT, |
386 | 27.7k | 0x02 => Type::Handshake, |
387 | 235k | 0x03 => Type::Retry, |
388 | 0 | _ => return Err(Error::InvalidPacket), |
389 | | } |
390 | | }; |
391 | | |
392 | 2.23M | let dcid_len = b.get_u8()?; |
393 | 2.17M | if crate::version_is_supported(version) && dcid_len > MAX_CID_LEN { |
394 | 25.5k | return Err(Error::InvalidPacket); |
395 | 2.14M | } |
396 | 2.14M | let dcid = b.get_bytes(dcid_len as usize)?.to_vec(); |
397 | | |
398 | 1.98M | let scid_len = b.get_u8()?; |
399 | 1.91M | if crate::version_is_supported(version) && scid_len > MAX_CID_LEN { |
400 | 14.1k | return Err(Error::InvalidPacket); |
401 | 1.90M | } |
402 | 1.90M | let scid = b.get_bytes(scid_len as usize)?.to_vec(); |
403 | | |
404 | | // End of invariants. |
405 | | |
406 | 1.80M | let mut token: Option<Vec<u8>> = None; |
407 | 1.80M | let mut versions: Option<Vec<u32>> = None; |
408 | | |
409 | 1.80M | match ty { |
410 | | Type::Initial => { |
411 | 1.62M | token = Some(b.get_bytes_with_varint_length()?.to_vec()); |
412 | | }, |
413 | | |
414 | | Type::Retry => { |
415 | | const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len(); |
416 | | |
417 | | // Exclude the integrity tag from the token. |
418 | 110k | if b.cap() < TAG_LEN { |
419 | 27.3k | return Err(Error::InvalidPacket); |
420 | 82.8k | } |
421 | | |
422 | 82.8k | let token_len = b.cap() - TAG_LEN; |
423 | 82.8k | token = Some(b.get_bytes(token_len)?.to_vec()); |
424 | | }, |
425 | | |
426 | | Type::VersionNegotiation => { |
427 | 37.1k | let mut list: Vec<u32> = Vec::new(); |
428 | | |
429 | 2.84M | while b.cap() > 0 { |
430 | 2.83M | let version = b.get_u32()?; |
431 | 2.81M | list.push(version); |
432 | | } |
433 | | |
434 | 14.0k | versions = Some(list); |
435 | | }, |
436 | | |
437 | 35.2k | _ => (), |
438 | | }; |
439 | | |
440 | 1.71M | Ok(Header { |
441 | 1.71M | ty, |
442 | 1.71M | version, |
443 | 1.71M | dcid: dcid.into(), |
444 | 1.71M | scid: scid.into(), |
445 | 1.71M | pkt_num: 0, |
446 | 1.71M | pkt_num_len: 0, |
447 | 1.71M | token, |
448 | 1.71M | versions, |
449 | 1.71M | key_phase: false, |
450 | 1.71M | }) |
451 | 7.57M | } |
452 | | |
453 | 7.40M | pub(crate) fn to_bytes(&self, out: &mut octets::OctetsMut) -> Result<()> { |
454 | 7.40M | let mut first = 0; |
455 | | |
456 | | // Encode pkt num length. |
457 | 7.40M | first |= self.pkt_num_len.saturating_sub(1) as u8; |
458 | | |
459 | | // Encode short header. |
460 | 7.40M | if self.ty == Type::Short { |
461 | | // Unset form bit for short header. |
462 | 4.28M | first &= !FORM_BIT; |
463 | | |
464 | | // Set fixed bit. |
465 | 4.28M | first |= FIXED_BIT; |
466 | | |
467 | | // Set key phase bit. |
468 | 4.28M | if self.key_phase { |
469 | 1.53M | first |= KEY_PHASE_BIT; |
470 | 2.74M | } else { |
471 | 2.74M | first &= !KEY_PHASE_BIT; |
472 | 2.74M | } |
473 | | |
474 | 4.28M | out.put_u8(first)?; |
475 | 4.28M | out.put_bytes(&self.dcid)?; |
476 | | |
477 | 4.28M | return Ok(()); |
478 | 3.12M | } |
479 | | |
480 | | // Encode long header. |
481 | 3.12M | let ty: u8 = match self.ty { |
482 | 3.09M | Type::Initial => 0x00, |
483 | 0 | Type::ZeroRTT => 0x01, |
484 | 30.8k | Type::Handshake => 0x02, |
485 | 0 | Type::Retry => 0x03, |
486 | 0 | _ => return Err(Error::InvalidPacket), |
487 | | }; |
488 | | |
489 | 3.12M | first |= FORM_BIT | FIXED_BIT | (ty << 4); |
490 | | |
491 | 3.12M | out.put_u8(first)?; |
492 | | |
493 | 3.12M | out.put_u32(self.version)?; |
494 | | |
495 | 3.11M | out.put_u8(self.dcid.len() as u8)?; |
496 | 3.11M | out.put_bytes(&self.dcid)?; |
497 | | |
498 | 3.07M | out.put_u8(self.scid.len() as u8)?; |
499 | 3.07M | out.put_bytes(&self.scid)?; |
500 | | |
501 | | // Only Initial and Retry packets have a token. |
502 | 3.02M | match self.ty { |
503 | | Type::Initial => { |
504 | 2.99M | match self.token { |
505 | 0 | Some(ref v) => { |
506 | 0 | out.put_varint(v.len() as u64)?; |
507 | 0 | out.put_bytes(v)?; |
508 | | }, |
509 | | |
510 | | // No token, so length = 0. |
511 | | None => { |
512 | 2.99M | out.put_varint(0)?; |
513 | | }, |
514 | | } |
515 | | }, |
516 | | |
517 | | Type::Retry => { |
518 | | // Retry packets don't have a token length. |
519 | 0 | out.put_bytes(self.token.as_ref().unwrap())?; |
520 | | }, |
521 | | |
522 | 28.5k | _ => (), |
523 | | } |
524 | | |
525 | 3.02M | Ok(()) |
526 | 7.40M | } |
527 | | |
528 | | /// Returns true if the packet has a long header. |
529 | | /// |
530 | | /// The `b` parameter represents the first byte of the QUIC header. |
531 | 11.4M | fn is_long(b: u8) -> bool { |
532 | 11.4M | b & FORM_BIT != 0 |
533 | 11.4M | } |
534 | | } |
535 | | |
536 | | impl std::fmt::Debug for Header<'_> { |
537 | 0 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
538 | 0 | write!(f, "{:?}", self.ty)?; |
539 | | |
540 | 0 | if self.ty != Type::Short { |
541 | 0 | write!(f, " version={:x}", self.version)?; |
542 | 0 | } |
543 | | |
544 | 0 | write!(f, " dcid={:?}", self.dcid)?; |
545 | | |
546 | 0 | if self.ty != Type::Short { |
547 | 0 | write!(f, " scid={:?}", self.scid)?; |
548 | 0 | } |
549 | | |
550 | 0 | if let Some(ref token) = self.token { |
551 | 0 | write!(f, " token=")?; |
552 | 0 | for b in token { |
553 | 0 | write!(f, "{b:02x}")?; |
554 | | } |
555 | 0 | } |
556 | | |
557 | 0 | if let Some(ref versions) = self.versions { |
558 | 0 | write!(f, " versions={versions:x?}")?; |
559 | 0 | } |
560 | | |
561 | 0 | if self.ty == Type::Short { |
562 | 0 | write!(f, " key_phase={}", self.key_phase)?; |
563 | 0 | } |
564 | | |
565 | 0 | Ok(()) |
566 | 0 | } |
567 | | } |
568 | | |
569 | 7.40M | pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize { |
570 | 7.40M | let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1; |
571 | | // computes ceil of num_unacked.log2() + 1 |
572 | 7.40M | let min_bits = u64::BITS - num_unacked.leading_zeros() + 1; |
573 | | // get the num len in bytes |
574 | 7.40M | min_bits.div_ceil(8) as usize |
575 | 7.40M | } |
576 | | |
577 | 2.52M | pub fn decrypt_hdr( |
578 | 2.52M | b: &mut octets::OctetsMut, hdr: &mut Header, aead: &crypto::Open, |
579 | 2.52M | ) -> Result<()> { |
580 | 2.52M | let mut first = { |
581 | 2.52M | let (first_buf, _) = b.split_at(1)?; |
582 | 2.52M | first_buf.as_ref()[0] |
583 | | }; |
584 | | |
585 | 2.52M | let mut pn_and_sample = b.peek_bytes_mut(MAX_PKT_NUM_LEN + SAMPLE_LEN)?; |
586 | | |
587 | 2.44M | let (mut ciphertext, sample) = pn_and_sample.split_at(MAX_PKT_NUM_LEN)?; |
588 | | |
589 | 2.44M | let ciphertext = ciphertext.as_mut(); |
590 | | |
591 | 2.44M | let mask = aead.new_mask(sample.as_ref())?; |
592 | | |
593 | 2.44M | if Header::is_long(first) { |
594 | 1.31M | first ^= mask[0] & 0x0f; |
595 | 1.31M | } else { |
596 | 1.13M | first ^= mask[0] & 0x1f; |
597 | 1.13M | } |
598 | | |
599 | 2.44M | let pn_len = usize::from((first & PKT_NUM_MASK) + 1); |
600 | | |
601 | 2.44M | let ciphertext = &mut ciphertext[..pn_len]; |
602 | | |
603 | 5.96M | for i in 0..pn_len { |
604 | 5.96M | ciphertext[i] ^= mask[i + 1]; |
605 | 5.96M | } |
606 | | |
607 | | // Extract packet number corresponding to the decoded length. |
608 | 2.44M | let pn = match pn_len { |
609 | 1.23M | 1 => u64::from(b.get_u8()?), |
610 | | |
611 | 16.3k | 2 => u64::from(b.get_u16()?), |
612 | | |
613 | 76.0k | 3 => u64::from(b.get_u24()?), |
614 | | |
615 | 1.11M | 4 => u64::from(b.get_u32()?), |
616 | | |
617 | 0 | _ => return Err(Error::InvalidPacket), |
618 | | }; |
619 | | |
620 | | // Write decrypted first byte back into the input buffer. |
621 | 2.44M | let (mut first_buf, _) = b.split_at(1)?; |
622 | 2.44M | first_buf.as_mut()[0] = first; |
623 | | |
624 | 2.44M | hdr.pkt_num = pn; |
625 | 2.44M | hdr.pkt_num_len = pn_len; |
626 | | |
627 | 2.44M | if hdr.ty == Type::Short { |
628 | 1.13M | hdr.key_phase = (first & KEY_PHASE_BIT) != 0; |
629 | 1.31M | } |
630 | | |
631 | 2.44M | Ok(()) |
632 | 2.52M | } |
633 | | |
634 | 2.44M | pub fn decode_pkt_num(largest_pn: u64, truncated_pn: u64, pn_len: usize) -> u64 { |
635 | 2.44M | let pn_nbits = pn_len * 8; |
636 | 2.44M | let expected_pn = largest_pn + 1; |
637 | 2.44M | let pn_win = 1 << pn_nbits; |
638 | 2.44M | let pn_hwin = pn_win / 2; |
639 | 2.44M | let pn_mask = pn_win - 1; |
640 | 2.44M | let candidate_pn = (expected_pn & !pn_mask) | truncated_pn; |
641 | | |
642 | 2.44M | if candidate_pn + pn_hwin <= expected_pn && candidate_pn < (1 << 62) - pn_win |
643 | | { |
644 | 622k | return candidate_pn + pn_win; |
645 | 1.82M | } |
646 | | |
647 | 1.82M | if candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win { |
648 | 25.6k | return candidate_pn - pn_win; |
649 | 1.79M | } |
650 | | |
651 | 1.79M | candidate_pn |
652 | 2.44M | } |
653 | | |
654 | 2.44M | pub fn decrypt_pkt<'a>( |
655 | 2.44M | b: &'a mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize, |
656 | 2.44M | aead: &crypto::Open, |
657 | 2.44M | ) -> Result<octets::Octets<'a>> { |
658 | 2.44M | let payload_offset = b.off(); |
659 | | |
660 | 2.44M | let (header, mut payload) = b.split_at(payload_offset)?; |
661 | | |
662 | 2.44M | let payload_len = payload_len |
663 | 2.44M | .checked_sub(pn_len) |
664 | 2.44M | .ok_or(Error::InvalidPacket)?; |
665 | | |
666 | 2.42M | let mut ciphertext = payload.peek_bytes_mut(payload_len)?; |
667 | | |
668 | 2.39M | let payload_len = |
669 | 2.42M | aead.open_with_u64_counter(pn, header.as_ref(), ciphertext.as_mut())?; |
670 | | |
671 | 2.39M | Ok(b.get_bytes(payload_len)?) |
672 | 2.44M | } |
673 | | |
674 | 1.41M | pub fn encrypt_hdr( |
675 | 1.41M | b: &mut octets::OctetsMut, pn_len: usize, payload: &[u8], aead: &crypto::Seal, |
676 | 1.41M | ) -> Result<()> { |
677 | 1.41M | let sample = &payload |
678 | 1.41M | [MAX_PKT_NUM_LEN - pn_len..SAMPLE_LEN + (MAX_PKT_NUM_LEN - pn_len)]; |
679 | | |
680 | 1.41M | let mask = aead.new_mask(sample)?; |
681 | | |
682 | 1.41M | let (mut first, mut rest) = b.split_at(1)?; |
683 | | |
684 | 1.41M | let first = first.as_mut(); |
685 | | |
686 | 1.41M | if Header::is_long(first[0]) { |
687 | 666k | first[0] ^= mask[0] & 0x0f; |
688 | 745k | } else { |
689 | 745k | first[0] ^= mask[0] & 0x1f; |
690 | 745k | } |
691 | | |
692 | 1.41M | let pn_buf = rest.slice_last(pn_len)?; |
693 | 2.46M | for i in 0..pn_len { |
694 | 2.46M | pn_buf[i] ^= mask[i + 1]; |
695 | 2.46M | } |
696 | | |
697 | 1.41M | Ok(()) |
698 | 1.41M | } |
699 | | |
700 | 1.41M | pub fn encrypt_pkt( |
701 | 1.41M | b: &mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize, |
702 | 1.41M | payload_offset: usize, extra_in: Option<&[u8]>, aead: &crypto::Seal, |
703 | 1.41M | ) -> Result<usize> { |
704 | 1.41M | let (mut header, mut payload) = b.split_at(payload_offset)?; |
705 | | |
706 | 1.41M | let ciphertext_len = aead.seal_with_u64_counter( |
707 | 1.41M | pn, |
708 | 1.41M | header.as_ref(), |
709 | 1.41M | payload.as_mut(), |
710 | 1.41M | payload_len, |
711 | 1.41M | extra_in, |
712 | 0 | )?; |
713 | | |
714 | 1.41M | encrypt_hdr(&mut header, pn_len, payload.as_ref(), aead)?; |
715 | | |
716 | 1.41M | Ok(payload_offset + ciphertext_len) |
717 | 1.41M | } |
718 | | |
719 | 7.25M | pub fn encode_pkt_num( |
720 | 7.25M | pn: u64, pn_len: usize, b: &mut octets::OctetsMut, |
721 | 7.25M | ) -> Result<()> { |
722 | 7.25M | match pn_len { |
723 | 841k | 1 => b.put_u8(pn as u8)?, |
724 | | |
725 | 6.41M | 2 => b.put_u16(pn as u16)?, |
726 | | |
727 | 0 | 3 => b.put_u24(pn as u32)?, |
728 | | |
729 | 0 | 4 => b.put_u32(pn as u32)?, |
730 | | |
731 | 0 | _ => return Err(Error::InvalidPacket), |
732 | | }; |
733 | | |
734 | 7.25M | Ok(()) |
735 | 7.25M | } |
736 | | |
737 | 0 | pub fn negotiate_version( |
738 | 0 | scid: &[u8], dcid: &[u8], out: &mut [u8], |
739 | 0 | ) -> Result<usize> { |
740 | 0 | let mut b = octets::OctetsMut::with_slice(out); |
741 | | |
742 | 0 | let first = rand::rand_u8() | FORM_BIT; |
743 | | |
744 | 0 | b.put_u8(first)?; |
745 | 0 | b.put_u32(0)?; |
746 | | |
747 | 0 | b.put_u8(scid.len() as u8)?; |
748 | 0 | b.put_bytes(scid)?; |
749 | 0 | b.put_u8(dcid.len() as u8)?; |
750 | 0 | b.put_bytes(dcid)?; |
751 | 0 | b.put_u32(crate::PROTOCOL_VERSION_V1)?; |
752 | | |
753 | 0 | Ok(b.off()) |
754 | 0 | } |
755 | | |
756 | 0 | pub fn retry( |
757 | 0 | scid: &[u8], dcid: &[u8], new_scid: &[u8], token: &[u8], version: u32, |
758 | 0 | out: &mut [u8], |
759 | 0 | ) -> Result<usize> { |
760 | 0 | let mut b = octets::OctetsMut::with_slice(out); |
761 | | |
762 | 0 | if !crate::version_is_supported(version) { |
763 | 0 | return Err(Error::UnknownVersion); |
764 | 0 | } |
765 | | |
766 | 0 | let hdr = Header { |
767 | 0 | ty: Type::Retry, |
768 | 0 | version, |
769 | 0 | dcid: ConnectionId::from_ref(scid), |
770 | 0 | scid: ConnectionId::from_ref(new_scid), |
771 | 0 | pkt_num: 0, |
772 | 0 | pkt_num_len: 0, |
773 | 0 | token: Some(token.to_vec()), |
774 | 0 | versions: None, |
775 | 0 | key_phase: false, |
776 | 0 | }; |
777 | | |
778 | 0 | hdr.to_bytes(&mut b)?; |
779 | | |
780 | 0 | let tag = compute_retry_integrity_tag(&b, dcid, version)?; |
781 | | |
782 | 0 | b.put_bytes(tag.as_ref())?; |
783 | | |
784 | 0 | Ok(b.off()) |
785 | 0 | } |
786 | | |
787 | 227 | pub fn verify_retry_integrity( |
788 | 227 | b: &octets::OctetsMut, odcid: &[u8], version: u32, |
789 | 227 | ) -> Result<()> { |
790 | | const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len(); |
791 | | |
792 | 227 | let tag = compute_retry_integrity_tag(b, odcid, version)?; |
793 | | |
794 | 227 | crypto::verify_slices_are_equal(&b.as_ref()[..TAG_LEN], tag.as_ref()) |
795 | 227 | } |
796 | | |
797 | 227 | fn compute_retry_integrity_tag( |
798 | 227 | b: &octets::OctetsMut, odcid: &[u8], version: u32, |
799 | 227 | ) -> Result<Vec<u8>> { |
800 | | const KEY_LEN: usize = RETRY_AEAD_ALG.key_len(); |
801 | | const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len(); |
802 | | |
803 | | const RETRY_INTEGRITY_KEY_V1: [u8; KEY_LEN] = [ |
804 | | 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54, |
805 | | 0xe3, 0x68, 0xc8, 0x4e, |
806 | | ]; |
807 | | |
808 | | const RETRY_INTEGRITY_NONCE_V1: [u8; crypto::MAX_NONCE_LEN] = [ |
809 | | 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb, |
810 | | ]; |
811 | | |
812 | 227 | let (key, nonce) = match version { |
813 | | crate::PROTOCOL_VERSION_V1 => |
814 | 227 | (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1), |
815 | | |
816 | 0 | _ => (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1), |
817 | | }; |
818 | | |
819 | 227 | let hdr_len = b.off(); |
820 | | |
821 | 227 | let mut pseudo = vec![0; 1 + odcid.len() + hdr_len]; |
822 | | |
823 | 227 | let mut pb = octets::OctetsMut::with_slice(&mut pseudo); |
824 | | |
825 | 227 | pb.put_u8(odcid.len() as u8)?; |
826 | 227 | pb.put_bytes(odcid)?; |
827 | 227 | pb.put_bytes(&b.buf()[..hdr_len])?; |
828 | | |
829 | 227 | let key = crypto::PacketKey::new( |
830 | | RETRY_AEAD_ALG, |
831 | 227 | key.to_vec(), |
832 | 227 | nonce.to_vec(), |
833 | | crypto::Seal::ENCRYPT, |
834 | 0 | )?; |
835 | | |
836 | 227 | let mut out_tag = vec![0_u8; TAG_LEN]; |
837 | | |
838 | 227 | let out_len = key.seal_with_u64_counter(0, &pseudo, &mut out_tag, 0, None)?; |
839 | | |
840 | | // Ensure that the output only contains the AEAD tag. |
841 | 227 | if out_len != out_tag.len() { |
842 | 0 | return Err(Error::CryptoFail); |
843 | 227 | } |
844 | | |
845 | 227 | Ok(out_tag) |
846 | 227 | } |
847 | | |
848 | | pub struct KeyUpdate { |
849 | | /// 1-RTT key used prior to a key update. |
850 | | pub crypto_open: crypto::Open, |
851 | | |
852 | | /// The packet number triggered the latest key-update. |
853 | | /// |
854 | | /// Incoming packets with lower pn should use this (prev) crypto key. |
855 | | pub pn_on_update: u64, |
856 | | |
857 | | /// Whether ACK frame for key-update has been sent. |
858 | | pub update_acked: bool, |
859 | | |
860 | | /// When the old key should be discarded. |
861 | | pub timer: Instant, |
862 | | } |
863 | | |
864 | | pub struct PktNumSpace { |
865 | | /// The largest packet number received. |
866 | | pub largest_rx_pkt_num: u64, |
867 | | |
868 | | /// Time the largest packet number received. |
869 | | pub largest_rx_pkt_time: Instant, |
870 | | |
871 | | /// The largest non-probing packet number. |
872 | | pub largest_rx_non_probing_pkt_num: u64, |
873 | | |
874 | | /// The largest packet number send in the packet number space so far. |
875 | | pub largest_tx_pkt_num: Option<u64>, |
876 | | |
877 | | /// Range of packet numbers that we need to send an ACK for. |
878 | | pub recv_pkt_need_ack: ranges::RangeSet, |
879 | | |
880 | | /// Tracks received packet numbers. |
881 | | pub recv_pkt_num: PktNumWindow, |
882 | | |
883 | | /// Track if a received packet is ack eliciting. |
884 | | pub ack_elicited: bool, |
885 | | } |
886 | | |
887 | | impl PktNumSpace { |
888 | 123k | pub fn new() -> PktNumSpace { |
889 | 123k | PktNumSpace { |
890 | 123k | largest_rx_pkt_num: 0, |
891 | 123k | largest_rx_pkt_time: Instant::now(), |
892 | 123k | largest_rx_non_probing_pkt_num: 0, |
893 | 123k | largest_tx_pkt_num: None, |
894 | 123k | recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES), |
895 | 123k | recv_pkt_num: PktNumWindow::default(), |
896 | 123k | ack_elicited: false, |
897 | 123k | } |
898 | 123k | } |
899 | | |
900 | 46.5k | pub fn clear(&mut self) { |
901 | 46.5k | self.ack_elicited = false; |
902 | 46.5k | } |
903 | | |
904 | 12.3M | pub fn ready(&self) -> bool { |
905 | 12.3M | self.ack_elicited |
906 | 12.3M | } |
907 | | |
908 | 1.41M | pub fn on_packet_sent(&mut self, sent_pkt: &recovery::Sent) { |
909 | | // Track the largest packet number sent |
910 | 1.41M | self.largest_tx_pkt_num = |
911 | 1.41M | self.largest_tx_pkt_num.max(Some(sent_pkt.pkt_num)); |
912 | 1.41M | } |
913 | | } |
914 | | |
915 | | pub struct CryptoContext { |
916 | | pub key_update: Option<KeyUpdate>, |
917 | | pub crypto_open: Option<crypto::Open>, |
918 | | pub crypto_seal: Option<crypto::Seal>, |
919 | | pub crypto_0rtt_open: Option<crypto::Open>, |
920 | | pub crypto_stream: stream::Stream, |
921 | | } |
922 | | |
923 | | impl CryptoContext { |
924 | 123k | pub fn new() -> CryptoContext { |
925 | 123k | let crypto_stream = stream::Stream::new( |
926 | | 0, // dummy |
927 | | u64::MAX, |
928 | | u64::MAX, |
929 | | true, |
930 | | true, |
931 | | stream::MAX_STREAM_WINDOW, |
932 | | ); |
933 | 123k | CryptoContext { |
934 | 123k | key_update: None, |
935 | 123k | crypto_open: None, |
936 | 123k | crypto_seal: None, |
937 | 123k | crypto_0rtt_open: None, |
938 | 123k | crypto_stream, |
939 | 123k | } |
940 | 123k | } |
941 | | |
942 | 46.5k | pub fn clear(&mut self) { |
943 | 46.5k | self.crypto_open = None; |
944 | 46.5k | self.crypto_seal = None; |
945 | 46.5k | self.crypto_stream = <stream::Stream>::new( |
946 | | 0, // dummy |
947 | | u64::MAX, |
948 | | u64::MAX, |
949 | | true, |
950 | | true, |
951 | | stream::MAX_STREAM_WINDOW, |
952 | | ); |
953 | 46.5k | } |
954 | | |
955 | 14.3M | pub fn data_available(&self) -> bool { |
956 | 14.3M | self.crypto_stream.is_flushable() |
957 | 14.3M | } |
958 | | |
959 | 7.40M | pub fn crypto_overhead(&self) -> Option<usize> { |
960 | 7.40M | Some(self.crypto_seal.as_ref()?.alg().tag_len()) |
961 | 7.40M | } |
962 | | |
963 | 1.67M | pub fn has_keys(&self) -> bool { |
964 | 1.67M | self.crypto_open.is_some() && self.crypto_seal.is_some() |
965 | 1.67M | } |
966 | | } |
967 | | |
968 | | /// QUIC recommends skipping packet numbers to elicit a [faster ACK] or to |
969 | | /// mitigate an [optimistic ACK attack] (OACK attack). quiche currently skips |
970 | | /// packets only for the purposes of optimistic attack mitigation. |
971 | | /// |
972 | | /// ## What is an Optimistic ACK attack |
973 | | /// A typical endpoint is responsible for making concurrent progress on multiple |
974 | | /// connections and needs to fairly allocate resources across those connection. |
975 | | /// In order to ensure fairness, an endpoint relies on "recovery signals" to |
976 | | /// determine the optimal sending rate per connection. For example, when a new |
977 | | /// flow joins a shared network, it might induce packet loss for other flows and |
978 | | /// cause those flows to yield bandwidth on the network. ACKs are the primary |
979 | | /// source of recovery signals for a QUIC connection. |
980 | | /// |
981 | | /// The goal of an OACK attack is to mount a DDoS attack by exploiting recovery |
982 | | /// signals and causing a server to expand its sending rate. A server with an |
983 | | /// inflated sending rate would then be able to flood a shared network and |
984 | | /// cripple all other flows. The fundamental reason that makes OACK |
985 | | /// attach possible is the use of unvalidated ACK data, which is then used to |
986 | | /// modify internal state. Therefore at a high level, a mitigation should |
987 | | /// validate the incoming ACK data before use. |
988 | | /// |
989 | | /// ## Optimistic ACK attack mitigation |
990 | | /// quiche follows the RFC's recommendation for mitigating an [optimistic ACK |
991 | | /// attack] by skipping packets and validating that the peer does NOT send ACKs |
992 | | /// for those skipped packets. If an ACK for a skipped packet is received, the |
993 | | /// connection is closed with a [PROTOCOL_VIOLATION] error. |
994 | | /// |
995 | | /// A robust mitigation should skip packets randomly to ensure that an attacker |
996 | | /// can't predict which packet number was skipped. Skip/validation should happen |
997 | | /// "periodically" over the lifetime of the connection. Since skipping packets |
998 | | /// also elicits a faster ACK, we need to balance the skip frequency to |
999 | | /// sufficiently validate the peer without impacting other aspects of recovery. |
1000 | | /// |
1001 | | /// A naive approach could be to skip a random packet number in the range |
1002 | | /// 200-500 (pick some static range). While this might work, its not apparent if |
1003 | | /// a static range is effective for all networks with varying bandwidths/RTTs. |
1004 | | /// |
1005 | | /// Since an attacker can potentially influence the sending rate once per |
1006 | | /// "round", it would be ideal to validate the peer once per round. Therefore, |
1007 | | /// an ideal range seems to be one that dynamically adjusts based on packets |
1008 | | /// sent per round, ie. adjust skip range based on the current CWND. |
1009 | | /// |
1010 | | /// [faster ACK]: https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.4 |
1011 | | /// [optimistic ACK attack]: https://www.rfc-editor.org/rfc/rfc9000.html#section-21.4 |
1012 | | /// [PROTOCOL_VIOLATION]: https://www.rfc-editor.org/rfc/rfc9000#section-13.1 |
1013 | | pub struct PktNumManager { |
1014 | | // TODO: |
1015 | | // Defer including next_pkt_num in order to reduce the size of this patch |
1016 | | // /// Next packet number. |
1017 | | // next_pkt_num: u64, |
1018 | | /// Track if we have skipped a packet number. |
1019 | | skip_pn: Option<u64>, |
1020 | | |
1021 | | /// Track when to skip the next packet number |
1022 | | /// |
1023 | | /// None indicates the counter is not armed while Some(0) indicates that the |
1024 | | /// counter has expired. |
1025 | | pub skip_pn_counter: Option<u64>, |
1026 | | } |
1027 | | |
1028 | | impl PktNumManager { |
1029 | 41.1k | pub fn new() -> Self { |
1030 | 41.1k | PktNumManager { |
1031 | 41.1k | skip_pn: None, |
1032 | 41.1k | skip_pn_counter: None, |
1033 | 41.1k | } |
1034 | 41.1k | } |
1035 | | |
1036 | 1.41M | pub fn on_packet_sent( |
1037 | 1.41M | &mut self, cwnd: usize, max_datagram_size: usize, |
1038 | 1.41M | handshake_completed: bool, |
1039 | 1.41M | ) { |
1040 | | // Decrement skip_pn_counter for each packet sent |
1041 | 1.41M | if let Some(counter) = &mut self.skip_pn_counter { |
1042 | 104k | *counter = counter.saturating_sub(1); |
1043 | 1.30M | } else if self.should_arm_skip_counter(handshake_completed) { |
1044 | 23.4k | self.arm_skip_counter(cwnd, max_datagram_size); |
1045 | 1.28M | } |
1046 | 1.41M | } |
1047 | | |
1048 | 1.30M | fn should_arm_skip_counter(&self, handshake_completed: bool) -> bool { |
1049 | | // Arm if the counter is not set |
1050 | 1.30M | let counter_not_set = self.skip_pn_counter.is_none(); |
1051 | | // Don't arm until we have verified the current skip_pn. Rearming the |
1052 | | // counter could result in overwriting the skip_pn before |
1053 | | // validating the current skip_pn. |
1054 | 1.30M | let no_current_skip_packet = self.skip_pn.is_none(); |
1055 | | |
1056 | | // Skip pn only after the handshake has completed |
1057 | 1.30M | counter_not_set && no_current_skip_packet && handshake_completed |
1058 | 1.30M | } |
1059 | | |
1060 | 7.40M | pub fn should_skip_pn(&self, handshake_completed: bool) -> bool { |
1061 | | // Only skip a new packet once we have validated the peer hasn't sent the |
1062 | | // current skip packet. For the purposes of OACK, a skip_pn is |
1063 | | // considered validated once we receive an ACK for pn > skip_pn. |
1064 | 7.40M | let no_current_skip_packet = self.skip_pn.is_none(); |
1065 | 7.40M | let counter_expired = match self.skip_pn_counter { |
1066 | | // Skip if counter has expired |
1067 | 174k | Some(counter) => counter == 0, |
1068 | | // Don't skip if the counter has not been set |
1069 | 7.23M | None => false, |
1070 | | }; |
1071 | | |
1072 | | // Skip pn only after the handshake has completed |
1073 | 7.40M | counter_expired && no_current_skip_packet && handshake_completed |
1074 | 7.40M | } |
1075 | | |
1076 | 432k | pub fn skip_pn(&self) -> Option<u64> { |
1077 | 432k | self.skip_pn |
1078 | 432k | } |
1079 | | |
1080 | 2.27k | pub fn set_skip_pn(&mut self, skip_pn: Option<u64>) { |
1081 | 2.27k | if skip_pn.is_some() { |
1082 | | // Never overwrite skip_pn until the previous one has been verified |
1083 | 1.79k | debug_assert!(self.skip_pn.is_none()); |
1084 | | // The skip_pn_counter should be expired |
1085 | 1.79k | debug_assert_eq!(self.skip_pn_counter.unwrap(), 0); |
1086 | 482 | } |
1087 | | |
1088 | 2.27k | self.skip_pn = skip_pn; |
1089 | | // unset the counter |
1090 | 2.27k | self.skip_pn_counter = None; |
1091 | 2.27k | } |
1092 | | |
1093 | | // Dynamically vary the skip counter based on the CWND. |
1094 | 23.4k | fn arm_skip_counter(&mut self, cwnd: usize, max_datagram_size: usize) { |
1095 | 23.4k | let packets_per_cwnd = (cwnd / max_datagram_size) as u64; |
1096 | 23.4k | let lower = packets_per_cwnd / 2; |
1097 | 23.4k | let upper = packets_per_cwnd * 2; |
1098 | | // rand_u64_uniform requires a non-zero value so add 1 |
1099 | 23.4k | let skip_range = upper - lower + 1; |
1100 | 23.4k | let rand_skip_value = rand::rand_u64_uniform(skip_range); |
1101 | | |
1102 | | // Skip calculation: |
1103 | | // skip_counter = min_skip |
1104 | | // + lower |
1105 | | // + rand(skip_range.lower, skip_range.upper) |
1106 | | // |
1107 | | //``` |
1108 | | // c: the current packet number |
1109 | | // s: range of random packet number to skip from |
1110 | | // |
1111 | | // curr_pn |
1112 | | // | |
1113 | | // v |--- (upper - lower) ---| |
1114 | | // [c x x x x x x x x s s s s s s s s s s s s s x x] |
1115 | | // |--min_skip---| |------skip_range-------| |
1116 | | // |
1117 | | //``` |
1118 | 23.4k | let skip_pn_counter = MIN_SKIP_COUNTER_VALUE + lower + rand_skip_value; |
1119 | | |
1120 | 23.4k | self.skip_pn_counter = Some(skip_pn_counter); |
1121 | 23.4k | } |
1122 | | } |
1123 | | |
1124 | | #[derive(Clone, Copy, Default)] |
1125 | | pub struct PktNumWindow { |
1126 | | lower: u64, |
1127 | | window: u128, |
1128 | | } |
1129 | | |
1130 | | impl PktNumWindow { |
1131 | 1.90M | pub fn insert(&mut self, seq: u64) { |
1132 | | // Packet is on the left end of the window. |
1133 | 1.90M | if seq < self.lower { |
1134 | 0 | return; |
1135 | 1.90M | } |
1136 | | |
1137 | | // Packet is on the right end of the window. |
1138 | 1.90M | if seq > self.upper() { |
1139 | 1.52M | let diff = seq - self.upper(); |
1140 | 1.52M | self.lower += diff; |
1141 | 1.52M | |
1142 | 1.52M | self.window = self.window.checked_shl(diff as u32).unwrap_or(0); |
1143 | 1.52M | } |
1144 | | |
1145 | 1.90M | let mask = 1_u128 << (self.upper() - seq); |
1146 | 1.90M | self.window |= mask; |
1147 | 1.90M | } |
1148 | | |
1149 | 2.39M | pub fn contains(&mut self, seq: u64) -> bool { |
1150 | | // Packet is on the right end of the window. |
1151 | 2.39M | if seq > self.upper() { |
1152 | 1.53M | return false; |
1153 | 868k | } |
1154 | | |
1155 | | // Packet is on the left end of the window. |
1156 | 868k | if seq < self.lower { |
1157 | 65.4k | return true; |
1158 | 803k | } |
1159 | | |
1160 | 803k | let mask = 1_u128 << (self.upper() - seq); |
1161 | 803k | self.window & mask != 0 |
1162 | 2.39M | } |
1163 | | |
1164 | 8.53M | fn upper(&self) -> u64 { |
1165 | 8.53M | self.lower.saturating_add(size_of::<u128>() as u64 * 8) - 1 |
1166 | 8.53M | } |
1167 | | } |
1168 | | |
1169 | | #[cfg(test)] |
1170 | | mod tests { |
1171 | | use super::*; |
1172 | | use crate::test_utils; |
1173 | | use crate::MAX_SEND_UDP_PAYLOAD_SIZE; |
1174 | | |
1175 | | #[test] |
1176 | | fn retry() { |
1177 | | let hdr = Header { |
1178 | | ty: Type::Retry, |
1179 | | version: 0xafafafaf, |
1180 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1181 | | .into(), |
1182 | | scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(), |
1183 | | pkt_num: 0, |
1184 | | pkt_num_len: 0, |
1185 | | token: Some(vec![0xba; 24]), |
1186 | | versions: None, |
1187 | | key_phase: false, |
1188 | | }; |
1189 | | |
1190 | | let mut d = [0; 63]; |
1191 | | |
1192 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1193 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1194 | | |
1195 | | // Add fake retry integrity token. |
1196 | | b.put_bytes(&[0xba; 16]).unwrap(); |
1197 | | |
1198 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1199 | | assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr); |
1200 | | } |
1201 | | |
1202 | | #[test] |
1203 | | fn initial() { |
1204 | | let hdr = Header { |
1205 | | ty: Type::Initial, |
1206 | | version: 0xafafafaf, |
1207 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1208 | | .into(), |
1209 | | scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(), |
1210 | | pkt_num: 0, |
1211 | | pkt_num_len: 0, |
1212 | | token: Some(vec![0x05, 0x06, 0x07, 0x08]), |
1213 | | versions: None, |
1214 | | key_phase: false, |
1215 | | }; |
1216 | | |
1217 | | let mut d = [0; 50]; |
1218 | | |
1219 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1220 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1221 | | |
1222 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1223 | | assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr); |
1224 | | } |
1225 | | |
1226 | | #[test] |
1227 | | fn initial_v1_dcid_too_long() { |
1228 | | let hdr = Header { |
1229 | | ty: Type::Initial, |
1230 | | version: crate::PROTOCOL_VERSION, |
1231 | | dcid: vec![ |
1232 | | 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, |
1233 | | 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, |
1234 | | ] |
1235 | | .into(), |
1236 | | scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(), |
1237 | | pkt_num: 0, |
1238 | | pkt_num_len: 0, |
1239 | | token: Some(vec![0x05, 0x06, 0x07, 0x08]), |
1240 | | versions: None, |
1241 | | key_phase: false, |
1242 | | }; |
1243 | | |
1244 | | let mut d = [0; 50]; |
1245 | | |
1246 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1247 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1248 | | |
1249 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1250 | | assert_eq!(Header::from_bytes(&mut b, 21), Err(Error::InvalidPacket)); |
1251 | | } |
1252 | | |
1253 | | #[test] |
1254 | | fn initial_v1_scid_too_long() { |
1255 | | let hdr = Header { |
1256 | | ty: Type::Initial, |
1257 | | version: crate::PROTOCOL_VERSION, |
1258 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1259 | | .into(), |
1260 | | scid: vec![ |
1261 | | 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, |
1262 | | 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, |
1263 | | ] |
1264 | | .into(), |
1265 | | pkt_num: 0, |
1266 | | pkt_num_len: 0, |
1267 | | token: Some(vec![0x05, 0x06, 0x07, 0x08]), |
1268 | | versions: None, |
1269 | | key_phase: false, |
1270 | | }; |
1271 | | |
1272 | | let mut d = [0; 50]; |
1273 | | |
1274 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1275 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1276 | | |
1277 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1278 | | assert_eq!(Header::from_bytes(&mut b, 9), Err(Error::InvalidPacket)); |
1279 | | } |
1280 | | |
1281 | | #[test] |
1282 | | fn initial_non_v1_scid_long() { |
1283 | | let hdr = Header { |
1284 | | ty: Type::Initial, |
1285 | | version: 0xafafafaf, |
1286 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1287 | | .into(), |
1288 | | scid: vec![ |
1289 | | 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, |
1290 | | 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, |
1291 | | ] |
1292 | | .into(), |
1293 | | pkt_num: 0, |
1294 | | pkt_num_len: 0, |
1295 | | token: Some(vec![0x05, 0x06, 0x07, 0x08]), |
1296 | | versions: None, |
1297 | | key_phase: false, |
1298 | | }; |
1299 | | |
1300 | | let mut d = [0; 50]; |
1301 | | |
1302 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1303 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1304 | | |
1305 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1306 | | assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr); |
1307 | | } |
1308 | | |
1309 | | #[test] |
1310 | | fn handshake() { |
1311 | | let hdr = Header { |
1312 | | ty: Type::Handshake, |
1313 | | version: 0xafafafaf, |
1314 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1315 | | .into(), |
1316 | | scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(), |
1317 | | pkt_num: 0, |
1318 | | pkt_num_len: 0, |
1319 | | token: None, |
1320 | | versions: None, |
1321 | | key_phase: false, |
1322 | | }; |
1323 | | |
1324 | | let mut d = [0; 50]; |
1325 | | |
1326 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1327 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1328 | | |
1329 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1330 | | assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr); |
1331 | | } |
1332 | | |
1333 | | #[test] |
1334 | | fn application() { |
1335 | | let hdr = Header { |
1336 | | ty: Type::Short, |
1337 | | version: 0, |
1338 | | dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba] |
1339 | | .into(), |
1340 | | scid: ConnectionId::default(), |
1341 | | pkt_num: 0, |
1342 | | pkt_num_len: 0, |
1343 | | token: None, |
1344 | | versions: None, |
1345 | | key_phase: false, |
1346 | | }; |
1347 | | |
1348 | | let mut d = [0; 50]; |
1349 | | |
1350 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1351 | | assert!(hdr.to_bytes(&mut b).is_ok()); |
1352 | | |
1353 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1354 | | assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr); |
1355 | | } |
1356 | | |
1357 | | #[test] |
1358 | | fn pkt_num_encode_decode() { |
1359 | | let num_len = pkt_num_len(0, 0); |
1360 | | assert_eq!(num_len, 1); |
1361 | | let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2); |
1362 | | assert_eq!(pn, 0xa82f9b32); |
1363 | | let mut d = [0; 10]; |
1364 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1365 | | let num_len = pkt_num_len(0xac5c02, 0xabe8b3); |
1366 | | assert_eq!(num_len, 2); |
1367 | | encode_pkt_num(0xac5c02, num_len, &mut b).unwrap(); |
1368 | | // reading |
1369 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1370 | | let hdr_num = u64::from(b.get_u16().unwrap()); |
1371 | | let pn = decode_pkt_num(0xac5c01, hdr_num, num_len); |
1372 | | assert_eq!(pn, 0xac5c02); |
1373 | | // sending 0xace8fe while having 0xabe8b3 acked |
1374 | | let num_len = pkt_num_len(0xace9fe, 0xabe8b3); |
1375 | | assert_eq!(num_len, 3); |
1376 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1377 | | encode_pkt_num(0xace9fe, num_len, &mut b).unwrap(); |
1378 | | // reading |
1379 | | let mut b = octets::OctetsMut::with_slice(&mut d); |
1380 | | let hdr_num = u64::from(b.get_u24().unwrap()); |
1381 | | let pn = decode_pkt_num(0xace9fa, hdr_num, num_len); |
1382 | | assert_eq!(pn, 0xace9fe); |
1383 | | // roundtrip |
1384 | | let base = 0xdeadbeef; |
1385 | | for i in 1..255 { |
1386 | | let pn = base + i; |
1387 | | let num_len = pkt_num_len(pn, base); |
1388 | | if num_len == 1 { |
1389 | | let decoded = decode_pkt_num(base, pn & 0xff, num_len); |
1390 | | assert_eq!(decoded, pn); |
1391 | | } else { |
1392 | | assert_eq!(num_len, 2); |
1393 | | let decoded = decode_pkt_num(base, pn & 0xffff, num_len); |
1394 | | assert_eq!(decoded, pn); |
1395 | | } |
1396 | | } |
1397 | | } |
1398 | | |
1399 | | #[test] |
1400 | | fn pkt_num_window() { |
1401 | | let mut win = PktNumWindow::default(); |
1402 | | assert_eq!(win.lower, 0); |
1403 | | assert!(!win.contains(0)); |
1404 | | assert!(!win.contains(1)); |
1405 | | |
1406 | | win.insert(0); |
1407 | | assert_eq!(win.lower, 0); |
1408 | | assert!(win.contains(0)); |
1409 | | assert!(!win.contains(1)); |
1410 | | |
1411 | | win.insert(1); |
1412 | | assert_eq!(win.lower, 0); |
1413 | | assert!(win.contains(0)); |
1414 | | assert!(win.contains(1)); |
1415 | | |
1416 | | win.insert(3); |
1417 | | assert_eq!(win.lower, 0); |
1418 | | assert!(win.contains(0)); |
1419 | | assert!(win.contains(1)); |
1420 | | assert!(!win.contains(2)); |
1421 | | assert!(win.contains(3)); |
1422 | | |
1423 | | win.insert(10); |
1424 | | assert_eq!(win.lower, 0); |
1425 | | assert!(win.contains(0)); |
1426 | | assert!(win.contains(1)); |
1427 | | assert!(!win.contains(2)); |
1428 | | assert!(win.contains(3)); |
1429 | | assert!(!win.contains(4)); |
1430 | | assert!(!win.contains(5)); |
1431 | | assert!(!win.contains(6)); |
1432 | | assert!(!win.contains(7)); |
1433 | | assert!(!win.contains(8)); |
1434 | | assert!(!win.contains(9)); |
1435 | | assert!(win.contains(10)); |
1436 | | |
1437 | | win.insert(132); |
1438 | | assert_eq!(win.lower, 5); |
1439 | | assert!(win.contains(0)); |
1440 | | assert!(win.contains(1)); |
1441 | | assert!(win.contains(2)); |
1442 | | assert!(win.contains(3)); |
1443 | | assert!(win.contains(4)); |
1444 | | assert!(!win.contains(5)); |
1445 | | assert!(!win.contains(6)); |
1446 | | assert!(!win.contains(7)); |
1447 | | assert!(!win.contains(8)); |
1448 | | assert!(!win.contains(9)); |
1449 | | assert!(win.contains(10)); |
1450 | | assert!(!win.contains(128)); |
1451 | | assert!(!win.contains(130)); |
1452 | | assert!(!win.contains(131)); |
1453 | | assert!(win.contains(132)); |
1454 | | |
1455 | | win.insert(1024); |
1456 | | assert_eq!(win.lower, 897); |
1457 | | assert!(win.contains(0)); |
1458 | | assert!(win.contains(1)); |
1459 | | assert!(win.contains(2)); |
1460 | | assert!(win.contains(3)); |
1461 | | assert!(win.contains(4)); |
1462 | | assert!(win.contains(5)); |
1463 | | assert!(win.contains(6)); |
1464 | | assert!(win.contains(7)); |
1465 | | assert!(win.contains(8)); |
1466 | | assert!(win.contains(9)); |
1467 | | assert!(win.contains(10)); |
1468 | | assert!(win.contains(128)); |
1469 | | assert!(win.contains(130)); |
1470 | | assert!(win.contains(132)); |
1471 | | assert!(win.contains(896)); |
1472 | | assert!(!win.contains(897)); |
1473 | | assert!(!win.contains(1022)); |
1474 | | assert!(!win.contains(1023)); |
1475 | | assert!(win.contains(1024)); |
1476 | | assert!(!win.contains(1025)); |
1477 | | assert!(!win.contains(1026)); |
1478 | | |
1479 | | win.insert(u64::MAX - 1); |
1480 | | assert!(win.contains(0)); |
1481 | | assert!(win.contains(1)); |
1482 | | assert!(win.contains(2)); |
1483 | | assert!(win.contains(3)); |
1484 | | assert!(win.contains(4)); |
1485 | | assert!(win.contains(5)); |
1486 | | assert!(win.contains(6)); |
1487 | | assert!(win.contains(7)); |
1488 | | assert!(win.contains(8)); |
1489 | | assert!(win.contains(9)); |
1490 | | assert!(win.contains(10)); |
1491 | | assert!(win.contains(128)); |
1492 | | assert!(win.contains(130)); |
1493 | | assert!(win.contains(132)); |
1494 | | assert!(win.contains(896)); |
1495 | | assert!(win.contains(897)); |
1496 | | assert!(win.contains(1022)); |
1497 | | assert!(win.contains(1023)); |
1498 | | assert!(win.contains(1024)); |
1499 | | assert!(win.contains(1025)); |
1500 | | assert!(win.contains(1026)); |
1501 | | assert!(!win.contains(u64::MAX - 2)); |
1502 | | assert!(win.contains(u64::MAX - 1)); |
1503 | | } |
1504 | | |
1505 | | fn assert_decrypt_initial_pkt( |
1506 | | pkt: &mut [u8], dcid: &[u8], is_server: bool, expected_frames: &[u8], |
1507 | | expected_pn: u64, expected_pn_len: usize, |
1508 | | ) { |
1509 | | let mut b = octets::OctetsMut::with_slice(pkt); |
1510 | | |
1511 | | let mut hdr = Header::from_bytes(&mut b, 0).unwrap(); |
1512 | | assert_eq!(hdr.ty, Type::Initial); |
1513 | | |
1514 | | let payload_len = b.get_varint().unwrap() as usize; |
1515 | | |
1516 | | let (aead, _) = crypto::derive_initial_key_material( |
1517 | | dcid, |
1518 | | hdr.version, |
1519 | | is_server, |
1520 | | false, |
1521 | | ) |
1522 | | .unwrap(); |
1523 | | |
1524 | | decrypt_hdr(&mut b, &mut hdr, &aead).unwrap(); |
1525 | | assert_eq!(hdr.pkt_num_len, expected_pn_len); |
1526 | | |
1527 | | let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len); |
1528 | | assert_eq!(pn, expected_pn); |
1529 | | |
1530 | | let payload = |
1531 | | decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap(); |
1532 | | |
1533 | | let payload = payload.as_ref(); |
1534 | | assert_eq!(&payload[..expected_frames.len()], expected_frames); |
1535 | | } |
1536 | | |
1537 | | #[test] |
1538 | | fn decrypt_client_initial_v1() { |
1539 | | let mut pkt = [ |
1540 | | 0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, |
1541 | | 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34, |
1542 | | 0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2, |
1543 | | 0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d, |
1544 | | 0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27, |
1545 | | 0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26, |
1546 | | 0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b, |
1547 | | 0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad, |
1548 | | 0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53, |
1549 | | 0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa, |
1550 | | 0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00, |
1551 | | 0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11, |
1552 | | 0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff, |
1553 | | 0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e, |
1554 | | 0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0, |
1555 | | 0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15, |
1556 | | 0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe, |
1557 | | 0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06, |
1558 | | 0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62, |
1559 | | 0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48, |
1560 | | 0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e, |
1561 | | 0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a, |
1562 | | 0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1, |
1563 | | 0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3, |
1564 | | 0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc, |
1565 | | 0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38, |
1566 | | 0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64, |
1567 | | 0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda, |
1568 | | 0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae, |
1569 | | 0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b, |
1570 | | 0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9, |
1571 | | 0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8, |
1572 | | 0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a, |
1573 | | 0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26, |
1574 | | 0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe, |
1575 | | 0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50, |
1576 | | 0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d, |
1577 | | 0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44, |
1578 | | 0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49, |
1579 | | 0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8, |
1580 | | 0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90, |
1581 | | 0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c, |
1582 | | 0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c, |
1583 | | 0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e, |
1584 | | 0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a, |
1585 | | 0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b, |
1586 | | 0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82, |
1587 | | 0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf, |
1588 | | 0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69, |
1589 | | 0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8, |
1590 | | 0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57, |
1591 | | 0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2, |
1592 | | 0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55, |
1593 | | 0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79, |
1594 | | 0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5, |
1595 | | 0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46, |
1596 | | 0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76, |
1597 | | 0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11, |
1598 | | 0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a, |
1599 | | 0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f, |
1600 | | 0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09, |
1601 | | 0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3, |
1602 | | 0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36, |
1603 | | 0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73, |
1604 | | 0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4, |
1605 | | 0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c, |
1606 | | 0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb, |
1607 | | 0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63, |
1608 | | 0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d, |
1609 | | 0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60, |
1610 | | 0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56, |
1611 | | 0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06, |
1612 | | 0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb, |
1613 | | 0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5, |
1614 | | 0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f, |
1615 | | 0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10, |
1616 | | 0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13, |
1617 | | 0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3, |
1618 | | 0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f, |
1619 | | 0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5, |
1620 | | 0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda, |
1621 | | 0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12, |
1622 | | 0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd, |
1623 | | 0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6, |
1624 | | 0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50, |
1625 | | 0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab, |
1626 | | 0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a, |
1627 | | 0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1, |
1628 | | 0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52, |
1629 | | 0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f, |
1630 | | 0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2, |
1631 | | 0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8, |
1632 | | 0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94, |
1633 | | 0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5, |
1634 | | 0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a, |
1635 | | 0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab, |
1636 | | 0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8, |
1637 | | 0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d, |
1638 | | 0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9, |
1639 | | 0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3, |
1640 | | 0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf, |
1641 | | 0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d, |
1642 | | 0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa, |
1643 | | 0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4, |
1644 | | 0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf, |
1645 | | 0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c, |
1646 | | 0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88, |
1647 | | 0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd, |
1648 | | 0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47, |
1649 | | 0x88, |
1650 | | ]; |
1651 | | |
1652 | | let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08]; |
1653 | | |
1654 | | let frames = [ |
1655 | | 0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb, |
1656 | | 0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96, |
1657 | | 0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04, |
1658 | | 0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00, |
1659 | | 0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, |
1660 | | 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d, |
1661 | | 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01, |
1662 | | 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, |
1663 | | 0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c, |
1664 | | 0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, |
1665 | | 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93, |
1666 | | 0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f, |
1667 | | 0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c, |
1668 | | 0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b, |
1669 | | 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e, |
1670 | | 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08, |
1671 | | 0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c, |
1672 | | 0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff, |
1673 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00, |
1674 | | 0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10, |
1675 | | 0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08, |
1676 | | 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80, |
1677 | | 0x00, 0xff, 0xff, |
1678 | | ]; |
1679 | | |
1680 | | assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4); |
1681 | | } |
1682 | | |
1683 | | #[test] |
1684 | | fn decrypt_server_initial_v1() { |
1685 | | let mut pkt = [ |
1686 | | 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, |
1687 | | 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48, |
1688 | | 0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58, |
1689 | | 0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75, |
1690 | | 0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c, |
1691 | | 0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb, |
1692 | | 0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e, |
1693 | | 0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde, |
1694 | | 0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e, |
1695 | | 0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a, |
1696 | | 0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20, |
1697 | | 0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d, |
1698 | | 0xd0, 0x74, 0xee, |
1699 | | ]; |
1700 | | |
1701 | | let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08]; |
1702 | | |
1703 | | let frames = [ |
1704 | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00, |
1705 | | 0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1, |
1706 | | 0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88, |
1707 | | 0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a, |
1708 | | 0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, |
1709 | | 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89, |
1710 | | 0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca, |
1711 | | 0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc, |
1712 | | 0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, |
1713 | | ]; |
1714 | | |
1715 | | assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2); |
1716 | | } |
1717 | | |
1718 | | #[test] |
1719 | | fn decrypt_chacha20() { |
1720 | | let secret = [ |
1721 | | 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42, |
1722 | | 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0, |
1723 | | 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b, |
1724 | | ]; |
1725 | | |
1726 | | let mut pkt = [ |
1727 | | 0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6, |
1728 | | 0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb, |
1729 | | ]; |
1730 | | |
1731 | | let mut b = octets::OctetsMut::with_slice(&mut pkt); |
1732 | | |
1733 | | let alg = crypto::Algorithm::ChaCha20_Poly1305; |
1734 | | |
1735 | | let aead = crypto::Open::from_secret(alg, &secret).unwrap(); |
1736 | | |
1737 | | let mut hdr = Header::from_bytes(&mut b, 0).unwrap(); |
1738 | | assert_eq!(hdr.ty, Type::Short); |
1739 | | |
1740 | | let payload_len = b.cap(); |
1741 | | |
1742 | | decrypt_hdr(&mut b, &mut hdr, &aead).unwrap(); |
1743 | | assert_eq!(hdr.pkt_num_len, 3); |
1744 | | |
1745 | | let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len); |
1746 | | assert_eq!(pn, 654_360_564); |
1747 | | |
1748 | | let payload = |
1749 | | decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap(); |
1750 | | |
1751 | | let payload = payload.as_ref(); |
1752 | | assert_eq!(&payload, &[0x01]); |
1753 | | } |
1754 | | |
1755 | | fn assert_encrypt_initial_pkt( |
1756 | | header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize, |
1757 | | is_server: bool, expected_pkt: &[u8], |
1758 | | ) { |
1759 | | let mut b = octets::OctetsMut::with_slice(header); |
1760 | | |
1761 | | let hdr = Header::from_bytes(&mut b, 0).unwrap(); |
1762 | | assert_eq!(hdr.ty, Type::Initial); |
1763 | | |
1764 | | let mut out = vec![0; expected_pkt.len()]; |
1765 | | let mut b = octets::OctetsMut::with_slice(&mut out); |
1766 | | |
1767 | | b.put_bytes(header).unwrap(); |
1768 | | |
1769 | | let (_, aead) = crypto::derive_initial_key_material( |
1770 | | dcid, |
1771 | | hdr.version, |
1772 | | is_server, |
1773 | | false, |
1774 | | ) |
1775 | | .unwrap(); |
1776 | | |
1777 | | let payload_len = frames.len(); |
1778 | | |
1779 | | let payload_offset = b.off(); |
1780 | | |
1781 | | b.put_bytes(frames).unwrap(); |
1782 | | |
1783 | | let written = encrypt_pkt( |
1784 | | &mut b, |
1785 | | pn, |
1786 | | pn_len, |
1787 | | payload_len, |
1788 | | payload_offset, |
1789 | | None, |
1790 | | &aead, |
1791 | | ) |
1792 | | .unwrap(); |
1793 | | |
1794 | | assert_eq!(written, expected_pkt.len()); |
1795 | | assert_eq!(&out[..written], expected_pkt); |
1796 | | } |
1797 | | |
1798 | | #[test] |
1799 | | fn encrypt_client_initial_v1() { |
1800 | | let mut header = [ |
1801 | | 0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, |
1802 | | 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02, |
1803 | | ]; |
1804 | | |
1805 | | let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08]; |
1806 | | |
1807 | | let frames = [ |
1808 | | 0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb, |
1809 | | 0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96, |
1810 | | 0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04, |
1811 | | 0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00, |
1812 | | 0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, |
1813 | | 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d, |
1814 | | 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01, |
1815 | | 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, |
1816 | | 0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c, |
1817 | | 0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, |
1818 | | 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93, |
1819 | | 0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f, |
1820 | | 0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c, |
1821 | | 0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b, |
1822 | | 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e, |
1823 | | 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08, |
1824 | | 0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c, |
1825 | | 0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff, |
1826 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00, |
1827 | | 0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10, |
1828 | | 0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08, |
1829 | | 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80, |
1830 | | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1831 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1832 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1833 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1834 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1835 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1836 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1837 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1838 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1839 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1840 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1841 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1842 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1843 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1844 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1845 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1846 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1847 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1848 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1849 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1850 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1851 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1852 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1853 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1854 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1855 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1856 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1857 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1858 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1859 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1860 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1861 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1862 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1863 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1864 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1865 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1866 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1867 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1868 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1869 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1870 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1871 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1872 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1873 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1874 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1875 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1876 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1877 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1878 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1879 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1880 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1881 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1882 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1883 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1884 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1885 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1886 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1887 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1888 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1889 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1890 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1891 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1892 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1893 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1894 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1895 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1896 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1897 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1898 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1899 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1900 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1901 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1902 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1903 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1904 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1905 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1906 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1907 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1908 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1909 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1910 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1911 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1912 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1913 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1914 | | ]; |
1915 | | |
1916 | | let pkt = [ |
1917 | | 0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, |
1918 | | 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34, |
1919 | | 0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2, |
1920 | | 0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d, |
1921 | | 0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27, |
1922 | | 0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26, |
1923 | | 0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b, |
1924 | | 0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad, |
1925 | | 0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53, |
1926 | | 0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa, |
1927 | | 0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00, |
1928 | | 0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11, |
1929 | | 0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff, |
1930 | | 0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e, |
1931 | | 0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0, |
1932 | | 0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15, |
1933 | | 0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe, |
1934 | | 0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06, |
1935 | | 0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62, |
1936 | | 0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48, |
1937 | | 0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e, |
1938 | | 0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a, |
1939 | | 0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1, |
1940 | | 0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3, |
1941 | | 0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc, |
1942 | | 0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38, |
1943 | | 0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64, |
1944 | | 0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda, |
1945 | | 0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae, |
1946 | | 0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b, |
1947 | | 0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9, |
1948 | | 0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8, |
1949 | | 0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a, |
1950 | | 0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26, |
1951 | | 0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe, |
1952 | | 0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50, |
1953 | | 0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d, |
1954 | | 0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44, |
1955 | | 0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49, |
1956 | | 0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8, |
1957 | | 0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90, |
1958 | | 0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c, |
1959 | | 0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c, |
1960 | | 0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e, |
1961 | | 0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a, |
1962 | | 0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b, |
1963 | | 0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82, |
1964 | | 0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf, |
1965 | | 0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69, |
1966 | | 0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8, |
1967 | | 0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57, |
1968 | | 0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2, |
1969 | | 0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55, |
1970 | | 0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79, |
1971 | | 0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5, |
1972 | | 0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46, |
1973 | | 0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76, |
1974 | | 0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11, |
1975 | | 0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a, |
1976 | | 0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f, |
1977 | | 0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09, |
1978 | | 0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3, |
1979 | | 0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36, |
1980 | | 0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73, |
1981 | | 0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4, |
1982 | | 0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c, |
1983 | | 0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb, |
1984 | | 0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63, |
1985 | | 0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d, |
1986 | | 0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60, |
1987 | | 0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56, |
1988 | | 0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06, |
1989 | | 0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb, |
1990 | | 0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5, |
1991 | | 0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f, |
1992 | | 0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10, |
1993 | | 0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13, |
1994 | | 0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3, |
1995 | | 0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f, |
1996 | | 0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5, |
1997 | | 0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda, |
1998 | | 0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12, |
1999 | | 0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd, |
2000 | | 0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6, |
2001 | | 0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50, |
2002 | | 0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab, |
2003 | | 0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a, |
2004 | | 0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1, |
2005 | | 0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52, |
2006 | | 0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f, |
2007 | | 0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2, |
2008 | | 0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8, |
2009 | | 0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94, |
2010 | | 0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5, |
2011 | | 0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a, |
2012 | | 0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab, |
2013 | | 0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8, |
2014 | | 0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d, |
2015 | | 0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9, |
2016 | | 0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3, |
2017 | | 0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf, |
2018 | | 0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d, |
2019 | | 0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa, |
2020 | | 0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4, |
2021 | | 0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf, |
2022 | | 0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c, |
2023 | | 0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88, |
2024 | | 0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd, |
2025 | | 0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47, |
2026 | | 0x88, |
2027 | | ]; |
2028 | | |
2029 | | assert_encrypt_initial_pkt( |
2030 | | &mut header, |
2031 | | &dcid, |
2032 | | &frames, |
2033 | | 2, |
2034 | | 4, |
2035 | | false, |
2036 | | &pkt, |
2037 | | ); |
2038 | | } |
2039 | | |
2040 | | #[test] |
2041 | | fn encrypt_server_initial_v1() { |
2042 | | let mut header = [ |
2043 | | 0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, |
2044 | | 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01, |
2045 | | ]; |
2046 | | |
2047 | | let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08]; |
2048 | | |
2049 | | let frames = [ |
2050 | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00, |
2051 | | 0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1, |
2052 | | 0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88, |
2053 | | 0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a, |
2054 | | 0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, |
2055 | | 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89, |
2056 | | 0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca, |
2057 | | 0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc, |
2058 | | 0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, |
2059 | | ]; |
2060 | | |
2061 | | let pkt = [ |
2062 | | 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, |
2063 | | 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48, |
2064 | | 0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58, |
2065 | | 0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75, |
2066 | | 0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c, |
2067 | | 0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb, |
2068 | | 0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e, |
2069 | | 0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde, |
2070 | | 0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e, |
2071 | | 0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a, |
2072 | | 0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20, |
2073 | | 0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d, |
2074 | | 0xd0, 0x74, 0xee, |
2075 | | ]; |
2076 | | |
2077 | | assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt); |
2078 | | } |
2079 | | |
2080 | | #[test] |
2081 | | fn encrypt_chacha20() { |
2082 | | let secret = [ |
2083 | | 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42, |
2084 | | 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0, |
2085 | | 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b, |
2086 | | ]; |
2087 | | |
2088 | | let mut header = [0x42, 0x00, 0xbf, 0xf4]; |
2089 | | |
2090 | | let expected_pkt = [ |
2091 | | 0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6, |
2092 | | 0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb, |
2093 | | ]; |
2094 | | |
2095 | | let mut b = octets::OctetsMut::with_slice(&mut header); |
2096 | | |
2097 | | let hdr = Header::from_bytes(&mut b, 0).unwrap(); |
2098 | | assert_eq!(hdr.ty, Type::Short); |
2099 | | |
2100 | | let mut out = vec![0; expected_pkt.len()]; |
2101 | | let mut b = octets::OctetsMut::with_slice(&mut out); |
2102 | | |
2103 | | b.put_bytes(&header).unwrap(); |
2104 | | |
2105 | | let alg = crypto::Algorithm::ChaCha20_Poly1305; |
2106 | | |
2107 | | let aead = crypto::Seal::from_secret(alg, &secret).unwrap(); |
2108 | | |
2109 | | let pn = 654_360_564; |
2110 | | let pn_len = 3; |
2111 | | |
2112 | | let frames = [0x01]; |
2113 | | |
2114 | | let payload_len = frames.len(); |
2115 | | |
2116 | | let payload_offset = b.off(); |
2117 | | |
2118 | | b.put_bytes(&frames).unwrap(); |
2119 | | |
2120 | | let written = encrypt_pkt( |
2121 | | &mut b, |
2122 | | pn, |
2123 | | pn_len, |
2124 | | payload_len, |
2125 | | payload_offset, |
2126 | | None, |
2127 | | &aead, |
2128 | | ) |
2129 | | .unwrap(); |
2130 | | |
2131 | | assert_eq!(written, expected_pkt.len()); |
2132 | | assert_eq!(&out[..written], &expected_pkt[..]); |
2133 | | } |
2134 | | |
2135 | | #[test] |
2136 | | fn decrypt_pkt_underflow() { |
2137 | | let mut buf = [0; 65535]; |
2138 | | let mut b = octets::OctetsMut::with_slice(&mut buf); |
2139 | | |
2140 | | let hdr = Header { |
2141 | | ty: Type::Initial, |
2142 | | version: crate::PROTOCOL_VERSION, |
2143 | | dcid: ConnectionId::default(), |
2144 | | scid: ConnectionId::default(), |
2145 | | pkt_num: 0, |
2146 | | pkt_num_len: 0, |
2147 | | token: None, |
2148 | | versions: None, |
2149 | | key_phase: false, |
2150 | | }; |
2151 | | |
2152 | | hdr.to_bytes(&mut b).unwrap(); |
2153 | | |
2154 | | b.put_bytes(&[0; 50]).unwrap(); |
2155 | | |
2156 | | let payload_len = b.get_varint().unwrap() as usize; |
2157 | | |
2158 | | let (aead, _) = |
2159 | | crypto::derive_initial_key_material(b"", hdr.version, true, false) |
2160 | | .unwrap(); |
2161 | | |
2162 | | assert_eq!( |
2163 | | decrypt_pkt(&mut b, 0, 1, payload_len, &aead), |
2164 | | Err(Error::InvalidPacket) |
2165 | | ); |
2166 | | } |
2167 | | |
2168 | | #[test] |
2169 | | fn decrypt_pkt_too_small() { |
2170 | | let mut buf = [0; 65535]; |
2171 | | let mut b = octets::OctetsMut::with_slice(&mut buf); |
2172 | | |
2173 | | let hdr = Header { |
2174 | | ty: Type::Initial, |
2175 | | version: crate::PROTOCOL_VERSION, |
2176 | | dcid: ConnectionId::default(), |
2177 | | scid: ConnectionId::default(), |
2178 | | pkt_num: 0, |
2179 | | pkt_num_len: 0, |
2180 | | token: None, |
2181 | | versions: None, |
2182 | | key_phase: false, |
2183 | | }; |
2184 | | |
2185 | | hdr.to_bytes(&mut b).unwrap(); |
2186 | | |
2187 | | b.put_bytes(&[0; 1]).unwrap(); |
2188 | | |
2189 | | // No space for decryption. |
2190 | | let payload_len = 1; |
2191 | | |
2192 | | let (aead, _) = |
2193 | | crypto::derive_initial_key_material(b"", hdr.version, true, false) |
2194 | | .unwrap(); |
2195 | | |
2196 | | assert_eq!( |
2197 | | decrypt_pkt(&mut b, 0, 1, payload_len, &aead), |
2198 | | Err(Error::CryptoFail) |
2199 | | ); |
2200 | | } |
2201 | | |
2202 | | #[test] |
2203 | | fn track_largest_packet_sent() { |
2204 | | let now = Instant::now(); |
2205 | | let mut pkt_space = PktNumSpace::new(); |
2206 | | |
2207 | | assert!(pkt_space.largest_tx_pkt_num.is_none()); |
2208 | | |
2209 | | let sent_ctx = test_utils::helper_packet_sent(1, now, 10); |
2210 | | pkt_space.on_packet_sent(&sent_ctx); |
2211 | | assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 1); |
2212 | | |
2213 | | let sent_ctx = test_utils::helper_packet_sent(2, now, 10); |
2214 | | pkt_space.on_packet_sent(&sent_ctx); |
2215 | | assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 2); |
2216 | | } |
2217 | | |
2218 | | #[test] |
2219 | | fn skip_pn() { |
2220 | | let mut skip_manager = PktNumManager::new(); |
2221 | | let cwnd = 1000; |
2222 | | let handshake_completed = true; |
2223 | | let mut next_pn = 0; |
2224 | | |
2225 | | assert!(skip_manager.skip_pn.is_none()); |
2226 | | assert!(skip_manager.skip_pn_counter.is_none()); |
2227 | | assert!(!skip_manager.should_skip_pn(handshake_completed)); |
2228 | | |
2229 | | // Arm `skip_pn_counter` |
2230 | | skip_manager.on_packet_sent( |
2231 | | cwnd, |
2232 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2233 | | handshake_completed, |
2234 | | ); |
2235 | | assert_eq!(next_pn, 0); |
2236 | | assert!(skip_manager.skip_pn.is_none()); |
2237 | | assert!(skip_manager.skip_pn_counter.unwrap() >= MIN_SKIP_COUNTER_VALUE); |
2238 | | assert!(!skip_manager.should_skip_pn(handshake_completed)); |
2239 | | |
2240 | | // `should_skip_pn()` should be true once the counter expires |
2241 | | while skip_manager.skip_pn_counter.unwrap() > 0 { |
2242 | | // pretend to send the next packet |
2243 | | next_pn += 1; |
2244 | | |
2245 | | skip_manager.on_packet_sent( |
2246 | | cwnd, |
2247 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2248 | | handshake_completed, |
2249 | | ); |
2250 | | } |
2251 | | assert!(next_pn >= MIN_SKIP_COUNTER_VALUE); |
2252 | | assert!(skip_manager.skip_pn.is_none()); |
2253 | | assert_eq!(skip_manager.skip_pn_counter.unwrap(), 0); |
2254 | | assert!(skip_manager.should_skip_pn(handshake_completed)); |
2255 | | |
2256 | | // skip the next pkt_num |
2257 | | skip_manager.set_skip_pn(Some(next_pn)); |
2258 | | assert_eq!(skip_manager.skip_pn.unwrap(), next_pn); |
2259 | | assert!(skip_manager.skip_pn_counter.is_none()); |
2260 | | assert!(!skip_manager.should_skip_pn(handshake_completed)); |
2261 | | } |
2262 | | |
2263 | | #[test] |
2264 | | fn arm_skip_counter_only_after_verifying_prev_skip_pn() { |
2265 | | let mut skip_manager = PktNumManager::new(); |
2266 | | let cwnd = 1000; |
2267 | | let handshake_completed = true; |
2268 | | |
2269 | | // Set skip pn |
2270 | | skip_manager.skip_pn_counter = Some(0); |
2271 | | skip_manager.set_skip_pn(Some(42)); |
2272 | | assert!(skip_manager.skip_pn.is_some()); |
2273 | | assert!(skip_manager.skip_pn_counter.is_none()); |
2274 | | |
2275 | | // Don't arm the skip_pn_counter since its still armed (0 means |
2276 | | // expired) |
2277 | | skip_manager.on_packet_sent( |
2278 | | cwnd, |
2279 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2280 | | handshake_completed, |
2281 | | ); |
2282 | | assert!(skip_manager.skip_pn.is_some()); |
2283 | | assert!(skip_manager.skip_pn_counter.is_none()); |
2284 | | |
2285 | | // Arm the skip_pn_counter once the skip_pn has been verified |
2286 | | skip_manager.skip_pn = None; |
2287 | | skip_manager.on_packet_sent( |
2288 | | cwnd, |
2289 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2290 | | handshake_completed, |
2291 | | ); |
2292 | | assert!(skip_manager.skip_pn.is_none()); |
2293 | | assert!(skip_manager.skip_pn_counter.is_some()); |
2294 | | } |
2295 | | |
2296 | | #[test] |
2297 | | fn arm_skip_counter_only_after_handshake_complete() { |
2298 | | let mut skip_manager = PktNumManager::new(); |
2299 | | let cwnd = 1000; |
2300 | | skip_manager.skip_pn_counter = None; |
2301 | | |
2302 | | // Don't arm the skip_pn_counter since handshake is not complete |
2303 | | let mut handshake_completed = false; |
2304 | | skip_manager.on_packet_sent( |
2305 | | cwnd, |
2306 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2307 | | handshake_completed, |
2308 | | ); |
2309 | | assert!(skip_manager.skip_pn_counter.is_none()); |
2310 | | |
2311 | | // Arm counter after handshake complete |
2312 | | handshake_completed = true; |
2313 | | skip_manager.on_packet_sent( |
2314 | | cwnd, |
2315 | | MAX_SEND_UDP_PAYLOAD_SIZE, |
2316 | | handshake_completed, |
2317 | | ); |
2318 | | assert!(skip_manager.skip_pn_counter.is_some()); |
2319 | | } |
2320 | | |
2321 | | #[test] |
2322 | | fn only_skip_after_handshake_complete() { |
2323 | | let mut skip_manager = PktNumManager::new(); |
2324 | | skip_manager.skip_pn_counter = Some(0); |
2325 | | |
2326 | | let mut handshake_completed = false; |
2327 | | // Don't skip since handshake is not complete |
2328 | | assert!(!skip_manager.should_skip_pn(handshake_completed)); |
2329 | | |
2330 | | handshake_completed = true; |
2331 | | // Skip pn after handshake complete |
2332 | | assert!(skip_manager.should_skip_pn(handshake_completed)); |
2333 | | } |
2334 | | } |