Use Span in QUIC-LB EncryptionPass()

PiperOrigin-RevId: 441529229
diff --git a/quiche/quic/load_balancer/load_balancer_config.cc b/quiche/quic/load_balancer/load_balancer_config.cc
index b0c161f..56669e0 100644
--- a/quiche/quic/load_balancer/load_balancer_config.cc
+++ b/quiche/quic/load_balancer/load_balancer_config.cc
@@ -137,25 +137,25 @@
              : absl::optional<LoadBalancerConfig>();
 }
 
-bool LoadBalancerConfig::EncryptionPass(uint8_t *target,
+bool LoadBalancerConfig::EncryptionPass(absl::Span<uint8_t> target,
                                         const uint8_t index) const {
   uint8_t buf[kLoadBalancerBlockSize];
-  if (!key_.has_value() || target == nullptr) {
+  if (!key_.has_value() || target.size() < plaintext_len()) {
     return false;
   }
   if (index % 2) {  // Odd indices go from left to right
-    TakePlaintextFromLeft(buf, target, plaintext_len(), index);
+    TakePlaintextFromLeft(buf, target.data(), plaintext_len(), index);
   } else {
-    TakePlaintextFromRight(buf, target, plaintext_len(), index);
+    TakePlaintextFromRight(buf, target.data(), plaintext_len(), index);
   }
   if (!BlockEncrypt(buf, buf)) {
     return false;
   }
   // XOR bits over the correct half.
   if (index % 2) {
-    CiphertextXorWithRight(target, buf, plaintext_len());
+    CiphertextXorWithRight(target.data(), buf, plaintext_len());
   } else {
-    CiphertextXorWithLeft(target, buf, plaintext_len());
+    CiphertextXorWithLeft(target.data(), buf, plaintext_len());
   }
   return true;
 }
diff --git a/quiche/quic/load_balancer/load_balancer_config.h b/quiche/quic/load_balancer/load_balancer_config.h
index 251cd3a..bc92d5f 100644
--- a/quiche/quic/load_balancer/load_balancer_config.h
+++ b/quiche/quic/load_balancer/load_balancer_config.h
@@ -47,8 +47,9 @@
 
   // Handles one pass of 4-pass encryption. Encoder and decoder use of this
   // function varies substantially, so they are not implemented here.
-  // Returns false if the config is not encrypted.
-  ABSL_MUST_USE_RESULT bool EncryptionPass(uint8_t *target,
+  // Returns false if the config is not encrypted, or if |target| isn't long
+  // enough.
+  ABSL_MUST_USE_RESULT bool EncryptionPass(absl::Span<uint8_t> target,
                                            const uint8_t index) const;
   // Use the key to do a block encryption, which is used both in all cases of
   // encrypted configs. Returns false if there's no key.
diff --git a/quiche/quic/load_balancer/load_balancer_config_test.cc b/quiche/quic/load_balancer/load_balancer_config_test.cc
index 8c58c5d..f59a3be 100644
--- a/quiche/quic/load_balancer/load_balancer_config_test.cc
+++ b/quiche/quic/load_balancer/load_balancer_config_test.cc
@@ -4,6 +4,9 @@
 
 #include "quiche/quic/load_balancer/load_balancer_config.h"
 
+#include <cstdint>
+
+#include "absl/types/span.h"
 #include "quiche/quic/platform/api/quic_expect_bug.h"
 #include "quiche/quic/platform/api/quic_test.h"
 #include "quiche/quic/test_tools/quic_test_utils.h"
@@ -91,27 +94,26 @@
   std::array<uint8_t, 7> bytes = {
       0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
   };
-  EXPECT_FALSE(config->EncryptionPass(nullptr, 0));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 1));
+  // Input is too short.
+  EXPECT_FALSE(config->EncryptionPass(absl::Span<uint8_t>(bytes.data(), 6), 0));
+  EXPECT_TRUE(config->EncryptionPass(absl::Span<uint8_t>(bytes), 1));
   EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                             {0x31, 0x44, 0x1a, 0x9d, 0xbc, 0x04, 0x26})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 2));
+  EXPECT_TRUE(config->EncryptionPass(absl::Span<uint8_t>(bytes), 2));
   EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                             {0x4f, 0xdd, 0x0c, 0x9d, 0xbc, 0x04, 0x26})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 3));
+  EXPECT_TRUE(config->EncryptionPass(absl::Span<uint8_t>(bytes), 3));
   EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                             {0x4f, 0xdd, 0x0c, 0x9b, 0xba, 0x1e, 0xe0})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 4));
+  EXPECT_TRUE(config->EncryptionPass(absl::Span<uint8_t>(bytes), 4));
   EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                             {0xe2, 0x3c, 0xb4, 0x2b, 0xba, 0x1e, 0xe0})));
 }
 
 TEST_F(LoadBalancerConfigTest, EncryptionPassPlaintext) {
   auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  std::array<uint8_t, 7> bytes = {
-      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
-  };
-  EXPECT_FALSE(config->EncryptionPass(bytes.data(), 1));
+  std::array<uint8_t, 7> bytes = {0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75};
+  EXPECT_FALSE(config->EncryptionPass(absl::Span<uint8_t>(bytes), 1));
 }
 
 TEST_F(LoadBalancerConfigTest, InvalidBlockEncryption) {
@@ -119,7 +121,7 @@
   auto pt_config = LoadBalancerConfig::CreateUnencrypted(0, 8, 8);
   EXPECT_FALSE(pt_config->BlockEncrypt(pt, ct));
   EXPECT_FALSE(pt_config->BlockDecrypt(ct, pt));
-  EXPECT_FALSE(pt_config->EncryptionPass(pt, 0));
+  EXPECT_FALSE(pt_config->EncryptionPass(absl::Span<uint8_t>(pt), 0));
   auto small_cid_config =
       LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
   EXPECT_TRUE(small_cid_config->BlockEncrypt(pt, ct));
diff --git a/quiche/quic/load_balancer/load_balancer_decoder.cc b/quiche/quic/load_balancer/load_balancer_decoder.cc
index 4f328e8..a946b36 100644
--- a/quiche/quic/load_balancer/load_balancer_decoder.cc
+++ b/quiche/quic/load_balancer/load_balancer_decoder.cc
@@ -61,7 +61,7 @@
     memcpy(result, data, config->plaintext_len());
     uint8_t end = (config->server_id_len() > config->nonce_len()) ? 1 : 2;
     for (uint8_t i = kNumLoadBalancerCryptoPasses; i >= end; i--) {
-      if (!config->EncryptionPass(result, i)) {
+      if (!config->EncryptionPass(absl::Span<uint8_t>(result), i)) {
         return absl::optional<LoadBalancerServerId>();
       }
     }
diff --git a/quiche/quic/load_balancer/load_balancer_encoder.cc b/quiche/quic/load_balancer/load_balancer_encoder.cc
index 6a4655c..bb9608b 100644
--- a/quiche/quic/load_balancer/load_balancer_encoder.cc
+++ b/quiche/quic/load_balancer/load_balancer_encoder.cc
@@ -154,7 +154,8 @@
     }
   } else {
     for (uint8_t i = 1; i <= kNumLoadBalancerCryptoPasses; i++) {
-      if (!config_->EncryptionPass(block_start, i)) {
+      if (!config_->EncryptionPass(absl::Span<uint8_t>(block_start, length - 1),
+                                   i)) {
         QUIC_LOG(ERROR) << "Block encryption failed";
         return QuicConnectionId();
       }