1 diff --git svx/inc/mscodec.hxx svx/inc/mscodec.hxx
2 index 66dcf5d..be67b46 100644
3 --- svx/inc/mscodec.hxx
4 +++ svx/inc/mscodec.hxx
5 @@ -235,6 +235,14 @@ public:
7 bool InitCipher( sal_uInt32 nCounter );
9 + /** Creates an MD5 digest of salt digest. */
10 + bool CreateSaltDigest(
11 + const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
14 + const void* pData, sal_Size nDatLen,
15 + sal_uInt8* pBuffer, sal_Size nBufLen );
17 /** Decodes a block of memory.
19 @see rtl_cipher_decode()
20 @@ -276,6 +284,9 @@ public:
21 bool Skip( sal_Size nDatLen );
24 + void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
27 SVX_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& );
28 SVX_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& );
30 diff --git svx/source/msfilter/mscodec.cxx svx/source/msfilter/mscodec.cxx
31 index 30baed5..d086754 100644
32 --- svx/source/msfilter/mscodec.cxx
33 +++ svx/source/msfilter/mscodec.cxx
36 #include <tools/solar.h>
38 +#define DEBUG_MSO_ENCRYPTION_STD97 0
40 +#if DEBUG_MSO_ENCRYPTION_STD97
47 // ============================================================================
48 @@ -241,15 +248,50 @@ MSCodec_Std97::~MSCodec_Std97 ()
49 rtl_cipher_destroy (m_hCipher);
52 +#if DEBUG_MSO_ENCRYPTION_STD97
53 +static void lcl_PrintKeyData(const sal_uInt8* pKeyData, const char* msg)
55 + printf("pKeyData: (%s)\n", msg);
56 + for (int j = 0; j < 4; ++j)
58 + for (int i = 0; i < 16; ++i)
59 + printf("%2.2x ", pKeyData[j*16+i]);
64 +static void lcl_PrintKeyData(const sal_uInt8* /*pKeyData*/, const char* /*msg*/)
69 +#if DEBUG_MSO_ENCRYPTION_STD97
70 +static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg)
72 + printf("digest: (%s)\n", msg);
73 + for (int i = 0; i < 16; ++i)
74 + printf("%2.2x ", pDigest[i]);
78 +static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
83 void MSCodec_Std97::InitKey (
84 const sal_uInt16 pPassData[16],
85 const sal_uInt8 pUnique[16])
87 +#if DEBUG_MSO_ENCRYPTION_STD97
88 + fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
90 sal_uInt8 pKeyData[64];
93 // Fill PassData into KeyData.
94 (void)memset (pKeyData, 0, sizeof(pKeyData));
95 + lcl_PrintKeyData(pKeyData, "initial");
96 for (i = 0, n = 16; (i < n) && pPassData[i]; i++)
98 pKeyData[2*i ] = sal::static_int_cast< sal_uInt8 >(
99 @@ -260,12 +302,16 @@ void MSCodec_Std97::InitKey (
100 pKeyData[2*i] = 0x80;
101 pKeyData[ 56] = sal::static_int_cast< sal_uInt8 >(i << 4);
103 + lcl_PrintKeyData(pKeyData, "password data");
105 // Fill raw digest of KeyData into KeyData.
106 (void)rtl_digest_updateMD5 (
107 m_hDigest, pKeyData, sizeof(pKeyData));
108 (void)rtl_digest_rawMD5 (
109 m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
111 + lcl_PrintKeyData(pKeyData, "raw digest of key data");
113 // Update digest with KeyData and Unique.
114 for (i = 0; i < 16; i++)
116 @@ -279,6 +325,8 @@ void MSCodec_Std97::InitKey (
120 + lcl_PrintKeyData(pKeyData, "update digest with padding");
122 rtl_digest_updateMD5 (
123 m_hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16);
125 @@ -286,6 +334,8 @@ void MSCodec_Std97::InitKey (
127 m_hDigest, m_pDigestValue, sizeof(m_pDigestValue));
129 + lcl_PrintDigest(m_pDigestValue, "digest value");
131 // Erase KeyData array and leave.
132 (void)memset (pKeyData, 0, sizeof(pKeyData));
134 @@ -294,27 +344,21 @@ bool MSCodec_Std97::VerifyKey (
135 const sal_uInt8 pSaltData[16],
136 const sal_uInt8 pSaltDigest[16])
138 + // both the salt data and salt digest (hash) come from the document being imported.
140 +#if DEBUG_MSO_ENCRYPTION_STD97
141 + fprintf(stdout, "MSCodec_Std97::VerifyKey: \n");
142 + lcl_PrintDigest(pSaltData, "salt data");
143 + lcl_PrintDigest(pSaltDigest, "salt hash");
149 sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
150 - sal_uInt8 pBuffer[64];
152 - // Decode SaltData into Buffer.
153 - rtl_cipher_decode (
154 - m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
156 - pBuffer[16] = 0x80;
157 - (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
158 - pBuffer[56] = 0x80;
160 - // Fill raw digest of Buffer into Digest.
161 - rtl_digest_updateMD5 (
162 - m_hDigest, pBuffer, sizeof(pBuffer));
163 - rtl_digest_rawMD5 (
164 - m_hDigest, pDigest, sizeof(pDigest));
165 + GetDigestFromSalt(pSaltData, pDigest);
167 + sal_uInt8 pBuffer[16];
168 // Decode original SaltDigest into Buffer.
170 m_hCipher, pSaltDigest, 16, pBuffer, sizeof(pBuffer));
171 @@ -333,7 +377,7 @@ bool MSCodec_Std97::VerifyKey (
172 bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
174 rtlCipherError result;
175 - sal_uInt8 pKeyData[64];
176 + sal_uInt8 pKeyData[64]; // 512-bit message block
178 // Initialize KeyData array.
179 (void)memset (pKeyData, 0, sizeof(pKeyData));
180 @@ -358,7 +402,7 @@ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
182 // Initialize Cipher with KeyData (for decoding).
183 result = rtl_cipher_init (
184 - m_hCipher, rtl_Cipher_DirectionDecode,
185 + m_hCipher, rtl_Cipher_DirectionBoth,
186 pKeyData, RTL_DIGEST_LENGTH_MD5, 0, 0);
188 // Erase KeyData array and leave.
189 @@ -367,6 +411,38 @@ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
190 return (result == rtl_Cipher_E_None);
193 +bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
195 +#if DEBUG_MSO_ENCRYPTION_STD97
196 + lcl_PrintDigest(pSaltData, "salt data");
198 + bool result = false;
202 + sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
203 + GetDigestFromSalt(nSaltData, pDigest);
205 + rtl_cipher_decode (
206 + m_hCipher, pDigest, 16, pDigest, sizeof(pDigest));
208 + (void)memcpy(nSaltDigest, pDigest, 16);
214 +bool MSCodec_Std97::Encode(
215 + const void *pData, sal_Size nDatLen,
216 + sal_uInt8 *pBuffer, sal_Size nBufLen)
218 + rtlCipherError result;
219 + result = rtl_cipher_encode (
220 + m_hCipher, pData, nDatLen, pBuffer, nBufLen);
222 + return (result == rtl_Cipher_E_None);
225 bool MSCodec_Std97::Decode (
226 const void *pData, sal_Size nDatLen,
227 sal_uInt8 *pBuffer, sal_Size nBufLen)
228 @@ -395,6 +471,33 @@ bool MSCodec_Std97::Skip( sal_Size nDatLen )
232 +void MSCodec_Std97::GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] )
234 + sal_uInt8 pBuffer[64];
235 + sal_uInt8 pDigestLocal[16];
237 + // Decode SaltData into Buffer.
238 + rtl_cipher_decode (
239 + m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
241 + // set the 129th bit to make the buffer 128-bit in length.
242 + pBuffer[16] = 0x80;
244 + // erase the rest of the buffer with zeros.
245 + (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
247 + // set the 441st bit.
248 + pBuffer[56] = 0x80;
250 + // Fill raw digest of Buffer into Digest.
251 + rtl_digest_updateMD5 (
252 + m_hDigest, pBuffer, sizeof(pBuffer));
253 + rtl_digest_rawMD5 (
254 + m_hDigest, pDigestLocal, sizeof(pDigestLocal));
256 + memcpy(pDigest, pDigestLocal, 16);
259 // ============================================================================