In the PHP documentation for mcrypt_get_iv_size it is stated that the return value will be zero when the algorithm / block mode combination does not use an IV:
Returns the size of the Initialization Vector (IV) in bytes. On error the function returns FALSE. If the IV is ignored in the specified cipher/mode combination zero is returned.
When I call this function with MCRYPT_DES as the algo and MCRYPT_MODE_ECB as the mode it returns 8 (eight) instead of the expected 0 (zero).
It's my understanding that ECB does not and can not use an IV, and hence I expect the zero value. Is this incorrect, is the documentation incorrect, or am I missing something else?
The following snippet demonstrates the problem:
<?php
// I expect this call to return zero.
$size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
echo 'IV Size: ' . $size . PHP_EOL;
Please note that I'm not actually using ECB for real-world encryption, I'm simply trying to find a reliable way for determining if an arbitrary algo/mode requires an IV. (I notice that the mcrypt library has a function "mcrypt_enc_mode_has_iv", but there does not seem to be an equivalent PHP function).
I'm using PHP v5.3.12 with libmcrypt 2.5.8_1.
Update with possible workaround:
Looking at the libmcrypt source it seems as though mcrypt_enc_get_iv_size() will always return the block size for any block cipher mode, but falls back to "asking" the algorithm for stream modes.
int mcrypt_enc_get_iv_size(MCRYPT td)
{
if (mcrypt_enc_is_block_algorithm_mode(td) == 1) {
return mcrypt_enc_get_block_size(td);
} else {
return mcrypt_get_algo_iv_size(td);
}
}
The mcrypt_get_algo_iv_size() call is forwarded on to the algorithm library's _mcrypt_get_algo_iv_size() function. So hopefully this means if I handle the ECB case manually it should yield the correct result for those algorithms that require an IV in stream mode.