Make CRYPT_ArcFourCryptBlock() take spans.

Take 2 spans instead of 2 pairs of pointers + size. Along the way, add
support for spans to CFX_BinaryBuf.

Change-Id: Ia6c6b6058dd1267168607441a8d2796a48795c88
Bug: 1030583
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63154
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fdrm/fx_crypt.cpp b/core/fdrm/fx_crypt.cpp
index 2c3d379..5d53fab 100644
--- a/core/fdrm/fx_crypt.cpp
+++ b/core/fdrm/fx_crypt.cpp
@@ -165,13 +165,11 @@
   }
 }
 
-void CRYPT_ArcFourCryptBlock(uint8_t* pData,
-                             uint32_t size,
-                             const uint8_t* key,
-                             uint32_t keylen) {
+void CRYPT_ArcFourCryptBlock(pdfium::span<uint8_t> data,
+                             pdfium::span<const uint8_t> key) {
   CRYPT_rc4_context s;
-  CRYPT_ArcFourSetup(&s, key, keylen);
-  CRYPT_ArcFourCrypt(&s, pData, size);
+  CRYPT_ArcFourSetup(&s, key.data(), key.size());
+  CRYPT_ArcFourCrypt(&s, data.data(), data.size());
 }
 
 void CRYPT_MD5Start(CRYPT_md5_context* context) {
diff --git a/core/fdrm/fx_crypt.h b/core/fdrm/fx_crypt.h
index 90af101..5cd5a4a 100644
--- a/core/fdrm/fx_crypt.h
+++ b/core/fdrm/fx_crypt.h
@@ -8,6 +8,7 @@
 #define CORE_FDRM_FX_CRYPT_H_
 
 #include "core/fxcrt/fx_system.h"
+#include "third_party/base/span.h"
 
 constexpr int32_t kRC4ContextPermutationLength = 256;
 struct CRYPT_rc4_context {
@@ -45,10 +46,8 @@
   uint8_t buffer[128];
 };
 
-void CRYPT_ArcFourCryptBlock(uint8_t* data,
-                             uint32_t size,
-                             const uint8_t* key,
-                             uint32_t keylen);
+void CRYPT_ArcFourCryptBlock(pdfium::span<uint8_t> data,
+                             pdfium::span<const uint8_t> key);
 void CRYPT_ArcFourSetup(CRYPT_rc4_context* context,
                         const uint8_t* key,
                         uint32_t size);
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index f551318..6453ee6 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -97,7 +97,7 @@
     ASSERT(dest_size == source.size());
     if (dest_buf != source.data())
       memcpy(dest_buf, source.data(), source.size());
-    CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
+    CRYPT_ArcFourCryptBlock({dest_buf, dest_size}, {realkey, realkeylen});
   }
 }
 
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index d0dee15..7553864 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -432,7 +432,7 @@
   uint8_t ukeybuf[32];
   if (m_Revision == 2) {
     memcpy(ukeybuf, defpasscode, 32);
-    CRYPT_ArcFourCryptBlock(ukeybuf, 32, m_EncryptKey, m_KeyLen);
+    CRYPT_ArcFourCryptBlock(ukeybuf, {m_EncryptKey, m_KeyLen});
     return memcmp(ukey.c_str(), ukeybuf, 16) == 0;
   }
 
@@ -444,7 +444,7 @@
   for (int32_t i = 19; i >= 0; i--) {
     for (size_t j = 0; j < m_KeyLen; j++)
       tmpkey[j] = m_EncryptKey[j] ^ static_cast<uint8_t>(i);
-    CRYPT_ArcFourCryptBlock(test, 32, tmpkey, m_KeyLen);
+    CRYPT_ArcFourCryptBlock(test, {tmpkey, m_KeyLen});
   }
   CRYPT_md5_context md5;
   CRYPT_MD5Start(&md5);
@@ -479,18 +479,19 @@
   size_t okeylen = std::min<size_t>(okey.GetLength(), 32);
   uint8_t okeybuf[64] = {};
   memcpy(okeybuf, okey.c_str(), okeylen);
+  pdfium::span<uint8_t> okey_span(okeybuf, okeylen);
   if (m_Revision == 2) {
-    CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, m_KeyLen);
+    CRYPT_ArcFourCryptBlock(okey_span, {enckey, m_KeyLen});
   } else {
     for (int32_t i = 19; i >= 0; i--) {
       uint8_t tempkey[32] = {};
       for (size_t j = 0; j < m_KeyLen; j++)
         tempkey[j] = enckey[j] ^ static_cast<uint8_t>(i);
-      CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, m_KeyLen);
+      CRYPT_ArcFourCryptBlock(okey_span, {tempkey, m_KeyLen});
     }
   }
   size_t len = 32;
-  while (len && defpasscode[len - 1] == okeybuf[len - 1])
+  while (len && defpasscode[len - 1] == okey_span[len - 1])
     len--;
 
   return ByteString(okeybuf, len);
@@ -559,13 +560,13 @@
                         ? user_password[i]
                         : defpasscode[i - user_password.GetLength()];
     }
