1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
31 namespace com::sun::star
{
32 namespace beans
{ struct NamedValue
; }
38 /** Encodes and decodes data from protected MSO 95- documents.
40 class MSFILTER_DLLPUBLIC MSCodec_Xor95
43 explicit MSCodec_Xor95(int nRotateDistance
);
44 virtual ~MSCodec_Xor95();
46 /** Initializes the algorithm with the specified password.
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.
57 The sequence contains the necessary data to initialize
60 bool InitCodec( const css::uno::Sequence
< css::beans::NamedValue
>& aData
);
62 /** Retrieves the encryption data
65 The sequence contains the necessary data to initialize
68 css::uno::Sequence
< css::beans::NamedValue
> GetEncryptionData();
71 /** Verifies the validity of the password using the passed key and hash.
74 The codec must be initialized with InitKey() before this function
78 Password key value read from the file.
80 Password hash value read from the file.
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.
92 The codec must be initialized with InitKey() before this function
97 /** Decodes a block of memory inplace.
100 The codec must be initialized with InitKey() before this function
104 Encrypted data block. Will contain the decrypted data afterwards.
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().
116 The codec must be initialized with InitKey() before this function
120 Number of bytes to be skipped (cipher "seeks" forward).
122 void Skip( std::size_t nBytes
);
125 sal_uInt8 mpnKey
[ 16 ] = {}; /// Encryption key.
126 std::size_t mnOffset
; /// Key offset.
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
142 explicit MSCodec_XorXLS95() : MSCodec_Xor95(2) {}
144 /** Decodes a block of memory inplace.
147 The codec must be initialized with InitKey() before this function
151 Encrypted data block. Will contain the decrypted data afterwards.
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
163 explicit MSCodec_XorWord95() : MSCodec_Xor95(7) {}
165 /** Decodes a block of memory inplace.
168 The codec must be initialized with InitKey() before this function
172 Encrypted data block. Will contain the decrypted data afterwards.
174 Size of the passed data block.
176 virtual void Decode( sal_uInt8
* pnData
, std::size_t nBytes
) override
;
179 class MSFILTER_DLLPUBLIC MSCodec97
182 MSCodec97(size_t nHashLen
, OUString aEncKeyName
);
183 virtual ~MSCodec97();
185 /** Initializes the algorithm with the encryption data.
188 The sequence contains the necessary data to initialize
191 bool InitCodec(const css::uno::Sequence
< css::beans::NamedValue
>& aData
);
193 /** Retrieves the encryption data
196 The sequence contains the necessary data to initialize
199 virtual css::uno::Sequence
<css::beans::NamedValue
> GetEncryptionData();
201 /** Initializes the algorithm with the specified password and document ID.
204 Wide character array containing the password. Must be zero
205 terminated, which results in a maximum length of 15 characters.
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.
216 The codec must be initialized with InitKey() before this function
220 Salt data block read from the file.
222 Salt digest read from the file.
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
240 The codec must be initialized with InitKey() before this function
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()
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).
259 Unencrypted source data block.
261 Size of the passed source data block.
263 Destination buffer for the encrypted data.
265 Size of the destination buffer.
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()
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).
284 Encrypted source data block.
286 Size of the passed source data block.
288 Destination buffer for the decrypted data.
290 Size of the destination buffer.
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().
304 The codec must be initialized with InitKey() before this function
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] );
317 MSCodec97(const MSCodec97
&) = delete;
318 MSCodec97
& operator=(const MSCodec97
&) = delete;
321 OUString m_sEncKeyName
;
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
338 virtual ~MSCodec_Std97() override
;
340 /** Initializes the algorithm with the specified password and document ID.
343 Wide character array containing the password. Must be zero
344 terminated, which results in a maximum length of 15 characters.
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
360 The codec must be initialized with InitKey() before this function
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.
375 The codec must be initialized with InitKey() before this function
379 Salt, a random number.
381 Salt data block generated from the salt.
383 Salt digest generated from the salt.
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
;
393 MSCodec_Std97( const MSCodec_Std97
& ) = delete;
394 MSCodec_Std97
& operator=( const MSCodec_Std97
& ) = delete;
399 class MSFILTER_DLLPUBLIC MSCodec_CryptoAPI final
: public MSCodec97
402 css::uno::Sequence
<sal_Int8
> m_aStd97Key
;
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
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
499 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */