1use std::fmt::Display;
28
29use std::ops::Index;
30use std::ops::IndexMut;
31use std::ops::RangeInclusive;
32
33use std::time::Instant;
34
35use crate::Error;
36use crate::Result;
37use crate::DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS;
38
39use crate::crypto;
40use crate::rand;
41use crate::ranges;
42use crate::recovery;
43use crate::stream;
44
45const FORM_BIT: u8 = 0x80;
46const FIXED_BIT: u8 = 0x40;
47const KEY_PHASE_BIT: u8 = 0x04;
48
49const TYPE_MASK: u8 = 0x30;
50const PKT_NUM_MASK: u8 = 0x03;
51
52pub const MAX_CID_LEN: u8 = 20;
53
54pub const MAX_PKT_NUM_LEN: usize = 4;
55
56const SAMPLE_LEN: usize = 16;
57
58const MIN_SKIP_COUNTER_VALUE: u64 =
61 DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS as u64 * 2;
62
63const RETRY_AEAD_ALG: crypto::Algorithm = crypto::Algorithm::AES128_GCM;
64
65#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
66pub enum Epoch {
67 Initial = 0,
68 Handshake = 1,
69 Application = 2,
70}
71
72static EPOCHS: [Epoch; 3] =
73 [Epoch::Initial, Epoch::Handshake, Epoch::Application];
74
75impl Epoch {
76 pub fn epochs(range: RangeInclusive<Epoch>) -> &'static [Epoch] {
79 &EPOCHS[*range.start() as usize..=*range.end() as usize]
80 }
81
82 pub const fn count() -> usize {
83 3
84 }
85}
86
87impl Display for Epoch {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 write!(f, "{}", usize::from(*self))
90 }
91}
92
93impl From<Epoch> for usize {
94 fn from(e: Epoch) -> Self {
95 e as usize
96 }
97}
98
99impl<T> Index<Epoch> for [T]
100where
101 T: Sized,
102{
103 type Output = T;
104
105 fn index(&self, index: Epoch) -> &Self::Output {
106 self.index(usize::from(index))
107 }
108}
109
110impl<T> IndexMut<Epoch> for [T]
111where
112 T: Sized,
113{
114 fn index_mut(&mut self, index: Epoch) -> &mut Self::Output {
115 self.index_mut(usize::from(index))
116 }
117}
118
119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
121pub enum Type {
122 Initial,
124
125 Retry,
127
128 Handshake,
130
131 ZeroRTT,
133
134 VersionNegotiation,
136
137 Short,
139}
140
141impl Type {
142 pub(crate) fn from_epoch(e: Epoch) -> Type {
143 match e {
144 Epoch::Initial => Type::Initial,
145
146 Epoch::Handshake => Type::Handshake,
147
148 Epoch::Application => Type::Short,
149 }
150 }
151
152 pub(crate) fn to_epoch(self) -> Result<Epoch> {
153 match self {
154 Type::Initial => Ok(Epoch::Initial),
155
156 Type::ZeroRTT => Ok(Epoch::Application),
157
158 Type::Handshake => Ok(Epoch::Handshake),
159
160 Type::Short => Ok(Epoch::Application),
161
162 _ => Err(Error::InvalidPacket),
163 }
164 }
165
166 #[cfg(feature = "qlog")]
167 pub(crate) fn to_qlog(self) -> qlog::events::quic::PacketType {
168 match self {
169 Type::Initial => qlog::events::quic::PacketType::Initial,
170
171 Type::Retry => qlog::events::quic::PacketType::Retry,
172
173 Type::Handshake => qlog::events::quic::PacketType::Handshake,
174
175 Type::ZeroRTT => qlog::events::quic::PacketType::ZeroRtt,
176
177 Type::VersionNegotiation =>
178 qlog::events::quic::PacketType::VersionNegotiation,
179
180 Type::Short => qlog::events::quic::PacketType::OneRtt,
181 }
182 }
183}
184
185pub struct ConnectionId<'a>(ConnectionIdInner<'a>);
187
188enum ConnectionIdInner<'a> {
189 Vec(Vec<u8>),
190 Ref(&'a [u8]),
191}
192
193impl<'a> ConnectionId<'a> {
194 #[inline]
196 pub const fn from_vec(cid: Vec<u8>) -> Self {
197 Self(ConnectionIdInner::Vec(cid))
198 }
199
200 #[inline]
202 pub const fn from_ref(cid: &'a [u8]) -> Self {
203 Self(ConnectionIdInner::Ref(cid))
204 }
205
206 #[inline]
208 pub fn into_owned(self) -> ConnectionId<'static> {
209 ConnectionId::from_vec(self.into())
210 }
211}
212
213impl Default for ConnectionId<'_> {
214 #[inline]
215 fn default() -> Self {
216 Self::from_vec(Vec::new())
217 }
218}
219
220impl From<Vec<u8>> for ConnectionId<'_> {
221 #[inline]
222 fn from(v: Vec<u8>) -> Self {
223 Self::from_vec(v)
224 }
225}
226
227impl From<ConnectionId<'_>> for Vec<u8> {
228 #[inline]
229 fn from(id: ConnectionId<'_>) -> Self {
230 match id.0 {
231 ConnectionIdInner::Vec(cid) => cid,
232 ConnectionIdInner::Ref(cid) => cid.to_vec(),
233 }
234 }
235}
236
237impl PartialEq for ConnectionId<'_> {
238 #[inline]
239 fn eq(&self, other: &Self) -> bool {
240 self.as_ref() == other.as_ref()
241 }
242}
243
244impl Eq for ConnectionId<'_> {}
245
246impl AsRef<[u8]> for ConnectionId<'_> {
247 #[inline]
248 fn as_ref(&self) -> &[u8] {
249 match &self.0 {
250 ConnectionIdInner::Vec(v) => v.as_ref(),
251 ConnectionIdInner::Ref(v) => v,
252 }
253 }
254}
255
256impl std::hash::Hash for ConnectionId<'_> {
257 #[inline]
258 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
259 self.as_ref().hash(state);
260 }
261}
262
263impl std::ops::Deref for ConnectionId<'_> {
264 type Target = [u8];
265
266 #[inline]
267 fn deref(&self) -> &[u8] {
268 match &self.0 {
269 ConnectionIdInner::Vec(v) => v.as_ref(),
270 ConnectionIdInner::Ref(v) => v,
271 }
272 }
273}
274
275impl Clone for ConnectionId<'_> {
276 #[inline]
277 fn clone(&self) -> Self {
278 Self::from_vec(self.as_ref().to_vec())
279 }
280}
281
282impl std::fmt::Debug for ConnectionId<'_> {
283 #[inline]
284 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
285 for c in self.as_ref() {
286 write!(f, "{c:02x}")?;
287 }
288
289 Ok(())
290 }
291}
292
293#[derive(Clone, PartialEq, Eq)]
295pub struct Header<'a> {
296 pub ty: Type,
298
299 pub version: u32,
301
302 pub dcid: ConnectionId<'a>,
304
305 pub scid: ConnectionId<'a>,
307
308 pub(crate) pkt_num: u64,
311
312 pub(crate) pkt_num_len: usize,
315
316 pub token: Option<Vec<u8>>,
319
320 pub versions: Option<Vec<u32>>,
323
324 pub(crate) key_phase: bool,
327}
328
329impl<'a> Header<'a> {
330 #[inline]
348 pub fn from_slice<'b>(
349 buf: &'b mut [u8], dcid_len: usize,
350 ) -> Result<Header<'a>> {
351 let mut b = octets::OctetsMut::with_slice(buf);
352 Header::from_bytes(&mut b, dcid_len)
353 }
354
355 pub(crate) fn from_bytes<'b>(
356 b: &'b mut octets::OctetsMut, dcid_len: usize,
357 ) -> Result<Header<'a>> {
358 let first = b.get_u8()?;
359
360 if !Header::is_long(first) {
361 let dcid = b.get_bytes(dcid_len)?;
363
364 return Ok(Header {
365 ty: Type::Short,
366 version: 0,
367 dcid: dcid.to_vec().into(),
368 scid: ConnectionId::default(),
369 pkt_num: 0,
370 pkt_num_len: 0,
371 token: None,
372 versions: None,
373 key_phase: false,
374 });
375 }
376
377 let version = b.get_u32()?;
379
380 let ty = if version == 0 {
381 Type::VersionNegotiation
382 } else {
383 match (first & TYPE_MASK) >> 4 {
384 0x00 => Type::Initial,
385 0x01 => Type::ZeroRTT,
386 0x02 => Type::Handshake,
387 0x03 => Type::Retry,
388 _ => return Err(Error::InvalidPacket),
389 }
390 };
391
392 let dcid_len = b.get_u8()?;
393 if crate::version_is_supported(version) && dcid_len > MAX_CID_LEN {
394 return Err(Error::InvalidPacket);
395 }
396 let dcid = b.get_bytes(dcid_len as usize)?.to_vec();
397
398 let scid_len = b.get_u8()?;
399 if crate::version_is_supported(version) && scid_len > MAX_CID_LEN {
400 return Err(Error::InvalidPacket);
401 }
402 let scid = b.get_bytes(scid_len as usize)?.to_vec();
403
404 let mut token: Option<Vec<u8>> = None;
407 let mut versions: Option<Vec<u32>> = None;
408
409 match ty {
410 Type::Initial => {
411 token = Some(b.get_bytes_with_varint_length()?.to_vec());
412 },
413
414 Type::Retry => {
415 const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
416
417 if b.cap() < TAG_LEN {
419 return Err(Error::InvalidPacket);
420 }
421
422 let token_len = b.cap() - TAG_LEN;
423 token = Some(b.get_bytes(token_len)?.to_vec());
424 },
425
426 Type::VersionNegotiation => {
427 let mut list: Vec<u32> = Vec::new();
428
429 while b.cap() > 0 {
430 let version = b.get_u32()?;
431 list.push(version);
432 }
433
434 versions = Some(list);
435 },
436
437 _ => (),
438 };
439
440 Ok(Header {
441 ty,
442 version,
443 dcid: dcid.into(),
444 scid: scid.into(),
445 pkt_num: 0,
446 pkt_num_len: 0,
447 token,
448 versions,
449 key_phase: false,
450 })
451 }
452
453 pub(crate) fn to_bytes(&self, out: &mut octets::OctetsMut) -> Result<()> {
454 let mut first = 0;
455
456 first |= self.pkt_num_len.saturating_sub(1) as u8;
458
459 if self.ty == Type::Short {
461 first &= !FORM_BIT;
463
464 first |= FIXED_BIT;
466
467 if self.key_phase {
469 first |= KEY_PHASE_BIT;
470 } else {
471 first &= !KEY_PHASE_BIT;
472 }
473
474 out.put_u8(first)?;
475 out.put_bytes(&self.dcid)?;
476
477 return Ok(());
478 }
479
480 let ty: u8 = match self.ty {
482 Type::Initial => 0x00,
483 Type::ZeroRTT => 0x01,
484 Type::Handshake => 0x02,
485 Type::Retry => 0x03,
486 _ => return Err(Error::InvalidPacket),
487 };
488
489 first |= FORM_BIT | FIXED_BIT | (ty << 4);
490
491 out.put_u8(first)?;
492
493 out.put_u32(self.version)?;
494
495 out.put_u8(self.dcid.len() as u8)?;
496 out.put_bytes(&self.dcid)?;
497
498 out.put_u8(self.scid.len() as u8)?;
499 out.put_bytes(&self.scid)?;
500
501 match self.ty {
503 Type::Initial => {
504 match self.token {
505 Some(ref v) => {
506 out.put_varint(v.len() as u64)?;
507 out.put_bytes(v)?;
508 },
509
510 None => {
512 out.put_varint(0)?;
513 },
514 }
515 },
516
517 Type::Retry => {
518 out.put_bytes(self.token.as_ref().unwrap())?;
520 },
521
522 _ => (),
523 }
524
525 Ok(())
526 }
527
528 fn is_long(b: u8) -> bool {
532 b & FORM_BIT != 0
533 }
534}
535
536impl std::fmt::Debug for Header<'_> {
537 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
538 write!(f, "{:?}", self.ty)?;
539
540 if self.ty != Type::Short {
541 write!(f, " version={:x}", self.version)?;
542 }
543
544 write!(f, " dcid={:?}", self.dcid)?;
545
546 if self.ty != Type::Short {
547 write!(f, " scid={:?}", self.scid)?;
548 }
549
550 if let Some(ref token) = self.token {
551 write!(f, " token=")?;
552 for b in token {
553 write!(f, "{b:02x}")?;
554 }
555 }
556
557 if let Some(ref versions) = self.versions {
558 write!(f, " versions={versions:x?}")?;
559 }
560
561 if self.ty == Type::Short {
562 write!(f, " key_phase={}", self.key_phase)?;
563 }
564
565 Ok(())
566 }
567}
568
569pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize {
570 let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1;
571 let min_bits = u64::BITS - num_unacked.leading_zeros();
573 min_bits.div_ceil(8) as usize
575}
576
577pub fn decrypt_hdr(
578 b: &mut octets::OctetsMut, hdr: &mut Header, aead: &crypto::Open,
579) -> Result<()> {
580 let mut first = {
581 let (first_buf, _) = b.split_at(1)?;
582 first_buf.as_ref()[0]
583 };
584
585 let mut pn_and_sample = b.peek_bytes_mut(MAX_PKT_NUM_LEN + SAMPLE_LEN)?;
586
587 let (mut ciphertext, sample) = pn_and_sample.split_at(MAX_PKT_NUM_LEN)?;
588
589 let ciphertext = ciphertext.as_mut();
590
591 let mask = aead.new_mask(sample.as_ref())?;
592
593 if Header::is_long(first) {
594 first ^= mask[0] & 0x0f;
595 } else {
596 first ^= mask[0] & 0x1f;
597 }
598
599 let pn_len = usize::from((first & PKT_NUM_MASK) + 1);
600
601 let ciphertext = &mut ciphertext[..pn_len];
602
603 for i in 0..pn_len {
604 ciphertext[i] ^= mask[i + 1];
605 }
606
607 let pn = match pn_len {
609 1 => u64::from(b.get_u8()?),
610
611 2 => u64::from(b.get_u16()?),
612
613 3 => u64::from(b.get_u24()?),
614
615 4 => u64::from(b.get_u32()?),
616
617 _ => return Err(Error::InvalidPacket),
618 };
619
620 let (mut first_buf, _) = b.split_at(1)?;
622 first_buf.as_mut()[0] = first;
623
624 hdr.pkt_num = pn;
625 hdr.pkt_num_len = pn_len;
626
627 if hdr.ty == Type::Short {
628 hdr.key_phase = (first & KEY_PHASE_BIT) != 0;
629 }
630
631 Ok(())
632}
633
634pub fn decode_pkt_num(largest_pn: u64, truncated_pn: u64, pn_len: usize) -> u64 {
635 let pn_nbits = pn_len * 8;
636 let expected_pn = largest_pn + 1;
637 let pn_win = 1 << pn_nbits;
638 let pn_hwin = pn_win / 2;
639 let pn_mask = pn_win - 1;
640 let candidate_pn = (expected_pn & !pn_mask) | truncated_pn;
641
642 if candidate_pn + pn_hwin <= expected_pn && candidate_pn < (1 << 62) - pn_win
643 {
644 return candidate_pn + pn_win;
645 }
646
647 if candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win {
648 return candidate_pn - pn_win;
649 }
650
651 candidate_pn
652}
653
654pub fn decrypt_pkt<'a>(
655 b: &'a mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
656 aead: &crypto::Open,
657) -> Result<octets::Octets<'a>> {
658 let payload_offset = b.off();
659
660 let (header, mut payload) = b.split_at(payload_offset)?;
661
662 let payload_len = payload_len
663 .checked_sub(pn_len)
664 .ok_or(Error::InvalidPacket)?;
665
666 let mut ciphertext = payload.peek_bytes_mut(payload_len)?;
667
668 let payload_len =
669 aead.open_with_u64_counter(pn, header.as_ref(), ciphertext.as_mut())?;
670
671 Ok(b.get_bytes(payload_len)?)
672}
673
674pub fn encrypt_hdr(
675 b: &mut octets::OctetsMut, pn_len: usize, payload: &[u8], aead: &crypto::Seal,
676) -> Result<()> {
677 let sample = &payload
678 [MAX_PKT_NUM_LEN - pn_len..SAMPLE_LEN + (MAX_PKT_NUM_LEN - pn_len)];
679
680 let mask = aead.new_mask(sample)?;
681
682 let (mut first, mut rest) = b.split_at(1)?;
683
684 let first = first.as_mut();
685
686 if Header::is_long(first[0]) {
687 first[0] ^= mask[0] & 0x0f;
688 } else {
689 first[0] ^= mask[0] & 0x1f;
690 }
691
692 let pn_buf = rest.slice_last(pn_len)?;
693 for i in 0..pn_len {
694 pn_buf[i] ^= mask[i + 1];
695 }
696
697 Ok(())
698}
699
700pub fn encrypt_pkt(
701 b: &mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
702 payload_offset: usize, extra_in: Option<&[u8]>, aead: &crypto::Seal,
703) -> Result<usize> {
704 let (mut header, mut payload) = b.split_at(payload_offset)?;
705
706 let ciphertext_len = aead.seal_with_u64_counter(
707 pn,
708 header.as_ref(),
709 payload.as_mut(),
710 payload_len,
711 extra_in,
712 )?;
713
714 encrypt_hdr(&mut header, pn_len, payload.as_ref(), aead)?;
715
716 Ok(payload_offset + ciphertext_len)
717}
718
719pub fn encode_pkt_num(
720 pn: u64, pn_len: usize, b: &mut octets::OctetsMut,
721) -> Result<()> {
722 match pn_len {
723 1 => b.put_u8(pn as u8)?,
724
725 2 => b.put_u16(pn as u16)?,
726
727 3 => b.put_u24(pn as u32)?,
728
729 4 => b.put_u32(pn as u32)?,
730
731 _ => return Err(Error::InvalidPacket),
732 };
733
734 Ok(())
735}
736
737pub fn negotiate_version(
738 scid: &[u8], dcid: &[u8], out: &mut [u8],
739) -> Result<usize> {
740 let mut b = octets::OctetsMut::with_slice(out);
741
742 let first = rand::rand_u8() | FORM_BIT;
743
744 b.put_u8(first)?;
745 b.put_u32(0)?;
746
747 b.put_u8(scid.len() as u8)?;
748 b.put_bytes(scid)?;
749 b.put_u8(dcid.len() as u8)?;
750 b.put_bytes(dcid)?;
751 b.put_u32(crate::PROTOCOL_VERSION_V1)?;
752
753 Ok(b.off())
754}
755
756pub fn retry(
757 scid: &[u8], dcid: &[u8], new_scid: &[u8], token: &[u8], version: u32,
758 out: &mut [u8],
759) -> Result<usize> {
760 let mut b = octets::OctetsMut::with_slice(out);
761
762 if !crate::version_is_supported(version) {
763 return Err(Error::UnknownVersion);
764 }
765
766 let hdr = Header {
767 ty: Type::Retry,
768 version,
769 dcid: ConnectionId::from_ref(scid),
770 scid: ConnectionId::from_ref(new_scid),
771 pkt_num: 0,
772 pkt_num_len: 0,
773 token: Some(token.to_vec()),
774 versions: None,
775 key_phase: false,
776 };
777
778 hdr.to_bytes(&mut b)?;
779
780 let tag = compute_retry_integrity_tag(&b, dcid, version)?;
781
782 b.put_bytes(tag.as_ref())?;
783
784 Ok(b.off())
785}
786
787pub fn verify_retry_integrity(
788 b: &octets::OctetsMut, odcid: &[u8], version: u32,
789) -> Result<()> {
790 const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
791
792 let tag = compute_retry_integrity_tag(b, odcid, version)?;
793
794 crypto::verify_slices_are_equal(&b.as_ref()[..TAG_LEN], tag.as_ref())
795}
796
797fn compute_retry_integrity_tag(
798 b: &octets::OctetsMut, odcid: &[u8], version: u32,
799) -> Result<Vec<u8>> {
800 const KEY_LEN: usize = RETRY_AEAD_ALG.key_len();
801 const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
802
803 const RETRY_INTEGRITY_KEY_V1: [u8; KEY_LEN] = [
804 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
805 0xe3, 0x68, 0xc8, 0x4e,
806 ];
807
808 const RETRY_INTEGRITY_NONCE_V1: [u8; crypto::MAX_NONCE_LEN] = [
809 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,
810 ];
811
812 let (key, nonce) = match version {
813 crate::PROTOCOL_VERSION_V1 =>
814 (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
815
816 _ => (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
817 };
818
819 let hdr_len = b.off();
820
821 let mut pseudo = vec![0; 1 + odcid.len() + hdr_len];
822
823 let mut pb = octets::OctetsMut::with_slice(&mut pseudo);
824
825 pb.put_u8(odcid.len() as u8)?;
826 pb.put_bytes(odcid)?;
827 pb.put_bytes(&b.buf()[..hdr_len])?;
828
829 let key = crypto::PacketKey::new(
830 RETRY_AEAD_ALG,
831 key.to_vec(),
832 nonce.to_vec(),
833 crypto::Seal::ENCRYPT,
834 )?;
835
836 let mut out_tag = vec![0_u8; TAG_LEN];
837
838 let out_len = key.seal_with_u64_counter(0, &pseudo, &mut out_tag, 0, None)?;
839
840 if out_len != out_tag.len() {
842 return Err(Error::CryptoFail);
843 }
844
845 Ok(out_tag)
846}
847
848pub struct KeyUpdate {
849 pub crypto_open: crypto::Open,
851
852 pub pn_on_update: u64,
856
857 pub update_acked: bool,
859
860 pub timer: Instant,
862}
863
864pub struct PktNumSpace {
865 pub largest_rx_pkt_num: u64,
867
868 pub largest_rx_pkt_time: Instant,
870
871 pub largest_rx_non_probing_pkt_num: u64,
873
874 pub largest_tx_pkt_num: Option<u64>,
876
877 pub recv_pkt_need_ack: ranges::RangeSet,
879
880 pub recv_pkt_num: PktNumWindow,
882
883 pub ack_elicited: bool,
885}
886
887impl PktNumSpace {
888 pub fn new() -> PktNumSpace {
889 PktNumSpace {
890 largest_rx_pkt_num: 0,
891 largest_rx_pkt_time: Instant::now(),
892 largest_rx_non_probing_pkt_num: 0,
893 largest_tx_pkt_num: None,
894 recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES),
895 recv_pkt_num: PktNumWindow::default(),
896 ack_elicited: false,
897 }
898 }
899
900 pub fn clear(&mut self) {
901 self.ack_elicited = false;
902 }
903
904 pub fn ready(&self) -> bool {
905 self.ack_elicited
906 }
907
908 pub fn on_packet_sent(&mut self, sent_pkt: &recovery::Sent) {
909 self.largest_tx_pkt_num =
911 self.largest_tx_pkt_num.max(Some(sent_pkt.pkt_num));
912 }
913}
914
915pub struct CryptoContext {
916 pub key_update: Option<KeyUpdate>,
917 pub crypto_open: Option<crypto::Open>,
918 pub crypto_seal: Option<crypto::Seal>,
919 pub crypto_0rtt_open: Option<crypto::Open>,
920 pub crypto_stream: stream::Stream,
921}
922
923impl CryptoContext {
924 pub fn new() -> CryptoContext {
925 let crypto_stream = stream::Stream::new(
926 0, u64::MAX,
928 u64::MAX,
929 true,
930 true,
931 stream::MAX_STREAM_WINDOW,
932 );
933 CryptoContext {
934 key_update: None,
935 crypto_open: None,
936 crypto_seal: None,
937 crypto_0rtt_open: None,
938 crypto_stream,
939 }
940 }
941
942 pub fn clear(&mut self) {
943 self.crypto_open = None;
944 self.crypto_seal = None;
945 self.crypto_stream = <stream::Stream>::new(
946 0, u64::MAX,
948 u64::MAX,
949 true,
950 true,
951 stream::MAX_STREAM_WINDOW,
952 );
953 }
954
955 pub fn data_available(&self) -> bool {
956 self.crypto_stream.is_flushable()
957 }
958
959 pub fn crypto_overhead(&self) -> Option<usize> {
960 Some(self.crypto_seal.as_ref()?.alg().tag_len())
961 }
962
963 pub fn has_keys(&self) -> bool {
964 self.crypto_open.is_some() && self.crypto_seal.is_some()
965 }
966}
967
968pub struct PktNumManager {
1014 skip_pn: Option<u64>,
1020
1021 pub skip_pn_counter: Option<u64>,
1026}
1027
1028impl PktNumManager {
1029 pub fn new() -> Self {
1030 PktNumManager {
1031 skip_pn: None,
1032 skip_pn_counter: None,
1033 }
1034 }
1035
1036 pub fn on_packet_sent(
1037 &mut self, cwnd: usize, max_datagram_size: usize,
1038 handshake_completed: bool,
1039 ) {
1040 if let Some(counter) = &mut self.skip_pn_counter {
1042 *counter = counter.saturating_sub(1);
1043 } else if self.should_arm_skip_counter(handshake_completed) {
1044 self.arm_skip_counter(cwnd, max_datagram_size);
1045 }
1046 }
1047
1048 fn should_arm_skip_counter(&self, handshake_completed: bool) -> bool {
1049 let counter_not_set = self.skip_pn_counter.is_none();
1051 let no_current_skip_packet = self.skip_pn.is_none();
1055
1056 counter_not_set && no_current_skip_packet && handshake_completed
1058 }
1059
1060 pub fn should_skip_pn(&self, handshake_completed: bool) -> bool {
1061 let no_current_skip_packet = self.skip_pn.is_none();
1065 let counter_expired = match self.skip_pn_counter {
1066 Some(counter) => counter == 0,
1068 None => false,
1070 };
1071
1072 counter_expired && no_current_skip_packet && handshake_completed
1074 }
1075
1076 pub fn skip_pn(&self) -> Option<u64> {
1077 self.skip_pn
1078 }
1079
1080 pub fn set_skip_pn(&mut self, skip_pn: Option<u64>) {
1081 if skip_pn.is_some() {
1082 debug_assert!(self.skip_pn.is_none());
1084 debug_assert_eq!(self.skip_pn_counter.unwrap(), 0);
1086 }
1087
1088 self.skip_pn = skip_pn;
1089 self.skip_pn_counter = None;
1091 }
1092
1093 fn arm_skip_counter(&mut self, cwnd: usize, max_datagram_size: usize) {
1095 let packets_per_cwnd = (cwnd / max_datagram_size) as u64;
1096 let lower = packets_per_cwnd / 2;
1097 let upper = packets_per_cwnd * 2;
1098 let skip_range = upper - lower + 1;
1100 let rand_skip_value = rand::rand_u64_uniform(skip_range);
1101
1102 let skip_pn_counter = MIN_SKIP_COUNTER_VALUE + lower + rand_skip_value;
1119
1120 self.skip_pn_counter = Some(skip_pn_counter);
1121 }
1122}
1123
1124#[derive(Clone, Copy, Default)]
1125pub struct PktNumWindow {
1126 lower: u64,
1127 window: u128,
1128}
1129
1130impl PktNumWindow {
1131 pub fn insert(&mut self, seq: u64) {
1132 if seq < self.lower {
1134 return;
1135 }
1136
1137 if seq > self.upper() {
1139 let diff = seq - self.upper();
1140 self.lower += diff;
1141
1142 self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
1143 }
1144
1145 let mask = 1_u128 << (self.upper() - seq);
1146 self.window |= mask;
1147 }
1148
1149 pub fn contains(&mut self, seq: u64) -> bool {
1150 if seq > self.upper() {
1152 return false;
1153 }
1154
1155 if seq < self.lower {
1157 return true;
1158 }
1159
1160 let mask = 1_u128 << (self.upper() - seq);
1161 self.window & mask != 0
1162 }
1163
1164 fn upper(&self) -> u64 {
1165 self.lower.saturating_add(size_of::<u128>() as u64 * 8) - 1
1166 }
1167}
1168
1169#[cfg(test)]
1170mod tests {
1171 use super::*;
1172 use crate::test_utils;
1173 use crate::MAX_SEND_UDP_PAYLOAD_SIZE;
1174
1175 #[test]
1176 fn retry() {
1177 let hdr = Header {
1178 ty: Type::Retry,
1179 version: 0xafafafaf,
1180 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1181 .into(),
1182 scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1183 pkt_num: 0,
1184 pkt_num_len: 0,
1185 token: Some(vec![0xba; 24]),
1186 versions: None,
1187 key_phase: false,
1188 };
1189
1190 let mut d = [0; 63];
1191
1192 let mut b = octets::OctetsMut::with_slice(&mut d);
1193 assert!(hdr.to_bytes(&mut b).is_ok());
1194
1195 b.put_bytes(&[0xba; 16]).unwrap();
1197
1198 let mut b = octets::OctetsMut::with_slice(&mut d);
1199 assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1200 }
1201
1202 #[test]
1203 fn initial() {
1204 let hdr = Header {
1205 ty: Type::Initial,
1206 version: 0xafafafaf,
1207 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1208 .into(),
1209 scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1210 pkt_num: 0,
1211 pkt_num_len: 0,
1212 token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1213 versions: None,
1214 key_phase: false,
1215 };
1216
1217 let mut d = [0; 50];
1218
1219 let mut b = octets::OctetsMut::with_slice(&mut d);
1220 assert!(hdr.to_bytes(&mut b).is_ok());
1221
1222 let mut b = octets::OctetsMut::with_slice(&mut d);
1223 assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1224 }
1225
1226 #[test]
1227 fn initial_v1_dcid_too_long() {
1228 let hdr = Header {
1229 ty: Type::Initial,
1230 version: crate::PROTOCOL_VERSION,
1231 dcid: vec![
1232 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1233 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1234 ]
1235 .into(),
1236 scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1237 pkt_num: 0,
1238 pkt_num_len: 0,
1239 token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1240 versions: None,
1241 key_phase: false,
1242 };
1243
1244 let mut d = [0; 50];
1245
1246 let mut b = octets::OctetsMut::with_slice(&mut d);
1247 assert!(hdr.to_bytes(&mut b).is_ok());
1248
1249 let mut b = octets::OctetsMut::with_slice(&mut d);
1250 assert_eq!(Header::from_bytes(&mut b, 21), Err(Error::InvalidPacket));
1251 }
1252
1253 #[test]
1254 fn initial_v1_scid_too_long() {
1255 let hdr = Header {
1256 ty: Type::Initial,
1257 version: crate::PROTOCOL_VERSION,
1258 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1259 .into(),
1260 scid: vec![
1261 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1262 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1263 ]
1264 .into(),
1265 pkt_num: 0,
1266 pkt_num_len: 0,
1267 token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1268 versions: None,
1269 key_phase: false,
1270 };
1271
1272 let mut d = [0; 50];
1273
1274 let mut b = octets::OctetsMut::with_slice(&mut d);
1275 assert!(hdr.to_bytes(&mut b).is_ok());
1276
1277 let mut b = octets::OctetsMut::with_slice(&mut d);
1278 assert_eq!(Header::from_bytes(&mut b, 9), Err(Error::InvalidPacket));
1279 }
1280
1281 #[test]
1282 fn initial_non_v1_scid_long() {
1283 let hdr = Header {
1284 ty: Type::Initial,
1285 version: 0xafafafaf,
1286 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1287 .into(),
1288 scid: vec![
1289 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1290 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1291 ]
1292 .into(),
1293 pkt_num: 0,
1294 pkt_num_len: 0,
1295 token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1296 versions: None,
1297 key_phase: false,
1298 };
1299
1300 let mut d = [0; 50];
1301
1302 let mut b = octets::OctetsMut::with_slice(&mut d);
1303 assert!(hdr.to_bytes(&mut b).is_ok());
1304
1305 let mut b = octets::OctetsMut::with_slice(&mut d);
1306 assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1307 }
1308
1309 #[test]
1310 fn handshake() {
1311 let hdr = Header {
1312 ty: Type::Handshake,
1313 version: 0xafafafaf,
1314 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1315 .into(),
1316 scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1317 pkt_num: 0,
1318 pkt_num_len: 0,
1319 token: None,
1320 versions: None,
1321 key_phase: false,
1322 };
1323
1324 let mut d = [0; 50];
1325
1326 let mut b = octets::OctetsMut::with_slice(&mut d);
1327 assert!(hdr.to_bytes(&mut b).is_ok());
1328
1329 let mut b = octets::OctetsMut::with_slice(&mut d);
1330 assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1331 }
1332
1333 #[test]
1334 fn application() {
1335 let hdr = Header {
1336 ty: Type::Short,
1337 version: 0,
1338 dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1339 .into(),
1340 scid: ConnectionId::default(),
1341 pkt_num: 0,
1342 pkt_num_len: 0,
1343 token: None,
1344 versions: None,
1345 key_phase: false,
1346 };
1347
1348 let mut d = [0; 50];
1349
1350 let mut b = octets::OctetsMut::with_slice(&mut d);
1351 assert!(hdr.to_bytes(&mut b).is_ok());
1352
1353 let mut b = octets::OctetsMut::with_slice(&mut d);
1354 assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1355 }
1356
1357 #[test]
1358 fn pkt_num_encode_decode() {
1359 let num_len = pkt_num_len(0, 0);
1360 assert_eq!(num_len, 1);
1361 let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2);
1362 assert_eq!(pn, 0xa82f9b32);
1363 let mut d = [0; 10];
1364 let mut b = octets::OctetsMut::with_slice(&mut d);
1365 let num_len = pkt_num_len(0xac5c02, 0xabe8b3);
1366 assert_eq!(num_len, 2);
1367 encode_pkt_num(0xac5c02, num_len, &mut b).unwrap();
1368 let mut b = octets::OctetsMut::with_slice(&mut d);
1370 let hdr_num = u64::from(b.get_u16().unwrap());
1371 let pn = decode_pkt_num(0xac5c01, hdr_num, num_len);
1372 assert_eq!(pn, 0xac5c02);
1373 let num_len = pkt_num_len(0xace9fe, 0xabe8b3);
1375 assert_eq!(num_len, 3);
1376 let mut b = octets::OctetsMut::with_slice(&mut d);
1377 encode_pkt_num(0xace9fe, num_len, &mut b).unwrap();
1378 let mut b = octets::OctetsMut::with_slice(&mut d);
1380 let hdr_num = u64::from(b.get_u24().unwrap());
1381 let pn = decode_pkt_num(0xace9fa, hdr_num, num_len);
1382 assert_eq!(pn, 0xace9fe);
1383 }
1384
1385 #[test]
1386 fn pkt_num_window() {
1387 let mut win = PktNumWindow::default();
1388 assert_eq!(win.lower, 0);
1389 assert!(!win.contains(0));
1390 assert!(!win.contains(1));
1391
1392 win.insert(0);
1393 assert_eq!(win.lower, 0);
1394 assert!(win.contains(0));
1395 assert!(!win.contains(1));
1396
1397 win.insert(1);
1398 assert_eq!(win.lower, 0);
1399 assert!(win.contains(0));
1400 assert!(win.contains(1));
1401
1402 win.insert(3);
1403 assert_eq!(win.lower, 0);
1404 assert!(win.contains(0));
1405 assert!(win.contains(1));
1406 assert!(!win.contains(2));
1407 assert!(win.contains(3));
1408
1409 win.insert(10);
1410 assert_eq!(win.lower, 0);
1411 assert!(win.contains(0));
1412 assert!(win.contains(1));
1413 assert!(!win.contains(2));
1414 assert!(win.contains(3));
1415 assert!(!win.contains(4));
1416 assert!(!win.contains(5));
1417 assert!(!win.contains(6));
1418 assert!(!win.contains(7));
1419 assert!(!win.contains(8));
1420 assert!(!win.contains(9));
1421 assert!(win.contains(10));
1422
1423 win.insert(132);
1424 assert_eq!(win.lower, 5);
1425 assert!(win.contains(0));
1426 assert!(win.contains(1));
1427 assert!(win.contains(2));
1428 assert!(win.contains(3));
1429 assert!(win.contains(4));
1430 assert!(!win.contains(5));
1431 assert!(!win.contains(6));
1432 assert!(!win.contains(7));
1433 assert!(!win.contains(8));
1434 assert!(!win.contains(9));
1435 assert!(win.contains(10));
1436 assert!(!win.contains(128));
1437 assert!(!win.contains(130));
1438 assert!(!win.contains(131));
1439 assert!(win.contains(132));
1440
1441 win.insert(1024);
1442 assert_eq!(win.lower, 897);
1443 assert!(win.contains(0));
1444 assert!(win.contains(1));
1445 assert!(win.contains(2));
1446 assert!(win.contains(3));
1447 assert!(win.contains(4));
1448 assert!(win.contains(5));
1449 assert!(win.contains(6));
1450 assert!(win.contains(7));
1451 assert!(win.contains(8));
1452 assert!(win.contains(9));
1453 assert!(win.contains(10));
1454 assert!(win.contains(128));
1455 assert!(win.contains(130));
1456 assert!(win.contains(132));
1457 assert!(win.contains(896));
1458 assert!(!win.contains(897));
1459 assert!(!win.contains(1022));
1460 assert!(!win.contains(1023));
1461 assert!(win.contains(1024));
1462 assert!(!win.contains(1025));
1463 assert!(!win.contains(1026));
1464
1465 win.insert(u64::MAX - 1);
1466 assert!(win.contains(0));
1467 assert!(win.contains(1));
1468 assert!(win.contains(2));
1469 assert!(win.contains(3));
1470 assert!(win.contains(4));
1471 assert!(win.contains(5));
1472 assert!(win.contains(6));
1473 assert!(win.contains(7));
1474 assert!(win.contains(8));
1475 assert!(win.contains(9));
1476 assert!(win.contains(10));
1477 assert!(win.contains(128));
1478 assert!(win.contains(130));
1479 assert!(win.contains(132));
1480 assert!(win.contains(896));
1481 assert!(win.contains(897));
1482 assert!(win.contains(1022));
1483 assert!(win.contains(1023));
1484 assert!(win.contains(1024));
1485 assert!(win.contains(1025));
1486 assert!(win.contains(1026));
1487 assert!(!win.contains(u64::MAX - 2));
1488 assert!(win.contains(u64::MAX - 1));
1489 }
1490
1491 fn assert_decrypt_initial_pkt(
1492 pkt: &mut [u8], dcid: &[u8], is_server: bool, expected_frames: &[u8],
1493 expected_pn: u64, expected_pn_len: usize,
1494 ) {
1495 let mut b = octets::OctetsMut::with_slice(pkt);
1496
1497 let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1498 assert_eq!(hdr.ty, Type::Initial);
1499
1500 let payload_len = b.get_varint().unwrap() as usize;
1501
1502 let (aead, _) = crypto::derive_initial_key_material(
1503 dcid,
1504 hdr.version,
1505 is_server,
1506 false,
1507 )
1508 .unwrap();
1509
1510 decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1511 assert_eq!(hdr.pkt_num_len, expected_pn_len);
1512
1513 let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len);
1514 assert_eq!(pn, expected_pn);
1515
1516 let payload =
1517 decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1518
1519 let payload = payload.as_ref();
1520 assert_eq!(&payload[..expected_frames.len()], expected_frames);
1521 }
1522
1523 #[test]
1524 fn decrypt_client_initial_v1() {
1525 let mut pkt = [
1526 0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1527 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1528 0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1529 0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1530 0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1531 0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1532 0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1533 0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1534 0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1535 0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1536 0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1537 0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1538 0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1539 0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1540 0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1541 0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1542 0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1543 0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1544 0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1545 0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1546 0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1547 0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1548 0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1549 0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1550 0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1551 0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1552 0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1553 0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1554 0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1555 0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1556 0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1557 0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1558 0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1559 0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1560 0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1561 0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1562 0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1563 0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1564 0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1565 0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1566 0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1567 0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1568 0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1569 0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1570 0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1571 0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1572 0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1573 0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1574 0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1575 0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1576 0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1577 0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1578 0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1579 0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1580 0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1581 0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1582 0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1583 0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1584 0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1585 0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1586 0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1587 0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1588 0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1589 0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1590 0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1591 0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1592 0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1593 0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1594 0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1595 0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1596 0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1597 0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1598 0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1599 0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1600 0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1601 0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1602 0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1603 0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1604 0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1605 0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1606 0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1607 0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1608 0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1609 0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1610 0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1611 0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1612 0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1613 0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1614 0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1615 0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1616 0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1617 0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1618 0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1619 0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1620 0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1621 0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1622 0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1623 0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1624 0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1625 0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1626 0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1627 0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1628 0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1629 0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1630 0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1631 0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1632 0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1633 0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1634 0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1635 0x88,
1636 ];
1637
1638 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1639
1640 let frames = [
1641 0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1642 0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1643 0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1644 0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1645 0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1646 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1647 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1648 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1649 0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1650 0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1651 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1652 0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1653 0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1654 0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1655 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1656 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1657 0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1658 0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1659 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1660 0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1661 0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1662 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1663 0x00, 0xff, 0xff,
1664 ];
1665
1666 assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4);
1667 }
1668
1669 #[test]
1670 fn decrypt_server_initial_v1() {
1671 let mut pkt = [
1672 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1673 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1674 0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1675 0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1676 0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1677 0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1678 0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1679 0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1680 0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1681 0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1682 0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1683 0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1684 0xd0, 0x74, 0xee,
1685 ];
1686
1687 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1688
1689 let frames = [
1690 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1691 0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1692 0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1693 0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1694 0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1695 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1696 0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1697 0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1698 0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1699 ];
1700
1701 assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2);
1702 }
1703
1704 #[test]
1705 fn decrypt_chacha20() {
1706 let secret = [
1707 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1708 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1709 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1710 ];
1711
1712 let mut pkt = [
1713 0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1714 0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1715 ];
1716
1717 let mut b = octets::OctetsMut::with_slice(&mut pkt);
1718
1719 let alg = crypto::Algorithm::ChaCha20_Poly1305;
1720
1721 let aead = crypto::Open::from_secret(alg, &secret).unwrap();
1722
1723 let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1724 assert_eq!(hdr.ty, Type::Short);
1725
1726 let payload_len = b.cap();
1727
1728 decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1729 assert_eq!(hdr.pkt_num_len, 3);
1730
1731 let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len);
1732 assert_eq!(pn, 654_360_564);
1733
1734 let payload =
1735 decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1736
1737 let payload = payload.as_ref();
1738 assert_eq!(&payload, &[0x01]);
1739 }
1740
1741 fn assert_encrypt_initial_pkt(
1742 header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize,
1743 is_server: bool, expected_pkt: &[u8],
1744 ) {
1745 let mut b = octets::OctetsMut::with_slice(header);
1746
1747 let hdr = Header::from_bytes(&mut b, 0).unwrap();
1748 assert_eq!(hdr.ty, Type::Initial);
1749
1750 let mut out = vec![0; expected_pkt.len()];
1751 let mut b = octets::OctetsMut::with_slice(&mut out);
1752
1753 b.put_bytes(header).unwrap();
1754
1755 let (_, aead) = crypto::derive_initial_key_material(
1756 dcid,
1757 hdr.version,
1758 is_server,
1759 false,
1760 )
1761 .unwrap();
1762
1763 let payload_len = frames.len();
1764
1765 let payload_offset = b.off();
1766
1767 b.put_bytes(frames).unwrap();
1768
1769 let written = encrypt_pkt(
1770 &mut b,
1771 pn,
1772 pn_len,
1773 payload_len,
1774 payload_offset,
1775 None,
1776 &aead,
1777 )
1778 .unwrap();
1779
1780 assert_eq!(written, expected_pkt.len());
1781 assert_eq!(&out[..written], expected_pkt);
1782 }
1783
1784 #[test]
1785 fn encrypt_client_initial_v1() {
1786 let mut header = [
1787 0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1788 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
1789 ];
1790
1791 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1792
1793 let frames = [
1794 0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1795 0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1796 0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1797 0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1798 0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1799 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1800 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1801 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1802 0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1803 0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1804 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1805 0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1806 0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1807 0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1808 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1809 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1810 0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1811 0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1812 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1813 0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1814 0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1815 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1816 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1823 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1872 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1873 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1874 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1881 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1899 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900 ];
1901
1902 let pkt = [
1903 0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1904 0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1905 0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1906 0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1907 0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1908 0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1909 0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1910 0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1911 0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1912 0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1913 0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1914 0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1915 0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1916 0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1917 0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1918 0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1919 0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1920 0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1921 0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1922 0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1923 0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1924 0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1925 0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1926 0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1927 0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1928 0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1929 0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1930 0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1931 0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1932 0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1933 0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1934 0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1935 0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1936 0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1937 0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1938 0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1939 0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1940 0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1941 0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1942 0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1943 0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1944 0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1945 0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1946 0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1947 0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1948 0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1949 0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1950 0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1951 0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1952 0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1953 0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1954 0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1955 0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1956 0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1957 0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1958 0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1959 0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1960 0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1961 0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1962 0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1963 0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1964 0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1965 0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1966 0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1967 0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1968 0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1969 0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1970 0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1971 0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1972 0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1973 0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1974 0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1975 0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1976 0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1977 0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1978 0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1979 0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1980 0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1981 0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1982 0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1983 0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1984 0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1985 0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1986 0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1987 0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1988 0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1989 0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1990 0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1991 0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1992 0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1993 0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1994 0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1995 0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1996 0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1997 0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1998 0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1999 0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
2000 0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
2001 0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
2002 0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
2003 0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
2004 0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
2005 0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
2006 0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
2007 0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
2008 0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
2009 0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
2010 0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
2011 0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
2012 0x88,
2013 ];
2014
2015 assert_encrypt_initial_pkt(
2016 &mut header,
2017 &dcid,
2018 &frames,
2019 2,
2020 4,
2021 false,
2022 &pkt,
2023 );
2024 }
2025
2026 #[test]
2027 fn encrypt_server_initial_v1() {
2028 let mut header = [
2029 0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
2030 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01,
2031 ];
2032
2033 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
2034
2035 let frames = [
2036 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
2037 0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
2038 0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
2039 0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
2040 0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
2041 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
2042 0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
2043 0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
2044 0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
2045 ];
2046
2047 let pkt = [
2048 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
2049 0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
2050 0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
2051 0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
2052 0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
2053 0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
2054 0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
2055 0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
2056 0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
2057 0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
2058 0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
2059 0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
2060 0xd0, 0x74, 0xee,
2061 ];
2062
2063 assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt);
2064 }
2065
2066 #[test]
2067 fn encrypt_chacha20() {
2068 let secret = [
2069 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
2070 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
2071 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
2072 ];
2073
2074 let mut header = [0x42, 0x00, 0xbf, 0xf4];
2075
2076 let expected_pkt = [
2077 0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
2078 0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
2079 ];
2080
2081 let mut b = octets::OctetsMut::with_slice(&mut header);
2082
2083 let hdr = Header::from_bytes(&mut b, 0).unwrap();
2084 assert_eq!(hdr.ty, Type::Short);
2085
2086 let mut out = vec![0; expected_pkt.len()];
2087 let mut b = octets::OctetsMut::with_slice(&mut out);
2088
2089 b.put_bytes(&header).unwrap();
2090
2091 let alg = crypto::Algorithm::ChaCha20_Poly1305;
2092
2093 let aead = crypto::Seal::from_secret(alg, &secret).unwrap();
2094
2095 let pn = 654_360_564;
2096 let pn_len = 3;
2097
2098 let frames = [0x01];
2099
2100 let payload_len = frames.len();
2101
2102 let payload_offset = b.off();
2103
2104 b.put_bytes(&frames).unwrap();
2105
2106 let written = encrypt_pkt(
2107 &mut b,
2108 pn,
2109 pn_len,
2110 payload_len,
2111 payload_offset,
2112 None,
2113 &aead,
2114 )
2115 .unwrap();
2116
2117 assert_eq!(written, expected_pkt.len());
2118 assert_eq!(&out[..written], &expected_pkt[..]);
2119 }
2120
2121 #[test]
2122 fn decrypt_pkt_underflow() {
2123 let mut buf = [0; 65535];
2124 let mut b = octets::OctetsMut::with_slice(&mut buf);
2125
2126 let hdr = Header {
2127 ty: Type::Initial,
2128 version: crate::PROTOCOL_VERSION,
2129 dcid: ConnectionId::default(),
2130 scid: ConnectionId::default(),
2131 pkt_num: 0,
2132 pkt_num_len: 0,
2133 token: None,
2134 versions: None,
2135 key_phase: false,
2136 };
2137
2138 hdr.to_bytes(&mut b).unwrap();
2139
2140 b.put_bytes(&[0; 50]).unwrap();
2141
2142 let payload_len = b.get_varint().unwrap() as usize;
2143
2144 let (aead, _) =
2145 crypto::derive_initial_key_material(b"", hdr.version, true, false)
2146 .unwrap();
2147
2148 assert_eq!(
2149 decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
2150 Err(Error::InvalidPacket)
2151 );
2152 }
2153
2154 #[test]
2155 fn decrypt_pkt_too_small() {
2156 let mut buf = [0; 65535];
2157 let mut b = octets::OctetsMut::with_slice(&mut buf);
2158
2159 let hdr = Header {
2160 ty: Type::Initial,
2161 version: crate::PROTOCOL_VERSION,
2162 dcid: ConnectionId::default(),
2163 scid: ConnectionId::default(),
2164 pkt_num: 0,
2165 pkt_num_len: 0,
2166 token: None,
2167 versions: None,
2168 key_phase: false,
2169 };
2170
2171 hdr.to_bytes(&mut b).unwrap();
2172
2173 b.put_bytes(&[0; 1]).unwrap();
2174
2175 let payload_len = 1;
2177
2178 let (aead, _) =
2179 crypto::derive_initial_key_material(b"", hdr.version, true, false)
2180 .unwrap();
2181
2182 assert_eq!(
2183 decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
2184 Err(Error::CryptoFail)
2185 );
2186 }
2187
2188 #[test]
2189 fn track_largest_packet_sent() {
2190 let now = Instant::now();
2191 let mut pkt_space = PktNumSpace::new();
2192
2193 assert!(pkt_space.largest_tx_pkt_num.is_none());
2194
2195 let sent_ctx = test_utils::helper_packet_sent(1, now, 10);
2196 pkt_space.on_packet_sent(&sent_ctx);
2197 assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 1);
2198
2199 let sent_ctx = test_utils::helper_packet_sent(2, now, 10);
2200 pkt_space.on_packet_sent(&sent_ctx);
2201 assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 2);
2202 }
2203
2204 #[test]
2205 fn skip_pn() {
2206 let mut skip_manager = PktNumManager::new();
2207 let cwnd = 1000;
2208 let handshake_completed = true;
2209 let mut next_pn = 0;
2210
2211 assert!(skip_manager.skip_pn.is_none());
2212 assert!(skip_manager.skip_pn_counter.is_none());
2213 assert!(!skip_manager.should_skip_pn(handshake_completed));
2214
2215 skip_manager.on_packet_sent(
2217 cwnd,
2218 MAX_SEND_UDP_PAYLOAD_SIZE,
2219 handshake_completed,
2220 );
2221 assert_eq!(next_pn, 0);
2222 assert!(skip_manager.skip_pn.is_none());
2223 assert!(skip_manager.skip_pn_counter.unwrap() >= MIN_SKIP_COUNTER_VALUE);
2224 assert!(!skip_manager.should_skip_pn(handshake_completed));
2225
2226 while skip_manager.skip_pn_counter.unwrap() > 0 {
2228 next_pn += 1;
2230
2231 skip_manager.on_packet_sent(
2232 cwnd,
2233 MAX_SEND_UDP_PAYLOAD_SIZE,
2234 handshake_completed,
2235 );
2236 }
2237 assert!(next_pn >= MIN_SKIP_COUNTER_VALUE);
2238 assert!(skip_manager.skip_pn.is_none());
2239 assert_eq!(skip_manager.skip_pn_counter.unwrap(), 0);
2240 assert!(skip_manager.should_skip_pn(handshake_completed));
2241
2242 skip_manager.set_skip_pn(Some(next_pn));
2244 assert_eq!(skip_manager.skip_pn.unwrap(), next_pn);
2245 assert!(skip_manager.skip_pn_counter.is_none());
2246 assert!(!skip_manager.should_skip_pn(handshake_completed));
2247 }
2248
2249 #[test]
2250 fn arm_skip_counter_only_after_verifying_prev_skip_pn() {
2251 let mut skip_manager = PktNumManager::new();
2252 let cwnd = 1000;
2253 let handshake_completed = true;
2254
2255 skip_manager.skip_pn_counter = Some(0);
2257 skip_manager.set_skip_pn(Some(42));
2258 assert!(skip_manager.skip_pn.is_some());
2259 assert!(skip_manager.skip_pn_counter.is_none());
2260
2261 skip_manager.on_packet_sent(
2264 cwnd,
2265 MAX_SEND_UDP_PAYLOAD_SIZE,
2266 handshake_completed,
2267 );
2268 assert!(skip_manager.skip_pn.is_some());
2269 assert!(skip_manager.skip_pn_counter.is_none());
2270
2271 skip_manager.skip_pn = None;
2273 skip_manager.on_packet_sent(
2274 cwnd,
2275 MAX_SEND_UDP_PAYLOAD_SIZE,
2276 handshake_completed,
2277 );
2278 assert!(skip_manager.skip_pn.is_none());
2279 assert!(skip_manager.skip_pn_counter.is_some());
2280 }
2281
2282 #[test]
2283 fn arm_skip_counter_only_after_handshake_complete() {
2284 let mut skip_manager = PktNumManager::new();
2285 let cwnd = 1000;
2286 skip_manager.skip_pn_counter = None;
2287
2288 let mut handshake_completed = false;
2290 skip_manager.on_packet_sent(
2291 cwnd,
2292 MAX_SEND_UDP_PAYLOAD_SIZE,
2293 handshake_completed,
2294 );
2295 assert!(skip_manager.skip_pn_counter.is_none());
2296
2297 handshake_completed = true;
2299 skip_manager.on_packet_sent(
2300 cwnd,
2301 MAX_SEND_UDP_PAYLOAD_SIZE,
2302 handshake_completed,
2303 );
2304 assert!(skip_manager.skip_pn_counter.is_some());
2305 }
2306
2307 #[test]
2308 fn only_skip_after_handshake_complete() {
2309 let mut skip_manager = PktNumManager::new();
2310 skip_manager.skip_pn_counter = Some(0);
2311
2312 let mut handshake_completed = false;
2313 assert!(!skip_manager.should_skip_pn(handshake_completed));
2315
2316 handshake_completed = true;
2317 assert!(skip_manager.should_skip_pn(handshake_completed));
2319 }
2320}