Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/source/fitz/crypt-sha2.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 This code is based on the code found from 7-Zip, which has a modified | |
| 3 version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>. | |
| 4 The code was modified a little to fit into liblzma and fitz. | |
| 5 | |
| 6 This file has been put into the public domain. | |
| 7 You can do whatever you want with this file. | |
| 8 | |
| 9 SHA-384 and SHA-512 were also taken from Crypto++ and adapted for fitz. | |
| 10 */ | |
| 11 | |
| 12 #include "mupdf/fitz.h" | |
| 13 | |
| 14 #include <string.h> | |
| 15 | |
| 16 static inline int isbigendian(void) | |
| 17 { | |
| 18 static const int one = 1; | |
| 19 return *(char*)&one == 0; | |
| 20 } | |
| 21 | |
| 22 static inline unsigned int bswap32(unsigned int num) | |
| 23 { | |
| 24 return ( (((num) << 24)) | |
| 25 | (((num) << 8) & 0x00FF0000) | |
| 26 | (((num) >> 8) & 0x0000FF00) | |
| 27 | (((num) >> 24)) ); | |
| 28 } | |
| 29 | |
| 30 static inline uint64_t bswap64(uint64_t num) | |
| 31 { | |
| 32 return ( (((num) << 56)) | |
| 33 | (((num) << 40) & 0x00FF000000000000ULL) | |
| 34 | (((num) << 24) & 0x0000FF0000000000ULL) | |
| 35 | (((num) << 8) & 0x000000FF00000000ULL) | |
| 36 | (((num) >> 8) & 0x00000000FF000000ULL) | |
| 37 | (((num) >> 24) & 0x0000000000FF0000ULL) | |
| 38 | (((num) >> 40) & 0x000000000000FF00ULL) | |
| 39 | (((num) >> 56)) ); | |
| 40 } | |
| 41 | |
| 42 /* At least on x86, GCC is able to optimize this to a rotate instruction. */ | |
| 43 #define rotr(num, amount) ((num) >> (amount) | (num) << (8 * sizeof(num) - (amount))) | |
| 44 | |
| 45 #define blk0(i) (W[i] = data[i]) | |
| 46 #define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \ | |
| 47 + s0(W[(i - 15) & 15])) | |
| 48 | |
| 49 #define Ch(x, y, z) (z ^ (x & (y ^ z))) | |
| 50 #define Maj(x, y, z) ((x & y) | (z & (x | y))) | |
| 51 | |
| 52 #define a(i) T[(0 - i) & 7] | |
| 53 #define b(i) T[(1 - i) & 7] | |
| 54 #define c(i) T[(2 - i) & 7] | |
| 55 #define d(i) T[(3 - i) & 7] | |
| 56 #define e(i) T[(4 - i) & 7] | |
| 57 #define f(i) T[(5 - i) & 7] | |
| 58 #define g(i) T[(6 - i) & 7] | |
| 59 #define h(i) T[(7 - i) & 7] | |
| 60 | |
| 61 #define R(i) \ | |
| 62 h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + K[i + j] \ | |
| 63 + (j ? blk2(i) : blk0(i)); \ | |
| 64 d(i) += h(i); \ | |
| 65 h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) | |
| 66 | |
| 67 /* For SHA256 */ | |
| 68 | |
| 69 #define S0(x) (rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22)) | |
| 70 #define S1(x) (rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25)) | |
| 71 #define s0(x) (rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3)) | |
| 72 #define s1(x) (rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10)) | |
| 73 | |
| 74 static const unsigned int SHA256_K[64] = { | |
| 75 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, | |
| 76 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, | |
| 77 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, | |
| 78 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, | |
| 79 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, | |
| 80 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, | |
| 81 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, | |
| 82 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, | |
| 83 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, | |
| 84 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, | |
| 85 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, | |
| 86 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, | |
| 87 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, | |
| 88 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, | |
| 89 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, | |
| 90 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, | |
| 91 }; | |
| 92 | |
| 93 static void | |
| 94 transform256(unsigned int state[8], unsigned int data[16]) | |
| 95 { | |
| 96 const unsigned int *K = SHA256_K; | |
| 97 unsigned int W[16]; | |
| 98 unsigned int T[8]; | |
| 99 unsigned int j; | |
| 100 | |
| 101 /* ensure big-endian integers */ | |
| 102 if (!isbigendian()) | |
| 103 for (j = 0; j < 16; j++) | |
| 104 data[j] = bswap32(data[j]); | |
| 105 | |
| 106 /* Copy state[] to working vars. */ | |
| 107 memcpy(T, state, sizeof(T)); | |
| 108 | |
| 109 /* 64 operations, partially loop unrolled */ | |
| 110 for (j = 0; j < 64; j += 16) { | |
| 111 R( 0); R( 1); R( 2); R( 3); | |
| 112 R( 4); R( 5); R( 6); R( 7); | |
| 113 R( 8); R( 9); R(10); R(11); | |
| 114 R(12); R(13); R(14); R(15); | |
| 115 } | |
| 116 | |
| 117 /* Add the working vars back into state[]. */ | |
| 118 state[0] += a(0); | |
| 119 state[1] += b(0); | |
| 120 state[2] += c(0); | |
| 121 state[3] += d(0); | |
| 122 state[4] += e(0); | |
| 123 state[5] += f(0); | |
| 124 state[6] += g(0); | |
| 125 state[7] += h(0); | |
| 126 } | |
| 127 | |
| 128 #undef S0 | |
| 129 #undef S1 | |
| 130 #undef s0 | |
| 131 #undef s1 | |
| 132 | |
| 133 void fz_sha256_init(fz_sha256 *context) | |
| 134 { | |
| 135 context->count[0] = context->count[1] = 0; | |
| 136 | |
| 137 context->state[0] = 0x6A09E667; | |
| 138 context->state[1] = 0xBB67AE85; | |
| 139 context->state[2] = 0x3C6EF372; | |
| 140 context->state[3] = 0xA54FF53A; | |
| 141 context->state[4] = 0x510E527F; | |
| 142 context->state[5] = 0x9B05688C; | |
| 143 context->state[6] = 0x1F83D9AB; | |
| 144 context->state[7] = 0x5BE0CD19; | |
| 145 } | |
| 146 | |
| 147 void fz_sha256_update(fz_sha256 *context, const unsigned char *input, size_t inlen) | |
| 148 { | |
| 149 /* Copy the input data into a properly aligned temporary buffer. | |
| 150 * This way we can be called with arbitrarily sized buffers | |
| 151 * (no need to be multiple of 64 bytes), and the code works also | |
| 152 * on architectures that don't allow unaligned memory access. */ | |
| 153 while (inlen > 0) | |
| 154 { | |
| 155 const unsigned int copy_start = context->count[0] & 0x3F; | |
| 156 unsigned int copy_size = 64 - copy_start; | |
| 157 if (copy_size > inlen) | |
| 158 copy_size = (unsigned int)inlen; | |
| 159 | |
| 160 memcpy(context->buffer.u8 + copy_start, input, copy_size); | |
| 161 | |
| 162 input += copy_size; | |
| 163 inlen -= copy_size; | |
| 164 context->count[0] += copy_size; | |
| 165 /* carry overflow from low to high */ | |
| 166 if (context->count[0] < copy_size) | |
| 167 context->count[1]++; | |
| 168 | |
| 169 if ((context->count[0] & 0x3F) == 0) | |
| 170 transform256(context->state, context->buffer.u32); | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 void fz_sha256_final(fz_sha256 *context, unsigned char digest[32]) | |
| 175 { | |
| 176 /* Add padding as described in RFC 3174 (it describes SHA-1 but | |
| 177 * the same padding style is used for SHA-256 too). */ | |
| 178 unsigned int j = context->count[0] & 0x3F; | |
| 179 context->buffer.u8[j++] = 0x80; | |
| 180 | |
| 181 while (j != 56) | |
| 182 { | |
| 183 if (j == 64) | |
| 184 { | |
| 185 transform256(context->state, context->buffer.u32); | |
| 186 j = 0; | |
| 187 } | |
| 188 context->buffer.u8[j++] = 0x00; | |
| 189 } | |
| 190 | |
| 191 /* Convert the message size from bytes to bits. */ | |
| 192 context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29); | |
| 193 context->count[0] = context->count[0] << 3; | |
| 194 | |
| 195 if (!isbigendian()) | |
| 196 { | |
| 197 context->buffer.u32[14] = bswap32(context->count[1]); | |
| 198 context->buffer.u32[15] = bswap32(context->count[0]); | |
| 199 } | |
| 200 else | |
| 201 { | |
| 202 context->buffer.u32[14] = context->count[1]; | |
| 203 context->buffer.u32[15] = context->count[0]; | |
| 204 } | |
| 205 transform256(context->state, context->buffer.u32); | |
| 206 | |
| 207 if (!isbigendian()) | |
| 208 for (j = 0; j < 8; j++) | |
| 209 context->state[j] = bswap32(context->state[j]); | |
| 210 | |
| 211 memcpy(digest, &context->state[0], 32); | |
| 212 memset(context, 0, sizeof(fz_sha256)); | |
| 213 } | |
| 214 | |
| 215 /* For SHA512 */ | |
| 216 | |
| 217 #define S0(x) (rotr(x, 28) ^ rotr(x, 34) ^ rotr(x, 39)) | |
| 218 #define S1(x) (rotr(x, 14) ^ rotr(x, 18) ^ rotr(x, 41)) | |
| 219 #define s0(x) (rotr(x, 1) ^ rotr(x, 8) ^ (x >> 7)) | |
| 220 #define s1(x) (rotr(x, 19) ^ rotr(x, 61) ^ (x >> 6)) | |
| 221 | |
| 222 static const uint64_t SHA512_K[80] = { | |
| 223 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, | |
| 224 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL, | |
| 225 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL, | |
| 226 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, | |
| 227 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL, | |
| 228 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL, | |
| 229 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, | |
| 230 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL, | |
| 231 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL, | |
| 232 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, | |
| 233 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL, | |
| 234 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL, | |
| 235 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, | |
| 236 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL, | |
| 237 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL, | |
| 238 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, | |
| 239 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL, | |
| 240 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL, | |
| 241 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, | |
| 242 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL, | |
| 243 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL, | |
| 244 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, | |
| 245 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL, | |
| 246 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL, | |
| 247 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, | |
| 248 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL, | |
| 249 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL, | |
| 250 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, | |
| 251 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL, | |
| 252 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL, | |
| 253 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, | |
| 254 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL, | |
| 255 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL, | |
| 256 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, | |
| 257 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL, | |
| 258 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL, | |
| 259 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, | |
| 260 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL, | |
| 261 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL, | |
| 262 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL, | |
| 263 }; | |
| 264 | |
| 265 static void | |
| 266 transform512(uint64_t state[8], uint64_t data[16]) | |
| 267 { | |
| 268 const uint64_t *K = SHA512_K; | |
| 269 uint64_t W[16]; | |
| 270 uint64_t T[8]; | |
| 271 unsigned int j; | |
| 272 | |
| 273 /* ensure big-endian integers */ | |
| 274 if (!isbigendian()) | |
| 275 for (j = 0; j < 16; j++) | |
| 276 data[j] = bswap64(data[j]); | |
| 277 | |
| 278 /* Copy state[] to working vars. */ | |
| 279 memcpy(T, state, sizeof(T)); | |
| 280 | |
| 281 /* 80 operations, partially loop unrolled */ | |
| 282 for (j = 0; j < 80; j+= 16) { | |
| 283 R( 0); R( 1); R( 2); R( 3); | |
| 284 R( 4); R( 5); R( 6); R( 7); | |
| 285 R( 8); R( 9); R(10); R(11); | |
| 286 R(12); R(13); R(14); R(15); | |
| 287 } | |
| 288 | |
| 289 /* Add the working vars back into state[]. */ | |
| 290 state[0] += a(0); | |
| 291 state[1] += b(0); | |
| 292 state[2] += c(0); | |
| 293 state[3] += d(0); | |
| 294 state[4] += e(0); | |
| 295 state[5] += f(0); | |
| 296 state[6] += g(0); | |
| 297 state[7] += h(0); | |
| 298 } | |
| 299 | |
| 300 #undef S0 | |
| 301 #undef S1 | |
| 302 #undef s0 | |
| 303 #undef s1 | |
| 304 | |
| 305 void fz_sha512_init(fz_sha512 *context) | |
| 306 { | |
| 307 context->count[0] = context->count[1] = 0; | |
| 308 | |
| 309 context->state[0] = 0x6A09E667F3BCC908ull; | |
| 310 context->state[1] = 0xBB67AE8584CAA73Bull; | |
| 311 context->state[2] = 0x3C6EF372FE94F82Bull; | |
| 312 context->state[3] = 0xA54FF53A5F1D36F1ull; | |
| 313 context->state[4] = 0x510E527FADE682D1ull; | |
| 314 context->state[5] = 0x9B05688C2B3E6C1Full; | |
| 315 context->state[6] = 0x1F83D9ABFB41BD6Bull; | |
| 316 context->state[7] = 0x5BE0CD19137E2179ull; | |
| 317 } | |
| 318 | |
| 319 void fz_sha512_update(fz_sha512 *context, const unsigned char *input, size_t inlen) | |
| 320 { | |
| 321 /* Copy the input data into a properly aligned temporary buffer. | |
| 322 * This way we can be called with arbitrarily sized buffers | |
| 323 * (no need to be multiple of 128 bytes), and the code works also | |
| 324 * on architectures that don't allow unaligned memory access. */ | |
| 325 while (inlen > 0) | |
| 326 { | |
| 327 const unsigned int copy_start = context->count[0] & 0x7F; | |
| 328 unsigned int copy_size = 128 - copy_start; | |
| 329 if (copy_size > inlen) | |
| 330 copy_size = (unsigned int)inlen; | |
| 331 | |
| 332 memcpy(context->buffer.u8 + copy_start, input, copy_size); | |
| 333 | |
| 334 input += copy_size; | |
| 335 inlen -= copy_size; | |
| 336 context->count[0] += copy_size; | |
| 337 /* carry overflow from low to high */ | |
| 338 if (context->count[0] < copy_size) | |
| 339 context->count[1]++; | |
| 340 | |
| 341 if ((context->count[0] & 0x7F) == 0) | |
| 342 transform512(context->state, context->buffer.u64); | |
| 343 } | |
| 344 } | |
| 345 | |
| 346 void fz_sha512_final(fz_sha512 *context, unsigned char digest[64]) | |
| 347 { | |
| 348 /* Add padding as described in RFC 3174 (it describes SHA-1 but | |
| 349 * the same padding style is used for SHA-512 too). */ | |
| 350 unsigned int j = context->count[0] & 0x7F; | |
| 351 context->buffer.u8[j++] = 0x80; | |
| 352 | |
| 353 while (j != 112) | |
| 354 { | |
| 355 if (j == 128) | |
| 356 { | |
| 357 transform512(context->state, context->buffer.u64); | |
| 358 j = 0; | |
| 359 } | |
| 360 context->buffer.u8[j++] = 0x00; | |
| 361 } | |
| 362 | |
| 363 /* Convert the message size from bytes to bits. */ | |
| 364 context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29); | |
| 365 context->count[0] = context->count[0] << 3; | |
| 366 | |
| 367 if (!isbigendian()) | |
| 368 { | |
| 369 context->buffer.u64[14] = bswap64(context->count[1]); | |
| 370 context->buffer.u64[15] = bswap64(context->count[0]); | |
| 371 } | |
| 372 else | |
| 373 { | |
| 374 context->buffer.u64[14] = context->count[1]; | |
| 375 context->buffer.u64[15] = context->count[0]; | |
| 376 } | |
| 377 transform512(context->state, context->buffer.u64); | |
| 378 | |
| 379 if (!isbigendian()) | |
| 380 for (j = 0; j < 8; j++) | |
| 381 context->state[j] = bswap64(context->state[j]); | |
| 382 | |
| 383 memcpy(digest, &context->state[0], 64); | |
| 384 memset(context, 0, sizeof(fz_sha512)); | |
| 385 } | |
| 386 | |
| 387 void fz_sha384_init(fz_sha384 *context) | |
| 388 { | |
| 389 context->count[0] = context->count[1] = 0; | |
| 390 | |
| 391 context->state[0] = 0xCBBB9D5DC1059ED8ull; | |
| 392 context->state[1] = 0x629A292A367CD507ull; | |
| 393 context->state[2] = 0x9159015A3070DD17ull; | |
| 394 context->state[3] = 0x152FECD8F70E5939ull; | |
| 395 context->state[4] = 0x67332667FFC00B31ull; | |
| 396 context->state[5] = 0x8EB44A8768581511ull; | |
| 397 context->state[6] = 0xDB0C2E0D64F98FA7ull; | |
| 398 context->state[7] = 0x47B5481DBEFA4FA4ull; | |
| 399 } | |
| 400 | |
| 401 void fz_sha384_update(fz_sha384 *context, const unsigned char *input, size_t inlen) | |
| 402 { | |
| 403 fz_sha512_update(context, input, inlen); | |
| 404 } | |
| 405 | |
| 406 void fz_sha384_final(fz_sha384 *context, unsigned char digest[64]) | |
| 407 { | |
| 408 fz_sha512_final(context, digest); | |
| 409 } |
