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;
28use std::ops::Index;
29use std::ops::IndexMut;
30use std::ops::RangeInclusive;
31use std::time;
32
33use crate::Error;
34use crate::Result;
35
36use crate::crypto;
37use crate::rand;
38use crate::ranges;
39use crate::stream;
40
41const FORM_BIT: u8 = 0x80;
42const FIXED_BIT: u8 = 0x40;
43const KEY_PHASE_BIT: u8 = 0x04;
44
45const TYPE_MASK: u8 = 0x30;
46const PKT_NUM_MASK: u8 = 0x03;
47
48pub const MAX_CID_LEN: u8 = 20;
49
50pub const MAX_PKT_NUM_LEN: usize = 4;
51
52const SAMPLE_LEN: usize = 16;
53
54const RETRY_AEAD_ALG: crypto::Algorithm = crypto::Algorithm::AES128_GCM;
55
56#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
57pub enum Epoch {
58    Initial     = 0,
59    Handshake   = 1,
60    Application = 2,
61}
62
63static EPOCHS: [Epoch; 3] =
64    [Epoch::Initial, Epoch::Handshake, Epoch::Application];
65
66impl Epoch {
67    /// Returns an ordered slice containing the `Epoch`s that fit in the
68    /// provided `range`.
69    pub fn epochs(range: RangeInclusive<Epoch>) -> &'static [Epoch] {
70        &EPOCHS[*range.start() as usize..=*range.end() as usize]
71    }
72
73    pub const fn count() -> usize {
74        3
75    }
76}
77
78impl Display for Epoch {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        write!(f, "{}", usize::from(*self))
81    }
82}
83
84impl From<Epoch> for usize {
85    fn from(e: Epoch) -> Self {
86        e as usize
87    }
88}
89
90impl<T> Index<Epoch> for [T]
91where
92    T: Sized,
93{
94    type Output = T;
95
96    fn index(&self, index: Epoch) -> &Self::Output {
97        self.index(usize::from(index))
98    }
99}
100
101impl<T> IndexMut<Epoch> for [T]
102where
103    T: Sized,
104{
105    fn index_mut(&mut self, index: Epoch) -> &mut Self::Output {
106        self.index_mut(usize::from(index))
107    }
108}
109
110/// QUIC packet type.
111#[derive(Clone, Copy, Debug, PartialEq, Eq)]
112pub enum Type {
113    /// Initial packet.
114    Initial,
115
116    /// Retry packet.
117    Retry,
118
119    /// Handshake packet.
120    Handshake,
121
122    /// 0-RTT packet.
123    ZeroRTT,
124
125    /// Version negotiation packet.
126    VersionNegotiation,
127
128    /// 1-RTT short header packet.
129    Short,
130}
131
132impl Type {
133    pub(crate) fn from_epoch(e: Epoch) -> Type {
134        match e {
135            Epoch::Initial => Type::Initial,
136
137            Epoch::Handshake => Type::Handshake,
138
139            Epoch::Application => Type::Short,
140        }
141    }
142
143    pub(crate) fn to_epoch(self) -> Result<Epoch> {
144        match self {
145            Type::Initial => Ok(Epoch::Initial),
146
147            Type::ZeroRTT => Ok(Epoch::Application),
148
149            Type::Handshake => Ok(Epoch::Handshake),
150
151            Type::Short => Ok(Epoch::Application),
152
153            _ => Err(Error::InvalidPacket),
154        }
155    }
156
157    #[cfg(feature = "qlog")]
158    pub(crate) fn to_qlog(self) -> qlog::events::quic::PacketType {
159        match self {
160            Type::Initial => qlog::events::quic::PacketType::Initial,
161
162            Type::Retry => qlog::events::quic::PacketType::Retry,
163
164            Type::Handshake => qlog::events::quic::PacketType::Handshake,
165
166            Type::ZeroRTT => qlog::events::quic::PacketType::ZeroRtt,
167
168            Type::VersionNegotiation =>
169                qlog::events::quic::PacketType::VersionNegotiation,
170
171            Type::Short => qlog::events::quic::PacketType::OneRtt,
172        }
173    }
174}
175
176/// A QUIC connection ID.
177pub struct ConnectionId<'a>(ConnectionIdInner<'a>);
178
179enum ConnectionIdInner<'a> {
180    Vec(Vec<u8>),
181    Ref(&'a [u8]),
182}
183
184impl<'a> ConnectionId<'a> {
185    /// Creates a new connection ID from the given vector.
186    #[inline]
187    pub const fn from_vec(cid: Vec<u8>) -> Self {
188        Self(ConnectionIdInner::Vec(cid))
189    }
190
191    /// Creates a new connection ID from the given slice.
192    #[inline]
193    pub const fn from_ref(cid: &'a [u8]) -> Self {
194        Self(ConnectionIdInner::Ref(cid))
195    }
196
197    /// Returns a new owning connection ID from the given existing one.
198    #[inline]
199    pub fn into_owned(self) -> ConnectionId<'static> {
200        ConnectionId::from_vec(self.into())
201    }
202}
203
204impl Default for ConnectionId<'_> {
205    #[inline]
206    fn default() -> Self {
207        Self::from_vec(Vec::new())
208    }
209}
210
211impl From<Vec<u8>> for ConnectionId<'_> {
212    #[inline]
213    fn from(v: Vec<u8>) -> Self {
214        Self::from_vec(v)
215    }
216}
217
218impl From<ConnectionId<'_>> for Vec<u8> {
219    #[inline]
220    fn from(id: ConnectionId<'_>) -> Self {
221        match id.0 {
222            ConnectionIdInner::Vec(cid) => cid,
223            ConnectionIdInner::Ref(cid) => cid.to_vec(),
224        }
225    }
226}
227
228impl PartialEq for ConnectionId<'_> {
229    #[inline]
230    fn eq(&self, other: &Self) -> bool {
231        self.as_ref() == other.as_ref()
232    }
233}
234
235impl Eq for ConnectionId<'_> {}
236
237impl AsRef<[u8]> for ConnectionId<'_> {
238    #[inline]
239    fn as_ref(&self) -> &[u8] {
240        match &self.0 {
241            ConnectionIdInner::Vec(v) => v.as_ref(),
242            ConnectionIdInner::Ref(v) => v,
243        }
244    }
245}
246
247impl std::hash::Hash for ConnectionId<'_> {
248    #[inline]
249    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
250        self.as_ref().hash(state);
251    }
252}
253
254impl std::ops::Deref for ConnectionId<'_> {
255    type Target = [u8];
256
257    #[inline]
258    fn deref(&self) -> &[u8] {
259        match &self.0 {
260            ConnectionIdInner::Vec(v) => v.as_ref(),
261            ConnectionIdInner::Ref(v) => v,
262        }
263    }
264}
265
266impl Clone for ConnectionId<'_> {
267    #[inline]
268    fn clone(&self) -> Self {
269        Self::from_vec(self.as_ref().to_vec())
270    }
271}
272
273impl std::fmt::Debug for ConnectionId<'_> {
274    #[inline]
275    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
276        for c in self.as_ref() {
277            write!(f, "{c:02x}")?;
278        }
279
280        Ok(())
281    }
282}
283
284/// A QUIC packet's header.
285#[derive(Clone, PartialEq, Eq)]
286pub struct Header<'a> {
287    /// The type of the packet.
288    pub ty: Type,
289
290    /// The version of the packet.
291    pub version: u32,
292
293    /// The destination connection ID of the packet.
294    pub dcid: ConnectionId<'a>,
295
296    /// The source connection ID of the packet.
297    pub scid: ConnectionId<'a>,
298
299    /// The packet number. It's only meaningful after the header protection is
300    /// removed.
301    pub(crate) pkt_num: u64,
302
303    /// The length of the packet number. It's only meaningful after the header
304    /// protection is removed.
305    pub(crate) pkt_num_len: usize,
306
307    /// The address verification token of the packet. Only present in `Initial`
308    /// and `Retry` packets.
309    pub token: Option<Vec<u8>>,
310
311    /// The list of versions in the packet. Only present in
312    /// `VersionNegotiation` packets.
313    pub versions: Option<Vec<u32>>,
314
315    /// The key phase bit of the packet. It's only meaningful after the header
316    /// protection is removed.
317    pub(crate) key_phase: bool,
318}
319
320impl<'a> Header<'a> {
321    /// Parses a QUIC packet header from the given buffer.
322    ///
323    /// The `dcid_len` parameter is the length of the destination connection ID,
324    /// required to parse short header packets.
325    ///
326    /// ## Examples:
327    ///
328    /// ```no_run
329    /// # const LOCAL_CONN_ID_LEN: usize = 16;
330    /// # let mut buf = [0; 512];
331    /// # let mut out = [0; 512];
332    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
333    /// let (len, src) = socket.recv_from(&mut buf).unwrap();
334    ///
335    /// let hdr = quiche::Header::from_slice(&mut buf[..len], LOCAL_CONN_ID_LEN)?;
336    /// # Ok::<(), quiche::Error>(())
337    /// ```
338    #[inline]
339    pub fn from_slice<'b>(
340        buf: &'b mut [u8], dcid_len: usize,
341    ) -> Result<Header<'a>> {
342        let mut b = octets::OctetsMut::with_slice(buf);
343        Header::from_bytes(&mut b, dcid_len)
344    }
345
346    pub(crate) fn from_bytes<'b>(
347        b: &'b mut octets::OctetsMut, dcid_len: usize,
348    ) -> Result<Header<'a>> {
349        let first = b.get_u8()?;
350
351        if !Header::is_long(first) {
352            // Decode short header.
353            let dcid = b.get_bytes(dcid_len)?;
354
355            return Ok(Header {
356                ty: Type::Short,
357                version: 0,
358                dcid: dcid.to_vec().into(),
359                scid: ConnectionId::default(),
360                pkt_num: 0,
361                pkt_num_len: 0,
362                token: None,
363                versions: None,
364                key_phase: false,
365            });
366        }
367
368        // Decode long header.
369        let version = b.get_u32()?;
370
371        let ty = if version == 0 {
372            Type::VersionNegotiation
373        } else {
374            match (first & TYPE_MASK) >> 4 {
375                0x00 => Type::Initial,
376                0x01 => Type::ZeroRTT,
377                0x02 => Type::Handshake,
378                0x03 => Type::Retry,
379                _ => return Err(Error::InvalidPacket),
380            }
381        };
382
383        let dcid_len = b.get_u8()?;
384        if crate::version_is_supported(version) && dcid_len > MAX_CID_LEN {
385            return Err(Error::InvalidPacket);
386        }
387        let dcid = b.get_bytes(dcid_len as usize)?.to_vec();
388
389        let scid_len = b.get_u8()?;
390        if crate::version_is_supported(version) && scid_len > MAX_CID_LEN {
391            return Err(Error::InvalidPacket);
392        }
393        let scid = b.get_bytes(scid_len as usize)?.to_vec();
394
395        // End of invariants.
396
397        let mut token: Option<Vec<u8>> = None;
398        let mut versions: Option<Vec<u32>> = None;
399
400        match ty {
401            Type::Initial => {
402                token = Some(b.get_bytes_with_varint_length()?.to_vec());
403            },
404
405            Type::Retry => {
406                const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
407
408                // Exclude the integrity tag from the token.
409                if b.cap() < TAG_LEN {
410                    return Err(Error::InvalidPacket);
411                }
412
413                let token_len = b.cap() - TAG_LEN;
414                token = Some(b.get_bytes(token_len)?.to_vec());
415            },
416
417            Type::VersionNegotiation => {
418                let mut list: Vec<u32> = Vec::new();
419
420                while b.cap() > 0 {
421                    let version = b.get_u32()?;
422                    list.push(version);
423                }
424
425                versions = Some(list);
426            },
427
428            _ => (),
429        };
430
431        Ok(Header {
432            ty,
433            version,
434            dcid: dcid.into(),
435            scid: scid.into(),
436            pkt_num: 0,
437            pkt_num_len: 0,
438            token,
439            versions,
440            key_phase: false,
441        })
442    }
443
444    pub(crate) fn to_bytes(&self, out: &mut octets::OctetsMut) -> Result<()> {
445        let mut first = 0;
446
447        // Encode pkt num length.
448        first |= self.pkt_num_len.saturating_sub(1) as u8;
449
450        // Encode short header.
451        if self.ty == Type::Short {
452            // Unset form bit for short header.
453            first &= !FORM_BIT;
454
455            // Set fixed bit.
456            first |= FIXED_BIT;
457
458            // Set key phase bit.
459            if self.key_phase {
460                first |= KEY_PHASE_BIT;
461            } else {
462                first &= !KEY_PHASE_BIT;
463            }
464
465            out.put_u8(first)?;
466            out.put_bytes(&self.dcid)?;
467
468            return Ok(());
469        }
470
471        // Encode long header.
472        let ty: u8 = match self.ty {
473            Type::Initial => 0x00,
474            Type::ZeroRTT => 0x01,
475            Type::Handshake => 0x02,
476            Type::Retry => 0x03,
477            _ => return Err(Error::InvalidPacket),
478        };
479
480        first |= FORM_BIT | FIXED_BIT | (ty << 4);
481
482        out.put_u8(first)?;
483
484        out.put_u32(self.version)?;
485
486        out.put_u8(self.dcid.len() as u8)?;
487        out.put_bytes(&self.dcid)?;
488
489        out.put_u8(self.scid.len() as u8)?;
490        out.put_bytes(&self.scid)?;
491
492        // Only Initial and Retry packets have a token.
493        match self.ty {
494            Type::Initial => {
495                match self.token {
496                    Some(ref v) => {
497                        out.put_varint(v.len() as u64)?;
498                        out.put_bytes(v)?;
499                    },
500
501                    // No token, so length = 0.
502                    None => {
503                        out.put_varint(0)?;
504                    },
505                }
506            },
507
508            Type::Retry => {
509                // Retry packets don't have a token length.
510                out.put_bytes(self.token.as_ref().unwrap())?;
511            },
512
513            _ => (),
514        }
515
516        Ok(())
517    }
518
519    /// Returns true if the packet has a long header.
520    ///
521    /// The `b` parameter represents the first byte of the QUIC header.
522    fn is_long(b: u8) -> bool {
523        b & FORM_BIT != 0
524    }
525}
526
527impl std::fmt::Debug for Header<'_> {
528    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
529        write!(f, "{:?}", self.ty)?;
530
531        if self.ty != Type::Short {
532            write!(f, " version={:x}", self.version)?;
533        }
534
535        write!(f, " dcid={:?}", self.dcid)?;
536
537        if self.ty != Type::Short {
538            write!(f, " scid={:?}", self.scid)?;
539        }
540
541        if let Some(ref token) = self.token {
542            write!(f, " token=")?;
543            for b in token {
544                write!(f, "{b:02x}")?;
545            }
546        }
547
548        if let Some(ref versions) = self.versions {
549            write!(f, " versions={versions:x?}")?;
550        }
551
552        if self.ty == Type::Short {
553            write!(f, " key_phase={}", self.key_phase)?;
554        }
555
556        Ok(())
557    }
558}
559
560pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize {
561    let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1;
562    // computes ceil of num_unacked.log2()
563    let min_bits = u64::BITS - num_unacked.leading_zeros();
564    // get the num len in bytes
565    min_bits.div_ceil(8) as usize
566}
567
568pub fn decrypt_hdr(
569    b: &mut octets::OctetsMut, hdr: &mut Header, aead: &crypto::Open,
570) -> Result<()> {
571    let mut first = {
572        let (first_buf, _) = b.split_at(1)?;
573        first_buf.as_ref()[0]
574    };
575
576    let mut pn_and_sample = b.peek_bytes_mut(MAX_PKT_NUM_LEN + SAMPLE_LEN)?;
577
578    let (mut ciphertext, sample) = pn_and_sample.split_at(MAX_PKT_NUM_LEN)?;
579
580    let ciphertext = ciphertext.as_mut();
581
582    let mask = aead.new_mask(sample.as_ref())?;
583
584    if Header::is_long(first) {
585        first ^= mask[0] & 0x0f;
586    } else {
587        first ^= mask[0] & 0x1f;
588    }
589
590    let pn_len = usize::from((first & PKT_NUM_MASK) + 1);
591
592    let ciphertext = &mut ciphertext[..pn_len];
593
594    for i in 0..pn_len {
595        ciphertext[i] ^= mask[i + 1];
596    }
597
598    // Extract packet number corresponding to the decoded length.
599    let pn = match pn_len {
600        1 => u64::from(b.get_u8()?),
601
602        2 => u64::from(b.get_u16()?),
603
604        3 => u64::from(b.get_u24()?),
605
606        4 => u64::from(b.get_u32()?),
607
608        _ => return Err(Error::InvalidPacket),
609    };
610
611    // Write decrypted first byte back into the input buffer.
612    let (mut first_buf, _) = b.split_at(1)?;
613    first_buf.as_mut()[0] = first;
614
615    hdr.pkt_num = pn;
616    hdr.pkt_num_len = pn_len;
617
618    if hdr.ty == Type::Short {
619        hdr.key_phase = (first & KEY_PHASE_BIT) != 0;
620    }
621
622    Ok(())
623}
624
625pub fn decode_pkt_num(largest_pn: u64, truncated_pn: u64, pn_len: usize) -> u64 {
626    let pn_nbits = pn_len * 8;
627    let expected_pn = largest_pn + 1;
628    let pn_win = 1 << pn_nbits;
629    let pn_hwin = pn_win / 2;
630    let pn_mask = pn_win - 1;
631    let candidate_pn = (expected_pn & !pn_mask) | truncated_pn;
632
633    if candidate_pn + pn_hwin <= expected_pn && candidate_pn < (1 << 62) - pn_win
634    {
635        return candidate_pn + pn_win;
636    }
637
638    if candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win {
639        return candidate_pn - pn_win;
640    }
641
642    candidate_pn
643}
644
645pub fn decrypt_pkt<'a>(
646    b: &'a mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
647    aead: &crypto::Open,
648) -> Result<octets::Octets<'a>> {
649    let payload_offset = b.off();
650
651    let (header, mut payload) = b.split_at(payload_offset)?;
652
653    let payload_len = payload_len
654        .checked_sub(pn_len)
655        .ok_or(Error::InvalidPacket)?;
656
657    let mut ciphertext = payload.peek_bytes_mut(payload_len)?;
658
659    let payload_len =
660        aead.open_with_u64_counter(pn, header.as_ref(), ciphertext.as_mut())?;
661
662    Ok(b.get_bytes(payload_len)?)
663}
664
665pub fn encrypt_hdr(
666    b: &mut octets::OctetsMut, pn_len: usize, payload: &[u8], aead: &crypto::Seal,
667) -> Result<()> {
668    let sample = &payload
669        [MAX_PKT_NUM_LEN - pn_len..SAMPLE_LEN + (MAX_PKT_NUM_LEN - pn_len)];
670
671    let mask = aead.new_mask(sample)?;
672
673    let (mut first, mut rest) = b.split_at(1)?;
674
675    let first = first.as_mut();
676
677    if Header::is_long(first[0]) {
678        first[0] ^= mask[0] & 0x0f;
679    } else {
680        first[0] ^= mask[0] & 0x1f;
681    }
682
683    let pn_buf = rest.slice_last(pn_len)?;
684    for i in 0..pn_len {
685        pn_buf[i] ^= mask[i + 1];
686    }
687
688    Ok(())
689}
690
691pub fn encrypt_pkt(
692    b: &mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
693    payload_offset: usize, extra_in: Option<&[u8]>, aead: &crypto::Seal,
694) -> Result<usize> {
695    let (mut header, mut payload) = b.split_at(payload_offset)?;
696
697    let ciphertext_len = aead.seal_with_u64_counter(
698        pn,
699        header.as_ref(),
700        payload.as_mut(),
701        payload_len,
702        extra_in,
703    )?;
704
705    encrypt_hdr(&mut header, pn_len, payload.as_ref(), aead)?;
706
707    Ok(payload_offset + ciphertext_len)
708}
709
710pub fn encode_pkt_num(
711    pn: u64, pn_len: usize, b: &mut octets::OctetsMut,
712) -> Result<()> {
713    match pn_len {
714        1 => b.put_u8(pn as u8)?,
715
716        2 => b.put_u16(pn as u16)?,
717
718        3 => b.put_u24(pn as u32)?,
719
720        4 => b.put_u32(pn as u32)?,
721
722        _ => return Err(Error::InvalidPacket),
723    };
724
725    Ok(())
726}
727
728pub fn negotiate_version(
729    scid: &[u8], dcid: &[u8], out: &mut [u8],
730) -> Result<usize> {
731    let mut b = octets::OctetsMut::with_slice(out);
732
733    let first = rand::rand_u8() | FORM_BIT;
734
735    b.put_u8(first)?;
736    b.put_u32(0)?;
737
738    b.put_u8(scid.len() as u8)?;
739    b.put_bytes(scid)?;
740    b.put_u8(dcid.len() as u8)?;
741    b.put_bytes(dcid)?;
742    b.put_u32(crate::PROTOCOL_VERSION_V1)?;
743
744    Ok(b.off())
745}
746
747pub fn retry(
748    scid: &[u8], dcid: &[u8], new_scid: &[u8], token: &[u8], version: u32,
749    out: &mut [u8],
750) -> Result<usize> {
751    let mut b = octets::OctetsMut::with_slice(out);
752
753    if !crate::version_is_supported(version) {
754        return Err(Error::UnknownVersion);
755    }
756
757    let hdr = Header {
758        ty: Type::Retry,
759        version,
760        dcid: ConnectionId::from_ref(scid),
761        scid: ConnectionId::from_ref(new_scid),
762        pkt_num: 0,
763        pkt_num_len: 0,
764        token: Some(token.to_vec()),
765        versions: None,
766        key_phase: false,
767    };
768
769    hdr.to_bytes(&mut b)?;
770
771    let tag = compute_retry_integrity_tag(&b, dcid, version)?;
772
773    b.put_bytes(tag.as_ref())?;
774
775    Ok(b.off())
776}
777
778pub fn verify_retry_integrity(
779    b: &octets::OctetsMut, odcid: &[u8], version: u32,
780) -> Result<()> {
781    const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
782
783    let tag = compute_retry_integrity_tag(b, odcid, version)?;
784
785    crypto::verify_slices_are_equal(&b.as_ref()[..TAG_LEN], tag.as_ref())
786}
787
788fn compute_retry_integrity_tag(
789    b: &octets::OctetsMut, odcid: &[u8], version: u32,
790) -> Result<Vec<u8>> {
791    const KEY_LEN: usize = RETRY_AEAD_ALG.key_len();
792    const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
793
794    const RETRY_INTEGRITY_KEY_V1: [u8; KEY_LEN] = [
795        0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
796        0xe3, 0x68, 0xc8, 0x4e,
797    ];
798
799    const RETRY_INTEGRITY_NONCE_V1: [u8; crypto::MAX_NONCE_LEN] = [
800        0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,
801    ];
802
803    let (key, nonce) = match version {
804        crate::PROTOCOL_VERSION_V1 =>
805            (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
806
807        _ => (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
808    };
809
810    let hdr_len = b.off();
811
812    let mut pseudo = vec![0; 1 + odcid.len() + hdr_len];
813
814    let mut pb = octets::OctetsMut::with_slice(&mut pseudo);
815
816    pb.put_u8(odcid.len() as u8)?;
817    pb.put_bytes(odcid)?;
818    pb.put_bytes(&b.buf()[..hdr_len])?;
819
820    let key = crypto::PacketKey::new(
821        RETRY_AEAD_ALG,
822        key.to_vec(),
823        nonce.to_vec(),
824        crypto::Seal::ENCRYPT,
825    )?;
826
827    let mut out_tag = vec![0_u8; TAG_LEN];
828
829    let out_len = key.seal_with_u64_counter(0, &pseudo, &mut out_tag, 0, None)?;
830
831    // Ensure that the output only contains the AEAD tag.
832    if out_len != out_tag.len() {
833        return Err(Error::CryptoFail);
834    }
835
836    Ok(out_tag)
837}
838
839pub struct KeyUpdate {
840    /// 1-RTT key used prior to a key update.
841    pub crypto_open: crypto::Open,
842
843    /// The packet number triggered the latest key-update.
844    ///
845    /// Incoming packets with lower pn should use this (prev) crypto key.
846    pub pn_on_update: u64,
847
848    /// Whether ACK frame for key-update has been sent.
849    pub update_acked: bool,
850
851    /// When the old key should be discarded.
852    pub timer: time::Instant,
853}
854
855pub struct PktNumSpace {
856    /// The largest packet number received.
857    pub largest_rx_pkt_num: u64,
858
859    /// Time the largest packet number received.
860    pub largest_rx_pkt_time: time::Instant,
861
862    /// The largest non-probing packet number.
863    pub largest_rx_non_probing_pkt_num: u64,
864
865    /// Range of packet numbers that we need to send an ACK for.
866    pub recv_pkt_need_ack: ranges::RangeSet,
867
868    /// Tracks received packet numbers.
869    pub recv_pkt_num: PktNumWindow,
870
871    /// Track if a received packet is ack eliciting.
872    pub ack_elicited: bool,
873}
874
875impl PktNumSpace {
876    pub fn new() -> PktNumSpace {
877        PktNumSpace {
878            largest_rx_pkt_num: 0,
879            largest_rx_pkt_time: time::Instant::now(),
880            largest_rx_non_probing_pkt_num: 0,
881            recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES),
882            recv_pkt_num: PktNumWindow::default(),
883            ack_elicited: false,
884        }
885    }
886
887    pub fn clear(&mut self) {
888        self.ack_elicited = false;
889    }
890
891    pub fn ready(&self) -> bool {
892        self.ack_elicited
893    }
894}
895
896pub struct CryptoContext {
897    pub key_update: Option<KeyUpdate>,
898    pub crypto_open: Option<crypto::Open>,
899    pub crypto_seal: Option<crypto::Seal>,
900    pub crypto_0rtt_open: Option<crypto::Open>,
901    pub crypto_stream: stream::Stream,
902}
903
904impl CryptoContext {
905    pub fn new() -> CryptoContext {
906        let crypto_stream = stream::Stream::new(
907            0, // dummy
908            u64::MAX,
909            u64::MAX,
910            true,
911            true,
912            stream::MAX_STREAM_WINDOW,
913        );
914        CryptoContext {
915            key_update: None,
916            crypto_open: None,
917            crypto_seal: None,
918            crypto_0rtt_open: None,
919            crypto_stream,
920        }
921    }
922
923    pub fn clear(&mut self) {
924        self.crypto_open = None;
925        self.crypto_seal = None;
926        self.crypto_stream = <stream::Stream>::new(
927            0, // dummy
928            u64::MAX,
929            u64::MAX,
930            true,
931            true,
932            stream::MAX_STREAM_WINDOW,
933        );
934    }
935
936    pub fn data_available(&self) -> bool {
937        self.crypto_stream.is_flushable()
938    }
939
940    pub fn crypto_overhead(&self) -> Option<usize> {
941        Some(self.crypto_seal.as_ref()?.alg().tag_len())
942    }
943
944    pub fn has_keys(&self) -> bool {
945        self.crypto_open.is_some() && self.crypto_seal.is_some()
946    }
947}
948
949#[derive(Clone, Copy, Default)]
950pub struct PktNumWindow {
951    lower: u64,
952    window: u128,
953}
954
955impl PktNumWindow {
956    pub fn insert(&mut self, seq: u64) {
957        // Packet is on the left end of the window.
958        if seq < self.lower {
959            return;
960        }
961
962        // Packet is on the right end of the window.
963        if seq > self.upper() {
964            let diff = seq - self.upper();
965            self.lower += diff;
966
967            self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
968        }
969
970        let mask = 1_u128 << (self.upper() - seq);
971        self.window |= mask;
972    }
973
974    pub fn contains(&mut self, seq: u64) -> bool {
975        // Packet is on the right end of the window.
976        if seq > self.upper() {
977            return false;
978        }
979
980        // Packet is on the left end of the window.
981        if seq < self.lower {
982            return true;
983        }
984
985        let mask = 1_u128 << (self.upper() - seq);
986        self.window & mask != 0
987    }
988
989    fn upper(&self) -> u64 {
990        self.lower
991            .saturating_add(std::mem::size_of::<u128>() as u64 * 8) -
992            1
993    }
994}
995
996#[cfg(test)]
997mod tests {
998    use super::*;
999
1000    #[test]
1001    fn retry() {
1002        let hdr = Header {
1003            ty: Type::Retry,
1004            version: 0xafafafaf,
1005            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1006                .into(),
1007            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1008            pkt_num: 0,
1009            pkt_num_len: 0,
1010            token: Some(vec![0xba; 24]),
1011            versions: None,
1012            key_phase: false,
1013        };
1014
1015        let mut d = [0; 63];
1016
1017        let mut b = octets::OctetsMut::with_slice(&mut d);
1018        assert!(hdr.to_bytes(&mut b).is_ok());
1019
1020        // Add fake retry integrity token.
1021        b.put_bytes(&[0xba; 16]).unwrap();
1022
1023        let mut b = octets::OctetsMut::with_slice(&mut d);
1024        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1025    }
1026
1027    #[test]
1028    fn initial() {
1029        let hdr = Header {
1030            ty: Type::Initial,
1031            version: 0xafafafaf,
1032            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1033                .into(),
1034            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1035            pkt_num: 0,
1036            pkt_num_len: 0,
1037            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1038            versions: None,
1039            key_phase: false,
1040        };
1041
1042        let mut d = [0; 50];
1043
1044        let mut b = octets::OctetsMut::with_slice(&mut d);
1045        assert!(hdr.to_bytes(&mut b).is_ok());
1046
1047        let mut b = octets::OctetsMut::with_slice(&mut d);
1048        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1049    }
1050
1051    #[test]
1052    fn initial_v1_dcid_too_long() {
1053        let hdr = Header {
1054            ty: Type::Initial,
1055            version: crate::PROTOCOL_VERSION,
1056            dcid: vec![
1057                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1058                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1059            ]
1060            .into(),
1061            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1062            pkt_num: 0,
1063            pkt_num_len: 0,
1064            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1065            versions: None,
1066            key_phase: false,
1067        };
1068
1069        let mut d = [0; 50];
1070
1071        let mut b = octets::OctetsMut::with_slice(&mut d);
1072        assert!(hdr.to_bytes(&mut b).is_ok());
1073
1074        let mut b = octets::OctetsMut::with_slice(&mut d);
1075        assert_eq!(Header::from_bytes(&mut b, 21), Err(Error::InvalidPacket));
1076    }
1077
1078    #[test]
1079    fn initial_v1_scid_too_long() {
1080        let hdr = Header {
1081            ty: Type::Initial,
1082            version: crate::PROTOCOL_VERSION,
1083            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1084                .into(),
1085            scid: vec![
1086                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1087                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1088            ]
1089            .into(),
1090            pkt_num: 0,
1091            pkt_num_len: 0,
1092            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1093            versions: None,
1094            key_phase: false,
1095        };
1096
1097        let mut d = [0; 50];
1098
1099        let mut b = octets::OctetsMut::with_slice(&mut d);
1100        assert!(hdr.to_bytes(&mut b).is_ok());
1101
1102        let mut b = octets::OctetsMut::with_slice(&mut d);
1103        assert_eq!(Header::from_bytes(&mut b, 9), Err(Error::InvalidPacket));
1104    }
1105
1106    #[test]
1107    fn initial_non_v1_scid_long() {
1108        let hdr = Header {
1109            ty: Type::Initial,
1110            version: 0xafafafaf,
1111            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1112                .into(),
1113            scid: vec![
1114                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1115                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1116            ]
1117            .into(),
1118            pkt_num: 0,
1119            pkt_num_len: 0,
1120            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1121            versions: None,
1122            key_phase: false,
1123        };
1124
1125        let mut d = [0; 50];
1126
1127        let mut b = octets::OctetsMut::with_slice(&mut d);
1128        assert!(hdr.to_bytes(&mut b).is_ok());
1129
1130        let mut b = octets::OctetsMut::with_slice(&mut d);
1131        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1132    }
1133
1134    #[test]
1135    fn handshake() {
1136        let hdr = Header {
1137            ty: Type::Handshake,
1138            version: 0xafafafaf,
1139            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1140                .into(),
1141            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1142            pkt_num: 0,
1143            pkt_num_len: 0,
1144            token: None,
1145            versions: None,
1146            key_phase: false,
1147        };
1148
1149        let mut d = [0; 50];
1150
1151        let mut b = octets::OctetsMut::with_slice(&mut d);
1152        assert!(hdr.to_bytes(&mut b).is_ok());
1153
1154        let mut b = octets::OctetsMut::with_slice(&mut d);
1155        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1156    }
1157
1158    #[test]
1159    fn application() {
1160        let hdr = Header {
1161            ty: Type::Short,
1162            version: 0,
1163            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1164                .into(),
1165            scid: ConnectionId::default(),
1166            pkt_num: 0,
1167            pkt_num_len: 0,
1168            token: None,
1169            versions: None,
1170            key_phase: false,
1171        };
1172
1173        let mut d = [0; 50];
1174
1175        let mut b = octets::OctetsMut::with_slice(&mut d);
1176        assert!(hdr.to_bytes(&mut b).is_ok());
1177
1178        let mut b = octets::OctetsMut::with_slice(&mut d);
1179        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1180    }
1181
1182    #[test]
1183    fn pkt_num_encode_decode() {
1184        let num_len = pkt_num_len(0, 0);
1185        assert_eq!(num_len, 1);
1186        let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2);
1187        assert_eq!(pn, 0xa82f9b32);
1188        let mut d = [0; 10];
1189        let mut b = octets::OctetsMut::with_slice(&mut d);
1190        let num_len = pkt_num_len(0xac5c02, 0xabe8b3);
1191        assert_eq!(num_len, 2);
1192        encode_pkt_num(0xac5c02, num_len, &mut b).unwrap();
1193        // reading
1194        let mut b = octets::OctetsMut::with_slice(&mut d);
1195        let hdr_num = u64::from(b.get_u16().unwrap());
1196        let pn = decode_pkt_num(0xac5c01, hdr_num, num_len);
1197        assert_eq!(pn, 0xac5c02);
1198        // sending 0xace8fe while having 0xabe8b3 acked
1199        let num_len = pkt_num_len(0xace9fe, 0xabe8b3);
1200        assert_eq!(num_len, 3);
1201        let mut b = octets::OctetsMut::with_slice(&mut d);
1202        encode_pkt_num(0xace9fe, num_len, &mut b).unwrap();
1203        // reading
1204        let mut b = octets::OctetsMut::with_slice(&mut d);
1205        let hdr_num = u64::from(b.get_u24().unwrap());
1206        let pn = decode_pkt_num(0xace9fa, hdr_num, num_len);
1207        assert_eq!(pn, 0xace9fe);
1208    }
1209
1210    #[test]
1211    fn pkt_num_window() {
1212        let mut win = PktNumWindow::default();
1213        assert_eq!(win.lower, 0);
1214        assert!(!win.contains(0));
1215        assert!(!win.contains(1));
1216
1217        win.insert(0);
1218        assert_eq!(win.lower, 0);
1219        assert!(win.contains(0));
1220        assert!(!win.contains(1));
1221
1222        win.insert(1);
1223        assert_eq!(win.lower, 0);
1224        assert!(win.contains(0));
1225        assert!(win.contains(1));
1226
1227        win.insert(3);
1228        assert_eq!(win.lower, 0);
1229        assert!(win.contains(0));
1230        assert!(win.contains(1));
1231        assert!(!win.contains(2));
1232        assert!(win.contains(3));
1233
1234        win.insert(10);
1235        assert_eq!(win.lower, 0);
1236        assert!(win.contains(0));
1237        assert!(win.contains(1));
1238        assert!(!win.contains(2));
1239        assert!(win.contains(3));
1240        assert!(!win.contains(4));
1241        assert!(!win.contains(5));
1242        assert!(!win.contains(6));
1243        assert!(!win.contains(7));
1244        assert!(!win.contains(8));
1245        assert!(!win.contains(9));
1246        assert!(win.contains(10));
1247
1248        win.insert(132);
1249        assert_eq!(win.lower, 5);
1250        assert!(win.contains(0));
1251        assert!(win.contains(1));
1252        assert!(win.contains(2));
1253        assert!(win.contains(3));
1254        assert!(win.contains(4));
1255        assert!(!win.contains(5));
1256        assert!(!win.contains(6));
1257        assert!(!win.contains(7));
1258        assert!(!win.contains(8));
1259        assert!(!win.contains(9));
1260        assert!(win.contains(10));
1261        assert!(!win.contains(128));
1262        assert!(!win.contains(130));
1263        assert!(!win.contains(131));
1264        assert!(win.contains(132));
1265
1266        win.insert(1024);
1267        assert_eq!(win.lower, 897);
1268        assert!(win.contains(0));
1269        assert!(win.contains(1));
1270        assert!(win.contains(2));
1271        assert!(win.contains(3));
1272        assert!(win.contains(4));
1273        assert!(win.contains(5));
1274        assert!(win.contains(6));
1275        assert!(win.contains(7));
1276        assert!(win.contains(8));
1277        assert!(win.contains(9));
1278        assert!(win.contains(10));
1279        assert!(win.contains(128));
1280        assert!(win.contains(130));
1281        assert!(win.contains(132));
1282        assert!(win.contains(896));
1283        assert!(!win.contains(897));
1284        assert!(!win.contains(1022));
1285        assert!(!win.contains(1023));
1286        assert!(win.contains(1024));
1287        assert!(!win.contains(1025));
1288        assert!(!win.contains(1026));
1289
1290        win.insert(u64::MAX - 1);
1291        assert!(win.contains(0));
1292        assert!(win.contains(1));
1293        assert!(win.contains(2));
1294        assert!(win.contains(3));
1295        assert!(win.contains(4));
1296        assert!(win.contains(5));
1297        assert!(win.contains(6));
1298        assert!(win.contains(7));
1299        assert!(win.contains(8));
1300        assert!(win.contains(9));
1301        assert!(win.contains(10));
1302        assert!(win.contains(128));
1303        assert!(win.contains(130));
1304        assert!(win.contains(132));
1305        assert!(win.contains(896));
1306        assert!(win.contains(897));
1307        assert!(win.contains(1022));
1308        assert!(win.contains(1023));
1309        assert!(win.contains(1024));
1310        assert!(win.contains(1025));
1311        assert!(win.contains(1026));
1312        assert!(!win.contains(u64::MAX - 2));
1313        assert!(win.contains(u64::MAX - 1));
1314    }
1315
1316    fn assert_decrypt_initial_pkt(
1317        pkt: &mut [u8], dcid: &[u8], is_server: bool, expected_frames: &[u8],
1318        expected_pn: u64, expected_pn_len: usize,
1319    ) {
1320        let mut b = octets::OctetsMut::with_slice(pkt);
1321
1322        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1323        assert_eq!(hdr.ty, Type::Initial);
1324
1325        let payload_len = b.get_varint().unwrap() as usize;
1326
1327        let (aead, _) = crypto::derive_initial_key_material(
1328            dcid,
1329            hdr.version,
1330            is_server,
1331            false,
1332        )
1333        .unwrap();
1334
1335        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1336        assert_eq!(hdr.pkt_num_len, expected_pn_len);
1337
1338        let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len);
1339        assert_eq!(pn, expected_pn);
1340
1341        let payload =
1342            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1343
1344        let payload = payload.as_ref();
1345        assert_eq!(&payload[..expected_frames.len()], expected_frames);
1346    }
1347
1348    #[test]
1349    fn decrypt_client_initial_v1() {
1350        let mut pkt = [
1351            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1352            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1353            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1354            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1355            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1356            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1357            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1358            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1359            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1360            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1361            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1362            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1363            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1364            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1365            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1366            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1367            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1368            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1369            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1370            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1371            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1372            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1373            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1374            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1375            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1376            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1377            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1378            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1379            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1380            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1381            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1382            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1383            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1384            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1385            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1386            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1387            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1388            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1389            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1390            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1391            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1392            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1393            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1394            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1395            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1396            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1397            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1398            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1399            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1400            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1401            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1402            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1403            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1404            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1405            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1406            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1407            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1408            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1409            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1410            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1411            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1412            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1413            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1414            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1415            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1416            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1417            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1418            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1419            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1420            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1421            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1422            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1423            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1424            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1425            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1426            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1427            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1428            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1429            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1430            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1431            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1432            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1433            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1434            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1435            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1436            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1437            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1438            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1439            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1440            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1441            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1442            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1443            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1444            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1445            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1446            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1447            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1448            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1449            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1450            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1451            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1452            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1453            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1454            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1455            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1456            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1457            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1458            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1459            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1460            0x88,
1461        ];
1462
1463        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1464
1465        let frames = [
1466            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1467            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1468            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1469            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1470            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1471            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1472            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1473            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1474            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1475            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1476            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1477            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1478            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1479            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1480            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1481            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1482            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1483            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1484            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1485            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1486            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1487            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1488            0x00, 0xff, 0xff,
1489        ];
1490
1491        assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4);
1492    }
1493
1494    #[test]
1495    fn decrypt_server_initial_v1() {
1496        let mut pkt = [
1497            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1498            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1499            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1500            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1501            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1502            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1503            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1504            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1505            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1506            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1507            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1508            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1509            0xd0, 0x74, 0xee,
1510        ];
1511
1512        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1513
1514        let frames = [
1515            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1516            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1517            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1518            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1519            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1520            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1521            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1522            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1523            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1524        ];
1525
1526        assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2);
1527    }
1528
1529    #[test]
1530    fn decrypt_chacha20() {
1531        let secret = [
1532            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1533            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1534            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1535        ];
1536
1537        let mut pkt = [
1538            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1539            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1540        ];
1541
1542        let mut b = octets::OctetsMut::with_slice(&mut pkt);
1543
1544        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1545
1546        let aead = crypto::Open::from_secret(alg, &secret).unwrap();
1547
1548        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1549        assert_eq!(hdr.ty, Type::Short);
1550
1551        let payload_len = b.cap();
1552
1553        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1554        assert_eq!(hdr.pkt_num_len, 3);
1555
1556        let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len);
1557        assert_eq!(pn, 654_360_564);
1558
1559        let payload =
1560            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1561
1562        let payload = payload.as_ref();
1563        assert_eq!(&payload, &[0x01]);
1564    }
1565
1566    fn assert_encrypt_initial_pkt(
1567        header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize,
1568        is_server: bool, expected_pkt: &[u8],
1569    ) {
1570        let mut b = octets::OctetsMut::with_slice(header);
1571
1572        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1573        assert_eq!(hdr.ty, Type::Initial);
1574
1575        let mut out = vec![0; expected_pkt.len()];
1576        let mut b = octets::OctetsMut::with_slice(&mut out);
1577
1578        b.put_bytes(header).unwrap();
1579
1580        let (_, aead) = crypto::derive_initial_key_material(
1581            dcid,
1582            hdr.version,
1583            is_server,
1584            false,
1585        )
1586        .unwrap();
1587
1588        let payload_len = frames.len();
1589
1590        let payload_offset = b.off();
1591
1592        b.put_bytes(frames).unwrap();
1593
1594        let written = encrypt_pkt(
1595            &mut b,
1596            pn,
1597            pn_len,
1598            payload_len,
1599            payload_offset,
1600            None,
1601            &aead,
1602        )
1603        .unwrap();
1604
1605        assert_eq!(written, expected_pkt.len());
1606        assert_eq!(&out[..written], expected_pkt);
1607    }
1608
1609    #[test]
1610    fn encrypt_client_initial_v1() {
1611        let mut header = [
1612            0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1613            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
1614        ];
1615
1616        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1617
1618        let frames = [
1619            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1620            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1621            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1622            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1623            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1624            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1625            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1626            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1627            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1628            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1629            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1630            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1631            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1632            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1633            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1634            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1635            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1636            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1637            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1638            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1639            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1640            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1641            0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1651            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1652            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1653            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1654            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1655            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1656            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1657            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1661            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1664            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1666            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1668            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1671            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1677            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1678            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1679            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1681            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1682            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1686            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1687            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1688            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1689            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1692            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1693            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1694            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1695            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1696            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1697            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1698            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1701            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1702            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1703            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1704            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1705            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1709            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1711            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1712            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1713            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1714            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1716            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1717            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1718            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1719            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1721            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1723            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1724            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1725        ];
1726
1727        let pkt = [
1728            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1729            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1730            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1731            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1732            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1733            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1734            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1735            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1736            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1737            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1738            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1739            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1740            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1741            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1742            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1743            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1744            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1745            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1746            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1747            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1748            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1749            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1750            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1751            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1752            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1753            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1754            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1755            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1756            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1757            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1758            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1759            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1760            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1761            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1762            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1763            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1764            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1765            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1766            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1767            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1768            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1769            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1770            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1771            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1772            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1773            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1774            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1775            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1776            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1777            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1778            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1779            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1780            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1781            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1782            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1783            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1784            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1785            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1786            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1787            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1788            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1789            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1790            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1791            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1792            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1793            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1794            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1795            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1796            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1797            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1798            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1799            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1800            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1801            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1802            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1803            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1804            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1805            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1806            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1807            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1808            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1809            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1810            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1811            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1812            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1813            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1814            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1815            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1816            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1817            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1818            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1819            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1820            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1821            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1822            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1823            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1824            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1825            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1826            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1827            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1828            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1829            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1830            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1831            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1832            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1833            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1834            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1835            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1836            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1837            0x88,
1838        ];
1839
1840        assert_encrypt_initial_pkt(
1841            &mut header,
1842            &dcid,
1843            &frames,
1844            2,
1845            4,
1846            false,
1847            &pkt,
1848        );
1849    }
1850
1851    #[test]
1852    fn encrypt_server_initial_v1() {
1853        let mut header = [
1854            0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1855            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01,
1856        ];
1857
1858        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1859
1860        let frames = [
1861            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1862            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1863            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1864            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1865            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1866            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1867            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1868            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1869            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1870        ];
1871
1872        let pkt = [
1873            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1874            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1875            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1876            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1877            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1878            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1879            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1880            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1881            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1882            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1883            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1884            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1885            0xd0, 0x74, 0xee,
1886        ];
1887
1888        assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt);
1889    }
1890
1891    #[test]
1892    fn encrypt_chacha20() {
1893        let secret = [
1894            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1895            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1896            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1897        ];
1898
1899        let mut header = [0x42, 0x00, 0xbf, 0xf4];
1900
1901        let expected_pkt = [
1902            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1903            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1904        ];
1905
1906        let mut b = octets::OctetsMut::with_slice(&mut header);
1907
1908        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1909        assert_eq!(hdr.ty, Type::Short);
1910
1911        let mut out = vec![0; expected_pkt.len()];
1912        let mut b = octets::OctetsMut::with_slice(&mut out);
1913
1914        b.put_bytes(&header).unwrap();
1915
1916        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1917
1918        let aead = crypto::Seal::from_secret(alg, &secret).unwrap();
1919
1920        let pn = 654_360_564;
1921        let pn_len = 3;
1922
1923        let frames = [0x01];
1924
1925        let payload_len = frames.len();
1926
1927        let payload_offset = b.off();
1928
1929        b.put_bytes(&frames).unwrap();
1930
1931        let written = encrypt_pkt(
1932            &mut b,
1933            pn,
1934            pn_len,
1935            payload_len,
1936            payload_offset,
1937            None,
1938            &aead,
1939        )
1940        .unwrap();
1941
1942        assert_eq!(written, expected_pkt.len());
1943        assert_eq!(&out[..written], &expected_pkt[..]);
1944    }
1945
1946    #[test]
1947    fn decrypt_pkt_underflow() {
1948        let mut buf = [0; 65535];
1949        let mut b = octets::OctetsMut::with_slice(&mut buf);
1950
1951        let hdr = Header {
1952            ty: Type::Initial,
1953            version: crate::PROTOCOL_VERSION,
1954            dcid: ConnectionId::default(),
1955            scid: ConnectionId::default(),
1956            pkt_num: 0,
1957            pkt_num_len: 0,
1958            token: None,
1959            versions: None,
1960            key_phase: false,
1961        };
1962
1963        hdr.to_bytes(&mut b).unwrap();
1964
1965        b.put_bytes(&[0; 50]).unwrap();
1966
1967        let payload_len = b.get_varint().unwrap() as usize;
1968
1969        let (aead, _) =
1970            crypto::derive_initial_key_material(b"", hdr.version, true, false)
1971                .unwrap();
1972
1973        assert_eq!(
1974            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
1975            Err(Error::InvalidPacket)
1976        );
1977    }
1978
1979    #[test]
1980    fn decrypt_pkt_too_small() {
1981        let mut buf = [0; 65535];
1982        let mut b = octets::OctetsMut::with_slice(&mut buf);
1983
1984        let hdr = Header {
1985            ty: Type::Initial,
1986            version: crate::PROTOCOL_VERSION,
1987            dcid: ConnectionId::default(),
1988            scid: ConnectionId::default(),
1989            pkt_num: 0,
1990            pkt_num_len: 0,
1991            token: None,
1992            versions: None,
1993            key_phase: false,
1994        };
1995
1996        hdr.to_bytes(&mut b).unwrap();
1997
1998        b.put_bytes(&[0; 1]).unwrap();
1999
2000        // No space for decryption.
2001        let payload_len = 1;
2002
2003        let (aead, _) =
2004            crypto::derive_initial_key_material(b"", hdr.version, true, false)
2005                .unwrap();
2006
2007        assert_eq!(
2008            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
2009            Err(Error::CryptoFail)
2010        );
2011    }
2012}