summaryrefslogtreecommitdiff
path: root/default.h
blob: 7fe443f2a49b998cb6c75eae32d4bafba30d820e (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// default.h - originally written and placed in the public domain by Wei Dai

/// \file default.h
/// \brief Classes for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC

#ifndef CRYPTOPP_DEFAULT_H
#define CRYPTOPP_DEFAULT_H

#include "sha.h"
#include "hmac.h"
#include "aes.h"
#include "des.h"
#include "modes.h"
#include "filters.h"
#include "smartptr.h"

NAMESPACE_BEGIN(CryptoPP)

/// \brief Legacy block cipher for LegacyEncryptor, LegacyDecryptor, LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef DES_EDE2 LegacyBlockCipher;
/// \brief Legacy hash for use with LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef SHA1 LegacyHashModule;
/// \brief Legacy HMAC for use withLegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef HMAC<LegacyHashModule> LegacyMAC;

/// \brief Default block cipher for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef AES DefaultBlockCipher;
/// \brief Default hash for use with DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef SHA256 DefaultHashModule;
/// \brief Default HMAC for use withDefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef HMAC<DefaultHashModule> DefaultMAC;

/// \brief Exception thrown when LegacyDecryptorWithMAC or DefaultDecryptorWithMAC decryption error is encountered
class DataDecryptorErr : public Exception
{
public:
	DataDecryptorErr(const std::string &s)
		: Exception(DATA_INTEGRITY_CHECK_FAILED, s) {}
};

/// \brief Exception thrown when a bad key is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
class KeyBadErr : public DataDecryptorErr
{
	public: KeyBadErr()
		: DataDecryptorErr("DataDecryptor: cannot decrypt message with this passphrase") {}
};

/// \brief Exception thrown when an incorrect MAC is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
class MACBadErr : public DataDecryptorErr
{
	public: MACBadErr()
		: DataDecryptorErr("DataDecryptorWithMAC: MAC check failed") {}
};

/// \brief Algorithm information for password-based encryptors and decryptors
template <unsigned int BlockSize, unsigned int KeyLength, unsigned int DigestSize, unsigned int SaltSize, unsigned int Iterations>
struct DataParametersInfo
{
	CRYPTOPP_CONSTANT(BLOCKSIZE  = BlockSize);
	CRYPTOPP_CONSTANT(KEYLENGTH  = KeyLength);
	CRYPTOPP_CONSTANT(SALTLENGTH = SaltSize);
	CRYPTOPP_CONSTANT(DIGESTSIZE = DigestSize);
	CRYPTOPP_CONSTANT(ITERATIONS = Iterations);
};

typedef DataParametersInfo<LegacyBlockCipher::BLOCKSIZE, LegacyBlockCipher::DEFAULT_KEYLENGTH, LegacyHashModule::DIGESTSIZE, 8, 200> LegacyParametersInfo;
typedef DataParametersInfo<DefaultBlockCipher::BLOCKSIZE, DefaultBlockCipher::DEFAULT_KEYLENGTH, DefaultHashModule::DIGESTSIZE, 8, 2500> DefaultParametersInfo;

/// \brief Password-based Encryptor
/// \tparam BC BlockCipher based class used for encryption
/// \tparam H HashTransformation based class used for mashing
/// \tparam Info Constants used by the algorithms
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256.
/// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
/// \since Crypto++ 2.0
template <class BC, class H, class Info>
class DataEncryptor : public ProxyFilter, public Info
{
public:
	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);

	/// \brief Construct a DataEncryptor
	/// \param passphrase a C-String password
	/// \param attachment a BufferedTransformation to attach to this object
	DataEncryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR);

	/// \brief Construct a DataEncryptor
	/// \param passphrase a byte string password
	/// \param passphraseLength the length of the byte string password
	/// \param attachment a BufferedTransformation to attach to this object
	DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR);

protected:
	void FirstPut(const byte *);
	void LastPut(const byte *inString, size_t length);

private:
	SecByteBlock m_passphrase;
	typename CBC_Mode<BC>::Encryption m_cipher;
};

/// \brief Password-based Decryptor
/// \tparam BC BlockCipher based class used for encryption
/// \tparam H HashTransformation based class used for mashing
/// \tparam Info Constants used by the algorithms
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256.
/// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
/// \since Crypto++ 2.0
template <class BC, class H, class Info>
class DataDecryptor : public ProxyFilter, public Info
{
public:
	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);

	/// \brief Constructs a DataDecryptor
	/// \param passphrase a C-String password
	/// \param attachment a BufferedTransformation to attach to this object
	/// \param throwException a flag specifying whether an Exception should be thrown on error
	DataDecryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true);

	/// \brief Constructs a DataDecryptor
	/// \param passphrase a byte string password
	/// \param passphraseLength the length of the byte string password
	/// \param attachment a BufferedTransformation to attach to this object
	/// \param throwException a flag specifying whether an Exception should be thrown on error
	DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true);

	enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD};
	State CurrentState() const {return m_state;}

