ooxml_crypt 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ooxml_crypt/version.rb +1 -1
- data/vendor/cybozulib/common.mk +3 -3
- data/vendor/cybozulib/common.props +1 -1
- data/vendor/cybozulib/debug.props +1 -1
- data/vendor/cybozulib/include/cybozu/atomic.hpp +15 -5
- data/vendor/cybozulib/include/cybozu/bfd.hpp +1 -1
- data/vendor/cybozulib/include/cybozu/bit_operation.hpp +8 -10
- data/vendor/cybozulib/include/cybozu/crypto.hpp +59 -5
- data/vendor/cybozulib/include/cybozu/endian.hpp +0 -2
- data/vendor/cybozulib/include/cybozu/inttype.hpp +17 -3
- data/vendor/cybozulib/include/cybozu/link_libeay32.hpp +1 -1
- data/vendor/cybozulib/include/cybozu/link_mpir.hpp +1 -1
- data/vendor/cybozulib/include/cybozu/link_ssleay32.hpp +1 -1
- data/vendor/cybozulib/include/cybozu/random_generator.hpp +1 -0
- data/vendor/cybozulib/include/cybozu/sha2.hpp +102 -0
- data/vendor/cybozulib/sample/proj/ssl_smpl/ssl_smpl.vcxproj +1 -1
- data/vendor/cybozulib/sample/proj/stacktrace_smpl/stacktrace_smpl.vcxproj +1 -1
- data/vendor/cybozulib/test/Makefile +3 -3
- data/vendor/cybozulib/test/base/proj/array_test/array_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/atoi_test/atoi_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/atomic_test/atomic_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/base64_test/base64_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/condition_variable_cs_test/condition_variable_cs_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/condition_variable_test/condition_variable_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/config_test/config_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/csv_test/csv_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/endian_test/endian_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/env_test/env_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/event_test/event_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/file_test/file_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/itoa_test/itoa_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/mecab_test/mecab_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/minixml_test/minixml_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/mmap_test/mmap_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/serializer_test/serializer_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/sha1_test/sha1_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/stream_test/stream_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/string_operation_test/string_operation_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/string_test/string_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/thread_test/thread_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/time_test/time_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/tls_test/tls_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/proj/zlib_test/zlib_test.vcxproj +1 -1
- data/vendor/cybozulib/test/base/sha2_test.cpp +1 -1
- data/vendor/cybozulib/test/base/zlib_test.cpp +2 -0
- data/vendor/msoffice/Makefile +2 -2
- data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
- data/vendor/msoffice/common.mk +11 -6
- data/vendor/msoffice/common.props +25 -25
- data/vendor/msoffice/debug.props +13 -13
- data/vendor/msoffice/include/crypto_util.hpp +454 -450
- data/vendor/msoffice/readme.md +2 -0
- data/vendor/msoffice/release.props +27 -27
- data/vendor/msoffice/test/Makefile +4 -1
- data/vendor/msoffice/test/proj/cfb/cfb_test.vcxproj +89 -89
- data/vendor/msoffice/test/proj/hash/hash_test.vcxproj +89 -89
- data/vendor/msoffice/test_all.py +4 -4
- metadata +7 -7
|
@@ -1,450 +1,454 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
/**
|
|
3
|
-
@file
|
|
4
|
-
Copyright (C) 2012 Cybozu Labs, Inc., all rights reserved.
|
|
5
|
-
*/
|
|
6
|
-
#include "util.hpp"
|
|
7
|
-
#include <cybozu/crypto.hpp>
|
|
8
|
-
#include <cybozu/stream.hpp>
|
|
9
|
-
#include <cybozu/string.hpp>
|
|
10
|
-
#include <cybozu/minixml.hpp>
|
|
11
|
-
#include <cybozu/endian.hpp>
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
#ifdef
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
#
|
|
57
|
-
cybozu::crypto::Hash
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
printf("
|
|
119
|
-
printf("
|
|
120
|
-
printf("
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
hashName = cybozu::crypto::Hash::
|
|
158
|
-
} else if (hashNameStr == "
|
|
159
|
-
hashName = cybozu::crypto::Hash::
|
|
160
|
-
} else {
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
case cybozu::crypto::Hash::
|
|
193
|
-
hashSize =
|
|
194
|
-
hashNameStr = "
|
|
195
|
-
break;
|
|
196
|
-
case cybozu::crypto::Hash::
|
|
197
|
-
hashSize =
|
|
198
|
-
hashNameStr = "
|
|
199
|
-
break;
|
|
200
|
-
case cybozu::crypto::Hash::
|
|
201
|
-
hashSize =
|
|
202
|
-
hashNameStr = "
|
|
203
|
-
break;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
#
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
std::string
|
|
231
|
-
std::string
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
printf("
|
|
283
|
-
puts("
|
|
284
|
-
|
|
285
|
-
printf("
|
|
286
|
-
printf("
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
if (
|
|
301
|
-
throw cybozu::Exception("ms:
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
//
|
|
327
|
-
const cybozu::minixml::Node *
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
"
|
|
361
|
-
"
|
|
362
|
-
"
|
|
363
|
-
"
|
|
364
|
-
"
|
|
365
|
-
"
|
|
366
|
-
"
|
|
367
|
-
"
|
|
368
|
-
"
|
|
369
|
-
"
|
|
370
|
-
"
|
|
371
|
-
"
|
|
372
|
-
"
|
|
373
|
-
"
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
enc64(
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
1
|
+
#pragma once
|
|
2
|
+
/**
|
|
3
|
+
@file
|
|
4
|
+
Copyright (C) 2012 Cybozu Labs, Inc., all rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
#include "util.hpp"
|
|
7
|
+
#include <cybozu/crypto.hpp>
|
|
8
|
+
#include <cybozu/stream.hpp>
|
|
9
|
+
#include <cybozu/string.hpp>
|
|
10
|
+
#include <cybozu/minixml.hpp>
|
|
11
|
+
#include <cybozu/endian.hpp>
|
|
12
|
+
#if CYBOZU_HOST == CYBOZU_HOST_INTEL
|
|
13
|
+
// #define USE_CUSTOM_SHA1
|
|
14
|
+
#endif
|
|
15
|
+
#ifdef USE_CUSTOM_SHA1
|
|
16
|
+
#include "custom_sha1.hpp"
|
|
17
|
+
#endif
|
|
18
|
+
//#define DEBUG_CLK
|
|
19
|
+
|
|
20
|
+
#ifdef DEBUG_CLK
|
|
21
|
+
#define XBYAK_NO_OP_NAMES
|
|
22
|
+
#include <xbyak/xbyak_util.h>
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
namespace ms {
|
|
26
|
+
|
|
27
|
+
// [OFFCRYPTO] 2.3.4.13 encryptedVerifierHashInput step 2
|
|
28
|
+
static const std::string blkKey_VerifierHashInput("\xfe" "\xa7" "\xd2" "\x76" "\x3b" "\x4b" "\x9e" "\x79", 8);
|
|
29
|
+
// [OFFCRYPTO] 2.3.4.13 encryptedVerifierHashValue step 2
|
|
30
|
+
static const std::string blkKey_encryptedVerifierHashValue("\xd7" "\xaa" "\x0f" "\x6d" "\x30" "\x61" "\x34" "\x4e", 8);
|
|
31
|
+
// [OFFCRYPTO] 2.3.4.13 encryptedKeyValue step 2
|
|
32
|
+
static const std::string blkKey_encryptedKeyValue("\x14" "\x6e" "\x0b" "\xe7" "\xab" "\xac" "\xd0" "\xd6", 8);
|
|
33
|
+
// [OFFCRYPTO] 2.3.4.14 DataIntegrity Generation step 3
|
|
34
|
+
static const std::string blkKey_dataIntegrity1("\x5f" "\xb2" "\xad" "\x01" "\x0c" "\xb9" "\xe1" "\xf6", 8);
|
|
35
|
+
// [OFFCRYPTO] 2.3.4.14 DataIntegrity Generation step 6
|
|
36
|
+
static const std::string blkKey_dataIntegrity2("\xa0" "\x67" "\x7f" "\x02" "\xb2" "\x2c" "\x84" "\x33", 8);
|
|
37
|
+
|
|
38
|
+
inline void normalizeKey(std::string& key, size_t keySize)
|
|
39
|
+
{
|
|
40
|
+
key.resize(keySize, char(0x36));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#ifdef DEBUG_CLK
|
|
44
|
+
Xbyak::util::Clock clk;
|
|
45
|
+
struct XXX {
|
|
46
|
+
~XXX()
|
|
47
|
+
{
|
|
48
|
+
printf("%.1f Mclk\n", clk.getClock() / double(clk.getCount()) * 1e-6);
|
|
49
|
+
}
|
|
50
|
+
} xxx;
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
inline std::string hashPassword(cybozu::crypto::Hash::Name name, const std::string& salt, const std::string& pass, int spinCount)
|
|
55
|
+
{
|
|
56
|
+
#ifdef USE_CUSTOM_SHA1
|
|
57
|
+
if (name != cybozu::crypto::Hash::N_SHA1) {
|
|
58
|
+
throw cybozu::Exception("hashPassword") << "not support" << cybozu::crypto::Hash::getName(name);
|
|
59
|
+
}
|
|
60
|
+
#endif
|
|
61
|
+
cybozu::crypto::Hash s(name);
|
|
62
|
+
std::string h = s.digest(salt + pass);
|
|
63
|
+
#ifdef DEBUG_CLK
|
|
64
|
+
clk.begin();
|
|
65
|
+
#endif
|
|
66
|
+
#ifdef USE_CUSTOM_SHA1
|
|
67
|
+
assert(h.size() == 20);
|
|
68
|
+
CustomSha1::digest(&h[0], spinCount);
|
|
69
|
+
#else
|
|
70
|
+
for (int i = 0; i < spinCount; i++) {
|
|
71
|
+
char iter[4];
|
|
72
|
+
cybozu::Set32bitAsLE(iter, i);
|
|
73
|
+
s.update(iter, sizeof(iter));
|
|
74
|
+
s.digest(&h[0], &h[0], h.size());
|
|
75
|
+
}
|
|
76
|
+
#endif
|
|
77
|
+
#ifdef DEBUG_CLK
|
|
78
|
+
clk.end();
|
|
79
|
+
#endif
|
|
80
|
+
return h;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#ifdef SHA1_USE_SIMD
|
|
84
|
+
template<int n>
|
|
85
|
+
inline void sha1PasswordX(std::string out[n], const std::string& salt, const std::string pass[n], int spinCount)
|
|
86
|
+
{
|
|
87
|
+
for (int i = 0; i < n; i++) {
|
|
88
|
+
out[i] = cybozu::crypto::Hash::digest(cybozu::crypto::Hash::N_SHA1, salt + pass[i]);
|
|
89
|
+
}
|
|
90
|
+
CustomSha1::digestX<n>(out, spinCount);
|
|
91
|
+
}
|
|
92
|
+
#endif
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
[MS-OFFCRYPTO] 2.3.4.10
|
|
96
|
+
*/
|
|
97
|
+
struct CipherParam {
|
|
98
|
+
cybozu::crypto::Cipher::Name cipherName;
|
|
99
|
+
std::string cipherNameStr;
|
|
100
|
+
size_t saltSize;
|
|
101
|
+
size_t blockSize;
|
|
102
|
+
size_t keyBits;
|
|
103
|
+
|
|
104
|
+
cybozu::crypto::Hash::Name hashName;
|
|
105
|
+
std::string hashNameStr;
|
|
106
|
+
int hashSize;
|
|
107
|
+
std::string saltValue;
|
|
108
|
+
|
|
109
|
+
CipherParam()
|
|
110
|
+
: saltSize(0)
|
|
111
|
+
, blockSize(0)
|
|
112
|
+
, keyBits(0)
|
|
113
|
+
, hashSize(0)
|
|
114
|
+
{
|
|
115
|
+
}
|
|
116
|
+
void put() const
|
|
117
|
+
{
|
|
118
|
+
printf("cipherName = %s\n", cipherNameStr.c_str());
|
|
119
|
+
printf("saltSize = %d\n", (int)saltSize);
|
|
120
|
+
printf("blockSize = %d\n", (int)blockSize);
|
|
121
|
+
printf("keyBits = %d\n", (int)keyBits);
|
|
122
|
+
printf("hashName = %s\n", hashNameStr.c_str());
|
|
123
|
+
printf("hashSize = %d\n", hashSize);
|
|
124
|
+
printf("saltValue = "); dump(saltValue, false);
|
|
125
|
+
}
|
|
126
|
+
explicit CipherParam(const cybozu::minixml::Node *node)
|
|
127
|
+
{
|
|
128
|
+
setByXml(node);
|
|
129
|
+
}
|
|
130
|
+
void setByXml(const cybozu::minixml::Node *node)
|
|
131
|
+
{
|
|
132
|
+
saltSize = cybozu::atoi(node->attr["saltSize"]);
|
|
133
|
+
blockSize = cybozu::atoi(node->attr["blockSize"]);
|
|
134
|
+
keyBits = cybozu::atoi(node->attr["keyBits"]);
|
|
135
|
+
hashSize = cybozu::atoi(node->attr["hashSize"]);
|
|
136
|
+
saltValue = dec64(node->attr["saltValue"]);
|
|
137
|
+
|
|
138
|
+
if (saltSize < 1 || saltSize > 65536) {
|
|
139
|
+
throw cybozu::Exception("ms:CipherParam:saltSize") << saltSize;
|
|
140
|
+
}
|
|
141
|
+
if (blockSize < 2 || blockSize > 4096 || (blockSize & 1)) {
|
|
142
|
+
throw cybozu::Exception("ms:CipherParam:blockSize") << blockSize;
|
|
143
|
+
}
|
|
144
|
+
const std::string& chaining = node->attr["cipherChaining"];
|
|
145
|
+
cipherNameStr = node->attr["cipherAlgorithm"];
|
|
146
|
+
|
|
147
|
+
if (cipherNameStr == "AES" && keyBits == 128 && chaining == "ChainingModeCBC") {
|
|
148
|
+
cipherName = cybozu::crypto::Cipher::N_AES128_CBC;
|
|
149
|
+
} else if (cipherNameStr == "AES" && keyBits == 256 && chaining == "ChainingModeCBC") {
|
|
150
|
+
cipherName = cybozu::crypto::Cipher::N_AES256_CBC;
|
|
151
|
+
} else {
|
|
152
|
+
throw cybozu::Exception("ms:CipherParam:cipherNameStr") << cipherNameStr << keyBits << chaining;
|
|
153
|
+
}
|
|
154
|
+
hashNameStr = node->attr["hashAlgorithm"];
|
|
155
|
+
|
|
156
|
+
if (hashNameStr == "SHA1" && hashSize == 20) {
|
|
157
|
+
hashName = cybozu::crypto::Hash::N_SHA1;
|
|
158
|
+
} else if (hashNameStr == "SHA256" && hashSize == 32) {
|
|
159
|
+
hashName = cybozu::crypto::Hash::N_SHA256;
|
|
160
|
+
} else if (hashNameStr == "SHA384" && hashSize == 48) {
|
|
161
|
+
hashName = cybozu::crypto::Hash::N_SHA384;
|
|
162
|
+
} else if (hashNameStr == "SHA512" && hashSize == 64) {
|
|
163
|
+
hashName = cybozu::crypto::Hash::N_SHA512;
|
|
164
|
+
} else {
|
|
165
|
+
throw cybozu::Exception("ms:CipherParam:hashNameStr") << hashNameStr << hashSize;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
void setByName(cybozu::crypto::Cipher::Name cipherName, cybozu::crypto::Hash::Name hashName)
|
|
169
|
+
{
|
|
170
|
+
this->cipherName = cipherName;
|
|
171
|
+
this->hashName = hashName;
|
|
172
|
+
|
|
173
|
+
switch (cipherName) {
|
|
174
|
+
case cybozu::crypto::Cipher::N_AES128_CBC:
|
|
175
|
+
saltSize = 16;
|
|
176
|
+
blockSize = 16;
|
|
177
|
+
keyBits = 128;
|
|
178
|
+
cipherNameStr = "AES";
|
|
179
|
+
break;
|
|
180
|
+
case cybozu::crypto::Cipher::N_AES256_CBC:
|
|
181
|
+
saltSize = 16;
|
|
182
|
+
blockSize = 16;
|
|
183
|
+
keyBits = 256;
|
|
184
|
+
cipherNameStr = "AES";
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
throw cybozu::Exception("ms:CipherParam:not support cipherName") << cipherName;
|
|
188
|
+
}
|
|
189
|
+
if (saltSize == 0 || saltSize > 65536) throw cybozu::Exception("ms:CipherParam:setByName:bad saltSize") << saltSize;
|
|
190
|
+
|
|
191
|
+
switch (hashName) {
|
|
192
|
+
case cybozu::crypto::Hash::N_SHA1:
|
|
193
|
+
hashSize = 20;
|
|
194
|
+
hashNameStr = "SHA1";
|
|
195
|
+
break;
|
|
196
|
+
case cybozu::crypto::Hash::N_SHA256:
|
|
197
|
+
hashSize = 32;
|
|
198
|
+
hashNameStr = "SHA256";
|
|
199
|
+
break;
|
|
200
|
+
case cybozu::crypto::Hash::N_SHA384:
|
|
201
|
+
hashSize = 48;
|
|
202
|
+
hashNameStr = "SHA384";
|
|
203
|
+
break;
|
|
204
|
+
case cybozu::crypto::Hash::N_SHA512:
|
|
205
|
+
hashSize = 64;
|
|
206
|
+
hashNameStr = "SHA512";
|
|
207
|
+
break;
|
|
208
|
+
default:
|
|
209
|
+
throw cybozu::Exception("ms:CipherParam:setByName:not support hash") << hashName;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
} // ms
|
|
215
|
+
|
|
216
|
+
#include "standard_encryption.hpp"
|
|
217
|
+
|
|
218
|
+
namespace ms {
|
|
219
|
+
|
|
220
|
+
#ifdef __GNUC__ // defined in sys/sysmacros.h
|
|
221
|
+
#undef major
|
|
222
|
+
#undef minor
|
|
223
|
+
#endif
|
|
224
|
+
struct EncryptionInfo {
|
|
225
|
+
int spinCount;
|
|
226
|
+
uint16_t major;
|
|
227
|
+
uint16_t minor;
|
|
228
|
+
cybozu::MiniXml xml;
|
|
229
|
+
CipherParam keyData;
|
|
230
|
+
std::string encryptedHmacKey;
|
|
231
|
+
std::string encryptedHmacValue;
|
|
232
|
+
CipherParam encryptedKey;
|
|
233
|
+
std::string encryptedVerifierHashInput;
|
|
234
|
+
std::string encryptedVerifierHashValue;
|
|
235
|
+
std::string encryptedKeyValue;
|
|
236
|
+
// for LibreOffice
|
|
237
|
+
bool isStandardEncryption;
|
|
238
|
+
EncryptionHeader seHeader;
|
|
239
|
+
EncryptionVerifier seVerifier;
|
|
240
|
+
|
|
241
|
+
EncryptionInfo()
|
|
242
|
+
: spinCount(0)
|
|
243
|
+
, major(0)
|
|
244
|
+
, minor(0)
|
|
245
|
+
, isStandardEncryption(false)
|
|
246
|
+
{
|
|
247
|
+
}
|
|
248
|
+
explicit EncryptionInfo(const std::string& data)
|
|
249
|
+
: spinCount(0)
|
|
250
|
+
, major(0)
|
|
251
|
+
, minor(0)
|
|
252
|
+
, isStandardEncryption(false)
|
|
253
|
+
{
|
|
254
|
+
if (data.size() < 8) {
|
|
255
|
+
throw cybozu::Exception("ms:EncryptionInfo:data.size") << data.size();
|
|
256
|
+
}
|
|
257
|
+
const char *p = &data[0];
|
|
258
|
+
major = cybozu::Get16bitAsLE(p + 0);
|
|
259
|
+
minor = cybozu::Get16bitAsLE(p + 2);
|
|
260
|
+
// [MS-OFFCRYPTO] 2.3.4.10
|
|
261
|
+
if (major == 4 && minor == 4) {
|
|
262
|
+
setAgileEncryptionInfo(data);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if ((major == 3 || major == 4) && minor == 2) {
|
|
266
|
+
setStandardEncryptionInfo(data);
|
|
267
|
+
isStandardEncryption = true;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
throw cybozu::Exception("ms:EncryptionInfo:not support version") << major << minor;
|
|
271
|
+
}
|
|
272
|
+
void put() const
|
|
273
|
+
{
|
|
274
|
+
if (!isDebug(0)) return;
|
|
275
|
+
printf("major = %d\n", major);
|
|
276
|
+
printf("minor = %d\n", minor);
|
|
277
|
+
printf("isStandardEncryption = %d\n", isStandardEncryption);
|
|
278
|
+
if (isStandardEncryption) {
|
|
279
|
+
seHeader.put();
|
|
280
|
+
seVerifier.put();
|
|
281
|
+
} else {
|
|
282
|
+
printf("spinCount = %d\n", spinCount);
|
|
283
|
+
puts("keyData");
|
|
284
|
+
keyData.put();
|
|
285
|
+
printf("encryptedHmacKey = "); dump(encryptedHmacKey, false);
|
|
286
|
+
printf("encryptedHmacValue = "); dump(encryptedHmacValue, false);
|
|
287
|
+
puts("encryptedKey");
|
|
288
|
+
encryptedKey.put();
|
|
289
|
+
printf("encryptedVerifierHashInput = "); dump(encryptedVerifierHashInput, false);
|
|
290
|
+
printf("encryptedVerifierHashValue = "); dump(encryptedVerifierHashValue, false);
|
|
291
|
+
printf("encryptedKeyValue = "); dump(encryptedKeyValue, false);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
void setStandardEncryptionInfo(const std::string& data)
|
|
296
|
+
{
|
|
297
|
+
const size_t encryptionHeaderSizePos = 8;
|
|
298
|
+
size_t dataSize = data.size();
|
|
299
|
+
const char *p = data.c_str();
|
|
300
|
+
if (dataSize < encryptionHeaderSizePos + 4) {
|
|
301
|
+
throw cybozu::Exception("ms:StandardEncryption2007Info:bad data size") << dataSize;
|
|
302
|
+
}
|
|
303
|
+
const uint32_t encryptionHeaderSize = cybozu::Get32bitAsLE(p + encryptionHeaderSizePos);
|
|
304
|
+
if (encryptionHeaderSize > dataSize) {
|
|
305
|
+
throw cybozu::Exception("ms:setStandardEncryptionInfo:bad size") << encryptionHeaderSize << dataSize;
|
|
306
|
+
}
|
|
307
|
+
p += encryptionHeaderSizePos + 4;
|
|
308
|
+
dataSize -= encryptionHeaderSizePos + 4;
|
|
309
|
+
seHeader.analyze(p, encryptionHeaderSize);
|
|
310
|
+
seHeader.put();
|
|
311
|
+
|
|
312
|
+
p += encryptionHeaderSize;
|
|
313
|
+
dataSize -= encryptionHeaderSize;
|
|
314
|
+
printf("dataSize=%u\n", (uint32_t)dataSize);
|
|
315
|
+
seVerifier.analyze(p, dataSize);
|
|
316
|
+
seVerifier.put();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
void setAgileEncryptionInfo(const std::string& data)
|
|
320
|
+
{
|
|
321
|
+
const char *p = &data[0];
|
|
322
|
+
const uint32_t reserved = cybozu::Get32bitAsLE(p + 4);
|
|
323
|
+
MS_ASSERT_EQUAL(reserved, 0x40u);
|
|
324
|
+
xml.parse(p + 8, p + data.size());
|
|
325
|
+
|
|
326
|
+
// keyData
|
|
327
|
+
const cybozu::minixml::Node *keyDataNode = xml.get().getFirstTagByName("keyData");
|
|
328
|
+
if (keyDataNode == 0) throw cybozu::Exception("ms:EncryptionInfo:no keyData");
|
|
329
|
+
keyData.setByXml(keyDataNode);
|
|
330
|
+
// dataIntegrity
|
|
331
|
+
const cybozu::minixml::Node *dataIntegrity = xml.get().getFirstTagByName("dataIntegrity");
|
|
332
|
+
if (dataIntegrity == 0) throw cybozu::Exception("ms:EncryptionInfo:no dataIntegrity");
|
|
333
|
+
encryptedHmacKey = dec64(dataIntegrity->attr["encryptedHmacKey"]);
|
|
334
|
+
encryptedHmacValue = dec64(dataIntegrity->attr["encryptedHmacValue"]);
|
|
335
|
+
|
|
336
|
+
// keyEncryptor
|
|
337
|
+
const cybozu::minixml::Node *encryptedKeyNode = xml.get().getFirstTagByName("p:encryptedKey");
|
|
338
|
+
if (encryptedKeyNode == 0) throw cybozu::Exception("ms:EncryptionInfo:no p:encryptedKey");
|
|
339
|
+
encryptedKey.setByXml(encryptedKeyNode);
|
|
340
|
+
spinCount = cybozu::atoi(encryptedKeyNode->attr["spinCount"]);
|
|
341
|
+
encryptedVerifierHashInput = dec64(encryptedKeyNode->attr["encryptedVerifierHashInput"]);
|
|
342
|
+
encryptedVerifierHashValue = dec64(encryptedKeyNode->attr["encryptedVerifierHashValue"]);
|
|
343
|
+
encryptedKeyValue = dec64(encryptedKeyNode->attr["encryptedKeyValue"]);
|
|
344
|
+
}
|
|
345
|
+
std::string addHeader(const std::string& xmlStr) const
|
|
346
|
+
{
|
|
347
|
+
char buf[8];
|
|
348
|
+
const uint16_t major = 4;
|
|
349
|
+
const uint16_t minor = 4;
|
|
350
|
+
const uint32_t reserved = 0x40u;
|
|
351
|
+
cybozu::Set16bitAsLE(buf + 0, major);
|
|
352
|
+
cybozu::Set16bitAsLE(buf + 2, minor);
|
|
353
|
+
cybozu::Set32bitAsLE(buf + 4, reserved);
|
|
354
|
+
return std::string(buf, sizeof(buf)) + xmlStr;
|
|
355
|
+
}
|
|
356
|
+
std::string toXml(bool isOffice2013 = false) const
|
|
357
|
+
{
|
|
358
|
+
char buf[2048];
|
|
359
|
+
CYBOZU_SNPRINTF(buf, sizeof(buf),
|
|
360
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
|
361
|
+
"<encryption xmlns=\"http://schemas.microsoft.com/office/2006/encryption\""
|
|
362
|
+
" xmlns:p=\"http://schemas.microsoft.com/office/2006/keyEncryptor/password\""
|
|
363
|
+
// " xmlns:c=\"http://schemas.microsoft.com/office/2006/keyEncryptor/certificate\""
|
|
364
|
+
"%s"
|
|
365
|
+
">"
|
|
366
|
+
"<keyData saltSize=\"%d\" blockSize=\"%d\" keyBits=\"%d\" hashSize=\"%d\""
|
|
367
|
+
" cipherAlgorithm=\"%s\" cipherChaining=\"ChainingModeCBC\" hashAlgorithm=\"%s\""
|
|
368
|
+
" saltValue=\"%s\"/>"
|
|
369
|
+
"<dataIntegrity encryptedHmacKey=\"%s\""
|
|
370
|
+
" encryptedHmacValue=\"%s\"/><keyEncryptors>"
|
|
371
|
+
"<keyEncryptor uri=\"http://schemas.microsoft.com/office/2006/keyEncryptor/password\">"
|
|
372
|
+
"<p:encryptedKey spinCount=\"%d\" saltSize=\"%d\" blockSize=\"%d\" keyBits=\"%d\" hashSize=\"%d\""
|
|
373
|
+
" cipherAlgorithm=\"%s\" cipherChaining=\"ChainingModeCBC\" hashAlgorithm=\"%s\""
|
|
374
|
+
" saltValue=\"%s\""
|
|
375
|
+
" encryptedVerifierHashInput=\"%s\""
|
|
376
|
+
" encryptedVerifierHashValue=\"%s\""
|
|
377
|
+
" encryptedKeyValue=\"%s\"/></keyEncryptor></keyEncryptors></encryption>",
|
|
378
|
+
isOffice2013 ? " xmlns:c=\"http://schemas.microsoft.com/office/2006/keyEncryptor/certificate\"" : "",
|
|
379
|
+
int(keyData.saltSize), int(keyData.blockSize), int(keyData.keyBits), int(keyData.hashSize),
|
|
380
|
+
keyData.cipherNameStr.c_str(), keyData.hashNameStr.c_str(),
|
|
381
|
+
enc64(keyData.saltValue).c_str(),
|
|
382
|
+
enc64(encryptedHmacKey).c_str(),
|
|
383
|
+
enc64(encryptedHmacValue).c_str(),
|
|
384
|
+
spinCount,
|
|
385
|
+
int(encryptedKey.saltSize), int(encryptedKey.blockSize), int(encryptedKey.keyBits), int(encryptedKey.hashSize),
|
|
386
|
+
encryptedKey.cipherNameStr.c_str(), encryptedKey.hashNameStr.c_str(),
|
|
387
|
+
enc64(encryptedKey.saltValue).c_str(),
|
|
388
|
+
enc64(encryptedVerifierHashInput).c_str(),
|
|
389
|
+
enc64(encryptedVerifierHashValue).c_str(),
|
|
390
|
+
enc64(encryptedKeyValue).c_str()
|
|
391
|
+
);
|
|
392
|
+
return buf;
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
inline std::string cipher(cybozu::crypto::Cipher::Name name, const char *msg, size_t msgLen, const std::string& key, const std::string& iv, cybozu::crypto::Cipher::Mode mode)
|
|
397
|
+
{
|
|
398
|
+
cybozu::crypto::Cipher cipher(name);
|
|
399
|
+
cipher.setup(mode, key, iv);
|
|
400
|
+
|
|
401
|
+
std::string ret;
|
|
402
|
+
ret.resize(msgLen + 128/* margin */);
|
|
403
|
+
|
|
404
|
+
const size_t roundMsgLen = msgLen & ~15;
|
|
405
|
+
|
|
406
|
+
if (roundMsgLen > 0) {
|
|
407
|
+
int writeSize = cipher.update(&ret[0], msg, (int)roundMsgLen);
|
|
408
|
+
if (writeSize < 0) {
|
|
409
|
+
throw cybozu::Exception("ms:cipher:update");
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const int remainSize = int(msgLen - roundMsgLen);
|
|
413
|
+
if (remainSize > 0) {
|
|
414
|
+
std::string remain(msg + roundMsgLen, remainSize);
|
|
415
|
+
remain.resize(16);
|
|
416
|
+
int writeSize = cipher.update(&ret[roundMsgLen], &remain[0], 16);
|
|
417
|
+
if (writeSize < 0) {
|
|
418
|
+
throw cybozu::Exception("ms:cipher:update:remain");
|
|
419
|
+
}
|
|
420
|
+
ret.resize(roundMsgLen + 16);
|
|
421
|
+
} else {
|
|
422
|
+
ret.resize(msgLen);
|
|
423
|
+
}
|
|
424
|
+
return ret;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
inline std::string cipher(cybozu::crypto::Cipher::Name name, const std::string& msg, const std::string& key, const std::string& iv, cybozu::crypto::Cipher::Mode mode)
|
|
428
|
+
{
|
|
429
|
+
return cipher(name, msg.c_str(), msg.size(), key, iv, mode);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
inline std::string generateIv(const CipherParam& param, const std::string& blockKey, const std::string& salt)
|
|
433
|
+
{
|
|
434
|
+
std::string ret;
|
|
435
|
+
if (blockKey.empty()) {
|
|
436
|
+
ret = salt;
|
|
437
|
+
} else {
|
|
438
|
+
ret = cybozu::crypto::Hash::digest(param.hashName, salt + blockKey);
|
|
439
|
+
}
|
|
440
|
+
normalizeKey(ret, param.blockSize);
|
|
441
|
+
return ret;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/*
|
|
445
|
+
[MS-OFFCRYPTO] 2.3.4.11
|
|
446
|
+
*/
|
|
447
|
+
inline std::string generateKey(const CipherParam& param, const std::string& hash, const std::string& blockKey)
|
|
448
|
+
{
|
|
449
|
+
std::string ret = cybozu::crypto::Hash::digest(param.hashName, hash + blockKey);
|
|
450
|
+
normalizeKey(ret, param.keyBits / 8);
|
|
451
|
+
return ret;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
} // ms
|