tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / include / filter / msfilter / mscodec.hxx
blob90c39a8cc6b505dc9be363cd8d8f4c31e2ac617a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_FILTER_MSFILTER_MSCODEC_HXX
21 #define INCLUDED_FILTER_MSFILTER_MSCODEC_HXX
23 #include <com/sun/star/uno/Sequence.hxx>
24 #include <filter/msfilter/msfilterdllapi.h>
25 #include <rtl/cipher.h>
26 #include <rtl/digest.h>
27 #include <sal/types.h>
28 #include <comphelper/hash.hxx>
29 #include <vector>
31 namespace com::sun::star {
32 namespace beans { struct NamedValue; }
35 namespace msfilter {
38 /** Encodes and decodes data from protected MSO 95- documents.
40 class MSFILTER_DLLPUBLIC MSCodec_Xor95
42 public:
43 explicit MSCodec_Xor95(int nRotateDistance);
44 virtual ~MSCodec_Xor95();
46 /** Initializes the algorithm with the specified password.
48 @param pPassData
49 Character array containing the password. Must be zero terminated,
50 which results in a maximum length of 15 characters.
52 void InitKey( const sal_uInt8 pnPassData[ 16 ] );
54 /** Initializes the algorithm with the encryption data.
56 @param aData
57 The sequence contains the necessary data to initialize
58 the codec.
60 bool InitCodec( const css::uno::Sequence< css::beans::NamedValue >& aData );
62 /** Retrieves the encryption data
64 @return
65 The sequence contains the necessary data to initialize
66 the codec.
68 css::uno::Sequence< css::beans::NamedValue > GetEncryptionData();
71 /** Verifies the validity of the password using the passed key and hash.
73 @precond
74 The codec must be initialized with InitKey() before this function
75 can be used.
77 @param nKey
78 Password key value read from the file.
79 @param nHash
80 Password hash value read from the file.
82 @return
83 true = Test was successful.
85 bool VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;
87 /** Reinitializes the codec to start a new memory block.
89 Resets the internal key offset to 0.
91 @precond
92 The codec must be initialized with InitKey() before this function
93 can be used.
95 void InitCipher();
97 /** Decodes a block of memory inplace.
99 @precond
100 The codec must be initialized with InitKey() before this function
101 can be used.
103 @param pnData
104 Encrypted data block. Will contain the decrypted data afterwards.
105 @param nBytes
106 Size of the passed data block.
108 virtual void Decode( sal_uInt8* pnData, std::size_t nBytes )=0;
110 /** Lets the cipher skip a specific amount of bytes.
112 This function sets the cipher to the same state as if the specified
113 amount of data has been decoded with one or more calls of Decode().
115 @precond
116 The codec must be initialized with InitKey() before this function
117 can be used.
119 @param nBytes
120 Number of bytes to be skipped (cipher "seeks" forward).
122 void Skip( std::size_t nBytes );
124 protected:
125 sal_uInt8 mpnKey[ 16 ] = {}; /// Encryption key.
126 std::size_t mnOffset; /// Key offset.
128 private:
129 MSCodec_Xor95( const MSCodec_Xor95& ) = delete;
130 MSCodec_Xor95& operator=( const MSCodec_Xor95& ) = delete;
132 sal_uInt16 mnKey; /// Base key from password.
133 sal_uInt16 mnHash; /// Hash value from password.
134 int mnRotateDistance;
137 /** Encodes and decodes data from protected MSO XLS 95- documents.
139 class MSFILTER_DLLPUBLIC MSCodec_XorXLS95 final : public MSCodec_Xor95
141 public:
142 explicit MSCodec_XorXLS95() : MSCodec_Xor95(2) {}
144 /** Decodes a block of memory inplace.
146 @precond
147 The codec must be initialized with InitKey() before this function
148 can be used.
150 @param pnData
151 Encrypted data block. Will contain the decrypted data afterwards.
152 @param nBytes
153 Size of the passed data block.
155 virtual void Decode( sal_uInt8* pnData, std::size_t nBytes ) override;
158 /** Encodes and decodes data from protected MSO Word 95- documents.
160 class MSFILTER_DLLPUBLIC MSCodec_XorWord95 final : public MSCodec_Xor95
162 public:
163 explicit MSCodec_XorWord95() : MSCodec_Xor95(7) {}
165 /** Decodes a block of memory inplace.
167 @precond
168 The codec must be initialized with InitKey() before this function
169 can be used.
171 @param pnData
172 Encrypted data block. Will contain the decrypted data afterwards.
173 @param nBytes
174 Size of the passed data block.
176 virtual void Decode( sal_uInt8* pnData, std::size_t nBytes ) override;
179 class MSFILTER_DLLPUBLIC MSCodec97
181 public:
182 MSCodec97(size_t nHashLen, OUString aEncKeyName);
183 virtual ~MSCodec97();
185 /** Initializes the algorithm with the encryption data.
187 @param aData
188 The sequence contains the necessary data to initialize
189 the codec.
191 bool InitCodec(const css::uno::Sequence< css::beans::NamedValue >& aData);
193 /** Retrieves the encryption data
195 @return
196 The sequence contains the necessary data to initialize
197 the codec.
199 virtual css::uno::Sequence<css::beans::NamedValue> GetEncryptionData();
201 /** Initializes the algorithm with the specified password and document ID.
203 @param pPassData
204 Wide character array containing the password. Must be zero
205 terminated, which results in a maximum length of 15 characters.
206 @param pDocId
207 Unique document identifier read from or written to the file.
209 virtual void InitKey(const sal_uInt16 pPassData[16],
210 const sal_uInt8 pDocId[16]) = 0;
213 /** Verifies the validity of the password using the passed salt data.
215 @precond
216 The codec must be initialized with InitKey() before this function
217 can be used.
219 @param pSaltData
220 Salt data block read from the file.
221 @param pSaltDigest
222 Salt digest read from the file.
224 @return
225 true = Test was successful.
227 bool VerifyKey(const sal_uInt8* pSaltData, const sal_uInt8* pSaltDigest);
229 virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) = 0;
231 /** Rekeys the codec using the specified counter.
233 After reading a specific amount of data the cipher algorithm needs to
234 be rekeyed using a counter that counts the data blocks.
236 The block size is for example 512 Bytes for Word files and 1024 Bytes
237 for Excel files.
239 @precond
240 The codec must be initialized with InitKey() before this function
241 can be used.
243 @param nCounter
244 Block counter used to rekey the cipher.
246 virtual bool InitCipher(sal_uInt32 nCounter) = 0;
248 /** Encodes a block of memory.
250 @see rtl_cipher_encode()
252 @precond
253 The codec must be initialized with InitKey() before this function
254 can be used. The destination buffer must be able to take all
255 unencoded data from the source buffer (usually this means it must be
256 as long as or longer than the source buffer).
258 @param pData
259 Unencrypted source data block.
260 @param nDatLen
261 Size of the passed source data block.
262 @param pBuffer
263 Destination buffer for the encrypted data.
264 @param nBufLen
265 Size of the destination buffer.
267 @return
268 true = Encoding was successful (no error occurred).
270 bool Encode(const void* pData, std::size_t nDatLen,
271 sal_uInt8* pBuffer, std::size_t nBufLen);
273 /** Decodes a block of memory.
275 @see rtl_cipher_decode()
277 @precond
278 The codec must be initialized with InitKey() before this function
279 can be used. The destination buffer must be able to take all
280 encoded data from the source buffer (usually this means it must be
281 as long as or longer than the source buffer).
283 @param pData
284 Encrypted source data block.
285 @param nDatLen
286 Size of the passed source data block.
287 @param pBuffer
288 Destination buffer for the decrypted data.
289 @param nBufLen
290 Size of the destination buffer.
292 @return
293 true = Decoding was successful (no error occurred).
295 bool Decode(const void* pData, std::size_t nDatLen,
296 sal_uInt8* pBuffer, std::size_t nBufLen);
298 /** Lets the cipher skip a specific amount of bytes.
300 This function sets the cipher to the same state as if the specified
301 amount of data has been decoded with one or more calls of Decode().
303 @precond
304 The codec must be initialized with InitKey() before this function
305 can be used.
307 @param nDatLen
308 Number of bytes to be skipped (cipher "seeks" forward).
310 bool Skip(std::size_t nDatLen);
312 /* allows to get the unique document id from the codec
314 void GetDocId( sal_uInt8 pDocId[16] );
316 private:
317 MSCodec97(const MSCodec97&) = delete;
318 MSCodec97& operator=(const MSCodec97&) = delete;
320 protected:
321 OUString m_sEncKeyName;
322 size_t m_nHashLen;
323 rtlCipher m_hCipher;
324 std::vector<sal_uInt8> m_aDocId;
325 std::vector<sal_uInt8> m_aDigestValue;
328 /** Encodes and decodes data from protected MSO 97+ documents.
330 This is a wrapper class around low level cryptographic functions from RTL.
331 Implementation is based on the wvDecrypt package by Caolan McNamara:
332 http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
334 class MSFILTER_DLLPUBLIC MSCodec_Std97 final : public MSCodec97
336 public:
337 MSCodec_Std97();
338 virtual ~MSCodec_Std97() override;
340 /** Initializes the algorithm with the specified password and document ID.
342 @param pPassData
343 Wide character array containing the password. Must be zero
344 terminated, which results in a maximum length of 15 characters.
345 @param pDocId
346 Unique document identifier read from or written to the file.
348 virtual void InitKey(const sal_uInt16 pPassData[16],
349 const sal_uInt8 pDocId[16]) override;
351 /** Rekeys the codec using the specified counter.
353 After reading a specific amount of data the cipher algorithm needs to
354 be rekeyed using a counter that counts the data blocks.
356 The block size is for example 512 Bytes for Word files and 1024 Bytes
357 for Excel files.
359 @precond
360 The codec must be initialized with InitKey() before this function
361 can be used.
363 @param nCounter
364 Block counter used to rekey the cipher.
366 virtual bool InitCipher(sal_uInt32 nCounter) override;
368 /** Creates an MD5 digest of salt digest. */
369 void CreateSaltDigest(
370 const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
372 /** Gets salt data and salt digest.
374 @precond
375 The codec must be initialized with InitKey() before this function
376 can be used.
378 @param pSalt
379 Salt, a random number.
380 @param pSaltData
381 Salt data block generated from the salt.
382 @param pSaltDigest
383 Salt digest generated from the salt.
385 void GetEncryptKey (
386 const sal_uInt8 pSalt[16],
387 sal_uInt8 pSaltData[16],
388 sal_uInt8 pSaltDigest[16]);
390 virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) override;
392 private:
393 MSCodec_Std97( const MSCodec_Std97& ) = delete;
394 MSCodec_Std97& operator=( const MSCodec_Std97& ) = delete;
396 rtlDigest m_hDigest;
399 class MSFILTER_DLLPUBLIC MSCodec_CryptoAPI final : public MSCodec97
401 private:
402 css::uno::Sequence<sal_Int8> m_aStd97Key;
403 public:
404 MSCodec_CryptoAPI();
406 virtual void InitKey(const sal_uInt16 pPassData[16],
407 const sal_uInt8 pDocId[16]) override;
408 virtual bool InitCipher(sal_uInt32 nCounter) override;
409 virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) override;
410 virtual css::uno::Sequence<css::beans::NamedValue> GetEncryptionData() override;
413 const sal_uInt32 ENCRYPTINFO_CRYPTOAPI = 0x00000004;
414 const sal_uInt32 ENCRYPTINFO_DOCPROPS = 0x00000008;
415 const sal_uInt32 ENCRYPTINFO_EXTERNAL = 0x00000010;
416 const sal_uInt32 ENCRYPTINFO_AES = 0x00000020;
418 const sal_uInt32 ENCRYPT_ALGO_AES128 = 0x0000660E;
419 const sal_uInt32 ENCRYPT_ALGO_AES192 = 0x0000660F;
420 const sal_uInt32 ENCRYPT_ALGO_AES256 = 0x00006610;
421 const sal_uInt32 ENCRYPT_ALGO_RC4 = 0x00006801;
423 const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004;
425 const sal_uInt32 ENCRYPT_KEY_SIZE_AES_128 = 0x00000080;
426 const sal_uInt32 ENCRYPT_KEY_SIZE_AES_192 = 0x000000C0;
427 const sal_uInt32 ENCRYPT_KEY_SIZE_AES_256 = 0x00000100;
429 const sal_uInt32 ENCRYPT_PROVIDER_TYPE_AES = 0x00000018;
430 const sal_uInt32 ENCRYPT_PROVIDER_TYPE_RC4 = 0x00000001;
432 // version of encryption info used in MS Office 1997 (major = 1, minor = 1)
433 const sal_uInt32 VERSION_INFO_1997_FORMAT = 0x00010001;
434 // version of encryption info used in MS Office 2007 (major = 3, minor = 2)
435 const sal_uInt32 VERSION_INFO_2007_FORMAT = 0x00020003;
436 // version of encryption info used in MS Office 2007 SP2 and older (major = 4, minor = 2)
437 const sal_uInt32 VERSION_INFO_2007_FORMAT_SP2 = 0x00020004;
439 // version of encryption info - agile (major = 4, minor = 4)
440 const sal_uInt32 VERSION_INFO_AGILE = 0x00040004;
442 const sal_uInt32 AGILE_ENCRYPTION_RESERVED = 0x00000040;
444 const sal_uInt32 SALT_LENGTH = 16;
445 const sal_uInt32 ENCRYPTED_VERIFIER_LENGTH = 16;
447 struct MSFILTER_DLLPUBLIC EncryptionStandardHeader
449 sal_uInt32 flags;
450 sal_uInt32 sizeExtra; // 0
451 sal_uInt32 algId; // if flag AES && CRYPTOAPI this defaults to 128-bit AES
452 sal_uInt32 algIdHash; // 0: determine by flags - defaults to SHA-1 if not external
453 sal_uInt32 keyBits; // key size in bits: 0 (determine by flags), 128, 192, 256
454 sal_uInt32 providedType; // AES or RC4
455 sal_uInt32 reserved1; // 0
456 sal_uInt32 reserved2; // 0
458 EncryptionStandardHeader();
461 struct MSFILTER_DLLPUBLIC EncryptionVerifierAES
463 sal_uInt32 saltSize; // must be 0x00000010
464 sal_uInt8 salt[SALT_LENGTH] = {}; // random generated salt value
465 sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH] = {}; // randomly generated verifier value
466 sal_uInt32 encryptedVerifierHashSize; // actually written hash size - depends on algorithm
467 sal_uInt8 encryptedVerifierHash[comphelper::SHA256_HASH_LENGTH] = {}; // verifier value hash - itself also encrypted
469 EncryptionVerifierAES();
472 struct MSFILTER_DLLPUBLIC EncryptionVerifierRC4
474 sal_uInt32 saltSize; // must be 0x00000010
475 sal_uInt8 salt[SALT_LENGTH] = {}; // random generated salt value
476 sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH] = {}; // randomly generated verifier value
477 sal_uInt32 encryptedVerifierHashSize; // actually written hash size - depends on algorithm
478 sal_uInt8 encryptedVerifierHash[comphelper::SHA1_HASH_LENGTH] = {}; // verifier value hash - itself also encrypted
480 EncryptionVerifierRC4();
483 struct MSFILTER_DLLPUBLIC StandardEncryptionInfo
485 EncryptionStandardHeader header;
486 EncryptionVerifierAES verifier;
489 struct MSFILTER_DLLPUBLIC RC4EncryptionInfo
491 EncryptionStandardHeader header;
492 EncryptionVerifierRC4 verifier;
495 } // namespace msfilter
497 #endif
499 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */