Blame SOURCES/0001-Fix-endianness-issues-in-OOX-crypto-routines.patch

0c7e3c
From 96b088a62174a70441ebe959495756e9d86203a2 Mon Sep 17 00:00:00 2001
0c7e3c
From: Stephan Bergmann <sbergman@redhat.com>
0c7e3c
Date: Thu, 24 Sep 2020 14:51:16 +0200
0c7e3c
Subject: [PATCH] Fix endianness issues in OOX crypto routines
0c7e3c
0c7e3c
...without which CppunitTest_sw_ooxmlencryption failed on (big-endian) s390x:
0c7e3c
0c7e3c
* The 32-bit segment counter in AgileEngine::de-/encrypt apparently needs to be
0c7e3c
  stored in LSB format (at least, if it is, CppunitTest_sw_ooxmlencryption
0c7e3c
  ultimately succeeded, whereas otherwise it failed).
0c7e3c
0c7e3c
* The UTF-16 string in Standard2007Engine::calculateEncryptionKey apparently
0c7e3c
  needs to be in LSB format (at least, if it is, CppunitTest_sw_ooxmlencryption
0c7e3c
  ultimately succeeded, whereas otherwise it failed).
0c7e3c
0c7e3c
* The various 32-bit values in the EncryptionStandardHeader and
0c7e3c
  EncryptionVerifierAES data structures apparently need to be written out in LSB
0c7e3c
  format in Standard2007Engine::writeEncryptionInfo, given that they are always
0c7e3c
  read in LSB format in Standard2007Engine::readEncryptionInfo.
0c7e3c
0c7e3c
Change-Id: I3a1efbfe324b1bbd539b88dc5d40bb44f9676ffa
0c7e3c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103315
0c7e3c
Tested-by: Jenkins
0c7e3c
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
0c7e3c
(cherry picked from commit 646a69757b928aeaf6e0d0d41c4b30c02803a3a3)
0c7e3c
---
0c7e3c
 oox/source/crypto/AgileEngine.cxx        | 16 +++++++++-----
0c7e3c
 oox/source/crypto/Standard2007Engine.cxx | 28 +++++++++++++++++-------
0c7e3c
 2 files changed, 30 insertions(+), 14 deletions(-)
