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