public static function legacyDecrypt($ciphertext, $key)
{
RuntimeTests::runtimeTest();
// Extract the HMAC from the front of the ciphertext.
if (Core::ourStrlen($ciphertext) <= Core::LEGACY_MAC_BYTE_SIZE) {
throw new Ex\WrongKeyOrModifiedCiphertextException('Ciphertext is too short.');
}
$hmac = Core::ourSubstr($ciphertext, 0, Core::LEGACY_MAC_BYTE_SIZE);
if ($hmac === false) {
throw new Ex\EnvironmentIsBrokenException();
}
$ciphertext = Core::ourSubstr($ciphertext, Core::LEGACY_MAC_BYTE_SIZE);
if ($ciphertext === false) {
throw new Ex\EnvironmentIsBrokenException();
}
// Regenerate the same authentication sub-key.
$akey = Core::HKDF(Core::LEGACY_HASH_FUNCTION_NAME, $key, Core::LEGACY_KEY_BYTE_SIZE, Core::LEGACY_AUTHENTICATION_INFO_STRING, null);
if (self::verifyHMAC($hmac, $ciphertext, $akey)) {
// Regenerate the same encryption sub-key.
$ekey = Core::HKDF(Core::LEGACY_HASH_FUNCTION_NAME, $key, Core::LEGACY_KEY_BYTE_SIZE, Core::LEGACY_ENCRYPTION_INFO_STRING, null);
// Extract the IV from the ciphertext.
if (Core::ourStrlen($ciphertext) <= Core::LEGACY_BLOCK_BYTE_SIZE) {
throw new Ex\WrongKeyOrModifiedCiphertextException('Ciphertext is too short.');
}
$iv = Core::ourSubstr($ciphertext, 0, Core::LEGACY_BLOCK_BYTE_SIZE);
if ($iv === false) {
throw new Ex\EnvironmentIsBrokenException();
}
$ciphertext = Core::ourSubstr($ciphertext, Core::LEGACY_BLOCK_BYTE_SIZE);
if ($ciphertext === false) {
throw new Ex\EnvironmentIsBrokenException();
}
// Do the decryption.
$plaintext = self::plainDecrypt($ciphertext, $ekey, $iv, Core::LEGACY_CIPHER_METHOD);
return $plaintext;
} else {
throw new Ex\WrongKeyOrModifiedCiphertextException('Integrity check failed.');
}
}