1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef SVX_MSCODEC_HXX 25 #define SVX_MSCODEC_HXX 26 27 #include <com/sun/star/uno/Sequence.hxx> 28 #include <com/sun/star/beans/NamedValue.hpp> 29 30 #include <rtl/cipher.h> 31 #include <rtl/digest.h> 32 #include "filter/msfilter/msfilterdllapi.h" 33 34 namespace msfilter { 35 36 // ============================================================================ 37 38 /** Encodes and decodes data from protected MSO 95- documents. 39 */ 40 class MSFILTER_DLLPUBLIC MSCodec_Xor95 41 { 42 public: 43 explicit MSCodec_Xor95(int nRotateDistance); 44 virtual ~MSCodec_Xor95(); 45 46 /** Initializes the algorithm with the specified password. 47 48 @param pPassData 49 Character array containing the password. Must be zero terminated, 50 which results in a maximum length of 15 characters. 51 */ 52 void InitKey( const sal_uInt8 pnPassData[ 16 ] ); 53 54 /** Initializes the algorithm with the encryption data. 55 56 @param aData 57 The sequence contains the necessary data to initialize 58 the codec. 59 */ 60 sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); 61 62 /** Retrieves the encryption data 63 64 @return 65 The sequence contains the necessary data to initialize 66 the codec. 67 */ 68 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData(); 69 70 71 /** Verifies the validity of the password using the passed key and hash. 72 73 @precond 74 The codec must be initialized with InitKey() before this function 75 can be used. 76 77 @param nKey 78 Password key value read from the file. 79 @param nHash 80 Password hash value read from the file. 81 82 @return 83 true = Test was successful. 84 */ 85 bool VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const; 86 87 /** Reinitializes the codec to start a new memory block. 88 89 Resets the internal key offset to 0. 90 91 @precond 92 The codec must be initialized with InitKey() before this function 93 can be used. 94 */ 95 void InitCipher(); 96 97 /** Decodes a block of memory inplace. 98 99 @precond 100 The codec must be initialized with InitKey() before this function 101 can be used. 102 103 @param pnData 104 Encrypted data block. Will contain the decrypted data afterwards. 105 @param nBytes 106 Size of the passed data block. 107 */ 108 virtual void Decode( sal_uInt8* pnData, sal_Size nBytes )=0; 109 110 /** Lets the cipher skip a specific amount of bytes. 111 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(). 114 115 @precond 116 The codec must be initialized with InitKey() before this function 117 can be used. 118 119 @param nBytes 120 Number of bytes to be skipped (cipher "seeks" forward). 121 */ 122 void Skip( sal_Size nBytes ); 123 124 protected: 125 sal_uInt8 mpnKey[ 16 ]; /// Encryption key. 126 sal_Size mnOffset; /// Key offset. 127 128 private: 129 MSFILTER_DLLPRIVATE MSCodec_Xor95( const MSCodec_Xor95& ); 130 MSFILTER_DLLPRIVATE MSCodec_Xor95& operator=( const MSCodec_Xor95& ); 131 132 sal_uInt16 mnKey; /// Base key from password. 133 sal_uInt16 mnHash; /// Hash value from password. 134 int mnRotateDistance; 135 }; 136 137 /** Encodes and decodes data from protected MSO XLS 95- documents. 138 */ 139 class MSFILTER_DLLPUBLIC MSCodec_XorXLS95 : public MSCodec_Xor95 140 { 141 public: MSCodec_XorXLS95()142 explicit MSCodec_XorXLS95() : MSCodec_Xor95(2) {} 143 144 /** Decodes a block of memory inplace. 145 146 @precond 147 The codec must be initialized with InitKey() before this function 148 can be used. 149 150 @param pnData 151 Encrypted data block. Will contain the decrypted data afterwards. 152 @param nBytes 153 Size of the passed data block. 154 */ 155 virtual void Decode( sal_uInt8* pnData, sal_Size nBytes ); 156 }; 157 158 /** Encodes and decodes data from protected MSO Word 95- documents. 159 */ 160 class MSFILTER_DLLPUBLIC MSCodec_XorWord95 : public MSCodec_Xor95 161 { 162 public: MSCodec_XorWord95()163 explicit MSCodec_XorWord95() : MSCodec_Xor95(7) {} 164 165 /** Decodes a block of memory inplace. 166 167 @precond 168 The codec must be initialized with InitKey() before this function 169 can be used. 170 171 @param pnData 172 Encrypted data block. Will contain the decrypted data afterwards. 173 @param nBytes 174 Size of the passed data block. 175 */ 176 virtual void Decode( sal_uInt8* pnData, sal_Size nBytes ); 177 }; 178 179 180 // ============================================================================ 181 182 /** Encodes and decodes data from protected MSO 97+ documents. 183 184 This is a wrapper class around low level cryptographic functions from RTL. 185 Implementation is based on the wvDecrypt package by Caolan McNamara: 186 http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html 187 */ 188 class MSFILTER_DLLPUBLIC MSCodec_Std97 189 { 190 public: 191 explicit MSCodec_Std97(); 192 ~MSCodec_Std97(); 193 194 /** Initializes the algorithm with the encryption data. 195 196 @param aData 197 The sequence contains the necessary data to initialize 198 the codec. 199 */ 200 sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); 201 202 /** Retrieves the encryption data 203 204 @return 205 The sequence contains the necessary data to initialize 206 the codec. 207 */ 208 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData(); 209 210 211 /** Initializes the algorithm with the specified password and document ID. 212 213 @param pPassData 214 Wide character array containing the password. Must be zero 215 terminated, which results in a maximum length of 15 characters. 216 @param pDocId 217 Unique document identifier read from or written to the file. 218 */ 219 void InitKey( 220 const sal_uInt16 pPassData[ 16 ], 221 const sal_uInt8 pDocId[ 16 ] ); 222 223 /** Verifies the validity of the password using the passed salt data. 224 225 @precond 226 The codec must be initialized with InitKey() before this function 227 can be used. 228 229 @param pSaltData 230 Salt data block read from the file. 231 @param pSaltDigest 232 Salt digest read from the file. 233 234 @return 235 true = Test was successful. 236 */ 237 bool VerifyKey( 238 const sal_uInt8 pSaltData[ 16 ], 239 const sal_uInt8 pSaltDigest[ 16 ] ); 240 241 /** Rekeys the codec using the specified counter. 242 243 After reading a specific amount of data the cipher algorithm needs to 244 be rekeyed using a counter that counts the data blocks. 245 246 The block size is for example 512 Bytes for Word files and 1024 Bytes 247 for Excel files. 248 249 @precond 250 The codec must be initialized with InitKey() before this function 251 can be used. 252 253 @param nCounter 254 Block counter used to rekey the cipher. 255 */ 256 bool InitCipher( sal_uInt32 nCounter ); 257 258 /** Creates an MD5 digest of salt digest. */ 259 bool CreateSaltDigest( 260 const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] ); 261 262 /** Encodes a block of memory. 263 264 @see rtl_cipher_encode() 265 266 @precond 267 The codec must be initialized with InitKey() before this function 268 can be used. The destination buffer must be able to take all 269 unencoded data from the source buffer (usually this means it must be 270 as long as or longer than the source buffer). 271 272 @param pData 273 Unencrypted source data block. 274 @param nDatLen 275 Size of the passed source data block. 276 @param pBuffer 277 Destination buffer for the encrypted data. 278 @param nBufLen 279 Size of the destination buffer. 280 281 @return 282 true = Encoding was successful (no error occured). 283 */ 284 bool Encode( 285 const void* pData, sal_Size nDatLen, 286 sal_uInt8* pBuffer, sal_Size nBufLen ); 287 288 /** Decodes a block of memory. 289 290 @see rtl_cipher_decode() 291 292 @precond 293 The codec must be initialized with InitKey() before this function 294 can be used. The destination buffer must be able to take all 295 encoded data from the source buffer (usually this means it must be 296 as long as or longer than the source buffer). 297 298 @param pData 299 Encrypted source data block. 300 @param nDatLen 301 Size of the passed source data block. 302 @param pBuffer 303 Destination buffer for the decrypted data. 304 @param nBufLen 305 Size of the destination buffer. 306 307 @return 308 true = Decoding was successful (no error occured). 309 */ 310 bool Decode( 311 const void* pData, sal_Size nDatLen, 312 sal_uInt8* pBuffer, sal_Size nBufLen ); 313 314 /** Lets the cipher skip a specific amount of bytes. 315 316 This function sets the cipher to the same state as if the specified 317 amount of data has been decoded with one or more calls of Decode(). 318 319 @precond 320 The codec must be initialized with InitKey() before this function 321 can be used. 322 323 @param nDatLen 324 Number of bytes to be skipped (cipher "seeks" forward). 325 */ 326 bool Skip( sal_Size nDatLen ); 327 328 /** Gets salt data and salt digest. 329 330 @precond 331 The codec must be initialized with InitKey() before this function 332 can be used. 333 334 @param pSalt 335 Salt, a random number. 336 @param pSaltData 337 Salt data block generated from the salt. 338 @param pSaltDigest 339 Salt digest generated from the salt. 340 */ 341 void GetEncryptKey ( 342 const sal_uInt8 pSalt[16], 343 sal_uInt8 pSaltData[16], 344 sal_uInt8 pSaltDigest[16]); 345 346 /* allows to get the unique document id from the codec 347 */ 348 void GetDocId( sal_uInt8 pDocId[16] ); 349 350 void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] ); 351 352 private: 353 void InitKeyImpl( 354 const sal_uInt8 pKeyData[64], 355 const sal_uInt8 pDocId[16] ); 356 357 358 private: 359 MSFILTER_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& ); 360 MSFILTER_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& ); 361 362 rtlCipher m_hCipher; 363 rtlDigest m_hDigest; 364 sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ]; 365 sal_uInt8 m_pDocId[16]; 366 }; 367 368 // ============================================================================ 369 370 } // namespace msfilter 371 372 #endif 373 374