Coverage Report

Created: 2026-08-22 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/xpdf/Decrypt.cc
Line
Count
Source
1
//========================================================================
2
//
3
// Decrypt.cc
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <string.h>
12
#include "gmem.h"
13
#include "gmempp.h"
14
#include "Decrypt.h"
15
16
static void aes256KeyExpansion(DecryptAES256State *s,
17
             Guchar *objKey, int objKeyLen);
18
static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last);
19
static void sha256(Guchar *msg, int msgLen, Guchar *hash);
20
static void sha384(Guchar *msg, int msgLen, Guchar *hash);
21
static void sha512(Guchar *msg, int msgLen, Guchar *hash);
22
23
static Guchar passwordPad[32] = {
24
  0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
25
  0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 
26
  0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 
27
  0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
28
};
29
30
//------------------------------------------------------------------------
31
// Decrypt
32
//------------------------------------------------------------------------
33
34
GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
35
         GString *ownerKey, GString *userKey,
36
         GString *ownerEnc, GString *userEnc,
37
         int permissions, GString *fileID,
38
         GString *ownerPassword, GString *userPassword,
39
         Guchar *fileKey, GBool encryptMetadata,
40
1.25k
         GBool *ownerPasswordOk) {
41
1.25k
  DecryptAES256State state;
42
1.25k
  Guchar test[127 + 56], test2[32];
43
1.25k
  GString *userPassword2;
44
1.25k
  const char *userPW;
45
1.25k
  Guchar fState[256];
46
1.25k
  Guchar tmpKey[16];
47
1.25k
  Guchar fx, fy;
48
1.25k
  int len, i, j;
49
50
1.25k
  *ownerPasswordOk = gFalse;
51
52
1.25k
  if (encRevision == 5 || encRevision == 6) {
53
54
    // check the owner password
55
262
    if (ownerPassword) {
56
      //~ this is supposed to convert the password to UTF-8 using "SASLprep"
57
0
      len = ownerPassword->getLength();
58
0
      if (len > 127) {
59
0
  len = 127;
60
0
      }
61
0
      memcpy(test, ownerPassword->getCString(), len);
62
0
      memcpy(test + len, ownerKey->getCString() + 32, 8);
63
0
      memcpy(test + len + 8, userKey->getCString(), 48);
64
0
      sha256(test, len + 56, test);
65
0
      if (encRevision == 6) {
66
0
  r6Hash(test, 32, ownerPassword->getCString(), len,
67
0
         userKey->getCString());
68
0
      }
69
0
      if (!memcmp(test, ownerKey->getCString(), 32)) {
70
71
  // compute the file key from the owner password
72
0
  memcpy(test, ownerPassword->getCString(), len);
73
0
  memcpy(test + len, ownerKey->getCString() + 40, 8);
74
0
  memcpy(test + len + 8, userKey->getCString(), 48);
75
0
  sha256(test, len + 56, test);
76
0
  if (encRevision == 6) {
77
0
    r6Hash(test, 32, ownerPassword->getCString(), len,
78
0
     userKey->getCString());
79
0
  }
80
0
  aes256KeyExpansion(&state, test, 32);
81
0
  for (i = 0; i < 16; ++i) {
82
0
    state.cbc[i] = 0;
83
0
  }
84
0
  aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString(), gFalse);
85
0
  memcpy(fileKey, state.buf, 16);
86
0
  aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString() + 16,
87
0
         gFalse);
88
0
  memcpy(fileKey + 16, state.buf, 16);
89
90
0
  *ownerPasswordOk = gTrue;
91
0
  return gTrue;
92
0
      }
93
0
    }
94
95
    // check the user password
96
262
    if (userPassword) {
97
      //~ this is supposed to convert the password to UTF-8 using "SASLprep"
98
0
      userPW = userPassword->getCString();
99
0
      len = userPassword->getLength();
100
0
      if (len > 127) {
101
0
  len = 127;
102
0
      }
103
262
    } else {
104
262
      userPW = "";
105
262
      len = 0;
106
262
    }
107
262
    memcpy(test, userPW, len);
108
262
    memcpy(test + len, userKey->getCString() + 32, 8);
109
262
    sha256(test, len + 8, test);
110
262
    if (encRevision == 6) {
111
261
      r6Hash(test, 32, userPW, len, NULL);
112
261
    }
113
262
    if (!memcmp(test, userKey->getCString(), 32)) {
114
115
      // compute the file key from the user password
116
224
      memcpy(test, userPW, len);
117
224
      memcpy(test + len, userKey->getCString() + 40, 8);
118
224
      sha256(test, len + 8, test);
119
224
      if (encRevision == 6) {
120
224
  r6Hash(test, 32, userPW, len, NULL);
121
224
      }
122
224
      aes256KeyExpansion(&state, test, 32);
123
3.80k
      for (i = 0; i < 16; ++i) {
124
3.58k
  state.cbc[i] = 0;
125
3.58k
      }
126
224
      aes256DecryptBlock(&state, (Guchar *)userEnc->getCString(), gFalse);
127
224
      memcpy(fileKey, state.buf, 16);
128
224
      aes256DecryptBlock(&state, (Guchar *)userEnc->getCString() + 16,
129
224
       gFalse);
130
224
      memcpy(fileKey + 16, state.buf, 16);
131
132
224
      return gTrue; 
133
224
    }
134
135
38
    return gFalse;
136
137
991
  } else {
138
139
    // try using the supplied owner password to generate the user password
140
991
    if (ownerPassword) {
141
0
      len = ownerPassword->getLength();
142
0
      if (len < 32) {
143
0
  memcpy(test, ownerPassword->getCString(), len);
144
0
  memcpy(test + len, passwordPad, 32 - len);
145
0
      } else {
146
0
  memcpy(test, ownerPassword->getCString(), 32);
147
0
      }
148
0
      md5(test, 32, test);
149
0
      if (encRevision == 3) {
150
0
  for (i = 0; i < 50; ++i) {
151
0
    md5(test, keyLength, test);
152
0
  }
153
0
      }
154
0
      if (encRevision == 2) {
155
0
  rc4InitKey(test, keyLength, fState);
156
0
  fx = fy = 0;
157
0
  for (i = 0; i < 32; ++i) {
158
0
    test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
159
0
  }
160
0
      } else {
161
0
  memcpy(test2, ownerKey->getCString(), 32);
162
0
  for (i = 19; i >= 0; --i) {
163
0
    for (j = 0; j < keyLength; ++j) {
164
0
      tmpKey[j] = (Guchar)(test[j] ^ i);
165
0
    }
166
0
    rc4InitKey(tmpKey, keyLength, fState);
167
0
    fx = fy = 0;
168
0
    for (j = 0; j < 32; ++j) {
169
0
      test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]);
170
0
    }
171
0
  }
172
0
      }
173
0
      userPassword2 = new GString((char *)test2, 32);
174
0
      if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
175
0
           permissions, fileID, userPassword2, fileKey,
176
0
           encryptMetadata)) {
177
0
  *ownerPasswordOk = gTrue;
178
0
  delete userPassword2;
179
0
  return gTrue;
180
0
      }
181
0
      delete userPassword2;
182
0
    }
183
184
    // try using the supplied user password
185
991
    return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
186
991
      permissions, fileID, userPassword, fileKey,
187
991
      encryptMetadata);
188
991
  }
189
1.25k
}
190
191
void Decrypt::r6Hash(Guchar *key, int keyLen, const char *pwd, int pwdLen,
192
485
         char *userKey) {
193
485
  Guchar key1[64*(127+64+48)];
194
485
  DecryptAESState state128;
195
485
  int n, i, j, k;
196
197
485
  i = 0;
198
33.9k
  while (1) {
199
33.9k
    memcpy(key1, pwd, pwdLen);
200
33.9k
    memcpy(key1 + pwdLen, key, keyLen);
201
33.9k
    n = pwdLen + keyLen;
202
33.9k
    if (userKey) {
203
0
      memcpy(key1 + pwdLen + keyLen, userKey, 48);
204
0
      n += 48;
205
0
    }
206
2.17M
    for (j = 1; j < 64; ++j) {
207
2.14M
      memcpy(key1 + j * n, key1, n);
208
2.14M
    }
209
33.9k
    n *= 64;
210
33.9k
    aesKeyExpansion(&state128, key, 16, gFalse);
211
577k
    for (j = 0; j < 16; ++j) {
212
543k
      state128.cbc[j] = key[16+j];
213
543k
    }
214
6.52M
    for (j = 0; j < n; j += 16) {
215
6.48M
      aesEncryptBlock(&state128, key1 + j);
216
6.48M
      memcpy(key1 + j, state128.buf, 16);
217
6.48M
    }
218
33.9k
    k = 0;
219
577k
    for (j = 0; j < 16; ++j) {
220
543k
      k += key1[j] % 3;
221
543k
    }
222
33.9k
    k %= 3;
223
33.9k
    switch (k) {
224
11.1k
    case 0:
225
11.1k
      sha256(key1, n, key);
226
11.1k
      keyLen = 32;
227
11.1k
      break;
228
11.6k
    case 1:
229
11.6k
      sha384(key1, n, key);
230
11.6k
      keyLen = 48;
231
11.6k
      break;
232
11.1k
    case 2:
233
11.1k
      sha512(key1, n, key);
234
11.1k
      keyLen = 64;
235
11.1k
      break;
236
33.9k
    }
237
    // from the spec, it appears that i should be incremented after
238
    // the test, but that doesn't match what Adobe does
239
33.9k
    ++i;
240
33.9k
    if (i >= 64 && key1[n - 1] <= i - 32) {
241
485
      break;
242
485
    }
243
33.9k
  }
244
485
}
245
246
GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
247
          GString *ownerKey, GString *userKey,
