16#include <rtl/random.h>
28void lclRandomGenerateValues(
sal_uInt8* aArray, sal_uInt32 aSize)
31 rtl_random_getBytes(aRandomPool, aArray, aSize);
32 rtl_random_destroyPool(aRandomPool);
35constexpr OUStringLiteral lclCspName =
u"Microsoft Enhanced RSA and AES Cryptographic Provider";
36constexpr const sal_uInt32 AES128Size = 16;
43 if (
mKey.size() != 16)
49 lclRandomGenerateValues(verifier.data(), verifier.size());
51 std::vector<sal_uInt8> iv;
64 aEncryptorHash.
update(encryptedHash, hash, hash.size());
73 size_t passwordByteLength = rPassword.size() * 2;
77 std::vector<sal_uInt8> initialData(saltSize + passwordByteLength);
78 std::copy(saltArray, saltArray + saltSize, initialData.begin());
80 auto p = initialData.begin() + saltSize;
81 for (
size_t i = 0;
i != rPassword.size(); ++
i) {
82 auto c = rPassword[
i];
94 for (sal_Int32
i = 0;
i < 50000; ++
i)
97 std::copy(hash.begin(), hash.end(), data.begin() + 4);
100 std::copy(hash.begin(), hash.end(), data.begin() );
106 std::vector<sal_uInt8> buffer(64, 0x36);
107 for (
size_t i = 0;
i < hash.size(); ++
i)
108 buffer[
i] ^= hash[
i];
111 if (
mKey.size() > hash.size())
113 std::copy(hash.begin(), hash.begin() +
mKey.size(),
mKey.begin());
141 encryptedVerifier.begin());
147 encryptedHash.begin());
149 std::vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
152 std::vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
157 return std::equal(hash.begin(), hash.end(), verifierHash.begin());
163 sal_uInt32 totalSize = aInputStream.
readuInt32();
164 aInputStream.
skip(4);
166 std::vector<sal_uInt8> iv;
168 std::vector<sal_uInt8> inputBuffer (4096);
169 std::vector<sal_uInt8> outputBuffer(4096);
170 sal_uInt32 inputLength;
171 sal_uInt32 outputLength;
172 sal_uInt32 remaining = totalSize;
174 while ((inputLength = aInputStream.
readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
176 outputLength = aDecryptor.
update(outputBuffer, inputBuffer, inputLength);
177 sal_uInt32 writeLength = std::min(outputLength, remaining);
178 aOutputStream.
writeMemory(outputBuffer.data(), writeLength);
179 remaining -= outputLength;
201 mKey.resize(keyLength, 0);
216 sal_uInt32 cspNameSize = (lclCspName.getLength() * 2) + 2;
221 sal_uInt32 headerSize = encryptionHeaderSize + cspNameSize;
244 css::uno::Reference<css::io::XOutputStream> & rxOutputStream,
256 std::vector<sal_uInt8> inputBuffer(1024);
257 std::vector<sal_uInt8> outputBuffer(1024);
259 sal_uInt32 inputLength;
260 sal_uInt32 outputLength;
262 std::vector<sal_uInt8> iv;
265 while ((inputLength = aBinaryInputStream.
readMemory(inputBuffer.data(), inputBuffer.size())) > 0)
268 inputLength = inputLength % AES128Size == 0 ?
269 inputLength :
roundUp(inputLength, AES128Size);
270 outputLength = aEncryptor.
update(outputBuffer, inputBuffer, inputLength);
271 aBinaryOutputStream.
writeMemory(outputBuffer.data(), outputLength);
283 sal_uInt32 nHeaderSize = aBinaryStream.
readuInt32();
285 sal_uInt32 actualHeaderSize =
sizeof(
mInfo.
header);
287 if (nHeaderSize < actualHeaderSize)
299 aBinaryStream.
skip(nHeaderSize - actualHeaderSize);
328 return !aBinaryStream.
isEof();
static std::vector< unsigned char > calculateHash(const unsigned char *pInput, size_t length, HashType eType)
BinaryOutputStream & WriteUInt32(sal_uInt32 x)
BinaryOutputStream & WriteUInt16(sal_uInt16 x)
void writeUnicodeArray(const OUString &rString)
bool isEof() const
Returns true, if the stream position is invalid (EOF).
Wraps a UNO output stream and provides convenient access functions.
virtual void writeMemory(const void *pMem, sal_Int32 nBytes, size_t nAtomSize=1) override
Write nBytes bytes from the (preallocated!) buffer pMem.
static void writeLittleEndian(void *pDstBuffer, Type nValue)
Writes a value to memory, while converting it to little-endian.
std::vector< sal_uInt8 > mKey
sal_uInt32 update(std::vector< sal_uInt8 > &output, std::vector< sal_uInt8 > &input, sal_uInt32 inputLength=0)
static sal_uInt32 aes128ecb(std::vector< sal_uInt8 > &output, std::vector< sal_uInt8 > &input, std::vector< sal_uInt8 > &key)
sal_uInt32 update(std::vector< sal_uInt8 > &output, std::vector< sal_uInt8 > &input, sal_uInt32 inputLength=0)
virtual bool setupEncryption(OUString const &rPassword) override
virtual bool generateEncryptionKey(OUString const &rPassword) override
void encrypt(const css::uno::Reference< css::io::XInputStream > &rxInputStream, css::uno::Reference< css::io::XOutputStream > &rxOutputStream, sal_uInt32 nSize) override
bool checkDataIntegrity() override
msfilter::StandardEncryptionInfo mInfo
virtual void writeEncryptionInfo(BinaryXOutputStream &rStream) override
bool calculateEncryptionKey(std::u16string_view rPassword)
bool readEncryptionInfo(css::uno::Reference< css::io::XInputStream > &rxInputStream) override
virtual bool decrypt(BinaryXInputStream &aInputStream, BinaryXOutputStream &aOutputStream) override
#define SAL_N_ELEMENTS(arr)
const sal_uInt32 SHA256_HASH_LENGTH
const sal_uInt32 SHA1_HASH_LENGTH
const sal_uInt32 ENCRYPT_PROVIDER_TYPE_AES
const sal_uInt32 VERSION_INFO_2007_FORMAT
const sal_uInt32 ENCRYPT_KEY_SIZE_AES_128
const sal_uInt32 ENCRYPT_ALGO_AES128
const sal_uInt32 ENCRYPT_HASH_SHA1
const sal_uInt32 ENCRYPTINFO_AES
const sal_uInt32 ENCRYPTED_VERIFIER_LENGTH
const sal_uInt32 ENCRYPTINFO_CRYPTOAPI
const sal_uInt32 ENCRYPTINFO_EXTERNAL
T roundUp(T input, T multiple)
Rounds up the input to the nearest multiple.
bool getFlag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
sal_uInt8 salt[SALT_LENGTH]
sal_uInt8 encryptedVerifierHash[comphelper::SHA256_HASH_LENGTH]
sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH]
sal_uInt32 encryptedVerifierHashSize
EncryptionVerifierAES verifier
EncryptionStandardHeader header