Coverage Report

Created: 2022-03-21 07:20

/src/xpdf-4.03/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
0
         GBool *ownerPasswordOk) {
45
0
  DecryptAES256State state;
46
0
  Guchar test[127 + 56], test2[32];
47
0
  GString *userPassword2;
48
0
  const char *userPW;
49
0
  Guchar fState[256];
50
0
  Guchar tmpKey[16];
51
0
  Guchar fx, fy;
52
0
  int len, i, j;
53
54
0
  *ownerPasswordOk = gFalse;
55
56
0
  if (encRevision == 5 || encRevision == 6) {
57
58
    // check the owner password
59
0
    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
0
    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
0
    } else {
108
0
      userPW = "";
109
0
      len = 0;
110
0
    }
111
0
    memcpy(test, userPW, len);
112
0
    memcpy(test + len, userKey->getCString() + 32, 8);
113
0
    sha256(test, len + 8, test);
114
0
    if (encRevision == 6) {
115
0
      r6Hash(test, 32, userPW, len, NULL);
116
0
    }
117
0
    if (!memcmp(test, userKey->getCString(), 32)) {
118
119
      // compute the file key from the user password
120
0
      memcpy(test, userPW, len);
121
0
      memcpy(test + len, userKey->getCString() + 40, 8);
122
0
      sha256(test, len + 8, test);
123
0
      if (encRevision == 6) {
124
0
  r6Hash(test, 32, userPW, len, NULL);
125
0
      }
126
0
      aes256KeyExpansion(&state, test, 32);
127
0
      for (i = 0; i < 16; ++i) {
128
0
  state.cbc[i] = 0;
129
0
      }
130
0
      aes256DecryptBlock(&state, (Guchar *)userEnc->getCString(), gFalse);
131
0
      memcpy(fileKey, state.buf, 16);
132
0
      aes256DecryptBlock(&state, (Guchar *)userEnc->getCString() + 16,
133
0
       gFalse);
134
0
      memcpy(fileKey + 16, state.buf, 16);
135
136
0
      return gTrue; 
137
0
    }
138
139
0
    return gFalse;
140
141
0
  } else {
142
143
    // try using the supplied owner password to generate the user password
144
0
    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
0
    return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
190
0
      permissions, fileID, userPassword, fileKey,
191
0
      encryptMetadata);
192
0
  }
193
0
}
194
195
void Decrypt::r6Hash(Guchar *key, int keyLen, const char *pwd, int pwdLen,
196
0
         char *userKey) {
197
0
  Guchar key1[64*(127+64+48)];
198
0
  DecryptAESState state128;
199
0
  int n, i, j, k;
200
201
0
  i = 0;
202
0
  while (1) {
203
0
    memcpy(key1, pwd, pwdLen);
204
0
    memcpy(key1 + pwdLen, key, keyLen);
205
0
    n = pwdLen + keyLen;
206
0
    if (userKey) {
207
0
      memcpy(key1 + pwdLen + keyLen, userKey, 48);
208
0
      n += 48;
209
0
    }
210
0
    for (j = 1; j < 64; ++j) {
211
0
      memcpy(key1 + j * n, key1, n);
212
0
    }
213
0
    n *= 64;
214
0
    aesKeyExpansion(&state128, key, 16, gFalse);
215
0
    for (j = 0; j < 16; ++j) {
216
0
      state128.cbc[j] = key[16+j];
217
0
    }
218
0
    for (j = 0; j < n; j += 16) {
219
0
      aesEncryptBlock(&state128, key1 + j);
220
0
      memcpy(key1 + j, state128.buf, 16);
221
0
    }
222
0
    k = 0;
223
0
    for (j = 0; j < 16; ++j) {
224
0
      k += key1[j] % 3;
225
0
    }
226
0
    k %= 3;
227
0
    switch (k) {
228
0
    case 0:
229
0
      sha256(key1, n, key);
230
0
      keyLen = 32;
231
0
      break;
232
0
    case 1:
233
0
      sha384(key1, n, key);
234
0
      keyLen = 48;
235
0
      break;
236
0
    case 2:
237
0
      sha512(key1, n, key);
238
0
      keyLen = 64;
239
0
      break;
240
0
    }
241
    // from the spec, it appears that i should be incremented after
242
    // the test, but that doesn't match what Adobe does
243
0
    ++i;
244
0
    if (i >= 64 && key1[n - 1] <= i - 32) {
245
0
      break;
246
0
    }
247
0
  }
248
0
}
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
0
          GBool encryptMetadata) {
255
0
  Guchar *buf;
256
0
  Guchar test[32];
257
0
  Guchar fState[256];
258
0
  Guchar tmpKey[16];
259
0
  Guchar fx, fy;
260
0
  int len, i, j;
261
0
  GBool ok;
262
263
  // generate file key
264
0
  buf = (Guchar *)gmalloc(72 + fileID->getLength());
265
0
  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
0
  } else {
274
0
    memcpy(buf, passwordPad, 32);
275
0
  }
276
0
  memcpy(buf + 32, ownerKey->getCString(), 32);
277
0
  buf[64] = (Guchar)(permissions & 0xff);
278
0
  buf[65] = (Guchar)((permissions >> 8) & 0xff);
279
0
  buf[66] = (Guchar)((permissions >> 16) & 0xff);
280
0
  buf[67] = (Guchar)((permissions >> 24) & 0xff);
281
0
  memcpy(buf + 68, fileID->getCString(), fileID->getLength());
282
0
  len = 68 + fileID->getLength();
283
0
  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
0
  md5(buf, len, fileKey);
290
0
  if (encRevision == 3) {
291
0
    for (i = 0; i < 50; ++i) {
292
0
      md5(fileKey, keyLength, fileKey);
293
0
    }
294
0
  }
295
296
  // test user password
297
0
  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
0
  } else if (encRevision == 3) {
305
0
    memcpy(test, userKey->getCString(), 32);
306
0
    for (i = 19; i >= 0; --i) {
307
0
      for (j = 0; j < keyLength; ++j) {
308
0
  tmpKey[j] = (Guchar)(fileKey[j] ^ i);
309
0
      }
310
0
      rc4InitKey(tmpKey, keyLength, fState);
311
0
      fx = fy = 0;
312
0
      for (j = 0; j < 32; ++j) {
313
0
  test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]);
314
0
      }
315
0
    }
316
0
    memcpy(buf, passwordPad, 32);
317
0
    memcpy(buf + 32, fileID->getCString(), fileID->getLength());
318
0
    md5(buf, 32 + fileID->getLength(), buf);
319
0
    ok = memcmp(test, buf, 16) == 0;
320
0
  } else {
321
0
    ok = gFalse;
322
0
  }
323
324
0
  gfree(buf);
325
0
  return ok;
