1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
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 //========================================================================
30 #ifdef USE_GCC_PRAGMAS
31 #pragma implementation
36 #include "goo/grandom.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 //------------------------------------------------------------------------
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
;
81 *ownerPasswordOk
= gFalse
;
83 if (encRevision
== 5) {
85 // check the owner password
87 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
88 len
= ownerPassword
->getLength();
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
) {
107 aes256DecryptBlock(&state
, (Guchar
*)ownerEnc
->getCString(), gFalse
);
108 memcpy(fileKey
, state
.buf
, 16);
109 aes256DecryptBlock(&state
, (Guchar
*)ownerEnc
->getCString() + 16,
111 memcpy(fileKey
+ 16, state
.buf
, 16);
113 *ownerPasswordOk
= gTrue
;
118 // check the user password
120 //~ this is supposed to convert the password to UTF-8 using "SASLprep"
121 len
= userPassword
->getLength();
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
) {
138 aes256DecryptBlock(&state
, (Guchar
*)userEnc
->getCString(), gFalse
);
139 memcpy(fileKey
, state
.buf
, 16);
140 aes256DecryptBlock(&state
, (Guchar
*)userEnc
->getCString() + 16,
142 memcpy(fileKey
+ 16, state
.buf
, 16);
151 // try using the supplied owner password to generate the user password
153 len
= ownerPassword
->getLength();
155 memcpy(test
, ownerPassword
->getCString(), len
);
156 memcpy(test
+ len
, passwordPad
, 32 - len
);
158 memcpy(test
, ownerPassword
->getCString(), 32);
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
);
169 for (i
= 0; i
< 32; ++i
) {
170 test2
[i
] = rc4DecryptByte(fState
, &fx
, &fy
, ownerKey
->getChar(i
));
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
);
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
,
189 *ownerPasswordOk
= gTrue
;
190 delete userPassword2
;
193 delete userPassword2
;
196 // try using the supplied user password
197 return makeFileKey2(encVersion
, encRevision
, keyLength
, ownerKey
, userKey
,
198 permissions
, fileID
, userPassword
, fileKey
,
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
) {
217 buf
= (Guchar
*)gmalloc(72 + fileID
->getLength());
219 len
= userPassword
->getLength();
221 memcpy(buf
, userPassword
->getCString(), len
);
222 memcpy(buf
+ len
, passwordPad
, 32 - len
);
224 memcpy(buf
, userPassword
->getCString(), 32);
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
) {
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
);
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
);
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;
281 //------------------------------------------------------------------------
283 //------------------------------------------------------------------------
285 BaseCryptStream::BaseCryptStream(Stream
*strA
, Guchar
*fileKey
, CryptAlgorithm algoA
,
286 int keyLength
, int objNum
, int objGen
):
293 // construct object key
294 for (i
= 0; i
< keyLength
; ++i
) {
295 objKey
[i
] = fileKey
[i
];
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) {
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) {
325 objKeyLength
= keyLength
;
333 BaseCryptStream::~BaseCryptStream() {
339 void BaseCryptStream::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
359 GBool
BaseCryptStream::isBinary(GBool last
) {
360 return str
->isBinary(last
);
363 void BaseCryptStream::setAutoDelete(GBool val
) {
367 //------------------------------------------------------------------------
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
378 grandom_fill(state
.aes
.cbc
, 16);
381 grandom_fill(state
.aes256
.cbc
, 16);
388 EncryptStream::~EncryptStream() {
391 void EncryptStream::reset() {
392 BaseCryptStream::reset();
396 state
.rc4
.x
= state
.rc4
.y
= 0;
397 rc4InitKey(objKey
, objKeyLength
, state
.rc4
.state
);
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
;
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
;
414 int EncryptStream::lookChar() {
418 if (nextCharBuff
!= EOF
)
421 c
= EOF
; // make gcc happy
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
);
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) {
437 c
= state
.aes
.buf
[state
.aes
.bufIdx
++];
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) {
448 c
= state
.aes256
.buf
[state
.aes256
.bufIdx
++];
452 return (nextCharBuff
= c
);
455 //------------------------------------------------------------------------
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() {
470 BaseCryptStream::reset();
474 state
.rc4
.x
= state
.rc4
.y
= 0;
475 rc4InitKey(objKey
, objKeyLength
, state
.rc4
.state
);
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;
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;
494 int DecryptStream::lookChar() {
498 if (nextCharBuff
!= EOF
)
501 c
= EOF
; // make gcc happy
504 if ((c
= str
->getChar()) != EOF
) {
505 c
= rc4DecryptByte(state
.rc4
.state
, &state
.rc4
.x
, &state
.rc4
.y
, (Guchar
)c
);
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) {
517 c
= state
.aes
.buf
[state
.aes
.bufIdx
++];
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) {
529 c
= state
.aes256
.buf
[state
.aes256
.bufIdx
++];
533 return (nextCharBuff
= c
);
536 //------------------------------------------------------------------------
537 // RC4-compatible decryption
538 //------------------------------------------------------------------------
540 static void rc4InitKey(Guchar
*key
, int keyLen
, Guchar
*state
) {
541 Guchar index1
, index2
;
545 for (i
= 0; i
< 256; ++i
)
548 if (unlikely(keyLen
== 0))
552 for (i
= 0; i
< 256; ++i
) {
553 index2
= (key
[index1
] + state
[i
] + index2
) % 256;
555 state
[i
] = state
[index2
];
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;
570 return c
^ state
[(tx
+ ty
) % 256];
573 //------------------------------------------------------------------------
575 //------------------------------------------------------------------------
577 // Returns gFalse if EOF was reached, gTrue otherwise
578 static GBool
aesReadBlock(Stream
*str
, Guchar
*in
, GBool addPadding
)
582 for (i
= 0; i
< 16; ++i
) {
583 if ((c
= str
->getChar()) != EOF
) {
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
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)
662 static inline Guint
rotWord(Guint x
) {
663 return ((x
<< 8) & 0xffffffff) | (x
>> 24);
666 static inline void subBytes(Guchar
*state
) {
669 for (i
= 0; i
< 16; ++i
) {
670 state
[i
] = sbox
[state
[i
]];
674 static inline void invSubBytes(Guchar
*state
) {
677 for (i
= 0; i
< 16; ++i
) {
678 state
[i
] = invSbox
[state
[i
]];
682 static inline void shiftRows(Guchar
*state
) {
692 state
[8] = state
[10];
695 state
[9] = state
[11];
699 state
[15] = state
[14];
700 state
[14] = state
[13];
701 state
[13] = state
[12];
705 static inline void invShiftRows(Guchar
*state
) {
715 state
[8] = state
[10];
718 state
[9] = state
[11];
722 state
[12] = state
[13];
723 state
[13] = state
[14];
724 state
[14] = state
[15];
729 static inline Guchar
mul02(Guchar s
) {
730 return (s
& 0x80) ? ((s
<< 1) ^ 0x1b) : (s
<< 1);
734 static inline Guchar
mul03(Guchar s
) {
735 Guchar s2
= (s
& 0x80) ? ((s
<< 1) ^ 0x1b) : (s
<< 1);
740 static inline Guchar
mul09(Guchar s
) {
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);
750 static inline Guchar
mul0b(Guchar s
) {
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);
760 static inline Guchar
mul0d(Guchar s
) {
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);
770 static inline Guchar
mul0e(Guchar s
) {
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);
779 static inline void mixColumns(Guchar
*state
) {
781 Guchar s0
, s1
, s2
, s3
;
783 for (c
= 0; c
< 4; ++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
) {
797 Guchar s0
, s1
, s2
, s3
;
799 for (c
= 0; c
< 4; ++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
) {
813 Guchar s0
, s1
, s2
, s3
;
815 for (c
= 0; c
< 4; ++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
) {
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;
838 static void aesKeyExpansion(DecryptAESState
*s
,
839 Guchar
*objKey
, int /*objKeyLen*/, GBool decrypt
) {
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
) {
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 */
859 for (round
= 1; round
<= 9; ++round
) {
860 invMixColumnsW(&s
->w
[round
* 4]);
865 static void aesEncryptBlock(DecryptAESState
*s
, Guchar
*in
) {
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];
877 addRoundKey(s
->state
, &s
->w
[0]);
880 for (round
= 1; round
<= 9; ++round
) {
883 mixColumns(s
->state
);
884 addRoundKey(s
->state
, &s
->w
[round
* 4]);
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
];
902 static void aesDecryptBlock(DecryptAESState
*s
, Guchar
*in
, GBool last
) {
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];
914 addRoundKey(s
->state
, &s
->w
[10 * 4]);
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]);
925 invSubBytes(s
->state
);
926 invShiftRows(s
->state
);
927 addRoundKey(s
->state
, &s
->w
[0]);
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
) {
946 if (n
< 1 || n
> 16) { // this should never happen
949 for (i
= 15; i
>= n
; --i
) {
950 s
->buf
[i
] = s
->buf
[i
-n
];
956 //------------------------------------------------------------------------
957 // AES-256 decryption
958 //------------------------------------------------------------------------
960 static void aes256KeyExpansion(DecryptAES256State
*s
,
961 Guchar
*objKey
, int objKeyLen
, GBool decrypt
) {
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
) {
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 */
983 for (round
= 1; round
<= 13; ++round
) {
984 invMixColumnsW(&s
->w
[round
* 4]);
989 static void aes256EncryptBlock(DecryptAES256State
*s
, Guchar
*in
) {
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];
1001 addRoundKey(s
->state
, &s
->w
[0]);
1004 for (round
= 1; round
<= 13; ++round
) {
1006 shiftRows(s
->state
);
1007 mixColumns(s
->state
);
1008 addRoundKey(s
->state
, &s
->w
[round
* 4]);
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
];
1026 static void aes256DecryptBlock(DecryptAES256State
*s
, Guchar
*in
, GBool last
) {
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];
1038 addRoundKey(s
->state
, &s
->w
[14 * 4]);
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]);
1049 invSubBytes(s
->state
);
1050 invShiftRows(s
->state
);
1051 addRoundKey(s
->state
, &s
->w
[0]);
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
) {
1070 if (n
< 1 || n
> 16) { // this should never happen
1073 for (i
= 15; i
>= n
; --i
) {
1074 s
->buf
[i
] = s
->buf
[i
-n
];
1079 error(errSyntaxError
, -1, "Reducing bufIdx from {0:d} to 16 to not crash", n
);
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
) {
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
) {
1117 Gulong a
, b
, c
, d
, aa
, bb
, cc
, dd
;
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
1136 // loop through blocks
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
];
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
];
1155 x
[14] = msgLen
<< 3;
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);
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);
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);
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
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 //------------------------------------------------------------------------
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
) {
1315 Guint a
, b
, c
, d
, e
, f
, g
, h
;
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) |
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
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
);
1354 // 4. compute the intermediate hash value
1365 static void sha256(Guchar
*msg
, int msgLen
, Guchar
*hash
) {
1380 for (i
= 0; i
+ 64 <= msgLen
; i
+= 64) {
1381 sha256HashBlock(msg
+ i
, H
);
1383 blkLen
= msgLen
- i
;
1385 memcpy(blk
, msg
+ i
, blkLen
);
1389 blk
[blkLen
++] = 0x80;
1391 while (blkLen
< 64) {
1394 sha256HashBlock(blk
, H
);
1397 while (blkLen
< 56) {
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
];