Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does PHP's mcrypt_get_iv_size actually return zero when the IV is not required?

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.

like image 233
jmalloc Avatar asked Nov 13 '22 01:11

jmalloc


1 Answers

You are right, ECB does not use an IV, as it is also pointed out in the PHP documentation for mcrypt_get_iv_size:

One of the MCRYPT_MODE_modename constants, or one of the following strings: "ecb", "cbc", "cfb", "ofb", "nofb" or "stream". The IV is ignored in ECB mode as this mode does not require it. You will need to have the same IV (think: starting point) both at encryption and decryption stages, otherwise your encryption will fail.

Why mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB) returns 8 is odd. Intentional or not, you should disregard it.

like image 56
kba Avatar answered May 09 '23 18:05

kba