Coverage Report

Created: 2025-07-23 06:37

/src/mupdf/source/fitz/crypt-sha2.c
Line
Count
Source (jump to first uncovered line)
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
#include <string.h>
15
16
static inline int isbigendian(void)
17
278k
{
18
278k
  static const int one = 1;
19
278k
  return *(char*)&one == 0;
20
278k
}
21
22
static inline unsigned int bswap32(unsigned int num)
23
2.23M
{
24
2.23M
  return  ( (((num) << 24))
25
2.23M
    | (((num) << 8) & 0x00FF0000)
26
2.23M
    | (((num) >> 8) & 0x0000FF00)
27
2.23M
    | (((num) >> 24)) );
28
2.23M
}
29
30
static inline uint64_t bswap64(uint64_t num)
31
2.09M
{
32
2.09M
  return ( (((num) << 56))
33
2.09M
    | (((num) << 40) & 0x00FF000000000000ULL)
34
2.09M
    | (((num) << 24) & 0x0000FF0000000000ULL)
35
2.09M
    | (((num) << 8) & 0x000000FF00000000ULL)
36
2.09M
    | (((num) >> 8) & 0x00000000FF000000ULL)
37
2.09M
    | (((num) >> 24) & 0x0000000000FF0000ULL)
38
2.09M
    | (((num) >> 40) & 0x000000000000FF00ULL)
39
2.09M
    | (((num) >> 56)) );
40
2.09M
}
41
42
/* At least on x86, GCC is able to optimize this to a rotate instruction. */
43
174M
#define rotr(num, amount) ((num) >> (amount) | (num) << (8 * sizeof(num) - (amount)))
44
45
4.27M
#define blk0(i) (W[i] = data[i])
46
14.8M
#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
47
14.8M
    + s0(W[(i - 15) & 15]))
48
49
19.1M
#define Ch(x, y, z) (z ^ (x & (y ^ z)))
50
19.1M
#define Maj(x, y, z) ((x & y) | (z & (x | y)))
51
52
267k
#define a(i) T[(0 - i) & 7]
53
267k
#define b(i) T[(1 - i) & 7]
54
267k
#define c(i) T[(2 - i) & 7]
55
19.4M
#define d(i) T[(3 - i) & 7]
56
267k
#define e(i) T[(4 - i) & 7]
57
267k
#define f(i) T[(5 - i) & 7]
58
267k
#define g(i) T[(6 - i) & 7]
59
57.7M
#define h(i) T[(7 - i) & 7]
60
61
#define R(i) \
62
19.1M
  h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + K[i + j] \
63
19.1M
    + (j ? blk2(i) : blk0(i)); \
64
19.1M
  d(i) += h(i); \
65
19.1M
  h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
66
67
/* For SHA256 */
68
69
8.87M
#define S0(x) (rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22))
70
8.87M
#define S1(x) (rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25))
71
6.65M
#define s0(x) (rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3))
72
6.65M
#define s1(x) (rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10))
73
74
static 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
93
static void
94
transform256(unsigned int state[8], unsigned int data[16])
95
138k
{
96
138k
  const unsigned int *K = SHA256_K;
97
138k
  unsigned int W[16];
98
138k
  unsigned int T[8];
99
138k
  unsigned int j;
100
101
  /* ensure big-endian integers */
102
138k
  if (!isbigendian())
103
2.35M
    for (j = 0; j < 16; j++)
104
2.21M
      data[j] = bswap32(data[j]);
105
106
  /* Copy state[] to working vars. */
107
138k
  memcpy(T, state, sizeof(T));
108
109
  /* 64 operations, partially loop unrolled */
110
693k
  for (j = 0; j < 64; j += 16) {
111
554k
    R( 0); R( 1); R( 2); R( 3);
112
554k
    R( 4); R( 5); R( 6); R( 7);
113
554k
    R( 8); R( 9); R(10); R(11);
114
554k
    R(12); R(13); R(14); R(15);
115
554k
  }
116
117
  /* Add the working vars back into state[]. */
118
138k
  state[0] += a(0);
119
138k
  state[1] += b(0);
120
138k
  state[2] += c(0);
121
138k
  state[3] += d(0);
122
138k
  state[4] += e(0);
123
138k
  state[5] += f(0);
124
138k
  state[6] += g(0);
125
138k
  state[7] += h(0);
126
138k
}
127
128
#undef S0
129
#undef S1
130
#undef s0
131
#undef s1
132
133
void fz_sha256_init(fz_sha256 *context)
134
2.18k
{
135
2.18k
  context->count[0] = context->count[1] = 0;
136
137
2.18k
  context->state[0] = 0x6A09E667;
138
2.18k
  context->state[1] = 0xBB67AE85;
139
2.18k
  context->state[2] = 0x3C6EF372;
140
2.18k
  context->state[3] = 0xA54FF53A;
141
2.18k
  context->state[4] = 0x510E527F;
142
2.18k
  context->state[5] = 0x9B05688C;
143
2.18k
  context->state[6] = 0x1F83D9AB;
144
2.18k
  context->state[7] = 0x5BE0CD19;
145
2.18k
}
146
147
void fz_sha256_update(fz_sha256 *context, const unsigned char *input, size_t inlen)
148
2.30k
{
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
138k
  while (inlen > 0)
154
136k
  {
155
136k
    const unsigned int copy_start = context->count[0] & 0x3F;
156
136k
    unsigned int copy_size = 64 - copy_start;
157
136k
    if (copy_size > inlen)
158
120
      copy_size = (unsigned int)inlen;
159
160
136k
    memcpy(context->buffer.u8 + copy_start, input, copy_size);
161
162
136k
    input += copy_size;
163
136k
    inlen -= copy_size;
164
136k
    context->count[0] += copy_size;
165
    /* carry overflow from low to high */
166
136k
    if (context->count[0] < copy_size)
167
0
      context->count[1]++;
168
169
136k
    if ((context->count[0] & 0x3F) == 0)
170
136k
      transform256(context->state, context->buffer.u32);
171
136k
  }
172
2.30k
}
173
174
void fz_sha256_final(fz_sha256 *context, unsigned char digest[32])
175
2.18k
{
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
2.18k
  unsigned int j = context->count[0] & 0x3F;
179
2.18k
  context->buffer.u8[j++] = 0x80;
180
181
121k
  while (j != 56)
182
119k
  {
183
119k
    if (j == 64)
184
34
    {
185
34
      transform256(context->state, context->buffer.u32);
186
34
      j = 0;
187
34
    }
188
119k
    context->buffer.u8[j++] = 0x00;
189
119k
  }
190
191
  /* Convert the message size from bytes to bits. */
192
2.18k
  context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29);