248
          int permissions, GString *fileID,
249
          GString *userPassword, Guchar *fileKey,
250
991
          GBool encryptMetadata) {
251
991
  Guchar *buf;
252
991
  Guchar test[32];
253
991
  Guchar fState[256];
254
991
  Guchar tmpKey[16];
255
991
  Guchar fx, fy;
256
991
  int len, i, j;
257
991
  GBool ok;
258
259
  // generate file key
260
991
  buf = (Guchar *)gmalloc(72 + fileID->getLength());
261
991
  if (userPassword) {
262
0
    len = userPassword->getLength();
263
0
    if (len < 32) {
264
0
      memcpy(buf, userPassword->getCString(), len);
265
0
      memcpy(buf + len, passwordPad, 32 - len);
266
0
    } else {
267
0
      memcpy(buf, userPassword->getCString(), 32);
268
0
    }
269
991
  } else {
270
991
    memcpy(buf, passwordPad, 32);
271
991
  }
272
991
  memcpy(buf + 32, ownerKey->getCString(), 32);
273
991
  buf[64] = (Guchar)(permissions & 0xff);
274
991
  buf[65] = (Guchar)((permissions >> 8) & 0xff);
275
991
  buf[66] = (Guchar)((permissions >> 16) & 0xff);
276
991
  buf[67] = (Guchar)((permissions >> 24) & 0xff);
277
991
  memcpy(buf + 68, fileID->getCString(), fileID->getLength());
278
991
  len = 68 + fileID->getLength();
279
991
  if (!encryptMetadata) {
280
0
    buf[len++] = 0xff;
281
0
    buf[len++] = 0xff;
282
0
    buf[len++] = 0xff;
283
0
    buf[len++] = 0xff;
284
0
  }
285
991
  md5(buf, len, fileKey);
286
991
  if (encRevision == 3) {
287
11.4k
    for (i = 0; i < 50; ++i) {
288
11.2k
      md5(fileKey, keyLength, fileKey);
289
11.2k
    }
290
225
  }
291
292
  // test user password
293
991
  if (encRevision == 2) {
294
766
    rc4InitKey(fileKey, keyLength, fState);
295
766
    fx = fy = 0;
296
25.2k
    for (i = 0; i < 32; ++i) {
297
24.5k
      test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i));
298
24.5k
    }
299
766
    ok = memcmp(test, passwordPad, 32) == 0;
300
766
  } else if (encRevision == 3) {
301
225
    memcpy(test, userKey->getCString(), 32);
302
4.72k
    for (i = 19; i >= 0; --i) {
303
72.5k
      for (j = 0; j < keyLength; ++j) {
304
68.0k
  tmpKey[j] = (Guchar)(fileKey[j] ^ i);
305
68.0k
      }
306
4.50k
      rc4InitKey(tmpKey, keyLength, fState);
307
4.50k
      fx = fy = 0;
308
148k
      for (j = 0; j < 32; ++j) {
309
144k
  test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]);
310
144k
      }
311
4.50k
    }
312
225
    memcpy(buf, passwordPad, 32);
313
225
    memcpy(buf + 32, fileID->getCString(), fileID->getLength());
314
225
    md5(buf, 32 + fileID->getLength(), buf);
315
225
    ok = memcmp(test, buf, 16) == 0;
316
225
  } else {
317
0
    ok = gFalse;
318
0
  }
319
320
991
  gfree(buf);
321
991
  return ok;
322
991
}
323
324
//------------------------------------------------------------------------
325
// DecryptStream
326
//------------------------------------------------------------------------
327
328
DecryptStream::DecryptStream(Stream *strA, Guchar *fileKeyA,
329
           CryptAlgorithm algoA, int keyLengthA,
330
           int objNumA, int objGenA):
331
41.8k
  FilterStream(strA)
332
41.8k
{
333
41.8k
  int i;
334
335
41.8k
  memcpy(fileKey, fileKeyA, keyLengthA);
336
41.8k
  algo = algoA;
337
41.8k
  keyLength = keyLengthA;
338
41.8k
  objNum = objNumA;
339
41.8k
  objGen = objGenA;
340
341
  // construct object key
342
652k
  for (i = 0; i < keyLength; ++i) {
343
610k
    objKey[i] = fileKey[i];
344
610k
  }
345
41.8k
  switch (algo) {
346
20.9k
  case cryptRC4:
347
20.9k
    objKey[keyLength] = (Guchar)(objNum & 0xff);
348
20.9k
    objKey[keyLength + 1] = (Guchar)((objNum >> 8) & 0xff);
349
20.9k
    objKey[keyLength + 2] = (Guchar)((objNum >> 16) & 0xff);
350
20.9k
    objKey[keyLength + 3] = (Guchar)(objGen & 0xff);
351
20.9k
    objKey[keyLength + 4] = (Guchar)((objGen >> 8) & 0xff);
352
20.9k
    md5(objKey, keyLength + 5, objKey);
353
20.9k
    if ((objKeyLength = keyLength + 5) > 16) {
354
1.34k
      objKeyLength = 16;
355
1.34k
    }
356
20.9k
    break;
357
11.8k
  case cryptAES:
358
11.8k
    objKey[keyLength] = (Guchar)(objNum & 0xff);
359
11.8k
    objKey[keyLength + 1] = (Guchar)((objNum >> 8) & 0xff);
360
11.8k
    objKey[keyLength + 2] = (Guchar)((objNum >> 16) & 0xff);
361
11.8k
    objKey[keyLength + 3] = (Guchar)(objGen & 0xff);
362
11.8k
    objKey[keyLength + 4] = (Guchar)((objGen >> 8) & 0xff);
363
11.8k
    objKey[keyLength + 5] = 0x73; // 's'
364
11.8k
    objKey[keyLength + 6] = 0x41; // 'A'
365
11.8k
    objKey[keyLength + 7] = 0x6c; // 'l'
366
11.8k
    objKey[keyLength + 8] = 0x54; // 'T'
367
11.8k
    md5(objKey, keyLength + 9, objKey);
368
11.8k
    if ((objKeyLength = keyLength + 5) > 16) {
369
11.8k
      objKeyLength = 16;
370
11.8k
    }
371
11.8k
    break;
372
9.03k
  case cryptAES256:
373
9.03k
    objKeyLength = keyLength;
374
9.03k
    break;
375
41.8k
  }
376
41.8k
}
377
378
41.8k
DecryptStream::~DecryptStream() {
379
41.8k
  delete str;
380
41.8k
}
381
382
6.97k
Stream *DecryptStream::copy() {
383
6.97k
  return new DecryptStream(str->copy(), fileKey, algo, keyLength,
384
6.97k
         objNum, objGen);
385
6.97k
}
386
387
32.1k
void DecryptStream::reset() {
388
32.1k
  str->reset();
389
32.1k
  switch (algo) {
390
13.9k
  case cryptRC4:
391
13.9k
    state.rc4.x = state.rc4.y = 0;
392
13.9k
    rc4InitKey(objKey, objKeyLength, state.rc4.state);
393
13.9k
    state.rc4.buf = EOF;
394
13.9k
    break;
395
9.46k
  case cryptAES:
396
9.46k
    aesKeyExpansion(&state.aes, objKey, objKeyLength, gTrue);
397
9.46k
    str->getBlock((char *)state.aes.cbc, 16);
398
9.46k
    state.aes.bufIdx = 16;
399
9.46k
    break;
400
8.73k
  case cryptAES256:
401
8.73k
    aes256KeyExpansion(&state.aes256, objKey, objKeyLength);
402
8.73k
    str->getBlock((char *)state.aes256.cbc, 16);
403
8.73k
    state.aes256.bufIdx = 16;
404
8.73k
    break;
405
32.1k
  }
406
32.1k
}
407
408
8.39M
int DecryptStream::getChar() {
409
8.39M
  Guchar in[16];
410
8.39M
  int c;
411
412
8.39M
  c = EOF; // make gcc happy
413
8.39M
  switch (algo) {
414
7.14M
  case cryptRC4:
415
7.14M
    if (state.rc4.buf == EOF) {
416
7.13M
      c = str->getChar();
417
7.13M
      if (c != EOF) {
418
7.12M
  state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
419
7.12M
               &state.rc4.y, (Guchar)c);
420
7.12M
      }
421
7.13M
    }
422
7.14M
    c = state.rc4.buf;
423
7.14M
    state.rc4.buf = EOF;
424
7.14M
    break;
425
716k
  case cryptAES:
426
716k
    if (state.aes.bufIdx == 16) {
427
52.4k
      if (str->getBlock((char *)in, 16) != 16) {
428
8.52k
  return EOF;
429
8.52k
      }
430
43.9k
      aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
431
43.9k
    }
432
708k
    if (state.aes.bufIdx == 16) {
433
897
      c = EOF;
434
707k
    } else {
435
707k
      c = state.aes.buf[state.aes.bufIdx++];
436
707k
    }
437
708k
    break;
438
538k
  case cryptAES256:
439
538k
    if (state.aes256.bufIdx == 16) {
440
42.1k
      if (str->getBlock((char *)in, 16) != 16) {
441
7.65k
  return EOF;
442
7.65k
      }
443
34.4k
      aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
444
34.4k
    }
445
530k
    if (state.aes256.bufIdx == 16) {
446
918
      c = EOF;
447
529k
    } else {
448
529k
      c = state.aes256.buf[state.aes256.bufIdx++];
449
529k
    }
450
530k
    break;
451
8.39M
  }