326
0
}
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
0
{
337
0
  int i;
338
339
0
  memcpy(fileKey, fileKeyA, keyLengthA);
340
0
  algo = algoA;
341
0
  keyLength = keyLengthA;
342
0
  objNum = objNumA;
343
0
  objGen = objGenA;
344
345
  // construct object key
346
0
  for (i = 0; i < keyLength; ++i) {
347
0
    objKey[i] = fileKey[i];
348
0
  }
349
0
  switch (algo) {
350
0
  case cryptRC4:
351
0
    objKey[keyLength] = (Guchar)(objNum & 0xff);
352
0
    objKey[keyLength + 1] = (Guchar)((objNum >> 8) & 0xff);
353
0
    objKey[keyLength + 2] = (Guchar)((objNum >> 16) & 0xff);
354
0
    objKey[keyLength + 3] = (Guchar)(objGen & 0xff);
355
0
    objKey[keyLength + 4] = (Guchar)((objGen >> 8) & 0xff);
356
0
    md5(objKey, keyLength + 5, objKey);
357
0
    if ((objKeyLength = keyLength + 5) > 16) {
358
0
      objKeyLength = 16;
359
0
    }
360
0
    break;
361
0
  case cryptAES:
362
0
    objKey[keyLength] = (Guchar)(objNum & 0xff);
363
0
    objKey[keyLength + 1] = (Guchar)((objNum >> 8) & 0xff);
364
0
    objKey[keyLength + 2] = (Guchar)((objNum >> 16) & 0xff);
365
0
    objKey[keyLength + 3] = (Guchar)(objGen & 0xff);
366
0
    objKey[keyLength + 4] = (Guchar)((objGen >> 8) & 0xff);
367
0
    objKey[keyLength + 5] = 0x73; // 's'
368
0
    objKey[keyLength + 6] = 0x41; // 'A'
369
0
    objKey[keyLength + 7] = 0x6c; // 'l'
370
0
    objKey[keyLength + 8] = 0x54; // 'T'
371
0
    md5(objKey, keyLength + 9, objKey);
372
0
    if ((objKeyLength = keyLength + 5) > 16) {
373
0
      objKeyLength = 16;
374
0
    }
375
0
    break;
376
0
  case cryptAES256:
377
0
    objKeyLength = keyLength;
378
0
    break;
379
0
  }
380
0
}
381
382
0
DecryptStream::~DecryptStream() {
383
0
  delete str;
384
0
}
385
386
0
Stream *DecryptStream::copy() {
387
0
  return new DecryptStream(str->copy(), fileKey, algo, keyLength,
388
0
         objNum, objGen);
389
0
}
390
391
0
void DecryptStream::reset() {
392
0
  str->reset();
393
0
  switch (algo) {
394
0
  case cryptRC4:
395
0
    state.rc4.x = state.rc4.y = 0;
396
0
    rc4InitKey(objKey, objKeyLength, state.rc4.state);
397
0
    state.rc4.buf = EOF;
398
0
    break;
399
0
  case cryptAES:
400
0
    aesKeyExpansion(&state.aes, objKey, objKeyLength, gTrue);
401
0
    str->getBlock((char *)state.aes.cbc, 16);
402
0
    state.aes.bufIdx = 16;
403
0
    break;
404
0
  case cryptAES256:
405
0
    aes256KeyExpansion(&state.aes256, objKey, objKeyLength);
406
0
    str->getBlock((char *)state.aes256.cbc, 16);
407
0
    state.aes256.bufIdx = 16;
408
0
    break;
409
0
  }
410
0
}
411
412
0
int DecryptStream::getChar() {
413
0
  Guchar in[16];
414
0
  int c;
415
416
0
  c = EOF; // make gcc happy
417
0
  switch (algo) {
418
0
  case cryptRC4:
419
0
    if (state.rc4.buf == EOF) {
420
0
      c = str->getChar();
421
0
      if (c != EOF) {
422
0
  state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
423
0
               &state.rc4.y, (Guchar)c);
424
0
      }
425
0
    }
426
0
    c = state.rc4.buf;
427
0
    state.rc4.buf = EOF;
428
0
    break;
429
0
  case cryptAES:
430
0
    if (state.aes.bufIdx == 16) {
431
0
      if (str->getBlock((char *)in, 16) != 16) {
432
0
  return EOF;
433
0
      }
434
0
      aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
435
0
    }
436
0
    if (state.aes.bufIdx == 16) {
437
0
      c = EOF;
438
0
    } else {
439
0
      c = state.aes.buf[state.aes.bufIdx++];
440
0
    }
441
0
    break;
442
0
  case cryptAES256:
443
0
    if (state.aes256.bufIdx == 16) {
444
0
      if (str->getBlock((char *)in, 16) != 16) {
445
0
  return EOF;
446
0
      }
447
0
      aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
448
0
    }
449
0
    if (state.aes256.bufIdx == 16) {
450
0
      c = EOF;
451
0
    } else {
452
0
      c = state.aes256.buf[state.aes256.bufIdx++];
453
0
    }
454
0
    break;
455
0
  }
456
0
  return c;
457
0
}
458
459
0
int DecryptStream::lookChar() {
460
0
  Guchar in[16];
461
0
  int c;
462
463
0
  c = EOF; // make gcc happy
464
0
  switch (algo) {
465
0
  case cryptRC4:
466
0
    if (state.rc4.buf == EOF) {
467
0
      c = str->getChar();
468
0
      if (c != EOF) {
469
0
  state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
470
0
               &state.rc4.y, (Guchar)c);
471
0
      }
472
0
    }
473
0
    c = state.rc4.buf;
474
0
    break;
475
0
  case cryptAES:
476
0
    if (state.aes.bufIdx == 16) {
477
0
      if (str->getBlock((char *)in, 16) != 16) {
478
0
  return EOF;
479
0
      }
480
0
      aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
481
0
    }
482
0
    if (state.aes.bufIdx == 16) {
483
0
      c = EOF;
484
0
    } else {
485
0
      c = state.aes.buf[state.aes.bufIdx];
486
0
    }
487
0
    break;
488
0
  case cryptAES256:
489
0
    if (state.aes256.bufIdx == 16) {
490
0
      if (str->getBlock((char *)in, 16) != 16) {
491
0
  return EOF;
492
0
      }
493
0
      aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
494
0
    }
495
0
    if (state.aes256.bufIdx == 16) {
496
0
      c = EOF;
497
0
    } else {
498
0
      c = state.aes256.buf[state.aes256.bufIdx];
499
0
    }
500
0
    break;
501
0
  }
502
0
  return c;
503
0
}
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
0
void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
514
0
  Guchar index1, index2;
515
0
  Guchar t;
516
0
  int i;
517
518
0
  for (i = 0; i < 256; ++i)
519
0
    state[i] = (Guchar)i;
520
0
  index1 = index2 = 0;
521
0
  for (i = 0; i < 256; ++i) {
522
0
    index2 = (Guchar)(key[index1] + state[i] + index2);
523
0
    t = state[i];
524
0
    state[i] = state[index2];
525
0
    state[index2] = t;
526
0
    index1 = (Guchar)((index1 + 1) % keyLen);
527
0
  }