193
2.18k
  context->count[0] = context->count[0] << 3;
194
195
2.18k
  if (!isbigendian())
196
2.18k
  {
197
2.18k
    context->buffer.u32[14] = bswap32(context->count[1]);
198
2.18k
    context->buffer.u32[15] = bswap32(context->count[0]);
199
2.18k
  }
200
0
  else
201
0
  {
202
0
    context->buffer.u32[14] = context->count[1];
203
0
    context->buffer.u32[15] = context->count[0];
204
0
  }
205
2.18k
  transform256(context->state, context->buffer.u32);
206
207
2.18k
  if (!isbigendian())
208
19.6k
    for (j = 0; j < 8; j++)
209
17.4k
      context->state[j] = bswap32(context->state[j]);
210
211
2.18k
  memcpy(digest, &context->state[0], 32);
212
2.18k
  memset(context, 0, sizeof(fz_sha256));
213
2.18k
}
214
215
/* For SHA512 */
216
217
10.2M
#define S0(x) (rotr(x, 28) ^ rotr(x, 34) ^ rotr(x, 39))
218
10.2M
#define S1(x) (rotr(x, 14) ^ rotr(x, 18) ^ rotr(x, 41))
219
8.22M
#define s0(x) (rotr(x, 1) ^ rotr(x, 8) ^ (x >> 7))
220
8.22M
#define s1(x) (rotr(x, 19) ^ rotr(x, 61) ^ (x >> 6))
221
222
static 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
265
static void
266
transform512(uint64_t state[8], uint64_t data[16])
267
128k
{
268
128k
  const uint64_t *K = SHA512_K;
269
128k
  uint64_t W[16];
270
128k
  uint64_t T[8];
271
128k
  unsigned int j;
272
273
  /* ensure big-endian integers */
274
128k
  if (!isbigendian())
275
2.18M
    for (j = 0; j < 16; j++)
276
2.05M
      data[j] = bswap64(data[j]);
277
278
  /* Copy state[] to working vars. */
279
128k
  memcpy(T, state, sizeof(T));
280
281
  /* 80 operations, partially loop unrolled */
282
770k
  for (j = 0; j < 80; j+= 16) {
283
642k
    R( 0); R( 1); R( 2); R( 3);
284
642k
    R( 4); R( 5); R( 6); R( 7);
285
642k
    R( 8); R( 9); R(10); R(11);
286
642k
    R(12); R(13); R(14); R(15);
287
642k
  }
288
289
  /* Add the working vars back into state[]. */
290
128k
  state[0] += a(0);
291
128k
  state[1] += b(0);
292
128k
  state[2] += c(0);
293
128k
  state[3] += d(0);
294
128k
  state[4] += e(0);
295
128k
  state[5] += f(0);
296
128k
  state[6] += g(0);
297
128k
  state[7] += h(0);
298
128k
}
299
300
#undef S0
301
#undef S1
302
#undef s0
303
#undef s1
304
305
void fz_sha512_init(fz_sha512 *context)
306
1.84k
{
307
1.84k
  context->count[0] = context->count[1] = 0;
308
309
1.84k
  context->state[0] = 0x6A09E667F3BCC908ull;
310
1.84k
  context->state[1] = 0xBB67AE8584CAA73Bull;
311
1.84k
  context->state[2] = 0x3C6EF372FE94F82Bull;
312
1.84k
  context->state[3] = 0xA54FF53A5F1D36F1ull;
313
1.84k
  context->state[4] = 0x510E527FADE682D1ull;
314
1.84k
  context->state[5] = 0x9B05688C2B3E6C1Full;
315
1.84k
  context->state[6] = 0x1F83D9ABFB41BD6Bull;
316
1.84k
  context->state[7] = 0x5BE0CD19137E2179ull;
317
1.84k
}
318
319
void fz_sha512_update(fz_sha512 *context, const unsigned char *input, size_t inlen)
320
3.73k
{
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
128k
  while (inlen > 0)
326
124k
  {
327
124k
    const unsigned int copy_start = context->count[0] & 0x7F;
328
124k
    unsigned int copy_size = 128 - copy_start;
329
124k
    if (copy_size > inlen)
330
0
      copy_size = (unsigned int)inlen;
331
332
124k
    memcpy(context->buffer.u8 + copy_start, input, copy_size);
333
334
124k
    input += copy_size;
335
124k
    inlen -= copy_size;
336
124k
    context->count[0] += copy_size;
337
    /* carry overflow from low to high */
338
124k
    if (context->count[0] < copy_size)
339
0
      context->count[1]++;
340
341
124k
    if ((context->count[0] & 0x7F) == 0)
342
124k
      transform512(context->state, context->buffer.u64);
343
124k
  }
344
3.73k
}
345
346
void fz_sha512_final(fz_sha512 *context, unsigned char digest[64])
347
3.73k
{
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
3.73k
  unsigned int j = context->count[0] & 0x7F;
351
3.73k
  context->buffer.u8[j++] = 0x80;
352
353
418k
  while (j != 112)
354
414k
  {
355
414k
    if (j == 128)
356
0
    {
357
0
      transform512(context->state, context->buffer.u64);
358
0
      j = 0;
359
0
    }
360
414k
    context->buffer.u8[j++] = 0x00;
361
414k
  }
362
363
  /* Convert the message size from bytes to bits. */
364
3.73k
  context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29);
