I came accross a weird behaviour that i could not comprehend.
I am using mcrypt xtea (cfb mode) to encrypt some data. Since php 7.2 is getting rid of mcrypt and since openssl does nor support Xtea, i had to implement the algorithm myself.
The problem is, no matter the algorithm used :
I tested the one provided here: pear implementation which is an ECB mode only (no init vector)
And the one provided on the wikipedia page taken from this stackoverflow topic
And the one i developed here (for the CFB mode) basing myself on the two following articles from wikipedia here and here and mcrypt source code that can be found here :
/* * $v is the data, $k is the 128bits key and $iv is 64bits init vector (size = 8) * Code is not optimized */ function encryptCfb($v, $k, $iv) { $v = array_values(unpack('N*', $v)); $iv = array_values(unpack('N*', $iv)); $k = array_values(unpack('N*', $k)); $cipher = []; //IV ciphering using the 128bits key list ($v0, $v1) = cipher($iv[0], $iv[1], $k); //Xoring the cipherd block with the first 64bits of data (32bits in V0 and 32 others in V1) $cipher[0] = $v0 ^ $v[0]; $cipher[1] = $v1 ^ $v[1]; for ($i=2; $i < count($v); $i+=2) { //Now ciphering the latest "cipherd" data using the 128bits key list ($y, $z) = cipher($cipher[$i-2], $cipher[$i-1], $k); //Xoring the cipherd block with the second 64bits of data (32bits in V0 and 32 others in V1) $cipher[$i] = $y ^ $v[$i]; $cipher[$i+1] = $z ^ $v[$i+1]; } $output = ""; foreach ($cipher as $i) { $output .= pack('N', $i); } return $output; } function cipher($v0, $v1, $k) { $delta=0x9e3779b9; $sum = 0; $limit = $delta * 32; for ($i=0; $i < 32; $i++) { $v0 += ((($v1<<4) ^ ($v1>>5)) + $v1) ^ ($sum + $k[$sum & 3]); $sum += $delta; $v1 += ((($v0 << 4) ^ ($v0 >> 5)) + $v0) ^ ($sum + $k[($sum>>11) & 3]); } return [$v0, $v1]; }
i get a different result and furthmore, none of them gives the exact same result mcrypt gives using :
$cryptModule = mcrypt_module_open('xtea', '', 'ncfb', '');
mcrypt_generic_init($cryptModule, $key, $iv);
mcrypt_generic($cryptModule, $data);
You can check and test the different tests i made here using same data/key/IV :
My implementation VS mcrypt in CFB mode. Note that :
- The number of rounds changes nothing (32 or 64)
- Packing/Unpacking using N mode (big endian) or V mode (little endian) changes nothings
Does anyone know why i get different result?