0c7e3c
0c7e3c
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
0c7e3c
index 7c2a0e9c93d2..0fc972bf2ca5 100644
0c7e3c
--- a/oox/source/crypto/AgileEngine.cxx
0c7e3c
+++ b/oox/source/crypto/AgileEngine.cxx
0c7e3c
@@ -457,9 +457,11 @@ bool AgileEngine::decrypt(BinaryXInputStream& aInputStream,
0c7e3c
 
0c7e3c
     while ((inputLength = aInputStream.readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
0c7e3c
     {
0c7e3c
-        sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&segment);
0c7e3c
-        sal_uInt8* segmentEnd   = segmentBegin + sizeof(segment);
0c7e3c
-        std::copy(segmentBegin, segmentEnd, saltWithBlockKey.begin() + saltSize);
0c7e3c
+        auto p = saltWithBlockKey.begin() + saltSize;
0c7e3c
+        p[0] = segment & 0xFF;
0c7e3c
+        p[1] = (segment >> 8) & 0xFF;
0c7e3c
+        p[2] = (segment >> 16) & 0xFF;
0c7e3c
+        p[3] = segment >> 24;
0c7e3c
 
0c7e3c
         hashCalc(hash, saltWithBlockKey, mInfo.hashAlgorithm);
0c7e3c
 
0c7e3c
@@ -800,9 +802,11 @@ void AgileEngine::encrypt(css::uno::Reference<css::io::XInputStream> &  rxInputS
0c7e3c
                         inputLength : oox::core::roundUp(inputLength, sal_uInt32(mInfo.blockSize));
0c7e3c
 
0c7e3c
         // Update Key
0c7e3c
-        sal_uInt8* segmentBegin = reinterpret_cast<sal_uInt8*>(&nSegment);
0c7e3c
-        sal_uInt8* segmentEnd   = segmentBegin + nSegmentByteSize;
0c7e3c
-        std::copy(segmentBegin, segmentEnd, saltWithBlockKey.begin() + saltSize);
0c7e3c
+        auto p = saltWithBlockKey.begin() + saltSize;
0c7e3c
+        p[0] = nSegment & 0xFF;
0c7e3c
+        p[1] = (nSegment >> 8) & 0xFF;
0c7e3c
+        p[2] = (nSegment >> 16) & 0xFF;
0c7e3c
+        p[3] = nSegment >> 24;
0c7e3c
 
0c7e3c
         hashCalc(hash, saltWithBlockKey, mInfo.hashAlgorithm);
0c7e3c
 
0c7e3c
diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
0c7e3c
index 38c4e03baf15..e96fc8f841f2 100644
0c7e3c
--- a/oox/source/crypto/Standard2007Engine.cxx
0c7e3c
+++ b/oox/source/crypto/Standard2007Engine.cxx
0c7e3c
@@ -79,12 +79,12 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
0c7e3c
     std::vector<sal_uInt8> initialData(saltSize + passwordByteLength);
0c7e3c
     std::copy(saltArray, saltArray + saltSize, initialData.begin());
0c7e3c
 
0c7e3c
-    const sal_uInt8* passwordByteArray = reinterpret_cast<const sal_uInt8*>(rPassword.getStr());
0c7e3c
-
0c7e3c
-    std::copy(
0c7e3c
-        passwordByteArray,
0c7e3c
-        passwordByteArray + passwordByteLength,
0c7e3c
-        initialData.begin() + saltSize);
0c7e3c
+    auto p = initialData.begin() + saltSize;
0c7e3c
+    for (sal_Int32 i = 0; i != rPassword.getLength(); ++i) {
0c7e3c
+        auto c = rPassword[i];
0c7e3c
+        *p++ = c & 0xFF;
0c7e3c
+        *p++ = c >> 8;
0c7e3c
+    }
0c7e3c
 
0c7e3c
     // use "hash" vector for result of sha1 hashing
0c7e3c
     // calculate SHA1 hash of initialData
0c7e3c
@@ -223,11 +223,23 @@ void Standard2007Engine::writeEncryptionInfo(BinaryXOutputStream& rStream)
0c7e3c
     sal_uInt32 headerSize = encryptionHeaderSize + cspNameSize;
0c7e3c
     rStream.WriteUInt32(headerSize);
0c7e3c
 
0c7e3c
-    rStream.writeMemory(&mInfo.header, encryptionHeaderSize);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.flags);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.sizeExtra);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.algId);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.algIdHash);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.keyBits);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.providedType);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.reserved1);
0c7e3c
+    rStream.WriteUInt32(mInfo.header.reserved2);
0c7e3c
     rStream.writeUnicodeArray(lclCspName);
0c7e3c
     rStream.WriteUInt16(0);
0c7e3c
 
0c7e3c
-    rStream.writeMemory(&mInfo.verifier, sizeof(msfilter::EncryptionVerifierAES));
0c7e3c
+    rStream.WriteUInt32(mInfo.verifier.saltSize);
0c7e3c
+    rStream.writeMemory(&mInfo.verifier.salt, sizeof mInfo.verifier.salt);
0c7e3c
+    rStream.writeMemory(&mInfo.verifier.encryptedVerifier, sizeof mInfo.verifier.encryptedVerifier);
0c7e3c
+    rStream.WriteUInt32(mInfo.verifier.encryptedVerifierHashSize);
0c7e3c
+    rStream.writeMemory(
0c7e3c
+        &mInfo.verifier.encryptedVerifierHash, sizeof mInfo.verifier.encryptedVerifierHash);
0c7e3c
 }
0c7e3c
 
0c7e3c
 void Standard2007Engine::encrypt(css::uno::Reference<css::io::XInputStream> &  rxInputStream,
0c7e3c
-- 
0c7e3c
2.33.1
0c7e3c