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, _) = crypto::derive_initial_key_material(
1316            dcid,
1317            hdr.version,
1318            is_server,
1319            false,
1320        )
1321        .unwrap();
1322
1323        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1324        assert_eq!(hdr.pkt_num_len, expected_pn_len);
1325
1326        let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len);
1327        assert_eq!(pn, expected_pn);
1328
1329        let payload =
1330            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1331
1332        let payload = payload.as_ref();
1333        assert_eq!(&payload[..expected_frames.len()], expected_frames);
1334    }
1335
1336    #[test]
1337    fn decrypt_client_initial_v1() {
1338        let mut pkt = [
1339            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1340            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1341            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1342            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1343            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1344            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1345            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1346            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1347            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1348            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1349            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1350            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1351            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1352            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1353            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1354            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1355            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1356            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1357            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1358            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1359            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1360            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1361            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1362            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1363            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1364            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1365            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1366            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1367            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1368            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1369            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1370            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1371            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1372            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1373            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1374            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1375            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1376            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1377            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1378            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1379            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1380            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1381            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1382            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1383            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1384            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1385            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1386            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1387            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1388            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1389            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1390            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1391            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1392            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1393            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1394            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1395            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1396            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1397            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1398            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1399            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1400            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1401            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1402            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1403            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1404            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1405            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1406            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1407            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1408            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1409            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1410            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1411            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1412            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1413            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1414            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1415            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1416            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1417            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1418            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1419            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1420            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1421            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1422            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1423            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1424            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1425            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1426            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1427            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1428            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1429            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1430            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1431            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1432            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1433            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1434            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1435            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1436            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1437            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1438            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1439            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1440            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1441            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1442            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1443            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1444            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1445            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1446            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1447            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1448            0x88,
1449        ];
1450
1451        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1452
1453        let frames = [
1454            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1455            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1456            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1457            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1458            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1459            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1460            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1461            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1462            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1463            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1464            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1465            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1466            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1467            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1468            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1469            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1470            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1471            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1472            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1473            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1474            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1475            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1476            0x00, 0xff, 0xff,
1477        ];
1478
1479        assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4);
1480    }
1481
1482    #[test]
1483    fn decrypt_server_initial_v1() {
1484        let mut pkt = [
1485            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1486            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1487            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1488            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1489            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1490            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1491            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1492            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1493            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1494            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1495            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1496            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1497            0xd0, 0x74, 0xee,
1498        ];
1499
1500        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1501
1502        let frames = [
1503            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1504            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1505            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1506            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1507            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1508            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1509            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1510            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1511            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1512        ];
1513
1514        assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2);
1515    }
1516
1517    #[test]
1518    fn decrypt_chacha20() {
1519        let secret = [
1520            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1521            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1522            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1523        ];
1524
1525        let mut pkt = [
1526            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1527            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1528        ];
1529
1530        let mut b = octets::OctetsMut::with_slice(&mut pkt);
1531
1532        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1533
1534        let aead = crypto::Open::from_secret(alg, &secret).unwrap();
1535
1536        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1537        assert_eq!(hdr.ty, Type::Short);
1538
1539        let payload_len = b.cap();
1540
1541        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1542        assert_eq!(hdr.pkt_num_len, 3);
1543
1544        let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len);
1545        assert_eq!(pn, 654_360_564);
1546
1547        let payload =
1548            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1549
1550        let payload = payload.as_ref();
1551        assert_eq!(&payload, &[0x01]);
1552    }
1553
1554    fn assert_encrypt_initial_pkt(
1555        header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize,
1556        is_server: bool, expected_pkt: &[u8],
1557    ) {
1558        let mut b = octets::OctetsMut::with_slice(header);
1559
1560        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1561        assert_eq!(hdr.ty, Type::Initial);
1562
1563        let mut out = vec![0; expected_pkt.len()];
1564        let mut b = octets::OctetsMut::with_slice(&mut out);
1565
1566        b.put_bytes(header).unwrap();
1567
1568        let (_, aead) = crypto::derive_initial_key_material(
1569            dcid,
1570            hdr.version,
1571            is_server,
1572            false,
1573        )
1574        .unwrap();
1575
1576        let payload_len = frames.len();
1577
1578        let payload_offset = b.off();
1579
1580        b.put_bytes(frames).unwrap();
1581
1582        let written = encrypt_pkt(
1583            &mut b,
1584            pn,
1585            pn_len,
1586            payload_len,
1587            payload_offset,
1588            None,
1589            &aead,
1590        )
1591        .unwrap();
1592
1593        assert_eq!(written, expected_pkt.len());
1594        assert_eq!(&out[..written], expected_pkt);
1595    }
1596
1597    #[test]
1598    fn encrypt_client_initial_v1() {
1599        let mut header = [
1600            0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1601            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
1602        ];
1603
1604        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1605
1606        let frames = [
1607            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1608            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1609            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1610            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1611            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1612            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1613            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1614            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1615            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1616            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1617            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1618            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1619            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1620            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1621            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1622            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1623            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1624            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1625            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1626            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1627            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1628            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1629            0x00, 0xff, 0xff, 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, 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,
1713        ];
1714
1715        let pkt = [
1716            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1717            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1718            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1719            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1720            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1721            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1722            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1723            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1724            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1725            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1726            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1727            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1728            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1729            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1730            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1731            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1732            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1733            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1734            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1735            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1736            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1737            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1738            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1739            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1740            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1741            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1742            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1743            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1744            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1745            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1746            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1747            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1748            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1749            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1750            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1751            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1752            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1753            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1754            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1755            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1756            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1757            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1758            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1759            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1760            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1761            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1762            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1763            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1764            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1765            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1766            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1767            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1768            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1769            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1770            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1771            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1772            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1773            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1774            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1775            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1776            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1777            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1778            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1779            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1780            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1781            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1782            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1783            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1784            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1785            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1786            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1787            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1788            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1789            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1790            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1791            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1792            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1793            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1794            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1795            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1796            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1797            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1798            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1799            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1800            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1801            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1802            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1803            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1804            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1805            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1806            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1807            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1808            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1809            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1810            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1811            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1812            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1813            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1814            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1815            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1816            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1817            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1818            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1819            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1820            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1821            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1822            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1823            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1824            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1825            0x88,
1826        ];
1827
1828        assert_encrypt_initial_pkt(
1829            &mut header,
1830            &dcid,
1831            &frames,
1832            2,
1833            4,
1834            false,
1835            &pkt,
1836        );
1837    }
1838
1839    #[test]
1840    fn encrypt_server_initial_v1() {
1841        let mut header = [
1842            0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1843            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01,
1844        ];
1845
1846        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1847
1848        let frames = [
1849            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1850            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1851            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1852            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1853            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1854            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1855            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1856            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1857            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1858        ];
1859
1860        let pkt = [
1861            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1862            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1863            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1864            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1865            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1866            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1867            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1868            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1869            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1870            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1871            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1872            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1873            0xd0, 0x74, 0xee,
1874        ];
1875
1876        assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt);
1877    }
1878
1879    #[test]
1880    fn encrypt_chacha20() {
1881        let secret = [
1882            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1883            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1884            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1885        ];
1886
1887        let mut header = [0x42, 0x00, 0xbf, 0xf4];
1888
1889        let expected_pkt = [
1890            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1891            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1892        ];
1893
1894        let mut b = octets::OctetsMut::with_slice(&mut header);
1895
1896        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1897        assert_eq!(hdr.ty, Type::Short);
1898
1899        let mut out = vec![0; expected_pkt.len()];
1900        let mut b = octets::OctetsMut::with_slice(&mut out);
1901
1902        b.put_bytes(&header).unwrap();
1903
1904        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1905
1906        let aead = crypto::Seal::from_secret(alg, &secret).unwrap();
1907
1908        let pn = 654_360_564;
1909        let pn_len = 3;
1910
1911        let frames = [0x01];
1912
1913        let payload_len = frames.len();
1914
1915        let payload_offset = b.off();
1916
1917        b.put_bytes(&frames).unwrap();
1918
1919        let written = encrypt_pkt(
1920            &mut b,
1921            pn,
1922            pn_len,
1923            payload_len,
1924            payload_offset,
1925            None,
1926            &aead,
1927        )
1928        .unwrap();
1929
1930        assert_eq!(written, expected_pkt.len());
1931        assert_eq!(&out[..written], &expected_pkt[..]);
1932    }
1933
1934    #[test]
1935    fn decrypt_pkt_underflow() {
1936        let mut buf = [0; 65535];
1937        let mut b = octets::OctetsMut::with_slice(&mut buf);
1938
1939        let hdr = Header {
1940            ty: Type::Initial,
1941            version: crate::PROTOCOL_VERSION,
1942            dcid: ConnectionId::default(),
1943            scid: ConnectionId::default(),
1944            pkt_num: 0,
1945            pkt_num_len: 0,
1946            token: None,
1947            versions: None,
1948            key_phase: false,
1949        };
1950
1951        hdr.to_bytes(&mut b).unwrap();
1952
1953        b.put_bytes(&[0; 50]).unwrap();
1954
1955        let payload_len = b.get_varint().unwrap() as usize;
1956
1957        let (aead, _) =
1958            crypto::derive_initial_key_material(b"", hdr.version, true, false)
1959                .unwrap();
1960
1961        assert_eq!(
1962            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
1963            Err(Error::InvalidPacket)
1964        );
1965    }
1966
1967    #[test]
1968    fn decrypt_pkt_too_small() {
1969        let mut buf = [0; 65535];
1970        let mut b = octets::OctetsMut::with_slice(&mut buf);
1971
1972        let hdr = Header {
1973            ty: Type::Initial,
1974            version: crate::PROTOCOL_VERSION,
1975            dcid: ConnectionId::default(),
1976            scid: ConnectionId::default(),
1977            pkt_num: 0,
1978            pkt_num_len: 0,
1979            token: None,
1980            versions: None,
1981            key_phase: false,
1982        };
1983
1984        hdr.to_bytes(&mut b).unwrap();
1985
1986        b.put_bytes(&[0; 1]).unwrap();
1987
1988        // No space for decryption.
1989        let payload_len = 1;
1990
1991        let (aead, _) =
1992            crypto::derive_initial_key_material(b"", hdr.version, true, false)
1993                .unwrap();
1994
1995        assert_eq!(
1996            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
1997            Err(Error::CryptoFail)
1998        );
1999    }
2000}