452
8.38M
  return c;
453
8.39M
}
454
455
38.8k
int DecryptStream::lookChar() {
456
38.8k
  Guchar in[16];
457
38.8k
  int c;
458
459
38.8k
  c = EOF; // make gcc happy
460
38.8k
  switch (algo) {
461
10.9k
  case cryptRC4:
462
10.9k
    if (state.rc4.buf == EOF) {
463
10.9k
      c = str->getChar();
464
10.9k
      if (c != EOF) {
465
10.9k
  state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
466
10.9k
               &state.rc4.y, (Guchar)c);
467
10.9k
      }
468
10.9k
    }
469
10.9k
    c = state.rc4.buf;
470
10.9k
    break;
471
24.0k
  case cryptAES:
472
24.0k
    if (state.aes.bufIdx == 16) {
473
1.48k
      if (str->getBlock((char *)in, 16) != 16) {
474
10
  return EOF;
475
10
      }
476
1.47k
      aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
477
1.47k
    }
478
24.0k
    if (state.aes.bufIdx == 16) {
479
10
      c = EOF;
480
24.0k
    } else {
481
24.0k
      c = state.aes.buf[state.aes.bufIdx];
482
24.0k
    }
483
24.0k
    break;
484
3.77k
  case cryptAES256:
485
3.77k
    if (state.aes256.bufIdx == 16) {
486
242
      if (str->getBlock((char *)in, 16) != 16) {
487
15
  return EOF;
488
15
      }
489
227
      aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
490
227
    }
491
3.75k
    if (state.aes256.bufIdx == 16) {
492
10
      c = EOF;
493
3.74k
    } else {
494
3.74k
      c = state.aes256.buf[state.aes256.bufIdx];
495
3.74k
    }
496
3.75k
    break;
497
38.8k
  }
498
38.7k
  return c;
499
38.8k
}
500
501
0
GBool DecryptStream::isBinary(GBool last) {
502
0
  return str->isBinary(last);
503
0
}
504
505
//------------------------------------------------------------------------
506
// RC4-compatible decryption
507
//------------------------------------------------------------------------
508
509
19.2k
void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
510
19.2k
  Guchar index1, index2;
511
19.2k
  Guchar t;
512
19.2k
  int i;
513
514
4.94M
  for (i = 0; i < 256; ++i)
515
4.92M
    state[i] = (Guchar)i;
516
19.2k
  index1 = index2 = 0;
517
4.94M
  for (i = 0; i < 256; ++i) {
518
4.92M
    index2 = (Guchar)(key[index1] + state[i] + index2);
519
4.92M
    t = state[i];
520
4.92M
    state[i] = state[index2];
521
4.92M
    state[index2] = t;
522
4.92M
    index1 = (Guchar)((index1 + 1) % keyLen);
523
4.92M
  }
524
19.2k
}
525
526
7.29M
Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) {
527
7.29M
  Guchar x1, y1, tx, ty;
528
529
7.29M
  x1 = *x = (Guchar)(*x + 1);
530
7.29M
  y1 = *y = (Guchar)(state[*x] + *y);
531
7.29M
  tx = state[x1];
532
7.29M
  ty = state[y1];
533
7.29M
  state[x1] = ty;
534
7.29M
  state[y1] = tx;
535
7.29M
  return c ^ state[(tx + ty) % 256];
536
7.29M
}
537
538
//------------------------------------------------------------------------
539
// AES decryption
540
//------------------------------------------------------------------------
541
542
static Guchar sbox[256] = {
543
  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
544
  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
545
  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
546
  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
547
  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
548
  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
549
  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
550
  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
551
  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
552
  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
553
  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
554
  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
555
  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
556
  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
557
  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
558
  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
559
};
560
561
static Guchar invSbox[256] = {
562
  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
563
  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
564
  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
565
  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
566
  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
567
  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
568
  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
569
  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
570
  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
571
  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
572
  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
573
  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
574
  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
575
  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
576
  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
577
  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
578
};
579
580
static Guint rcon[11] = {
581
  0x00000000, // unused
582
  0x01000000,
583
  0x02000000,
584
  0x04000000,
585
  0x08000000,
586
  0x10000000,
587
  0x20000000,
588
  0x40000000,
589
  0x80000000,
590
  0x1b000000,
591
  0x36000000
592
};
593
594
551k
static inline Guint subWord(Guint x) {
595
551k
  return (sbox[x >> 24] << 24)
596
551k
         | (sbox[(x >> 16) & 0xff] << 16)
597
551k
         | (sbox[(x >> 8) & 0xff] << 8)
598
551k
         | sbox[x & 0xff];
599
551k
}
600
601
497k
static inline Guint rotWord(Guint x) {
602
497k
  return ((x << 8) & 0xffffffff) | (x >> 24);
603
497k
}
604
605
64.8M
static inline void subBytes(Guchar *state) {
606
64.8M
  int i;
607
608
1.10G
  for (i = 0; i < 16; ++i) {
609
1.03G
    state[i] = sbox[state[i]];
610
1.03G
  }
611
64.8M
}
612
613
946k
static inline void invSubBytes(Guchar *state) {
614
946k
  int i;
615
616
16.0M
  for (i = 0; i < 16; ++i) {
617
15.1M
    state[i] = invSbox[state[i]];
618
15.1M
  }
619
946k
}
620
621
64.8M
static inline void shiftRows(Guchar *state) {
622
64.8M
  Guchar t;
623
624
64.8M
  t = state[4];
625
64.8M
  state[4] = state[5];
626
64.8M
  state[5] = state[6];
627
64.8M
  state[6] = state[7];
628
64.8M
  state[7] = t;
629
630
64.8M
  t = state[8];
631
64.8M
  state[8] = state[10];
632
64.8M
  state[10] = t;
633
64.8M
  t = state[9];
634
64.8M
  state[9] = state[11];
635
64.8M
  state[11] = t;
636
637
64.8M
  t = state[15];
638
64.8M
  state[15] = state[14];
639
64.8M
  state[14] = state[13];
640
64.8M
  state[13] = state[12];
641
64.8M
  state[12] = t;
642
64.8M
}
643
644
946k
static inline void invShiftRows(Guchar *state) {
645
946k
  Guchar t;
646
647
946k
  t = state[7];
648
946k
  state[7] = state[6];
649
946k
  state[6] = state[5];
650
946k
  state[5] = state[4];
651
946k
  state[4] = t;
652
653
946k
  t = state[8];
654
946k
  state[8] = state[10];
655
946k
  state[10] = t;
656
946k
  t = state[9];
657
946k
  state[9] = state[11];
658
946k
  state[11] = t;
659
660
946k
  t = state[12];
661
946k
  state[12] = state[13];
662
946k
  state[13] = state[14];
663
946k
  state[14] = state[15];
664
946k
  state[15] = t;
665
946k
}
666
667
// {02} \cdot s
668
934M
static inline Guchar mul02(Guchar s) {
669
934M
  Guchar s2;
670
671
934M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
672
934M
  return s2;
673
934M
}
674
675
// {03} \cdot s
676
934M
static inline Guchar mul03(Guchar s) {
677
934M
  Guchar s2;
678
679
934M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
680
934M
  return s ^ s2;
681
934M
}
682
683
// {09} \cdot s
684
17.0M
static inline Guchar mul09(Guchar s) {
685
17.0M
  Guchar s2, s4, s8;
686
687
17.0M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
688
17.0M
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
689
17.0M
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
690
17.0M
  return s ^ s8;
691
17.0M
}
692
693
// {0b} \cdot s
694
17.0M
static inline Guchar mul0b(Guchar s) {
695
17.0M
  Guchar s2, s4, s8;
696
697
17.0M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
698
17.0M
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
699
17.0M
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
700
17.0M
  return s ^ s2 ^ s8;
701
17.0M
}
702
703
// {0d} \cdot s
704
17.0M
static inline Guchar mul0d(Guchar s) {
705
17.0M
  Guchar s2, s4, s8;
706
707
17.0M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
708
17.0M
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
709
17.0M
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
710
17.0M
  return s ^ s4 ^ s8;
711
17.0M
}
712
713
// {0e} \cdot s
714
17.0M
static inline Guchar mul0e(Guchar s) {
715
17.0M
  Guchar s2, s4, s8;
716
717
17.0M
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
718
17.0M
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
719
17.0M
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
720
17.0M
  return s2 ^ s4 ^ s8;
721
17.0M
}
722
723
58.3M
static inline void mixColumns(Guchar *state) {
724
58.3M
  int c;
725
58.3M
  Guchar s0, s1, s2, s3;
726
727
291M
  for (c = 0; c < 4; ++c) {
728
233M
    s0 = state[c];
729
233M
    s1 = state[4+c];
730
233M
    s2 = state[8+c];
731
233M
    s3 = state[12+c];
732
233M
    state[c] =    mul02(s0) ^ mul03(s1) ^       s2  ^       s3;
733
233M
    state[4+c] =        s0  ^ mul02(s1) ^ mul03(s2) ^       s3;
734
233M
    state[8+c] =        s0  ^       s1  ^ mul02(s2) ^ mul03(s3);
735
233M
    state[12+c] = mul03(s0) ^       s1  ^       s2  ^ mul02(s3);
736
233M
  }
737
58.3M
}
738
739
865k
static inline void invMixColumns(Guchar *state) {
740
865k
  int c;
741
865k
  Guchar s0, s1, s2, s3;
742
743
4.32M
  for (c = 0; c < 4; ++c) {
744
3.46M
    s0 = state[c];
745
3.46M
    s1 = state[4+c];
746
3.46M
    s2 = state[8+c];
747
3.46M
    s3 = state[12+c];
748
3.46M
    state[c] =    mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3);
749
3.46M
    state[4+c] =  mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3);
