Automated g4 rollback of changelist 242988047.

*** Reason for rollback ***

Revert as this change is not easily compatible in chromium.

*** Original change description ***

Add new methods to QuicFramer for controlling decrypters

This CL is a roll forward of cl/242758726. I had to make test-only changes to fix the broken test //third_party/quic/core:tls_handshaker_test.

gfe-relnote: Protected behind QUIC_VERSION_99 and quic_supports_tls_handshake

***

PiperOrigin-RevId: 243273832
Change-Id: I84b0ae565dcb5ceed2351fc37ad195c229d09488
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 9a99ca7..4e1dc9e 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -489,22 +489,13 @@
   EXPECT_CALL(*connection_, OnError(_)).Times(1);
 
   // Verify that a decryptable packet with bad frames does close the connection.
-  QuicConnectionId destination_connection_id =
-      session_->connection()->connection_id();
-  QuicConnectionId source_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId connection_id = session_->connection()->connection_id();
   QuicFramerPeer::SetLastSerializedConnectionId(
-      QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
+      QuicConnectionPeer::GetFramer(connection_), connection_id);
   ParsedQuicVersionVector versions = {GetParam()};
-  bool version_flag = false;
-  QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
-  if (GetParam().transport_version > QUIC_VERSION_43) {
-    version_flag = true;
-    source_connection_id = destination_connection_id;
-    scid_included = CONNECTION_ID_PRESENT;
-  }
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, false, 100,
-      "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
+      connection_id, EmptyQuicConnectionId(), false, false, 100, "data",
+      CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER,
       &versions, Perspective::IS_SERVER));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*packet, QuicTime::Zero()));
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 307104d..8546076 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -388,7 +388,8 @@
   }
   QUIC_DLOG(INFO) << ENDPOINT
                   << "Created connection with connection_id: " << connection_id
-                  << " and version: " << ParsedQuicVersionToString(version());
+                  << " and version: "
+                  << QuicVersionToString(transport_version());
 
   QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(connection_id,
                                                         transport_version()))
@@ -2883,20 +2884,6 @@
   }
 }
 
-void QuicConnection::InstallDecrypter(
-    EncryptionLevel level,
-    std::unique_ptr<QuicDecrypter> decrypter) {
-  framer_.InstallDecrypter(level, std::move(decrypter));
-  if (!undecryptable_packets_.empty() &&
-      !process_undecryptable_packets_alarm_->IsSet()) {
-    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
-  framer_.RemoveDecrypter(level);
-}
-
 const QuicDecrypter* QuicConnection::decrypter() const {
   return framer_.decrypter();
 }
@@ -3920,13 +3907,6 @@
   return packet_generator_.GetGuaranteedLargestMessagePayload();
 }
 
-uint32_t QuicConnection::cipher_id() const {
-  if (version().KnowsWhichDecrypterToUse()) {
-    return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
-  }
-  return framer_.decrypter()->cipher_id();
-}
-
 bool QuicConnection::ShouldSetAckAlarm() const {
   DCHECK(ack_frame_updated());
   if (ack_alarm_->IsSet()) {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index d13458d..602361e 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -672,10 +672,6 @@
                                std::unique_ptr<QuicDecrypter> decrypter,
                                bool latch_once_used);
 
-  void InstallDecrypter(EncryptionLevel level,
-                        std::unique_ptr<QuicDecrypter> decrypter);
-  void RemoveDecrypter(EncryptionLevel level);
-
   const QuicDecrypter* decrypter() const;
   const QuicDecrypter* alternative_decrypter() const;
 
@@ -769,8 +765,8 @@
   // connection ID lengths do not change.
   QuicPacketLength GetGuaranteedLargestMessagePayload() const;
 
-  // Returns the id of the cipher last used for decrypting packets.
-  uint32_t cipher_id() const;
+  // Return the id of the cipher of the primary decrypter of the framer.
+  uint32_t cipher_id() const { return framer_.decrypter()->cipher_id(); }
 
   std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
     return termination_packets_.get();
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 4072ecd..cd53edf 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -5,15 +5,14 @@
 #include "net/third_party/quiche/src/quic/core/quic_connection.h"
 
 #include <errno.h>
-
 #include <memory>
 #include <ostream>
-#include <string>
 #include <utility>
 
+#include <string>
+
 #include "net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h"
 #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
-#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -359,21 +358,8 @@
     }
 
     if (use_tagging_decrypter_) {
-      if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-        framer_.framer()->InstallDecrypter(ENCRYPTION_INITIAL,
-                                           QuicMakeUnique<TaggingDecrypter>());
-        framer_.framer()->InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                                           QuicMakeUnique<TaggingDecrypter>());
-        framer_.framer()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                                           QuicMakeUnique<TaggingDecrypter>());
-      } else {
-        framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
-                                       QuicMakeUnique<TaggingDecrypter>());
-      }
-    } else if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-      framer_.framer()->InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
+      framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
+                                     QuicMakeUnique<TaggingDecrypter>());
     }
     EXPECT_TRUE(framer_.ProcessPacket(packet));
     if (block_on_next_write_) {
@@ -981,12 +967,6 @@
         .WillRepeatedly(Return(QuicTime::Zero()));
     EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
         .Times(AnyNumber());
-
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      connection_.InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
-    }
   }
 
   QuicConnectionTest(const QuicConnectionTest&) = delete;