528
0
}
529
530
0
Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) {
531
0
  Guchar x1, y1, tx, ty;
532
533
0
  x1 = *x = (Guchar)(*x + 1);
534
0
  y1 = *y = (Guchar)(state[*x] + *y);
535
0
  tx = state[x1];
536
0
  ty = state[y1];
537
0
  state[x1] = ty;
538
0
  state[y1] = tx;
539
0
  return c ^ state[(tx + ty) % 256];
540
0
}
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
0
static inline Guint subWord(Guint x) {
599
0
  return (sbox[x >> 24] << 24)
600
0
         | (sbox[(x >> 16) & 0xff] << 16)
601
0
         | (sbox[(x >> 8) & 0xff] << 8)
602
0
         | sbox[x & 0xff];
603
0
}
604
605
0
static inline Guint rotWord(Guint x) {
606
0
  return ((x << 8) & 0xffffffff) | (x >> 24);
607
0
}
608
609
0
static inline void subBytes(Guchar *state) {
610
0
  int i;
611
612
0
  for (i = 0; i < 16; ++i) {
613
0
    state[i] = sbox[state[i]];
614
0
  }
615
0
}
616
617
0
static inline void invSubBytes(Guchar *state) {
618
0
  int i;
619
620
0
  for (i = 0; i < 16; ++i) {
621
0
    state[i] = invSbox[state[i]];
622
0
  }
623
0
}
624
625
0
static inline void shiftRows(Guchar *state) {
626
0
  Guchar t;
627
628
0
  t = state[4];
629
0
  state[4] = state[5];
630
0
  state[5] = state[6];
631
0
  state[6] = state[7];
632
0
  state[7] = t;
633
634
0
  t = state[8];
635
0
  state[8] = state[10];
636
0
  state[10] = t;
637
0
  t = state[9];
638
0
  state[9] = state[11];
639
0
  state[11] = t;
640
641
0
  t = state[15];
642
0
  state[15] = state[14];
643
0
  state[14] = state[13];
644
0
  state[13] = state[12];
645
0
  state[12] = t;
646
0
}
647
648
0
static inline void invShiftRows(Guchar *state) {
649
0
  Guchar t;
650
651
0
  t = state[7];
652
0
  state[7] = state[6];
653
0
  state[6] = state[5];
654
0
  state[5] = state[4];
655
0
  state[4] = t;
656
657
0
  t = state[8];
658
0
  state[8] = state[10];
659
0
  state[10] = t;
660
0
  t = state[9];
661
0
  state[9] = state[11];
662
0
  state[11] = t;
663
664
0
  t = state[12];
665
0
  state[12] = state[13];
666
0
  state[13] = state[14];
667
0
  state[14] = state[15];
668
0
  state[15] = t;
669
0
}
670
671
// {02} \cdot s
672
0
static inline Guchar mul02(Guchar s) {
673
0
  Guchar s2;
674
675
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
676
0
  return s2;
677
0
}
678
679
// {03} \cdot s
680
0
static inline Guchar mul03(Guchar s) {
681
0
  Guchar s2;
682
683
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
684
0
  return s ^ s2;
685
0
}
686
687
// {09} \cdot s
688
0
static inline Guchar mul09(Guchar s) {
689
0
  Guchar s2, s4, s8;
690
691
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
692
0
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
693
0
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
694
0
  return s ^ s8;
695
0
}
696
697
// {0b} \cdot s
698
0
static inline Guchar mul0b(Guchar s) {
699
0
  Guchar s2, s4, s8;
700
701
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
702
0
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
703
0
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
704
0
  return s ^ s2 ^ s8;
705
0
}
706
707
// {0d} \cdot s
708
0
static inline Guchar mul0d(Guchar s) {
709
0
  Guchar s2, s4, s8;
710
711
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
712
0
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
713
0
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
714
0
  return s ^ s4 ^ s8;
715
0
}
716
717
// {0e} \cdot s
718
0
static inline Guchar mul0e(Guchar s) {
719
0
  Guchar s2, s4, s8;
720
721
0
  s2 = (Guchar)((s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1));
722
0
  s4 = (Guchar)((s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1));
723
0
  s8 = (Guchar)((s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1));
724
0
  return s2 ^ s4 ^ s8;
725
0
}
726
727
0
static inline void mixColumns(Guchar *state) {
728
0
  int c;
729
0
  Guchar s0, s1, s2, s3;
730
731
0
  for (c = 0; c < 4; ++c) {
732
0
    s0 = state[c];
733
0
    s1 = state[4+c];
734
0
    s2 = state[8+c];
735
0
    s3 = state[12+c];
736
0
    state[c] =    mul02(s0) ^ mul03(s1) ^       s2  ^       s3;
737
0
    state[4+c] =        s0  ^ mul02(s1) ^ mul03(s2) ^       s3;
738
0
    state[8+c] =        s0  ^       s1  ^ mul02(s2) ^ mul03(s3);
739
0
    state[12+c] = mul03(s0) ^       s1  ^       s2  ^ mul02(s3);
740
0
  }
741
0
}
742
743
0
static inline void invMixColumns(Guchar *state) {
744
0
  int c;
745
0
  Guchar s0, s1, s2, s3;
746
747
0
  for (c = 0; c < 4; ++c) {
748
0
    s0 = state[c];
749
0
    s1 = state[4+c];
750
0
    s2 = state[8+c];
751
0
    s3 = state[12+c];
752
0
    state[c] =    mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3);
753
0
    state[4+c] =  mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3);
754
0
    state[8+c] =  mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3);
755
0
    state[12+c] = mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3);
756
0
  }
757
0
}
758
759
0
static inline void invMixColumnsW(Guint *w) {
760
0
  int c;
761
0
  Guchar s0, s1, s2, s3;
762
763
0
  for (c = 0; c < 4; ++c) {
764
0
    s0 = (Guchar)(w[c] >> 24);
765
0
    s1 = (Guchar)(w[c] >> 16);
766
0
    s2 = (Guchar)(w[c] >> 8);
767
0
    s3 = (Guchar)w[c];
768
0
    w[c] = ((mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3)) << 24)
769
0
           | ((mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3)) << 16)
770
0
           | ((mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3)) << 8)
771
0
           | (mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3));
772
0
  }
