Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "filter/msfilter/mscodec.hxx"
30 : :
31 : : #include <osl/diagnose.h>
32 : : #include <algorithm>
33 : : #include <string.h>
34 : : #include <tools/solar.h>
35 : :
36 : : #include <comphelper/sequenceashashmap.hxx>
37 : : #include <comphelper/docpasswordhelper.hxx>
38 : :
39 : : #define DEBUG_MSO_ENCRYPTION_STD97 0
40 : :
41 : : #if DEBUG_MSO_ENCRYPTION_STD97
42 : : #include <stdio.h>
43 : : #endif
44 : :
45 : : using namespace ::com::sun::star;
46 : :
47 : : namespace msfilter {
48 : :
49 : : // ============================================================================
50 : :
51 : : namespace {
52 : :
53 : : /** Rotates rnValue left by nBits bits. */
54 : : template< typename Type >
55 : 0 : inline void lclRotateLeft( Type& rnValue, int nBits )
56 : : {
57 : : OSL_ASSERT(
58 : : nBits >= 0 &&
59 : : sal::static_int_cast< unsigned int >(nBits) < sizeof( Type ) * 8 );
60 : 0 : rnValue = static_cast< Type >( (rnValue << nBits) | (rnValue >> (sizeof( Type ) * 8 - nBits)) );
61 : 0 : }
62 : :
63 : : /** Rotates the lower nWidth bits of rnValue left by nBits bits. */
64 : : template< typename Type >
65 : 0 : inline void lclRotateLeft( Type& rnValue, sal_uInt8 nBits, sal_uInt8 nWidth )
66 : : {
67 : : OSL_ASSERT( (nBits < nWidth) && (nWidth < sizeof( Type ) * 8) );
68 : 0 : Type nMask = static_cast< Type >( (1UL << nWidth) - 1 );
69 : 0 : rnValue = static_cast< Type >(
70 : : ((rnValue << nBits) | ((rnValue & nMask) >> (nWidth - nBits))) & nMask );
71 : 0 : }
72 : :
73 : 0 : sal_Size lclGetLen( const sal_uInt8* pnPassData, sal_Size nBufferSize )
74 : : {
75 : 0 : sal_Size nLen = 0;
76 [ # # ][ # # ]: 0 : while( (nLen < nBufferSize) && pnPassData[ nLen ] ) ++nLen;
[ # # ]
77 : 0 : return nLen;
78 : : }
79 : :
80 : 0 : sal_uInt16 lclGetKey( const sal_uInt8* pnPassData, sal_Size nBufferSize )
81 : : {
82 : 0 : sal_Size nLen = lclGetLen( pnPassData, nBufferSize );
83 [ # # ]: 0 : if( !nLen ) return 0;
84 : :
85 : 0 : sal_uInt16 nKey = 0;
86 : 0 : sal_uInt16 nKeyBase = 0x8000;
87 : 0 : sal_uInt16 nKeyEnd = 0xFFFF;
88 : 0 : const sal_uInt8* pnChar = pnPassData + nLen - 1;
89 [ # # ]: 0 : for( sal_Size nIndex = 0; nIndex < nLen; ++nIndex, --pnChar )
90 : : {
91 : 0 : sal_uInt8 cChar = *pnChar & 0x7F;
92 [ # # ]: 0 : for( sal_uInt8 nBit = 0; nBit < 8; ++nBit )
93 : : {
94 : 0 : lclRotateLeft( nKeyBase, 1 );
95 [ # # ]: 0 : if( nKeyBase & 1 ) nKeyBase ^= 0x1020;
96 [ # # ]: 0 : if( cChar & 1 ) nKey ^= nKeyBase;
97 : 0 : cChar >>= 1;
98 : 0 : lclRotateLeft( nKeyEnd, 1 );
99 [ # # ]: 0 : if( nKeyEnd & 1 ) nKeyEnd ^= 0x1020;
100 : : }
101 : : }
102 : 0 : return nKey ^ nKeyEnd;
103 : : }
104 : :
105 : 0 : sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, sal_Size nBufferSize )
106 : : {
107 : 0 : sal_Size nLen = lclGetLen( pnPassData, nBufferSize );
108 : :
109 : 0 : sal_uInt16 nHash = static_cast< sal_uInt16 >( nLen );
110 [ # # ]: 0 : if( nLen )
111 : 0 : nHash ^= 0xCE4B;
112 : :
113 : 0 : const sal_uInt8* pnChar = pnPassData;
114 [ # # ]: 0 : for( sal_Size nIndex = 0; nIndex < nLen; ++nIndex, ++pnChar )
115 : : {
116 : 0 : sal_uInt16 cChar = *pnChar;
117 : 0 : sal_uInt8 nRot = static_cast< sal_uInt8 >( (nIndex + 1) % 15 );
118 : 0 : lclRotateLeft( cChar, nRot, 15 );
119 : 0 : nHash ^= cChar;
120 : : }
121 : 0 : return nHash;
122 : : }
123 : :
124 : :
125 : : } // namespace
126 : :
127 : : // ============================================================================
128 : :
129 : 0 : MSCodec_Xor95::MSCodec_Xor95(int nRotateDistance) :
130 : : mnOffset( 0 ),
131 : : mnKey( 0 ),
132 : : mnHash( 0 ),
133 : 0 : mnRotateDistance( nRotateDistance )
134 : : {
135 : 0 : (void)memset( mpnKey, 0, sizeof( mpnKey ) );
136 : 0 : }
137 : :
138 : 0 : MSCodec_Xor95::~MSCodec_Xor95()
139 : : {
140 : 0 : (void)memset( mpnKey, 0, sizeof( mpnKey ) );
141 : 0 : mnKey = mnHash = 0;
142 [ # # ]: 0 : }
143 : :
144 : 0 : void MSCodec_Xor95::InitKey( const sal_uInt8 pnPassData[ 16 ] )
145 : : {
146 [ # # ]: 0 : mnKey = lclGetKey( pnPassData, 16 );
147 [ # # ]: 0 : mnHash = lclGetHash( pnPassData, 16 );
148 : :
149 : 0 : (void)memcpy( mpnKey, pnPassData, 16 );
150 : :
151 : : static const sal_uInt8 spnFillChars[] =
152 : : {
153 : : 0xBB, 0xFF, 0xFF, 0xBA,
154 : : 0xFF, 0xFF, 0xB9, 0x80,
155 : : 0x00, 0xBE, 0x0F, 0x00,
156 : : 0xBF, 0x0F, 0x00
157 : : };
158 : :
159 : : sal_Size nIndex;
160 : 0 : sal_Size nLen = lclGetLen( pnPassData, 16 );
161 : 0 : const sal_uInt8* pnFillChar = spnFillChars;
162 [ # # ]: 0 : for( nIndex = nLen; nIndex < sizeof( mpnKey ); ++nIndex, ++pnFillChar )
163 : 0 : mpnKey[ nIndex ] = *pnFillChar;
164 : :
165 : : SVBT16 pnOrigKey;
166 : 0 : ShortToSVBT16( mnKey, pnOrigKey );
167 : 0 : sal_uInt8* pnKeyChar = mpnKey;
168 [ # # ]: 0 : for( nIndex = 0; nIndex < sizeof( mpnKey ); ++nIndex, ++pnKeyChar )
169 : : {
170 : 0 : *pnKeyChar ^= pnOrigKey[ nIndex & 0x01 ];
171 : 0 : lclRotateLeft( *pnKeyChar, mnRotateDistance );
172 : : }
173 : 0 : }
174 : :
175 : 0 : sal_Bool MSCodec_Xor95::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
176 : : {
177 : 0 : sal_Bool bResult = sal_False;
178 : :
179 [ # # ]: 0 : ::comphelper::SequenceAsHashMap aHashData( aData );
180 [ # # ][ # # ]: 0 : uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
[ # # ][ # # ]
181 : :
182 [ # # ]: 0 : if ( aKey.getLength() == 16 )
183 : : {
184 : 0 : (void)memcpy( mpnKey, aKey.getConstArray(), 16 );
185 : 0 : bResult = sal_True;
186 : :
187 [ # # ][ # # ]: 0 : mnKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 );
188 [ # # ][ # # ]: 0 : mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 );
189 : : }
190 : : else
191 : : OSL_FAIL( "Unexpected key size!\n" );
192 : :
193 [ # # ][ # # ]: 0 : return bResult;
194 : : }
195 : :
196 : 0 : uno::Sequence< beans::NamedValue > MSCodec_Xor95::GetEncryptionData()
197 : : {
198 [ # # ]: 0 : ::comphelper::SequenceAsHashMap aHashData;
199 [ # # ][ # # ]: 0 : aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 );
[ # # ][ # # ]
[ # # ]
200 [ # # ][ # # ]: 0 : aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnKey;
[ # # ]
201 [ # # ][ # # ]: 0 : aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash;
[ # # ]
202 : :
203 [ # # ][ # # ]: 0 : return aHashData.getAsConstNamedValueList();
204 : : }
205 : :
206 : 0 : bool MSCodec_Xor95::VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
207 : : {
208 [ # # ][ # # ]: 0 : return (nKey == mnKey) && (nHash == mnHash);
209 : : }
210 : :
211 : 0 : void MSCodec_Xor95::InitCipher()
212 : : {
213 : 0 : mnOffset = 0;
214 : 0 : }
215 : :
216 : 0 : void MSCodec_XorXLS95::Decode( sal_uInt8* pnData, sal_Size nBytes )
217 : : {
218 : 0 : const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
219 : 0 : const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
220 : :
221 [ # # ]: 0 : for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
222 : : {
223 : 0 : lclRotateLeft( *pnData, 3 );
224 : 0 : *pnData ^= *pnCurrKey;
225 [ # # ]: 0 : if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
226 : : }
227 : :
228 : : // update mnOffset
229 : 0 : Skip( nBytes );
230 : 0 : }
231 : :
232 : 0 : void MSCodec_XorWord95::Decode( sal_uInt8* pnData, sal_Size nBytes )
233 : : {
234 : 0 : const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
235 : 0 : const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
236 : :
237 [ # # ]: 0 : for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
238 : : {
239 : 0 : const sal_uInt8 cChar = *pnData ^ *pnCurrKey;
240 [ # # ][ # # ]: 0 : if (*pnData && cChar)
241 : 0 : *pnData = cChar;
242 [ # # ]: 0 : if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
243 : : }
244 : :
245 : : // update mnOffset
246 : 0 : Skip( nBytes );
247 : 0 : }
248 : :
249 : :
250 : 0 : void MSCodec_Xor95::Skip( sal_Size nBytes )
251 : : {
252 : 0 : mnOffset = (mnOffset + nBytes) & 0x0F;
253 : 0 : }
254 : :
255 : : // ============================================================================
256 : :
257 : 9 : MSCodec_Std97::MSCodec_Std97 ()
258 : : {
259 : : m_hCipher = rtl_cipher_create (
260 : 9 : rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream);
261 : : OSL_ASSERT(m_hCipher != 0);
262 : :
263 : : m_hDigest = rtl_digest_create (
264 : 9 : rtl_Digest_AlgorithmMD5);
265 : : OSL_ASSERT(m_hDigest != 0);
266 : :
267 : 9 : (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
268 : 9 : (void)memset (m_pDocId, 0, sizeof(m_pDocId));
269 : 9 : }
270 : :
271 : 9 : MSCodec_Std97::~MSCodec_Std97 ()
272 : : {
273 : 9 : (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
274 : 9 : (void)memset (m_pDocId, 0, sizeof(m_pDocId));
275 : 9 : rtl_digest_destroy (m_hDigest);
276 : 9 : rtl_cipher_destroy (m_hCipher);
277 : 9 : }
278 : :
279 : : #if DEBUG_MSO_ENCRYPTION_STD97
280 : : static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg)
281 : : {
282 : : printf("digest: (%s)\n", msg);
283 : : for (int i = 0; i < 16; ++i)
284 : : printf("%2.2x ", pDigest[i]);
285 : : printf("\n");
286 : : }
287 : : #else
288 : 0 : static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
289 : : {
290 : 0 : }
291 : : #endif
292 : :
293 : 0 : sal_Bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
294 : : {
295 : : #if DEBUG_MSO_ENCRYPTION_STD97
296 : : fprintf(stdout, "MSCodec_Std97::InitCodec: --begin\n");fflush(stdout);
297 : : #endif
298 : 0 : sal_Bool bResult = sal_False;
299 : :
300 [ # # ]: 0 : ::comphelper::SequenceAsHashMap aHashData( aData );
301 [ # # ][ # # ]: 0 : uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
[ # # ][ # # ]
302 : :
303 [ # # ]: 0 : if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 )
304 : : {
305 : 0 : (void)memcpy( m_pDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 );
306 [ # # ][ # # ]: 0 : uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() );
[ # # ][ # # ]
307 [ # # ]: 0 : if ( aUniqueID.getLength() == 16 )
308 : : {
309 : 0 : (void)memcpy( m_pDocId, aUniqueID.getConstArray(), 16 );
310 : 0 : bResult = sal_True;
311 : 0 : lcl_PrintDigest(m_pDigestValue, "digest value");
312 : 0 : lcl_PrintDigest(m_pDocId, "DocId value");
313 : : }
314 : : else
315 [ # # ]: 0 : OSL_FAIL( "Unexpected document ID!\n" );
316 : : }
317 : : else
318 : : OSL_FAIL( "Unexpected key size!\n" );
319 : :
320 [ # # ][ # # ]: 0 : return bResult;
321 : : }
322 : :
323 : 0 : uno::Sequence< beans::NamedValue > MSCodec_Std97::GetEncryptionData()
324 : : {
325 [ # # ]: 0 : ::comphelper::SequenceAsHashMap aHashData;
326 [ # # ][ # # ]: 0 : aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDigestValue, RTL_DIGEST_LENGTH_MD5 );
[ # # ][ # # ]
[ # # ]
327 [ # # ][ # # ]: 0 : aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDocId, 16 );
[ # # ][ # # ]
[ # # ]
328 : :
329 [ # # ][ # # ]: 0 : return aHashData.getAsConstNamedValueList();
330 : : }
331 : :
332 : 0 : void MSCodec_Std97::InitKey (
333 : : const sal_uInt16 pPassData[16],
334 : : const sal_uInt8 pDocId[16])
335 : : {
336 : : #if DEBUG_MSO_ENCRYPTION_STD97
337 : : fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
338 : : #endif
339 [ # # ][ # # ]: 0 : uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pDocId, 16 ) );
[ # # ]
340 : : // Fill raw digest of above updates into DigestValue.
341 : :
342 [ # # ]: 0 : if ( aKey.getLength() == sizeof(m_pDigestValue) )
343 : 0 : (void)memcpy ( m_pDigestValue, aKey.getConstArray(), sizeof(m_pDigestValue) );
344 : : else
345 : 0 : memset( m_pDigestValue, 0, sizeof(m_pDigestValue) );
346 : :
347 : 0 : lcl_PrintDigest(m_pDigestValue, "digest value");
348 : :
349 : 0 : (void)memcpy (m_pDocId, pDocId, 16);
350 : :
351 [ # # ]: 0 : lcl_PrintDigest(m_pDocId, "DocId value");
352 : 0 : }
353 : :
354 : 0 : bool MSCodec_Std97::VerifyKey (
355 : : const sal_uInt8 pSaltData[16],
356 : : const sal_uInt8 pSaltDigest[16])
357 : : {
358 : : // both the salt data and salt digest (hash) come from the document being imported.
359 : :
360 : : #if DEBUG_MSO_ENCRYPTION_STD97
361 : : fprintf(stdout, "MSCodec_Std97::VerifyKey: \n");
362 : : lcl_PrintDigest(pSaltData, "salt data");
363 : : lcl_PrintDigest(pSaltDigest, "salt hash");
364 : : #endif
365 : 0 : bool result = false;
366 : :
367 [ # # ]: 0 : if (InitCipher(0))
368 : : {
369 : : sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
370 [ # # ]: 0 : GetDigestFromSalt(pSaltData, pDigest);
371 : :
372 : : sal_uInt8 pBuffer[16];
373 : : // Decode original SaltDigest into Buffer.
374 : : rtl_cipher_decode (
375 : 0 : m_hCipher, pSaltDigest, 16, pBuffer, sizeof(pBuffer));
376 : :
377 : : // Compare Buffer with computed Digest.
378 : 0 : result = (memcmp (pBuffer, pDigest, sizeof(pDigest)) == 0);
379 : :
380 : : // Erase Buffer and Digest arrays.
381 : 0 : (void)memset (pBuffer, 0, sizeof(pBuffer));
382 : 0 : (void)memset (pDigest, 0, sizeof(pDigest));
383 : : }
384 : :
385 : 0 : return (result);
386 : : }
387 : :
388 : 0 : bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
389 : : {
390 : : rtlCipherError result;
391 : : sal_uInt8 pKeyData[64]; // 512-bit message block
392 : :
393 : : // Initialize KeyData array.
394 : 0 : (void)memset (pKeyData, 0, sizeof(pKeyData));
395 : :
396 : : // Fill 40 bit of DigestValue into [0..4].
397 : 0 : (void)memcpy (pKeyData, m_pDigestValue, 5);
398 : :
399 : : // Fill counter into [5..8].
400 : 0 : pKeyData[ 5] = sal_uInt8((nCounter >> 0) & 0xff);
401 : 0 : pKeyData[ 6] = sal_uInt8((nCounter >> 8) & 0xff);
402 : 0 : pKeyData[ 7] = sal_uInt8((nCounter >> 16) & 0xff);
403 : 0 : pKeyData[ 8] = sal_uInt8((nCounter >> 24) & 0xff);
404 : :
405 : 0 : pKeyData[ 9] = 0x80;
406 : 0 : pKeyData[56] = 0x48;
407 : :
408 : : // Fill raw digest of KeyData into KeyData.
409 : : (void)rtl_digest_updateMD5 (
410 : 0 : m_hDigest, pKeyData, sizeof(pKeyData));
411 : : (void)rtl_digest_rawMD5 (
412 : 0 : m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
413 : :
414 : : // Initialize Cipher with KeyData (for decoding).
415 : : result = rtl_cipher_init (
416 : : m_hCipher, rtl_Cipher_DirectionBoth,
417 : 0 : pKeyData, RTL_DIGEST_LENGTH_MD5, 0, 0);
418 : :
419 : : // Erase KeyData array and leave.
420 : 0 : (void)memset (pKeyData, 0, sizeof(pKeyData));
421 : :
422 : 0 : return (result == rtl_Cipher_E_None);
423 : : }
424 : :
425 : 0 : bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
426 : : {
427 : : #if DEBUG_MSO_ENCRYPTION_STD97
428 : : lcl_PrintDigest(nSaltData, "salt data");
429 : : #endif
430 : 0 : bool result = false;
431 : :
432 [ # # ]: 0 : if (InitCipher(0))
433 : : {
434 : : sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
435 [ # # ]: 0 : GetDigestFromSalt(nSaltData, pDigest);
436 : :
437 : : rtl_cipher_decode (
438 : 0 : m_hCipher, pDigest, 16, pDigest, sizeof(pDigest));
439 : :
440 : 0 : (void)memcpy(nSaltDigest, pDigest, 16);
441 : : }
442 : :
443 : 0 : return (result);
444 : : }
445 : :
446 : 0 : bool MSCodec_Std97::Encode (
447 : : const void *pData, sal_Size nDatLen,
448 : : sal_uInt8 *pBuffer, sal_Size nBufLen)
449 : : {
450 : : rtlCipherError result;
451 : :
452 : : result = rtl_cipher_encode (
453 : 0 : m_hCipher, pData, nDatLen, pBuffer, nBufLen);
454 : :
455 : 0 : return (result == rtl_Cipher_E_None);
456 : : }
457 : :
458 : 0 : bool MSCodec_Std97::Decode (
459 : : const void *pData, sal_Size nDatLen,
460 : : sal_uInt8 *pBuffer, sal_Size nBufLen)
461 : : {
462 : : rtlCipherError result;
463 : :
464 : : result = rtl_cipher_decode (
465 : 0 : m_hCipher, pData, nDatLen, pBuffer, nBufLen);
466 : :
467 : 0 : return (result == rtl_Cipher_E_None);
468 : : }
469 : :
470 : 0 : bool MSCodec_Std97::Skip( sal_Size nDatLen )
471 : : {
472 : : sal_uInt8 pnDummy[ 1024 ];
473 : 0 : sal_Size nDatLeft = nDatLen;
474 : 0 : bool bResult = true;
475 : :
476 [ # # ][ # # ]: 0 : while (bResult && nDatLeft)
[ # # ]
477 : : {
478 [ # # ]: 0 : sal_Size nBlockLen = ::std::min< sal_Size >( nDatLeft, sizeof(pnDummy) );
479 [ # # ]: 0 : bResult = Decode( pnDummy, nBlockLen, pnDummy, nBlockLen );
480 : 0 : nDatLeft -= nBlockLen;
481 : : }
482 : :
483 : 0 : return bResult;
484 : : }
485 : :
486 : 0 : void MSCodec_Std97::GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] )
487 : : {
488 : : sal_uInt8 pBuffer[64];
489 : : sal_uInt8 pDigestLocal[16];
490 : :
491 : : // Decode SaltData into Buffer.
492 : : rtl_cipher_decode (
493 : 0 : m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
494 : :
495 : : // set the 129th bit to make the buffer 128-bit in length.
496 : 0 : pBuffer[16] = 0x80;
497 : :
498 : : // erase the rest of the buffer with zeros.
499 : 0 : (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
500 : :
501 : : // set the 441st bit.
502 : 0 : pBuffer[56] = 0x80;
503 : :
504 : : // Fill raw digest of Buffer into Digest.
505 : : rtl_digest_updateMD5 (
506 : 0 : m_hDigest, pBuffer, sizeof(pBuffer));
507 : : rtl_digest_rawMD5 (
508 : 0 : m_hDigest, pDigestLocal, sizeof(pDigestLocal));
509 : :
510 : 0 : memcpy(pDigest, pDigestLocal, 16);
511 : 0 : }
512 : :
513 : 0 : void MSCodec_Std97::GetEncryptKey (
514 : : const sal_uInt8 pSalt[16],
515 : : sal_uInt8 pSaltData[16],
516 : : sal_uInt8 pSaltDigest[16])
517 : : {
518 [ # # ]: 0 : if (InitCipher(0))
519 : : {
520 : : sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
521 : : sal_uInt8 pBuffer[64];
522 : :
523 : : rtl_cipher_encode (
524 : 0 : m_hCipher, pSalt, 16, pSaltData, sizeof(pBuffer));
525 : :
526 : 0 : (void)memcpy( pBuffer, pSalt, 16 );
527 : :
528 : 0 : pBuffer[16] = 0x80;
529 : 0 : (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
530 : 0 : pBuffer[56] = 0x80;
531 : :
532 : : rtl_digest_updateMD5 (
533 : 0 : m_hDigest, pBuffer, sizeof(pBuffer));
534 : : rtl_digest_rawMD5 (
535 : 0 : m_hDigest, pDigest, sizeof(pDigest));
536 : :
537 : : rtl_cipher_encode (
538 : 0 : m_hCipher, pDigest, 16, pSaltDigest, 16);
539 : :
540 : 0 : (void)memset (pBuffer, 0, sizeof(pBuffer));
541 : 0 : (void)memset (pDigest, 0, sizeof(pDigest));
542 : : }
543 : 0 : }
544 : :
545 : 0 : void MSCodec_Std97::GetDocId( sal_uInt8 pDocId[16] )
546 : : {
547 : : if ( sizeof( m_pDocId ) == 16 )
548 : 0 : (void)memcpy( pDocId, m_pDocId, 16 );
549 : 0 : }
550 : :
551 : : // ============================================================================
552 : :
553 : : } // namespace svx
554 : :
555 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|