@@ -1014,16 +994,6 @@
 
   void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
 
-  void SetDecrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicDecrypter> decrypter) {
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      connection_.InstallDecrypter(level, std::move(decrypter));
-      connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
-    } else {
-      connection_.SetDecrypter(level, std::move(decrypter));
-    }
-  }
-
   void ProcessPacket(uint64_t number) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacket(number);
@@ -1078,11 +1048,8 @@
   void ForceProcessFramePacket(QuicFrame frame) {
     QuicFrames frames;
     frames.push_back(QuicFrame(frame));
-    bool send_version = connection_.perspective() == Perspective::IS_SERVER;
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      send_version = true;
-    }
-    QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
+    QuicPacketCreatorPeer::SetSendVersionInPacket(
+        &peer_creator_, connection_.perspective() == Perspective::IS_SERVER);
     QuicPacketHeader header;
     QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
     char encrypted_buffer[kMaxOutgoingPacketSize];
@@ -1114,16 +1081,6 @@
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_included = CONNECTION_ID_ABSENT;
     }
-    if (level == ENCRYPTION_INITIAL &&
-        peer_framer_.version().KnowsWhichDecrypterToUse()) {
-      header.version_flag = true;
-      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-      if (peer_framer_.perspective() == Perspective::IS_SERVER) {
-        header.source_connection_id = connection_id_;
-        header.source_connection_id_included = CONNECTION_ID_PRESENT;
-      }
-    }
     header.packet_number = QuicPacketNumber(number);
     QuicFrames frames;
     frames.push_back(frame);
@@ -1137,16 +1094,9 @@
           QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
           QuicMakeUnique<TaggingEncrypter>(0x01));
       // Set the corresponding decrypter.
-      if (connection_.version().KnowsWhichDecrypterToUse()) {
-        connection_.InstallDecrypter(
-            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-            QuicMakeUnique<StrictTaggingDecrypter>(0x01));
-        connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
-      } else {
-        connection_.SetDecrypter(
-            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-            QuicMakeUnique<StrictTaggingDecrypter>(0x01));
-      }
+      connection_.SetDecrypter(
+          QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+          QuicMakeUnique<StrictTaggingDecrypter>(0x01));
     }
 
     char buffer[kMaxOutgoingPacketSize];
@@ -3012,8 +2962,8 @@
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
   peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
                             QuicMakeUnique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+  connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           QuicMakeUnique<StrictTaggingDecrypter>(0x01));
   ProcessDataPacketAtLevel(2, false, ENCRYPTION_FORWARD_SECURE);
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -3438,7 +3388,7 @@
         1, stream_id, QUIC_ERROR_PROCESSING_STREAM, 14)));
   }
   EXPECT_EQ(1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
   EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
 }
 
@@ -4250,8 +4200,8 @@
 
   // Transition to the new encryption state and process another encrypted packet
   // which should result in the original packet being processed.
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
   connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                            QuicMakeUnique<TaggingEncrypter>(tag));
@@ -4324,8 +4274,8 @@
   // Transition to the new encryption state and process another encrypted packet
   // which should result in the original packets being processed.
   EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
   connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
@@ -5658,8 +5608,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -5700,8 +5650,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -5781,8 +5731,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -5843,8 +5793,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -5981,8 +5931,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6037,8 +5987,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6098,8 +6048,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6165,8 +6115,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6252,8 +6202,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6323,8 +6273,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(tag));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(tag));
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(tag));
   // Process a packet from the non-crypto stream.
@@ -6494,8 +6444,8 @@
   EXPECT_CALL(visitor_, OnStreamFrame(_));
   peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
                             QuicMakeUnique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+  connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           QuicMakeUnique<StrictTaggingDecrypter>(0x01));
   ProcessDataPacketAtLevel(1, false, ENCRYPTION_FORWARD_SECURE);
   connection_.SendStreamDataWithString(
       GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
@@ -8780,8 +8730,8 @@
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(0x02));
   connection_.SetEncrypter(ENCRYPTION_INITIAL,
                            QuicMakeUnique<TaggingEncrypter>(0x02));
   // Receives packet 1000 in application data.