773
0
}
774
775
0
static inline void addRoundKey(Guchar *state, Guint *w) {
776
0
  int c;
777
778
0
  for (c = 0; c < 4; ++c) {
779
0
    state[c] ^= (Guchar)(w[c] >> 24);
780
0
    state[4+c] ^= (Guchar)(w[c] >> 16);
781
0
    state[8+c] ^= (Guchar)(w[c] >> 8);
782
0
    state[12+c] ^= (Guchar)w[c];
783
0
  }
784
0
}
785
786
void aesKeyExpansion(DecryptAESState *s,
787
         Guchar *objKey, int objKeyLen,
788
0
         GBool decrypt) {
789
0
  Guint temp;
790
0
  int i, round;
791
792
  //~ this assumes objKeyLen == 16
793
794
0
  for (i = 0; i < 4; ++i) {
795
0
    s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
796
0
              (objKey[4*i+2] << 8) + objKey[4*i+3];
797
0
  }
798
0
  for (i = 4; i < 44; ++i) {
799
0
    temp = s->w[i-1];
800
0
    if (!(i & 3)) {
801
0
      temp = subWord(rotWord(temp)) ^ rcon[i/4];
802
0
    }
803
0
    s->w[i] = s->w[i-4] ^ temp;
804
0
  }
805
0
  if (decrypt) {
806
0
    for (round = 1; round <= 9; ++round) {
807
0
      invMixColumnsW(&s->w[round * 4]);
808
0
    }
809
0
  }
810
0
}
811
812
0
void aesEncryptBlock(DecryptAESState *s, Guchar *in) {
813
0
  int c, round;
814
815
  // initial state + CBC
816
0
  for (c = 0; c < 4; ++c) {
817
0
    s->state[c] = in[4*c] ^ s->cbc[4*c];
818
0
    s->state[4+c] = in[4*c+1] ^ s->cbc[4*c+1];
819
0
    s->state[8+c] = in[4*c+2] ^ s->cbc[4*c+2];
820
0
    s->state[12+c] = in[4*c+3] ^ s->cbc[4*c+3];
821
0
  }
822
823
  // round 0
824
0
  addRoundKey(s->state, &s->w[0]);
825
826
  // rounds 1 .. 9
827
0
  for (round = 1; round <= 9; ++round) {
828
0
    subBytes(s->state);
829
0
    shiftRows(s->state);
830
0
    mixColumns(s->state);
831
0
    addRoundKey(s->state, &s->w[round * 4]);
832
0
  }
833
834
  // round 10
835
0
  subBytes(s->state);
836
0
  shiftRows(s->state);
837
0
  addRoundKey(s->state, &s->w[10 * 4]);
838
839
  // output + save for next CBC
840
0
  for (c = 0; c < 4; ++c) {
841
0
    s->buf[4*c] = s->cbc[4*c] = s->state[c];
842
0
    s->buf[4*c+1] = s->cbc[4*c+1] = s->state[4+c];
843
0
    s->buf[4*c+2] = s->cbc[4*c+2] = s->state[8+c];
844
0
    s->buf[4*c+3] = s->cbc[4*c+3] = s->state[12+c];
845
0
  }
846
0
}
847
848
0
void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last) {
849
0
  int c, round, n, i;
850
851
  // initial state
852
0
  for (c = 0; c < 4; ++c) {
853
0
    s->state[c] = in[4*c];
854
0
    s->state[4+c] = in[4*c+1];
855
0
    s->state[8+c] = in[4*c+2];
856
0
    s->state[12+c] = in[4*c+3];
857
0
  }
858
859
  // round 0
860
0
  addRoundKey(s->state, &s->w[10 * 4]);
861
862
  // rounds 1-9
863
0
  for (round = 9; round >= 1; --round) {
864
0
    invSubBytes(s->state);
865
0
    invShiftRows(s->state);
866
0
    invMixColumns(s->state);
867
0
    addRoundKey(s->state, &s->w[round * 4]);
868
0
  }
869
870
  // round 10
871
0
  invSubBytes(s->state);
872
0
  invShiftRows(s->state);
873
0
  addRoundKey(s->state, &s->w[0]);
874
875
  // CBC
876
0
  for (c = 0; c < 4; ++c) {
877
0
    s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
878
0
    s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
879
0
    s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
880
0
    s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
881
0
  }
882
883
  // save the input block for the next CBC
884
0
  for (i = 0; i < 16; ++i) {
885
0
    s->cbc[i] = in[i];
886
0
  }
887
888
  // remove padding
889
0
  s->bufIdx = 0;
890
0
  if (last) {
891
0
    n = s->buf[15];
892
0
    if (n < 1 || n > 16) { // this should never happen
893
0
      n = 16;
894
0
    }
895
0
    for (i = 15; i >= n; --i) {
896
0
      s->buf[i] = s->buf[i-n];
897
0
    }
898
0
    s->bufIdx = n;
899
0
  }
900
0
}
901
902
//------------------------------------------------------------------------
903
// AES-256 decryption
904
//------------------------------------------------------------------------
905
906
static void aes256KeyExpansion(DecryptAES256State *s,
907
0
             Guchar *objKey, int objKeyLen) {
908
0
  Guint temp;
909
0
  int i, round;
910
911
  //~ this assumes objKeyLen == 32
912
913
0
  for (i = 0; i < 8; ++i) {
914
0
    s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
915
0
              (objKey[4*i+2] << 8) + objKey[4*i+3];
916
0
  }
917
0
  for (i = 8; i < 60; ++i) {
918
0
    temp = s->w[i-1];
919
0
    if ((i & 7) == 0) {
920
0
      temp = subWord(rotWord(temp)) ^ rcon[i/8];
921
0
    } else if ((i & 7) == 4) {
922
0
      temp = subWord(temp);
923
0
    }
924
0
    s->w[i] = s->w[i-8] ^ temp;
925
0
  }
926
0
  for (round = 1; round <= 13; ++round) {
927
0
    invMixColumnsW(&s->w[round * 4]);
928
0
  }
929
0
}
930
931
0
static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last) {
932
0
  int c, round, n, i;
933
934
  // initial state
935
0
  for (c = 0; c < 4; ++c) {
936
0
    s->state[c] = in[4*c];
937
0
    s->state[4+c] = in[4*c+1];
938
0
    s->state[8+c] = in[4*c+2];
939
0
    s->state[12+c] = in[4*c+3];
940
0
  }
941
942
  // round 0
943
0
  addRoundKey(s->state, &s->w[14 * 4]);
944
945
  // rounds 13-1
946
0
  for (round = 13; round >= 1; --round) {
947
0
    invSubBytes(s->state);
948
0
    invShiftRows(s->state);
949
0
    invMixColumns(s->state);
950
0
    addRoundKey(s->state, &s->w[round * 4]);
951
0
  }
952
953
  // round 14
954
0
  invSubBytes(s->state);
955
0
  invShiftRows(s->state);
956
0
  addRoundKey(s->state, &s->w[0]);
957
958
  // CBC
959
0
  for (c = 0; c < 4; ++c) {
960
0
    s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
961
0
    s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
962
0
    s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
963
0
    s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
964
0
  }
965
966
  // save the input block for the next CBC
967
0
  for (i = 0; i < 16; ++i) {
968
0
    s->cbc[i] = in[i];
969
0
  }
970
971
  // remove padding
972
0
  s->bufIdx = 0;
973
0
  if (last) {
974
0
    n = s->buf[15];
975
0
    if (n < 1 || n > 16) { // this should never happen
976
0
      n = 16;
977
0
    }
978
0
    for (i = 15; i >= n; --i) {
979
0
      s->buf[i] = s->buf[i-n];
980
0
    }
981
0
    s->bufIdx = n;
982
0
  }
983
0
}
984
985
//------------------------------------------------------------------------
986
// MD5 message digest
987
//------------------------------------------------------------------------
988
989
// this works around a bug in older Sun compilers
990
0
static inline Gulong rotateLeft(Gulong x, int r) {
991
0
  x &= 0xffffffff;
992
0
  return ((x << r) | (x >> (32 - r))) & 0xffffffff;
993
0
}
994
995
static inline Gulong md5Round1(Gulong a, Gulong b, Gulong c, Gulong d,
996
0
             Gulong Xk, int s, Gulong Ti) {
997
0
  return b + rotateLeft((a + ((b & c) | (~b & d)) + Xk + Ti), s);
998
0
}
999
1000
static inline Gulong md5Round2(Gulong a, Gulong b, Gulong c, Gulong d,
1001
0
             Gulong Xk, int s, Gulong Ti) {
1002
0
  return b + rotateLeft((a + ((b & d) | (c & ~d)) + Xk + Ti), s);
1003
0
}
1004
1005
static inline Gulong md5Round3(Gulong a, Gulong b, Gulong c, Gulong d,
1006
0
             Gulong Xk, int s, Gulong Ti) {
1007
0
  return b + rotateLeft((a + (b ^ c ^ d) + Xk + Ti), s);
1008
0
}
1009
1010
static inline Gulong md5Round4(Gulong a, Gulong b, Gulong c, Gulong d,
1011
0
             Gulong Xk, int s, Gulong Ti) {
1012
0
  return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s);
