beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / Decrypt.cc
blobba44f959c310a7a710a355fb06565c0c3f9838a2
1 //========================================================================
2 //
3 // Decrypt.cc
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
17 // Copyright (C) 2008, 2010 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 Adrian Johnson <ajohnson@redneon.com>
23 // To see a description of the changes please see the Changelog file that
24 // came with your tarball or type make ChangeLog if you are building from git
26 //========================================================================
28 #include <config.h>
30 #ifdef USE_GCC_PRAGMAS
31 #pragma implementation
32 #endif
34 #include <string.h>
35 #include "goo/gmem.h"
36 #include "goo/grandom.h"
37 #include "Decrypt.h"
38 #include "Error.h"
40 static void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
41 static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
43 static GBool aesReadBlock(Stream *str, Guchar *in, GBool addPadding);
45 static void aesKeyExpansion(DecryptAESState *s, Guchar *objKey, int objKeyLen, GBool decrypt);
46 static void aesEncryptBlock(DecryptAESState *s, Guchar *in);
47 static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last);
49 static void aes256KeyExpansion(DecryptAES256State *s, Guchar *objKey, int objKeyLen, GBool decrypt);
50 static void aes256EncryptBlock(DecryptAES256State *s, Guchar *in);
51 static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last);
53 static void sha256(Guchar *msg, int msgLen, Guchar *hash);
55 static const Guchar passwordPad[32] = {
56 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
57 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
58 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
59 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
62 //------------------------------------------------------------------------
63 // Decrypt
64 //------------------------------------------------------------------------
66 GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
67 GooString *ownerKey, GooString *userKey,
68 GooString *ownerEnc, GooString *userEnc,
69 int permissions, GooString *fileID,
70 GooString *ownerPassword, GooString *userPassword,
71 Guchar *fileKey, GBool encryptMetadata,
72 GBool *ownerPasswordOk) {
73 DecryptAES256State state;
74 Guchar test[127 + 56], test2[32];
75 GooString *userPassword2;
76 Guchar fState[256];
77 Guchar tmpKey[16];
78 Guchar fx, fy;
79 int len, i, j;
81 *ownerPasswordOk = gFalse;
83 if (encRevision == 5) {
85 // check the owner password
86 if (ownerPassword) {
87 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
88 len = ownerPassword->getLength();
89 if (len > 127) {
90 len = 127;
92 memcpy(test, ownerPassword->getCString(), len);
93 memcpy(test + len, ownerKey->getCString() + 32, 8);
94 memcpy(test + len + 8, userKey->getCString(), 48);
95 sha256(test, len + 56, test);
96 if (!memcmp(test, ownerKey->getCString(), 32)) {
98 // compute the file key from the owner password
99 memcpy(test, ownerPassword->getCString(), len);
100 memcpy(test + len, ownerKey->getCString() + 40, 8);
101 memcpy(test + len + 8, userKey->getCString(), 48);
102 sha256(test, len + 56, test);
103 aes256KeyExpansion(&state, test, 32, gTrue);
104 for (i = 0; i < 16; ++i) {
105 state.cbc[i] = 0;
107 aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString(), gFalse);
108 memcpy(fileKey, state.buf, 16);
109 aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString() + 16,
110 gFalse);
111 memcpy(fileKey + 16, state.buf, 16);
113 *ownerPasswordOk = gTrue;
114 return gTrue;
118 // check the user password
119 if (userPassword) {
120 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
121 len = userPassword->getLength();
122 if (len > 127) {
123 len = 127;
125 memcpy(test, userPassword->getCString(), len);
126 memcpy(test + len, userKey->getCString() + 32, 8);
127 sha256(test, len + 8, test);
128 if (!memcmp(test, userKey->getCString(), 32)) {
130 // compute the file key from the user password
131 memcpy(test, userPassword->getCString(), len);
132 memcpy(test + len, userKey->getCString() + 40, 8);
133 sha256(test, len + 8, test);
134 aes256KeyExpansion(&state, test, 32, gTrue);
135 for (i = 0; i < 16; ++i) {
136 state.cbc[i] = 0;
138 aes256DecryptBlock(&state, (Guchar *)userEnc->getCString(), gFalse);
139 memcpy(fileKey, state.buf, 16);
140 aes256DecryptBlock(&state, (Guchar *)userEnc->getCString() + 16,
141 gFalse);
142 memcpy(fileKey + 16, state.buf, 16);
144 return gTrue;
148 return gFalse;
149 } else {
151 // try using the supplied owner password to generate the user password
152 if (ownerPassword) {
153 len = ownerPassword->getLength();
154 if (len < 32) {
155 memcpy(test, ownerPassword->getCString(), len);
156 memcpy(test + len, passwordPad, 32 - len);
157 } else {
158 memcpy(test, ownerPassword->getCString(), 32);
160 md5(test, 32, test);
161 if (encRevision == 3) {
162 for (i = 0; i < 50; ++i) {
163 md5(test, keyLength, test);
166 if (encRevision == 2) {
167 rc4InitKey(test, keyLength, fState);
168 fx = fy = 0;
169 for (i = 0; i < 32; ++i) {
170 test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
172 } else {
173 memcpy(test2, ownerKey->getCString(), 32);
174 for (i = 19; i >= 0; --i) {
175 for (j = 0; j < keyLength; ++j) {
176 tmpKey[j] = test[j] ^ i;
178 rc4InitKey(tmpKey, keyLength, fState);
179 fx = fy = 0;
180 for (j = 0; j < 32; ++j) {
181 test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]);
185 userPassword2 = new GooString((char *)test2, 32);
186 if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
187 permissions, fileID, userPassword2, fileKey,
188 encryptMetadata)) {
189 *ownerPasswordOk = gTrue;
190 delete userPassword2;
191 return gTrue;
193 delete userPassword2;
196 // try using the supplied user password
197 return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
198 permissions, fileID, userPassword, fileKey,
199 encryptMetadata);
203 GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
204 GooString *ownerKey, GooString *userKey,
205 int permissions, GooString *fileID,
206 GooString *userPassword, Guchar *fileKey,
207 GBool encryptMetadata) {
208 Guchar *buf;
209 Guchar test[32];
210 Guchar fState[256];
211 Guchar tmpKey[16];
212 Guchar fx, fy;
213 int len, i, j;
214 GBool ok;
216 // generate file key
217 buf = (Guchar *)gmalloc(72 + fileID->getLength());
218 if (userPassword) {
219 len = userPassword->getLength();
220 if (len < 32) {
221 memcpy(buf, userPassword->getCString(), len);
222 memcpy(buf + len, passwordPad, 32 - len);
223 } else {
224 memcpy(buf, userPassword->getCString(), 32);
226 } else {
227 memcpy(buf, passwordPad, 32);
229 memcpy(buf + 32, ownerKey->getCString(), 32);
230 buf[64] = permissions & 0xff;
231 buf[65] = (permissions >> 8) & 0xff;
232 buf[66] = (permissions >> 16) & 0xff;
233 buf[67] = (permissions >> 24) & 0xff;
234 memcpy(buf + 68, fileID->getCString(), fileID->getLength());
235 len = 68 + fileID->getLength();
236 if (!encryptMetadata) {
237 buf[len++] = 0xff;
238 buf[len++] = 0xff;
239 buf[len++] = 0xff;
240 buf[len++] = 0xff;
242 md5(buf, len, fileKey);
243 if (encRevision == 3) {
244 for (i = 0; i < 50; ++i) {
245 md5(fileKey, keyLength, fileKey);
249 // test user password
250 if (encRevision == 2) {
251 rc4InitKey(fileKey, keyLength, fState);
252 fx = fy = 0;
253 for (i = 0; i < 32; ++i) {
254 test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i));
256 ok = memcmp(test, passwordPad, 32) == 0;
257 } else if (encRevision == 3) {
258 memcpy(test, userKey->getCString(), 32);
259 for (i = 19; i >= 0; --i) {
260 for (j = 0; j < keyLength; ++j) {
261 tmpKey[j] = fileKey[j] ^ i;
263 rc4InitKey(tmpKey, keyLength, fState);
264 fx = fy = 0;
265 for (j = 0; j < 32; ++j) {
266 test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]);
269 memcpy(buf, passwordPad, 32);
270 memcpy(buf + 32, fileID->getCString(), fileID->getLength());
271 md5(buf, 32 + fileID->getLength(), buf);
272 ok = memcmp(test, buf, 16) == 0;
273 } else {
274 ok = gFalse;
277 gfree(buf);
278 return ok;
281 //------------------------------------------------------------------------
282 // BaseCryptStream
283 //------------------------------------------------------------------------
285 BaseCryptStream::BaseCryptStream(Stream *strA, Guchar *fileKey, CryptAlgorithm algoA,
286 int keyLength, int objNum, int objGen):
287 FilterStream(strA)
289 int i;
291 algo = algoA;
293 // construct object key
294 for (i = 0; i < keyLength; ++i) {
295 objKey[i] = fileKey[i];
297 switch (algo) {
298 case cryptRC4:
299 objKey[keyLength] = objNum & 0xff;
300 objKey[keyLength + 1] = (objNum >> 8) & 0xff;
301 objKey[keyLength + 2] = (objNum >> 16) & 0xff;
302 objKey[keyLength + 3] = objGen & 0xff;
303 objKey[keyLength + 4] = (objGen >> 8) & 0xff;
304 md5(objKey, keyLength + 5, objKey);
305 if ((objKeyLength = keyLength + 5) > 16) {
306 objKeyLength = 16;
308 break;
309 case cryptAES:
310 objKey[keyLength] = objNum & 0xff;
311 objKey[keyLength + 1] = (objNum >> 8) & 0xff;
312 objKey[keyLength + 2] = (objNum >> 16) & 0xff;
313 objKey[keyLength + 3] = objGen & 0xff;
314 objKey[keyLength + 4] = (objGen >> 8) & 0xff;
315 objKey[keyLength + 5] = 0x73; // 's'
316 objKey[keyLength + 6] = 0x41; // 'A'
317 objKey[keyLength + 7] = 0x6c; // 'l'
318 objKey[keyLength + 8] = 0x54; // 'T'
319 md5(objKey, keyLength + 9, objKey);
320 if ((objKeyLength = keyLength + 5) > 16) {
321 objKeyLength = 16;
323 break;
324 case cryptAES256:
325 objKeyLength = keyLength;
326 break;
329 charactersRead = 0;
330 autoDelete = gTrue;
333 BaseCryptStream::~BaseCryptStream() {
334 if (autoDelete) {
335 delete str;
339 void BaseCryptStream::reset() {
340 charactersRead = 0;
341 nextCharBuff = EOF;
342 str->reset();
345 Goffset BaseCryptStream::getPos() {
346 return charactersRead;
349 int BaseCryptStream::getChar() {
350 // Read next character and empty the buffer, so that a new character will be read next time
351 int c = lookChar();
352 nextCharBuff = EOF;
354 if (c != EOF)
355 charactersRead++;
356 return c;
359 GBool BaseCryptStream::isBinary(GBool last) {
360 return str->isBinary(last);
363 void BaseCryptStream::setAutoDelete(GBool val) {
364 autoDelete = val;
367 //------------------------------------------------------------------------
368 // EncryptStream
369 //------------------------------------------------------------------------
371 EncryptStream::EncryptStream(Stream *strA, Guchar *fileKey, CryptAlgorithm algoA,
372 int keyLength, int objNum, int objGen):
373 BaseCryptStream(strA, fileKey, algoA, keyLength, objNum, objGen)
375 // Fill the CBC initialization vector for AES and AES-256
376 switch (algo) {
377 case cryptAES:
378 grandom_fill(state.aes.cbc, 16);
379 break;
380 case cryptAES256:
381 grandom_fill(state.aes256.cbc, 16);
382 break;
383 default:
384 break;
388 EncryptStream::~EncryptStream() {
391 void EncryptStream::reset() {
392 BaseCryptStream::reset();
394 switch (algo) {
395 case cryptRC4:
396 state.rc4.x = state.rc4.y = 0;
397 rc4InitKey(objKey, objKeyLength, state.rc4.state);
398 break;
399 case cryptAES:
400 aesKeyExpansion(&state.aes, objKey, objKeyLength, gFalse);
401 memcpy(state.aes.buf, state.aes.cbc, 16); // Copy CBC IV to buf
402 state.aes.bufIdx = 0;
403 state.aes.paddingReached = gFalse;
404 break;
405 case cryptAES256:
406 aes256KeyExpansion(&state.aes256, objKey, objKeyLength, gFalse);
407 memcpy(state.aes256.buf, state.aes256.cbc, 16); // Copy CBC IV to buf
408 state.aes256.bufIdx = 0;
409 state.aes256.paddingReached = gFalse;
410 break;
414 int EncryptStream::lookChar() {
415 Guchar in[16];
416 int c;
418 if (nextCharBuff != EOF)
419 return nextCharBuff;
421 c = EOF; // make gcc happy
422 switch (algo) {
423 case cryptRC4:
424 if ((c = str->getChar()) != EOF) {
425 // RC4 is XOR-based: the decryption algorithm works for encryption too
426 c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (Guchar)c);
428 break;
429 case cryptAES:
430 if (state.aes.bufIdx == 16 && !state.aes.paddingReached) {
431 state.aes.paddingReached = !aesReadBlock(str, in, gTrue);
432 aesEncryptBlock(&state.aes, in);
434 if (state.aes.bufIdx == 16) {
435 c = EOF;
436 } else {
437 c = state.aes.buf[state.aes.bufIdx++];
439 break;
440 case cryptAES256:
441 if (state.aes256.bufIdx == 16 && !state.aes256.paddingReached) {
442 state.aes256.paddingReached = !aesReadBlock(str, in, gTrue);
443 aes256EncryptBlock(&state.aes256, in);
445 if (state.aes256.bufIdx == 16) {
446 c = EOF;
447 } else {
448 c = state.aes256.buf[state.aes256.bufIdx++];
450 break;
452 return (nextCharBuff = c);
455 //------------------------------------------------------------------------
456 // DecryptStream
457 //------------------------------------------------------------------------
459 DecryptStream::DecryptStream(Stream *strA, Guchar *fileKey, CryptAlgorithm algoA,
460 int keyLength, int objNum, int objGen):
461 BaseCryptStream(strA, fileKey, algoA, keyLength, objNum, objGen)
465 DecryptStream::~DecryptStream() {
468 void DecryptStream::reset() {
469 int i;
470 BaseCryptStream::reset();
472 switch (algo) {
473 case cryptRC4:
474 state.rc4.x = state.rc4.y = 0;
475 rc4InitKey(objKey, objKeyLength, state.rc4.state);
476 break;
477 case cryptAES:
478 aesKeyExpansion(&state.aes, objKey, objKeyLength, gTrue);
479 for (i = 0; i < 16; ++i) {
480 state.aes.cbc[i] = str->getChar();
482 state.aes.bufIdx = 16;
483 break;
484 case cryptAES256:
485 aes256KeyExpansion(&state.aes256, objKey, objKeyLength, gTrue);
486 for (i = 0; i < 16; ++i) {
487 state.aes256.cbc[i] = str->getChar();
489 state.aes256.bufIdx = 16;
490 break;
494 int DecryptStream::lookChar() {
495 Guchar in[16];
496 int c;
498 if (nextCharBuff != EOF)
499 return nextCharBuff;
501 c = EOF; // make gcc happy
502 switch (algo) {
503 case cryptRC4:
504 if ((c = str->getChar()) != EOF) {
505 c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (Guchar)c);
507 break;
508 case cryptAES:
509 if (state.aes.bufIdx == 16) {
510 if (aesReadBlock(str, in, gFalse)) {
511 aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
514 if (state.aes.bufIdx == 16) {
515 c = EOF;
516 } else {
517 c = state.aes.buf[state.aes.bufIdx++];
519 break;
520 case cryptAES256:
521 if (state.aes256.bufIdx == 16) {
522 if (aesReadBlock(str, in, gFalse)) {
523 aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
526 if (state.aes256.bufIdx == 16) {
527 c = EOF;
528 } else {
529 c = state.aes256.buf[state.aes256.bufIdx++];
531 break;
533 return (nextCharBuff = c);
536 //------------------------------------------------------------------------
537 // RC4-compatible decryption
538 //------------------------------------------------------------------------
540 static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
541 Guchar index1, index2;
542 Guchar t;
543 int i;
545 for (i = 0; i < 256; ++i)
546 state[i] = i;
548 if (unlikely(keyLen == 0))
549 return;
551 index1 = index2 = 0;
552 for (i = 0; i < 256; ++i) {
553 index2 = (key[index1] + state[i] + index2) % 256;
554 t = state[i];
555 state[i] = state[index2];
556 state[index2] = t;
557 index1 = (index1 + 1) % keyLen;
561 static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) {
562 Guchar x1, y1, tx, ty;
564 x1 = *x = (*x + 1) % 256;
565 y1 = *y = (state[*x] + *y) % 256;
566 tx = state[x1];
567 ty = state[y1];
568 state[x1] = ty;
569 state[y1] = tx;
570 return c ^ state[(tx + ty) % 256];
573 //------------------------------------------------------------------------
574 // AES decryption
575 //------------------------------------------------------------------------
577 // Returns gFalse if EOF was reached, gTrue otherwise
578 static GBool aesReadBlock(Stream *str, Guchar *in, GBool addPadding)
580 int c, i;
582 for (i = 0; i < 16; ++i) {
583 if ((c = str->getChar()) != EOF) {
584 in[i] = (Guchar)c;
585 } else {
586 break;
590 if (i == 16) {
591 return gTrue;
592 } else {
593 if (addPadding) {
594 c = 16 - i;
595 while (i < 16) {
596 in[i++] = (Guchar)c;
599 return gFalse;
603 static const Guchar sbox[256] = {
604 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
605 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
606 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
607 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
608 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
609 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
610 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
611 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
612 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
613 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
614 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
615 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
616 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
617 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
618 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
619 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
622 static const Guchar invSbox[256] = {
623 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
624 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
625 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
626 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
627 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
628 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
629 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
630 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
631 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
632 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
633 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
634 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
635 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
636 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
637 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
638 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
641 static const Guint rcon[11] = {
642 0x00000000, // unused
643 0x01000000,
644 0x02000000,
645 0x04000000,
646 0x08000000,
647 0x10000000,
648 0x20000000,
649 0x40000000,
650 0x80000000,
651 0x1b000000,
652 0x36000000
655 static inline Guint subWord(Guint x) {
656 return (sbox[x >> 24] << 24)
657 | (sbox[(x >> 16) & 0xff] << 16)
658 | (sbox[(x >> 8) & 0xff] << 8)
659 | sbox[x & 0xff];
662 static inline Guint rotWord(Guint x) {
663 return ((x << 8) & 0xffffffff) | (x >> 24);
666 static inline void subBytes(Guchar *state) {
667 int i;
669 for (i = 0; i < 16; ++i) {
670 state[i] = sbox[state[i]];
674 static inline void invSubBytes(Guchar *state) {
675 int i;
677 for (i = 0; i < 16; ++i) {
678 state[i] = invSbox[state[i]];
682 static inline void shiftRows(Guchar *state) {
683 Guchar t;
685 t = state[4];
686 state[4] = state[5];
687 state[5] = state[6];
688 state[6] = state[7];
689 state[7] = t;
691 t = state[8];
692 state[8] = state[10];
693 state[10] = t;
694 t = state[9];
695 state[9] = state[11];
696 state[11] = t;
698 t = state[15];
699 state[15] = state[14];
700 state[14] = state[13];
701 state[13] = state[12];
702 state[12] = t;
705 static inline void invShiftRows(Guchar *state) {
706 Guchar t;
708 t = state[7];
709 state[7] = state[6];
710 state[6] = state[5];
711 state[5] = state[4];
712 state[4] = t;
714 t = state[8];
715 state[8] = state[10];
716 state[10] = t;
717 t = state[9];
718 state[9] = state[11];
719 state[11] = t;
721 t = state[12];
722 state[12] = state[13];
723 state[13] = state[14];
724 state[14] = state[15];
725 state[15] = t;
728 // {02} \cdot s
729 static inline Guchar mul02(Guchar s) {
730 return (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
733 // {03} \cdot s
734 static inline Guchar mul03(Guchar s) {
735 Guchar s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
736 return s ^ s2;
739 // {09} \cdot s
740 static inline Guchar mul09(Guchar s) {
741 Guchar s2, s4, s8;
743 s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
744 s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
745 s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
746 return s ^ s8;
749 // {0b} \cdot s
750 static inline Guchar mul0b(Guchar s) {
751 Guchar s2, s4, s8;
753 s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
754 s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
755 s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
756 return s ^ s2 ^ s8;
759 // {0d} \cdot s
760 static inline Guchar mul0d(Guchar s) {
761 Guchar s2, s4, s8;
763 s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
764 s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
765 s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
766 return s ^ s4 ^ s8;
769 // {0e} \cdot s
770 static inline Guchar mul0e(Guchar s) {
771 Guchar s2, s4, s8;
773 s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
774 s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
775 s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
776 return s2 ^ s4 ^ s8;
779 static inline void mixColumns(Guchar *state) {
780 int c;
781 Guchar s0, s1, s2, s3;
783 for (c = 0; c < 4; ++c) {
784 s0 = state[c];
785 s1 = state[4+c];
786 s2 = state[8+c];
787 s3 = state[12+c];
788 state[c] = mul02(s0) ^ mul03(s1) ^ s2 ^ s3;
789 state[4+c] = s0 ^ mul02(s1) ^ mul03(s2) ^ s3;
790 state[8+c] = s0 ^ s1 ^ mul02(s2) ^ mul03(s3);
791 state[12+c] = mul03(s0) ^ s1 ^ s2 ^ mul02(s3);
795 static inline void invMixColumns(Guchar *state) {
796 int c;
797 Guchar s0, s1, s2, s3;
799 for (c = 0; c < 4; ++c) {
800 s0 = state[c];
801 s1 = state[4+c];
802 s2 = state[8+c];
803 s3 = state[12+c];
804 state[c] = mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3);
805 state[4+c] = mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3);
806 state[8+c] = mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3);
807 state[12+c] = mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3);
811 static inline void invMixColumnsW(Guint *w) {
812 int c;
813 Guchar s0, s1, s2, s3;
815 for (c = 0; c < 4; ++c) {
816 s0 = w[c] >> 24;
817 s1 = w[c] >> 16;
818 s2 = w[c] >> 8;
819 s3 = w[c];
820 w[c] = ((mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3)) << 24)
821 | ((mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3)) << 16)
822 | ((mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3)) << 8)
823 | (mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3));
827 static inline void addRoundKey(Guchar *state, Guint *w) {
828 int c;
830 for (c = 0; c < 4; ++c) {
831 state[c] ^= w[c] >> 24;
832 state[4+c] ^= w[c] >> 16;
833 state[8+c] ^= w[c] >> 8;
834 state[12+c] ^= w[c];
838 static void aesKeyExpansion(DecryptAESState *s,
839 Guchar *objKey, int /*objKeyLen*/, GBool decrypt) {
840 Guint temp;
841 int i, round;
843 //~ this assumes objKeyLen == 16
845 for (i = 0; i < 4; ++i) {
846 s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
847 (objKey[4*i+2] << 8) + objKey[4*i+3];
849 for (i = 4; i < 44; ++i) {
850 temp = s->w[i-1];
851 if (!(i & 3)) {
852 temp = subWord(rotWord(temp)) ^ rcon[i/4];
854 s->w[i] = s->w[i-4] ^ temp;
857 /* In case of decryption, adjust the key schedule for the equivalent inverse cipher */
858 if (decrypt) {
859 for (round = 1; round <= 9; ++round) {
860 invMixColumnsW(&s->w[round * 4]);
865 static void aesEncryptBlock(DecryptAESState *s, Guchar *in) {
866 int c, round;
868 // initial state (input is xor'd with previous output because of CBC)
869 for (c = 0; c < 4; ++c) {
870 s->state[c] = in[4*c] ^ s->buf[4*c];
871 s->state[4+c] = in[4*c+1] ^ s->buf[4*c+1];
872 s->state[8+c] = in[4*c+2] ^ s->buf[4*c+2];
873 s->state[12+c] = in[4*c+3] ^ s->buf[4*c+3];
876 // round 0
877 addRoundKey(s->state, &s->w[0]);
879 // rounds 1-9
880 for (round = 1; round <= 9; ++round) {
881 subBytes(s->state);
882 shiftRows(s->state);
883 mixColumns(s->state);
884 addRoundKey(s->state, &s->w[round * 4]);
887 // round 10
888 subBytes(s->state);
889 shiftRows(s->state);
890 addRoundKey(s->state, &s->w[10 * 4]);
892 for (c = 0; c < 4; ++c) {
893 s->buf[4*c] = s->state[c];
894 s->buf[4*c+1] = s->state[4+c];
895 s->buf[4*c+2] = s->state[8+c];
896 s->buf[4*c+3] = s->state[12+c];
899 s->bufIdx = 0;
902 static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last) {
903 int c, round, n, i;
905 // initial state
906 for (c = 0; c < 4; ++c) {
907 s->state[c] = in[4*c];
908 s->state[4+c] = in[4*c+1];
909 s->state[8+c] = in[4*c+2];
910 s->state[12+c] = in[4*c+3];
913 // round 0
914 addRoundKey(s->state, &s->w[10 * 4]);
916 // rounds 1-9
917 for (round = 9; round >= 1; --round) {
918 invSubBytes(s->state);
919 invShiftRows(s->state);
920 invMixColumns(s->state);
921 addRoundKey(s->state, &s->w[round * 4]);
924 // round 10
925 invSubBytes(s->state);
926 invShiftRows(s->state);
927 addRoundKey(s->state, &s->w[0]);
929 // CBC
930 for (c = 0; c < 4; ++c) {
931 s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
932 s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
933 s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
934 s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
937 // save the input block for the next CBC
938 for (i = 0; i < 16; ++i) {
939 s->cbc[i] = in[i];
942 // remove padding
943 s->bufIdx = 0;
944 if (last) {
945 n = s->buf[15];
946 if (n < 1 || n > 16) { // this should never happen
947 n = 16;
949 for (i = 15; i >= n; --i) {
950 s->buf[i] = s->buf[i-n];
952 s->bufIdx = n;
956 //------------------------------------------------------------------------
957 // AES-256 decryption
958 //------------------------------------------------------------------------
960 static void aes256KeyExpansion(DecryptAES256State *s,
961 Guchar *objKey, int objKeyLen, GBool decrypt) {
962 Guint temp;
963 int i, round;
965 //~ this assumes objKeyLen == 32
967 for (i = 0; i < 8; ++i) {
968 s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
969 (objKey[4*i+2] << 8) + objKey[4*i+3];
971 for (i = 8; i < 60; ++i) {
972 temp = s->w[i-1];
973 if ((i & 7) == 0) {
974 temp = subWord(rotWord(temp)) ^ rcon[i/8];
975 } else if ((i & 7) == 4) {
976 temp = subWord(temp);
978 s->w[i] = s->w[i-8] ^ temp;
981 /* In case of decryption, adjust the key schedule for the equivalent inverse cipher */
982 if (decrypt) {
983 for (round = 1; round <= 13; ++round) {
984 invMixColumnsW(&s->w[round * 4]);
989 static void aes256EncryptBlock(DecryptAES256State *s, Guchar *in) {
990 int c, round;
992 // initial state (input is xor'd with previous output because of CBC)
993 for (c = 0; c < 4; ++c) {
994 s->state[c] = in[4*c] ^ s->buf[4*c];
995 s->state[4+c] = in[4*c+1] ^ s->buf[4*c+1];
996 s->state[8+c] = in[4*c+2] ^ s->buf[4*c+2];
997 s->state[12+c] = in[4*c+3] ^ s->buf[4*c+3];
1000 // round 0
1001 addRoundKey(s->state, &s->w[0]);
1003 // rounds 1-13
1004 for (round = 1; round <= 13; ++round) {
1005 subBytes(s->state);
1006 shiftRows(s->state);
1007 mixColumns(s->state);
1008 addRoundKey(s->state, &s->w[round * 4]);
1011 // round 14
1012 subBytes(s->state);
1013 shiftRows(s->state);
1014 addRoundKey(s->state, &s->w[14 * 4]);
1016 for (c = 0; c < 4; ++c) {
1017 s->buf[4*c] = s->state[c];
1018 s->buf[4*c+1] = s->state[4+c];
1019 s->buf[4*c+2] = s->state[8+c];
1020 s->buf[4*c+3] = s->state[12+c];
1023 s->bufIdx = 0;
1026 static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last) {
1027 int c, round, n, i;
1029 // initial state
1030 for (c = 0; c < 4; ++c) {
1031 s->state[c] = in[4*c];
1032 s->state[4+c] = in[4*c+1];
1033 s->state[8+c] = in[4*c+2];
1034 s->state[12+c] = in[4*c+3];
1037 // round 0
1038 addRoundKey(s->state, &s->w[14 * 4]);
1040 // rounds 13-1
1041 for (round = 13; round >= 1; --round) {
1042 invSubBytes(s->state);
1043 invShiftRows(s->state);
1044 invMixColumns(s->state);
1045 addRoundKey(s->state, &s->w[round * 4]);
1048 // round 14
1049 invSubBytes(s->state);
1050 invShiftRows(s->state);
1051 addRoundKey(s->state, &s->w[0]);
1053 // CBC
1054 for (c = 0; c < 4; ++c) {
1055 s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
1056 s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
1057 s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
1058 s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
1061 // save the input block for the next CBC
1062 for (i = 0; i < 16; ++i) {
1063 s->cbc[i] = in[i];
1066 // remove padding
1067 s->bufIdx = 0;
1068 if (last) {
1069 n = s->buf[15];
1070 if (n < 1 || n > 16) { // this should never happen
1071 n = 16;
1073 for (i = 15; i >= n; --i) {
1074 s->buf[i] = s->buf[i-n];
1076 s->bufIdx = n;
1077 if (n > 16)
1079 error(errSyntaxError, -1, "Reducing bufIdx from {0:d} to 16 to not crash", n);
1080 s->bufIdx = 16;
1085 //------------------------------------------------------------------------
1086 // MD5 message digest
1087 //------------------------------------------------------------------------
1089 // this works around a bug in older Sun compilers
1090 static inline Gulong rotateLeft(Gulong x, int r) {
1091 x &= 0xffffffff;
1092 return ((x << r) | (x >> (32 - r))) & 0xffffffff;
1095 static inline Gulong md5Round1(Gulong a, Gulong b, Gulong c, Gulong d,
1096 Gulong Xk, Gulong s, Gulong Ti) {
1097 return b + rotateLeft((a + ((b & c) | (~b & d)) + Xk + Ti), s);
1100 static inline Gulong md5Round2(Gulong a, Gulong b, Gulong c, Gulong d,
1101 Gulong Xk, Gulong s, Gulong Ti) {
1102 return b + rotateLeft((a + ((b & d) | (c & ~d)) + Xk + Ti), s);
1105 static inline Gulong md5Round3(Gulong a, Gulong b, Gulong c, Gulong d,
1106 Gulong Xk, Gulong s, Gulong Ti) {
1107 return b + rotateLeft((a + (b ^ c ^ d) + Xk + Ti), s);
1110 static inline Gulong md5Round4(Gulong a, Gulong b, Gulong c, Gulong d,
1111 Gulong Xk, Gulong s, Gulong Ti) {
1112 return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s);
1115 void md5(Guchar *msg, int msgLen, Guchar *digest) {
1116 Gulong x[16];
1117 Gulong a, b, c, d, aa, bb, cc, dd;
1118 int n64;
1119 int i, j, k;
1121 // sanity check
1122 if (msgLen < 0) {
1123 return;
1126 // compute number of 64-byte blocks
1127 // (length + pad byte (0x80) + 8 bytes for length)
1128 n64 = (msgLen + 1 + 8 + 63) / 64;
1130 // initialize a, b, c, d
1131 a = 0x67452301;
1132 b = 0xefcdab89;
1133 c = 0x98badcfe;
1134 d = 0x10325476;
1136 // loop through blocks
1137 k = 0;
1138 for (i = 0; i < n64; ++i) {
1140 // grab a 64-byte block
1141 for (j = 0; j < 16 && k < msgLen - 3; ++j, k += 4)
1142 x[j] = (((((msg[k+3] << 8) + msg[k+2]) << 8) + msg[k+1]) << 8) + msg[k];
1143 if (i == n64 - 1) {
1144 if (k == msgLen - 3)
1145 x[j] = 0x80000000 + (((msg[k+2] << 8) + msg[k+1]) << 8) + msg[k];
1146 else if (k == msgLen - 2)
1147 x[j] = 0x800000 + (msg[k+1] << 8) + msg[k];
1148 else if (k == msgLen - 1)
1149 x[j] = 0x8000 + msg[k];
1150 else
1151 x[j] = 0x80;
1152 ++j;
1153 while (j < 16)
1154 x[j++] = 0;
1155 x[14] = msgLen << 3;
1158 // save a, b, c, d
1159 aa = a;
1160 bb = b;
1161 cc = c;
1162 dd = d;
1164 // round 1
1165 a = md5Round1(a, b, c, d, x[0], 7, 0xd76aa478);
1166 d = md5Round1(d, a, b, c, x[1], 12, 0xe8c7b756);
1167 c = md5Round1(c, d, a, b, x[2], 17, 0x242070db);
1168 b = md5Round1(b, c, d, a, x[3], 22, 0xc1bdceee);
1169 a = md5Round1(a, b, c, d, x[4], 7, 0xf57c0faf);
1170 d = md5Round1(d, a, b, c, x[5], 12, 0x4787c62a);
1171 c = md5Round1(c, d, a, b, x[6], 17, 0xa8304613);
1172 b = md5Round1(b, c, d, a, x[7], 22, 0xfd469501);
1173 a = md5Round1(a, b, c, d, x[8], 7, 0x698098d8);
1174 d = md5Round1(d, a, b, c, x[9], 12, 0x8b44f7af);
1175 c = md5Round1(c, d, a, b, x[10], 17, 0xffff5bb1);
1176 b = md5Round1(b, c, d, a, x[11], 22, 0x895cd7be);
1177 a = md5Round1(a, b, c, d, x[12], 7, 0x6b901122);
1178 d = md5Round1(d, a, b, c, x[13], 12, 0xfd987193);
1179 c = md5Round1(c, d, a, b, x[14], 17, 0xa679438e);
1180 b = md5Round1(b, c, d, a, x[15], 22, 0x49b40821);
1182 // round 2
1183 a = md5Round2(a, b, c, d, x[1], 5, 0xf61e2562);
1184 d = md5Round2(d, a, b, c, x[6], 9, 0xc040b340);
1185 c = md5Round2(c, d, a, b, x[11], 14, 0x265e5a51);
1186 b = md5Round2(b, c, d, a, x[0], 20, 0xe9b6c7aa);
1187 a = md5Round2(a, b, c, d, x[5], 5, 0xd62f105d);
1188 d = md5Round2(d, a, b, c, x[10], 9, 0x02441453);
1189 c = md5Round2(c, d, a, b, x[15], 14, 0xd8a1e681);
1190 b = md5Round2(b, c, d, a, x[4], 20, 0xe7d3fbc8);
1191 a = md5Round2(a, b, c, d, x[9], 5, 0x21e1cde6);
1192 d = md5Round2(d, a, b, c, x[14], 9, 0xc33707d6);
1193 c = md5Round2(c, d, a, b, x[3], 14, 0xf4d50d87);
1194 b = md5Round2(b, c, d, a, x[8], 20, 0x455a14ed);
1195 a = md5Round2(a, b, c, d, x[13], 5, 0xa9e3e905);
1196 d = md5Round2(d, a, b, c, x[2], 9, 0xfcefa3f8);
1197 c = md5Round2(c, d, a, b, x[7], 14, 0x676f02d9);
1198 b = md5Round2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
1200 // round 3
1201 a = md5Round3(a, b, c, d, x[5], 4, 0xfffa3942);
1202 d = md5Round3(d, a, b, c, x[8], 11, 0x8771f681);
1203 c = md5Round3(c, d, a, b, x[11], 16, 0x6d9d6122);
1204 b = md5Round3(b, c, d, a, x[14], 23, 0xfde5380c);
1205 a = md5Round3(a, b, c, d, x[1], 4, 0xa4beea44);
1206 d = md5Round3(d, a, b, c, x[4], 11, 0x4bdecfa9);
1207 c = md5Round3(c, d, a, b, x[7], 16, 0xf6bb4b60);
1208 b = md5Round3(b, c, d, a, x[10], 23, 0xbebfbc70);
1209 a = md5Round3(a, b, c, d, x[13], 4, 0x289b7ec6);
1210 d = md5Round3(d, a, b, c, x[0], 11, 0xeaa127fa);
1211 c = md5Round3(c, d, a, b, x[3], 16, 0xd4ef3085);
1212 b = md5Round3(b, c, d, a, x[6], 23, 0x04881d05);
1213 a = md5Round3(a, b, c, d, x[9], 4, 0xd9d4d039);
1214 d = md5Round3(d, a, b, c, x[12], 11, 0xe6db99e5);
1215 c = md5Round3(c, d, a, b, x[15], 16, 0x1fa27cf8);
1216 b = md5Round3(b, c, d, a, x[2], 23, 0xc4ac5665);
1218 // round 4
1219 a = md5Round4(a, b, c, d, x[0], 6, 0xf4292244);
1220 d = md5Round4(d, a, b, c, x[7], 10, 0x432aff97);
1221 c = md5Round4(c, d, a, b, x[14], 15, 0xab9423a7);
1222 b = md5Round4(b, c, d, a, x[5], 21, 0xfc93a039);
1223 a = md5Round4(a, b, c, d, x[12], 6, 0x655b59c3);
1224 d = md5Round4(d, a, b, c, x[3], 10, 0x8f0ccc92);
1225 c = md5Round4(c, d, a, b, x[10], 15, 0xffeff47d);
1226 b = md5Round4(b, c, d, a, x[1], 21, 0x85845dd1);
1227 a = md5Round4(a, b, c, d, x[8], 6, 0x6fa87e4f);
1228 d = md5Round4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
1229 c = md5Round4(c, d, a, b, x[6], 15, 0xa3014314);
1230 b = md5Round4(b, c, d, a, x[13], 21, 0x4e0811a1);
1231 a = md5Round4(a, b, c, d, x[4], 6, 0xf7537e82);
1232 d = md5Round4(d, a, b, c, x[11], 10, 0xbd3af235);
1233 c = md5Round4(c, d, a, b, x[2], 15, 0x2ad7d2bb);
1234 b = md5Round4(b, c, d, a, x[9], 21, 0xeb86d391);
1236 // increment a, b, c, d
1237 a += aa;
1238 b += bb;
1239 c += cc;
1240 d += dd;
1243 // break digest into bytes
1244 digest[0] = (Guchar)(a & 0xff);
1245 digest[1] = (Guchar)((a >>= 8) & 0xff);
1246 digest[2] = (Guchar)((a >>= 8) & 0xff);
1247 digest[3] = (Guchar)((a >>= 8) & 0xff);
1248 digest[4] = (Guchar)(b & 0xff);
1249 digest[5] = (Guchar)((b >>= 8) & 0xff);
1250 digest[6] = (Guchar)((b >>= 8) & 0xff);
1251 digest[7] = (Guchar)((b >>= 8) & 0xff);
1252 digest[8] = (Guchar)(c & 0xff);
1253 digest[9] = (Guchar)((c >>= 8) & 0xff);
1254 digest[10] = (Guchar)((c >>= 8) & 0xff);
1255 digest[11] = (Guchar)((c >>= 8) & 0xff);
1256 digest[12] = (Guchar)(d & 0xff);
1257 digest[13] = (Guchar)((d >>= 8) & 0xff);
1258 digest[14] = (Guchar)((d >>= 8) & 0xff);
1259 digest[15] = (Guchar)((d >>= 8) & 0xff);
1262 //------------------------------------------------------------------------
1263 // SHA-256 hash
1264 //------------------------------------------------------------------------
1266 static Guint sha256K[64] = {
1267 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
1268 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1269 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
1270 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1271 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
1272 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1273 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
1274 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1275 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
1276 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1277 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
1278 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1279 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
1280 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1281 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
1282 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1285 static inline Guint rotr(Guint x, Guint n) {
1286 return (x >> n) | (x << (32 - n));
1289 static inline Guint sha256Ch(Guint x, Guint y, Guint z) {
1290 return (x & y) ^ (~x & z);
1293 static inline Guint sha256Maj(Guint x, Guint y, Guint z) {
1294 return (x & y) ^ (x & z) ^ (y & z);
1297 static inline Guint sha256Sigma0(Guint x) {
1298 return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
1301 static inline Guint sha256Sigma1(Guint x) {
1302 return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
1305 static inline Guint sha256sigma0(Guint x) {
1306 return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
1309 static inline Guint sha256sigma1(Guint x) {
1310 return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
1313 void sha256HashBlock(Guchar *blk, Guint *H) {
1314 Guint W[64];
1315 Guint a, b, c, d, e, f, g, h;
1316 Guint T1, T2;
1317 Guint t;
1319 // 1. prepare the message schedule
1320 for (t = 0; t < 16; ++t) {
1321 W[t] = (blk[t*4] << 24) |
1322 (blk[t*4 + 1] << 16) |
1323 (blk[t*4 + 2] << 8) |
1324 blk[t*4 + 3];
1326 for (t = 16; t < 64; ++t) {
1327 W[t] = sha256sigma1(W[t-2]) + W[t-7] + sha256sigma0(W[t-15]) + W[t-16];
1330 // 2. initialize the eight working variables
1331 a = H[0];
1332 b = H[1];
1333 c = H[2];
1334 d = H[3];
1335 e = H[4];
1336 f = H[5];
1337 g = H[6];
1338 h = H[7];
1340 // 3.
1341 for (t = 0; t < 64; ++t) {
1342 T1 = h + sha256Sigma1(e) + sha256Ch(e,f,g) + sha256K[t] + W[t];
1343 T2 = sha256Sigma0(a) + sha256Maj(a,b,c);
1344 h = g;
1345 g = f;
1346 f = e;
1347 e = d + T1;
1348 d = c;
1349 c = b;
1350 b = a;
1351 a = T1 + T2;
1354 // 4. compute the intermediate hash value
1355 H[0] += a;
1356 H[1] += b;
1357 H[2] += c;
1358 H[3] += d;
1359 H[4] += e;
1360 H[5] += f;
1361 H[6] += g;
1362 H[7] += h;
1365 static void sha256(Guchar *msg, int msgLen, Guchar *hash) {
1366 Guchar blk[64];
1367 Guint H[8];
1368 int blkLen, i;
1370 H[0] = 0x6a09e667;
1371 H[1] = 0xbb67ae85;
1372 H[2] = 0x3c6ef372;
1373 H[3] = 0xa54ff53a;
1374 H[4] = 0x510e527f;
1375 H[5] = 0x9b05688c;
1376 H[6] = 0x1f83d9ab;
1377 H[7] = 0x5be0cd19;
1379 blkLen = 0;
1380 for (i = 0; i + 64 <= msgLen; i += 64) {
1381 sha256HashBlock(msg + i, H);
1383 blkLen = msgLen - i;
1384 if (blkLen > 0) {
1385 memcpy(blk, msg + i, blkLen);
1388 // pad the message
1389 blk[blkLen++] = 0x80;
1390 if (blkLen > 56) {
1391 while (blkLen < 64) {
1392 blk[blkLen++] = 0;
1394 sha256HashBlock(blk, H);
1395 blkLen = 0;
1397 while (blkLen < 56) {
1398 blk[blkLen++] = 0;
1400 blk[56] = 0;
1401 blk[57] = 0;
1402 blk[58] = 0;
1403 blk[59] = 0;
1404 blk[60] = (Guchar)(msgLen >> 21);
1405 blk[61] = (Guchar)(msgLen >> 13);
1406 blk[62] = (Guchar)(msgLen >> 5);
1407 blk[63] = (Guchar)(msgLen << 3);
1408 sha256HashBlock(blk, H);
1410 // copy the output into the buffer (convert words to bytes)
1411 for (i = 0; i < 8; ++i) {
1412 hash[i*4] = (Guchar)(H[i] >> 24);
1413 hash[i*4 + 1] = (Guchar)(H[i] >> 16);
1414 hash[i*4 + 2] = (Guchar)(H[i] >> 8);
1415 hash[i*4 + 3] = (Guchar)H[i];