@@ -8808,8 +8758,8 @@
 
   peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
                             QuicMakeUnique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+  connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           QuicMakeUnique<StrictTaggingDecrypter>(0x02));
   // Verify zero rtt and forward secure packets get acked in the same packet.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   ProcessDataPacketAtLevel(1003, false, ENCRYPTION_FORWARD_SECURE);
@@ -8828,8 +8778,8 @@
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
                             QuicMakeUnique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+  connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                           QuicMakeUnique<StrictTaggingDecrypter>(0x02));
   connection_.SetEncrypter(ENCRYPTION_INITIAL,
                            QuicMakeUnique<TaggingEncrypter>(0x02));
   // Receives packet 1000 in application data.
diff --git a/quic/core/quic_crypto_client_handshaker.cc b/quic/core/quic_crypto_client_handshaker.cc
index d6c9af4..013ab3f 100644
--- a/quic/core/quic_crypto_client_handshaker.cc
+++ b/quic/core/quic_crypto_client_handshaker.cc
@@ -375,16 +375,10 @@
       crypto_config_->pad_full_hello());
   SendHandshakeMessage(out);
   // Be prepared to decrypt with the new server write key.
-  if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
-    session()->connection()->InstallDecrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::move(crypto_negotiated_params_->initial_crypters.decrypter));
-  } else {
-    session()->connection()->SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::move(crypto_negotiated_params_->initial_crypters.decrypter),
-        true /* latch once used */);
-  }
+  session()->connection()->SetAlternativeDecrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+      true /* latch once used */);
   // Send subsequent packets under encryption on the assumption that the
   // server will accept the handshake.
   session()->connection()->SetEncrypter(
@@ -590,8 +584,10 @@
   // to see whether the response was a reject, and if so, move on to
   // the reject-processing state.
   if ((in->tag() == kREJ) || (in->tag() == kSREJ)) {
-    // A reject message must be sent in ENCRYPTION_INITIAL.
-    if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
+    // alternative_decrypter will be nullptr if the original alternative
+    // decrypter latched and became the primary decrypter. That happens
+    // if we received a message encrypted with the INITIAL key.
+    if (session()->connection()->alternative_decrypter() == nullptr) {
       // The rejection was sent encrypted!
       stream_->CloseConnectionWithDetails(
           QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, "encrypted REJ message");
@@ -607,7 +603,10 @@
     return;
   }
 
-  if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
+  // alternative_decrypter will be nullptr if the original alternative
+  // decrypter latched and became the primary decrypter. That happens
+  // if we received a message encrypted with the INITIAL key.
+  if (session()->connection()->alternative_decrypter() != nullptr) {
     // The server hello was sent without encryption.
     stream_->CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
                                         "unencrypted SHLO message");
@@ -639,14 +638,9 @@
   // has been floated that the server shouldn't send packets encrypted
   // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
   // packet from the client.
-  if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
-    session()->connection()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                                              std::move(crypters->decrypter));
-  } else {
-    session()->connection()->SetAlternativeDecrypter(
-        ENCRYPTION_FORWARD_SECURE, std::move(crypters->decrypter),
-        false /* don't latch */);
-  }
+  session()->connection()->SetAlternativeDecrypter(
+      ENCRYPTION_FORWARD_SECURE, std::move(crypters->decrypter),
+      false /* don't latch */);
   session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
                                         std::move(crypters->encrypter));
   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
diff --git a/quic/core/quic_crypto_server_handshaker.cc b/quic/core/quic_crypto_server_handshaker.cc
index c0e61ef..cd3cce9 100644
--- a/quic/core/quic_crypto_server_handshaker.cc
+++ b/quic/core/quic_crypto_server_handshaker.cc
@@ -230,16 +230,9 @@
   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
   // Set the decrypter immediately so that we no longer accept unencrypted
   // packets.
-  if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
-    session()->connection()->InstallDecrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::move(crypto_negotiated_params_->initial_crypters.decrypter));
-    session()->connection()->RemoveDecrypter(ENCRYPTION_INITIAL);
-  } else {
-    session()->connection()->SetDecrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::move(crypto_negotiated_params_->initial_crypters.decrypter));
-  }
+  session()->connection()->SetDecrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter));
   session()->connection()->SetDiversificationNonce(*diversification_nonce);
 
   session()->connection()->set_fully_pad_crypto_hadshake_packets(
@@ -251,17 +244,10 @@
       std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
 
-  if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
-    session()->connection()->InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::move(
-            crypto_negotiated_params_->forward_secure_crypters.decrypter));
-  } else {
-    session()->connection()->SetAlternativeDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
-        false /* don't latch */);
-  }
+  session()->connection()->SetAlternativeDecrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
+      false /* don't latch */);
 
   encryption_established_ = true;
   handshake_confirmed_ = true;
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 0e30453..f99b60f 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -346,32 +346,6 @@
   return NUM_PACKET_NUMBER_SPACES;
 }
 
-EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
-  switch (header.form) {
-    case GOOGLE_QUIC_PACKET:
-      QUIC_BUG << "Cannot determine EncryptionLevel from Google QUIC header";
-      break;
-    case IETF_QUIC_SHORT_HEADER_PACKET:
-      return ENCRYPTION_FORWARD_SECURE;
-    case IETF_QUIC_LONG_HEADER_PACKET:
-      switch (header.long_packet_type) {
-        case INITIAL:
-          return ENCRYPTION_INITIAL;
-        case HANDSHAKE:
-          return ENCRYPTION_HANDSHAKE;
-        case ZERO_RTT_PROTECTED:
-          return ENCRYPTION_ZERO_RTT;
-        case VERSION_NEGOTIATION:
-        case RETRY:
-        case INVALID_PACKET_TYPE:
-          QUIC_BUG << "No encryption used with type "
-                   << QuicUtils::QuicLongHeaderTypetoString(
-                          header.long_packet_type);
-      }
-  }
-  return NUM_ENCRYPTION_LEVELS;
-}
-
 QuicStringPiece TruncateErrorString(QuicStringPiece error) {
   if (error.length() <= kMaxErrorStringLength) {
     return error;
@@ -3887,7 +3861,6 @@
                               std::unique_ptr<QuicDecrypter> decrypter) {
   DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
   DCHECK_GE(level, decrypter_level_);
-  DCHECK(!version_.KnowsWhichDecrypterToUse());
   decrypter_[decrypter_level_] = nullptr;
   decrypter_[level] = std::move(decrypter);
   decrypter_level_ = level;
@@ -3898,7 +3871,6 @@
     std::unique_ptr<QuicDecrypter> decrypter,
     bool latch_once_used) {
   DCHECK_NE(level, decrypter_level_);
-  DCHECK(!version_.KnowsWhichDecrypterToUse());
   if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
     decrypter_[alternative_decrypter_level_] = nullptr;
   }
@@ -3907,22 +3879,6 @@
   alternative_decrypter_latch_ = latch_once_used;
 }
 
-void QuicFramer::InstallDecrypter(EncryptionLevel level,
-                                  std::unique_ptr<QuicDecrypter> decrypter) {
-  DCHECK(version_.KnowsWhichDecrypterToUse());
-  decrypter_[level] = std::move(decrypter);
-}
-
-void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
-  DCHECK(version_.KnowsWhichDecrypterToUse());
-  decrypter_[level] = nullptr;
-}
-
-const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
-  DCHECK(version_.KnowsWhichDecrypterToUse());
-  return decrypter_[level].get();
-}
-
 const QuicDecrypter* QuicFramer::decrypter() const {
   return decrypter_[decrypter_level_].get();
 }
@@ -4018,31 +3974,18 @@
                                 size_t buffer_length,
                                 size_t* decrypted_length,
                                 EncryptionLevel* decrypted_level) {
-  EncryptionLevel level = decrypter_level_;
-  QuicDecrypter* decrypter = decrypter_[level].get();
+  DCHECK(decrypter_[decrypter_level_] != nullptr);
   QuicDecrypter* alternative_decrypter = nullptr;
-  if (version().KnowsWhichDecrypterToUse()) {
-    level = GetEncryptionLevel(header);
-    decrypter = decrypter_[level].get();
-    if (decrypter == nullptr) {
-      return false;
-    }
-    if (level == ENCRYPTION_ZERO_RTT &&
-        perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
-      decrypter->SetDiversificationNonce(*header.nonce);
-    }
-  } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+  if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
     alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
   }
 
-  DCHECK(decrypter != nullptr);
-
-  bool success = decrypter->DecryptPacket(
+  bool success = decrypter_[decrypter_level_]->DecryptPacket(
       header.packet_number.ToUint64(), associated_data, encrypted,
       decrypted_buffer, decrypted_length, buffer_length);
   if (success) {
-    visitor_->OnDecryptedPacket(level);
-    *decrypted_level = level;
+    visitor_->OnDecryptedPacket(decrypter_level_);
+    *decrypted_level = decrypter_level_;
   } else if (alternative_decrypter != nullptr) {
     if (header.nonce != nullptr) {
       DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index 8d2fd93..fc189b2 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -475,11 +475,6 @@
                                std::unique_ptr<QuicDecrypter> decrypter,
                                bool latch_once_used);
 
-  void InstallDecrypter(EncryptionLevel level,
-                        std::unique_ptr<QuicDecrypter> decrypter);
-  void RemoveDecrypter(EncryptionLevel level);
-
-  const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
   const QuicDecrypter* decrypter() const;
   const QuicDecrypter* alternative_decrypter() const;
 
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 4cb837e..bc1dc5c 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -456,13 +456,8 @@
                 kQuicDefaultConnectionIdLength) {
     SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
     framer_.set_version(version_);
-    if (framer_.version().KnowsWhichDecrypterToUse()) {
-      framer_.InstallDecrypter(ENCRYPTION_INITIAL,
-                               std::unique_ptr<QuicDecrypter>(decrypter_));
-    } else {
-      framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                           std::unique_ptr<QuicDecrypter>(decrypter_));
-    }
+    framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                         std::unique_ptr<QuicDecrypter>(decrypter_));
     framer_.SetEncrypter(ENCRYPTION_INITIAL,
                          std::unique_ptr<QuicEncrypter>(encrypter_));
 