1013
0
}
1014
1015
0
void md5Start(MD5State *state) {
1016
0
  state->a = 0x67452301;
1017
0
  state->b = 0xefcdab89;
1018
0
  state->c = 0x98badcfe;
1019
0
  state->d = 0x10325476;
1020
0
  state->bufLen = 0;
1021
0
  state->msgLen = 0;
1022
0
}
1023
1024
0
static void md5ProcessBlock(MD5State *state) {
1025
0
  Gulong x[16];
1026
0
  Gulong a, b, c, d;
1027
0
  int i;
1028
1029
0
  for (i = 0; i < 16; ++i) {
1030
0
    x[i] = state->buf[4*i] | (state->buf[4*i+1] << 8) |
1031
0
           (state->buf[4*i+2] << 16) | (state->buf[4*i+3] << 24);
1032
0
  }
1033
1034
0
  a = state->a;
1035
0
  b = state->b;
1036
0
  c = state->c;
1037
0
  d = state->d;
1038
1039
  // round 1
1040
0
  a = md5Round1(a, b, c, d, x[0],   7, 0xd76aa478);
1041
0
  d = md5Round1(d, a, b, c, x[1],  12, 0xe8c7b756);
1042
0
  c = md5Round1(c, d, a, b, x[2],  17, 0x242070db);
1043
0
  b = md5Round1(b, c, d, a, x[3],  22, 0xc1bdceee);
1044
0
  a = md5Round1(a, b, c, d, x[4],   7, 0xf57c0faf);
1045
0
  d = md5Round1(d, a, b, c, x[5],  12, 0x4787c62a);
1046
0
  c = md5Round1(c, d, a, b, x[6],  17, 0xa8304613);
1047
0
  b = md5Round1(b, c, d, a, x[7],  22, 0xfd469501);
1048
0
  a = md5Round1(a, b, c, d, x[8],   7, 0x698098d8);
1049
0
  d = md5Round1(d, a, b, c, x[9],  12, 0x8b44f7af);
1050
0
  c = md5Round1(c, d, a, b, x[10], 17, 0xffff5bb1);
1051
0
  b = md5Round1(b, c, d, a, x[11], 22, 0x895cd7be);
1052
0
  a = md5Round1(a, b, c, d, x[12],  7, 0x6b901122);
1053
0
  d = md5Round1(d, a, b, c, x[13], 12, 0xfd987193);
1054
0
  c = md5Round1(c, d, a, b, x[14], 17, 0xa679438e);
1055
0
  b = md5Round1(b, c, d, a, x[15], 22, 0x49b40821);
1056
1057
  // round 2
1058
0
  a = md5Round2(a, b, c, d, x[1],   5, 0xf61e2562);
1059
0
  d = md5Round2(d, a, b, c, x[6],   9, 0xc040b340);
1060
0
  c = md5Round2(c, d, a, b, x[11], 14, 0x265e5a51);
1061
0
  b = md5Round2(b, c, d, a, x[0],  20, 0xe9b6c7aa);
1062
0
  a = md5Round2(a, b, c, d, x[5],   5, 0xd62f105d);
1063
0
  d = md5Round2(d, a, b, c, x[10],  9, 0x02441453);
1064
0
  c = md5Round2(c, d, a, b, x[15], 14, 0xd8a1e681);
1065
0
  b = md5Round2(b, c, d, a, x[4],  20, 0xe7d3fbc8);
1066
0
  a = md5Round2(a, b, c, d, x[9],   5, 0x21e1cde6);
1067
0
  d = md5Round2(d, a, b, c, x[14],  9, 0xc33707d6);
1068
0
  c = md5Round2(c, d, a, b, x[3],  14, 0xf4d50d87);
1069
0
  b = md5Round2(b, c, d, a, x[8],  20, 0x455a14ed);
1070
0
  a = md5Round2(a, b, c, d, x[13],  5, 0xa9e3e905);
1071
0
  d = md5Round2(d, a, b, c, x[2],   9, 0xfcefa3f8);
1072
0
  c = md5Round2(c, d, a, b, x[7],  14, 0x676f02d9);
1073
0
  b = md5Round2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
1074
1075
  // round 3
1076
0
  a = md5Round3(a, b, c, d, x[5],   4, 0xfffa3942);
1077
0
  d = md5Round3(d, a, b, c, x[8],  11, 0x8771f681);
1078
0
  c = md5Round3(c, d, a, b, x[11], 16, 0x6d9d6122);
1079
0
  b = md5Round3(b, c, d, a, x[14], 23, 0xfde5380c);
1080
0
  a = md5Round3(a, b, c, d, x[1],   4, 0xa4beea44);
1081
0
  d = md5Round3(d, a, b, c, x[4],  11, 0x4bdecfa9);
1082
0
  c = md5Round3(c, d, a, b, x[7],  16, 0xf6bb4b60);
1083
0
  b = md5Round3(b, c, d, a, x[10], 23, 0xbebfbc70);
1084
0
  a = md5Round3(a, b, c, d, x[13],  4, 0x289b7ec6);
1085
0
  d = md5Round3(d, a, b, c, x[0],  11, 0xeaa127fa);
1086
0
  c = md5Round3(c, d, a, b, x[3],  16, 0xd4ef3085);
1087
0
  b = md5Round3(b, c, d, a, x[6],  23, 0x04881d05);
1088
0
  a = md5Round3(a, b, c, d, x[9],   4, 0xd9d4d039);
1089
0
  d = md5Round3(d, a, b, c, x[12], 11, 0xe6db99e5);
1090
0
  c = md5Round3(c, d, a, b, x[15], 16, 0x1fa27cf8);
1091
0
  b = md5Round3(b, c, d, a, x[2],  23, 0xc4ac5665);
1092
1093
  // round 4
1094
0
  a = md5Round4(a, b, c, d, x[0],   6, 0xf4292244);
1095
0
  d = md5Round4(d, a, b, c, x[7],  10, 0x432aff97);
1096
0
  c = md5Round4(c, d, a, b, x[14], 15, 0xab9423a7);
1097
0
  b = md5Round4(b, c, d, a, x[5],  21, 0xfc93a039);
1098
0
  a = md5Round4(a, b, c, d, x[12],  6, 0x655b59c3);
1099
0
  d = md5Round4(d, a, b, c, x[3],  10, 0x8f0ccc92);
1100
0
  c = md5Round4(c, d, a, b, x[10], 15, 0xffeff47d);
1101
0
  b = md5Round4(b, c, d, a, x[1],  21, 0x85845dd1);
1102
0
  a = md5Round4(a, b, c, d, x[8],   6, 0x6fa87e4f);
1103
0
  d = md5Round4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
1104
0
  c = md5Round4(c, d, a, b, x[6],  15, 0xa3014314);
1105
0
  b = md5Round4(b, c, d, a, x[13], 21, 0x4e0811a1);
1106
0
  a = md5Round4(a, b, c, d, x[4],   6, 0xf7537e82);
1107
0
  d = md5Round4(d, a, b, c, x[11], 10, 0xbd3af235);
1108
0
  c = md5Round4(c, d, a, b, x[2],  15, 0x2ad7d2bb);
1109
0
  b = md5Round4(b, c, d, a, x[9],  21, 0xeb86d391);
1110
1111
  // increment a, b, c, d
1112
0
  state->a += a;
1113
0
  state->b += b;
1114
0
  state->c += c;
1115
0
  state->d += d;
1116
1117
0
  state->bufLen = 0;
1118
0
}
1119
1120
0
void md5Append(MD5State *state, Guchar *data, int dataLen) {
1121
0
  Guchar *p;
1122
0
  int remain, k;
1123
1124
0
  p = data;
1125
0
  remain = dataLen;
1126
0
  while (state->bufLen + remain >= 64) {
1127
0
    k = 64 - state->bufLen;
1128
0
    memcpy(state->buf + state->bufLen, p, k);
1129
0
    state->bufLen = 64;
1130
0
    md5ProcessBlock(state);
1131
0
    p += k;
1132
0
    remain -= k;
1133
0
  }
1134
0
  if (remain > 0) {
1135
0
    memcpy(state->buf + state->bufLen, p, remain);
1136
0
    state->bufLen += remain;
1137
0
  }
1138
0
  state->msgLen += dataLen;
1139
0
}
1140
1141
0
void md5Finish(MD5State *state) {
1142
  // padding and length
1143
0
  state->buf[state->bufLen++] = 0x80;
1144
0
  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
0
  while (state->bufLen < 56) {
1151
0
    state->buf[state->bufLen++] = 0x00;
1152
0
  }
1153
0
  state->buf[56] = (Guchar)(state->msgLen << 3);
1154
0
  state->buf[57] = (Guchar)(state->msgLen >> 5);
1155
0
  state->buf[58] = (Guchar)(state->msgLen >> 13);
1156
0
  state->buf[59] = (Guchar)(state->msgLen >> 21);
1157
0
  state->buf[60] = (Guchar)(state->msgLen >> 29);
1158
0
  state->buf[61] = (Guchar)0;
1159
0
  state->buf[62] = (Guchar)0;
1160
0
  state->buf[63] = (Guchar)0;
1161
0
  state->bufLen = 64;
1162
0
  md5ProcessBlock(state);
1163
1164
  // break digest into bytes
1165
0
  state->digest[0] = (Guchar)state->a;
1166
0
  state->digest[1] = (Guchar)(state->a >> 8);
1167
0
  state->digest[2] = (Guchar)(state->a >> 16);
1168
0
  state->digest[3] = (Guchar)(state->a >> 24);
1169
0
  state->digest[4] = (Guchar)state->b;
1170
0
  state->digest[5] = (Guchar)(state->b >> 8);
1171
0
  state->digest[6] = (Guchar)(state->b >> 16);
1172
0
  state->digest[7] = (Guchar)(state->b >> 24);
1173
0
  state->digest[8] = (Guchar)state->c;
1174
0
  state->digest[9] = (Guchar)(state->c >> 8);
1175
0
  state->digest[10] = (Guchar)(state->c >> 16);
1176
0
  state->digest[11] = (Guchar)(state->c >> 24);
1177
0
  state->digest[12] = (Guchar)state->d;
1178
0
  state->digest[13] = (Guchar)(state->d >> 8);
1179
0
  state->digest[14] = (Guchar)(state->d >> 16);
1180
0
  state->digest[15] = (Guchar)(state->d >> 24);
1181
0
}
1182
1183
0
void md5(Guchar *msg, int msgLen, Guchar *digest) {
1184
0
  MD5State state;
1185
0
  int i;
1186
1187
0
  if (msgLen < 0) {
1188
0
    return;
1189
0
  }
1190
0
  md5Start(&state);
1191
0
  md5Append(&state, msg, msgLen);
1192
0
  md5Finish(&state);
1193
0
  for (i = 0; i < 16; ++i) {
1194
0
    digest[i] = state.digest[i];
1195
0
  }
1196
0
}
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
0
static inline Guint rotr(Guint x, Guint n) {
1222
0
  return (x >> n) | (x << (32 - n));
1223
0
}
1224
1225
0
static inline Guint sha256Ch(Guint x, Guint y, Guint z) {
1226
0
  return (x & y) ^ (~x & z);
1227
0
}
1228
1229
0
static inline Guint sha256Maj(Guint x, Guint y, Guint z) {
1230
0
  return (x & y) ^ (x & z) ^ (y & z);
1231
0
}
1232
1233
0
static inline Guint sha256Sigma0(Guint x) {
1234
0
  return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
1235
0
}
1236
1237
0
static inline Guint sha256Sigma1(Guint x) {
1238
0
  return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
1239
0
}
1240
1241
0
static inline Guint sha256sigma0(Guint x) {
1242
0
  return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
1243
0
}
1244
1245
0
static inline Guint sha256sigma1(Guint x) {
1246
0
  return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
1247
0
}
1248
1249
0
static void sha256HashBlock(Guchar *blk, Guint *H) {
1250
0
  Guint W[64];
1251
0
  Guint a, b, c, d, e, f, g, h;
1252
0
  Guint T1, T2;
1253
0
  Guint t;
1254
1255
  // 1. prepare the message schedule
1256
0
  for (t = 0; t < 16; ++t) {
1257
0
    W[t] = (blk[t*4] << 24) |
1258
0
           (blk[t*4 + 1] << 16) |
1259
0
           (blk[t*4 + 2] << 8) |
1260
0
           blk[t*4 + 3];
1261
0
  }
1262
0
  for (t = 16; t < 64; ++t) {
1263
0
    W[t] = sha256sigma1(W[t-2]) + W[t-7] + sha256sigma0(W[t-15]) + W[t-16];
1264
0
  }
1265
1266
  // 2. initialize the eight working variables
1267
0
  a = H[0];
1268
0
  b = H[1];
1269
0
  c = H[2];
1270
0
  d = H[3];
1271
0
  e = H[4];
1272
0
  f = H[5];
1273
0
  g = H[6];
1274
0
  h = H[7];
1275
1276
  // 3.
1277
0
  for (t = 0; t < 64; ++t) {
1278
0
    T1 = h + sha256Sigma1(e) + sha256Ch(e,f,g) + sha256K[t] + W[t];
1279
0
    T2 = sha256Sigma0(a) + sha256Maj(a,b,c);
1280
0
    h = g;
1281
0
    g = f;
1282
0
    f = e;
1283
0
    e = d + T1;
1284
0
    d = c;
1285
0
    c = b;
1286
0
    b = a;
1287
0
    a = T1 + T2;
1288
0
  }
1289
1290
  // 4. compute the intermediate hash value
1291
0
  H[0] += a;
1292
0
  H[1] += b;
1293
0
  H[2] += c;
1294
0
  H[3] += d;
1295
0
  H[4] += e;
1296
0
  H[5] += f;
1297
0
  H[6] += g;
1298
0
  H[7] += h;
1299
0
}
1300
1301
0
static void sha256(Guchar *msg, int msgLen, Guchar *hash) {
1302
0
  Guchar blk[64];
1303
0
  Guint H[8];
1304
0
  int blkLen, i;
1305
1306
0
  H[0] = 0x6a09e667;
1307
0
  H[1] = 0xbb67ae85;
1308
0
  H[2] = 0x3c6ef372;
1309
0
  H[3] = 0xa54ff53a;
1310
0
  H[4] = 0x510e527f;
1311
0
  H[5] = 0x9b05688c;
1312
0
  H[6] = 0x1f83d9ab;
1313
0
  H[7] = 0x5be0cd19;
1314
1315
0
  blkLen = 0;
1316
0
  for (i = 0; i + 64 <= msgLen; i += 64) {
1317
0
    sha256HashBlock(msg + i, H);
1318
0
  }
1319
0
  blkLen = msgLen - i;
1320
0
  if (blkLen > 0) {
1321
0
    memcpy(blk, msg + i, blkLen);
1322
0
  }
1323
1324
  // pad the message
1325
0
  blk[blkLen++] = 0x80;
1326
0
  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
0
  while (blkLen < 56) {
1334
0
    blk[blkLen++] = 0;
1335
0
  }
1336
0
  blk[56] = 0;
1337
0
  blk[57] = 0;
1338
0
  blk[58] = 0;
1339
0
  blk[59] = 0;
1340
0
  blk[60] = (Guchar)(msgLen >> 21);
1341
0
  blk[61] = (Guchar)(msgLen >> 13);
1342
0
  blk[62] = (Guchar)(msgLen >> 5);
1343
0
  blk[63] = (Guchar)(msgLen << 3);
1344
0
  sha256HashBlock(blk, H);
1345
1346
  // copy the output into the buffer (convert words to bytes)
1347
0
  for (i = 0; i < 8; ++i) {
1348
0
    hash[i*4]     = (Guchar)(H[i] >> 24);
1349
0
    hash[i*4 + 1] = (Guchar)(H[i] >> 16);
1350
0
    hash[i*4 + 2] = (Guchar)(H[i] >> 8);
1351
0
    hash[i*4 + 3] = (Guchar)H[i];
1352
0
  }
1353
0
}
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
0
static inline SHA512Uint64 rotr64(SHA512Uint64 x, Guint n) {
1405
0
  return (x >> n) | (x << (64 - n));
1406
0
}
1407
1408
static inline SHA512Uint64 sha512Ch(SHA512Uint64 x, SHA512Uint64 y,
1409
0
            SHA512Uint64 z) {
1410
0
  return (x & y) ^ (~x & z);
1411
0
}
1412
1413
static inline SHA512Uint64 sha512Maj(SHA512Uint64 x, SHA512Uint64 y,
1414
0
             SHA512Uint64 z) {
1415
0
  return (x & y) ^ (x & z) ^ (y & z);
1416
0
}
1417
1418
0
static inline SHA512Uint64 sha512Sigma0(SHA512Uint64 x) {
1419
0
  return rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39);
