Coverage Report

Created: 2023-09-25 06:41

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