protected:
	void FirstPut(const byte *inString);
	void LastPut(const byte *inString, size_t length);

	State m_state;

private:
	void CheckKey(const byte *salt, const byte *keyCheck);

	SecByteBlock m_passphrase;
	typename CBC_Mode<BC>::Decryption m_cipher;
	member_ptr<FilterWithBufferedInput> m_decryptor;
	bool m_throwException;

};

/// \brief Password-based encryptor with MAC
/// \tparam BC BlockCipher based class used for encryption
/// \tparam H HashTransformation based class used for mashing
/// \tparam MAC HashTransformation based class used for authentication
/// \tparam Info Constants used by the algorithms
/// \details DataEncryptorWithMAC uses a non-standard mashup function called Mash() to derive key
///   bits from the password.
/// \details The purpose of the function Mash() is to take an arbitrary length input string and
///   *deterministically* produce an arbitrary length output string such that (1) it looks random,
///   (2) no information about the input is deducible from it, and (3) it contains as much entropy
///   as it can hold, or the amount of entropy in the input string, whichever is smaller.
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256.
/// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
/// \since Crypto++ 2.0
template <class BC, class H, class MAC, class Info>
class DataEncryptorWithMAC : public ProxyFilter
{
public:
	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);

	/// \brief Constructs a DataEncryptorWithMAC
	/// \param passphrase a C-String password
	/// \param attachment a BufferedTransformation to attach to this object
	DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR);

	/// \brief Constructs a DataEncryptorWithMAC
	/// \param passphrase a byte string password
	/// \param passphraseLength the length of the byte string password
	/// \param attachment a BufferedTransformation to attach to this object
	DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR);

protected:
	void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);}
	void LastPut(const byte *inString, size_t length);

private:
	member_ptr<MAC> m_mac;

};

/// \brief Password-based decryptor with MAC
/// \tparam BC BlockCipher based class used for encryption
/// \tparam H HashTransformation based class used for mashing
/// \tparam MAC HashTransformation based class used for authentication
/// \tparam Info Constants used by the algorithms
/// \details DataDecryptorWithMAC uses a non-standard mashup function called Mash() to derive key
///   bits from the password.
/// \details The purpose of the function Mash() is to take an arbitrary length input string and
///   *deterministically* produce an arbitrary length output string such that (1) it looks random,
///   (2) no information about the input is deducible from it, and (3) it contains as much entropy
///   as it can hold, or the amount of entropy in the input string, whichever is smaller.
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256.
/// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
/// \since Crypto++ 2.0
template <class BC, class H, class MAC, class Info>
class DataDecryptorWithMAC : public ProxyFilter
{
public:
	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);

	/// \brief Constructs a DataDecryptor
	/// \param passphrase a C-String password
	/// \param attachment a BufferedTransformation to attach to this object
	/// \param throwException a flag specifying whether an Exception should be thrown on error
	DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true);

	/// \brief Constructs a DataDecryptor
	/// \param passphrase a byte string password
	/// \param passphraseLength the length of the byte string password
	/// \param attachment a BufferedTransformation to attach to this object
	/// \param throwException a flag specifying whether an Exception should be thrown on error
	DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true);

	typename DataDecryptor<BC,H,Info>::State CurrentState() const;
	bool CheckLastMAC() const;

protected:
	void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);}
	void LastPut(const byte *inString, size_t length);

private:
	member_ptr<MAC> m_mac;
	HashVerificationFilter *m_hashVerifier;
	bool m_throwException;
};

#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
/// \brief Password-based encryptor (deprecated)
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct LegacyEncryptor : public DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> {};
/// \brief Password-based decryptor (deprecated)
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct LegacyDecryptor : public DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> {};
/// \brief Password-based encryptor
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct DefaultEncryptor : public DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> {};
/// \brief Password-based decryptor
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct DefaultDecryptor : public DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> {};
/// \brief Password-based encryptor with MAC (deprecated)
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct LegacyEncryptorWithMAC : public DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> {};
/// \brief Password-based decryptor with MAC (deprecated)
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct LegacyDecryptorWithMAC : public DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> {};
/// \brief Password-based encryptor with MAC
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct DefaultEncryptorWithMAC : public DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> {};
/// \brief Password-based decryptor with MAC
/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
struct DefaultDecryptorWithMAC : public DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> {};
#else
typedef DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyEncryptor;
typedef DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyDecryptor;

typedef DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultEncryptor;
typedef DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultDecryptor;

typedef DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> LegacyEncryptorWithMAC;
typedef DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> LegacyDecryptorWithMAC;

typedef DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultEncryptorWithMAC;
typedef DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultDecryptorWithMAC;
#endif

NAMESPACE_END

#endif