/* Initialize the state. */ static int s_SHA256E_init(stream_state * st) { stream_SHA256E_state *const ss = (stream_SHA256E_state *) st; pSHA256_Init(&ss->sha256); return 0; }
static void pdf_compute_hardened_hash_r6(unsigned char *password, int pwlen, unsigned char salt[16], unsigned char *ownerkey, unsigned char hash[32]) { unsigned char data[(128 + 64 + 48) * 64]; unsigned char block[64]; int block_size = 32; int data_len = 0; int i, j, sum; SHA256_CTX sha256; SHA384_CTX sha384; SHA512_CTX sha512; aes_context aes; pSHA256_Init(&sha256); pSHA256_Update(&sha256, password, pwlen); pSHA256_Update(&sha256, salt, 8); if (ownerkey) pSHA256_Update(&sha256, ownerkey, 48); pSHA256_Final((uint8_t *)block, &sha256); for (i = 0; i < 64 || i < data[data_len * 64 - 1] + 32; i++) { /* Step 2: repeat password and data block 64 times */ memcpy(data, password, pwlen); memcpy(data + pwlen, block, block_size); if (ownerkey) memcpy(data + pwlen + block_size, ownerkey, 48); data_len = pwlen + block_size + (ownerkey ? 48 : 0); for (j = 1; j < 64; j++) memcpy(data + j * data_len, data, data_len); /* Step 3: encrypt data using data block as key and iv */ aes_setkey_enc(&aes, block, 128); aes_crypt_cbc(&aes, AES_ENCRYPT, data_len * 64, block + 16, data, data); /* Step 4: determine SHA-2 hash size for this round */ for (j = 0, sum = 0; j < 16; j++) sum += data[j]; /* Step 5: calculate data block for next round */ block_size = 32 + (sum % 3) * 16; switch (block_size) { case 32: pSHA256_Init(&sha256); pSHA256_Update(&sha256, data, data_len * 64); pSHA256_Final((uint8_t *)block, &sha256); break; case 48: pSHA384_Init(&sha384); pSHA384_Update(&sha384, data, data_len * 64); pSHA384_Final((uint8_t *)block, &sha384); break; case 64: pSHA512_Init(&sha512); pSHA512_Update(&sha512, data, data_len * 64); pSHA512_Final((uint8_t *)block, &sha512); break; } } memset(data, 0, sizeof(data)); memcpy(hash, block, 32); }