-    CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
+    CRYPT_ArcFourCryptBlock(passcode, {enckey, key_len});
     uint8_t tempkey[32];
     if (m_Revision >= 3) {
       for (uint8_t i = 1; i <= 19; i++) {
         for (size_t j = 0; j < key_len; j++)
           tempkey[j] = enckey[j] ^ i;
-        CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
+        CRYPT_ArcFourCryptBlock(passcode, {tempkey, key_len});
       }
     }
     pEncryptDict->SetNewFor<CPDF_String>("O", ByteString(passcode, 32), false);
@@ -580,7 +581,7 @@
   if (m_Revision < 3) {
     uint8_t tempbuf[32];
     memcpy(tempbuf, defpasscode, 32);
-    CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
+    CRYPT_ArcFourCryptBlock(tempbuf, {m_EncryptKey, key_len});
     pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(tempbuf, 32), false);
   } else {
     CRYPT_md5_context md5;
@@ -591,12 +592,13 @@
 
     uint8_t digest[32];
     CRYPT_MD5Finish(&md5, digest);
-    CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
+    pdfium::span<uint8_t> partial_digest_span(digest, 16);
+    CRYPT_ArcFourCryptBlock(partial_digest_span, {m_EncryptKey, key_len});
     uint8_t tempkey[32];
     for (uint8_t i = 1; i <= 19; i++) {
       for (size_t j = 0; j < key_len; j++)
         tempkey[j] = m_EncryptKey[j] ^ i;
-      CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
+      CRYPT_ArcFourCryptBlock(partial_digest_span, {tempkey, key_len});
     }
     CRYPT_MD5Generate(digest, 16, digest + 16);
     pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(digest, 32), false);
diff --git a/core/fxcrt/cfx_binarybuf.cpp b/core/fxcrt/cfx_binarybuf.cpp
index 22800a5..e24590c 100644
--- a/core/fxcrt/cfx_binarybuf.cpp
+++ b/core/fxcrt/cfx_binarybuf.cpp
@@ -24,6 +24,14 @@
   m_DataSize -= count;
 }
 
+pdfium::span<uint8_t> CFX_BinaryBuf::GetSpan() {
+  return {GetBuffer(), GetSize()};
+}
+
+pdfium::span<const uint8_t> CFX_BinaryBuf::GetSpan() const {
+  return {GetBuffer(), GetSize()};
+}
+
 size_t CFX_BinaryBuf::GetLength() const {
   return m_DataSize;
 }
@@ -60,6 +68,10 @@
                       : FX_Alloc(uint8_t, m_AllocSize));
 }
 
+void CFX_BinaryBuf::AppendSpan(pdfium::span<const uint8_t> span) {
+  return AppendBlock(span.data(), span.size());
+}
+
 void CFX_BinaryBuf::AppendBlock(const void* pBuf, size_t size) {
   if (size == 0)
     return;
diff --git a/core/fxcrt/cfx_binarybuf.h b/core/fxcrt/cfx_binarybuf.h
index 84934af..b757c9a 100644
--- a/core/fxcrt/cfx_binarybuf.h
+++ b/core/fxcrt/cfx_binarybuf.h
@@ -12,12 +12,15 @@
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
+#include "third_party/base/span.h"
 
 class CFX_BinaryBuf {
  public:
   CFX_BinaryBuf();
   virtual ~CFX_BinaryBuf();
 
+  pdfium::span<uint8_t> GetSpan();
+  pdfium::span<const uint8_t> GetSpan() const;
   uint8_t* GetBuffer() const { return m_pBuffer.get(); }
   size_t GetSize() const { return m_DataSize; }
   virtual size_t GetLength() const;
@@ -26,6 +29,7 @@
   void Clear();
   void SetAllocStep(size_t step) { m_AllocStep = step; }
   void EstimateSize(size_t size);
+  void AppendSpan(pdfium::span<const uint8_t> span);
   void AppendBlock(const void* pBuf, size_t size);
   void AppendString(const ByteString& str) {
     AppendBlock(str.c_str(), str.GetLength());
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index 4038e9d..f5bfc82 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -282,8 +282,7 @@
   if (buffer.size() < kMinGlobalDataBytes)
     return false;
 
-  CRYPT_ArcFourCryptBlock(buffer.data(), buffer.size(), kRC4KEY,
-                          sizeof(kRC4KEY));
+  CRYPT_ArcFourCryptBlock(buffer, kRC4KEY);
 
   uint8_t* p = buffer.data();
   uint16_t wType = *((uint16_t*)p);
@@ -384,7 +383,7 @@
     if (sData.GetSize() + sElement.GetSize() > kMaxGlobalDataBytes)
       break;
 
-    sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
+    sData.AppendSpan(sElement.GetSpan());
     nCount++;
   }
 
@@ -397,10 +396,9 @@
 
   uint32_t dwSize = sData.GetSize();
   sFile.AppendBlock(&dwSize, sizeof(uint32_t));
-  sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
+  sFile.AppendSpan(sData.GetSpan());
 
-  CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), kRC4KEY,
-                          sizeof(kRC4KEY));
+  CRYPT_ArcFourCryptBlock(sFile.GetSpan(), kRC4KEY);
 
   return m_pDelegate->StoreBuffer({sFile.GetBuffer(), sFile.GetSize()});
 }