@@ -470,14 +465,6 @@
     framer_.InferPacketHeaderTypeFromVersion();
   }
 
-  void SetDecrypterLevel(EncryptionLevel level) {
-    if (!framer_.version().KnowsWhichDecrypterToUse()) {
-      return;
-    }
-    decrypter_ = new TestDecrypter();
-    framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
-  }
-
   // Helper function to get unsigned char representation of the handshake
   // protocol byte of the current QUIC version number.
   unsigned char GetQuicVersionProtocolByte() {
@@ -816,7 +803,6 @@
 }
 
 TEST_P(QuicFramerTest, LargePacket) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[kMaxIncomingPacketSize + 1] = {
     // public flags (8 byte connection_id)
@@ -974,7 +960,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   QuicFramerPeer::SetLastSerializedConnectionId(&framer_,
                                                 FramerTestConnectionId());
   QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
@@ -1030,7 +1015,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   PacketFragments packet = {
       // public flags (0 byte connection_id)
@@ -1130,7 +1114,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
 
   // clang-format off
@@ -1190,7 +1173,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
 
   // clang-format off
@@ -1251,7 +1233,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
 
   // clang-format off
@@ -1313,7 +1294,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // Test the case when a packet is received from the past and future packet
   // numbers are still calculated relative to the largest received packet.
   QuicPacketHeader header;
@@ -1380,7 +1360,6 @@
 }
 
 TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   unsigned char packet[] = {
     // public flags: includes nonce flag
@@ -1550,7 +1529,6 @@
 }
 
 TEST_P(QuicFramerTest, PaddingFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
@@ -1695,7 +1673,6 @@
 }
 
 TEST_P(QuicFramerTest, StreamFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -1852,7 +1829,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // type (short header, 4 byte packet number)
@@ -1906,18 +1882,11 @@
     return;
   }
   QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
   decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
-                                                     Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                         QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
+  framer_.SetAlternativeDecrypter(
+      ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
 
   // clang-format off
   unsigned char packet[] = {
@@ -2062,7 +2031,6 @@
 }
 
 TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -2214,7 +2182,6 @@
 }
 
 TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -2366,7 +2333,6 @@
 }
 
 TEST_P(QuicFramerTest, StreamFrameWithVersion) {
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   PacketFragments packet = {
       // public flags (version, 8 byte connection_id)
@@ -2556,7 +2522,6 @@
 }
 
 TEST_P(QuicFramerTest, RejectPacket) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   visitor_.accept_packet_ = false;
 
   // clang-format off
@@ -2702,7 +2667,6 @@
 }
 
 TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -2854,7 +2818,6 @@
 // and handles the case where the first ack block is larger than the
 // largest_acked packet.
 TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -2989,7 +2952,6 @@
     // for now, only v99
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -3047,7 +3009,6 @@
     // for now, only v99
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -3103,7 +3064,6 @@
     // for now, only v99
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -3153,7 +3113,6 @@
     // for now, only v99
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -3202,7 +3161,6 @@
     // for now, only v99
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -3401,7 +3359,6 @@
 }
 
 TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -3544,7 +3501,6 @@
 // Tests ability to handle multiple ackblocks after the first ack
 // block. Non-version-99 tests include multiple timestamps as well.
 TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -4178,7 +4134,6 @@
 }
 
 TEST_P(QuicFramerTest, RstStreamFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -4304,7 +4259,6 @@
 }
 
 TEST_P(QuicFramerTest, ConnectionCloseFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -4457,7 +4411,6 @@
     // This frame does not exist in versions other than 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -4736,7 +4689,6 @@
     // This frame is available only in version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -4780,7 +4732,6 @@
     // This frame available only in version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -4822,7 +4773,6 @@
 }
 
 TEST_P(QuicFramerTest, BlockedFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // public flags (8 byte connection_id)
@@ -4932,7 +4882,6 @@
 }
 
 TEST_P(QuicFramerTest, PingFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
      // public flags (8 byte connection_id)
@@ -5016,7 +4965,6 @@
   if (framer_.transport_version() <= QUIC_VERSION_44) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet45 = {
        // type (short header, 4 byte packet number)
@@ -5319,18 +5267,11 @@
     return;
   }
   QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
   decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
-                                                     Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                         QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
+  framer_.SetAlternativeDecrypter(
+      ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
   // This packet cannot be decrypted because diversification nonce is missing.
   QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
   EXPECT_TRUE(framer_.ProcessPacket(encrypted));
@@ -5356,18 +5297,11 @@
     return;
   }
   QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
   decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
-                                                     Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                         QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
+  framer_.SetAlternativeDecrypter(
+      ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
   // This packet cannot be decrypted because diversification nonce is missing.
   QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
   EXPECT_FALSE(framer_.ProcessPacket(encrypted));
@@ -6273,7 +6207,6 @@
     // CRYPTO frames aren't supported prior to v46.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet = {
@@ -9529,7 +9462,6 @@
 }
 
 TEST_P(QuicFramerTest, StopPacketProcessing) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
@@ -9724,14 +9656,10 @@
 TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
   // Since we are using ConstructEncryptedPacket, we have to set the framer's
   // crypto to be Null.
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        QuicMakeUnique<NullDecrypter>(framer_.perspective()));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                         QuicMakeUnique<NullDecrypter>(framer_.perspective()));
-  }
+  framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullDecrypter>(framer_.perspective()));
+  framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullEncrypter>(framer_.perspective()));
   ParsedQuicVersionVector versions;
   versions.push_back(framer_.version());
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
@@ -9766,16 +9694,10 @@
 // Verify that the packet returned by ConstructMisFramedEncryptedPacket()
 // does cause the framer to return an error.
 TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // Since we are using ConstructEncryptedPacket, we have to set the framer's
   // crypto to be Null.
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
-                                                     framer_.perspective()));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                         QuicMakeUnique<NullDecrypter>(framer_.perspective()));
-  }
+  framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                       QuicMakeUnique<NullDecrypter>(framer_.perspective()));
   framer_.SetEncrypter(ENCRYPTION_INITIAL,
                        QuicMakeUnique<NullEncrypter>(framer_.perspective()));
   ParsedQuicVersionVector versions;
