summaryrefslogtreecommitdiff
path: root/include/oox/crypto/AgileEngine.hxx
blob: 60d19fed11db0384b3b9c034428a56acbaec8a67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#ifndef INCLUDED_OOX_CRYPTO_AGILEENGINE_HXX
#define INCLUDED_OOX_CRYPTO_AGILEENGINE_HXX

#include <vector>

#include <oox/dllapi.h>
#include <oox/crypto/CryptTools.hxx>
#include <oox/crypto/CryptoEngine.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>

namespace oox {
    class BinaryXInputStream;
    class BinaryXOutputStream;
}

namespace oox {
namespace core {

struct OOX_DLLPUBLIC AgileEncryptionInfo
{
    sal_Int32 spinCount;
    sal_Int32 saltSize;
    sal_Int32 keyBits;
    sal_Int32 hashSize;
    sal_Int32 blockSize;

    OUString cipherAlgorithm;
    OUString cipherChaining;
    OUString hashAlgorithm;

    std::vector<sal_uInt8> keyDataSalt;

    // Key Encryptor
    std::vector<sal_uInt8> saltValue;
    std::vector<sal_uInt8> encryptedVerifierHashInput;
    std::vector<sal_uInt8> encryptedVerifierHashValue;
    std::vector<sal_uInt8> encryptedKeyValue;

    // HMAC
    std::vector<sal_uInt8> hmacKey;
    std::vector<sal_uInt8> hmacHash;
    std::vector<sal_uInt8> hmacCalculatedHash;
    std::vector<sal_uInt8> hmacEncryptedKey; // encrypted Key
    std::vector<sal_uInt8> hmacEncryptedValue; // encrypted Hash
};

struct OOX_DLLPUBLIC AgileEncryptionParameters
{
    sal_Int32 const spinCount;
    sal_Int32 const saltSize;
    sal_Int32 const keyBits;
    sal_Int32 const hashSize;
    sal_Int32 const blockSize;

    OUString const cipherAlgorithm;
    OUString const cipherChaining;
    OUString const hashAlgorithm;
};

enum class AgileEncryptionPreset
{
    AES_128_SHA1,
    AES_256_SHA512,
};

class OOX_DLLPUBLIC AgileEngine : public CryptoEngine
{
private:
    std::vector<sal_uInt8> mKey;
    AgileEncryptionInfo mInfo;
    AgileEncryptionPreset meEncryptionPreset;
    css::uno::Reference< css::uno::XComponentContext > mxContext;

    css::uno::Reference<css::io::XInputStream> getStream(css::uno::Sequence<css::beans::NamedValue> & rStreams, const OUString sStreamName);

    void calculateHashFinal(const OUString& rPassword, std::vector<sal_uInt8>& aHashFinal);

    void calculateBlock(
            std::vector<sal_uInt8> const & rBlock,
            std::vector<sal_uInt8>& rHashFinal,
            std::vector<sal_uInt8>& rInput,
            std::vector<sal_uInt8>& rOutput);

    void encryptBlock(
            std::vector<sal_uInt8> const & rBlock,
            std::vector<sal_uInt8>& rHashFinal,
            std::vector<sal_uInt8>& rInput,
            std::vector<sal_uInt8>& rOutput);

    static Crypto::CryptoType cryptoType(const AgileEncryptionInfo& rInfo);

    // Decryption

    bool decryptHmacKey();
    bool decryptHmacValue();

    AgileEncryptionInfo& getInfo() { return mInfo; }

    void setPreset(AgileEncryptionPreset ePreset)
    {
        meEncryptionPreset = ePreset;
    }

    void decryptEncryptionKey(OUString const & rPassword);
    bool decryptAndCheckVerifierHash(OUString const & rPassword);

    // Encryption

    bool encryptHmacKey();
    bool encryptHmacValue();

    bool generateAndEncryptVerifierHash(OUString const & rPassword);

    bool encryptEncryptionKey(OUString const & rPassword);
    void setupEncryptionParameters(AgileEncryptionParameters const & rAgileEncryptionParameters);
    bool setupEncryptionKey(OUString const & rPassword);

public:
    AgileEngine(const css::uno::Reference< css::uno::XComponentContext >& rxContext);

    // Decryption

    bool generateEncryptionKey(OUString const & rPassword) override;
    bool readEncryptionInfo(css::uno::Sequence<css::beans::NamedValue> aStreams) override;
    bool decrypt(BinaryXInputStream& aInputStream,
                 BinaryXOutputStream& aOutputStream) override;

    bool checkDataIntegrity() override;

    // Encryption

    void writeEncryptionInfo(oox::ole::OleStorage& rOleStorage) override;

    void encrypt(css::uno::Reference<css::io::XInputStream>&  rxInputStream,
                 css::uno::Reference<css::io::XOutputStream>& rxOutputStream,
                 sal_uInt32 nSize) override;

    bool setupEncryption(css::uno::Sequence<css::beans::NamedValue>& rMediaEncData) override;

    virtual void createEncryptionData(comphelper::SequenceAsHashMap & aEncryptionData, const OUString rPassword) override;
};

} // namespace core
} // namespace oox

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */