Coverage Report

Created: 2024-05-20 06:23

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