Spanify CRYPT_AESEncrypt() to remove a UNSAFE_TODO()

- Change parameters to spans.
- Use span operations and range-based for-loops within.
- Avoid unnecessary copying of IV. Operate in-place instead.

Bug: 42271176
Change-Id: Iad2f883cb4257d614fe1b0e2b09ea50df078ea08
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121154
Reviewed-by: Tom Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fdrm/fx_crypt_aes.cpp b/core/fdrm/fx_crypt_aes.cpp
index 80408d6..a191107 100644
--- a/core/fdrm/fx_crypt_aes.cpp
+++ b/core/fdrm/fx_crypt_aes.cpp
@@ -622,26 +622,19 @@
 }
 
 void CRYPT_AESEncrypt(CRYPT_aes_context* ctx,
-                      uint8_t* dest,
-                      const uint8_t* src,
-                      uint32_t size) {
-  unsigned int iv[4];
-  int i;
-  CHECK_EQ((size & 15), 0);
-  UNSAFE_TODO({
-    FXSYS_memcpy(iv, ctx->iv.data(), sizeof(iv));
-    while (size != 0) {
-      for (i = 0; i < 4; i++) {
-        iv[i] ^= fxcrt::GetUInt32MSBFirst(pdfium::make_span(src + 4 * i, 4u));
-      }
-      aes_encrypt_nb_4(ctx, iv);
-      for (i = 0; i < 4; i++) {
-        fxcrt::PutUInt32MSBFirst(iv[i], pdfium::make_span(dest + 4 * i, 4u));
-      }
-      dest += 16;
-      src += 16;
-      size -= 16;
+                      pdfium::span<uint8_t> dest,
+                      pdfium::span<const uint8_t> src) {
+  CHECK_EQ((src.size() & 15), 0);
+  auto ctx_iv = pdfium::make_span(ctx->iv).first(4u);
+  while (!src.empty()) {
+    for (auto& iv_element : ctx_iv) {
+      iv_element ^= fxcrt::GetUInt32MSBFirst(src.first(4u));
+      src = src.subspan(4u);
     }
-    FXSYS_memcpy(ctx->iv.data(), iv, sizeof(iv));
-  });
+    aes_encrypt_nb_4(ctx, ctx_iv.data());
+    for (auto& iv_element : ctx_iv) {
+      fxcrt::PutUInt32MSBFirst(iv_element, dest.first(4u));
+      dest = dest.subspan(4u);
+    }
+  }
 }
diff --git a/core/fdrm/fx_crypt_aes.h b/core/fdrm/fx_crypt_aes.h
index c916310..ab673d2 100644
--- a/core/fdrm/fx_crypt_aes.h
+++ b/core/fdrm/fx_crypt_aes.h
@@ -11,6 +11,8 @@
 
 #include <array>
 
+#include "core/fxcrt/span.h"
+
 struct CRYPT_aes_context {
   static constexpr int kMaxNb = 8;
   static constexpr int kMaxNr = 14;
@@ -32,8 +34,7 @@
                       const uint8_t* src,
                       uint32_t size);
 void CRYPT_AESEncrypt(CRYPT_aes_context* ctx,
-                      uint8_t* dest,
-                      const uint8_t* src,
-                      uint32_t size);
+                      pdfium::span<uint8_t> dest,
+                      pdfium::span<const uint8_t> src);
 
 #endif  // CORE_FDRM_FX_CRYPT_AES_H_
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index f323469..76df795 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -79,14 +79,14 @@
     DataVector<uint8_t> dest(32 + nblocks * 16);
     auto dest_span = pdfium::make_span(dest);
     fxcrt::Copy(iv, dest_span);
-    CRYPT_AESEncrypt(m_pAESContext.get(), dest_span.subspan(16).data(),
-                     source.data(), nblocks * 16);
+    CRYPT_AESEncrypt(m_pAESContext.get(), dest_span.subspan(16),
+                     source.first(nblocks * 16));
     uint8_t padding[16];
     fxcrt::Copy(source.subspan(nblocks * 16, source.size() % 16), padding);
     fxcrt::Fill(pdfium::make_span(padding).subspan(source.size() % 16),
                 16 - source.size() % 16);
-    CRYPT_AESEncrypt(m_pAESContext.get(),
-                     dest_span.subspan(nblocks * 16 + 16).data(), padding, 16);
+    CRYPT_AESEncrypt(m_pAESContext.get(), dest_span.subspan(nblocks * 16 + 16),
+                     padding);
     return dest;
   }
   DataVector<uint8_t> dest(source.begin(), source.end());
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index af1b3b0..bfe43d3 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -151,10 +151,10 @@
         }
       });
     }
+    CHECK_EQ(content.size(), encrypted_output.size());
     CRYPT_AESSetKey(&aes, key, 16);
     CRYPT_AESSetIV(&aes, iv);
-    CRYPT_AESEncrypt(&aes, encrypted_output_span.data(), content.data(),
-                     encrypted_output_span.size());
+    CRYPT_AESEncrypt(&aes, encrypted_output_span, content);
 
     switch (BigOrder64BitsMod3(encrypted_output_span)) {
       case 0:
@@ -652,7 +652,7 @@
   CRYPT_AESSetKey(&aes, digest1, 32);
   uint8_t iv[16] = {};
   CRYPT_AESSetIV(&aes, iv);
-  CRYPT_AESEncrypt(&aes, digest1, m_EncryptKey.data(), m_EncryptKey.size());
+  CRYPT_AESEncrypt(&aes, digest1, m_EncryptKey);
   pEncryptDict->SetNewFor<CPDF_String>("UE",
                                        UNSAFE_TODO(ByteString(digest1, 32)));
 }
@@ -685,10 +685,10 @@
   uint8_t iv[16] = {};
   CRYPT_AESSetIV(&aes, iv);
 
-  uint8_t buf1[16];
-  CRYPT_AESEncrypt(&aes, buf1, buf, 16);
+  uint8_t dest[16];
+  CRYPT_AESEncrypt(&aes, dest, buf);
   pEncryptDict->SetNewFor<CPDF_String>("Perms",
-                                       UNSAFE_TODO(ByteString(buf1, 16)));
+                                       UNSAFE_TODO(ByteString(dest, 16)));
 }
 
 void CPDF_SecurityHandler::InitCryptoHandler() {