protected function _mcrypt_encrypt($data, $params)
{
if (!is_resource($params['handle'])) {
return FALSE;
}
// The greater-than-1 comparison is mostly a work-around for a bug,
// where 1 is returned for ARCFour instead of 0.
$iv = ($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1 ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM) : NULL;
if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) {
if ($params['handle'] !== $this->_handle) {
mcrypt_module_close($params['handle']);
}
return FALSE;
}
// Use PKCS#7 padding in order to ensure compatibility with OpenSSL
// and other implementations outside of PHP.
if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE)) {
$block_size = mcrypt_enc_get_block_size($params['handle']);
$pad = $block_size - self::strlen($data) % $block_size;
$data .= str_repeat(chr($pad), $pad);
}
// Work-around for yet another strange behavior in MCrypt.
//
// When encrypting in ECB mode, the IV is ignored. Yet
// mcrypt_enc_get_iv_size() returns a value larger than 0
// even if ECB is used AND mcrypt_generic_init() complains
// if you don't pass an IV with length equal to the said
// return value.
//
// This probably would've been fine (even though still wasteful),
// but OpenSSL isn't that dumb and we need to make the process
// portable, so ...
$data = mcrypt_enc_get_modes_name($params['handle']) !== 'ECB' ? $iv . mcrypt_generic($params['handle'], $data) : mcrypt_generic($params['handle'], $data);
mcrypt_generic_deinit($params['handle']);
if ($params['handle'] !== $this->_handle) {
mcrypt_module_close($params['handle']);
}
return $data;
}