Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
/*
2
This code is based on the code found from 7-Zip, which has a modified
3
version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
4
The code was modified a little to fit into liblzma and fitz.
5
6
This file has been put into the public domain.
7
You can do whatever you want with this file.
8
9
SHA-384 and SHA-512 were also taken from Crypto++ and adapted for fitz.
10
*/
11
12
#include "mupdf/fitz.h"
13
14
static inline int isbigendian(void)
15
{
16
static const int one = 1;
17
return *(char*)&one == 0;
18
}
19
20
static inline unsigned int bswap32(unsigned int num)
21
{
22
return ( (((num) << 24))
23
| (((num) << 8) & 0x00FF0000)
24
| (((num) >> 8) & 0x0000FF00)
25
| (((num) >> 24)) );
26
}
27
28
static inline uint64_t bswap64(uint64_t num)
29
{
30
return ( (((num) << 56))
31
| (((num) << 40) & 0x00FF000000000000ULL)
32
| (((num) << 24) & 0x0000FF0000000000ULL)
33
| (((num) << 8) & 0x000000FF00000000ULL)
34
| (((num) >> 8) & 0x00000000FF000000ULL)
35
| (((num) >> 24) & 0x0000000000FF0000ULL)
36
| (((num) >> 40) & 0x000000000000FF00ULL)
37
| (((num) >> 56)) );
38
}
39
40
/* At least on x86, GCC is able to optimize this to a rotate instruction. */
41
#define rotr(num, amount) ((num) >> (amount) | (num) << (8 * sizeof(num) - (amount)))
42
43
#define blk0(i) (W[i] = data[i])
44
#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
45
+ s0(W[(i - 15) & 15]))
46
47
#define Ch(x, y, z) (z ^ (x & (y ^ z)))
48
#define Maj(x, y, z) ((x & y) | (z & (x | y)))
49
50
#define a(i) T[(0 - i) & 7]
51
#define b(i) T[(1 - i) & 7]
52
#define c(i) T[(2 - i) & 7]
53
#define d(i) T[(3 - i) & 7]
54
#define e(i) T[(4 - i) & 7]
55
#define f(i) T[(5 - i) & 7]
56
#define g(i) T[(6 - i) & 7]
57
#define h(i) T[(7 - i) & 7]
58
59
#define R(i) \
60
h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + K[i + j] \
61
+ (j ? blk2(i) : blk0(i)); \
62
d(i) += h(i); \
63
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
64
65
/* For SHA256 */
66
67
#define S0(x) (rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22))
68
#define S1(x) (rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25))
69
#define s0(x) (rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3))
70
#define s1(x) (rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10))
71
72
static const unsigned int SHA256_K[64] = {
73
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
74
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
75
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
76
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
77
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
78
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
79
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
80
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
81
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
82
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
83
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
84
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
85
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
86
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
87
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
88
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
89
};
90
91
static void
92
transform256(unsigned int state[8], unsigned int data[16])
93
{
94
const unsigned int *K = SHA256_K;
95
unsigned int W[16];
96
unsigned int T[8];
97
unsigned int j;
98
99
/* ensure big-endian integers */
100
if (!isbigendian())
101
for (j = 0; j < 16; j++)
102
data[j] = bswap32(data[j]);
103
104
/* Copy state[] to working vars. */
105
memcpy(T, state, sizeof(T));
106
107
/* 64 operations, partially loop unrolled */
108
for (j = 0; j < 64; j += 16) {
109
R( 0); R( 1); R( 2); R( 3);
110
R( 4); R( 5); R( 6); R( 7);
111
R( 8); R( 9); R(10); R(11);
112
R(12); R(13); R(14); R(15);
113
}
114
115
/* Add the working vars back into state[]. */
116
state[0] += a(0);
117
state[1] += b(0);
118
state[2] += c(0);
119
state[3] += d(0);
120
state[4] += e(0);
121
state[5] += f(0);
122
state[6] += g(0);
123
state[7] += h(0);
124
}
125
126
#undef S0
127
#undef S1
128
#undef s0
129
#undef s1
130
131
void fz_sha256_init(fz_sha256 *context)
132
{
133
context->count[0] = context->count[1] = 0;
134
135
context->state[0] = 0x6A09E667;
136
context->state[1] = 0xBB67AE85;
137
context->state[2] = 0x3C6EF372;
138
context->state[3] = 0xA54FF53A;
139
context->state[4] = 0x510E527F;
140
context->state[5] = 0x9B05688C;
141
context->state[6] = 0x1F83D9AB;
142
context->state[7] = 0x5BE0CD19;
143
}
144
145
void fz_sha256_update(fz_sha256 *context, const unsigned char *input, unsigned int inlen)
146
{
147
/* Copy the input data into a properly aligned temporary buffer.
148
* This way we can be called with arbitrarily sized buffers
149
* (no need to be multiple of 64 bytes), and the code works also
150
* on architectures that don't allow unaligned memory access. */
151
while (inlen > 0)
152
{
153
const unsigned int copy_start = context->count[0] & 0x3F;
154
unsigned int copy_size = 64 - copy_start;
155
if (copy_size > inlen)
156
copy_size = inlen;
157
158
memcpy(context->buffer.u8 + copy_start, input, copy_size);
159
160
input += copy_size;
161
inlen -= copy_size;
162
context->count[0] += copy_size;
163
/* carry overflow from low to high */
164
if (context->count[0] < copy_size)
165
context->count[1]++;
166
167
if ((context->count[0] & 0x3F) == 0)
168
transform256(context->state, context->buffer.u32);
169
}
170
}
171
172
void fz_sha256_final(fz_sha256 *context, unsigned char digest[32])
173
{
174
/* Add padding as described in RFC 3174 (it describes SHA-1 but
175
* the same padding style is used for SHA-256 too). */
176
unsigned int j = context->count[0] & 0x3F;
177
context->buffer.u8[j++] = 0x80;
178
179
while (j != 56)
180
{
181
if (j == 64)
182
{
183
transform256(context->state, context->buffer.u32);
184
j = 0;
185
}
186
context->buffer.u8[j++] = 0x00;
187
}
188
189
/* Convert the message size from bytes to bits. */
190
context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29);
191
context->count[0] = context->count[0] << 3;
192
193
if (!isbigendian())
194
{
195
context->buffer.u32[14] = bswap32(context->count[1]);
196
context->buffer.u32[15] = bswap32(context->count[0]);
197
}
198
else
199
{
200
context->buffer.u32[14] = context->count[1];
201
context->buffer.u32[15] = context->count[0];
202
}
203
transform256(context->state, context->buffer.u32);
204
205
if (!isbigendian())
206
for (j = 0; j < 8; j++)
207
context->state[j] = bswap32(context->state[j]);
208
209
memcpy(digest, &context->state[0], 32);
210
memset(context, 0, sizeof(fz_sha256));
211
}
212
213
/* For SHA512 */
214
215
#define S0(x) (rotr(x, 28) ^ rotr(x, 34) ^ rotr(x, 39))
216
#define S1(x) (rotr(x, 14) ^ rotr(x, 18) ^ rotr(x, 41))
217
#define s0(x) (rotr(x, 1) ^ rotr(x, 8) ^ (x >> 7))
218
#define s1(x) (rotr(x, 19) ^ rotr(x, 61) ^ (x >> 6))
219
220
static const uint64_t SHA512_K[80] = {
221
0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
222
0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
223
0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
224
0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
225
0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
226
0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
227
0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
228
0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
229
0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
230
0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
231
0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
232
0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
233
0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
234
0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
235
0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
236
0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
237
0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
238
0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
239
0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
240
0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
241
0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
242
0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
243
0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
244
0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
245
0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
246
0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
247
0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
248
0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
249
0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
250
0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
251
0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
252
0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
253
0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
254
0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
255
0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
256
0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
257
0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
258
0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
259
0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
260
0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL,
261
};
262
263
static void
264
transform512(uint64_t state[8], uint64_t data[16])
265
{
266
const uint64_t *K = SHA512_K;
267
uint64_t W[16];
268
uint64_t T[8];
269
unsigned int j;
270
271
/* ensure big-endian integers */
272
if (!isbigendian())
273
for (j = 0; j < 16; j++)
274
data[j] = bswap64(data[j]);
275
276
/* Copy state[] to working vars. */
277
memcpy(T, state, sizeof(T));
278
279
/* 80 operations, partially loop unrolled */
280
for (j = 0; j < 80; j+= 16) {
281
R( 0); R( 1); R( 2); R( 3);
282
R( 4); R( 5); R( 6); R( 7);
283
R( 8); R( 9); R(10); R(11);
284
R(12); R(13); R(14); R(15);
285
}
286
287
/* Add the working vars back into state[]. */
288
state[0] += a(0);
289
state[1] += b(0);
290
state[2] += c(0);
291
state[3] += d(0);
292
state[4] += e(0);
293
state[5] += f(0);
294
state[6] += g(0);
295
state[7] += h(0);
296
}
297
298
#undef S0
299
#undef S1
300
#undef s0
301
#undef s1
302
303
void fz_sha512_init(fz_sha512 *context)
304
{
305
context->count[0] = context->count[1] = 0;
306
307
context->state[0] = 0x6A09E667F3BCC908ull;
308
context->state[1] = 0xBB67AE8584CAA73Bull;
309
context->state[2] = 0x3C6EF372FE94F82Bull;
310
context->state[3] = 0xA54FF53A5F1D36F1ull;
311
context->state[4] = 0x510E527FADE682D1ull;
312
context->state[5] = 0x9B05688C2B3E6C1Full;
313
context->state[6] = 0x1F83D9ABFB41BD6Bull;
314
context->state[7] = 0x5BE0CD19137E2179ull;
315
}
316
317
void fz_sha512_update(fz_sha512 *context, const unsigned char *input, unsigned int inlen)
318
{
319
/* Copy the input data into a properly aligned temporary buffer.
320
* This way we can be called with arbitrarily sized buffers
321
* (no need to be multiple of 128 bytes), and the code works also
322
* on architectures that don't allow unaligned memory access. */
323
while (inlen > 0)
324
{
325
const unsigned int copy_start = context->count[0] & 0x7F;
326
unsigned int copy_size = 128 - copy_start;
327
if (copy_size > inlen)
328
copy_size = inlen;
329
330
memcpy(context->buffer.u8 + copy_start, input, copy_size);
331
332
input += copy_size;
333
inlen -= copy_size;
334
context->count[0] += copy_size;
335
/* carry overflow from low to high */
336
if (context->count[0] < copy_size)
337
context->count[1]++;
338
339
if ((context->count[0] & 0x7F) == 0)
340
transform512(context->state, context->buffer.u64);
341
}
342
}
343
344
void fz_sha512_final(fz_sha512 *context, unsigned char digest[64])
345
{
346
/* Add padding as described in RFC 3174 (it describes SHA-1 but
347
* the same padding style is used for SHA-512 too). */
348
unsigned int j = context->count[0] & 0x7F;
349
context->buffer.u8[j++] = 0x80;
350
351
while (j != 112)
352
{
353
if (j == 128)
354
{
355
transform512(context->state, context->buffer.u64);
356
j = 0;
357
}
358
context->buffer.u8[j++] = 0x00;
359
}
360
361
/* Convert the message size from bytes to bits. */
362
context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29);
363
context->count[0] = context->count[0] << 3;
364
365
if (!isbigendian())
366
{
367
context->buffer.u64[14] = bswap64(context->count[1]);
368
context->buffer.u64[15] = bswap64(context->count[0]);
369
}
370
else
371
{
372
context->buffer.u64[14] = context->count[1];
373
context->buffer.u64[15] = context->count[0];
374
}
375
transform512(context->state, context->buffer.u64);
376
377
if (!isbigendian())
378
for (j = 0; j < 8; j++)
379
context->state[j] = bswap64(context->state[j]);
380
381
memcpy(digest, &context->state[0], 64);
382
memset(context, 0, sizeof(fz_sha512));
383
}
384
385
void fz_sha384_init(fz_sha384 *context)
386
{
387
context->count[0] = context->count[1] = 0;
388
389
context->state[0] = 0xCBBB9D5DC1059ED8ull;
390
context->state[1] = 0x629A292A367CD507ull;
391
context->state[2] = 0x9159015A3070DD17ull;
392
context->state[3] = 0x152FECD8F70E5939ull;
393
context->state[4] = 0x67332667FFC00B31ull;
394
context->state[5] = 0x8EB44A8768581511ull;
395
context->state[6] = 0xDB0C2E0D64F98FA7ull;
396
context->state[7] = 0x47B5481DBEFA4FA4ull;
397
}
398
399
void fz_sha384_update(fz_sha384 *context, const unsigned char *input, unsigned int inlen)
400
{
401
fz_sha512_update(context, input, inlen);
402
}
403
404
void fz_sha384_final(fz_sha384 *context, unsigned char digest[64])
405
{
406
fz_sha512_final(context, digest);
407
}
408
409