@@ -9948,7 +9870,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10031,7 +9952,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10119,7 +10039,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10167,7 +10086,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10218,7 +10136,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10267,7 +10184,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10321,7 +10237,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10365,7 +10280,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10415,7 +10329,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10460,7 +10373,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10508,7 +10420,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10538,7 +10449,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10591,7 +10501,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10639,7 +10548,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10688,7 +10596,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -10740,7 +10647,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -10775,7 +10681,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   unsigned char packet99[] = {
@@ -11175,7 +11080,6 @@
     // This frame is only for version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -11231,7 +11135,6 @@
     // This frame is only for version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -11289,7 +11192,6 @@
     // The NEW_CONNECTION_ID frame is only for version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -11382,7 +11284,6 @@
     // This frame is only for version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // type (short header, 4 byte packet number)
@@ -11475,7 +11376,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -11563,7 +11463,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -11646,7 +11545,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet99 = {
@@ -11812,7 +11710,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // type (short header, 4 byte packet number)
@@ -11844,7 +11741,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet = {
@@ -11877,7 +11773,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet = {
@@ -11910,7 +11805,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // type (short header, 4 byte packet number)
@@ -11946,7 +11840,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet = {
@@ -11979,7 +11872,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packet = {
@@ -12012,7 +11904,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet = {
       // type (short header, 4 byte packet number)
@@ -12048,7 +11939,6 @@
   if (framer_.transport_version() != QUIC_VERSION_99) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
 
   // clang-format off
   PacketFragments packets[] = {
@@ -12449,7 +12339,6 @@
     // This frame is only for version 99.
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   PacketFragments packet99 = {
       // type (short header, 4 byte packet number)
@@ -12530,7 +12419,6 @@
 }
 
 TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
@@ -12631,7 +12519,6 @@
 }
 
 TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
@@ -12734,7 +12621,6 @@
 }
 
 TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char packet[] = {
     // public flags (8 byte connection_id)
@@ -12883,7 +12769,6 @@
   if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   unsigned char packet[] = {
     // first coalesced packet
@@ -12978,7 +12863,6 @@
   if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   unsigned char packet[] = {
     // first coalesced packet
@@ -13061,7 +12945,6 @@
   if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   // clang-format off
   unsigned char packet[] = {
     // first coalesced packet
@@ -13122,7 +13005,6 @@
   if (framer_.transport_version() < QUIC_VERSION_46) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   char connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
                                  0x54, 0x32, 0x10, 0x42};
   QuicConnectionId connection_id(connection_id_bytes,
@@ -13163,7 +13045,6 @@
   if (framer_.transport_version() < QUIC_VERSION_46) {
     return;
   }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
   framer_.SetShouldUpdateExpectedConnectionIdLength(true);
 
   // clang-format off
@@ -13218,7 +13099,6 @@
   EXPECT_EQ(visitor_.header_.get()->packet_number,
             QuicPacketNumber(UINT64_C(0x12345678)));
 
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off
   unsigned char short_header_packet[] = {
     // type (short header, 4 byte packet number)
@@ -13286,13 +13166,7 @@
   };
   // clang-format on
 
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             QuicMakeUnique<TestDecrypter>());
-    framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<TestDecrypter>());
-  }
+  framer_.SetDecrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<TestDecrypter>());
   if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
     EXPECT_TRUE(framer_.ProcessPacket(
         QuicEncryptedPacket(AsChars(long_header_packet),
@@ -13328,14 +13202,8 @@
 
   QuicEncryptedPacket short_header_encrypted(
       AsChars(short_header_packet), QUIC_ARRAYSIZE(short_header_packet), false);
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                             QuicMakeUnique<TestDecrypter>());
-    framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-                         QuicMakeUnique<TestDecrypter>());
-  }
+  framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                       QuicMakeUnique<TestDecrypter>());
   EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
 
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index 2b71b06..b642c9f 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -9,7 +9,6 @@
 #include <ostream>
 #include <string>
 
-#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -165,17 +164,6 @@
     client_framer_.set_visitor(&framer_visitor_);
     server_framer_.set_visitor(&framer_visitor_);
     client_framer_.set_data_producer(&producer_);
-    if (server_framer_.version().KnowsWhichDecrypterToUse()) {
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_ZERO_RTT,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_HANDSHAKE,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
-    }
   }
 
   ~QuicPacketCreatorTest() override {
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 1e12424..223383a 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
-#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -216,11 +215,6 @@
         QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
     creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE);
     framer_.set_data_producer(&producer_);
-    if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-      simple_framer_.framer()->InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
-    }
     generator_.AttachPacketFlusher();
   }
 
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index ef2657c..fa9f640 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -37,11 +37,6 @@
   }
 }
 
-bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
-  return transport_version == QUIC_VERSION_99 ||
-         handshake_protocol == PROTOCOL_TLS1_3;
-}
-
 std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
   os << ParsedQuicVersionToString(version);
   return os;
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 160adeb..cc780b4 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -145,8 +145,6 @@
     return handshake_protocol != other.handshake_protocol ||
            transport_version != other.transport_version;
   }
-
-  bool KnowsWhichDecrypterToUse() const;
 };
 
 QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 932d537..5081a48 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -73,8 +73,8 @@
       session()->connection_id(), &crypters);
   session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
                                         std::move(crypters.encrypter));
-  session()->connection()->InstallDecrypter(ENCRYPTION_INITIAL,
-                                            std::move(crypters.decrypter));
+  session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
+                                        std::move(crypters.decrypter));
   state_ = STATE_HANDSHAKE_RUNNING;
   // Configure certificate verification.
   // TODO(nharper): This only verifies certs on initial connection, not on
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
index 3a45f36..c6394b8 100644
--- a/quic/core/tls_handshaker.cc
+++ b/quic/core/tls_handshaker.cc
@@ -205,8 +205,22 @@
     const std::vector<uint8_t>& write_secret) {
   std::unique_ptr<QuicEncrypter> encrypter = CreateEncrypter(write_secret);
   session()->connection()->SetEncrypter(level, std::move(encrypter));
-  std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
-  session()->connection()->InstallDecrypter(level, std::move(decrypter));
+  if (level != ENCRYPTION_FORWARD_SECURE) {
+    std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
+    session()->connection()->SetDecrypter(level, std::move(decrypter));
+  } else {
+    // When forward-secure read keys are available, they get set as the
+    // alternative decrypter instead of the primary decrypter. One reason for
+    // this is that after the forward secure keys become available, the server
+    // still has crypto handshake messages to read at the handshake encryption
+    // level, meaning that both the ENCRYPTION_ZERO_RTT and
+    // ENCRYPTION_FORWARD_SECURE decrypters need to be available. (Tests also
+    // assume that an alternative decrypter gets set, so at some point we need
+    // to call SetAlternativeDecrypter.)
+    std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
+    session()->connection()->SetAlternativeDecrypter(
+        level, std::move(decrypter), /*latch_once_used*/ true);
+  }
 }
 
 void TlsHandshaker::WriteMessage(EncryptionLevel level, QuicStringPiece data) {
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc
index a7b2aa8..6aa83d2 100644
--- a/quic/core/tls_handshaker_test.cc
+++ b/quic/core/tls_handshaker_test.cc
@@ -263,31 +263,15 @@
   }
 }
 
