Implement QUIC Header Protection

gfe-relnote: Protected by QUIC_VERSION_99
PiperOrigin-RevId: 247137283
Change-Id: I1deb08d304b7739c3c8fa6b995e55fbd8652dc1e
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 3082a94..700c4cf 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1013,12 +1013,25 @@
         {"Unable to read packet number.",
          {0x12, 0x34, 0x56, 0x78}},
    };
+
+  PacketFragments packet_hp = {
+        // type (short header, 4 byte packet number)
+        {"Unable to read type.",
+         {0x43}},
+        // connection_id
+        // packet number
+        {"",
+         {0x12, 0x34, 0x56, 0x78}},
+   };
   // clang-format on
 
   PacketFragments& fragments =
-      framer_.transport_version() > QUIC_VERSION_44
-          ? packet46
-          : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 : packet);
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : framer_.transport_version() > QUIC_VERSION_44
+                ? packet46
+                : (framer_.transport_version() > QUIC_VERSION_43 ? packet44
+                                                                 : packet);
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       AssemblePacketFromFragments(fragments));
   EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
@@ -1173,12 +1186,27 @@
       {"Unable to read packet number.",
        {0x12, 0x34, 0x56, 0x78}},
   };
+
+  PacketFragments packet_hp = {
+      // type (short header, 4 byte packet number)
+      {"Unable to read type.",
+       {0x43}},
+      // connection_id
+      {"Unable to read Destination ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
   // clang-format on
 
   PacketFragments& fragments =
-      framer_.transport_version() > QUIC_VERSION_44
-          ? packet46
-          : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 : packet);
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : framer_.transport_version() > QUIC_VERSION_44
+                ? packet46
+                : (framer_.transport_version() > QUIC_VERSION_43 ? packet44
+                                                                 : packet);
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       AssemblePacketFromFragments(fragments));
   EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
@@ -1233,16 +1261,38 @@
       {"Unable to read packet number.",
        {0x56, 0x78}},
   };
+
+  PacketFragments packet_hp = {
+      // type (short header, 2 byte packet number)
+      {"Unable to read type.",
+       {0x41}},
+      // connection_id
+      {"Unable to read Destination ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78}},
+      // padding
+      {"", {0x00, 0x00}},
+  };
   // clang-format on
 
   PacketFragments& fragments =
-      framer_.transport_version() > QUIC_VERSION_44
-          ? packet46
-          : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 : packet);
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.transport_version() > QUIC_VERSION_44
+                 ? packet46
+                 : (framer_.transport_version() > QUIC_VERSION_43 ? packet44
+                                                                  : packet));
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+  }
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(FramerTestConnectionId(),
             visitor_.header_->destination_connection_id);
@@ -1295,16 +1345,38 @@
        {0x78}},
   };
 
+  PacketFragments packet_hp = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read type.",
+       {0x40}},
+      // connection_id
+      {"Unable to read Destination ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
+
   // clang-format on
 
   PacketFragments& fragments =
-      framer_.transport_version() > QUIC_VERSION_44
-          ? packet46
-          : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 : packet);
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.transport_version() > QUIC_VERSION_44
+                 ? packet46
+                 : (framer_.transport_version() > QUIC_VERSION_43 ? packet44
+                                                                  : packet));
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+  }
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(FramerTestConnectionId(),
             visitor_.header_->destination_connection_id);
@@ -1536,20 +1608,41 @@
     0x00,
     0x00, 0x00, 0x00, 0x00
   };
+
+  unsigned char packet45[] = {
+    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+    0xD3,
+    // version tag
+    'Q', '0', '0', '0',
+    // connection_id length
+    0x50,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
   // clang-format on
 
-  QuicEncryptedPacket encrypted(
-      AsChars(framer_.transport_version() > QUIC_VERSION_43 ? packet44
-                                                            : packet),
-      framer_.transport_version() > QUIC_VERSION_43 ? QUIC_ARRAYSIZE(packet44)
-                                                    : QUIC_ARRAYSIZE(packet),
-      false);
+  unsigned char* p = packet;
+  size_t p_size = QUIC_ARRAYSIZE(packet);
+  if (framer_.transport_version() > QUIC_VERSION_44) {
+    p = packet45;
+    p_size = QUIC_ARRAYSIZE(packet45);
+  } else if (framer_.transport_version() > QUIC_VERSION_43) {
+    p = packet44;
+    p_size = QUIC_ARRAYSIZE(packet44);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
   EXPECT_TRUE(framer_.ProcessPacket(encrypted));
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(0, visitor_.frame_count_);
   EXPECT_EQ(1, visitor_.version_mismatch_);
-  EXPECT_EQ(1u, visitor_.padding_frames_.size());
+  ASSERT_EQ(1u, visitor_.padding_frames_.size());
   EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes);
 }
 
