LibreOffice Module filter (master) 1
mscodec.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
22#include <osl/diagnose.h>
23#include <algorithm>
24#include <string.h>
25#include <tools/solar.h>
26
27#include <comphelper/hash.hxx>
30#include <com/sun/star/beans/NamedValue.hpp>
31#include <utility>
32
33#define DEBUG_MSO_ENCRYPTION_STD97 0
34
35#if DEBUG_MSO_ENCRYPTION_STD97
36#include <stdio.h>
37#endif
38
39using namespace ::com::sun::star;
40
41namespace msfilter {
42
43
44namespace {
45
47template< typename Type >
48void lclRotateLeft( Type& rnValue, int nBits )
49{
50 OSL_ASSERT(
51 nBits >= 0 &&
52 sal::static_int_cast< unsigned int >(nBits) < sizeof( Type ) * 8 );
53 rnValue = static_cast< Type >( (rnValue << nBits) | (rnValue >> (sizeof( Type ) * 8 - nBits)) );
54}
55
57template< typename Type >
58void lclRotateLeft( Type& rnValue, sal_uInt8 nBits, sal_uInt8 nWidth )
59{
60 OSL_ASSERT( (nBits < nWidth) && (nWidth < sizeof( Type ) * 8) );
61 Type nMask = static_cast< Type >( (1UL << nWidth) - 1 );
62 rnValue = static_cast< Type >(
63 ((rnValue << nBits) | ((rnValue & nMask) >> (nWidth - nBits))) & nMask );
64}
65
66std::size_t lclGetLen( const sal_uInt8* pnPassData, std::size_t nBufferSize )
67{
68 std::size_t nLen = 0;
69 while( (nLen < nBufferSize) && pnPassData[ nLen ] ) ++nLen;
70 return nLen;
71}
72
73sal_uInt16 lclGetKey( const sal_uInt8* pnPassData, std::size_t nBufferSize )
74{
75 std::size_t nLen = lclGetLen( pnPassData, nBufferSize );
76 if( !nLen ) return 0;
77
78 sal_uInt16 nKey = 0;
79 sal_uInt16 nKeyBase = 0x8000;
80 sal_uInt16 nKeyEnd = 0xFFFF;
81 const sal_uInt8* pnChar = pnPassData + nLen - 1;
82 for( std::size_t nIndex = 0; nIndex < nLen; ++nIndex, --pnChar )
83 {
84 sal_uInt8 cChar = *pnChar & 0x7F;
85 for( sal_uInt8 nBit = 0; nBit < 8; ++nBit )
86 {
87 lclRotateLeft( nKeyBase, 1 );
88 if( nKeyBase & 1 ) nKeyBase ^= 0x1020;
89 if( cChar & 1 ) nKey ^= nKeyBase;
90 cChar >>= 1;
91 lclRotateLeft( nKeyEnd, 1 );
92 if( nKeyEnd & 1 ) nKeyEnd ^= 0x1020;
93 }
94 }
95 return nKey ^ nKeyEnd;
96}
97
98sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, std::size_t nBufferSize )
99{
100 std::size_t nLen = lclGetLen( pnPassData, nBufferSize );
101
102 sal_uInt16 nHash = static_cast< sal_uInt16 >( nLen );
103 if( nLen )
104 nHash ^= 0xCE4B;
105
106 const sal_uInt8* pnChar = pnPassData;
107 for( std::size_t nIndex = 0; nIndex < nLen; ++nIndex, ++pnChar )
108 {
109 sal_uInt16 cChar = *pnChar;
110 sal_uInt8 nRot = static_cast< sal_uInt8 >( (nIndex + 1) % 15 );
111 lclRotateLeft( cChar, nRot, 15 );
112 nHash ^= cChar;
113 }
114 return nHash;
115}
116
117
118} // namespace
119
120
121MSCodec_Xor95::MSCodec_Xor95(int nRotateDistance) :
122 mnOffset( 0 ),
123 mnKey( 0 ),
124 mnHash( 0 ),
125 mnRotateDistance( nRotateDistance )
126{
127}
128
130{
131 memset( mpnKey, 0, sizeof( mpnKey ) );
132 mnKey = mnHash = 0;
133}
134
135void MSCodec_Xor95::InitKey( const sal_uInt8 pnPassData[ 16 ] )
136{
137 mnKey = lclGetKey( pnPassData, 16 );
138 mnHash = lclGetHash( pnPassData, 16 );
139
140 memcpy( mpnKey, pnPassData, 16 );
141
142 static const sal_uInt8 spnFillChars[] =
143 {
144 0xBB, 0xFF, 0xFF, 0xBA,
145 0xFF, 0xFF, 0xB9, 0x80,
146 0x00, 0xBE, 0x0F, 0x00,
147 0xBF, 0x0F, 0x00, 0x00
148 };
149
150 std::size_t nLen = lclGetLen( pnPassData, 16 );
151 const sal_uInt8* pnFillChar = spnFillChars;
152 for (std::size_t nIndex = nLen; nIndex < sizeof(mpnKey); ++nIndex, ++pnFillChar)
153 mpnKey[ nIndex ] = *pnFillChar;
154
155 SVBT16 pnOrigKey;
156 ShortToSVBT16( mnKey, pnOrigKey );
157 sal_uInt8* pnKeyChar = mpnKey;
158 for (std::size_t nIndex = 0; nIndex < sizeof(mpnKey); ++nIndex, ++pnKeyChar)
159 {
160 *pnKeyChar ^= pnOrigKey[ nIndex & 0x01 ];
161 lclRotateLeft( *pnKeyChar, mnRotateDistance );
162 }
163}
164
165bool MSCodec_Xor95::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
166{
167 bool bResult = false;
168
170 uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault("XOR95EncryptionKey", uno::Sequence< sal_Int8 >() );
171
172 if ( aKey.getLength() == 16 )
173 {
174 memcpy( mpnKey, aKey.getConstArray(), 16 );
175 bResult = true;
176
177 mnKey = static_cast<sal_uInt16>(aHashData.getUnpackedValueOrDefault("XOR95BaseKey", sal_Int16(0) ));
178 mnHash = static_cast<sal_uInt16>(aHashData.getUnpackedValueOrDefault("XOR95PasswordHash", sal_Int16(0) ));
179 }
180 else
181 OSL_FAIL( "Unexpected key size!" );
182
183 return bResult;
184}
185
186uno::Sequence< beans::NamedValue > MSCodec_Xor95::GetEncryptionData()
187{
189 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
190 aHashData[ OUString( "XOR95EncryptionKey" ) ] <<= uno::Sequence<sal_Int8>( reinterpret_cast<sal_Int8*>(mpnKey), 16 );
191 aHashData[ OUString( "XOR95BaseKey" ) ] <<= static_cast<sal_Int16>(mnKey);
192 aHashData[ OUString( "XOR95PasswordHash" ) ] <<= static_cast<sal_Int16>(mnHash);
193
194 return aHashData.getAsConstNamedValueList();
195}
196
197bool MSCodec_Xor95::VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
198{
199 return (nKey == mnKey) && (nHash == mnHash);
200}
201
203{
204 mnOffset = 0;
205}
206
207void MSCodec_XorXLS95::Decode( sal_uInt8* pnData, std::size_t nBytes )
208{
209 const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
210 const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
211
212 for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
213 {
214 lclRotateLeft( *pnData, 3 );
215 *pnData ^= *pnCurrKey;
216 if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
217 }
218
219 // update mnOffset
220 Skip( nBytes );
221}
222
223void MSCodec_XorWord95::Decode( sal_uInt8* pnData, std::size_t nBytes )
224{
225 const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
226 const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
227
228 for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
229 {
230 const sal_uInt8 cChar = *pnData ^ *pnCurrKey;
231 if (*pnData && cChar)
232 *pnData = cChar;
233
234 if( pnCurrKey < pnKeyLast )
235 ++pnCurrKey;
236 else
237 pnCurrKey = mpnKey;
238 }
239
240 // update mnOffset
241 Skip( nBytes );
242}
243
244
245void MSCodec_Xor95::Skip( std::size_t nBytes )
246{
247 mnOffset = (mnOffset + nBytes) & 0x0F;
248}
249
250MSCodec97::MSCodec97(size_t nHashLen, OUString aEncKeyName)
251 : m_sEncKeyName(std::move(aEncKeyName))
252 , m_nHashLen(nHashLen)
253 , m_hCipher(rtl_cipher_create(rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream))
254 , m_aDocId(16, 0)
255 , m_aDigestValue(nHashLen, 0)
256{
257 assert(m_hCipher != nullptr);
258}
259
261 : MSCodec97(RTL_DIGEST_LENGTH_MD5, "STD97EncryptionKey")
262{
263 m_hDigest = rtl_digest_create(rtl_Digest_AlgorithmMD5);
264 assert(m_hDigest != nullptr);
265}
266
268 : MSCodec97(RTL_DIGEST_LENGTH_SHA1, "CryptoAPIEncryptionKey")
269{
270}
271
273{
274 memset(m_aDigestValue.data(), 0, m_aDigestValue.size());
275 memset(m_aDocId.data(), 0, m_aDocId.size());
276 rtl_cipher_destroy(m_hCipher);
277}
278
280{
281 rtl_digest_destroy(m_hDigest);
282}
283
284#if DEBUG_MSO_ENCRYPTION_STD97
285static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg)
286{
287 printf("digest: (%s)\n", msg);
288 for (int i = 0; i < 16; ++i)
289 printf("%2.2x ", pDigest[i]);
290 printf("\n");
291}
292#else
293static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
294{
295}
296#endif
297
298bool MSCodec97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
299{
300#if DEBUG_MSO_ENCRYPTION_STD97
301 fprintf(stdout, "MSCodec_Std97::InitCodec: --begin\n");fflush(stdout);
302#endif
303 bool bResult = false;
304
306 uno::Sequence<sal_Int8> aKey = aHashData.getUnpackedValueOrDefault(m_sEncKeyName, uno::Sequence<sal_Int8>());
307 const size_t nKeyLen = aKey.getLength();
308 if (nKeyLen == m_nHashLen)
309 {
310 assert(m_aDigestValue.size() == m_nHashLen);
311 memcpy(m_aDigestValue.data(), aKey.getConstArray(), m_nHashLen);
312 uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault("STD97UniqueID", uno::Sequence< sal_Int8 >() );
313 if ( aUniqueID.getLength() == 16 )
314 {
315 assert(m_aDocId.size() == static_cast<size_t>(aUniqueID.getLength()));
316 memcpy(m_aDocId.data(), aUniqueID.getConstArray(), m_aDocId.size());
317 bResult = true;
318 lcl_PrintDigest(m_aDigestValue.data(), "digest value");
319 lcl_PrintDigest(m_aDocId.data(), "DocId value");
320 }
321 else
322 OSL_FAIL( "Unexpected document ID!" );
323 }
324 else
325 OSL_FAIL( "Unexpected key size!" );
326
327 return bResult;
328}
329
330uno::Sequence< beans::NamedValue > MSCodec97::GetEncryptionData()
331{
333 assert(m_aDigestValue.size() == m_nHashLen);
334 aHashData[m_sEncKeyName] <<= uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8*>(m_aDigestValue.data()), m_nHashLen);
335 aHashData[ OUString( "STD97UniqueID" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_aDocId.data()), m_aDocId.size() );
336
337 return aHashData.getAsConstNamedValueList();
338}
339
341 const sal_uInt16 pPassData[16],
342 const sal_uInt8 pDocId[16])
343{
344#if DEBUG_MSO_ENCRYPTION_STD97
345 fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
346#endif
347 uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key(pPassData, pDocId);
348 // Fill raw digest of above updates into DigestValue.
349
350 const size_t nKeyLen = aKey.getLength();
351 if (m_aDigestValue.size() == nKeyLen)
352 memcpy(m_aDigestValue.data(), aKey.getConstArray(), m_aDigestValue.size());
353 else
354 memset(m_aDigestValue.data(), 0, m_aDigestValue.size());
355
356 lcl_PrintDigest(m_aDigestValue.data(), "digest value");
357
358 memcpy (m_aDocId.data(), pDocId, 16);
359
360 lcl_PrintDigest(m_aDocId.data(), "DocId value");
361}
362
364 const sal_uInt16 pPassData[16],
365 const sal_uInt8 pDocId[16])
366{
367 sal_uInt32 const saltSize = 16;
368
369 // Prepare initial data -> salt + password (in 16-bit chars)
370 std::vector<sal_uInt8> initialData(pDocId, pDocId + saltSize);
371
372 // Fill PassData into KeyData.
373 for (sal_Int32 nInd = 0; nInd < 16 && pPassData[nInd]; ++nInd)
374 {
375 initialData.push_back(sal::static_int_cast<sal_uInt8>((pPassData[nInd] >> 0) & 0xff));
376 initialData.push_back(sal::static_int_cast<sal_uInt8>((pPassData[nInd] >> 8) & 0xff));
377 }
378
379 // calculate SHA1 hash of initialData
380 std::vector<unsigned char> const sha1(::comphelper::Hash::calculateHash(
381 initialData.data(), initialData.size(),
382 ::comphelper::HashType::SHA1));
383 m_aDigestValue = sha1;
384
385 lcl_PrintDigest(m_aDigestValue.data(), "digest value");
386
387 memcpy(m_aDocId.data(), pDocId, 16);
388
389 lcl_PrintDigest(m_aDocId.data(), "DocId value");
390
391 //generate the old format key while we have the required data
393}
394
395bool MSCodec97::VerifyKey(const sal_uInt8* pSaltData, const sal_uInt8* pSaltDigest)
396{
397 // both the salt data and salt digest (hash) come from the document being imported.
398
399#if DEBUG_MSO_ENCRYPTION_STD97
400 fprintf(stdout, "MSCodec97::VerifyKey: \n");
401 lcl_PrintDigest(pSaltData, "salt data");
402 lcl_PrintDigest(pSaltDigest, "salt hash");
403#endif
404 bool result = false;
405
406 if (InitCipher(0))
407 {
408 std::vector<sal_uInt8> aDigest(m_nHashLen);
409 GetDigestFromSalt(pSaltData, aDigest.data());
410
411 std::vector<sal_uInt8> aBuffer(m_nHashLen);
412 // Decode original SaltDigest into Buffer.
413 rtl_cipher_decode(m_hCipher, pSaltDigest, m_nHashLen, aBuffer.data(), m_nHashLen);
414
415 // Compare Buffer with computed Digest.
416 result = (memcmp(aBuffer.data(), aDigest.data(), m_nHashLen) == 0);
417
418 // Erase Buffer and Digest arrays.
419 rtl_secureZeroMemory(aBuffer.data(), m_nHashLen);
420 rtl_secureZeroMemory(aDigest.data(), m_nHashLen);
421 }
422
423 return result;
424}
425
427{
428 std::vector<sal_uInt8> verifier(16);
429 rtl_cipher_decode(m_hCipher,
430 pSaltData, 16, verifier.data(), verifier.size());
431
432 std::vector<unsigned char> const sha1(::comphelper::Hash::calculateHash(
433 verifier.data(), verifier.size(), ::comphelper::HashType::SHA1));
434 ::std::copy(sha1.begin(), sha1.end(), pDigest);
435}
436
437bool MSCodec_Std97::InitCipher(sal_uInt32 nCounter)
438{
439 sal_uInt8 pKeyData[64] = {}; // 512-bit message block
440
441 // Fill 40 bit of DigestValue into [0..4].
442 memcpy (pKeyData, m_aDigestValue.data(), 5);
443
444 // Fill counter into [5..8].
445 pKeyData[ 5] = sal_uInt8((nCounter >> 0) & 0xff);
446 pKeyData[ 6] = sal_uInt8((nCounter >> 8) & 0xff);
447 pKeyData[ 7] = sal_uInt8((nCounter >> 16) & 0xff);
448 pKeyData[ 8] = sal_uInt8((nCounter >> 24) & 0xff);
449
450 pKeyData[ 9] = 0x80;
451 pKeyData[56] = 0x48;
452
453 // Fill raw digest of KeyData into KeyData.
454 (void)rtl_digest_updateMD5 (
455 m_hDigest, pKeyData, sizeof(pKeyData));
456 (void)rtl_digest_rawMD5 (
457 m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
458
459 // Initialize Cipher with KeyData (for decoding).
460 rtlCipherError result = rtl_cipher_init (
461 m_hCipher, rtl_Cipher_DirectionBoth,
462 pKeyData, RTL_DIGEST_LENGTH_MD5, nullptr, 0);
463
464 // Erase KeyData array and leave.
465 rtl_secureZeroMemory (pKeyData, sizeof(pKeyData));
466
467 return (result == rtl_Cipher_E_None);
468}
469
470bool MSCodec_CryptoAPI::InitCipher(sal_uInt32 nCounter)
471{
472 // data = hash + iterator (4bytes)
473 std::vector<sal_uInt8> aKeyData(m_aDigestValue);
474 aKeyData.push_back(sal_uInt8((nCounter >> 0) & 0xff));
475 aKeyData.push_back(sal_uInt8((nCounter >> 8) & 0xff));
476 aKeyData.push_back(sal_uInt8((nCounter >> 16) & 0xff));
477 aKeyData.push_back(sal_uInt8((nCounter >> 24) & 0xff));
478
479 std::vector<unsigned char> const hash(::comphelper::Hash::calculateHash(
480 aKeyData.data(), aKeyData.size(), ::comphelper::HashType::SHA1));
481
482 rtlCipherError result =
483 rtl_cipher_init(m_hCipher, rtl_Cipher_DirectionDecode,
484 hash.data(), ENCRYPT_KEY_SIZE_AES_128/8, nullptr, 0);
485
486 return (result == rtl_Cipher_E_None);
487}
488
489uno::Sequence<beans::NamedValue> MSCodec_CryptoAPI::GetEncryptionData()
490{
492 //add in the old encryption key as well as our new key so saving using the
493 //old crypto scheme can be done without reprompt for the password
494 aHashData[OUString("STD97EncryptionKey")] <<= m_aStd97Key;
495 return aHashData.getAsConstNamedValueList();
496}
497
498void MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
499{
500#if DEBUG_MSO_ENCRYPTION_STD97
501 lcl_PrintDigest(nSaltData, "salt data");
502#endif
503 if (InitCipher(0))
504 {
505 sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
506 GetDigestFromSalt(nSaltData, pDigest);
507
508 rtl_cipher_decode (
509 m_hCipher, pDigest, 16, pDigest, sizeof(pDigest));
510
511 memcpy(nSaltDigest, pDigest, 16);
512 }
513}
514
516 const void *pData, std::size_t nDatLen,
517 sal_uInt8 *pBuffer, std::size_t nBufLen)
518{
519 rtlCipherError result = rtl_cipher_encode(
520 m_hCipher, pData, nDatLen, pBuffer, nBufLen);
521
522 return (result == rtl_Cipher_E_None);
523}
524
526 const void *pData, std::size_t nDatLen,
527 sal_uInt8 *pBuffer, std::size_t nBufLen)
528{
529 rtlCipherError result = rtl_cipher_decode(
530 m_hCipher, pData, nDatLen, pBuffer, nBufLen);
531
532 return (result == rtl_Cipher_E_None);
533}
534
535bool MSCodec97::Skip(std::size_t nDatLen)
536{
537 sal_uInt8 pnDummy[ 1024 ];
538 std::size_t nDatLeft = nDatLen;
539 bool bResult = true;
540
541 while (bResult && nDatLeft)
542 {
543 std::size_t nBlockLen = ::std::min< std::size_t >( nDatLeft, sizeof(pnDummy) );
544 bResult = Decode( pnDummy, nBlockLen, pnDummy, nBlockLen );
545 nDatLeft -= nBlockLen;
546 }
547
548 return bResult;
549}
550
552{
553 sal_uInt8 pBuffer[64];
554 sal_uInt8 pDigestLocal[16];
555
556 // Decode SaltData into Buffer.
557 rtl_cipher_decode (
558 m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
559
560 // set the 129th bit to make the buffer 128-bit in length.
561 pBuffer[16] = 0x80;
562
563 // erase the rest of the buffer with zeros.
564 memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
565
566 // set the 441st bit.
567 pBuffer[56] = 0x80;
568
569 // Fill raw digest of Buffer into Digest.
570 rtl_digest_updateMD5 (
571 m_hDigest, pBuffer, sizeof(pBuffer));
572 rtl_digest_rawMD5 (
573 m_hDigest, pDigestLocal, sizeof(pDigestLocal));
574
575 memcpy(pDigest, pDigestLocal, 16);
576}
577
579 const sal_uInt8 pSalt[16],
580 sal_uInt8 pSaltData[16],
581 sal_uInt8 pSaltDigest[16])
582{
583 if (!InitCipher(0))
584 return;
585
586 sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
587 sal_uInt8 pBuffer[64];
588
589 rtl_cipher_encode (
590 m_hCipher, pSalt, 16, pSaltData, sizeof(pBuffer));
591
592 memcpy( pBuffer, pSalt, 16 );
593
594 pBuffer[16] = 0x80;
595 memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
596 pBuffer[56] = 0x80;
597
598 rtl_digest_updateMD5 (
599 m_hDigest, pBuffer, sizeof(pBuffer));
600 rtl_digest_rawMD5 (
601 m_hDigest, pDigest, sizeof(pDigest));
602
603 rtl_cipher_encode (
604 m_hCipher, pDigest, 16, pSaltDigest, 16);
605
606 rtl_secureZeroMemory (pBuffer, sizeof(pBuffer));
607 rtl_secureZeroMemory (pDigest, sizeof(pDigest));
608}
609
611{
612 assert(m_aDocId.size() == 16);
613 memcpy(pDocId, m_aDocId.data(), 16);
614}
615
617{
618 flags = 0;
619 sizeExtra = 0;
620 algId = 0;
621 algIdHash = 0;
622 keyBits = 0;
623 providedType = 0;
624 reserved1 = 0;
625 reserved2 = 0;
626}
627
629 : saltSize(SALT_LENGTH)
630 , encryptedVerifierHashSize(comphelper::SHA1_HASH_LENGTH)
631{
632}
633
635 : saltSize(SALT_LENGTH)
636 , encryptedVerifierHashSize(comphelper::SHA1_HASH_LENGTH)
637{
638}
639
640}
641
642/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static css::uno::Sequence< sal_Int8 > GenerateStd97Key(std::u16string_view aPassword, const css::uno::Sequence< sal_Int8 > &aDocId)
static std::vector< unsigned char > calculateHash(const unsigned char *pInput, size_t length, HashType eType)
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
css::uno::Sequence< css::beans::NamedValue > getAsConstNamedValueList() const
bool Skip(std::size_t nDatLen)
Lets the cipher skip a specific amount of bytes.
Definition: mscodec.cxx:535
bool Encode(const void *pData, std::size_t nDatLen, sal_uInt8 *pBuffer, std::size_t nBufLen)
Encodes a block of memory.
Definition: mscodec.cxx:515
std::vector< sal_uInt8 > m_aDigestValue
Definition: mscodec.hxx:325
bool VerifyKey(const sal_uInt8 *pSaltData, const sal_uInt8 *pSaltDigest)
Verifies the validity of the password using the passed salt data.
Definition: mscodec.cxx:395
virtual bool InitCipher(sal_uInt32 nCounter)=0
Rekeys the codec using the specified counter.
MSCodec97(size_t nHashLen, OUString aEncKeyName)
Definition: mscodec.cxx:250
void GetDocId(sal_uInt8 pDocId[16])
Definition: mscodec.cxx:610
virtual ~MSCodec97()
Definition: mscodec.cxx:272
virtual void GetDigestFromSalt(const sal_uInt8 *pSaltData, sal_uInt8 *pDigest)=0
virtual css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
Retrieves the encryption data.
Definition: mscodec.cxx:330
rtlCipher m_hCipher
Definition: mscodec.hxx:323
bool Decode(const void *pData, std::size_t nDatLen, sal_uInt8 *pBuffer, std::size_t nBufLen)
Decodes a block of memory.
Definition: mscodec.cxx:525
std::vector< sal_uInt8 > m_aDocId
Definition: mscodec.hxx:324
OUString m_sEncKeyName
Definition: mscodec.hxx:321
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
Initializes the algorithm with the encryption data.
Definition: mscodec.cxx:298
css::uno::Sequence< sal_Int8 > m_aStd97Key
Definition: mscodec.hxx:402
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16]) override
Initializes the algorithm with the specified password and document ID.
Definition: mscodec.cxx:363
virtual bool InitCipher(sal_uInt32 nCounter) override
Rekeys the codec using the specified counter.
Definition: mscodec.cxx:470
virtual void GetDigestFromSalt(const sal_uInt8 *pSaltData, sal_uInt8 *pDigest) override
Definition: mscodec.cxx:426
virtual css::uno::Sequence< css::beans::NamedValue > GetEncryptionData() override
Retrieves the encryption data.
Definition: mscodec.cxx:489
virtual ~MSCodec_Std97() override
Definition: mscodec.cxx:279
void CreateSaltDigest(const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16])
Creates an MD5 digest of salt digest.
Definition: mscodec.cxx:498
virtual bool InitCipher(sal_uInt32 nCounter) override
Rekeys the codec using the specified counter.
Definition: mscodec.cxx:437
void GetEncryptKey(const sal_uInt8 pSalt[16], sal_uInt8 pSaltData[16], sal_uInt8 pSaltDigest[16])
Gets salt data and salt digest.
Definition: mscodec.cxx:578
virtual void GetDigestFromSalt(const sal_uInt8 *pSaltData, sal_uInt8 *pDigest) override
Definition: mscodec.cxx:551
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16]) override
Initializes the algorithm with the specified password and document ID.
Definition: mscodec.cxx:340
std::size_t mnOffset
Encryption key.
Definition: mscodec.hxx:126
sal_uInt8 mpnKey[16]
Definition: mscodec.hxx:125
css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
Retrieves the encryption data.
Definition: mscodec.cxx:186
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
Initializes the algorithm with the encryption data.
Definition: mscodec.cxx:165
virtual ~MSCodec_Xor95()
Definition: mscodec.cxx:129
MSCodec_Xor95(int nRotateDistance)
Definition: mscodec.cxx:121
void InitCipher()
Reinitializes the codec to start a new memory block.
Definition: mscodec.cxx:202
void Skip(std::size_t nBytes)
Lets the cipher skip a specific amount of bytes.
Definition: mscodec.cxx:245
int mnRotateDistance
Hash value from password.
Definition: mscodec.hxx:134
sal_uInt16 mnHash
Base key from password.
Definition: mscodec.hxx:133
bool VerifyKey(sal_uInt16 nKey, sal_uInt16 nHash) const
Verifies the validity of the password using the passed key and hash.
Definition: mscodec.cxx:197
void InitKey(const sal_uInt8 pnPassData[16])
Initializes the algorithm with the specified password.
Definition: mscodec.cxx:135
virtual void Decode(sal_uInt8 *pnData, std::size_t nBytes) override
Decodes a block of memory inplace.
Definition: mscodec.cxx:223
virtual void Decode(sal_uInt8 *pnData, std::size_t nBytes) override
Decodes a block of memory inplace.
Definition: mscodec.cxx:207
sal_Int32 nIndex
sal_Int16 nBit
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
Shape IDs per cluster in DGG atom.
const sal_uInt32 SHA1_HASH_LENGTH
Type
int i
Definition: gentoken.py:48
const sal_uInt32 ENCRYPT_KEY_SIZE_AES_128
Definition: mscodec.hxx:425
static void lcl_PrintDigest(const sal_uInt8 *, const char *)
Definition: mscodec.cxx:293
const sal_uInt32 SALT_LENGTH
Definition: mscodec.hxx:444
sal_uInt8 SVBT16[2]
unsigned char sal_uInt8
signed char sal_Int8
Any result
std::unique_ptr< char[]> aBuffer