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 + 7) / 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    pub largest_rx_pkt_num: u64,
857
858    pub largest_rx_pkt_time: time::Instant,
859
860    pub largest_rx_non_probing_pkt_num: u64,
861
862    pub recv_pkt_need_ack: ranges::RangeSet,
863
864    pub recv_pkt_num: PktNumWindow,
865
866    pub ack_elicited: bool,
867
868    pub key_update: Option<KeyUpdate>,
869
870    pub crypto_open: Option<crypto::Open>,
871    pub crypto_seal: Option<crypto::Seal>,
872
873    pub crypto_0rtt_open: Option<crypto::Open>,
874
875    pub crypto_stream: stream::Stream,
876}
877
878impl PktNumSpace {
879    pub fn new() -> PktNumSpace {
880        PktNumSpace {
881            largest_rx_pkt_num: 0,
882
883            largest_rx_pkt_time: time::Instant::now(),
884
885            largest_rx_non_probing_pkt_num: 0,
886
887            recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES),
888
889            recv_pkt_num: PktNumWindow::default(),
890
891            ack_elicited: false,
892
893            key_update: None,
894
895            crypto_open: None,
896            crypto_seal: None,
897
898            crypto_0rtt_open: None,
899
900            crypto_stream: stream::Stream::new(
901                0, // dummy
902                u64::MAX,
903                u64::MAX,
904                true,
905                true,
906                stream::MAX_STREAM_WINDOW,
907            ),
908        }
909    }
910
911    pub fn clear(&mut self) {
912        self.crypto_stream = stream::Stream::new(
913            0, // dummy
914            u64::MAX,
915            u64::MAX,
916            true,
917            true,
918            stream::MAX_STREAM_WINDOW,
919        );
920
921        self.ack_elicited = false;
922    }
923
924    pub fn crypto_overhead(&self) -> Option<usize> {
925        Some(self.crypto_seal.as_ref()?.alg().tag_len())
926    }
927
928    pub fn ready(&self) -> bool {
929        self.crypto_stream.is_flushable() || self.ack_elicited
930    }
931
932    pub fn has_keys(&self) -> bool {
933        self.crypto_open.is_some() && self.crypto_seal.is_some()
934    }
935}
936
937#[derive(Clone, Copy, Default)]
938pub struct PktNumWindow {
939    lower: u64,
940    window: u128,
941}
942
943impl PktNumWindow {
944    pub fn insert(&mut self, seq: u64) {
945        // Packet is on the left end of the window.
946        if seq < self.lower {
947            return;
948        }
949
950        // Packet is on the right end of the window.
951        if seq > self.upper() {
952            let diff = seq - self.upper();
953            self.lower += diff;
954
955            self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
956        }
957
958        let mask = 1_u128 << (self.upper() - seq);
959        self.window |= mask;
960    }
961
962    pub fn contains(&mut self, seq: u64) -> bool {
963        // Packet is on the right end of the window.
964        if seq > self.upper() {
965            return false;
966        }
967
968        // Packet is on the left end of the window.
969        if seq < self.lower {
970            return true;
971        }
972
973        let mask = 1_u128 << (self.upper() - seq);
974        self.window & mask != 0
975    }
976
977    fn upper(&self) -> u64 {
978        self.lower
979            .saturating_add(std::mem::size_of::<u128>() as u64 * 8) -
980            1
981    }
982}
983
984#[cfg(test)]
985mod tests {
986    use super::*;
987
988    #[test]
989    fn retry() {
990        let hdr = Header {
991            ty: Type::Retry,
992            version: 0xafafafaf,
993            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
994                .into(),
995            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
996            pkt_num: 0,
997            pkt_num_len: 0,
998            token: Some(vec![0xba; 24]),
999            versions: None,
1000            key_phase: false,
1001        };
1002
1003        let mut d = [0; 63];
1004
1005        let mut b = octets::OctetsMut::with_slice(&mut d);
1006        assert!(hdr.to_bytes(&mut b).is_ok());
1007
1008        // Add fake retry integrity token.
1009        b.put_bytes(&[0xba; 16]).unwrap();
1010
1011        let mut b = octets::OctetsMut::with_slice(&mut d);
1012        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1013    }
1014
1015    #[test]
1016    fn initial() {
1017        let hdr = Header {
1018            ty: Type::Initial,
1019            version: 0xafafafaf,
1020            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1021                .into(),
1022            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1023            pkt_num: 0,
1024            pkt_num_len: 0,
1025            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1026            versions: None,
1027            key_phase: false,
1028        };
1029
1030        let mut d = [0; 50];
1031
1032        let mut b = octets::OctetsMut::with_slice(&mut d);
1033        assert!(hdr.to_bytes(&mut b).is_ok());
1034
1035        let mut b = octets::OctetsMut::with_slice(&mut d);
1036        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1037    }
1038
1039    #[test]
1040    fn initial_v1_dcid_too_long() {
1041        let hdr = Header {
1042            ty: Type::Initial,
1043            version: crate::PROTOCOL_VERSION,
1044            dcid: vec![
1045                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1046                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1047            ]
1048            .into(),
1049            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1050            pkt_num: 0,
1051            pkt_num_len: 0,
1052            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1053            versions: None,
1054            key_phase: false,
1055        };
1056
1057        let mut d = [0; 50];
1058
1059        let mut b = octets::OctetsMut::with_slice(&mut d);
1060        assert!(hdr.to_bytes(&mut b).is_ok());
1061
1062        let mut b = octets::OctetsMut::with_slice(&mut d);
1063        assert_eq!(Header::from_bytes(&mut b, 21), Err(Error::InvalidPacket));
1064    }
1065
1066    #[test]
1067    fn initial_v1_scid_too_long() {
1068        let hdr = Header {
1069            ty: Type::Initial,
1070            version: crate::PROTOCOL_VERSION,
1071            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1072                .into(),
1073            scid: vec![
1074                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1075                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1076            ]
1077            .into(),
1078            pkt_num: 0,
1079            pkt_num_len: 0,
1080            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1081            versions: None,
1082            key_phase: false,
1083        };
1084
1085        let mut d = [0; 50];
1086
1087        let mut b = octets::OctetsMut::with_slice(&mut d);
1088        assert!(hdr.to_bytes(&mut b).is_ok());
1089
1090        let mut b = octets::OctetsMut::with_slice(&mut d);
1091        assert_eq!(Header::from_bytes(&mut b, 9), Err(Error::InvalidPacket));
1092    }
1093
1094    #[test]
1095    fn initial_non_v1_scid_long() {
1096        let hdr = Header {
1097            ty: Type::Initial,
1098            version: 0xafafafaf,
1099            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1100                .into(),
1101            scid: vec![
1102                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1103                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1104            ]
1105            .into(),
1106            pkt_num: 0,
1107            pkt_num_len: 0,
1108            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1109            versions: None,
1110            key_phase: false,
1111        };
1112
1113        let mut d = [0; 50];
1114
1115        let mut b = octets::OctetsMut::with_slice(&mut d);
1116        assert!(hdr.to_bytes(&mut b).is_ok());
1117
1118        let mut b = octets::OctetsMut::with_slice(&mut d);
1119        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1120    }
1121
1122    #[test]
1123    fn handshake() {
1124        let hdr = Header {
1125            ty: Type::Handshake,
1126            version: 0xafafafaf,
1127            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1128                .into(),
1129            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1130            pkt_num: 0,
1131            pkt_num_len: 0,
1132            token: None,
1133            versions: None,
1134            key_phase: false,
1135        };
1136
1137        let mut d = [0; 50];
1138
1139        let mut b = octets::OctetsMut::with_slice(&mut d);
1140        assert!(hdr.to_bytes(&mut b).is_ok());
1141
1142        let mut b = octets::OctetsMut::with_slice(&mut d);
1143        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1144    }
1145
1146    #[test]
1147    fn application() {
1148        let hdr = Header {
1149            ty: Type::Short,
1150            version: 0,
1151            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1152                .into(),
1153            scid: ConnectionId::default(),
1154            pkt_num: 0,
1155            pkt_num_len: 0,
1156            token: None,
1157            versions: None,
1158            key_phase: false,
1159        };
1160
1161        let mut d = [0; 50];
1162
1163        let mut b = octets::OctetsMut::with_slice(&mut d);
1164        assert!(hdr.to_bytes(&mut b).is_ok());
1165
1166        let mut b = octets::OctetsMut::with_slice(&mut d);
1167        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1168    }
1169
1170    #[test]
1171    fn pkt_num_encode_decode() {
1172        let num_len = pkt_num_len(0, 0);
1173        assert_eq!(num_len, 1);
1174        let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2);
1175        assert_eq!(pn, 0xa82f9b32);
1176        let mut d = [0; 10];
1177        let mut b = octets::OctetsMut::with_slice(&mut d);
1178        let num_len = pkt_num_len(0xac5c02, 0xabe8b3);
1179        assert_eq!(num_len, 2);
1180        encode_pkt_num(0xac5c02, num_len, &mut b).unwrap();
1181        // reading
1182        let mut b = octets::OctetsMut::with_slice(&mut d);
1183        let hdr_num = u64::from(b.get_u16().unwrap());
1184        let pn = decode_pkt_num(0xac5c01, hdr_num, num_len);
1185        assert_eq!(pn, 0xac5c02);
1186        // sending 0xace8fe while having 0xabe8b3 acked
1187        let num_len = pkt_num_len(0xace9fe, 0xabe8b3);
1188        assert_eq!(num_len, 3);
1189        let mut b = octets::OctetsMut::with_slice(&mut d);
1190        encode_pkt_num(0xace9fe, num_len, &mut b).unwrap();
1191        // reading
1192        let mut b = octets::OctetsMut::with_slice(&mut d);
1193        let hdr_num = u64::from(b.get_u24().unwrap());
1194        let pn = decode_pkt_num(0xace9fa, hdr_num, num_len);
1195        assert_eq!(pn, 0xace9fe);
1196    }
1197
1198    #[test]
1199    fn pkt_num_window() {
1200        let mut win = PktNumWindow::default();
1201        assert_eq!(win.lower, 0);
1202        assert!(!win.contains(0));
1203        assert!(!win.contains(1));
1204
1205        win.insert(0);
1206        assert_eq!(win.lower, 0);
1207        assert!(win.contains(0));
1208        assert!(!win.contains(1));
1209
1210        win.insert(1);
1211        assert_eq!(win.lower, 0);
1212        assert!(win.contains(0));
1213        assert!(win.contains(1));
1214
1215        win.insert(3);
1216        assert_eq!(win.lower, 0);
1217        assert!(win.contains(0));
1218        assert!(win.contains(1));
1219        assert!(!win.contains(2));
1220        assert!(win.contains(3));
1221
1222        win.insert(10);
1223        assert_eq!(win.lower, 0);
1224        assert!(win.contains(0));
1225        assert!(win.contains(1));
1226        assert!(!win.contains(2));
1227        assert!(win.contains(3));
1228        assert!(!win.contains(4));
1229        assert!(!win.contains(5));
1230        assert!(!win.contains(6));
1231        assert!(!win.contains(7));
1232        assert!(!win.contains(8));
1233        assert!(!win.contains(9));
1234        assert!(win.contains(10));
1235
1236        win.insert(132);
1237        assert_eq!(win.lower, 5);
1238        assert!(win.contains(0));
1239        assert!(win.contains(1));
1240        assert!(win.contains(2));
1241        assert!(win.contains(3));
1242        assert!(win.contains(4));
1243        assert!(!win.contains(5));
1244        assert!(!win.contains(6));
1245        assert!(!win.contains(7));
1246        assert!(!win.contains(8));
1247        assert!(!win.contains(9));
1248        assert!(win.contains(10));
1249        assert!(!win.contains(128));
1250        assert!(!win.contains(130));
1251        assert!(!win.contains(131));
1252        assert!(win.contains(132));
1253
1254        win.insert(1024);
1255        assert_eq!(win.lower, 897);
1256        assert!(win.contains(0));
1257        assert!(win.contains(1));
1258        assert!(win.contains(2));
1259        assert!(win.contains(3));
1260        assert!(win.contains(4));
1261        assert!(win.contains(5));
1262        assert!(win.contains(6));
1263        assert!(win.contains(7));
1264        assert!(win.contains(8));
1265        assert!(win.contains(9));
1266        assert!(win.contains(10));
1267        assert!(win.contains(128));
1268        assert!(win.contains(130));
1269        assert!(win.contains(132));
1270        assert!(win.contains(896));
1271        assert!(!win.contains(897));
1272        assert!(!win.contains(1022));
1273        assert!(!win.contains(1023));
1274        assert!(win.contains(1024));
1275        assert!(!win.contains(1025));
1276        assert!(!win.contains(1026));
1277
1278        win.insert(u64::MAX - 1);
1279        assert!(win.contains(0));
1280        assert!(win.contains(1));
1281        assert!(win.contains(2));
1282        assert!(win.contains(3));
1283        assert!(win.contains(4));
1284        assert!(win.contains(5));
1285        assert!(win.contains(6));
1286        assert!(win.contains(7));
1287        assert!(win.contains(8));
1288        assert!(win.contains(9));
1289        assert!(win.contains(10));
1290        assert!(win.contains(128));
1291        assert!(win.contains(130));
1292        assert!(win.contains(132));
1293        assert!(win.contains(896));
1294        assert!(win.contains(897));
1295        assert!(win.contains(1022));
1296        assert!(win.contains(1023));
1297        assert!(win.contains(1024));
1298        assert!(win.contains(1025));
1299        assert!(win.contains(1026));
1300        assert!(!win.contains(u64::MAX - 2));
1301        assert!(win.contains(u64::MAX - 1));
1302    }
1303
1304    fn assert_decrypt_initial_pkt(
1305        pkt: &mut [u8], dcid: &[u8], is_server: bool, expected_frames: &[u8],
1306        expected_pn: u64, expected_pn_len: usize,
1307    ) {
1308        let mut b = octets::OctetsMut::with_slice(pkt);
1309
1310        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1311        assert_eq!(hdr.ty, Type::Initial);
1312
1313        let payload_len = b.get_varint().unwrap() as usize;
1314
1315        let (aead, _) =
1316            crypto::derive_initial_key_material(dcid, hdr.version, is_server)
1317                .unwrap();
1318
1319        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1320        assert_eq!(hdr.pkt_num_len, expected_pn_len);
1321
1322        let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len);
1323        assert_eq!(pn, expected_pn);
1324
1325        let payload =
1326            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1327
1328        let payload = payload.as_ref();
1329        assert_eq!(&payload[..expected_frames.len()], expected_frames);
1330    }
1331
1332    #[test]
1333    fn decrypt_client_initial_v1() {
1334        let mut pkt = [
1335            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1336            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1337            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1338            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1339            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1340            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1341            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1342            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1343            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1344            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1345            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1346            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1347            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1348            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1349            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1350            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1351            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1352            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1353            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1354            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1355            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1356            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1357            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1358            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1359            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1360            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1361            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1362            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1363            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1364            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1365            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1366            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1367            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1368            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1369            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1370            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1371            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1372            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1373            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1374            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1375            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1376            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1377            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1378            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1379            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1380            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1381            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1382            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1383            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1384            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1385            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1386            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1387            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1388            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1389            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1390            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1391            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1392            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1393            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1394            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1395            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1396            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1397            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1398            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1399            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1400            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1401            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1402            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1403            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1404            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1405            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1406            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1407            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1408            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1409            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1410            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1411            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1412            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1413            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1414            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1415            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1416            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1417            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1418            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1419            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1420            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1421            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1422            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1423            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1424            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1425            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1426            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1427            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1428            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1429            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1430            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1431            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1432            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1433            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1434            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1435            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1436            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1437            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1438            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1439            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1440            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1441            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1442            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1443            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1444            0x88,
1445        ];
1446
1447        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1448
1449        let frames = [
1450            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1451            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1452            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1453            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1454            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1455            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1456            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1457            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1458            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1459            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1460            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1461            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1462            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1463            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1464            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1465            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1466            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1467            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1468            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1469            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1470            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1471            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1472            0x00, 0xff, 0xff,
1473        ];
1474
1475        assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4);
1476    }
1477
1478    #[test]
1479    fn decrypt_server_initial_v1() {
1480        let mut pkt = [
1481            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1482            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1483            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1484            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1485            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1486            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1487            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1488            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1489            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1490            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1491            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1492            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1493            0xd0, 0x74, 0xee,
1494        ];
1495
1496        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1497
1498        let frames = [
1499            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1500            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1501            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1502            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1503            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1504            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1505            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1506            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1507            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1508        ];
1509
1510        assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2);
1511    }
1512
1513    #[test]
1514    fn decrypt_chacha20() {
1515        let secret = [
1516            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1517            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1518            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1519        ];
1520
1521        let mut pkt = [
1522            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1523            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1524        ];
1525
1526        let mut b = octets::OctetsMut::with_slice(&mut pkt);
1527
1528        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1529
1530        let aead = crypto::Open::from_secret(alg, &secret).unwrap();
1531
1532        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1533        assert_eq!(hdr.ty, Type::Short);
1534
1535        let payload_len = b.cap();
1536
1537        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1538        assert_eq!(hdr.pkt_num_len, 3);
1539
1540        let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len);
1541        assert_eq!(pn, 654_360_564);
1542
1543        let payload =
1544            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1545
1546        let payload = payload.as_ref();
1547        assert_eq!(&payload, &[0x01]);
1548    }
1549
1550    fn assert_encrypt_initial_pkt(
1551        header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize,
1552        is_server: bool, expected_pkt: &[u8],
1553    ) {
1554        let mut b = octets::OctetsMut::with_slice(header);
1555
1556        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1557        assert_eq!(hdr.ty, Type::Initial);
1558
1559        let mut out = vec![0; expected_pkt.len()];
1560        let mut b = octets::OctetsMut::with_slice(&mut out);
1561
1562        b.put_bytes(header).unwrap();
1563
1564        let (_, aead) =
1565            crypto::derive_initial_key_material(dcid, hdr.version, is_server)
1566                .unwrap();
1567
1568        let payload_len = frames.len();
1569
1570        let payload_offset = b.off();
1571
1572        b.put_bytes(frames).unwrap();
1573
1574        let written = encrypt_pkt(
1575            &mut b,
1576            pn,
1577            pn_len,
1578            payload_len,
1579            payload_offset,
1580            None,
1581            &aead,
1582        )
1583        .unwrap();
1584
1585        assert_eq!(written, expected_pkt.len());
1586        assert_eq!(&out[..written], expected_pkt);
1587    }
1588
1589    #[test]
1590    fn encrypt_client_initial_v1() {
1591        let mut header = [
1592            0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1593            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
1594        ];
1595
1596        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1597
1598        let frames = [
1599            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1600            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1601            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1602            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1603            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1604            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1605            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1606            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1607            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1608            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1609            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1610            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1611            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1612            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1613            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1614            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1615            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1616            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1617            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1618            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1619            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1620            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1621            0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1622            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1623            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1624            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1625            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1629            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1630            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1631            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1632            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1633            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1638            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1639            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641            0x00, 0x00, 0x00, 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,
1705        ];
1706
1707        let pkt = [
1708            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1709            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1710            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1711            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1712            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1713            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1714            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1715            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1716            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1717            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1718            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1719            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1720            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1721            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1722            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1723            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1724            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1725            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1726            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1727            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1728            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1729            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1730            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1731            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1732            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1733            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1734            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1735            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1736            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1737            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1738            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1739            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1740            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1741            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1742            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1743            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1744            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1745            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1746            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1747            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1748            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1749            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1750            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1751            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1752            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1753            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1754            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1755            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1756            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1757            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1758            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1759            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1760            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1761            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1762            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1763            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1764            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1765            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1766            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1767            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1768            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1769            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1770            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1771            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1772            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1773            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1774            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1775            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1776            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1777            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1778            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1779            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1780            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1781            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1782            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1783            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1784            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1785            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1786            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1787            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1788            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1789            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1790            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1791            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1792            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1793            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1794            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1795            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1796            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1797            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1798            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1799            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1800            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1801            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1802            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1803            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1804            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1805            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1806            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1807            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1808            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1809            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1810            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1811            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1812            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1813            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1814            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1815            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1816            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1817            0x88,
1818        ];
1819
1820        assert_encrypt_initial_pkt(
1821            &mut header,
1822            &dcid,
1823            &frames,
1824            2,
1825            4,
1826            false,
1827            &pkt,
1828        );
1829    }
1830
1831    #[test]
1832    fn encrypt_server_initial_v1() {
1833        let mut header = [
1834            0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1835            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01,
1836        ];
1837
1838        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1839
1840        let frames = [
1841            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1842            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1843            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1844            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1845            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1846            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1847            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1848            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1849            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1850        ];
1851
1852        let pkt = [
1853            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1854            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1855            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1856            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1857            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1858            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1859            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1860            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1861            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1862            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1863            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1864            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1865            0xd0, 0x74, 0xee,
1866        ];
1867
1868        assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt);
1869    }
1870
1871    #[test]
1872    fn encrypt_chacha20() {
1873        let secret = [
1874            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1875            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1876            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1877        ];
1878
1879        let mut header = [0x42, 0x00, 0xbf, 0xf4];
1880
1881        let expected_pkt = [
1882            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1883            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1884        ];
1885
1886        let mut b = octets::OctetsMut::with_slice(&mut header);
1887
1888        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1889        assert_eq!(hdr.ty, Type::Short);
1890
1891        let mut out = vec![0; expected_pkt.len()];
1892        let mut b = octets::OctetsMut::with_slice(&mut out);
1893
1894        b.put_bytes(&header).unwrap();
1895
1896        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1897
1898        let aead = crypto::Seal::from_secret(alg, &secret).unwrap();
1899
1900        let pn = 654_360_564;
1901        let pn_len = 3;
1902
1903        let frames = [0x01];
1904
1905        let payload_len = frames.len();
1906
1907        let payload_offset = b.off();
1908
1909        b.put_bytes(&frames).unwrap();
1910
1911        let written = encrypt_pkt(
1912            &mut b,
1913            pn,
1914            pn_len,
1915            payload_len,
1916            payload_offset,
1917            None,
1918            &aead,
1919        )
1920        .unwrap();
1921
1922        assert_eq!(written, expected_pkt.len());
1923        assert_eq!(&out[..written], &expected_pkt[..]);
1924    }
1925
1926    #[test]
1927    fn decrypt_pkt_underflow() {
1928        let mut buf = [0; 65535];
1929        let mut b = octets::OctetsMut::with_slice(&mut buf);
1930
1931        let hdr = Header {
1932            ty: Type::Initial,
1933            version: crate::PROTOCOL_VERSION,
1934            dcid: ConnectionId::default(),
1935            scid: ConnectionId::default(),
1936            pkt_num: 0,
1937            pkt_num_len: 0,
1938            token: None,
1939            versions: None,
1940            key_phase: false,
1941        };
1942
1943        hdr.to_bytes(&mut b).unwrap();
1944
1945        b.put_bytes(&[0; 50]).unwrap();
1946
1947        let payload_len = b.get_varint().unwrap() as usize;
1948
1949        let (aead, _) =
1950            crypto::derive_initial_key_material(b"", hdr.version, true).unwrap();
1951
1952        assert_eq!(
1953            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
1954            Err(Error::InvalidPacket)
1955        );
1956    }
1957
1958    #[test]
1959    fn decrypt_pkt_too_small() {
1960        let mut buf = [0; 65535];
1961        let mut b = octets::OctetsMut::with_slice(&mut buf);
1962
1963        let hdr = Header {
1964            ty: Type::Initial,
1965            version: crate::PROTOCOL_VERSION,
1966            dcid: ConnectionId::default(),
1967            scid: ConnectionId::default(),
1968            pkt_num: 0,
1969            pkt_num_len: 0,
1970            token: None,
1971            versions: None,
1972            key_phase: false,
1973        };
1974
1975        hdr.to_bytes(&mut b).unwrap();
1976
1977        b.put_bytes(&[0; 1]).unwrap();
1978
1979        // No space for decryption.
1980        let payload_len = 1;
1981
1982        let (aead, _) =
1983            crypto::derive_initial_key_material(b"", hdr.version, true).unwrap();
1984
1985        assert_eq!(
1986            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
1987            Err(Error::CryptoFail)
1988        );
1989    }
1990}