@@ -1997,7 +2090,10 @@
   }
   QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
   EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  if (framer_.transport_version() >= QUIC_VERSION_44) {
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_EQ(QUIC_DECRYPTION_FAILURE, framer_.error());
+    EXPECT_EQ("Unable to decrypt header protection.", framer_.detailed_error());
+  } else if (framer_.transport_version() >= QUIC_VERSION_44) {
     // Cannot read diversification nonce.
     EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error());
     EXPECT_EQ("Unable to read nonce.", framer_.detailed_error());
@@ -9404,12 +9500,15 @@
     'e',  'f',  'g',  'h',
     'i',  'j',  'k',  'l',
     'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
   };
   // clang-format on
 
   unsigned char* p = packet;
+  size_t p_size = QUIC_ARRAYSIZE(packet);
   if (framer_.transport_version() == QUIC_VERSION_99) {
     p = packet99;
+    p_size = QUIC_ARRAYSIZE(packet99);
   } else if (framer_.transport_version() > QUIC_VERSION_44) {
     p = packet46;
   } else if (framer_.transport_version() > QUIC_VERSION_43) {
@@ -9417,7 +9516,7 @@
   }
 
   std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p), QUIC_ARRAYSIZE(packet), false, PACKET_8BYTE_CONNECTION_ID,
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
       VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
@@ -9430,6 +9529,7 @@
 }
 
 TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
   QuicPacketNumber packet_number = kPacketNumber;
   // clang-format off
   unsigned char packet[] = {
@@ -9504,26 +9604,28 @@
     'e',  'f',  'g',  'h',
     'i',  'j',  'k',  'l',
     'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
   };
   // clang-format on
 
   unsigned char* p = packet;
+  size_t p_size = QUIC_ARRAYSIZE(packet);
   if (framer_.transport_version() == QUIC_VERSION_99) {
     p = packet99;
+    p_size = QUIC_ARRAYSIZE(packet99);
   } else if (framer_.transport_version() > QUIC_VERSION_44) {
     p = packet46;
+    p_size = QUIC_ARRAYSIZE(packet46);
   } else if (framer_.transport_version() > QUIC_VERSION_43) {
     p = packet44;
+    p_size = QUIC_ARRAYSIZE(packet44);
   }
 
   std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p),
-      framer_.transport_version() > QUIC_VERSION_43 ? QUIC_ARRAYSIZE(packet44)
-                                                    : QUIC_ARRAYSIZE(packet),
-      false, PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID,
-      kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_4BYTE_PACKET_NUMBER, VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0));
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
   char buffer[kMaxOutgoingPacketSize];
   size_t encrypted_length = framer_.EncryptPayload(
       ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
@@ -13025,12 +13127,33 @@
       {"Unable to read packet number.",
        {0x78}},
   };
+
+  PacketFragments packet_with_padding = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read type.",
+       {0x40}},
+      // connection_id
+      {"Unable to read Destination ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
   // clang-format on
 
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection() ? packet_with_padding : packet;
   std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+  }
   ASSERT_TRUE(visitor_.header_.get());
   EXPECT_EQ(connection_id, visitor_.header_->destination_connection_id);
   EXPECT_FALSE(visitor_.header_->reset_flag);
@@ -13038,7 +13161,7 @@
   EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
   EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
 
-  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
 }
 
 TEST_P(QuicFramerTest, UpdateExpectedConnectionIdLength) {
@@ -13204,7 +13327,7 @@
      // packet number
      0x79,
      // padding frame
-     0x00,
+     0x00, 0x00, 0x00,
   };
   // clang-format on