-ParsedQuicVersionVector AllTlsSupportedVersions() {
-  SetQuicReloadableFlag(quic_enable_version_99, true);
-  SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
-  ParsedQuicVersionVector supported_versions;
-  for (QuicTransportVersion version : kSupportedTransportVersions) {
-    if (!QuicVersionUsesCryptoFrames(version)) {
-      // The TLS handshake is only deployable if CRYPTO frames are also used.
-      continue;
-    }
-    supported_versions.push_back(ParsedQuicVersion(PROTOCOL_TLS1_3, version));
-  }
-  return supported_versions;
-}
-
 class TlsHandshakerTest : public QuicTest {
  public:
   TlsHandshakerTest()
       : client_conn_(new MockQuicConnection(&conn_helper_,
                                             &alarm_factory_,
-                                            Perspective::IS_CLIENT,
-                                            AllTlsSupportedVersions())),
+                                            Perspective::IS_CLIENT)),
         server_conn_(new MockQuicConnection(&conn_helper_,
                                             &alarm_factory_,
-                                            Perspective::IS_SERVER,
-                                            AllTlsSupportedVersions())),
+                                            Perspective::IS_SERVER)),
         client_session_(client_conn_, /*create_mock_crypto_stream=*/false),
         server_session_(server_conn_, /*create_mock_crypto_stream=*/false) {
     client_stream_ = new TestQuicCryptoClientStream(&client_session_);
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index ec254b5..96e1802 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -63,16 +63,14 @@
     : TlsHandshaker(stream, session, ssl_ctx),
       proof_source_(proof_source),
       crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {
-  DCHECK_EQ(PROTOCOL_TLS1_3,
-            session->connection()->version().handshake_protocol);
   CrypterPair crypters;
   CryptoUtils::CreateTlsInitialCrypters(
       Perspective::IS_SERVER, session->connection()->transport_version(),
       session->connection_id(), &crypters);
   session->connection()->SetEncrypter(ENCRYPTION_INITIAL,
                                       std::move(crypters.encrypter));
-  session->connection()->InstallDecrypter(ENCRYPTION_INITIAL,
-                                          std::move(crypters.decrypter));
+  session->connection()->SetDecrypter(ENCRYPTION_INITIAL,
+                                      std::move(crypters.decrypter));
 
   // Configure the SSL to be a server.
   SSL_set_accept_state(ssl());
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc
index 63154b9..af33d4e 100644
--- a/quic/test_tools/crypto_test_utils.cc
+++ b/quic/test_tools/crypto_test_utils.cc
@@ -749,11 +749,6 @@
 void CompareCrypters(const QuicEncrypter* encrypter,
                      const QuicDecrypter* decrypter,
                      std::string label) {
-  if (encrypter == nullptr || decrypter == nullptr) {
-    ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
-                  << decrypter;
-    return;
-  }
   QuicStringPiece encrypter_key = encrypter->GetKey();
   QuicStringPiece encrypter_iv = encrypter->GetNoncePrefix();
   QuicStringPiece decrypter_key = decrypter->GetKey();
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index 2de1491..cd54eb8 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -499,7 +499,7 @@
     : QuicSession(connection,
                   nullptr,
                   DefaultQuicConfig(),
-                  connection->supported_versions()) {
+                  CurrentSupportedVersions()) {
   if (create_mock_crypto_stream) {
     crypto_stream_ = QuicMakeUnique<MockQuicCryptoStream>(this);
   }
@@ -923,11 +923,6 @@
   header.reset_flag = reset_flag;
   header.packet_number_length = packet_number_length;
   header.packet_number = QuicPacketNumber(packet_number);
-  if (QuicVersionHasLongHeaderLengths((*versions)[0].transport_version) &&
-      version_flag) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
   QuicFrame frame(QuicStreamFrame(1, false, 0, QuicStringPiece(data)));
   QuicFrames frames;
   frames.push_back(frame);
@@ -946,7 +941,8 @@
       GetIncludedDestinationConnectionIdLength(header),
       GetIncludedSourceConnectionIdLength(header), version_flag,
       false /* no diversification nonce */, packet_number_length,
-      header.retry_token_length_length, 0, header.length_length)] = 0x1F;
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0)] =
+      0x1F;
 
   char* buffer = new char[kMaxOutgoingPacketSize];
   size_t encrypted_length =
diff --git a/quic/test_tools/simulator/quic_endpoint.cc b/quic/test_tools/simulator/quic_endpoint.cc
index 9e5c3fa..1072724 100644
--- a/quic/test_tools/simulator/quic_endpoint.cc
+++ b/quic/test_tools/simulator/quic_endpoint.cc
@@ -86,14 +86,8 @@
   connection_.set_visitor(this);
   connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
                            QuicMakeUnique<NullEncrypter>(perspective));
-  if (connection_.version().KnowsWhichDecrypterToUse()) {
-    connection_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                                 QuicMakeUnique<NullDecrypter>(perspective));
-    connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
-  } else {
-    connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-                             QuicMakeUnique<NullDecrypter>(perspective));
-  }
+  connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           QuicMakeUnique<NullDecrypter>(perspective));
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   if (perspective == Perspective::IS_SERVER) {
     // Skip version negotiation.