quiche/
packet.rs

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
27use std::fmt::Display;
28
29use std::ops::Index;
30use std::ops::IndexMut;
31use std::ops::RangeInclusive;
32
33use std::time::Instant;
34
35use crate::Error;
36use crate::Result;
37use crate::DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS;
38
39use crate::crypto;
40use crate::rand;
41use crate::ranges;
42use crate::recovery;
43use crate::stream;
44
45const FORM_BIT: u8 = 0x80;
46const FIXED_BIT: u8 = 0x40;
47const KEY_PHASE_BIT: u8 = 0x04;
48
49const TYPE_MASK: u8 = 0x30;
50const PKT_NUM_MASK: u8 = 0x03;
51
52pub const MAX_CID_LEN: u8 = 20;
53
54pub const MAX_PKT_NUM_LEN: usize = 4;
55
56const SAMPLE_LEN: usize = 16;
57
58// Set the min skip skip interval to 2x the default number of initial packet
59// count.
60const MIN_SKIP_COUNTER_VALUE: u64 =
61    DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS as u64 * 2;
62
63const RETRY_AEAD_ALG: crypto::Algorithm = crypto::Algorithm::AES128_GCM;
64
65#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
66pub enum Epoch {
67    Initial     = 0,
68    Handshake   = 1,
69    Application = 2,
70}
71
72static EPOCHS: [Epoch; 3] =
73    [Epoch::Initial, Epoch::Handshake, Epoch::Application];
74
75impl Epoch {
76    /// Returns an ordered slice containing the `Epoch`s that fit in the
77    /// provided `range`.
78    pub fn epochs(range: RangeInclusive<Epoch>) -> &'static [Epoch] {
79        &EPOCHS[*range.start() as usize..=*range.end() as usize]
80    }
81
82    pub const fn count() -> usize {
83        3
84    }
85}
86
87impl Display for Epoch {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        write!(f, "{}", usize::from(*self))
90    }
91}
92
93impl From<Epoch> for usize {
94    fn from(e: Epoch) -> Self {
95        e as usize
96    }
97}
98
99impl<T> Index<Epoch> for [T]
100where
101    T: Sized,
102{
103    type Output = T;
104
105    fn index(&self, index: Epoch) -> &Self::Output {
106        self.index(usize::from(index))
107    }
108}
109
110impl<T> IndexMut<Epoch> for [T]
111where
112    T: Sized,
113{
114    fn index_mut(&mut self, index: Epoch) -> &mut Self::Output {
115        self.index_mut(usize::from(index))
116    }
117}
118
119/// QUIC packet type.
120#[derive(Clone, Copy, Debug, PartialEq, Eq)]
121pub 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
141impl Type {
142    pub(crate) fn from_epoch(e: Epoch) -> Type {
143        match e {
144            Epoch::Initial => Type::Initial,
145
146            Epoch::Handshake => Type::Handshake,
147
148            Epoch::Application => Type::Short,
149        }
150    }
151
152    pub(crate) fn to_epoch(self) -> Result<Epoch> {
153        match self {
154            Type::Initial => Ok(Epoch::Initial),
155
156            Type::ZeroRTT => Ok(Epoch::Application),
157
158            Type::Handshake => Ok(Epoch::Handshake),
159
160            Type::Short => Ok(Epoch::Application),
161
162            _ => Err(Error::InvalidPacket),
163        }
164    }
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.
186pub struct ConnectionId<'a>(ConnectionIdInner<'a>);
187
188enum ConnectionIdInner<'a> {
189    Vec(Vec<u8>),
190    Ref(&'a [u8]),
191}
192
193impl<'a> ConnectionId<'a> {
194    /// Creates a new connection ID from the given vector.
195    #[inline]
196    pub const fn from_vec(cid: Vec<u8>) -> Self {
197        Self(ConnectionIdInner::Vec(cid))
198    }
199
200    /// Creates a new connection ID from the given slice.
201    #[inline]
202    pub const fn from_ref(cid: &'a [u8]) -> Self {
203        Self(ConnectionIdInner::Ref(cid))
204    }
205
206    /// Returns a new owning connection ID from the given existing one.
207    #[inline]
208    pub fn into_owned(self) -> ConnectionId<'static> {
209        ConnectionId::from_vec(self.into())
210    }
211}
212
213impl Default for ConnectionId<'_> {
214    #[inline]
215    fn default() -> Self {
216        Self::from_vec(Vec::new())
217    }
218}
219
220impl From<Vec<u8>> for ConnectionId<'_> {
221    #[inline]
222    fn from(v: Vec<u8>) -> Self {
223        Self::from_vec(v)
224    }
225}
226
227impl From<ConnectionId<'_>> for Vec<u8> {
228    #[inline]
229    fn from(id: ConnectionId<'_>) -> Self {
230        match id.0 {
231            ConnectionIdInner::Vec(cid) => cid,
232            ConnectionIdInner::Ref(cid) => cid.to_vec(),
233        }
234    }
235}
236
237impl PartialEq for ConnectionId<'_> {
238    #[inline]
239    fn eq(&self, other: &Self) -> bool {
240        self.as_ref() == other.as_ref()
241    }
242}
243
244impl Eq for ConnectionId<'_> {}
245
246impl AsRef<[u8]> for ConnectionId<'_> {
247    #[inline]
248    fn as_ref(&self) -> &[u8] {
249        match &self.0 {
250            ConnectionIdInner::Vec(v) => v.as_ref(),
251            ConnectionIdInner::Ref(v) => v,
252        }
253    }
254}
255
256impl 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
263impl std::ops::Deref for ConnectionId<'_> {
264    type Target = [u8];
265
266    #[inline]
267    fn deref(&self) -> &[u8] {
268        match &self.0 {
269            ConnectionIdInner::Vec(v) => v.as_ref(),
270            ConnectionIdInner::Ref(v) => v,
271        }
272    }
273}
274
275impl Clone for ConnectionId<'_> {
276    #[inline]
277    fn clone(&self) -> Self {
278        Self::from_vec(self.as_ref().to_vec())
279    }
280}
281
282impl std::fmt::Debug for ConnectionId<'_> {
283    #[inline]
284    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
285        for c in self.as_ref() {
286            write!(f, "{c:02x}")?;
287        }
288
289        Ok(())
290    }
291}
292
293/// A QUIC packet's header.
294#[derive(Clone, PartialEq, Eq)]
295pub 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
329impl<'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    pub(crate) fn from_bytes<'b>(
356        b: &'b mut octets::OctetsMut, dcid_len: usize,
357    ) -> Result<Header<'a>> {
358        let first = b.get_u8()?;
359
360        if !Header::is_long(first) {
361            // Decode short header.
362            let dcid = b.get_bytes(dcid_len)?;
363
364            return Ok(Header {
365                ty: Type::Short,
366                version: 0,
367                dcid: dcid.to_vec().into(),
368                scid: ConnectionId::default(),
369                pkt_num: 0,
370                pkt_num_len: 0,
371                token: None,
372                versions: None,
373                key_phase: false,
374            });
375        }
376
377        // Decode long header.
378        let version = b.get_u32()?;
379
380        let ty = if version == 0 {
381            Type::VersionNegotiation
382        } else {
383            match (first & TYPE_MASK) >> 4 {
384                0x00 => Type::Initial,
385                0x01 => Type::ZeroRTT,
386                0x02 => Type::Handshake,
387                0x03 => Type::Retry,
388                _ => return Err(Error::InvalidPacket),
389            }
390        };
391
392        let dcid_len = b.get_u8()?;
393        if crate::version_is_supported(version) && dcid_len > MAX_CID_LEN {
394            return Err(Error::InvalidPacket);
395        }
396        let dcid = b.get_bytes(dcid_len as usize)?.to_vec();
397
398        let scid_len = b.get_u8()?;
399        if crate::version_is_supported(version) && scid_len > MAX_CID_LEN {
400            return Err(Error::InvalidPacket);
401        }
402        let scid = b.get_bytes(scid_len as usize)?.to_vec();
403
404        // End of invariants.
405
406        let mut token: Option<Vec<u8>> = None;
407        let mut versions: Option<Vec<u32>> = None;
408
409        match ty {
410            Type::Initial => {
411                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                if b.cap() < TAG_LEN {
419                    return Err(Error::InvalidPacket);
420                }
421
422                let token_len = b.cap() - TAG_LEN;
423                token = Some(b.get_bytes(token_len)?.to_vec());
424            },
425
426            Type::VersionNegotiation => {
427                let mut list: Vec<u32> = Vec::new();
428
429                while b.cap() > 0 {
430                    let version = b.get_u32()?;
431                    list.push(version);
432                }
433
434                versions = Some(list);
435            },
436
437            _ => (),
438        };
439
440        Ok(Header {
441            ty,
442            version,
443            dcid: dcid.into(),
444            scid: scid.into(),
445            pkt_num: 0,
446            pkt_num_len: 0,
447            token,
448            versions,
449            key_phase: false,
450        })
451    }
452
453    pub(crate) fn to_bytes(&self, out: &mut octets::OctetsMut) -> Result<()> {
454        let mut first = 0;
455
456        // Encode pkt num length.
457        first |= self.pkt_num_len.saturating_sub(1) as u8;
458
459        // Encode short header.
460        if self.ty == Type::Short {
461            // Unset form bit for short header.
462            first &= !FORM_BIT;
463
464            // Set fixed bit.
465            first |= FIXED_BIT;
466
467            // Set key phase bit.
468            if self.key_phase {
469                first |= KEY_PHASE_BIT;
470            } else {
471                first &= !KEY_PHASE_BIT;
472            }
473
474            out.put_u8(first)?;
475            out.put_bytes(&self.dcid)?;
476
477            return Ok(());
478        }
479
480        // Encode long header.
481        let ty: u8 = match self.ty {
482            Type::Initial => 0x00,
483            Type::ZeroRTT => 0x01,
484            Type::Handshake => 0x02,
485            Type::Retry => 0x03,
486            _ => return Err(Error::InvalidPacket),
487        };
488
489        first |= FORM_BIT | FIXED_BIT | (ty << 4);
490
491        out.put_u8(first)?;
492
493        out.put_u32(self.version)?;
494
495        out.put_u8(self.dcid.len() as u8)?;
496        out.put_bytes(&self.dcid)?;
497
498        out.put_u8(self.scid.len() as u8)?;
499        out.put_bytes(&self.scid)?;
500
501        // Only Initial and Retry packets have a token.
502        match self.ty {
503            Type::Initial => {
504                match self.token {
505                    Some(ref v) => {
506                        out.put_varint(v.len() as u64)?;
507                        out.put_bytes(v)?;
508                    },
509
510                    // No token, so length = 0.
511                    None => {
512                        out.put_varint(0)?;
513                    },
514                }
515            },
516
517            Type::Retry => {
518                // Retry packets don't have a token length.
519                out.put_bytes(self.token.as_ref().unwrap())?;
520            },
521
522            _ => (),
523        }
524
525        Ok(())
526    }
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    fn is_long(b: u8) -> bool {
532        b & FORM_BIT != 0
533    }
534}
535
536impl std::fmt::Debug for Header<'_> {
537    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
538        write!(f, "{:?}", self.ty)?;
539
540        if self.ty != Type::Short {
541            write!(f, " version={:x}", self.version)?;
542        }
543
544        write!(f, " dcid={:?}", self.dcid)?;
545
546        if self.ty != Type::Short {
547            write!(f, " scid={:?}", self.scid)?;
548        }
549
550        if let Some(ref token) = self.token {
551            write!(f, " token=")?;
552            for b in token {
553                write!(f, "{b:02x}")?;
554            }
555        }
556
557        if let Some(ref versions) = self.versions {
558            write!(f, " versions={versions:x?}")?;
559        }
560
561        if self.ty == Type::Short {
562            write!(f, " key_phase={}", self.key_phase)?;
563        }
564
565        Ok(())
566    }
567}
568
569pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize {
570    let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1;
571    // computes ceil of num_unacked.log2() + 1
572    let min_bits = u64::BITS - num_unacked.leading_zeros() + 1;
573    // get the num len in bytes
574    min_bits.div_ceil(8) as usize
575}
576
577pub fn decrypt_hdr(
578    b: &mut octets::OctetsMut, hdr: &mut Header, aead: &crypto::Open,
579) -> Result<()> {
580    let mut first = {
581        let (first_buf, _) = b.split_at(1)?;
582        first_buf.as_ref()[0]
583    };
584
585    let mut pn_and_sample = b.peek_bytes_mut(MAX_PKT_NUM_LEN + SAMPLE_LEN)?;
586
587    let (mut ciphertext, sample) = pn_and_sample.split_at(MAX_PKT_NUM_LEN)?;
588
589    let ciphertext = ciphertext.as_mut();
590
591    let mask = aead.new_mask(sample.as_ref())?;
592
593    if Header::is_long(first) {
594        first ^= mask[0] & 0x0f;
595    } else {
596        first ^= mask[0] & 0x1f;
597    }
598
599    let pn_len = usize::from((first & PKT_NUM_MASK) + 1);
600
601    let ciphertext = &mut ciphertext[..pn_len];
602
603    for i in 0..pn_len {
604        ciphertext[i] ^= mask[i + 1];
605    }
606
607    // Extract packet number corresponding to the decoded length.
608    let pn = match pn_len {
609        1 => u64::from(b.get_u8()?),
610
611        2 => u64::from(b.get_u16()?),
612
613        3 => u64::from(b.get_u24()?),
614
615        4 => u64::from(b.get_u32()?),
616
617        _ => return Err(Error::InvalidPacket),
618    };
619
620    // Write decrypted first byte back into the input buffer.
621    let (mut first_buf, _) = b.split_at(1)?;
622    first_buf.as_mut()[0] = first;
623
624    hdr.pkt_num = pn;
625    hdr.pkt_num_len = pn_len;
626
627    if hdr.ty == Type::Short {
628        hdr.key_phase = (first & KEY_PHASE_BIT) != 0;
629    }
630
631    Ok(())
632}
633
634pub fn decode_pkt_num(largest_pn: u64, truncated_pn: u64, pn_len: usize) -> u64 {
635    let pn_nbits = pn_len * 8;
636    let expected_pn = largest_pn + 1;
637    let pn_win = 1 << pn_nbits;
638    let pn_hwin = pn_win / 2;
639    let pn_mask = pn_win - 1;
640    let candidate_pn = (expected_pn & !pn_mask) | truncated_pn;
641
642    if candidate_pn + pn_hwin <= expected_pn && candidate_pn < (1 << 62) - pn_win
643    {
644        return candidate_pn + pn_win;
645    }
646
647    if candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win {
648        return candidate_pn - pn_win;
649    }
650
651    candidate_pn
652}
653
654pub fn decrypt_pkt<'a>(
655    b: &'a mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
656    aead: &crypto::Open,
657) -> Result<octets::Octets<'a>> {
658    let payload_offset = b.off();
659
660    let (header, mut payload) = b.split_at(payload_offset)?;
661
662    let payload_len = payload_len
663        .checked_sub(pn_len)
664        .ok_or(Error::InvalidPacket)?;
665
666    let mut ciphertext = payload.peek_bytes_mut(payload_len)?;
667
668    let payload_len =
669        aead.open_with_u64_counter(pn, header.as_ref(), ciphertext.as_mut())?;
670
671    Ok(b.get_bytes(payload_len)?)
672}
673
674pub fn encrypt_hdr(
675    b: &mut octets::OctetsMut, pn_len: usize, payload: &[u8], aead: &crypto::Seal,
676) -> Result<()> {
677    let sample = &payload
678        [MAX_PKT_NUM_LEN - pn_len..SAMPLE_LEN + (MAX_PKT_NUM_LEN - pn_len)];
679
680    let mask = aead.new_mask(sample)?;
681
682    let (mut first, mut rest) = b.split_at(1)?;
683
684    let first = first.as_mut();
685
686    if Header::is_long(first[0]) {
687        first[0] ^= mask[0] & 0x0f;
688    } else {
689        first[0] ^= mask[0] & 0x1f;
690    }
691
692    let pn_buf = rest.slice_last(pn_len)?;
693    for i in 0..pn_len {
694        pn_buf[i] ^= mask[i + 1];
695    }
696
697    Ok(())
698}
699
700pub fn encrypt_pkt(
701    b: &mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
702    payload_offset: usize, extra_in: Option<&[u8]>, aead: &crypto::Seal,
703) -> Result<usize> {
704    let (mut header, mut payload) = b.split_at(payload_offset)?;
705
706    let ciphertext_len = aead.seal_with_u64_counter(
707        pn,
708        header.as_ref(),
709        payload.as_mut(),
710        payload_len,
711        extra_in,
712    )?;
713
714    encrypt_hdr(&mut header, pn_len, payload.as_ref(), aead)?;
715
716    Ok(payload_offset + ciphertext_len)
717}
718
719pub fn encode_pkt_num(
720    pn: u64, pn_len: usize, b: &mut octets::OctetsMut,
721) -> Result<()> {
722    match pn_len {
723        1 => b.put_u8(pn as u8)?,
724
725        2 => b.put_u16(pn as u16)?,
726
727        3 => b.put_u24(pn as u32)?,
728
729        4 => b.put_u32(pn as u32)?,
730
731        _ => return Err(Error::InvalidPacket),
732    };
733
734    Ok(())
735}
736
737pub fn negotiate_version(
738    scid: &[u8], dcid: &[u8], out: &mut [u8],
739) -> Result<usize> {
740    let mut b = octets::OctetsMut::with_slice(out);
741
742    let first = rand::rand_u8() | FORM_BIT;
743
744    b.put_u8(first)?;
745    b.put_u32(0)?;
746
747    b.put_u8(scid.len() as u8)?;
748    b.put_bytes(scid)?;
749    b.put_u8(dcid.len() as u8)?;
750    b.put_bytes(dcid)?;
751    b.put_u32(crate::PROTOCOL_VERSION_V1)?;
752
753    Ok(b.off())
754}
755
756pub fn retry(
757    scid: &[u8], dcid: &[u8], new_scid: &[u8], token: &[u8], version: u32,
758    out: &mut [u8],
759) -> Result<usize> {
760    let mut b = octets::OctetsMut::with_slice(out);
761
762    if !crate::version_is_supported(version) {
763        return Err(Error::UnknownVersion);
764    }
765
766    let hdr = Header {
767        ty: Type::Retry,
768        version,
769        dcid: ConnectionId::from_ref(scid),
770        scid: ConnectionId::from_ref(new_scid),
771        pkt_num: 0,
772        pkt_num_len: 0,
773        token: Some(token.to_vec()),
774        versions: None,
775        key_phase: false,
776    };
777
778    hdr.to_bytes(&mut b)?;
779
780    let tag = compute_retry_integrity_tag(&b, dcid, version)?;
781
782    b.put_bytes(tag.as_ref())?;
783
784    Ok(b.off())
785}
786
787pub fn verify_retry_integrity(
788    b: &octets::OctetsMut, odcid: &[u8], version: u32,
789) -> Result<()> {
790    const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
791
792    let tag = compute_retry_integrity_tag(b, odcid, version)?;
793
794    crypto::verify_slices_are_equal(&b.as_ref()[..TAG_LEN], tag.as_ref())
795}
796
797fn compute_retry_integrity_tag(
798    b: &octets::OctetsMut, odcid: &[u8], version: u32,
799) -> 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    let (key, nonce) = match version {
813        crate::PROTOCOL_VERSION_V1 =>
814            (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
815
816        _ => (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
817    };
818
819    let hdr_len = b.off();
820
821    let mut pseudo = vec![0; 1 + odcid.len() + hdr_len];
822
823    let mut pb = octets::OctetsMut::with_slice(&mut pseudo);
824
825    pb.put_u8(odcid.len() as u8)?;
826    pb.put_bytes(odcid)?;
827    pb.put_bytes(&b.buf()[..hdr_len])?;
828
829    let key = crypto::PacketKey::new(
830        RETRY_AEAD_ALG,
831        key.to_vec(),
832        nonce.to_vec(),
833        crypto::Seal::ENCRYPT,
834    )?;
835
836    let mut out_tag = vec![0_u8; TAG_LEN];
837
838    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    if out_len != out_tag.len() {
842        return Err(Error::CryptoFail);
843    }
844
845    Ok(out_tag)
846}
847
848pub 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
864pub 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
887impl PktNumSpace {
888    pub fn new() -> PktNumSpace {
889        PktNumSpace {
890            largest_rx_pkt_num: 0,
891            largest_rx_pkt_time: Instant::now(),
892            largest_rx_non_probing_pkt_num: 0,
893            largest_tx_pkt_num: None,
894            recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES),
895            recv_pkt_num: PktNumWindow::default(),
896            ack_elicited: false,
897        }
898    }
899
900    pub fn clear(&mut self) {
901        self.ack_elicited = false;
902    }
903
904    pub fn ready(&self) -> bool {
905        self.ack_elicited
906    }
907
908    pub fn on_packet_sent(&mut self, sent_pkt: &recovery::Sent) {
909        // Track the largest packet number sent
910        self.largest_tx_pkt_num =
911            self.largest_tx_pkt_num.max(Some(sent_pkt.pkt_num));
912    }
913}
914
915pub 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
923impl CryptoContext {
924    pub fn new() -> CryptoContext {
925        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        CryptoContext {
934            key_update: None,
935            crypto_open: None,
936            crypto_seal: None,
937            crypto_0rtt_open: None,
938            crypto_stream,
939        }
940    }
941
942    pub fn clear(&mut self) {
943        self.crypto_open = None;
944        self.crypto_seal = None;
945        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    }
954
955    pub fn data_available(&self) -> bool {
956        self.crypto_stream.is_flushable()
957    }
958
959    pub fn crypto_overhead(&self) -> Option<usize> {
960        Some(self.crypto_seal.as_ref()?.alg().tag_len())
961    }
962
963    pub fn has_keys(&self) -> bool {
964        self.crypto_open.is_some() && self.crypto_seal.is_some()
965    }
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
1013pub 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
1028impl PktNumManager {
1029    pub fn new() -> Self {
1030        PktNumManager {
1031            skip_pn: None,
1032            skip_pn_counter: None,
1033        }
1034    }
1035
1036    pub fn on_packet_sent(
1037        &mut self, cwnd: usize, max_datagram_size: usize,
1038        handshake_completed: bool,
1039    ) {
1040        // Decrement skip_pn_counter for each packet sent
1041        if let Some(counter) = &mut self.skip_pn_counter {
1042            *counter = counter.saturating_sub(1);
1043        } else if self.should_arm_skip_counter(handshake_completed) {
1044            self.arm_skip_counter(cwnd, max_datagram_size);
1045        }
1046    }
1047
1048    fn should_arm_skip_counter(&self, handshake_completed: bool) -> bool {
1049        // Arm if the counter is not set
1050        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        let no_current_skip_packet = self.skip_pn.is_none();
1055
1056        // Skip pn only after the handshake has completed
1057        counter_not_set && no_current_skip_packet && handshake_completed
1058    }
1059
1060    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        let no_current_skip_packet = self.skip_pn.is_none();
1065        let counter_expired = match self.skip_pn_counter {
1066            // Skip if counter has expired
1067            Some(counter) => counter == 0,
1068            // Don't skip if the counter has not been set
1069            None => false,
1070        };
1071
1072        // Skip pn only after the handshake has completed
1073        counter_expired && no_current_skip_packet && handshake_completed
1074    }
1075
1076    pub fn skip_pn(&self) -> Option<u64> {
1077        self.skip_pn
1078    }
1079
1080    pub fn set_skip_pn(&mut self, skip_pn: Option<u64>) {
1081        if skip_pn.is_some() {
1082            // Never overwrite skip_pn until the previous one has been verified
1083            debug_assert!(self.skip_pn.is_none());
1084            // The skip_pn_counter should be expired
1085            debug_assert_eq!(self.skip_pn_counter.unwrap(), 0);
1086        }
1087
1088        self.skip_pn = skip_pn;
1089        // unset the counter
1090        self.skip_pn_counter = None;
1091    }
1092
1093    // Dynamically vary the skip counter based on the CWND.
1094    fn arm_skip_counter(&mut self, cwnd: usize, max_datagram_size: usize) {
1095        let packets_per_cwnd = (cwnd / max_datagram_size) as u64;
1096        let lower = packets_per_cwnd / 2;
1097        let upper = packets_per_cwnd * 2;
1098        // rand_u64_uniform requires a non-zero value so add 1
1099        let skip_range = upper - lower + 1;
1100        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        let skip_pn_counter = MIN_SKIP_COUNTER_VALUE + lower + rand_skip_value;
1119
1120        self.skip_pn_counter = Some(skip_pn_counter);
1121    }
1122}
1123
1124#[derive(Clone, Copy, Default)]
1125pub struct PktNumWindow {
1126    lower: u64,
1127    window: u128,
1128}
1129
1130impl PktNumWindow {
1131    pub fn insert(&mut self, seq: u64) {
1132        // Packet is on the left end of the window.
1133        if seq < self.lower {
1134            return;
1135        }
1136
1137        // Packet is on the right end of the window.
1138        if seq > self.upper() {
1139            let diff = seq - self.upper();
1140            self.lower += diff;
1141
1142            self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
1143        }
1144
1145        let mask = 1_u128 << (self.upper() - seq);
1146        self.window |= mask;
1147    }
1148
1149    pub fn contains(&mut self, seq: u64) -> bool {
1150        // Packet is on the right end of the window.
1151        if seq > self.upper() {
1152            return false;
1153        }
1154
1155        // Packet is on the left end of the window.
1156        if seq < self.lower {
1157            return true;
1158        }
1159
1160        let mask = 1_u128 << (self.upper() - seq);
1161        self.window & mask != 0
1162    }
1163
1164    fn upper(&self) -> u64 {
1165        self.lower.saturating_add(size_of::<u128>() as u64 * 8) - 1
1166    }
1167}
1168
1169#[cfg(test)]
1170mod 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}