~ubuntu-branches/debian/jessie/armory/jessie

« back to all changes in this revision

Viewing changes to cppForSwig/cryptopp/default.cpp

  • Committer: Package Import Robot
  • Author(s): Joseph Bisch
  • Date: 2014-10-07 10:22:45 UTC
  • Revision ID: package-import@ubuntu.com-20141007102245-2s3x3rhjxg689hek
Tags: upstream-0.92.3
ImportĀ upstreamĀ versionĀ 0.92.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// default.cpp - written and placed in the public domain by Wei Dai
 
2
 
 
3
#include "pch.h"
 
4
#include "default.h"
 
5
#include "queue.h"
 
6
#include <time.h>
 
7
#include <memory>
 
8
 
 
9
NAMESPACE_BEGIN(CryptoPP)
 
10
 
 
11
static const unsigned int MASH_ITERATIONS = 200;
 
12
static const unsigned int SALTLENGTH = 8;
 
13
static const unsigned int BLOCKSIZE = Default_BlockCipher::Encryption::BLOCKSIZE;
 
14
static const unsigned int KEYLENGTH = Default_BlockCipher::Encryption::DEFAULT_KEYLENGTH;
 
15
 
 
16
// The purpose of this function Mash() is to take an arbitrary length input
 
17
// string and *deterministicly* produce an arbitrary length output string such
 
18
// that (1) it looks random, (2) no information about the input is
 
19
// deducible from it, and (3) it contains as much entropy as it can hold, or
 
20
// the amount of entropy in the input string, whichever is smaller.
 
21
 
 
22
static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations)
 
23
{
 
24
        if (BytePrecision(outLen) > 2)
 
25
                throw InvalidArgument("Mash: output legnth too large");
 
26
 
 
27
        size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE);
 
28
        byte b[2];
 
29
        SecByteBlock buf(bufSize);
 
30
        SecByteBlock outBuf(bufSize);
 
31
        DefaultHashModule hash;
 
32
 
 
33
        unsigned int i;
 
34
        for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE)
 
35
        {
 
36
                b[0] = (byte) (i >> 8);
 
37
                b[1] = (byte) i;
 
38
                hash.Update(b, 2);
 
39
                hash.Update(in, inLen);
 
40
                hash.Final(outBuf+i);
 
41
        }
 
42
 
 
43
        while (iterations-- > 1)
 
44
        {
 
45
                memcpy(buf, outBuf, bufSize);
 
46
                for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE)
 
47
                {
 
48
                        b[0] = (byte) (i >> 8);
 
49
                        b[1] = (byte) i;
 
50
                        hash.Update(b, 2);
 
51
                        hash.Update(buf, bufSize);
 
52
                        hash.Final(outBuf+i);
 
53
                }
 
54
        }
 
55
 
 
56
        memcpy(out, outBuf, outLen);
 
57
}
 
58
 
 
59
static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV)
 
60
{
 
61
        SecByteBlock temp(passphraseLength+saltLength);
 
62
        memcpy(temp, passphrase, passphraseLength);
 
63
        memcpy(temp+passphraseLength, salt, saltLength);
 
64
        SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE);
 
65
        Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
 
66
        memcpy(key, keyIV, KEYLENGTH);
 
67
        memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
 
68
}
 
69
 
 
70
// ********************************************************
 
71
 
 
72
DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment)
 
73
        : ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
 
74
{
 
75
}
 
76
 
 
77
DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
 
78
        : ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
 
79
{
 
80
}
 
81
 
 
82
 
 
83
void DefaultEncryptor::FirstPut(const byte *)
 
84
{
 
85
        // VC60 workaround: __LINE__ expansion bug
 
86
        CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1);
 
87
        CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2);
 
88
 
 
89
        SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
 
90
        DefaultHashModule hash;
 
91
 
 
92
        // use hash(passphrase | time | clock) as salt
 
93
        hash.Update(m_passphrase, m_passphrase.size());
 
94
        time_t t=time(0);
 
95
        hash.Update((byte *)&t, sizeof(t));
 
96
        clock_t c=clock();
 
97
        hash.Update((byte *)&c, sizeof(c));
 
98
        hash.Final(salt);
 
99
 
 
100
        // use hash(passphrase | salt) as key check
 
101
        hash.Update(m_passphrase, m_passphrase.size());
 
102
        hash.Update(salt, SALTLENGTH);
 
103
        hash.Final(keyCheck);
 
104
 
 
105
        AttachedTransformation()->Put(salt, SALTLENGTH);
 
106
 
 
107
        // mash passphrase and salt together into key and IV
 