365
3.73k
  context->count[0] = context->count[0] << 3;
366
367
3.73k
  if (!isbigendian())
368
3.73k
  {
369
3.73k
    context->buffer.u64[14] = bswap64(context->count[1]);
370
3.73k
    context->buffer.u64[15] = bswap64(context->count[0]);
371
3.73k
  }
372
0
  else
373
0
  {
374
0
    context->buffer.u64[14] = context->count[1];
375
0
    context->buffer.u64[15] = context->count[0];
376
0
  }
377
3.73k
  transform512(context->state, context->buffer.u64);
378
379
3.73k
  if (!isbigendian())
380
33.6k
    for (j = 0; j < 8; j++)
381
29.8k
      context->state[j] = bswap64(context->state[j]);
382
383
3.73k
  memcpy(digest, &context->state[0], 64);
384
3.73k
  memset(context, 0, sizeof(fz_sha512));
385
3.73k
}
386
387
void fz_sha384_init(fz_sha384 *context)
388
1.89k
{
389
1.89k
  context->count[0] = context->count[1] = 0;
390
391
1.89k
  context->state[0] = 0xCBBB9D5DC1059ED8ull;
392
1.89k
  context->state[1] = 0x629A292A367CD507ull;
393
1.89k
  context->state[2] = 0x9159015A3070DD17ull;
394
1.89k
  context->state[3] = 0x152FECD8F70E5939ull;
395
1.89k
  context->state[4] = 0x67332667FFC00B31ull;
396
1.89k
  context->state[5] = 0x8EB44A8768581511ull;
397
1.89k
  context->state[6] = 0xDB0C2E0D64F98FA7ull;
398
1.89k
  context->state[7] = 0x47B5481DBEFA4FA4ull;
399
1.89k
}
400
401
void fz_sha384_update(fz_sha384 *context, const unsigned char *input, size_t inlen)
402
1.89k
{
403
1.89k
  fz_sha512_update(context, input, inlen);
404
1.89k
}
405
406
void fz_sha384_final(fz_sha384 *context, unsigned char digest[64])
407
1.89k
{
408
1.89k
  fz_sha512_final(context, digest);
409
1.89k
}