9 NAMESPACE_BEGIN(CryptoPP)
11 static const
unsigned int MASH_ITERATIONS = 200;
12 static const
unsigned int SALTLENGTH = 8;
22 static
void Mash(const byte *in,
size_t inLen, byte *out,
size_t outLen,
int iterations)
24 if (BytePrecision(outLen) > 2)
27 size_t bufSize = RoundUpToMultipleOf(outLen, (
size_t)DefaultHashModule::DIGESTSIZE);
34 for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE)
36 b[0] = (byte) (i >> 8);
39 hash.Update(in, inLen);
43 while (iterations-- > 1)
45 memcpy(buf, outBuf, bufSize);
46 for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE)
48 b[0] = (byte) (i >> 8);
51 hash.Update(buf, bufSize);
56 memcpy(out, outBuf, outLen);
59 static void GenerateKeyIV(
const byte *passphrase,
size_t passphraseLength,
const byte *salt,
size_t saltLength, byte *key, byte *IV)
62 memcpy(temp, passphrase, passphraseLength);
63 memcpy(temp+passphraseLength, salt, saltLength);
65 Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
66 memcpy(key, keyIV, KEYLENGTH);
67 memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
73 :
ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
77 DefaultEncryptor::DefaultEncryptor(
const byte *passphrase,
size_t passphraseLength,
BufferedTransformation *attachment)
78 :
ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
83 void DefaultEncryptor::FirstPut(
const byte *)
86 CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1);
87 CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2);
89 SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
93 hash.Update(m_passphrase, m_passphrase.size());
95 hash.Update((byte *)&t,
sizeof(t));
97 hash.Update((byte *)&c,
sizeof(c));
101 hash.Update(m_passphrase, m_passphrase.size());
102 hash.Update(salt, SALTLENGTH);
103 hash.Final(keyCheck);
110 GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key,
IV);
112 m_cipher.SetKeyWithIV(key, key.size(),
IV);
115 m_filter->
Put(keyCheck, BLOCKSIZE);
118 void DefaultEncryptor::LastPut(
const byte *inString,
size_t length)
120 m_filter->MessageEnd();
125 DefaultDecryptor::DefaultDecryptor(
const char *p,
BufferedTransformation *attachment,
bool throwException)
126 :
ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
127 , m_state(WAITING_FOR_KEYCHECK)
128 , m_passphrase((const byte *)p, strlen(p))
129 , m_throwException(throwException)
133 DefaultDecryptor::DefaultDecryptor(
const byte *passphrase,
size_t passphraseLength,
BufferedTransformation *attachment,
bool throwException)
134 :
ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
135 , m_state(WAITING_FOR_KEYCHECK)
136 , m_passphrase(passphrase, passphraseLength)
137 , m_throwException(throwException)
141 void DefaultDecryptor::FirstPut(
const byte *inString)
143 CheckKey(inString, inString+SALTLENGTH);
146 void DefaultDecryptor::LastPut(
const byte *inString,
size_t length)
148 if (m_filter.get() == NULL)
151 if (m_throwException)
156 m_filter->MessageEnd();
157 m_state = WAITING_FOR_KEYCHECK;
161 void DefaultDecryptor::CheckKey(
const byte *salt,
const byte *keyCheck)
163 SecByteBlock check(STDMAX((
unsigned int)2*BLOCKSIZE, (
unsigned int)DefaultHashModule::DIGESTSIZE));
166 hash.Update(m_passphrase, m_passphrase.size());
167 hash.Update(salt, SALTLENGTH);
172 GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key,
IV);
174 m_cipher.SetKeyWithIV(key, key.size(),
IV);
177 decryptor->Put(keyCheck, BLOCKSIZE);
178 decryptor->ForceNextPut();
179 decryptor->Get(check+BLOCKSIZE, BLOCKSIZE);
181 SetFilter(decryptor.release());
183 if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE))
186 if (m_throwException)
195 static DefaultMAC * NewDefaultEncryptorMAC(
const byte *passphrase,
size_t passphraseLength)
197 size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
200 Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
204 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(
const char *passphrase,
BufferedTransformation *attachment)
206 , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
211 DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(
const byte *passphrase,
size_t passphraseLength,
BufferedTransformation *attachment)
213 , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
218 void DefaultEncryptorWithMAC::LastPut(
const byte *inString,
size_t length)
220 m_filter->MessageEnd();
225 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(
const char *passphrase,
BufferedTransformation *attachment,
bool throwException)
227 , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
228 , m_throwException(throwException)
233 DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(
const byte *passphrase,
size_t passphraseLength,
BufferedTransformation *attachment,
bool throwException)
235 , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
236 , m_throwException(throwException)
238 SetFilter(
new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=
new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
241 DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState()
const
243 return static_cast<const DefaultDecryptor *
>(m_filter.get())->CurrentState();
246 bool DefaultDecryptorWithMAC::CheckLastMAC()
const
248 return m_hashVerifier->GetLastResult();
251 void DefaultDecryptorWithMAC::LastPut(
const byte *inString,
size_t length)
253 m_filter->MessageEnd();
254 if (m_throwException && !CheckLastMAC())
exception thrown when an invalid argument is detected
Base class for Filter classes that are proxies for a chain of other filters.
Password-Based Encryptor using DES-EDE2.
a block of memory allocated using A
Password-Based Decryptor using DES-EDE2.
Filter Wrapper for HashTransformation.
Filter Wrapper for HashTransformation.
BufferedTransformation * AttachedTransformation()
returns the object immediately attached to this object or NULL for no attachment
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.