750
3.46M
    state[8+c] =  mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3);
751
3.46M
    state[12+c] = mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3);
752
3.46M
  }
753
865k
}
754
755
201k
static inline void invMixColumnsW(Guint *w) {
756
201k
  int c;
757
201k
  Guchar s0, s1, s2, s3;
758
759
1.00M
  for (c = 0; c < 4; ++c) {
760
806k
    s0 = (Guchar)(w[c] >> 24);
761
806k
    s1 = (Guchar)(w[c] >> 16);
762
806k
    s2 = (Guchar)(w[c] >> 8);
763
806k
    s3 = (Guchar)w[c];
764
806k
    w[c] = ((mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3)) << 24)
765
806k
           | ((mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3)) << 16)
766
806k
           | ((mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3)) << 8)
767
806k
           | (mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3));
768
806k
  }
769
201k
}
770
771
72.3M
static inline void addRoundKey(Guchar *state, Guint *w) {
772
72.3M
  int c;
773
774
361M
  for (c = 0; c < 4; ++c) {
775
289M
    state[c] ^= (Guchar)(w[c] >> 24);
776
289M
    state[4+c] ^= (Guchar)(w[c] >> 16);
777
289M
    state[8+c] ^= (Guchar)(w[c] >> 8);
778
289M
    state[12+c] ^= (Guchar)w[c];
779
289M
  }
780
72.3M
}
781
782
void aesKeyExpansion(DecryptAESState *s,
783
         Guchar *objKey, int objKeyLen,
784
43.4k
         GBool decrypt) {
785
43.4k
  Guint temp;
786
43.4k
  int i, round;
787
788
  //~ this assumes objKeyLen == 16
789
790
217k
  for (i = 0; i < 4; ++i) {
791
173k
    s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
792
173k
              (objKey[4*i+2] << 8) + objKey[4*i+3];
793
173k
  }
794
1.78M
  for (i = 4; i < 44; ++i) {
795
1.73M
    temp = s->w[i-1];
796
1.73M
    if (!(i & 3)) {
797
434k
      temp = subWord(rotWord(temp)) ^ rcon[i/4];
798
434k
    }
799
1.73M
    s->w[i] = s->w[i-4] ^ temp;
800
1.73M
  }
801
43.4k
  if (decrypt) {
802
94.6k
    for (round = 1; round <= 9; ++round) {
803
85.1k
      invMixColumnsW(&s->w[round * 4]);
804
85.1k
    }
805
9.46k
  }
806
43.4k
}
807
808
6.48M
void aesEncryptBlock(DecryptAESState *s, Guchar *in) {
809
6.48M
  int c, round;
810
811
  // initial state + CBC
812
32.4M
  for (c = 0; c < 4; ++c) {
813
25.9M
    s->state[c] = in[4*c] ^ s->cbc[4*c];
814
25.9M
    s->state[4+c] = in[4*c+1] ^ s->cbc[4*c+1];
815
25.9M
    s->state[8+c] = in[4*c+2] ^ s->cbc[4*c+2];
816
25.9M
    s->state[12+c] = in[4*c+3] ^ s->cbc[4*c+3];
817
25.9M
  }
818
819
  // round 0
820
6.48M
  addRoundKey(s->state, &s->w[0]);
821
822
  // rounds 1 .. 9
823
64.8M
  for (round = 1; round <= 9; ++round) {
824
58.3M
    subBytes(s->state);
825
58.3M
    shiftRows(s->state);
826
58.3M
    mixColumns(s->state);
827
58.3M
    addRoundKey(s->state, &s->w[round * 4]);
828
58.3M
  }
829
830
  // round 10
831
6.48M
  subBytes(s->state);
832
6.48M
  shiftRows(s->state);
833
6.48M
  addRoundKey(s->state, &s->w[10 * 4]);
834
835
  // output + save for next CBC
836
32.4M
  for (c = 0; c < 4; ++c) {
837
25.9M
    s->buf[4*c] = s->cbc[4*c] = s->state[c];
838
25.9M
    s->buf[4*c+1] = s->cbc[4*c+1] = s->state[4+c];
839
25.9M
    s->buf[4*c+2] = s->cbc[4*c+2] = s->state[8+c];
840
25.9M
    s->buf[4*c+3] = s->cbc[4*c+3] = s->state[12+c];
841
25.9M
  }
842
6.48M
}
843
844
45.4k
void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last) {
845
45.4k
  int c, round, n, i;
846
847
  // initial state
848
227k
  for (c = 0; c < 4; ++c) {
849
181k
    s->state[c] = in[4*c];
850
181k
    s->state[4+c] = in[4*c+1];
851
181k
    s->state[8+c] = in[4*c+2];
852
181k
    s->state[12+c] = in[4*c+3];
853
181k
  }
854
855
  // round 0
856
45.4k
  addRoundKey(s->state, &s->w[10 * 4]);
857
858
  // rounds 1-9
859
454k
  for (round = 9; round >= 1; --round) {
860
408k
    invSubBytes(s->state);
861
408k
    invShiftRows(s->state);
862
408k
    invMixColumns(s->state);
863
408k
    addRoundKey(s->state, &s->w[round * 4]);
864
408k
  }
865
866
  // round 10
867
45.4k
  invSubBytes(s->state);
868
45.4k
  invShiftRows(s->state);
869
45.4k
  addRoundKey(s->state, &s->w[0]);
870
871
  // CBC
872
227k
  for (c = 0; c < 4; ++c) {
873
181k
    s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
874
181k
    s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
875
181k
    s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
876
181k
    s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
877
181k
  }
878
879
  // save the input block for the next CBC
880
772k
  for (i = 0; i < 16; ++i) {
881
726k
    s->cbc[i] = in[i];
882
726k
  }
883
884
  // remove padding
885
45.4k
  s->bufIdx = 0;
886
45.4k
  if (last) {
887
1.46k
    n = s->buf[15];
888
1.46k
    if (n < 1 || n > 16) { // this should never happen
889
905
      n = 16;
890
905
    }
891
5.44k
    for (i = 15; i >= n; --i) {
892
3.98k
      s->buf[i] = s->buf[i-n];
893
3.98k
    }
894
1.46k
    s->bufIdx = n;
895
1.46k
  }
896
45.4k
}
897
898
//------------------------------------------------------------------------
899
// AES-256 decryption
900
//------------------------------------------------------------------------
901
902
static void aes256KeyExpansion(DecryptAES256State *s,
903
8.96k
             Guchar *objKey, int objKeyLen) {
904
8.96k
  Guint temp;
905
8.96k
  int i, round;
906
907
  //~ this assumes objKeyLen == 32
908
909
80.6k
  for (i = 0; i < 8; ++i) {
910
71.6k
    s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
911
71.6k
              (objKey[4*i+2] << 8) + objKey[4*i+3];
912
71.6k
  }
913
474k
  for (i = 8; i < 60; ++i) {
914
466k
    temp = s->w[i-1];
915
466k
    if ((i & 7) == 0) {
916
62.7k
      temp = subWord(rotWord(temp)) ^ rcon[i/8];
917
403k
    } else if ((i & 7) == 4) {
918
53.7k
      temp = subWord(temp);
919
53.7k
    }
920
466k
    s->w[i] = s->w[i-8] ^ temp;
921
466k
  }
922
125k
  for (round = 1; round <= 13; ++round) {
923
116k
    invMixColumnsW(&s->w[round * 4]);
924
116k
  }
925
8.96k
}
926
927
35.1k
static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last) {
928
35.1k
  int c, round, n, i;
929
930
  // initial state
931
175k
  for (c = 0; c < 4; ++c) {
932
140k
    s->state[c] = in[4*c];
933
140k
    s->state[4+c] = in[4*c+1];
934
140k
    s->state[8+c] = in[4*c+2];
935
140k
    s->state[12+c] = in[4*c+3];
936
140k
  }
937
938
  // round 0
939
35.1k
  addRoundKey(s->state, &s->w[14 * 4]);
940
941
  // rounds 13-1
942
491k
  for (round = 13; round >= 1; --round) {
943
456k
    invSubBytes(s->state);
944
456k
    invShiftRows(s->state);
945
456k
    invMixColumns(s->state);
946
456k
    addRoundKey(s->state, &s->w[round * 4]);
947
456k
  }
948
949
  // round 14
950
35.1k
  invSubBytes(s->state);
951
35.1k
  invShiftRows(s->state);
952
35.1k
  addRoundKey(s->state, &s->w[0]);
953
954
  // CBC
955
175k
  for (c = 0; c < 4; ++c) {
956
140k
    s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
957
140k
    s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
958
140k
    s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
959
140k
    s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
960
140k
  }
961
962
  // save the input block for the next CBC
963
597k
  for (i = 0; i < 16; ++i) {
964
562k
    s->cbc[i] = in[i];
965
562k
  }
966
967
  // remove padding
968
35.1k
  s->bufIdx = 0;
969
35.1k
  if (last) {
970
1.96k
    n = s->buf[15];
971
1.96k
    if (n < 1 || n > 16) { // this should never happen
972
928
      n = 16;
973
928
    }
974
9.19k
    for (i = 15; i >= n; --i) {
975
7.22k
      s->buf[i] = s->buf[i-n];
976
7.22k
    }
977
1.96k
    s->bufIdx = n;
978
1.96k
  }
979
35.1k
}
980
981
//------------------------------------------------------------------------
982
// MD5 message digest
983
//------------------------------------------------------------------------
984
985
// this works around a bug in older Sun compilers
986
3.17M
static inline Gulong rotateLeft(Gulong x, int r) {
987
3.17M
  x &= 0xffffffff;
988
3.17M
  return ((x << r) | (x >> (32 - r))) & 0xffffffff;
989
3.17M
}
990
991
static inline Gulong md5Round1(Gulong a, Gulong b, Gulong c, Gulong d,
992
793k
             Gulong Xk, int s, Gulong Ti) {
993
793k
  return b + rotateLeft((a + ((b & c) | (~b & d)) + Xk + Ti), s);
994
793k
}
995
996
static inline Gulong md5Round2(Gulong a, Gulong b, Gulong c, Gulong d,
997
793k
             Gulong Xk, int s, Gulong Ti) {
998
793k
  return b + rotateLeft((a + ((b & d) | (c & ~d)) + Xk + Ti), s);
999
793k
}
1000
1001
static inline Gulong md5Round3(Gulong a, Gulong b, Gulong c, Gulong d,
1002
793k
             Gulong Xk, int s, Gulong Ti) {
1003
793k
  return b + rotateLeft((a + (b ^ c ^ d) + Xk + Ti), s);
1004
793k
}
1005
1006
static inline Gulong md5Round4(Gulong a, Gulong b, Gulong c, Gulong d,
1007
793k
             Gulong Xk, int s, Gulong Ti) {
1008
793k
  return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s);
1009
793k
}
1010
1011
45.2k
void md5Start(MD5State *state) {
1012
45.2k
  state->a = 0x67452301;
1013
45.2k
  state->b = 0xefcdab89;
1014
45.2k
  state->c = 0x98badcfe;
1015
45.2k
  state->d = 0x10325476;
1016
45.2k
  state->bufLen = 0;
1017
45.2k
  state->msgLen = 0;
1018
45.2k
}
1019
1020
49.5k
static void md5ProcessBlock(MD5State *state) {
1021
49.5k
  Gulong x[16];
1022
49.5k
  Gulong a, b, c, d;
1023
49.5k
  int i;
1024
1025
843k
  for (i = 0; i < 16; ++i) {
1026
793k
    x[i] = state->buf[4*i] | (state->buf[4*i+1] << 8) |
1027
793k
           (state->buf[4*i+2] << 16) | (state->buf[4*i+3] << 24);
1028
793k
  }
1029
1030
49.5k
  a = state->a;
1031
49.5k
  b = state->b;
1032
49.5k
  c = state->c;
1033
49.5k
  d = state->d;
1034
1035
  // round 1
1036
49.5k
  a = md5Round1(a, b, c, d, x[0],   7, 0xd76aa478);
1037
49.5k
  d = md5Round1(d, a, b, c, x[1],  12, 0xe8c7b756);
1038
49.5k
  c = md5Round1(c, d, a, b, x[2],  17, 0x242070db);
1039
49.5k
  b = md5Round1(b, c, d, a, x[3],  22, 0xc1bdceee);
1040
49.5k
  a = md5Round1(a, b, c, d, x[4],   7, 0xf57c0faf);
1041
49.5k
  d = md5Round1(d, a, b, c, x[5],  12, 0x4787c62a);
1042
49.5k
  c = md5Round1(c, d, a, b, x[6],  17, 0xa8304613);
1043
49.5k
  b = md5Round1(b, c, d, a, x[7],  22, 0xfd469501);
1044
49.5k
  a = md5Round1(a, b, c, d, x[8],   7, 0x698098d8);
1045
49.5k
  d = md5Round1(d, a, b, c, x[9],  12, 0x8b44f7af);
1046
49.5k
  c = md5Round1(c, d, a, b, x[10], 17, 0xffff5bb1);
1047
49.5k
  b = md5Round1(b, c, d, a, x[11], 22, 0x895cd7be);
1048
49.5k
  a = md5Round1(a, b, c, d, x[12],  7, 0x6b901122);
1049
49.5k
  d = md5Round1(d, a, b, c, x[13], 12, 0xfd987193);
1050
49.5k
  c = md5Round1(c, d, a, b, x[14], 17, 0xa679438e);
1051
49.5k
  b = md5Round1(b, c, d, a, x[15], 22, 0x49b40821);
1052
1053
  // round 2
1054
49.5k
  a = md5Round2(a, b, c, d, x[1],   5, 0xf61e2562);
1055
49.5k
  d = md5Round2(d, a, b, c, x[6],   9, 0xc040b340);
1056
49.5k
  c = md5Round2(c, d, a, b, x[11], 14, 0x265e5a51);
1057
49.5k
  b = md5Round2(b, c, d, a, x[0],  20, 0xe9b6c7aa);
1058
49.5k
  a = md5Round2(a, b, c, d, x[5],   5, 0xd62f105d);
1059
49.5k
  d = md5Round2(d, a, b, c, x[10],  9, 0x02441453);
1060
49.5k
  c = md5Round2(c, d, a, b, x[15], 14, 0xd8a1e681);
1061
49.5k
  b = md5Round2(b, c, d, a, x[4],  20, 0xe7d3fbc8);
1062
49.5k
  a = md5Round2(a, b, c, d, x[9],   5, 0x21e1cde6);
1063
49.5k
  d = md5Round2(d, a, b, c, x[14],  9, 0xc33707d6);
1064
49.5k
  c = md5Round2(c, d, a, b, x[3],  14, 0xf4d50d87);
1065
49.5k
  b = md5Round2(b, c, d, a, x[8],  20, 0x455a14ed);
1066
49.5k
  a = md5Round2(a, b, c, d, x[13],  5, 0xa9e3e905);
1067
49.5k
  d = md5Round2(d, a, b, c, x[2],   9, 0xfcefa3f8);
1068
49.5k
  c = md5Round2(c, d, a, b, x[7],  14, 0x676f02d9);
1069
49.5k
  b = md5Round2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
1070
1071
  // round 3
1072
49.5k
  a = md5Round3(a, b, c, d, x[5],   4, 0xfffa3942);
1073
49.5k
  d = md5Round3(d, a, b, c, x[8],  11, 0x8771f681);
1074
49.5k
  c = md5Round3(c, d, a, b, x[11], 16, 0x6d9d6122);
1075
49.5k
  b = md5Round3(b, c, d, a, x[14], 23, 0xfde5380c);
1076
49.5k
  a = md5Round3(a, b, c, d, x[1],   4, 0xa4beea44);
1077
49.5k
  d = md5Round3(d, a, b, c, x[4],  11, 0x4bdecfa9);
1078
49.5k
  c = md5Round3(c, d, a, b, x[7],  16, 0xf6bb4b60);
1079
49.5k
  b = md5Round3(b, c, d, a, x[10], 23, 0xbebfbc70);
1080
49.5k
  a = md5Round3(a, b, c, d, x[13],  4, 0x289b7ec6);
1081
49.5k
  d = md5Round3(d, a, b, c, x[0],  11, 0xeaa127fa);
1082
49.5k
  c = md5Round3(c, d, a, b, x[3],  16, 0xd4ef3085);
1083
49.5k
  b = md5Round3(b, c, d, a, x[6],  23, 0x04881d05);
1084
49.5k
  a = md5Round3(a, b, c, d, x[9],   4, 0xd9d4d039);
1085
49.5k
  d = md5Round3(d, a, b, c, x[12], 11, 0xe6db99e5);
1086
49.5k
  c = md5Round3(c, d, a, b, x[15], 16, 0x1fa27cf8);
1087
49.5k
  b = md5Round3(b, c, d, a, x[2],  23, 0xc4ac5665);
1088
1089
  // round 4
1090
49.5k
  a = md5Round4(a, b, c, d, x[0],   6, 0xf4292244);
1091
49.5k
  d = md5Round4(d, a, b, c, x[7],  10, 0x432aff97);
1092
49.5k
  c = md5Round4(c, d, a, b, x[14], 15, 0xab9423a7);
1093
49.5k
  b = md5Round4(b, c, d, a, x[5],  21, 0xfc93a039);
1094
49.5k
  a = md5Round4(a, b, c, d, x[12],  6, 0x655b59c3);
1095
49.5k
  d = md5Round4(d, a, b, c, x[3],  10, 0x8f0ccc92);
1096
49.5k
  c = md5Round4(c, d, a, b, x[10], 15, 0xffeff47d);
1097
49.5k
  b = md5Round4(b, c, d, a, x[1],  21, 0x85845dd1);
1098
49.5k
  a = md5Round4(a, b, c, d, x[8],   6, 0x6fa87e4f);
1099
49.5k
  d = md5Round4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
1100
49.5k
  c = md5Round4(c, d, a, b, x[6],  15, 0xa3014314);
1101
49.5k
  b = md5Round4(b, c, d, a, x[13], 21, 0x4e0811a1);
1102
49.5k
  a = md5Round4(a, b, c, d, x[4],   6, 0xf7537e82);
1103
49.5k
  d = md5Round4(d, a, b, c, x[11], 10, 0xbd3af235);
1104
49.5k
  c = md5Round4(c, d, a, b, x[2],  15, 0x2ad7d2bb);
1105
49.5k
  b = md5Round4(b, c, d, a, x[9],  21, 0xeb86d391);
1106
1107
  // increment a, b, c, d
1108
49.5k
  state->a += a;
1109
49.5k
  state->b += b;
1110
49.5k
  state->c += c;
1111
49.5k
  state->d += d;
1112
1113
49.5k
  state->bufLen = 0;
1114
49.5k
}
1115
1116
45.2k
void md5Append(MD5State *state, Guchar *data, int dataLen) {
1117
45.2k
  Guchar *p;
1118
45.2k
  int remain, k;
1119
1120
45.2k
  p = data;
1121
45.2k
  remain = dataLen;
1122
49.5k
  while (state->bufLen + remain >= 64) {
1123
4.34k
    k = 64 - state->bufLen;
1124
4.34k
    memcpy(state->buf + state->bufLen, p, k);
1125
4.34k
    state->bufLen = 64;
1126
4.34k
    md5ProcessBlock(state);
1127
4.34k
    p += k;
1128
4.34k
    remain -= k;
1129
4.34k
  }
1130
45.2k
  if (remain > 0) {
1131
45.2k
    memcpy(state->buf + state->bufLen, p, remain);
1132
45.2k
    state->bufLen += remain;
1133
45.2k
  }
1134
45.2k
  state->msgLen += dataLen;
1135
45.2k
}
1136
1137
45.2k
void md5Finish(MD5State *state) {
1138
  // padding and length
1139
45.2k
  state->buf[state->bufLen++] = 0x80;
1140
45.2k
  if (state->bufLen > 56) {
1141
35
    while (state->bufLen < 64) {
1142
25
      state->buf[state->bufLen++] = 0x00;
1143
25
    }
1144
10
    md5ProcessBlock(state);
1145
10
  }      
1146
1.78M
  while (state->bufLen < 56) {
1147
1.73M
    state->buf[state->bufLen++] = 0x00;
1148
1.73M
  }
1149
45.2k
  state->buf[56] = (Guchar)(state->msgLen << 3);
1150
45.2k
  state->buf[57] = (Guchar)(state->msgLen >> 5);
1151
45.2k
  state->buf[58] = (Guchar)(state->msgLen >> 13);
1152
45.2k
  state->buf[59] = (Guchar)(state->msgLen >> 21);
1153
45.2k
  state->buf[60] = (Guchar)(state->msgLen >> 29);
1154
45.2k
  state->buf[61] = (Guchar)0;
1155
45.2k
  state->buf[62] = (Guchar)0;
1156
45.2k
  state->buf[63] = (Guchar)0;
1157
45.2k
  state->bufLen = 64;
1158
45.2k
  md5ProcessBlock(state);
1159
1160
  // break digest into bytes
1161
45.2k
  state->digest[0] = (Guchar)state->a;
1162
45.2k
  state->digest[1] = (Guchar)(state->a >> 8);
1163
45.2k
  state->digest[2] = (Guchar)(state->a >> 16);
1164
45.2k
  state->digest[3] = (Guchar)(state->a >> 24);
1165
45.2k
  state->digest[4] = (Guchar)state->b;
1166
45.2k
  state->digest[5] = (Guchar)(state->b >> 8);
1167
45.2k
  state->digest[6] = (Guchar)(state->b >> 16);
1168
45.2k
  state->digest[7] = (Guchar)(state->b >> 24);
1169
45.2k
  state->digest[8] = (Guchar)state->c;
1170
45.2k
  state->digest[9] = (Guchar)(state->c >> 8);
1171
45.2k
  state->digest[10] = (Guchar)(state->c >> 16);
1172
45.2k
  state->digest[11] = (Guchar)(state->c >> 24);
1173
45.2k
  state->digest[12] = (Guchar)state->d;
1174
45.2k
  state->digest[13] = (Guchar)(state->d >> 8);
1175
45.2k
  state->digest[14] = (Guchar)(state->d >> 16);
1176
45.2k
  state->digest[15] = (Guchar)(state->d >> 24);
1177
45.2k
}
1178
1179
45.2k
void md5(Guchar *msg, int msgLen, Guchar *digest) {
1180
45.2k
  MD5State state;
1181
45.2k
  int i;
1182
1183
45.2k
  if (msgLen < 0) {
1184
0
    return;
1185
0
  }
1186
45.2k
  md5Start(&state);
1187
45.2k
  md5Append(&state, msg, msgLen);
1188
45.2k
  md5Finish(&state);
1189
768k
  for (i = 0; i < 16; ++i) {
1190
723k
    digest[i] = state.digest[i];
1191
723k
  }
1192
45.2k
}
1193
1194
//------------------------------------------------------------------------
1195
// SHA-256 hash
1196
//------------------------------------------------------------------------
1197
1198
static Guint sha256K[64] = {
1199
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
1200
  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1201
  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
1202
  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1203
  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
1204
  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1205
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
1206
  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1207
  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
1208
  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1209
  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
1210
  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1211
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
1212
  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1213
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
1214
  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1215
};
1216
1217
308M
static inline Guint rotr(Guint x, Guint n) {
1218
308M
  return (x >> n) | (x << (32 - n));
1219
308M
}
1220
1221
34.2M
static inline Guint sha256Ch(Guint x, Guint y, Guint z) {
1222
34.2M
  return (x & y) ^ (~x & z);
1223
34.2M
}
1224
1225
34.2M
static inline Guint sha256Maj(Guint x, Guint y, Guint z) {
1226
34.2M
  return (x & y) ^ (x & z) ^ (y & z);
1227
34.2M
}
1228
1229
34.2M
static inline Guint sha256Sigma0(Guint x) {
1230
34.2M
  return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
1231
34.2M
}
1232
1233
34.2M
static inline Guint sha256Sigma1(Guint x) {
1234
34.2M
  return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
1235
34.2M
}
1236
1237
25.7M
static inline Guint sha256sigma0(Guint x) {
1238
25.7M
  return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
1239
25.7M
}
1240
1241
25.7M
static inline Guint sha256sigma1(Guint x) {
1242
25.7M
  return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
1243
25.7M
}
1244
1245
535k
static void sha256HashBlock(Guchar *blk, Guint *H) {
1246
535k
  Guint W[64];
1247
535k
  Guint a, b, c, d, e, f, g, h;
1248
535k
  Guint T1, T2;
1249
535k
  Guint t;
1250
1251
  // 1. prepare the message schedule
1252
9.11M
  for (t = 0; t < 16; ++t) {
1253
8.57M
    W[t] = (blk[t*4] << 24) |
1254
8.57M
           (blk[t*4 + 1] << 16) |
1255
8.57M
           (blk[t*4 + 2] << 8) |
1256
8.57M
           blk[t*4 + 3];
1257
8.57M
  }
1258
26.2M
  for (t = 16; t < 64; ++t) {
1259
25.7M
    W[t] = sha256sigma1(W[t-2]) + W[t-7] + sha256sigma0(W[t-15]) + W[t-16];
1260
25.7M
  }
1261
1262
  // 2. initialize the eight working variables
1263
535k
  a = H[0];
1264
535k
  b = H[1];
1265
535k
  c = H[2];
1266
535k
  d = H[3];
1267
535k
  e = H[4];
1268
535k
  f = H[5];
1269
535k
  g = H[6];
1270
535k
  h = H[7];
1271
1272
  // 3.
1273
34.8M
  for (t = 0; t < 64; ++t) {
1274
34.2M
    T1 = h + sha256Sigma1(e) + sha256Ch(e,f,g) + sha256K[t] + W[t];
1275
34.2M
    T2 = sha256Sigma0(a) + sha256Maj(a,b,c);
1276
34.2M
    h = g;
1277
34.2M
    g = f;
1278
34.2M
    f = e;
1279
34.2M
    e = d + T1;
1280
34.2M
    d = c;
1281
34.2M
    c = b;
1282
34.2M
    b = a;
1283
34.2M
    a = T1 + T2;
1284
34.2M
  }
1285
1286
  // 4. compute the intermediate hash value
1287
535k
  H[0] += a;
1288
535k
  H[1] += b;
1289
535k
  H[2] += c;
1290
535k
  H[3] += d;
1291
535k
  H[4] += e;
1292
535k
  H[5] += f;
1293
535k
  H[6] += g;
1294
535k
  H[7] += h;
1295
535k
}
1296
1297
11.6k
static void sha256(Guchar *msg, int msgLen, Guchar *hash) {
1298
11.6k
  Guchar blk[64];
1299
11.6k
  Guint H[8];
1300
11.6k
  int blkLen, i;
1301
1302
11.6k
  H[0] = 0x6a09e667;
1303
11.6k
  H[1] = 0xbb67ae85;
1304
11.6k
  H[2] = 0x3c6ef372;
1305
11.6k
  H[3] = 0xa54ff53a;
1306
11.6k
  H[4] = 0x510e527f;
1307
11.6k
  H[5] = 0x9b05688c;
1308
11.6k
  H[6] = 0x1f83d9ab;
1309
11.6k
  H[7] = 0x5be0cd19;
1310
1311
11.6k
  blkLen = 0;
1312
535k
  for (i = 0; i + 64 <= msgLen; i += 64) {
1313
524k
    sha256HashBlock(msg + i, H);
1314
524k
  }
1315
11.6k
  blkLen = msgLen - i;
1316
11.6k
  if (blkLen > 0) {
1317
486
    memcpy(blk, msg + i, blkLen);
1318
486
  }
1319
1320
  // pad the message
1321
11.6k
  blk[blkLen++] = 0x80;
1322
11.6k
  if (blkLen > 56) {
1323
0
    while (blkLen < 64) {
1324
0
      blk[blkLen++] = 0;
1325
0
    }
1326
0
    sha256HashBlock(blk, H);
1327
0
    blkLen = 0;
1328
0
  }
1329
649k
  while (blkLen < 56) {
1330
637k
    blk[blkLen++] = 0;
1331
637k
  }
1332
11.6k
  blk[56] = 0;
1333
11.6k
  blk[57] = 0;
1334
11.6k
  blk[58] = 0;
1335
11.6k
  blk[59] = 0;
1336
11.6k
  blk[60] = (Guchar)(msgLen >> 21);
1337
11.6k
  blk[61] = (Guchar)(msgLen >> 13);
1338
11.6k
  blk[62] = (Guchar)(msgLen >> 5);
1339
11.6k
  blk[63] = (Guchar)(msgLen << 3);
1340
11.6k
  sha256HashBlock(blk, H);
1341
1342
  // copy the output into the buffer (convert words to bytes)
1343
104k
  for (i = 0; i < 8; ++i) {
1344
93.2k
    hash[i*4]     = (Guchar)(H[i] >> 24);
1345
93.2k
    hash[i*4 + 1] = (Guchar)(H[i] >> 16);
1346
93.2k
    hash[i*4 + 2] = (Guchar)(H[i] >> 8);
1347
93.2k
    hash[i*4 + 3] = (Guchar)H[i];
1348
93.2k
  }
1349
11.6k
}
1350
1351
//------------------------------------------------------------------------
1352
// SHA-384 and SHA-512 hashes
1353
//------------------------------------------------------------------------
1354
1355
typedef unsigned long long SHA512Uint64;
1356
1357
static SHA512Uint64 sha512K[80] = {
1358
  0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
1359
  0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
1360
  0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
1361
  0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
1362
  0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
1363
  0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
1364
  0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
1365
  0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
1366
  0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
1367
  0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
1368
  0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
1369
  0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
1370
  0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
1371
  0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
1372
  0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
1373
  0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
1374
  0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
1375
  0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
1376
  0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
1377
  0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
1378
  0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
1379
  0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
1380
  0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
1381
  0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
1382
  0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
1383
  0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
1384
  0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
1385
  0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
1386
  0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
1387
  0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
1388
  0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
1389
  0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
1390
  0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
1391
  0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
1392
  0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
1393
  0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
1394
  0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
1395
  0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
1396
  0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
1397
  0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
1398
};
1399
1400
420M
static inline SHA512Uint64 rotr64(SHA512Uint64 x, Guint n) {
1401
420M
  return (x >> n) | (x << (64 - n));
1402
420M
}
1403
1404
static inline SHA512Uint64 sha512Ch(SHA512Uint64 x, SHA512Uint64 y,
1405
45.7M
            SHA512Uint64 z) {
1406
45.7M
  return (x & y) ^ (~x & z);
1407
45.7M
}
1408
1409
static inline SHA512Uint64 sha512Maj(SHA512Uint64 x, SHA512Uint64 y,
1410
45.7M
             SHA512Uint64 z) {
1411
45.7M
  return (x & y) ^ (x & z) ^ (y & z);
1412
45.7M
}
1413
1414
45.7M
static inline SHA512Uint64 sha512Sigma0(SHA512Uint64 x) {
1415
45.7M
  return rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39);
