1 // default.h - originally written and placed in the public domain by Wei Dai
2 
3 /// \file default.h
4 /// \brief Classes for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
5 
6 #ifndef CRYPTOPP_DEFAULT_H
7 #define CRYPTOPP_DEFAULT_H
8 
9 #include "sha.h"
10 #include "hmac.h"
11 #include "aes.h"
12 #include "des.h"
13 #include "modes.h"
14 #include "filters.h"
15 #include "smartptr.h"
16 
17 NAMESPACE_BEGIN(CryptoPP)
18 
19 /// \brief Legacy block cipher for LegacyEncryptor, LegacyDecryptor, LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
20 typedef DES_EDE2 LegacyBlockCipher;
21 /// \brief Legacy hash for use with LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
22 typedef SHA1 LegacyHashModule;
23 /// \brief Legacy HMAC for use withLegacyEncryptorWithMAC and LegacyDecryptorWithMAC
24 typedef HMAC<LegacyHashModule> LegacyMAC;
25 
26 /// \brief Default block cipher for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
27 typedef AES DefaultBlockCipher;
28 /// \brief Default hash for use with DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
29 typedef SHA256 DefaultHashModule;
30 /// \brief Default HMAC for use withDefaultEncryptorWithMAC and DefaultDecryptorWithMAC
31 typedef HMAC<DefaultHashModule> DefaultMAC;
32 
33 /// \brief Exception thrown when LegacyDecryptorWithMAC or DefaultDecryptorWithMAC decryption error is encountered
34 class DataDecryptorErr : public Exception
35 {
36 public:
DataDecryptorErr(const std::string & s)37 	DataDecryptorErr(const std::string &s)
38 		: Exception(DATA_INTEGRITY_CHECK_FAILED, s) {}
39 };
40 
41 /// \brief Exception thrown when a bad key is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
42 class KeyBadErr : public DataDecryptorErr
43 {
KeyBadErr()44 	public: KeyBadErr()
45 		: DataDecryptorErr("DataDecryptor: cannot decrypt message with this passphrase") {}
46 };
47 
48 /// \brief Exception thrown when an incorrect MAC is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
49 class MACBadErr : public DataDecryptorErr
50 {
MACBadErr()51 	public: MACBadErr()
52 		: DataDecryptorErr("DataDecryptorWithMAC: MAC check failed") {}
53 };
54 
55 /// \brief Algorithm information for password-based encryptors and decryptors
56 template <unsigned int BlockSize, unsigned int KeyLength, unsigned int DigestSize, unsigned int SaltSize, unsigned int Iterations>
57 struct DataParametersInfo
58 {
59 	CRYPTOPP_CONSTANT(BLOCKSIZE  = BlockSize);
60 	CRYPTOPP_CONSTANT(KEYLENGTH  = KeyLength);
61 	CRYPTOPP_CONSTANT(SALTLENGTH = SaltSize);
62 	CRYPTOPP_CONSTANT(DIGESTSIZE = DigestSize);
63 	CRYPTOPP_CONSTANT(ITERATIONS = Iterations);
64 };
65 
66 typedef DataParametersInfo<LegacyBlockCipher::BLOCKSIZE, LegacyBlockCipher::DEFAULT_KEYLENGTH, LegacyHashModule::DIGESTSIZE, 8, 200> LegacyParametersInfo;
67 typedef DataParametersInfo<DefaultBlockCipher::BLOCKSIZE, DefaultBlockCipher::DEFAULT_KEYLENGTH, DefaultHashModule::DIGESTSIZE, 8, 2500> DefaultParametersInfo;
68 
69 /// \brief Password-based Encryptor
70 /// \tparam BC BlockCipher based class used for encryption
71 /// \tparam H HashTransformation based class used for mashing
72 /// \tparam Info Constants used by the algorithms
73 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
74 ///   Crypto++ 5.7 switched to AES and SHA256.
75 /// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
76 /// \since Crypto++ 2.0
77 template <class BC, class H, class Info>
78 class DataEncryptor : public ProxyFilter, public Info
79 {
80 public:
81 	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
82 	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
83 	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
84 	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
85 	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);
86 
87 	/// \brief Construct a DataEncryptor
88 	/// \param passphrase a C-String password
89 	/// \param attachment a BufferedTransformation to attach to this object
90 	DataEncryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR);
91 
92 	/// \brief Construct a DataEncryptor
93 	/// \param passphrase a byte string password
94 	/// \param passphraseLength the length of the byte string password
95 	/// \param attachment a BufferedTransformation to attach to this object
96 	DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR);
97 
98 protected:
99 	void FirstPut(const byte *);
100 	void LastPut(const byte *inString, size_t length);
101 
102 private:
103 	SecByteBlock m_passphrase;
104 	typename CBC_Mode<BC>::Encryption m_cipher;
105 };
106 
107 /// \brief Password-based Decryptor
108 /// \tparam BC BlockCipher based class used for encryption
109 /// \tparam H HashTransformation based class used for mashing
110 /// \tparam Info Constants used by the algorithms
111 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
112 ///   Crypto++ 5.7 switched to AES and SHA256.
113 /// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
114 /// \since Crypto++ 2.0
115 template <class BC, class H, class Info>
116 class DataDecryptor : public ProxyFilter, public Info
117 {
118 public:
119 	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
120 	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
121 	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
122 	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
123 	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);
124 
125 	/// \brief Constructs a DataDecryptor
126 	/// \param passphrase a C-String password
127 	/// \param attachment a BufferedTransformation to attach to this object
128 	/// \param throwException a flag specifying whether an Exception should be thrown on error
129 	DataDecryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true);
130 
131 	/// \brief Constructs a DataDecryptor
132 	/// \param passphrase a byte string password
133 	/// \param passphraseLength the length of the byte string password
134 	/// \param attachment a BufferedTransformation to attach to this object
135 	/// \param throwException a flag specifying whether an Exception should be thrown on error
136 	DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true);
137 
138 	enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD};
CurrentState()139 	State CurrentState() const {return m_state;}
140 
141 protected:
142 	void FirstPut(const byte *inString);
143 	void LastPut(const byte *inString, size_t length);
144 
145 	State m_state;
146 
147 private:
148 	void CheckKey(const byte *salt, const byte *keyCheck);
149 
150 	SecByteBlock m_passphrase;
151 	typename CBC_Mode<BC>::Decryption m_cipher;
152 	member_ptr<FilterWithBufferedInput> m_decryptor;
153 	bool m_throwException;
154 
155 };
156 
157 /// \brief Password-based encryptor with MAC
158 /// \tparam BC BlockCipher based class used for encryption
159 /// \tparam H HashTransformation based class used for mashing
160 /// \tparam MAC HashTransformation based class used for authentication
161 /// \tparam Info Constants used by the algorithms
162 /// \details DataEncryptorWithMAC uses a non-standard mashup function called Mash() to derive key
163 ///   bits from the password.
164 /// \details The purpose of the function Mash() is to take an arbitrary length input string and
165 ///   *deterministically* produce an arbitrary length output string such that (1) it looks random,
166 ///   (2) no information about the input is deducible from it, and (3) it contains as much entropy
167 ///   as it can hold, or the amount of entropy in the input string, whichever is smaller.
168 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
169 ///   Crypto++ 5.7 switched to AES and SHA256.
170 /// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
171 /// \since Crypto++ 2.0
172 template <class BC, class H, class MAC, class Info>
173 class DataEncryptorWithMAC : public ProxyFilter
174 {
175 public:
176 	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
177 	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
178 	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
179 	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
180 	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);
181 
182 	/// \brief Constructs a DataEncryptorWithMAC
183 	/// \param passphrase a C-String password
184 	/// \param attachment a BufferedTransformation to attach to this object
185 	DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR);
186 
187 	/// \brief Constructs a DataEncryptorWithMAC
188 	/// \param passphrase a byte string password
189 	/// \param passphraseLength the length of the byte string password
190 	/// \param attachment a BufferedTransformation to attach to this object
191 	DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR);
192 
193 protected:
FirstPut(const byte * inString)194 	void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);}
195 	void LastPut(const byte *inString, size_t length);
196 
197 private:
198 	member_ptr<MAC> m_mac;
199 
200 };
201 
202 /// \brief Password-based decryptor with MAC
203 /// \tparam BC BlockCipher based class used for encryption
204 /// \tparam H HashTransformation based class used for mashing
205 /// \tparam MAC HashTransformation based class used for authentication
206 /// \tparam Info Constants used by the algorithms
207 /// \details DataDecryptorWithMAC uses a non-standard mashup function called Mash() to derive key
208 ///   bits from the password.
209 /// \details The purpose of the function Mash() is to take an arbitrary length input string and
210 ///   *deterministically* produce an arbitrary length output string such that (1) it looks random,
211 ///   (2) no information about the input is deducible from it, and (3) it contains as much entropy
212 ///   as it can hold, or the amount of entropy in the input string, whichever is smaller.
213 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
214 ///   Crypto++ 5.7 switched to AES and SHA256.
215 /// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
216 /// \since Crypto++ 2.0
217 template <class BC, class H, class MAC, class Info>
218 class DataDecryptorWithMAC : public ProxyFilter
219 {
220 public:
221 	CRYPTOPP_CONSTANT(BLOCKSIZE  = Info::BLOCKSIZE);
222 	CRYPTOPP_CONSTANT(KEYLENGTH  = Info::KEYLENGTH);
223 	CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH);
224 	CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE);
225 	CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS);
226 
227 	/// \brief Constructs a DataDecryptor
228 	/// \param passphrase a C-String password
229 	/// \param attachment a BufferedTransformation to attach to this object
230 	/// \param throwException a flag specifying whether an Exception should be thrown on error
231 	DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true);
232 
233 	/// \brief Constructs a DataDecryptor
234 	/// \param passphrase a byte string password
235 	/// \param passphraseLength the length of the byte string password
236 	/// \param attachment a BufferedTransformation to attach to this object
237 	/// \param throwException a flag specifying whether an Exception should be thrown on error
238 	DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true);
239 
240 	typename DataDecryptor<BC,H,Info>::State CurrentState() const;
241 	bool CheckLastMAC() const;
242 
243 protected:
FirstPut(const byte * inString)244 	void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);}
245 	void LastPut(const byte *inString, size_t length);
246 
247 private:
248 	member_ptr<MAC> m_mac;
249 	HashVerificationFilter *m_hashVerifier;
250 	bool m_throwException;
251 };
252 
253 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
254 /// \brief Password-based encryptor (deprecated)
255 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
256 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
257 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
258 struct LegacyEncryptor : public DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> {};
259 /// \brief Password-based decryptor (deprecated)
260 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
261 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
262 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
263 struct LegacyDecryptor : public DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> {};
264 /// \brief Password-based encryptor
265 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
266 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
267 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
268 struct DefaultEncryptor : public DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> {};
269 /// \brief Password-based decryptor
270 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
271 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
272 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
273 struct DefaultDecryptor : public DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> {};
274 /// \brief Password-based encryptor with MAC (deprecated)
275 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
276 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
277 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
278 struct LegacyEncryptorWithMAC : public DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> {};
279 /// \brief Password-based decryptor with MAC (deprecated)
280 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
281 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
282 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
283 struct LegacyDecryptorWithMAC : public DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> {};
284 /// \brief Password-based encryptor with MAC
285 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
286 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
287 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
288 struct DefaultEncryptorWithMAC : public DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> {};
289 /// \brief Password-based decryptor with MAC
290 /// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
291 ///   Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the
292 ///   <tt>Default*</tt> classes, and the old algorithms are available with the <tt>Legacy*</tt> classes.
293 struct DefaultDecryptorWithMAC : public DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> {};
294 #else
295 typedef DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyEncryptor;
296 typedef DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyDecryptor;
297 
298 typedef DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultEncryptor;
299 typedef DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultDecryptor;
300 
301 typedef DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> LegacyEncryptorWithMAC;
302 typedef DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo> LegacyDecryptorWithMAC;
303 
304 typedef DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultEncryptorWithMAC;
305 typedef DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultDecryptorWithMAC;
306 #endif
307 
308 NAMESPACE_END
309 
310 #endif
311