Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/default.cpp
2 views
1
// default.cpp - originally written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
#include "config.h"
5
6
#if CRYPTOPP_MSC_VERSION
7
# pragma warning(disable: 4127 4189)
8
#endif
9
10
#include "cryptlib.h"
11
#include "filters.h"
12
#include "smartptr.h"
13
#include "default.h"
14
#include "queue.h"
15
16
#include <time.h>
17
#include <memory>
18
19
NAMESPACE_BEGIN(CryptoPP)
20
21
// The purpose of this function Mash() is to take an arbitrary length input
22
// string and *deterministically* produce an arbitrary length output string such
23
// that (1) it looks random, (2) no information about the input is
24
// deducible from it, and (3) it contains as much entropy as it can hold, or
25
// the amount of entropy in the input string, whichever is smaller.
26
27
template <class H>
28
static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations)
29
{
30
if (BytePrecision(outLen) > 2)
31
throw InvalidArgument("Mash: output length too large");
32
33
size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)H::DIGESTSIZE);
34
byte b[2];
35
SecByteBlock buf(bufSize);
36
SecByteBlock outBuf(bufSize);
37
H hash;
38
39
unsigned int i;
40
for(i=0; i<outLen; i+=H::DIGESTSIZE)
41
{
42
b[0] = (byte) (i >> 8);
43
b[1] = (byte) i;
44
hash.Update(b, 2);
45
hash.Update(in, inLen);
46
hash.Final(outBuf+i);
47
}
48
49
while (iterations-- > 1)
50
{
51
std::memcpy(buf, outBuf, bufSize);
52
for (i=0; i<bufSize; i+=H::DIGESTSIZE)
53
{
54
b[0] = (byte) (i >> 8);
55
b[1] = (byte) i;
56
hash.Update(b, 2);
57
hash.Update(buf, bufSize);
58
hash.Final(outBuf+i);
59
}
60
}
61
62
std::memcpy(out, outBuf, outLen);
63
}
64
65
template <class BC, class H, class Info>
66
static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, unsigned int iterations, byte *key, byte *IV)
67
{
68
// UBsan. User supplied params, may be NULL
69
SecByteBlock temp(passphraseLength+saltLength);
70
if (passphrase != NULLPTR)
71
std::memcpy(temp, passphrase, passphraseLength);
72
if (salt != NULLPTR)
73
std::memcpy(temp+passphraseLength, salt, saltLength);
74
75
// OK. Derived params, cannot be NULL
76
SecByteBlock keyIV(EnumToInt(Info::KEYLENGTH)+EnumToInt(+Info::BLOCKSIZE));
77
Mash<H>(temp, passphraseLength + saltLength, keyIV, EnumToInt(Info::KEYLENGTH)+EnumToInt(+Info::BLOCKSIZE), iterations);
78
std::memcpy(key, keyIV, Info::KEYLENGTH);
79
std::memcpy(IV, keyIV+Info::KEYLENGTH, Info::BLOCKSIZE);
80
}
81
82
// ********************************************************
83
84
template <class BC, class H, class Info>
85
DataEncryptor<BC,H,Info>::DataEncryptor(const char *passphrase, BufferedTransformation *attachment)
86
: ProxyFilter(NULLPTR, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
87
{
88
CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= DIGESTSIZE);
89
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE);
90
}
91
92
template <class BC, class H, class Info>
93
DataEncryptor<BC,H,Info>::DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
94
: ProxyFilter(NULLPTR, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
95
{
96
CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE);
97
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE);
98
}
99
100
template <class BC, class H, class Info>
101
void DataEncryptor<BC,H,Info>::FirstPut(const byte *)
102
{
103
SecByteBlock salt(DIGESTSIZE), keyCheck(DIGESTSIZE);
104
H hash;
105
106
// use hash(passphrase | time | clock) as salt
107
hash.Update(m_passphrase, m_passphrase.size());
108
time_t t=time(NULLPTR);
109
hash.Update((byte *)&t, sizeof(t));
110
clock_t c=clock();
111
hash.Update((byte *)&c, sizeof(c));
112
hash.Final(salt);
113
114
// use hash(passphrase | salt) as key check
115
hash.Update(m_passphrase, m_passphrase.size());
116
hash.Update(salt, SALTLENGTH);
117
hash.Final(keyCheck);
118
119
AttachedTransformation()->Put(salt, SALTLENGTH);
120
121
// mash passphrase and salt together into key and IV
122
SecByteBlock key(KEYLENGTH);
123
SecByteBlock IV(BLOCKSIZE);
124
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
125
126
m_cipher.SetKeyWithIV(key, key.size(), IV);
127
SetFilter(new StreamTransformationFilter(m_cipher));
128
129
m_filter->Put(keyCheck, BLOCKSIZE);
130
}
131
132
template <class BC, class H, class Info>
133
void DataEncryptor<BC,H,Info>::LastPut(const byte *inString, size_t length)
134
{
135
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
136
m_filter->MessageEnd();
137
}
138
139
// ********************************************************
140
141
template <class BC, class H, class Info>
142
DataDecryptor<BC,H,Info>::DataDecryptor(const char *p, BufferedTransformation *attachment, bool throwException)
143
: ProxyFilter(NULLPTR, EnumToInt(SALTLENGTH)+EnumToInt(BLOCKSIZE), 0, attachment)
144
, m_state(WAITING_FOR_KEYCHECK)
145
, m_passphrase((const byte *)p, strlen(p))
146
, m_throwException(throwException)
147
{
148
CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE);
149
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE);
150
}
151
152
template <class BC, class H, class Info>
153
DataDecryptor<BC,H,Info>::DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
154
: ProxyFilter(NULLPTR, EnumToInt(SALTLENGTH)+EnumToInt(BLOCKSIZE), 0, attachment)
155
, m_state(WAITING_FOR_KEYCHECK)
156
, m_passphrase(passphrase, passphraseLength)
157
, m_throwException(throwException)
158
{
159
CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE);
160
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE);
161
}
162
163
template <class BC, class H, class Info>
164
void DataDecryptor<BC,H,Info>::FirstPut(const byte *inString)
165
{
166
CheckKey(inString, inString+SALTLENGTH);
167
}
168
169
template <class BC, class H, class Info>
170
void DataDecryptor<BC,H,Info>::LastPut(const byte *inString, size_t length)
171
{
172
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
173
if (m_filter.get() == NULLPTR)
174
{
175
m_state = KEY_BAD;
176
if (m_throwException)
177
throw KeyBadErr();
178
}
179
else
180
{
181
m_filter->MessageEnd();
182
m_state = WAITING_FOR_KEYCHECK;
183
}
184
}
185
186
template <class BC, class H, class Info>
187
void DataDecryptor<BC,H,Info>::CheckKey(const byte *salt, const byte *keyCheck)
188
{
189
SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DIGESTSIZE));
190
191
H hash;
192
hash.Update(m_passphrase, m_passphrase.size());
193
hash.Update(salt, SALTLENGTH);
194
hash.Final(check);
195
196
SecByteBlock key(KEYLENGTH);
197
SecByteBlock IV(BLOCKSIZE);
198
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
199
200
m_cipher.SetKeyWithIV(key, key.size(), IV);
201
member_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher));
202
203
decryptor->Put(keyCheck, BLOCKSIZE);
204
decryptor->ForceNextPut();
205
decryptor->Get(check+EnumToInt(BLOCKSIZE), BLOCKSIZE);
206
207
SetFilter(decryptor.release());
208
209
if (!VerifyBufsEqual(check, check+EnumToInt(BLOCKSIZE), BLOCKSIZE))
210
{
211
m_state = KEY_BAD;
212
if (m_throwException)
213
throw KeyBadErr();
214
}
215
else
216
m_state = KEY_GOOD;
217
}
218
219
// ********************************************************
220
221
template <class H, class MAC>
222
static MAC* NewDataEncryptorMAC(const byte *passphrase, size_t passphraseLength)
223
{
224
size_t macKeyLength = MAC::StaticGetValidKeyLength(16);
225
SecByteBlock macKey(macKeyLength);
226
// since the MAC is encrypted there is no reason to mash the passphrase for many iterations
227
Mash<H>(passphrase, passphraseLength, macKey, macKeyLength, 1);
228
return new MAC(macKey, macKeyLength);
229
}
230
231
template <class BC, class H, class MAC, class Info>
232
DataEncryptorWithMAC<BC,H,MAC,Info>::DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
233
: ProxyFilter(NULLPTR, 0, 0, attachment)
234
, m_mac(NewDataEncryptorMAC<H,MAC>((const byte *)passphrase, strlen(passphrase)))
235
{
236
SetFilter(new HashFilter(*m_mac, new DataEncryptor<BC,H,Info>(passphrase), true));
237
}
238
239
template <class BC, class H, class MAC, class Info>
240
DataEncryptorWithMAC<BC,H,MAC,Info>::DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
241
: ProxyFilter(NULLPTR, 0, 0, attachment)
242
, m_mac(NewDataEncryptorMAC<H,MAC>(passphrase, passphraseLength))
243
{
244
SetFilter(new HashFilter(*m_mac, new DataEncryptor<BC,H,Info>(passphrase, passphraseLength), true));
245
}
246
247
template <class BC, class H, class MAC, class Info>
248
void DataEncryptorWithMAC<BC,H,MAC,Info>::LastPut(const byte *inString, size_t length)
249
{
250
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
251
m_filter->MessageEnd();
252
}
253
254
// ********************************************************
255
256
template <class BC, class H, class MAC, class Info>
257
DataDecryptorWithMAC<BC,H,MAC,Info>::DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
258
: ProxyFilter(NULLPTR, 0, 0, attachment)
259
, m_mac(NewDataEncryptorMAC<H,MAC>((const byte *)passphrase, strlen(passphrase)))
260
, m_throwException(throwException)
261
{
262
SetFilter(new DataDecryptor<BC,H,Info>(passphrase, m_hashVerifier=new HashVerificationFilter(*m_mac, NULLPTR, HashVerificationFilter::PUT_MESSAGE), throwException));
263
}
264
265
template <class BC, class H, class MAC, class Info>
266
DataDecryptorWithMAC<BC,H,MAC,Info>::DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
267
: ProxyFilter(NULLPTR, 0, 0, attachment)
268
, m_mac(NewDataEncryptorMAC<H,MAC>(passphrase, passphraseLength))
269
, m_throwException(throwException)
270
{
271
SetFilter(new DataDecryptor<BC,H,Info>(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULLPTR, HashVerificationFilter::PUT_MESSAGE), throwException));
272
}
273
274
template <class BC, class H, class MAC, class Info>
275
typename DataDecryptor<BC,H,Info>::State DataDecryptorWithMAC<BC,H,MAC,Info>::CurrentState() const
276
{
277
return static_cast<const DataDecryptor<BC,H,Info> *>(m_filter.get())->CurrentState();
278
}
279
280
template <class BC, class H, class MAC, class Info>
281
bool DataDecryptorWithMAC<BC,H,MAC,Info>::CheckLastMAC() const
282
{
283
return m_hashVerifier->GetLastResult();
284
}
285
286
template <class BC, class H, class MAC, class Info>
287
void DataDecryptorWithMAC<BC,H,MAC,Info>::LastPut(const byte *inString, size_t length)
288
{
289
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
290
m_filter->MessageEnd();
291
if (m_throwException && !CheckLastMAC())
292
throw MACBadErr();
293
}
294
295
template struct DataParametersInfo<LegacyBlockCipher::BLOCKSIZE, LegacyBlockCipher::DEFAULT_KEYLENGTH, LegacyHashModule::DIGESTSIZE, 8, 200>;
296
template struct DataParametersInfo<DefaultBlockCipher::BLOCKSIZE, DefaultBlockCipher::DEFAULT_KEYLENGTH, DefaultHashModule::DIGESTSIZE, 8, 2500>;
297
298
template class DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo>;
299
template class DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo>;
300
template class DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo>;
301
template class DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo>;
302
template class DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo>;
303
template class DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,LegacyMAC,LegacyParametersInfo>;
304
template class DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo>;
305
template class DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo>;
306
307
NAMESPACE_END
308
309