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