1420
0
}
1421
1422
0
static inline SHA512Uint64 sha512Sigma1(SHA512Uint64 x) {
1423
0
  return rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41);
1424
0
}
1425
1426
0
static inline SHA512Uint64 sha512sigma0(SHA512Uint64 x) {
1427
0
  return rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7);
1428
0
}
1429
1430
0
static inline SHA512Uint64 sha512sigma1(SHA512Uint64 x) {
1431
0
  return rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6);
1432
0
}
1433
1434
0
static void sha512HashBlock(Guchar *blk, SHA512Uint64 *H) {
1435
0
  SHA512Uint64 W[80];
1436
0
  SHA512Uint64 a, b, c, d, e, f, g, h;
1437
0
  SHA512Uint64 T1, T2;
1438
0
  Guint t;
1439
1440
  // 1. prepare the message schedule
1441
0
  for (t = 0; t < 16; ++t) {
1442
0
    W[t] = ((SHA512Uint64)blk[t*8] << 56) |
1443
0
           ((SHA512Uint64)blk[t*8 + 1] << 48) |
1444
0
           ((SHA512Uint64)blk[t*8 + 2] << 40) |
1445
0
           ((SHA512Uint64)blk[t*8 + 3] << 32) |
1446
0
           ((SHA512Uint64)blk[t*8 + 4] << 24) |
1447
0
           ((SHA512Uint64)blk[t*8 + 5] << 16) |
1448
0
           ((SHA512Uint64)blk[t*8 + 6] << 8) |
1449
0
           (SHA512Uint64)blk[t*8 + 7];
1450
0
  }
1451
0
  for (t = 16; t < 80; ++t) {
1452
0
    W[t] = sha512sigma1(W[t-2]) + W[t-7] + sha512sigma0(W[t-15]) + W[t-16];
1453
0
  }
1454
1455
  // 2. initialize the eight working variables
1456
0
  a = H[0];
1457
0
  b = H[1];
1458
0
  c = H[2];
1459
0
  d = H[3];
1460
0
  e = H[4];
1461
0
  f = H[5];
1462
0
  g = H[6];
1463
0
  h = H[7];
1464
1465
  // 3.
1466
0
  for (t = 0; t < 80; ++t) {
1467
0
    T1 = h + sha512Sigma1(e) + sha512Ch(e,f,g) + sha512K[t] + W[t];
1468
0
    T2 = sha512Sigma0(a) + sha512Maj(a,b,c);
1469
0
    h = g;
1470
0
    g = f;
1471
0
    f = e;
1472
0
    e = d + T1;
1473
0
    d = c;
1474
0
    c = b;
1475
0
    b = a;
1476
0
    a = T1 + T2;
1477
0
  }
1478
1479
  // 4. compute the intermediate hash value
1480
0
  H[0] += a;
1481
0
  H[1] += b;
1482
0
  H[2] += c;
1483
0
  H[3] += d;
1484
0
  H[4] += e;
1485
0
  H[5] += f;
1486
0
  H[6] += g;
1487
0
  H[7] += h;
1488
0
}
1489
1490
0
static void sha512(Guchar *msg, int msgLen, Guchar *hash) {
1491
0
  Guchar blk[128];
1492
0
  SHA512Uint64 H[8];
1493
0
  int blkLen, i;
1494
1495
0
  H[0] = 0x6a09e667f3bcc908LL;
1496
0
  H[1] = 0xbb67ae8584caa73bLL;
1497
0
  H[2] = 0x3c6ef372fe94f82bLL;
1498
0
  H[3] = 0xa54ff53a5f1d36f1LL;
1499
0
  H[4] = 0x510e527fade682d1LL;
1500
0
  H[5] = 0x9b05688c2b3e6c1fLL;
1501
0
  H[6] = 0x1f83d9abfb41bd6bLL;
1502
0
  H[7] = 0x5be0cd19137e2179LL;
1503
1504
0
  blkLen = 0;
1505
0
  for (i = 0; i + 128 <= msgLen; i += 128) {
1506
0
    sha512HashBlock(msg + i, H);
1507
0
  }
1508
0
  blkLen = msgLen - i;
1509
0
  if (blkLen > 0) {
1510
0
    memcpy(blk, msg + i, blkLen);
1511
0
  }
1512
1513
  // pad the message
1514
0
  blk[blkLen++] = 0x80;
1515
0
  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
0
  while (blkLen < 112) {
1523
0
    blk[blkLen++] = 0;
1524
0
  }
1525
0
  blk[112] = 0;
1526
0
  blk[113] = 0;
1527
0
  blk[114] = 0;
1528
0
  blk[115] = 0;
1529
0
  blk[116] = 0;
1530
0
  blk[117] = 0;
1531
0
  blk[118] = 0;
1532
0
  blk[119] = 0;
1533
0
  blk[120] = 0;
1534
0
  blk[121] = 0;
1535
0
  blk[122] = 0;
1536
0
  blk[123] = 0;
1537
0
  blk[124] = (Guchar)(msgLen >> 21);
1538
0
  blk[125] = (Guchar)(msgLen >> 13);
1539
0
  blk[126] = (Guchar)(msgLen >> 5);
1540
0
  blk[127] = (Guchar)(msgLen << 3);
1541
0
  sha512HashBlock(blk, H);
1542
1543
  // copy the output into the buffer (convert words to bytes)
1544
0
  for (i = 0; i < 8; ++i) {
1545
0
    hash[i*8]     = (Guchar)(H[i] >> 56);
1546
0
    hash[i*8 + 1] = (Guchar)(H[i] >> 48);
1547
0
    hash[i*8 + 2] = (Guchar)(H[i] >> 40);
1548
0
    hash[i*8 + 3] = (Guchar)(H[i] >> 32);
1549
0
    hash[i*8 + 4] = (Guchar)(H[i] >> 24);
1550
0
    hash[i*8 + 5] = (Guchar)(H[i] >> 16);
1551
0
    hash[i*8 + 6] = (Guchar)(H[i] >> 8);
1552
0
    hash[i*8 + 7] = (Guchar)H[i];
1553
0
  }
1554
0
}
1555
1556
0
static void sha384(Guchar *msg, int msgLen, Guchar *hash) {
1557
0
  Guchar blk[128];
1558
0
  SHA512Uint64 H[8];
1559
0
  int blkLen, i;
1560
1561
0
  H[0] = 0xcbbb9d5dc1059ed8LL;
1562
0
  H[1] = 0x629a292a367cd507LL;
1563
0
  H[2] = 0x9159015a3070dd17LL;
1564
0
  H[3] = 0x152fecd8f70e5939LL;
1565
0
  H[4] = 0x67332667ffc00b31LL;
1566
0
  H[5] = 0x8eb44a8768581511LL;
1567
0
  H[6] = 0xdb0c2e0d64f98fa7LL;
1568
0
  H[7] = 0x47b5481dbefa4fa4LL;
1569
1570
0
  blkLen = 0;
1571
0
  for (i = 0; i + 128 <= msgLen; i += 128) {
1572
0
    sha512HashBlock(msg + i, H);
1573
0
  }
1574
0
  blkLen = msgLen - i;
1575
0
  if (blkLen > 0) {
1576
0
    memcpy(blk, msg + i, blkLen);
1577
0
  }
1578
1579
  // pad the message
1580
0
  blk[blkLen++] = 0x80;
1581
0
  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
0
  while (blkLen < 112) {
1589
0
    blk[blkLen++] = 0;
1590
0
  }
1591
0
  blk[112] = 0;
1592
0
  blk[113] = 0;
1593
0
  blk[114] = 0;
1594
0
  blk[115] = 0;
1595
0
  blk[116] = 0;
1596
0
  blk[117] = 0;
1597
0
  blk[118] = 0;
1598
0
  blk[119] = 0;
1599
0
  blk[120] = 0;
1600
0
  blk[121] = 0;
1601
0
  blk[122] = 0;
1602
0
  blk[123] = 0;
1603
0
  blk[124] = (Guchar)(msgLen >> 21);
1604
0
  blk[125] = (Guchar)(msgLen >> 13);
1605
0
  blk[126] = (Guchar)(msgLen >> 5);
1606
0
  blk[127] = (Guchar)(msgLen << 3);
1607
0
  sha512HashBlock(blk, H);
1608
1609
  // copy the output into the buffer (convert words to bytes)
1610
0
  for (i = 0; i < 6; ++i) {
1611
0
    hash[i*8]     = (Guchar)(H[i] >> 56);
1612
0
    hash[i*8 + 1] = (Guchar)(H[i] >> 48);
1613
0
    hash[i*8 + 2] = (Guchar)(H[i] >> 40);
1614
0
    hash[i*8 + 3] = (Guchar)(H[i] >> 32);
1615
0
    hash[i*8 + 4] = (Guchar)(H[i] >> 24);
1616
0
    hash[i*8 + 5] = (Guchar)(H[i] >> 16);
1617
0
    hash[i*8 + 6] = (Guchar)(H[i] >> 8);
1618
0
    hash[i*8 + 7] = (Guchar)H[i];
1619
0
  }
1620
0
}