1416
45.7M
}
1417
1418
45.7M
static inline SHA512Uint64 sha512Sigma1(SHA512Uint64 x) {
1419
45.7M
  return rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41);
1420
45.7M
}
1421
1422
36.5M
static inline SHA512Uint64 sha512sigma0(SHA512Uint64 x) {
1423
36.5M
  return rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7);
1424
36.5M
}
1425
1426
36.5M
static inline SHA512Uint64 sha512sigma1(SHA512Uint64 x) {
1427
36.5M
  return rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6);
1428
36.5M
}
1429
1430
571k
static void sha512HashBlock(Guchar *blk, SHA512Uint64 *H) {
1431
571k
  SHA512Uint64 W[80];
1432
571k
  SHA512Uint64 a, b, c, d, e, f, g, h;
1433
571k
  SHA512Uint64 T1, T2;
1434
571k
  Guint t;
1435
1436
  // 1. prepare the message schedule
1437
9.71M
  for (t = 0; t < 16; ++t) {
1438
9.14M
    W[t] = ((SHA512Uint64)blk[t*8] << 56) |
1439
9.14M
           ((SHA512Uint64)blk[t*8 + 1] << 48) |
1440
9.14M
           ((SHA512Uint64)blk[t*8 + 2] << 40) |
1441
9.14M
           ((SHA512Uint64)blk[t*8 + 3] << 32) |
1442
9.14M
           ((SHA512Uint64)blk[t*8 + 4] << 24) |
1443
9.14M
           ((SHA512Uint64)blk[t*8 + 5] << 16) |
1444
9.14M
           ((SHA512Uint64)blk[t*8 + 6] << 8) |
1445
9.14M
           (SHA512Uint64)blk[t*8 + 7];
1446
9.14M
  }
1447
37.1M
  for (t = 16; t < 80; ++t) {
1448
36.5M
    W[t] = sha512sigma1(W[t-2]) + W[t-7] + sha512sigma0(W[t-15]) + W[t-16];
1449
36.5M
  }
1450
1451
  // 2. initialize the eight working variables
1452
571k
  a = H[0];
1453
571k
  b = H[1];
1454
571k
  c = H[2];
1455
571k
  d = H[3];
1456
571k
  e = H[4];
1457
571k
  f = H[5];
1458
571k
  g = H[6];
1459
571k
  h = H[7];
1460
1461
  // 3.
1462
46.3M
  for (t = 0; t < 80; ++t) {
1463
45.7M
    T1 = h + sha512Sigma1(e) + sha512Ch(e,f,g) + sha512K[t] + W[t];
1464
45.7M
    T2 = sha512Sigma0(a) + sha512Maj(a,b,c);
1465
45.7M
    h = g;
1466
45.7M
    g = f;
1467
45.7M
    f = e;
1468
45.7M
    e = d + T1;
1469
45.7M
    d = c;
1470
45.7M
    c = b;
1471
45.7M
    b = a;
1472
45.7M
    a = T1 + T2;
1473
45.7M
  }
1474
1475
  // 4. compute the intermediate hash value
1476
571k
  H[0] += a;
1477
571k
  H[1] += b;
1478
571k
  H[2] += c;
1479
571k
  H[3] += d;
1480
571k
  H[4] += e;
1481
571k
  H[5] += f;
1482
571k
  H[6] += g;
1483
571k
  H[7] += h;
1484
571k
}
1485
1486
11.1k
static void sha512(Guchar *msg, int msgLen, Guchar *hash) {
1487
11.1k
  Guchar blk[128];
1488
11.1k
  SHA512Uint64 H[8];
1489
11.1k
  int blkLen, i;
1490
1491
11.1k
  H[0] = 0x6a09e667f3bcc908ULL;
1492
11.1k
  H[1] = 0xbb67ae8584caa73bULL;
1493
11.1k
  H[2] = 0x3c6ef372fe94f82bULL;
1494
11.1k
  H[3] = 0xa54ff53a5f1d36f1ULL;
1495
11.1k
  H[4] = 0x510e527fade682d1ULL;
1496
11.1k
  H[5] = 0x9b05688c2b3e6c1fULL;
1497
11.1k
  H[6] = 0x1f83d9abfb41bd6bULL;
1498
11.1k
  H[7] = 0x5be0cd19137e2179ULL;
1499
1500
11.1k
  blkLen = 0;
1501
278k
  for (i = 0; i + 128 <= msgLen; i += 128) {
1502
267k
    sha512HashBlock(msg + i, H);
1503
267k
  }
1504
11.1k
  blkLen = msgLen - i;
1505
11.1k
  if (blkLen > 0) {
1506
0
    memcpy(blk, msg + i, blkLen);
1507
0
  }
1508
1509
  // pad the message
1510
11.1k
  blk[blkLen++] = 0x80;
1511
11.1k
  if (blkLen > 112) {
1512
0
    while (blkLen < 128) {
1513
0
      blk[blkLen++] = 0;
1514
0
    }
1515
0
    sha512HashBlock(blk, H);
1516
0
    blkLen = 0;
1517
0
  }
1518
1.25M
  while (blkLen < 112) {
1519
1.24M
    blk[blkLen++] = 0;
1520
1.24M
  }
1521
11.1k
  blk[112] = 0;
1522
11.1k
  blk[113] = 0;
1523
11.1k
  blk[114] = 0;
1524
11.1k
  blk[115] = 0;
1525
11.1k
  blk[116] = 0;
1526
11.1k
  blk[117] = 0;
1527
11.1k
  blk[118] = 0;
1528
11.1k
  blk[119] = 0;
1529
11.1k
  blk[120] = 0;
1530
11.1k
  blk[121] = 0;
1531
11.1k
  blk[122] = 0;
1532
11.1k
  blk[123] = 0;
1533
11.1k
  blk[124] = (Guchar)(msgLen >> 21);
1534
11.1k
  blk[125] = (Guchar)(msgLen >> 13);
1535
11.1k
  blk[126] = (Guchar)(msgLen >> 5);
1536
11.1k
  blk[127] = (Guchar)(msgLen << 3);
1537
11.1k
  sha512HashBlock(blk, H);
1538
1539
  // copy the output into the buffer (convert words to bytes)
1540
100k
  for (i = 0; i < 8; ++i) {
1541
89.4k
    hash[i*8]     = (Guchar)(H[i] >> 56);
1542
89.4k
    hash[i*8 + 1] = (Guchar)(H[i] >> 48);
1543
89.4k
    hash[i*8 + 2] = (Guchar)(H[i] >> 40);
1544
89.4k
    hash[i*8 + 3] = (Guchar)(H[i] >> 32);
1545
89.4k
    hash[i*8 + 4] = (Guchar)(H[i] >> 24);
1546
89.4k
    hash[i*8 + 5] = (Guchar)(H[i] >> 16);
1547
89.4k
    hash[i*8 + 6] = (Guchar)(H[i] >> 8);
1548
89.4k
    hash[i*8 + 7] = (Guchar)H[i];
1549
89.4k
  }
1550
11.1k
}
1551
1552
11.6k
static void sha384(Guchar *msg, int msgLen, Guchar *hash) {
1553
11.6k
  Guchar blk[128];
1554
11.6k
  SHA512Uint64 H[8];
1555
11.6k
  int blkLen, i;
1556
1557
11.6k
  H[0] = 0xcbbb9d5dc1059ed8ULL;
1558
11.6k
  H[1] = 0x629a292a367cd507ULL;
1559
11.6k
  H[2] = 0x9159015a3070dd17ULL;
1560
11.6k
  H[3] = 0x152fecd8f70e5939ULL;
1561
11.6k
  H[4] = 0x67332667ffc00b31ULL;
1562
11.6k
  H[5] = 0x8eb44a8768581511ULL;
1563
11.6k
  H[6] = 0xdb0c2e0d64f98fa7ULL;
1564
11.6k
  H[7] = 0x47b5481dbefa4fa4ULL;
1565
1566
11.6k
  blkLen = 0;
1567
293k
  for (i = 0; i + 128 <= msgLen; i += 128) {
1568
281k
    sha512HashBlock(msg + i, H);
1569
281k
  }
1570
11.6k
  blkLen = msgLen - i;
1571
11.6k
  if (blkLen > 0) {
1572
0
    memcpy(blk, msg + i, blkLen);
1573
0
  }
1574
1575
  // pad the message
1576
11.6k
  blk[blkLen++] = 0x80;
1577
11.6k
  if (blkLen > 112) {
1578
0
    while (blkLen < 128) {
1579
0
      blk[blkLen++] = 0;
1580
0
    }
1581
0
    sha512HashBlock(blk, H);
1582
0
    blkLen = 0;
1583
0
  }
1584
1.30M
  while (blkLen < 112) {
1585
1.29M
    blk[blkLen++] = 0;
1586
1.29M
  }
1587
11.6k
  blk[112] = 0;
1588
11.6k
  blk[113] = 0;
1589
11.6k
  blk[114] = 0;
1590
11.6k
  blk[115] = 0;
1591
11.6k
  blk[116] = 0;
1592
11.6k
  blk[117] = 0;
1593
11.6k
  blk[118] = 0;
1594
11.6k
  blk[119] = 0;
1595
11.6k
  blk[120] = 0;
1596
11.6k
  blk[121] = 0;
1597
11.6k
  blk[122] = 0;
1598
11.6k
  blk[123] = 0;
1599
11.6k
  blk[124] = (Guchar)(msgLen >> 21);
1600
11.6k
  blk[125] = (Guchar)(msgLen >> 13);
1601
11.6k
  blk[126] = (Guchar)(msgLen >> 5);
1602
11.6k
  blk[127] = (Guchar)(msgLen << 3);
1603
11.6k
  sha512HashBlock(blk, H);
1604
1605
  // copy the output into the buffer (convert words to bytes)
1606
81.4k
  for (i = 0; i < 6; ++i) {
1607
69.8k
    hash[i*8]     = (Guchar)(H[i] >> 56);
1608
69.8k
    hash[i*8 + 1] = (Guchar)(H[i] >> 48);
1609
69.8k
    hash[i*8 + 2] = (Guchar)(H[i] >> 40);
1610
69.8k
    hash[i*8 + 3] = (Guchar)(H[i] >> 32);
1611
69.8k
    hash[i*8 + 4] = (Guchar)(H[i] >> 24);
1612
69.8k
    hash[i*8 + 5] = (Guchar)(H[i] >> 16);
1613
69.8k
    hash[i*8 + 6] = (Guchar)(H[i] >> 8);
1614
69.8k
    hash[i*8 + 7] = (Guchar)H[i];
1615
69.8k
  }
1616
11.6k
}