00001
00002
00003 #include "pch.h"
00004 #include "config.h"
00005
00006 #if CRYPTOPP_MSC_VERSION
00007 # pragma warning(disable: 4127 4189)
00008 #endif
00009
00010 #include "cryptlib.h"
00011 #include "filters.h"
00012 #include "smartptr.h"
00013 #include "default.h"
00014 #include "queue.h"
00015
00016 #include <time.h>
00017 #include <memory>
00018
00019 NAMESPACE_BEGIN(CryptoPP)
00020
00021 static const unsigned int MASH_ITERATIONS = 200;
00022 static const unsigned int SALTLENGTH = 8;
00023 static const unsigned int BLOCKSIZE = DefaultBlockCipher::Encryption::BLOCKSIZE;
00024 static const unsigned int KEYLENGTH = DefaultBlockCipher::Encryption::DEFAULT_KEYLENGTH;
00025
00026
00027
00028
00029
00030
00031
00032 static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations)
00033 {
00034 if (BytePrecision(outLen) > 2)
00035 throw InvalidArgument("Mash: output legnth too large");
00036
00037 size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE);
00038 byte b[2];
00039 SecByteBlock buf(bufSize);
00040 SecByteBlock outBuf(bufSize);
00041 DefaultHashModule hash;
00042
00043 unsigned int i;
00044 for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE)
00045 {
00046 b[0] = (byte) (i >> 8);
00047 b[1] = (byte) i;
00048 hash.Update(b, 2);
00049 hash.Update(in, inLen);
00050 hash.Final(outBuf+i);
00051 }
00052
00053 while (iterations-- > 1)
00054 {
00055 memcpy(buf, outBuf, bufSize);
00056 for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE)
00057 {
00058 b[0] = (byte) (i >> 8);
00059 b[1] = (byte) i;
00060 hash.Update(b, 2);
00061 hash.Update(buf, bufSize);
00062 hash.Final(outBuf+i);
00063 }
00064 }
00065
00066 memcpy(out, outBuf, outLen);
00067 }
00068
00069 static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV)
00070 {
00071 SecByteBlock temp(passphraseLength+saltLength);
00072 memcpy(temp, passphrase, passphraseLength);
00073 memcpy(temp+passphraseLength, salt, saltLength);
00074 SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE);
00075 Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
00076 memcpy(key, keyIV, KEYLENGTH);
00077 memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
00078 }
00079
00080
00081
00082 DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment)
00083 : ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
00084 {
00085 }
00086
00087 DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
00088 : ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
00089 {
00090 }
00091
00092
00093 void DefaultEncryptor::FirstPut(const byte *)
00094 {
00095
00096 CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1);
00097 CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2);
00098
00099 SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
00100 DefaultHashModule hash;
00101
00102
00103 hash.Update(m_passphrase, m_passphrase.size());
00104 time_t t=time(0);
00105 hash.Update((byte *)&t, sizeof(t));
00106 clock_t c=clock();
00107 hash.Update((byte *)&c, sizeof(c));
00108 hash.Final(salt);
00109
00110
00111 hash.Update(m_passphrase, m_passphrase.size());
00112 hash.Update(salt, SALTLENGTH);
00113 hash.Final(keyCheck);
00114
00115 AttachedTransformation()->Put(salt, SALTLENGTH);
00116
00117
00118 SecByteBlock key(KEYLENGTH);
00119 SecByteBlock IV(BLOCKSIZE);
00120 GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
00121
00122 m_cipher.SetKeyWithIV(key, key.size(), IV);
00123 SetFilter(new StreamTransformationFilter(m_cipher));
00124
00125 m_filter->Put(keyCheck, BLOCKSIZE);
00126 }
00127
00128 void DefaultEncryptor::LastPut(const byte *inString, size_t length)
00129 {
00130 CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
00131 m_filter->MessageEnd();
00132 }
00133
00134
00135
00136 DefaultDecryptor::DefaultDecryptor(const char *p, BufferedTransformation *attachment, bool throwException)
00137 : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
00138 , m_state(WAITING_FOR_KEYCHECK)
00139 , m_passphrase((const byte *)p, strlen(p))
00140 , m_throwException(throwException)
00141 {
00142 }
00143
00144 DefaultDecryptor::DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
00145 : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
00146 , m_state(WAITING_FOR_KEYCHECK)
00147 , m_passphrase(passphrase, passphraseLength)
00148 , m_throwException(throwException)
00149 {
00150 }
00151
00152 void DefaultDecryptor::FirstPut(const byte *inString)
00153 {
00154 CheckKey(inString, inString+SALTLENGTH);
00155 }
00156
00157 void DefaultDecryptor::LastPut(const byte *inString, size_t length)
00158 {
00159 CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
00160 if (m_filter.get() == NULL)
00161 {
00162 m_state = KEY_BAD;
00163 if (m_throwException)
00164 throw KeyBadErr();
00165 }
00166 else
00167 {
00168 m_filter->MessageEnd();
00169 m_state = WAITING_FOR_KEYCHECK;
00170 }
00171 }
00172
00173 void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck)
00174 {
00175 SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE));
00176
00177 DefaultHashModule hash;
00178 hash.Update(m_passphrase, m_passphrase.size());
00179 hash.Update(salt, SALTLENGTH);
00180 hash.Final(check);
00181
00182 SecByteBlock key(KEYLENGTH);
00183 SecByteBlock IV(BLOCKSIZE);
00184 GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
00185
00186 m_cipher.SetKeyWithIV(key, key.size(), IV);
00187 member_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher));
00188
00189 decryptor->Put(keyCheck, BLOCKSIZE);
00190 decryptor->ForceNextPut();
00191 decryptor->Get(check+BLOCKSIZE, BLOCKSIZE);
00192
00193 SetFilter(decryptor.release());
00194
00195 if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE))
00196 {
00197 m_state = KEY_BAD;
00198 if (m_throwException)
00199 throw KeyBadErr();
00200 }
00201 else
00202 m_state = KEY_GOOD;
00203 }
00204
00205
00206
00207 static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength)
00208 {
00209 size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
00210 SecByteBlock macKey(macKeyLength);
00211
00212 Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
00213 return new DefaultMAC(macKey, macKeyLength);
00214 }
00215
00216 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
00217 : ProxyFilter(NULL, 0, 0, attachment)
00218 , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
00219 {
00220 SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true));
00221 }
00222
00223 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
00224 : ProxyFilter(NULL, 0, 0, attachment)
00225 , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
00226 {
00227 SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true));
00228 }
00229
00230 void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length)
00231 {
00232 CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
00233 m_filter->MessageEnd();
00234 }
00235
00236
00237
00238 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
00239 : ProxyFilter(NULL, 0, 0, attachment)
00240 , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
00241 , m_throwException(throwException)
00242 {
00243 SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
00244 }
00245
00246 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
00247 : ProxyFilter(NULL, 0, 0, attachment)
00248 , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
00249 , m_throwException(throwException)
00250 {
00251 SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
00252 }
00253
00254 DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const
00255 {
00256 return static_cast<const DefaultDecryptor *>(m_filter.get())->CurrentState();
00257 }
00258
00259 bool DefaultDecryptorWithMAC::CheckLastMAC() const
00260 {
00261 return m_hashVerifier->GetLastResult();
00262 }
00263
00264 void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length)
00265 {
00266 CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
00267 m_filter->MessageEnd();
00268 if (m_throwException && !CheckLastMAC())
00269 throw MACBadErr();
00270 }
00271
00272 NAMESPACE_END
00273