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() {