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