3
#include"../util/bytestream.h"
4
#include"../util/base64.h"
5
#include"../util/sha1.h"
7
bool sym_encrypt(const QByteArray &data, const Cipher::Key &key, const QByteArray &iv, QString *out)
9
QByteArray encData = iv.copy();
11
QByteArray a = Cipher::encrypt(data, key, iv, true, &ok);
14
ByteStream::appendArray(&encData, a);
16
*out = Base64::arrayToString(encData);
20
bool sym_decrypt(const QString &str, const Cipher::Key &key, QByteArray *out)
22
QByteArray data = Base64::stringToArray(str);
23
int r = Cipher::ivSize(key.type());
26
if((int)data.size() < r)
28
QByteArray iv = ByteStream::takeArray(&data, r);
30
QByteArray result = Cipher::decrypt(data, key, iv, true, &ok);
38
static QByteArray calcCMS(const QByteArray &key)
40
QByteArray a = SHA1::hash(key);
45
unsigned char sym_3des_fixed_iv[8] = { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
46
unsigned char sym_aes_fixed_val[8] = { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 };
48
static QByteArray cat64(const QByteArray &a1, const QByteArray &a2)
50
QByteArray out = a1.copy();
51
ByteStream::appendArray(&out, a2);
55
static QByteArray xor64(const QByteArray &a1, const QByteArray &a2)
57
QByteArray out(a1.size());
58
for(uint n = 0; n < a1.size(); ++n)
59
out[n] = a1[n] ^ a2[n];
63
static QByteArray msb64(const QByteArray &a)
66
for(uint n = 0; n < 8; ++n)
71
static QByteArray lsb64(const QByteArray &a)
74
for(uint n = 0; n < 8; ++n)
79
static QByteArray get64(const QByteArray &from, uint x)
83
for(uint n = 0; n < 8; ++n)
84
out[n] = from[base+n];
88
static void set64(QByteArray *from, uint x, const QByteArray &a)
91
for(uint n = 0; n < 8; ++n)
92
(*from)[base+n] = a[n];
95
static QByteArray uintTo64(uint x)
102
out[4] = (x >> 24) & 0xff;
103
out[5] = (x >> 16) & 0xff;
104
out[6] = (x >> 8) & 0xff;
105
out[7] = (x >> 0) & 0xff;
109
bool sym_keywrap(const QByteArray &data, const Cipher::Key &key, QString *out)
112
if(x == Cipher::TripleDES) {
113
QByteArray cks = calcCMS(data);
114
QByteArray wkcks = data.copy();
115
ByteStream::appendArray(&wkcks, cks);
116
QByteArray iv = Cipher::generateIV(key.type());
118
QByteArray temp1 = Cipher::encrypt(wkcks, key, iv, false, &ok);
121
QByteArray temp2 = iv;
122
ByteStream::appendArray(&temp2, temp1);
123
QByteArray temp3(temp2.size());
124
int n2 = (int)temp2.size()-1;
125
for(int n = 0; n < (int)temp2.size(); ++n)
126
temp3[n2--] = temp2[n];
127
memcpy(iv.data(), sym_3des_fixed_iv, 8);
128
QByteArray final = Cipher::encrypt(temp3, key, iv, false, &ok);
132
*out = Base64::arrayToString(final);
135
else if(x == Cipher::AES_128 || x == Cipher::AES_256) {
137
QByteArray work = data.copy();
138
int n = work.size() / 8;
146
memcpy(val.data(), sym_aes_fixed_val, 8);
148
c = Cipher::encrypt(cat64(val, work), key, QByteArray(), false, &ok);
155
memcpy(a.data(), sym_aes_fixed_val, 8);
157
for(int j = 0; j <= 5; ++j) {
158
for(int i = 1; i <= n; ++i) {
159
uint t = i + (j * n);
161
QByteArray b = Cipher::encrypt(cat64(a, get64(r, i)), key, QByteArray(), false, &ok);
164
a = xor64(uintTo64(t), msb64(b));
165
set64(&r, i, lsb64(b));
170
ByteStream::appendArray(&c, r);
173
*out = Base64::arrayToString(c);
180
bool sym_keyunwrap(const QString &str, const Cipher::Key &key, QByteArray *out)
183
QByteArray data = Base64::stringToArray(str);
184
if(x == Cipher::TripleDES) {
186
memcpy(iv.data(), sym_3des_fixed_iv, 8);
188
QByteArray temp3 = Cipher::decrypt(data, key, iv, false, &ok);
191
QByteArray temp2(temp3.size());
192
int n2 = (int)temp3.size()-1;
193
for(int n = 0; n < (int)temp3.size(); ++n)
194
temp2[n2--] = temp3[n];
195
if((int)temp2.size() < 8)
197
iv = ByteStream::takeArray(&temp2, 8);
198
QByteArray temp1 = temp2;
199
QByteArray wkcks = Cipher::decrypt(temp1, key, iv, false, &ok);
202
if((int)wkcks.size() < 8)
204
QByteArray wk = ByteStream::takeArray(&wkcks, wkcks.size() - 8);
205
QByteArray cks = wkcks;
206
QByteArray t = calcCMS(wk);
208
if(cks.size() != t.size())
210
for(int n = 0; n < (int)t.size(); ++n) {
217
else if(x == Cipher::AES_128 || x == Cipher::AES_256) {
219
QByteArray work = data.copy();
222
int n = (work.size() / 8) - 1;
229
QByteArray b = Cipher::decrypt(work, key, QByteArray(), false, &ok);
232
ByteStream::appendArray(&p, lsb64(b));
236
a = ByteStream::takeArray(&work, 8);
238
for(int j = 5; j >= 0; --j) {
239
for(int i = n; i >= 1; --i) {
240
uint t = i + (j * n);
241
QByteArray ta = xor64(uintTo64(t), a);
243
QByteArray b = Cipher::decrypt(cat64(ta, get64(r, i)), key, QByteArray(), false, &ok);
247
set64(&r, i, lsb64(b));
254
for(int i = 0; i < 8; ++i) {
255
if((unsigned char)a[i] != sym_aes_fixed_val[i])