1//========================================================================
2//
3// Decrypt.cc
4//
5// Copyright 1996-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
17// Copyright (C) 2008, 2010, 2016-2021 Albert Astals Cid <aacid@kde.org>
18// Copyright (C) 2009 Matthias Franz <matthias@ktug.or.kr>
19// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
20// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
21// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
22// Copyright (C) 2016 Alok Anand <alok4nand@gmail.com>
23// Copyright (C) 2016 Thomas Freitag <Thomas.Freitag@alfa.de>
24// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
25//
26// To see a description of the changes please see the Changelog file that
27// came with your tarball or type make ChangeLog if you are building from git
28//
29//========================================================================
30
31#include <config.h>
32
33#include <cstdint>
34#include <cstring>
35#include "goo/gmem.h"
36#include "goo/grandom.h"
37#include "Decrypt.h"
38#include "Error.h"
39
40static void rc4InitKey(const unsigned char *key, int keyLen, unsigned char *state);
41static unsigned char rc4DecryptByte(unsigned char *state, unsigned char *x, unsigned char *y, unsigned char c);
42
43static bool aesReadBlock(Stream *str, unsigned char *in, bool addPadding);
44
45static void aesKeyExpansion(DecryptAESState *s, const unsigned char *objKey, int objKeyLen, bool decrypt);
46static void aesEncryptBlock(DecryptAESState *s, const unsigned char *in);
47static void aesDecryptBlock(DecryptAESState *s, const unsigned char *in, bool last);
48
49static void aes256KeyExpansion(DecryptAES256State *s, const unsigned char *objKey, int objKeyLen, bool decrypt);
50static void aes256EncryptBlock(DecryptAES256State *s, const unsigned char *in);
51static void aes256DecryptBlock(DecryptAES256State *s, const unsigned char *in, bool last);
52
53static void sha256(unsigned char *msg, int msgLen, unsigned char *hash);
54static void sha384(unsigned char *msg, int msgLen, unsigned char *hash);
55static void sha512(unsigned char *msg, int msgLen, unsigned char *hash);
56
57static void revision6Hash(const GooString *inputPassword, unsigned char *K, const char *userKey);
58
59static const unsigned char passwordPad[32] = { 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a };
60
61//------------------------------------------------------------------------
62// Decrypt
63//------------------------------------------------------------------------
64
65bool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, const GooString *ownerKey, const GooString *userKey, const GooString *ownerEnc, const GooString *userEnc, int permissions, const GooString *fileID,
66 const GooString *ownerPassword, const GooString *userPassword, unsigned char *fileKey, bool encryptMetadata, bool *ownerPasswordOk)
67{
68 DecryptAES256State state;
69 unsigned char test[127 + 56], test2[32];
70 GooString *userPassword2;
71 unsigned char fState[256];
72 unsigned char tmpKey[16];
73 unsigned char fx, fy;
74 int len, i, j;
75
76 *ownerPasswordOk = false;
77
78 if (encRevision == 5 || encRevision == 6) {
79
80 // check the owner password
81 if (ownerPassword) {
82 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
83 len = ownerPassword->getLength();
84 if (len > 127) {
85 len = 127;
86 }
87 memcpy(dest: test, src: ownerPassword->c_str(), n: len);
88 memcpy(dest: test + len, src: ownerKey->c_str() + 32, n: 8);
89 memcpy(dest: test + len + 8, src: userKey->c_str(), n: 48);
90 sha256(msg: test, msgLen: len + 56, hash: test);
91 if (encRevision == 6) {
92 // test contains the initial SHA-256 hash as input K.
93 revision6Hash(inputPassword: ownerPassword, K: test, userKey: userKey->c_str());
94 }
95 if (!memcmp(s1: test, s2: ownerKey->c_str(), n: 32)) {
96
97 // compute the file key from the owner password
98 memcpy(dest: test, src: ownerPassword->c_str(), n: len);
99 memcpy(dest: test + len, src: ownerKey->c_str() + 40, n: 8);
100 memcpy(dest: test + len + 8, src: userKey->c_str(), n: 48);
101 sha256(msg: test, msgLen: len + 56, hash: test);
102 if (encRevision == 6) {
103 // test contains the initial SHA-256 hash input K.
104 revision6Hash(inputPassword: ownerPassword, K: test, userKey: userKey->c_str());
105 }
106 aes256KeyExpansion(s: &state, objKey: test, objKeyLen: 32, decrypt: true);
107 for (i = 0; i < 16; ++i) {
108 state.cbc[i] = 0;
109 }
110 aes256DecryptBlock(s: &state, in: (unsigned char *)ownerEnc->c_str(), last: false);
111 memcpy(dest: fileKey, src: state.buf, n: 16);
112 aes256DecryptBlock(s: &state, in: (unsigned char *)ownerEnc->c_str() + 16, last: false);
113 memcpy(dest: fileKey + 16, src: state.buf, n: 16);
114
115 *ownerPasswordOk = true;
116 return true;
117 }
118 }
119
120 // check the user password
121 if (userPassword) {
122 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
123 len = userPassword->getLength();
124 if (len > 127) {
125 len = 127;
126 }
127 memcpy(dest: test, src: userPassword->c_str(), n: len);
128 memcpy(dest: test + len, src: userKey->c_str() + 32, n: 8);
129 sha256(msg: test, msgLen: len + 8, hash: test);
130 if (encRevision == 6) {
131 // test contains the initial SHA-256 hash input K.
132 // user key is not used in checking user password.
133 revision6Hash(inputPassword: userPassword, K: test, userKey: nullptr);
134 }
135 if (!memcmp(s1: test, s2: userKey->c_str(), n: 32)) {
136
137 // compute the file key from the user password
138 memcpy(dest: test, src: userPassword->c_str(), n: len);
139 memcpy(dest: test + len, src: userKey->c_str() + 40, n: 8);
140 sha256(msg: test, msgLen: len + 8, hash: test);
141 if (encRevision == 6) {
142 // test contains the initial SHA-256 hash input K.
143 // user key is not used in computing intermediate user key.
144 revision6Hash(inputPassword: userPassword, K: test, userKey: nullptr);
145 }
146 aes256KeyExpansion(s: &state, objKey: test, objKeyLen: 32, decrypt: true);
147 for (i = 0; i < 16; ++i) {
148 state.cbc[i] = 0;
149 }
150 aes256DecryptBlock(s: &state, in: (unsigned char *)userEnc->c_str(), last: false);
151 memcpy(dest: fileKey, src: state.buf, n: 16);
152 aes256DecryptBlock(s: &state, in: (unsigned char *)userEnc->c_str() + 16, last: false);
153 memcpy(dest: fileKey + 16, src: state.buf, n: 16);
154
155 return true;
156 }
157 }
158
159 return false;
160 } else {
161
162 // try using the supplied owner password to generate the user password
163 if (ownerPassword) {
164 len = ownerPassword->getLength();
165 if (len < 32) {
166 memcpy(dest: test, src: ownerPassword->c_str(), n: len);
167 memcpy(dest: test + len, src: passwordPad, n: 32 - len);
168 } else {
169 memcpy(dest: test, src: ownerPassword->c_str(), n: 32);
170 }
171 md5(msg: test, msgLen: 32, digest: test);
172 if (encRevision == 3) {
173 for (i = 0; i < 50; ++i) {
174 md5(msg: test, msgLen: keyLength, digest: test);
175 }
176 }
177 if (encRevision == 2) {
178 rc4InitKey(key: test, keyLen: keyLength, state: fState);
179 fx = fy = 0;
180 for (i = 0; i < 32; ++i) {
181 test2[i] = rc4DecryptByte(state: fState, x: &fx, y: &fy, c: ownerKey->getChar(i));
182 }
183 } else {
184 memcpy(dest: test2, src: ownerKey->c_str(), n: 32);
185 for (i = 19; i >= 0; --i) {
186 for (j = 0; j < keyLength; ++j) {
187 tmpKey[j] = test[j] ^ i;
188 }
189 rc4InitKey(key: tmpKey, keyLen: keyLength, state: fState);
190 fx = fy = 0;
191 for (j = 0; j < 32; ++j) {
192 test2[j] = rc4DecryptByte(state: fState, x: &fx, y: &fy, c: test2[j]);
193 }
194 }
195 }
196 userPassword2 = new GooString((char *)test2, 32);
197 if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, permissions, fileID, userPassword: userPassword2, fileKey, encryptMetadata)) {
198 *ownerPasswordOk = true;
199 delete userPassword2;
200 return true;
201 }
202 delete userPassword2;
203 }
204
205 // try using the supplied user password
206 return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, permissions, fileID, userPassword, fileKey, encryptMetadata);
207 }
208}
209
210bool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, const GooString *ownerKey, const GooString *userKey, int permissions, const GooString *fileID, const GooString *userPassword, unsigned char *fileKey,
211 bool encryptMetadata)
212{
213 unsigned char *buf;
214 unsigned char test[32];
215 unsigned char fState[256];
216 unsigned char tmpKey[16];
217 unsigned char fx, fy;
218 int len, i, j;
219 bool ok;
220
221 // generate file key
222 buf = (unsigned char *)gmalloc(size: 72 + fileID->getLength());
223 if (userPassword) {
224 len = userPassword->getLength();
225 if (len < 32) {
226 memcpy(dest: buf, src: userPassword->c_str(), n: len);
227 memcpy(dest: buf + len, src: passwordPad, n: 32 - len);
228 } else {
229 memcpy(dest: buf, src: userPassword->c_str(), n: 32);
230 }
231 } else {
232 memcpy(dest: buf, src: passwordPad, n: 32);
233 }
234 memcpy(dest: buf + 32, src: ownerKey->c_str(), n: 32);
235 buf[64] = permissions & 0xff;
236 buf[65] = (permissions >> 8) & 0xff;
237 buf[66] = (permissions >> 16) & 0xff;
238 buf[67] = (permissions >> 24) & 0xff;
239 memcpy(dest: buf + 68, src: fileID->c_str(), n: fileID->getLength());
240 len = 68 + fileID->getLength();
241 if (!encryptMetadata) {
242 buf[len++] = 0xff;
243 buf[len++] = 0xff;
244 buf[len++] = 0xff;
245 buf[len++] = 0xff;
246 }
247 md5(msg: buf, msgLen: len, digest: fileKey);
248 if (encRevision == 3) {
249 for (i = 0; i < 50; ++i) {
250 md5(msg: fileKey, msgLen: keyLength, digest: fileKey);
251 }
252 }
253
254 // test user password
255 if (encRevision == 2) {
256 rc4InitKey(key: fileKey, keyLen: keyLength, state: fState);
257 fx = fy = 0;
258 for (i = 0; i < 32; ++i) {
259 test[i] = rc4DecryptByte(state: fState, x: &fx, y: &fy, c: userKey->getChar(i));
260 }
261 ok = memcmp(s1: test, s2: passwordPad, n: 32) == 0;
262 } else if (encRevision == 3) {
263 memcpy(dest: test, src: userKey->c_str(), n: 32);
264 for (i = 19; i >= 0; --i) {
265 for (j = 0; j < keyLength; ++j) {
266 tmpKey[j] = fileKey[j] ^ i;
267 }
268 rc4InitKey(key: tmpKey, keyLen: keyLength, state: fState);
269 fx = fy = 0;
270 for (j = 0; j < 32; ++j) {
271 test[j] = rc4DecryptByte(state: fState, x: &fx, y: &fy, c: test[j]);
272 }
273 }
274 memcpy(dest: buf, src: passwordPad, n: 32);
275 memcpy(dest: buf + 32, src: fileID->c_str(), n: fileID->getLength());
276 md5(msg: buf, msgLen: 32 + fileID->getLength(), digest: buf);
277 ok = memcmp(s1: test, s2: buf, n: 16) == 0;
278 } else {
279 ok = false;
280 }
281
282 gfree(p: buf);
283 return ok;
284}
285
286//------------------------------------------------------------------------
287// BaseCryptStream
288//------------------------------------------------------------------------
289
290BaseCryptStream::BaseCryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref refA) : FilterStream(strA)
291{
292 algo = algoA;
293
294 // construct object key
295 for (int i = 0; i < keyLength; ++i) {
296 objKey[i] = fileKey[i];
297 }
298 for (std::size_t i = keyLength; i < sizeof(objKey); ++i) {
299 objKey[i] = 0;
300 }
301
302 switch (algo) {
303 case cryptRC4:
304 if (likely(keyLength < static_cast<int>(sizeof(objKey) - 4))) {
305 objKey[keyLength] = refA.num & 0xff;
306 objKey[keyLength + 1] = (refA.num >> 8) & 0xff;
307 objKey[keyLength + 2] = (refA.num >> 16) & 0xff;
308 objKey[keyLength + 3] = refA.gen & 0xff;
309 objKey[keyLength + 4] = (refA.gen >> 8) & 0xff;
310 md5(msg: objKey, msgLen: keyLength + 5, digest: objKey);
311 }
312 if ((objKeyLength = keyLength + 5) > 16) {
313 objKeyLength = 16;
314 }
315 break;
316 case cryptAES:
317 objKey[keyLength] = refA.num & 0xff;
318 objKey[keyLength + 1] = (refA.num >> 8) & 0xff;
319 objKey[keyLength + 2] = (refA.num >> 16) & 0xff;
320 objKey[keyLength + 3] = refA.gen & 0xff;
321 objKey[keyLength + 4] = (refA.gen >> 8) & 0xff;
322 objKey[keyLength + 5] = 0x73; // 's'
323 objKey[keyLength + 6] = 0x41; // 'A'
324 objKey[keyLength + 7] = 0x6c; // 'l'
325 objKey[keyLength + 8] = 0x54; // 'T'
326 md5(msg: objKey, msgLen: keyLength + 9, digest: objKey);
327 if ((objKeyLength = keyLength + 5) > 16) {
328 objKeyLength = 16;
329 }
330 break;
331 case cryptAES256:
332 objKeyLength = keyLength;
333 break;
334 case cryptNone:
335 break;
336 }
337
338 charactersRead = 0;
339 nextCharBuff = EOF;
340 autoDelete = true;
341}
342
343BaseCryptStream::~BaseCryptStream()
344{
345 if (autoDelete) {
346 delete str;
347 }
348}
349
350void BaseCryptStream::reset()
351{
352 charactersRead = 0;
353 nextCharBuff = EOF;
354 str->reset();
355}
356
357Goffset BaseCryptStream::getPos()
358{
359 return charactersRead;
360}
361
362int BaseCryptStream::getChar()
363{
364 // Read next character and empty the buffer, so that a new character will be read next time
365 int c = lookChar();
366 nextCharBuff = EOF;
367
368 if (c != EOF) {
369 charactersRead++;
370 }
371 return c;
372}
373
374bool BaseCryptStream::isBinary(bool last) const
375{
376 return str->isBinary(last);
377}
378
379void BaseCryptStream::setAutoDelete(bool val)
380{
381 autoDelete = val;
382}
383
384//------------------------------------------------------------------------
385// EncryptStream
386//------------------------------------------------------------------------
387
388EncryptStream::EncryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref refA) : BaseCryptStream(strA, fileKey, algoA, keyLength, refA)
389{
390 // Fill the CBC initialization vector for AES and AES-256
391 switch (algo) {
392 case cryptAES:
393 grandom_fill(buff: state.aes.cbc, size: 16);
394 break;
395 case cryptAES256:
396 grandom_fill(buff: state.aes256.cbc, size: 16);
397 break;
398 default:
399 break;
400 }
401}
402
403EncryptStream::~EncryptStream() { }
404
405void EncryptStream::reset()
406{
407 BaseCryptStream::reset();
408
409 switch (algo) {
410 case cryptRC4:
411 state.rc4.x = state.rc4.y = 0;
412 rc4InitKey(key: objKey, keyLen: objKeyLength, state: state.rc4.state);
413 break;
414 case cryptAES:
415 aesKeyExpansion(s: &state.aes, objKey, objKeyLen: objKeyLength, decrypt: false);
416 memcpy(dest: state.aes.buf, src: state.aes.cbc, n: 16); // Copy CBC IV to buf
417 state.aes.bufIdx = 0;
418 state.aes.paddingReached = false;
419 break;
420 case cryptAES256:
421 aes256KeyExpansion(s: &state.aes256, objKey, objKeyLen: objKeyLength, decrypt: false);
422 memcpy(dest: state.aes256.buf, src: state.aes256.cbc, n: 16); // Copy CBC IV to buf
423 state.aes256.bufIdx = 0;
424 state.aes256.paddingReached = false;
425 break;
426 case cryptNone:
427 break;
428 }
429}
430
431int EncryptStream::lookChar()
432{
433 unsigned char in[16];
434 int c;
435
436 if (nextCharBuff != EOF) {
437 return nextCharBuff;
438 }
439
440 c = EOF; // make gcc happy
441 switch (algo) {
442 case cryptRC4:
443 if ((c = str->getChar()) != EOF) {
444 // RC4 is XOR-based: the decryption algorithm works for encryption too
445 c = rc4DecryptByte(state: state.rc4.state, x: &state.rc4.x, y: &state.rc4.y, c: (unsigned char)c);
446 }
447 break;
448 case cryptAES:
449 if (state.aes.bufIdx == 16 && !state.aes.paddingReached) {
450 state.aes.paddingReached = !aesReadBlock(str, in, addPadding: true);
451 aesEncryptBlock(s: &state.aes, in);
452 }
453 if (state.aes.bufIdx == 16) {
454 c = EOF;
455 } else {
456 c = state.aes.buf[state.aes.bufIdx++];
457 }
458 break;
459 case cryptAES256:
460 if (state.aes256.bufIdx == 16 && !state.aes256.paddingReached) {
461 state.aes256.paddingReached = !aesReadBlock(str, in, addPadding: true);
462 aes256EncryptBlock(s: &state.aes256, in);
463 }
464 if (state.aes256.bufIdx == 16) {
465 c = EOF;
466 } else {
467 c = state.aes256.buf[state.aes256.bufIdx++];
468 }
469 break;
470 case cryptNone:
471 break;
472 }
473 return (nextCharBuff = c);
474}
475
476//------------------------------------------------------------------------
477// DecryptStream
478//------------------------------------------------------------------------
479
480DecryptStream::DecryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref refA) : BaseCryptStream(strA, fileKey, algoA, keyLength, refA) { }
481
482DecryptStream::~DecryptStream() { }
483
484void DecryptStream::reset()
485{
486 int i;
487 BaseCryptStream::reset();
488
489 switch (algo) {
490 case cryptRC4:
491 state.rc4.x = state.rc4.y = 0;
492 rc4InitKey(key: objKey, keyLen: objKeyLength, state: state.rc4.state);
493 break;
494 case cryptAES:
495 aesKeyExpansion(s: &state.aes, objKey, objKeyLen: objKeyLength, decrypt: true);
496 for (i = 0; i < 16; ++i) {
497 state.aes.cbc[i] = str->getChar();
498 }
499 state.aes.bufIdx = 16;
500 break;
501 case cryptAES256:
502 aes256KeyExpansion(s: &state.aes256, objKey, objKeyLen: objKeyLength, decrypt: true);
503 for (i = 0; i < 16; ++i) {
504 state.aes256.cbc[i] = str->getChar();
505 }
506 state.aes256.bufIdx = 16;
507 break;
508 case cryptNone:
509 break;
510 }
511}
512
513int DecryptStream::lookChar()
514{
515 unsigned char in[16];
516 int c;
517
518 if (nextCharBuff != EOF) {
519 return nextCharBuff;
520 }
521
522 c = EOF; // make gcc happy
523 switch (algo) {
524 case cryptRC4:
525 if ((c = str->getChar()) != EOF) {
526 c = rc4DecryptByte(state: state.rc4.state, x: &state.rc4.x, y: &state.rc4.y, c: (unsigned char)c);
527 }
528 break;
529 case cryptAES:
530 if (state.aes.bufIdx == 16) {
531 if (aesReadBlock(str, in, addPadding: false)) {
532 aesDecryptBlock(s: &state.aes, in, last: str->lookChar() == EOF);
533 }
534 }
535 if (state.aes.bufIdx == 16) {
536 c = EOF;
537 } else {
538 c = state.aes.buf[state.aes.bufIdx++];
539 }
540 break;
541 case cryptAES256:
542 if (state.aes256.bufIdx == 16) {
543 if (aesReadBlock(str, in, addPadding: false)) {
544 aes256DecryptBlock(s: &state.aes256, in, last: str->lookChar() == EOF);
545 }
546 }
547 if (state.aes256.bufIdx == 16) {
548 c = EOF;
549 } else {
550 c = state.aes256.buf[state.aes256.bufIdx++];
551 }
552 break;
553 case cryptNone:
554 break;
555 }
556 return (nextCharBuff = c);
557}
558
559//------------------------------------------------------------------------
560// RC4-compatible decryption
561//------------------------------------------------------------------------
562
563static void rc4InitKey(const unsigned char *key, int keyLen, unsigned char *state)
564{
565 unsigned char index1, index2;
566 unsigned char t;
567 int i;
568
569 for (i = 0; i < 256; ++i) {
570 state[i] = i;
571 }
572
573 if (unlikely(keyLen == 0)) {
574 return;
575 }
576
577 index1 = index2 = 0;
578 for (i = 0; i < 256; ++i) {
579 index2 = (key[index1] + state[i] + index2) % 256;
580 t = state[i];
581 state[i] = state[index2];
582 state[index2] = t;
583 index1 = (index1 + 1) % keyLen;
584 }
585}
586
587static unsigned char rc4DecryptByte(unsigned char *state, unsigned char *x, unsigned char *y, unsigned char c)
588{
589 unsigned char x1, y1, tx, ty;
590
591 x1 = *x = (*x + 1) % 256;
592 y1 = *y = (state[*x] + *y) % 256;
593 tx = state[x1];
594 ty = state[y1];
595 state[x1] = ty;
596 state[y1] = tx;
597 return c ^ state[(tx + ty) % 256];
598}
599
600//------------------------------------------------------------------------
601// AES decryption
602//------------------------------------------------------------------------
603
604// Returns false if EOF was reached, true otherwise
605static bool aesReadBlock(Stream *str, unsigned char *in, bool addPadding)
606{
607 int c, i;
608
609 for (i = 0; i < 16; ++i) {
610 if ((c = str->getChar()) != EOF) {
611 in[i] = (unsigned char)c;
612 } else {
613 break;
614 }
615 }
616
617 if (i == 16) {
618 return true;
619 } else {
620 if (addPadding) {
621 c = 16 - i;
622 while (i < 16) {
623 in[i++] = (unsigned char)c;
624 }
625 }
626 return false;
627 }
628}
629
630static const unsigned char sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
631 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
632 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
633 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
634 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
635 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
636 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
637 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
638
639static const unsigned char invSbox[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
640 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
641 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
642 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
643 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
644 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
645 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
646 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
647
648static const unsigned int rcon[11] = { 0x00000000, // unused
649 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 };
650
651static inline unsigned int subWord(unsigned int x)
652{
653 return (sbox[x >> 24] << 24) | (sbox[(x >> 16) & 0xff] << 16) | (sbox[(x >> 8) & 0xff] << 8) | sbox[x & 0xff];
654}
655
656static inline unsigned int rotWord(unsigned int x)
657{
658 return ((x << 8) & 0xffffffff) | (x >> 24);
659}
660
661static inline void subBytes(unsigned char *state)
662{
663 int i;
664
665 for (i = 0; i < 16; ++i) {
666 state[i] = sbox[state[i]];
667 }
668}
669
670static inline void invSubBytes(unsigned char *state)
671{
672 int i;
673
674 for (i = 0; i < 16; ++i) {
675 state[i] = invSbox[state[i]];
676 }
677}
678
679static inline void shiftRows(unsigned char *state)
680{
681 unsigned char t;
682
683 t = state[4];
684 state[4] = state[5];
685 state[5] = state[6];
686 state[6] = state[7];
687 state[7] = t;
688
689 t = state[8];
690 state[8] = state[10];
691 state[10] = t;
692 t = state[9];
693 state[9] = state[11];
694 state[11] = t;
695
696 t = state[15];
697 state[15] = state[14];
698 state[14] = state[13];
699 state[13] = state[12];
700 state[12] = t;
701}
702
703static inline void invShiftRows(unsigned char *state)
704{
705 unsigned char t;
706
707 t = state[7];
708 state[7] = state[6];
709 state[6] = state[5];
710 state[5] = state[4];
711 state[4] = t;
712
713 t = state[8];
714 state[8] = state[10];
715 state[10] = t;
716 t = state[9];
717 state[9] = state[11];
718 state[11] = t;
719
720 t = state[12];
721 state[12] = state[13];
722 state[13] = state[14];
723 state[14] = state[15];
724 state[15] = t;
725}
726
727// {02} \cdot s
728struct Mul02Table
729{
730 constexpr Mul02Table() : values()
731 {
732 for (int s = 0; s < 256; s++) {
733 values[s] = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
734 }
735 }
736
737 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
738
739 unsigned char values[256];
740};
741
742static constexpr Mul02Table mul02;
743
744// {03} \cdot s
745struct Mul03Table
746{
747 constexpr Mul03Table() : values()
748 {
749 for (int s = 0; s < 256; s++) {
750 const unsigned char s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
751 values[s] = s ^ s2;
752 }
753 }
754
755 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
756
757 unsigned char values[256];
758};
759
760static constexpr Mul03Table mul03;
761
762// {09} \cdot s
763struct Mul09Table
764{
765 constexpr Mul09Table() : values()
766 {
767 for (int s = 0; s < 256; s++) {
768 const unsigned char s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
769 const unsigned char s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
770 const unsigned char s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
771 values[s] = s ^ s8;
772 }
773 }
774
775 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
776
777 unsigned char values[256];
778};
779
780static constexpr Mul09Table mul09;
781
782// {0b} \cdot s
783struct Mul0bTable
784{
785 constexpr Mul0bTable() : values()
786 {
787 for (int s = 0; s < 256; s++) {
788 const unsigned char s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
789 const unsigned char s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
790 const unsigned char s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
791 values[s] = s ^ s2 ^ s8;
792 }
793 }
794
795 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
796
797 unsigned char values[256];
798};
799
800static constexpr Mul0bTable mul0b;
801
802// {0d} \cdot s
803struct Mul0dTable
804{
805 constexpr Mul0dTable() : values()
806 {
807 for (int s = 0; s < 256; s++) {
808 const unsigned char s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
809 const unsigned char s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
810 const unsigned char s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
811 values[s] = s ^ s4 ^ s8;
812 }
813 }
814
815 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
816
817 unsigned char values[256];
818};
819
820static constexpr Mul0dTable mul0d;
821
822// {0e} \cdot s
823struct Mul0eTable
824{
825 constexpr Mul0eTable() : values()
826 {
827 for (int s = 0; s < 256; s++) {
828 const unsigned char s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
829 const unsigned char s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
830 const unsigned char s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
831 values[s] = s2 ^ s4 ^ s8;
832 }
833 }
834
835 constexpr unsigned char operator()(uint8_t i) const { return values[i]; }
836
837 unsigned char values[256];
838};
839
840static constexpr Mul0eTable mul0e;
841
842static inline void mixColumns(unsigned char *state)
843{
844 int c;
845 unsigned char s0, s1, s2, s3;
846
847 for (c = 0; c < 4; ++c) {
848 s0 = state[c];
849 s1 = state[4 + c];
850 s2 = state[8 + c];
851 s3 = state[12 + c];
852 state[c] = mul02(s0) ^ mul03(s1) ^ s2 ^ s3;
853 state[4 + c] = s0 ^ mul02(s1) ^ mul03(s2) ^ s3;
854 state[8 + c] = s0 ^ s1 ^ mul02(s2) ^ mul03(s3);
855 state[12 + c] = mul03(s0) ^ s1 ^ s2 ^ mul02(s3);
856 }
857}
858
859static inline void invMixColumns(unsigned char *state)
860{
861 int c;
862 unsigned char s0, s1, s2, s3;
863
864 for (c = 0; c < 4; ++c) {
865 s0 = state[c];
866 s1 = state[4 + c];
867 s2 = state[8 + c];
868 s3 = state[12 + c];
869 state[c] = mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3);
870 state[4 + c] = mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3);
871 state[8 + c] = mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3);
872 state[12 + c] = mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3);
873 }
874}
875
876static inline void invMixColumnsW(unsigned int *w)
877{
878 int c;
879 unsigned char s0, s1, s2, s3;
880
881 for (c = 0; c < 4; ++c) {
882 s0 = w[c] >> 24;
883 s1 = w[c] >> 16;
884 s2 = w[c] >> 8;
885 s3 = w[c];
886 w[c] = ((mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3)) << 24) | ((mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3)) << 16) | ((mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3)) << 8) | (mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3));
887 }
888}
889
890static inline void addRoundKey(unsigned char *state, const unsigned int *w)
891{
892 int c;
893
894 for (c = 0; c < 4; ++c) {
895 state[c] ^= w[c] >> 24;
896 state[4 + c] ^= w[c] >> 16;
897 state[8 + c] ^= w[c] >> 8;
898 state[12 + c] ^= w[c];
899 }
900}
901
902static void aesKeyExpansion(DecryptAESState *s, const unsigned char *objKey, int /*objKeyLen*/, bool decrypt)
903{
904 unsigned int temp;
905 int i, round;
906
907 //~ this assumes objKeyLen == 16
908
909 for (i = 0; i < 4; ++i) {
910 s->w[i] = (objKey[4 * i] << 24) + (objKey[4 * i + 1] << 16) + (objKey[4 * i + 2] << 8) + objKey[4 * i + 3];
911 }
912 for (i = 4; i < 44; ++i) {
913 temp = s->w[i - 1];
914 if (!(i & 3)) {
915 temp = subWord(x: rotWord(x: temp)) ^ rcon[i / 4];
916 }
917 s->w[i] = s->w[i - 4] ^ temp;
918 }
919
920 /* In case of decryption, adjust the key schedule for the equivalent inverse cipher */
921 if (decrypt) {
922 for (round = 1; round <= 9; ++round) {
923 invMixColumnsW(w: &s->w[round * 4]);
924 }
925 }
926}
927
928static void aesEncryptBlock(DecryptAESState *s, const unsigned char *in)
929{
930 int c, round;
931
932 // initial state (input is xor'd with previous output because of CBC)
933 for (c = 0; c < 4; ++c) {
934 s->state[c] = in[4 * c] ^ s->buf[4 * c];
935 s->state[4 + c] = in[4 * c + 1] ^ s->buf[4 * c + 1];
936 s->state[8 + c] = in[4 * c + 2] ^ s->buf[4 * c + 2];
937 s->state[12 + c] = in[4 * c + 3] ^ s->buf[4 * c + 3];
938 }
939
940 // round 0
941 addRoundKey(state: s->state, w: &s->w[0]);
942
943 // rounds 1-9
944 for (round = 1; round <= 9; ++round) {
945 subBytes(state: s->state);
946 shiftRows(state: s->state);
947 mixColumns(state: s->state);
948 addRoundKey(state: s->state, w: &s->w[round * 4]);
949 }
950
951 // round 10
952 subBytes(state: s->state);
953 shiftRows(state: s->state);
954 addRoundKey(state: s->state, w: &s->w[10 * 4]);
955
956 for (c = 0; c < 4; ++c) {
957 s->buf[4 * c] = s->state[c];
958 s->buf[4 * c + 1] = s->state[4 + c];
959 s->buf[4 * c + 2] = s->state[8 + c];
960 s->buf[4 * c + 3] = s->state[12 + c];
961 }
962
963 s->bufIdx = 0;
964}
965
966static void aesDecryptBlock(DecryptAESState *s, const unsigned char *in, bool last)
967{
968 int c, round, n, i;
969
970 // initial state
971 for (c = 0; c < 4; ++c) {
972 s->state[c] = in[4 * c];
973 s->state[4 + c] = in[4 * c + 1];
974 s->state[8 + c] = in[4 * c + 2];
975 s->state[12 + c] = in[4 * c + 3];
976 }
977
978 // round 0
979 addRoundKey(state: s->state, w: &s->w[10 * 4]);
980
981 // rounds 1-9
982 for (round = 9; round >= 1; --round) {
983 invSubBytes(state: s->state);
984 invShiftRows(state: s->state);
985 invMixColumns(state: s->state);
986 addRoundKey(state: s->state, w: &s->w[round * 4]);
987 }
988
989 // round 10
990 invSubBytes(state: s->state);
991 invShiftRows(state: s->state);
992 addRoundKey(state: s->state, w: &s->w[0]);
993
994 // CBC
995 for (c = 0; c < 4; ++c) {
996 s->buf[4 * c] = s->state[c] ^ s->cbc[4 * c];
997 s->buf[4 * c + 1] = s->state[4 + c] ^ s->cbc[4 * c + 1];
998 s->buf[4 * c + 2] = s->state[8 + c] ^ s->cbc[4 * c + 2];
999 s->buf[4 * c + 3] = s->state[12 + c] ^ s->cbc[4 * c + 3];
1000 }
1001
1002 // save the input block for the next CBC
1003 for (i = 0; i < 16; ++i) {
1004 s->cbc[i] = in[i];
1005 }
1006
1007 // remove padding
1008 s->bufIdx = 0;
1009 if (last) {
1010 n = s->buf[15];
1011 if (n < 1 || n > 16) { // this should never happen
1012 n = 16;
1013 }
1014 for (i = 15; i >= n; --i) {
1015 s->buf[i] = s->buf[i - n];
1016 }
1017 s->bufIdx = n;
1018 }
1019}
1020
1021//------------------------------------------------------------------------
1022// AES-256 decryption
1023//------------------------------------------------------------------------
1024
1025static void aes256KeyExpansion(DecryptAES256State *s, const unsigned char *objKey, int objKeyLen, bool decrypt)
1026{
1027 unsigned int temp;
1028 int i, round;
1029
1030 //~ this assumes objKeyLen == 32
1031
1032 for (i = 0; i < 8; ++i) {
1033 s->w[i] = (objKey[4 * i] << 24) + (objKey[4 * i + 1] << 16) + (objKey[4 * i + 2] << 8) + objKey[4 * i + 3];
1034 }
1035 for (i = 8; i < 60; ++i) {
1036 temp = s->w[i - 1];
1037 if ((i & 7) == 0) {
1038 temp = subWord(x: rotWord(x: temp)) ^ rcon[i / 8];
1039 } else if ((i & 7) == 4) {
1040 temp = subWord(x: temp);
1041 }
1042 s->w[i] = s->w[i - 8] ^ temp;
1043 }
1044
1045 /* In case of decryption, adjust the key schedule for the equivalent inverse cipher */
1046 if (decrypt) {
1047 for (round = 1; round <= 13; ++round) {
1048 invMixColumnsW(w: &s->w[round * 4]);
1049 }
1050 }
1051}
1052
1053static void aes256EncryptBlock(DecryptAES256State *s, const unsigned char *in)
1054{
1055 int c, round;
1056
1057 // initial state (input is xor'd with previous output because of CBC)
1058 for (c = 0; c < 4; ++c) {
1059 s->state[c] = in[4 * c] ^ s->buf[4 * c];
1060 s->state[4 + c] = in[4 * c + 1] ^ s->buf[4 * c + 1];
1061 s->state[8 + c] = in[4 * c + 2] ^ s->buf[4 * c + 2];
1062 s->state[12 + c] = in[4 * c + 3] ^ s->buf[4 * c + 3];
1063 }
1064
1065 // round 0
1066 addRoundKey(state: s->state, w: &s->w[0]);
1067
1068 // rounds 1-13
1069 for (round = 1; round <= 13; ++round) {
1070 subBytes(state: s->state);
1071 shiftRows(state: s->state);
1072 mixColumns(state: s->state);
1073 addRoundKey(state: s->state, w: &s->w[round * 4]);
1074 }
1075
1076 // round 14
1077 subBytes(state: s->state);
1078 shiftRows(state: s->state);
1079 addRoundKey(state: s->state, w: &s->w[14 * 4]);
1080
1081 for (c = 0; c < 4; ++c) {
1082 s->buf[4 * c] = s->state[c];
1083 s->buf[4 * c + 1] = s->state[4 + c];
1084 s->buf[4 * c + 2] = s->state[8 + c];
1085 s->buf[4 * c + 3] = s->state[12 + c];
1086 }
1087
1088 s->bufIdx = 0;
1089}
1090
1091static void aes256DecryptBlock(DecryptAES256State *s, const unsigned char *in, bool last)
1092{
1093 int c, round, n, i;
1094
1095 // initial state
1096 for (c = 0; c < 4; ++c) {
1097 s->state[c] = in[4 * c];
1098 s->state[4 + c] = in[4 * c + 1];
1099 s->state[8 + c] = in[4 * c + 2];
1100 s->state[12 + c] = in[4 * c + 3];
1101 }
1102
1103 // round 0
1104 addRoundKey(state: s->state, w: &s->w[14 * 4]);
1105
1106 // rounds 13-1
1107 for (round = 13; round >= 1; --round) {
1108 invSubBytes(state: s->state);
1109 invShiftRows(state: s->state);
1110 invMixColumns(state: s->state);
1111 addRoundKey(state: s->state, w: &s->w[round * 4]);
1112 }
1113
1114 // round 14
1115 invSubBytes(state: s->state);
1116 invShiftRows(state: s->state);
1117 addRoundKey(state: s->state, w: &s->w[0]);
1118
1119 // CBC
1120 for (c = 0; c < 4; ++c) {
1121 s->buf[4 * c] = s->state[c] ^ s->cbc[4 * c];
1122 s->buf[4 * c + 1] = s->state[4 + c] ^ s->cbc[4 * c + 1];
1123 s->buf[4 * c + 2] = s->state[8 + c] ^ s->cbc[4 * c + 2];
1124 s->buf[4 * c + 3] = s->state[12 + c] ^ s->cbc[4 * c + 3];
1125 }
1126
1127 // save the input block for the next CBC
1128 for (i = 0; i < 16; ++i) {
1129 s->cbc[i] = in[i];
1130 }
1131
1132 // remove padding
1133 s->bufIdx = 0;
1134 if (last) {
1135 n = s->buf[15];
1136 if (n < 1 || n > 16) { // this should never happen
1137 n = 16;
1138 }
1139 for (i = 15; i >= n; --i) {
1140 s->buf[i] = s->buf[i - n];
1141 }
1142 s->bufIdx = n;
1143 if (n > 16) {
1144 error(category: errSyntaxError, pos: -1, msg: "Reducing bufIdx from {0:d} to 16 to not crash", n);
1145 s->bufIdx = 16;
1146 }
1147 }
1148}
1149
1150//------------------------------------------------------------------------
1151// MD5 message digest
1152//------------------------------------------------------------------------
1153
1154// this works around a bug in older Sun compilers
1155static inline unsigned long rotateLeft(unsigned long x, int r)
1156{
1157 x &= 0xffffffff;
1158 return ((x << r) | (x >> (32 - r))) & 0xffffffff;
1159}
1160
1161static inline unsigned long md5Round1(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long Xk, unsigned long s, unsigned long Ti)
1162{
1163 return b + rotateLeft(x: (a + ((b & c) | (~b & d)) + Xk + Ti), r: s);
1164}
1165
1166static inline unsigned long md5Round2(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long Xk, unsigned long s, unsigned long Ti)
1167{
1168 return b + rotateLeft(x: (a + ((b & d) | (c & ~d)) + Xk + Ti), r: s);
1169}
1170
1171static inline unsigned long md5Round3(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long Xk, unsigned long s, unsigned long Ti)
1172{
1173 return b + rotateLeft(x: (a + (b ^ c ^ d) + Xk + Ti), r: s);
1174}
1175
1176static inline unsigned long md5Round4(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long Xk, unsigned long s, unsigned long Ti)
1177{
1178 return b + rotateLeft(x: (a + (c ^ (b | ~d)) + Xk + Ti), r: s);
1179}
1180
1181struct MD5State
1182{
1183 unsigned long a, b, c, d;
1184 unsigned char buf[64];
1185 int bufLen;
1186 int msgLen;
1187 unsigned char digest[16];
1188};
1189
1190static void md5Start(MD5State *state)
1191{
1192 state->a = 0x67452301;
1193 state->b = 0xefcdab89;
1194 state->c = 0x98badcfe;
1195 state->d = 0x10325476;
1196 state->bufLen = 0;
1197 state->msgLen = 0;
1198}
1199
1200static void md5ProcessBlock(MD5State *state)
1201{
1202 unsigned long x[16];
1203
1204 for (int i = 0; i < 16; ++i) {
1205 x[i] = state->buf[4 * i] | (state->buf[4 * i + 1] << 8) | (state->buf[4 * i + 2] << 16) | (state->buf[4 * i + 3] << 24);
1206 }
1207
1208 unsigned long a = state->a;
1209 unsigned long b = state->b;
1210 unsigned long c = state->c;
1211 unsigned long d = state->d;
1212
1213 // round 1
1214 a = md5Round1(a, b, c, d, Xk: x[0], s: 7, Ti: 0xd76aa478);
1215 d = md5Round1(a: d, b: a, c: b, d: c, Xk: x[1], s: 12, Ti: 0xe8c7b756);
1216 c = md5Round1(a: c, b: d, c: a, d: b, Xk: x[2], s: 17, Ti: 0x242070db);
1217 b = md5Round1(a: b, b: c, c: d, d: a, Xk: x[3], s: 22, Ti: 0xc1bdceee);
1218 a = md5Round1(a, b, c, d, Xk: x[4], s: 7, Ti: 0xf57c0faf);
1219 d = md5Round1(a: d, b: a, c: b, d: c, Xk: x[5], s: 12, Ti: 0x4787c62a);
1220 c = md5Round1(a: c, b: d, c: a, d: b, Xk: x[6], s: 17, Ti: 0xa8304613);
1221 b = md5Round1(a: b, b: c, c: d, d: a, Xk: x[7], s: 22, Ti: 0xfd469501);
1222 a = md5Round1(a, b, c, d, Xk: x[8], s: 7, Ti: 0x698098d8);
1223 d = md5Round1(a: d, b: a, c: b, d: c, Xk: x[9], s: 12, Ti: 0x8b44f7af);
1224 c = md5Round1(a: c, b: d, c: a, d: b, Xk: x[10], s: 17, Ti: 0xffff5bb1);
1225 b = md5Round1(a: b, b: c, c: d, d: a, Xk: x[11], s: 22, Ti: 0x895cd7be);
1226 a = md5Round1(a, b, c, d, Xk: x[12], s: 7, Ti: 0x6b901122);
1227 d = md5Round1(a: d, b: a, c: b, d: c, Xk: x[13], s: 12, Ti: 0xfd987193);
1228 c = md5Round1(a: c, b: d, c: a, d: b, Xk: x[14], s: 17, Ti: 0xa679438e);
1229 b = md5Round1(a: b, b: c, c: d, d: a, Xk: x[15], s: 22, Ti: 0x49b40821);
1230
1231 // round 2
1232 a = md5Round2(a, b, c, d, Xk: x[1], s: 5, Ti: 0xf61e2562);
1233 d = md5Round2(a: d, b: a, c: b, d: c, Xk: x[6], s: 9, Ti: 0xc040b340);
1234 c = md5Round2(a: c, b: d, c: a, d: b, Xk: x[11], s: 14, Ti: 0x265e5a51);
1235 b = md5Round2(a: b, b: c, c: d, d: a, Xk: x[0], s: 20, Ti: 0xe9b6c7aa);
1236 a = md5Round2(a, b, c, d, Xk: x[5], s: 5, Ti: 0xd62f105d);
1237 d = md5Round2(a: d, b: a, c: b, d: c, Xk: x[10], s: 9, Ti: 0x02441453);
1238 c = md5Round2(a: c, b: d, c: a, d: b, Xk: x[15], s: 14, Ti: 0xd8a1e681);
1239 b = md5Round2(a: b, b: c, c: d, d: a, Xk: x[4], s: 20, Ti: 0xe7d3fbc8);
1240 a = md5Round2(a, b, c, d, Xk: x[9], s: 5, Ti: 0x21e1cde6);
1241 d = md5Round2(a: d, b: a, c: b, d: c, Xk: x[14], s: 9, Ti: 0xc33707d6);
1242 c = md5Round2(a: c, b: d, c: a, d: b, Xk: x[3], s: 14, Ti: 0xf4d50d87);
1243 b = md5Round2(a: b, b: c, c: d, d: a, Xk: x[8], s: 20, Ti: 0x455a14ed);
1244 a = md5Round2(a, b, c, d, Xk: x[13], s: 5, Ti: 0xa9e3e905);
1245 d = md5Round2(a: d, b: a, c: b, d: c, Xk: x[2], s: 9, Ti: 0xfcefa3f8);
1246 c = md5Round2(a: c, b: d, c: a, d: b, Xk: x[7], s: 14, Ti: 0x676f02d9);
1247 b = md5Round2(a: b, b: c, c: d, d: a, Xk: x[12], s: 20, Ti: 0x8d2a4c8a);
1248
1249 // round 3
1250 a = md5Round3(a, b, c, d, Xk: x[5], s: 4, Ti: 0xfffa3942);
1251 d = md5Round3(a: d, b: a, c: b, d: c, Xk: x[8], s: 11, Ti: 0x8771f681);
1252 c = md5Round3(a: c, b: d, c: a, d: b, Xk: x[11], s: 16, Ti: 0x6d9d6122);
1253 b = md5Round3(a: b, b: c, c: d, d: a, Xk: x[14], s: 23, Ti: 0xfde5380c);
1254 a = md5Round3(a, b, c, d, Xk: x[1], s: 4, Ti: 0xa4beea44);
1255 d = md5Round3(a: d, b: a, c: b, d: c, Xk: x[4], s: 11, Ti: 0x4bdecfa9);
1256 c = md5Round3(a: c, b: d, c: a, d: b, Xk: x[7], s: 16, Ti: 0xf6bb4b60);
1257 b = md5Round3(a: b, b: c, c: d, d: a, Xk: x[10], s: 23, Ti: 0xbebfbc70);
1258 a = md5Round3(a, b, c, d, Xk: x[13], s: 4, Ti: 0x289b7ec6);
1259 d = md5Round3(a: d, b: a, c: b, d: c, Xk: x[0], s: 11, Ti: 0xeaa127fa);
1260 c = md5Round3(a: c, b: d, c: a, d: b, Xk: x[3], s: 16, Ti: 0xd4ef3085);
1261 b = md5Round3(a: b, b: c, c: d, d: a, Xk: x[6], s: 23, Ti: 0x04881d05);
1262 a = md5Round3(a, b, c, d, Xk: x[9], s: 4, Ti: 0xd9d4d039);
1263 d = md5Round3(a: d, b: a, c: b, d: c, Xk: x[12], s: 11, Ti: 0xe6db99e5);
1264 c = md5Round3(a: c, b: d, c: a, d: b, Xk: x[15], s: 16, Ti: 0x1fa27cf8);
1265 b = md5Round3(a: b, b: c, c: d, d: a, Xk: x[2], s: 23, Ti: 0xc4ac5665);
1266
1267 // round 4
1268 a = md5Round4(a, b, c, d, Xk: x[0], s: 6, Ti: 0xf4292244);
1269 d = md5Round4(a: d, b: a, c: b, d: c, Xk: x[7], s: 10, Ti: 0x432aff97);
1270 c = md5Round4(a: c, b: d, c: a, d: b, Xk: x[14], s: 15, Ti: 0xab9423a7);
1271 b = md5Round4(a: b, b: c, c: d, d: a, Xk: x[5], s: 21, Ti: 0xfc93a039);
1272 a = md5Round4(a, b, c, d, Xk: x[12], s: 6, Ti: 0x655b59c3);
1273 d = md5Round4(a: d, b: a, c: b, d: c, Xk: x[3], s: 10, Ti: 0x8f0ccc92);
1274 c = md5Round4(a: c, b: d, c: a, d: b, Xk: x[10], s: 15, Ti: 0xffeff47d);
1275 b = md5Round4(a: b, b: c, c: d, d: a, Xk: x[1], s: 21, Ti: 0x85845dd1);
1276 a = md5Round4(a, b, c, d, Xk: x[8], s: 6, Ti: 0x6fa87e4f);
1277 d = md5Round4(a: d, b: a, c: b, d: c, Xk: x[15], s: 10, Ti: 0xfe2ce6e0);
1278 c = md5Round4(a: c, b: d, c: a, d: b, Xk: x[6], s: 15, Ti: 0xa3014314);
1279 b = md5Round4(a: b, b: c, c: d, d: a, Xk: x[13], s: 21, Ti: 0x4e0811a1);
1280 a = md5Round4(a, b, c, d, Xk: x[4], s: 6, Ti: 0xf7537e82);
1281 d = md5Round4(a: d, b: a, c: b, d: c, Xk: x[11], s: 10, Ti: 0xbd3af235);
1282 c = md5Round4(a: c, b: d, c: a, d: b, Xk: x[2], s: 15, Ti: 0x2ad7d2bb);
1283 b = md5Round4(a: b, b: c, c: d, d: a, Xk: x[9], s: 21, Ti: 0xeb86d391);
1284
1285 // increment a, b, c, d
1286 state->a += a;
1287 state->b += b;
1288 state->c += c;
1289 state->d += d;
1290
1291 state->bufLen = 0;
1292}
1293
1294static void md5Append(MD5State *state, const unsigned char *data, int dataLen)
1295{
1296 const unsigned char *p = data;
1297 int remain = dataLen;
1298 while (state->bufLen + remain >= 64) {
1299 const int k = 64 - state->bufLen;
1300 memcpy(dest: state->buf + state->bufLen, src: p, n: k);
1301 state->bufLen = 64;
1302 md5ProcessBlock(state);
1303 p += k;
1304 remain -= k;
1305 }
1306 if (remain > 0) {
1307 memcpy(dest: state->buf + state->bufLen, src: p, n: remain);
1308 state->bufLen += remain;
1309 }
1310 state->msgLen += dataLen;
1311}
1312
1313static void md5Finish(MD5State *state)
1314{
1315 // padding and length
1316 state->buf[state->bufLen++] = 0x80;
1317 if (state->bufLen > 56) {
1318 while (state->bufLen < 64) {
1319 state->buf[state->bufLen++] = 0x00;
1320 }
1321 md5ProcessBlock(state);
1322 }
1323 while (state->bufLen < 56) {
1324 state->buf[state->bufLen++] = 0x00;
1325 }
1326 state->buf[56] = (unsigned char)(state->msgLen << 3);
1327 state->buf[57] = (unsigned char)(state->msgLen >> 5);
1328 state->buf[58] = (unsigned char)(state->msgLen >> 13);
1329 state->buf[59] = (unsigned char)(state->msgLen >> 21);
1330 state->buf[60] = (unsigned char)(state->msgLen >> 29);
1331 state->buf[61] = (unsigned char)0;
1332 state->buf[62] = (unsigned char)0;
1333 state->buf[63] = (unsigned char)0;
1334 state->bufLen = 64;
1335 md5ProcessBlock(state);
1336
1337 // break digest into bytes
1338 state->digest[0] = (unsigned char)state->a;
1339 state->digest[1] = (unsigned char)(state->a >> 8);
1340 state->digest[2] = (unsigned char)(state->a >> 16);
1341 state->digest[3] = (unsigned char)(state->a >> 24);
1342 state->digest[4] = (unsigned char)state->b;
1343 state->digest[5] = (unsigned char)(state->b >> 8);
1344 state->digest[6] = (unsigned char)(state->b >> 16);
1345 state->digest[7] = (unsigned char)(state->b >> 24);
1346 state->digest[8] = (unsigned char)state->c;
1347 state->digest[9] = (unsigned char)(state->c >> 8);
1348 state->digest[10] = (unsigned char)(state->c >> 16);
1349 state->digest[11] = (unsigned char)(state->c >> 24);
1350 state->digest[12] = (unsigned char)state->d;
1351 state->digest[13] = (unsigned char)(state->d >> 8);
1352 state->digest[14] = (unsigned char)(state->d >> 16);
1353 state->digest[15] = (unsigned char)(state->d >> 24);
1354}
1355
1356void md5(const unsigned char *msg, int msgLen, unsigned char *digest)
1357{
1358 if (msgLen < 0) {
1359 return;
1360 }
1361 MD5State state;
1362 md5Start(state: &state);
1363 md5Append(state: &state, data: msg, dataLen: msgLen);
1364 md5Finish(state: &state);
1365 for (int i = 0; i < 16; ++i) {
1366 digest[i] = state.digest[i];
1367 }
1368}
1369
1370//------------------------------------------------------------------------
1371// SHA-256 hash
1372//------------------------------------------------------------------------
1373
1374static const unsigned int sha256K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1375 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1376 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1377 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
1378
1379static inline unsigned int rotr(unsigned int x, unsigned int n)
1380{
1381 return (x >> n) | (x << (32 - n));
1382}
1383
1384static inline unsigned int sha256Ch(unsigned int x, unsigned int y, unsigned int z)
1385{
1386 return (x & y) ^ (~x & z);
1387}
1388
1389static inline unsigned int sha256Maj(unsigned int x, unsigned int y, unsigned int z)
1390{
1391 return (x & y) ^ (x & z) ^ (y & z);
1392}
1393
1394static inline unsigned int sha256Sigma0(unsigned int x)
1395{
1396 return rotr(x, n: 2) ^ rotr(x, n: 13) ^ rotr(x, n: 22);
1397}
1398
1399static inline unsigned int sha256Sigma1(unsigned int x)
1400{
1401 return rotr(x, n: 6) ^ rotr(x, n: 11) ^ rotr(x, n: 25);
1402}
1403
1404static inline unsigned int sha256sigma0(unsigned int x)
1405{
1406 return rotr(x, n: 7) ^ rotr(x, n: 18) ^ (x >> 3);
1407}
1408
1409static inline unsigned int sha256sigma1(unsigned int x)
1410{
1411 return rotr(x, n: 17) ^ rotr(x, n: 19) ^ (x >> 10);
1412}
1413
1414static void sha256HashBlock(const unsigned char *blk, unsigned int *H)
1415{
1416 unsigned int W[64];
1417 unsigned int a, b, c, d, e, f, g, h;
1418 unsigned int T1, T2;
1419 unsigned int t;
1420
1421 // 1. prepare the message schedule
1422 for (t = 0; t < 16; ++t) {
1423 W[t] = (blk[t * 4] << 24) | (blk[t * 4 + 1] << 16) | (blk[t * 4 + 2] << 8) | blk[t * 4 + 3];
1424 }
1425 for (t = 16; t < 64; ++t) {
1426 W[t] = sha256sigma1(x: W[t - 2]) + W[t - 7] + sha256sigma0(x: W[t - 15]) + W[t - 16];
1427 }
1428
1429 // 2. initialize the eight working variables
1430 a = H[0];
1431 b = H[1];
1432 c = H[2];
1433 d = H[3];
1434 e = H[4];
1435 f = H[5];
1436 g = H[6];
1437 h = H[7];
1438
1439 // 3.
1440 for (t = 0; t < 64; ++t) {
1441 T1 = h + sha256Sigma1(x: e) + sha256Ch(x: e, y: f, z: g) + sha256K[t] + W[t];
1442 T2 = sha256Sigma0(x: a) + sha256Maj(x: a, y: b, z: c);
1443 h = g;
1444 g = f;
1445 f = e;
1446 e = d + T1;
1447 d = c;
1448 c = b;
1449 b = a;
1450 a = T1 + T2;
1451 }
1452
1453 // 4. compute the intermediate hash value
1454 H[0] += a;
1455 H[1] += b;
1456 H[2] += c;
1457 H[3] += d;
1458 H[4] += e;
1459 H[5] += f;
1460 H[6] += g;
1461 H[7] += h;
1462}
1463
1464static void sha256(unsigned char *msg, int msgLen, unsigned char *hash)
1465{
1466 unsigned char blk[64];
1467 unsigned int H[8];
1468 int blkLen, i;
1469
1470 H[0] = 0x6a09e667;
1471 H[1] = 0xbb67ae85;
1472 H[2] = 0x3c6ef372;
1473 H[3] = 0xa54ff53a;
1474 H[4] = 0x510e527f;
1475 H[5] = 0x9b05688c;
1476 H[6] = 0x1f83d9ab;
1477 H[7] = 0x5be0cd19;
1478
1479 blkLen = 0;
1480 for (i = 0; i + 64 <= msgLen; i += 64) {
1481 sha256HashBlock(blk: msg + i, H);
1482 }
1483 blkLen = msgLen - i;
1484 if (blkLen > 0) {
1485 memcpy(dest: blk, src: msg + i, n: blkLen);
1486 }
1487
1488 // pad the message
1489 blk[blkLen++] = 0x80;
1490 if (blkLen > 56) {
1491 while (blkLen < 64) {
1492 blk[blkLen++] = 0;
1493 }
1494 sha256HashBlock(blk, H);
1495 blkLen = 0;
1496 }
1497 while (blkLen < 56) {
1498 blk[blkLen++] = 0;
1499 }
1500 blk[56] = 0;
1501 blk[57] = 0;
1502 blk[58] = 0;
1503 blk[59] = 0;
1504 blk[60] = (unsigned char)(msgLen >> 21);
1505 blk[61] = (unsigned char)(msgLen >> 13);
1506 blk[62] = (unsigned char)(msgLen >> 5);
1507 blk[63] = (unsigned char)(msgLen << 3);
1508 sha256HashBlock(blk, H);
1509
1510 // copy the output into the buffer (convert words to bytes)
1511 for (i = 0; i < 8; ++i) {
1512 hash[i * 4] = (unsigned char)(H[i] >> 24);
1513 hash[i * 4 + 1] = (unsigned char)(H[i] >> 16);
1514 hash[i * 4 + 2] = (unsigned char)(H[i] >> 8);
1515 hash[i * 4 + 3] = (unsigned char)H[i];
1516 }
1517}
1518//------------------------------------------------------------------------
1519// SHA-512 hash (see FIPS 180-4)
1520//------------------------------------------------------------------------
1521// SHA 384 and SHA 512 use the same sequence of eighty constant 64 bit words.
1522static const uint64_t shaK[80] = { 0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full, 0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull, 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull,
1523 0xd807aa98a3030242ull, 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull, 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull, 0xc19bf174cf692694ull,
1524 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull, 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull, 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
1525 0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full, 0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull, 0x06ca6351e003826full, 0x142929670a0e6e70ull,
1526 0x27b70a8546d22ffcull, 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull, 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull, 0x92722c851482353bull,
1527 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull, 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull, 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
1528 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull, 0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull, 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull,
1529 0x748f82ee5defb2fcull, 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull, 0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull, 0xc67178f2e372532bull,
1530 0xca273eceea26619cull, 0xd186b8c721c0c207ull, 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull, 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull,
1531 0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull, 0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull, 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull };
1532
1533static inline uint64_t rotr(uint64_t x, uint64_t n)
1534{
1535 return (x >> n) | (x << (64 - n));
1536}
1537static inline uint64_t sha512Ch(uint64_t x, uint64_t y, uint64_t z)
1538{
1539 return (x & y) ^ (~x & z);
1540}
1541static inline uint64_t sha512Maj(uint64_t x, uint64_t y, uint64_t z)
1542{
1543 return (x & y) ^ (x & z) ^ (y & z);
1544}
1545static inline uint64_t sha512Sigma0(uint64_t x)
1546{
1547 return rotr(x, n: 28) ^ rotr(x, n: 34) ^ rotr(x, n: 39);
1548}
1549static inline uint64_t sha512Sigma1(uint64_t x)
1550{
1551 return rotr(x, n: 14) ^ rotr(x, n: 18) ^ rotr(x, n: 41);
1552}
1553static inline uint64_t sha512sigma0(uint64_t x)
1554{
1555 return rotr(x, n: 1) ^ rotr(x, n: 8) ^ (x >> 7);
1556}
1557static inline uint64_t sha512sigma1(uint64_t x)
1558{
1559 return rotr(x, n: 19) ^ rotr(x, n: 61) ^ (x >> 6);
1560}
1561
1562static void sha512HashBlock(const unsigned char *blk, uint64_t *H)
1563{
1564 uint64_t W[80];
1565 uint64_t a, b, c, d, e, f, g, h;
1566 uint64_t T1, T2;
1567 unsigned int t;
1568
1569 // 1. prepare the message schedule
1570 for (t = 0; t < 16; ++t) {
1571 W[t] = (((uint64_t)blk[t * 8] << 56) | ((uint64_t)blk[t * 8 + 1] << 48) | ((uint64_t)blk[t * 8 + 2] << 40) | ((uint64_t)blk[t * 8 + 3] << 32) | ((uint64_t)blk[t * 8 + 4] << 24) | ((uint64_t)blk[t * 8 + 5] << 16)
1572 | ((uint64_t)blk[t * 8 + 6] << 8) | ((uint64_t)blk[t * 8 + 7]));
1573 }
1574 for (t = 16; t < 80; ++t) {
1575 W[t] = sha512sigma1(x: W[t - 2]) + W[t - 7] + sha512sigma0(x: W[t - 15]) + W[t - 16];
1576 }
1577
1578 // 2. initialize the eight working variables
1579 a = H[0];
1580 b = H[1];
1581 c = H[2];
1582 d = H[3];
1583 e = H[4];
1584 f = H[5];
1585 g = H[6];
1586 h = H[7];
1587
1588 // 3.
1589 for (t = 0; t < 80; ++t) {
1590 T1 = h + sha512Sigma1(x: e) + sha512Ch(x: e, y: f, z: g) + shaK[t] + W[t];
1591 T2 = sha512Sigma0(x: a) + sha512Maj(x: a, y: b, z: c);
1592 h = g;
1593 g = f;
1594 f = e;
1595 e = d + T1;
1596 d = c;
1597 c = b;
1598 b = a;
1599 a = T1 + T2;
1600 }
1601
1602 // 4. compute the intermediate hash value
1603 H[0] += a;
1604 H[1] += b;
1605 H[2] += c;
1606 H[3] += d;
1607 H[4] += e;
1608 H[5] += f;
1609 H[6] += g;
1610 H[7] += h;
1611}
1612
1613static void sha512(unsigned char *msg, int msgLen, unsigned char *hash)
1614{
1615 unsigned char blk[128];
1616 uint64_t H[8];
1617 int blkLen = 0, i;
1618 // setting the initial hash value.
1619 H[0] = 0x6a09e667f3bcc908ull;
1620 H[1] = 0xbb67ae8584caa73bull;
1621 H[2] = 0x3c6ef372fe94f82bull;
1622 H[3] = 0xa54ff53a5f1d36f1ull;
1623 H[4] = 0x510e527fade682d1ull;
1624 H[5] = 0x9b05688c2b3e6c1full;
1625 H[6] = 0x1f83d9abfb41bd6bull;
1626 H[7] = 0x5be0cd19137e2179ull;
1627
1628 for (i = 0; i + 128 <= msgLen; i += 128) {
1629 sha512HashBlock(blk: msg + i, H);
1630 }
1631 blkLen = msgLen - i;
1632 if (blkLen > 0) {
1633 memcpy(dest: blk, src: msg + i, n: blkLen);
1634 }
1635
1636 // pad the message
1637 blk[blkLen++] = 0x80;
1638 if (blkLen > 112) {
1639 while (blkLen < 128) {
1640 blk[blkLen++] = 0;
1641 }
1642 sha512HashBlock(blk, H);
1643 blkLen = 0;
1644 }
1645 while (blkLen < 112) {
1646 blk[blkLen++] = 0;
1647 }
1648 blk[112] = 0;
1649 blk[113] = 0;
1650 blk[114] = 0;
1651 blk[115] = 0;
1652 blk[116] = 0;
1653 blk[117] = 0;
1654 blk[118] = 0;
1655 blk[119] = 0;
1656 blk[120] = 0;
1657 blk[121] = 0;
1658 blk[122] = 0;
1659 blk[123] = 0;
1660 blk[124] = (unsigned char)(msgLen >> 21);
1661 blk[125] = (unsigned char)(msgLen >> 13);
1662 blk[126] = (unsigned char)(msgLen >> 5);
1663 blk[127] = (unsigned char)(msgLen << 3);
1664
1665 sha512HashBlock(blk, H);
1666
1667 // copy the output into the buffer (convert words to bytes)
1668 for (i = 0; i < 8; ++i) {
1669 hash[i * 8] = (unsigned char)(H[i] >> 56);
1670 hash[i * 8 + 1] = (unsigned char)(H[i] >> 48);
1671 hash[i * 8 + 2] = (unsigned char)(H[i] >> 40);
1672 hash[i * 8 + 3] = (unsigned char)(H[i] >> 32);
1673 hash[i * 8 + 4] = (unsigned char)(H[i] >> 24);
1674 hash[i * 8 + 5] = (unsigned char)(H[i] >> 16);
1675 hash[i * 8 + 6] = (unsigned char)(H[i] >> 8);
1676 hash[i * 8 + 7] = (unsigned char)H[i];
1677 }
1678}
1679
1680//------------------------------------------------------------------------
1681// SHA-384 (see FIPS 180-4)
1682//------------------------------------------------------------------------
1683// The algorithm is defined in the exact same manner as SHA 512 with 2 exceptions
1684// 1.Initial hash value is different.
1685// 2.A 384 bit message digest is obtained by truncating the final hash value.
1686static void sha384(unsigned char *msg, int msgLen, unsigned char *hash)
1687{
1688 unsigned char blk[128];
1689 uint64_t H[8];
1690 int blkLen, i;
1691 // setting initial hash values
1692 H[0] = 0xcbbb9d5dc1059ed8ull;
1693 H[1] = 0x629a292a367cd507ull;
1694 H[2] = 0x9159015a3070dd17ull;
1695 H[3] = 0x152fecd8f70e5939ull;
1696 H[4] = 0x67332667ffc00b31ull;
1697 H[5] = 0x8eb44a8768581511ull;
1698 H[6] = 0xdb0c2e0d64f98fa7ull;
1699 H[7] = 0x47b5481dbefa4fa4ull;
1700 // SHA 384 will use the same sha512HashBlock function.
1701 blkLen = 0;
1702 for (i = 0; i + 128 <= msgLen; i += 128) {
1703 sha512HashBlock(blk: msg + i, H);
1704 }
1705 blkLen = msgLen - i;
1706 if (blkLen > 0) {
1707 memcpy(dest: blk, src: msg + i, n: blkLen);
1708 }
1709
1710 // pad the message
1711 blk[blkLen++] = 0x80;
1712 if (blkLen > 112) {
1713 while (blkLen < 128) {
1714 blk[blkLen++] = 0;
1715 }
1716 sha512HashBlock(blk, H);
1717 blkLen = 0;
1718 }
1719 while (blkLen < 112) {
1720 blk[blkLen++] = 0;
1721 }
1722 blk[112] = 0;
1723 blk[113] = 0;
1724 blk[114] = 0;
1725 blk[115] = 0;
1726 blk[116] = 0;
1727 blk[117] = 0;
1728 blk[118] = 0;
1729 blk[119] = 0;
1730 blk[120] = 0;
1731 blk[121] = 0;
1732 blk[122] = 0;
1733 blk[123] = 0;
1734 blk[124] = (unsigned char)(msgLen >> 21);
1735 blk[125] = (unsigned char)(msgLen >> 13);
1736 blk[126] = (unsigned char)(msgLen >> 5);
1737 blk[127] = (unsigned char)(msgLen << 3);
1738
1739 sha512HashBlock(blk, H);
1740
1741 // copy the output into the buffer (convert words to bytes)
1742 // hash is truncated to 384 bits.
1743 for (i = 0; i < 6; ++i) {
1744 hash[i * 8] = (unsigned char)(H[i] >> 56);
1745 hash[i * 8 + 1] = (unsigned char)(H[i] >> 48);
1746 hash[i * 8 + 2] = (unsigned char)(H[i] >> 40);
1747 hash[i * 8 + 3] = (unsigned char)(H[i] >> 32);
1748 hash[i * 8 + 4] = (unsigned char)(H[i] >> 24);
1749 hash[i * 8 + 5] = (unsigned char)(H[i] >> 16);
1750 hash[i * 8 + 6] = (unsigned char)(H[i] >> 8);
1751 hash[i * 8 + 7] = (unsigned char)H[i];
1752 }
1753}
1754
1755//------------------------------------------------------------------------
1756// Section 7.6.3.3 (Encryption Key algorithm) of ISO/DIS 32000-2
1757// Algorithm 2.B:Computing a hash (for revision 6).
1758//------------------------------------------------------------------------
1759static void revision6Hash(const GooString *inputPassword, unsigned char *K, const char *userKey)
1760{
1761 unsigned char K1[64 * (127 + 64 + 48)];
1762 unsigned char E[64 * (127 + 64 + 48)];
1763 DecryptAESState state;
1764 unsigned char aesKey[16];
1765 unsigned char BE16byteNumber[16];
1766
1767 int inputPasswordLength = inputPassword->getLength();
1768 int KLength = 32;
1769 const int userKeyLength = userKey ? 48 : 0;
1770 int sequenceLength;
1771 int totalLength;
1772 int rounds = 0;
1773
1774 while (rounds < 64 || rounds < E[totalLength - 1] + 32) {
1775 sequenceLength = inputPasswordLength + KLength + userKeyLength;
1776 totalLength = 64 * sequenceLength;
1777 // a.make the string K1
1778 memcpy(dest: K1, src: inputPassword->c_str(), n: inputPasswordLength);
1779 memcpy(dest: K1 + inputPasswordLength, src: K, n: KLength);
1780 if (userKey) {
1781 memcpy(dest: K1 + inputPasswordLength + KLength, src: userKey, n: userKeyLength);
1782 }
1783 for (int i = 1; i < 64; ++i) {
1784 memcpy(dest: K1 + (i * sequenceLength), src: K1, n: sequenceLength);
1785 }
1786 // b.Encrypt K1
1787 memcpy(dest: aesKey, src: K, n: 16);
1788 memcpy(dest: state.cbc, src: K + 16, n: 16);
1789 memcpy(dest: state.buf, src: state.cbc, n: 16); // Copy CBC IV to buf
1790 state.bufIdx = 0;
1791 state.paddingReached = false;
1792 aesKeyExpansion(s: &state, objKey: aesKey, 16, decrypt: false);
1793
1794 for (int i = 0; i < (4 * sequenceLength); i++) {
1795 aesEncryptBlock(s: &state, in: K1 + (16 * i));
1796 memcpy(dest: E + (16 * i), src: state.buf, n: 16);
1797 }
1798 memcpy(dest: BE16byteNumber, src: E, n: 16);
1799 // c.Taking the first 16 Bytes of E as unsigned big-endian integer,
1800 // compute the remainder,modulo 3.
1801 uint64_t N1 = 0, N2 = 0, N3 = 0;
1802 // N1 contains first 8 bytes of BE16byteNumber
1803 N1 = ((uint64_t)BE16byteNumber[0] << 56 | (uint64_t)BE16byteNumber[1] << 48 | (uint64_t)BE16byteNumber[2] << 40 | (uint64_t)BE16byteNumber[3] << 32 | (uint64_t)BE16byteNumber[4] << 24 | (uint64_t)BE16byteNumber[5] << 16
1804 | (uint64_t)BE16byteNumber[6] << 8 | (uint64_t)BE16byteNumber[7]);
1805 uint64_t rem = N1 % 3;
1806 // N2 contains 0s in higher 4 bytes and 9th to 12 th bytes of BE16byteNumber in lower 4 bytes.
1807 N2 = ((uint64_t)BE16byteNumber[8] << 24 | (uint64_t)BE16byteNumber[9] << 16 | (uint64_t)BE16byteNumber[10] << 8 | (uint64_t)BE16byteNumber[11]);
1808 rem = ((rem << 32) | N2) % 3;
1809 // N3 contains 0s in higher 4 bytes and 13th to 16th bytes of BE16byteNumber in lower 4 bytes.
1810 N3 = ((uint64_t)BE16byteNumber[12] << 24 | (uint64_t)BE16byteNumber[13] << 16 | (uint64_t)BE16byteNumber[14] << 8 | (uint64_t)BE16byteNumber[15]);
1811 rem = ((rem << 32) | N3) % 3;
1812
1813 // d.If remainder is 0 perform SHA-256
1814 if (rem == 0) {
1815 KLength = 32;
1816 sha256(msg: E, msgLen: totalLength, hash: K);
1817 }
1818 // remainder is 1 perform SHA-384
1819 else if (rem == 1) {
1820 KLength = 48;
1821 sha384(msg: E, msgLen: totalLength, hash: K);
1822 }
1823 // remainder is 2 perform SHA-512
1824 else if (rem == 2) {
1825 KLength = 64;
1826 sha512(msg: E, msgLen: totalLength, hash: K);
1827 }
1828 rounds++;
1829 }
1830 // the first 32 bytes of the final K are the output of the function.
1831}
1832

source code of poppler/poppler/Decrypt.cc