108
        SecByteBlock key(KEYLENGTH);
 
109
        SecByteBlock IV(BLOCKSIZE);
 
110
        GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
 
111
 
 
112
        m_cipher.SetKeyWithIV(key, key.size(), IV);
 
113
        SetFilter(new StreamTransformationFilter(m_cipher));
 
114
 
 
115
        m_filter->Put(keyCheck, BLOCKSIZE);
 
116
}
 
117
 
 
118
void DefaultEncryptor::LastPut(const byte *inString, size_t length)
 
119
{
 
120
        m_filter->MessageEnd();
 
121
}
 
122
 
 
123
// ********************************************************
 
124
 
 
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)
 
130
{
 
131
}
 
132
 
 
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)
 
138
{
 
139
}
 
140
 
 
141
void DefaultDecryptor::FirstPut(const byte *inString)
 
142
{
 
143
        CheckKey(inString, inString+SALTLENGTH);
 
144
}
 
145
 
 
146
void DefaultDecryptor::LastPut(const byte *inString, size_t length)
 
147
{
 
148
        if (m_filter.get() == NULL)
 
149
        {
 
150
                m_state = KEY_BAD;
 
151
                if (m_throwException)
 
152
                        throw KeyBadErr();
 
153
        }
 
154
        else
 
155
        {
 
156
                m_filter->MessageEnd();
 
157
                m_state = WAITING_FOR_KEYCHECK;
 
158
        }
 
159
}
 
160
 
 
161
void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck)
 
162
{
 
163
        SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE));
 
164
 
 
165
        DefaultHashModule hash;
 
166
        hash.Update(m_passphrase, m_passphrase.size());
 
167
        hash.Update(salt, SALTLENGTH);
 
168
        hash.Final(check);
 
169
 
 
170
        SecByteBlock key(KEYLENGTH);
 
171
        SecByteBlock IV(BLOCKSIZE);
 
172
        GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
 
173
 
 
174
        m_cipher.SetKeyWithIV(key, key.size(), IV);
 
175
        std::auto_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher));
 
176
 
 
177
        decryptor->Put(keyCheck, BLOCKSIZE);
 
178
        decryptor->ForceNextPut();
 
179
        decryptor->Get(check+BLOCKSIZE, BLOCKSIZE);
 
180
 
 
181
        SetFilter(decryptor.release());
 
182
 
 
183
        if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE))
 
184
        {
 
185
                m_state = KEY_BAD;
 
186
                if (m_throwException)
 
187
                        throw KeyBadErr();
 
188
        }
 
189
        else
 
190
                m_state = KEY_GOOD;
 
191
}
 
192
 
 
193
// ********************************************************
 
194
 
 
195
static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength)
 
196
{
 
197
        size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
 
198
        SecByteBlock macKey(macKeyLength);
 
199
        // since the MAC is encrypted there is no reason to mash the passphrase for many iterations
 
200
        Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
 
201
        return new DefaultMAC(macKey, macKeyLength);
 
202
}
 
203
 
 
204
DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
 
205
        : ProxyFilter(NULL, 0, 0, attachment)
 
206
        , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
 
207
{
 
208
        SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true));
 
209
}
 
210
 
 
211
DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
 
212
        : ProxyFilter(NULL, 0, 0, attachment)
 
213
        , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
 
214
{
 
215
        SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true));
 
216
}
 
217
 
 
218
void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length)
 
219
{
 
220
        m_filter->MessageEnd();
 
221
}
 
222
 
 
223
// ********************************************************
 
224
 
 
225
DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
 
226
        : ProxyFilter(NULL, 0, 0, attachment)
 
227
        , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
 
228
        , m_throwException(throwException)
 
229
{
 
230
        SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
 
231
}
 
232
 
 
233
DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
 
234
        : ProxyFilter(NULL, 0, 0, attachment)
 
235
        , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
 
236
        , m_throwException(throwException)
 
237
{
 
238
        SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
 
239
}
 
240
 
 
241
DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const
 
242
{
 
243
        return static_cast<const DefaultDecryptor *>(m_filter.get())->CurrentState();
 
244
}
 
245
 
 
246
bool DefaultDecryptorWithMAC::CheckLastMAC() const
 
247
{
 
248
        return m_hashVerifier->GetLastResult();
 
249
}
 
250
 
 
251
void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length)
 
252
{
 
253
        m_filter->MessageEnd();
 
254
        if (m_throwException && !CheckLastMAC())
 
255
                throw MACBadErr();
 
256
}
 
257
 
 
258
NAMESPACE_END