int AESPHM_Decrypt(u8 *passphrase, u8 *output, u8 *input) {
aes_context ctx;
int inputlen,
passphraselen,
ivoff,
paddingLen,
payloadLen;
u8 key[SHA256_DIGESTSIZE],
iv[IV_SIZE],
checkDigest[HMACSHA_DIGESTSIZE],
firstPadByte,
*digest,
*ivSeed,
*payload;
passphraselen = strlen(passphrase);
inputlen = hex2byte(input, input);
if(inputlen < MINIMUM_CIPHERTEXT_LENGTH) return(-1);
digest = input + inputlen - HMACSHA_DIGESTSIZE;
ivSeed = digest - IV_SEED_SIZE;
sha2(passphrase, passphraselen, key, 0);
sha1_hmac(key, sizeof(key), input, digest - input, checkDigest);
if(memcmp(checkDigest, digest, sizeof(checkDigest))) return(-1);
AESPHM_GenerateIvFromSeed(ivSeed, iv);
aes_setkey_enc(&ctx, key, sizeof(key) << 3);
ivoff = 0; // AES_cfb128_encrypt in OpenSSL
aes_crypt_cfb(&ctx, AES_ENCRYPT, 1, &ivoff, iv, input, &firstPadByte);
paddingLen = (firstPadByte & 0x0f) + 3;
if((input + paddingLen) > ivSeed) return(-1);
payload = input + paddingLen;
payloadLen = ivSeed - payload;
if(payloadLen) {
aes_crypt_cfb(&ctx, AES_ENCRYPT, paddingLen - 1, &ivoff, iv, input + 1, output);
aes_crypt_cfb(&ctx, AES_ENCRYPT, payloadLen, &ivoff, iv, payload, output);
}
return(payloadLen);
}