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