From:             bwise837 at users dot sourceforge dot net
Operating system: all
PHP version:      5.0.4
PHP Bug Type:     mcrypt related
Bug description:  treatment of initial vectors invalidates algorithm

Description:
------------
The initial vectors are treated in MCRYPT in a way
that invalidates the algorithms. This appears to apply
to all PHP version, all algorithms, all modes.

Diligent searching of the bug database does not reveal
any similar bug reports. This is a fundamental design
error, not a minor problem like '\0' line terminators
getting trimmed when decrypting binary data.

The example on page
http://us4.php.net/manual/en/function.mcrypt-module-open.php
clearly shows that decryption does not merely require the N bits of the
"secret key" to decrypt, but also the M bits of 
the "initial vector" to decrypt. This is NOT the way initial
vectors are used in standard cryptography, as documented
by Schneier, Koblitz, Rivest, et al. You have wrapped the
encryption algorithm (all algorithms, all modes) in another,
creating a new encryption algorithm that requires an N+M
bit secret key to decrypt. This is a VERY SERIOUS error.
Schneier's writings are full of examples of how such simple 
changes, that naivley look like improvements, can sometimes
break the security of the algorithm. Maybe it did here, maybe not: a fully
cryptanalysis is required to determine
if the new N+M-bit-key algorithm is as good as the
N-bit-key algorithm on which it was based. Until then, it
can't be trusted.

I'm sorry to say such strong things, but I happen to have 
a mathematical background in cryptography, and I'm shocked
to find such an elementary and gross error.

There is a simple work around, and I'd be happy to send
a php script I've made which demos it. The essence is to
always use a public, constant string for the MCRYPT-style
IV, while using a secret, random string for the standard-
style IV. This adds one extra block to the cipher text length, but that is
a small price to pay for undoing a
terribly wrong design decision.

(The script is more than 20 lines, and I don't have
my own website up yet. But it's a simple fix.)


Reproduce code:
---------------
from http://us4.php.net/manual/en/function.mcrypt-module-open.php
<?php
   $td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
   $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td),
MCRYPT_DEV_RANDOM);
   $ks = mcrypt_enc_get_key_size($td);
   $key = substr(md5('very secret key'), 0, $ks);
   mcrypt_generic_init($td, $key, $iv);
   $encrypted = mcrypt_generic($td, 'This is very important data');
   mcrypt_generic_deinit($td);

   /* Initialize encryption module for decryption */
   mcrypt_generic_init($td, $key, $iv);
   $decrypted = mdecrypt_generic($td, $encrypted);
   mcrypt_generic_deinit($td);
   mcrypt_module_close($td);
   echo trim($decrypted) . "\n";
?> 

Expected result:
----------------
I would expect, as per textbook cryptography, to be
able to decrypt the string using ONLY the secret key:

In cryptography, the reverse of security by obscurity is Kerckhoffs'
principle from the late 1880s, which states that system designers should
assume that the entire design of a security system is known to all
attackers, with the exception of the cryptographic key: "the security of a
cypher resides entirely in the key". 

from 

http://www.answers.com/topic/security-through-obscurity

Actual result:
--------------
Both the IV and 'secret key' are needed to decrypt,
in violation of Kerckhoff's laws.

Outside MCRYPT, for every single algorithm and mode, only
the secret key is required to decrypt. This alone mathematically proves
that MCRYPT is implementing different
algorithms with different true keys ('true key' = what is
required to decrypt = 'secret key' + MCRYPT-style 'IV') than
the algorithms which it claims to implement.

-- 
Edit bug report at http://bugs.php.net/?id=33256&edit=1
-- 
Try a CVS snapshot (php4):   http://bugs.php.net/fix.php?id=33256&r=trysnapshot4
Try a CVS snapshot (php5.0): 
http://bugs.php.net/fix.php?id=33256&r=trysnapshot50
Try a CVS snapshot (php5.1): 
http://bugs.php.net/fix.php?id=33256&r=trysnapshot51
Fixed in CVS:                http://bugs.php.net/fix.php?id=33256&r=fixedcvs
Fixed in release:            http://bugs.php.net/fix.php?id=33256&r=alreadyfixed
Need backtrace:              http://bugs.php.net/fix.php?id=33256&r=needtrace
Need Reproduce Script:       http://bugs.php.net/fix.php?id=33256&r=needscript
Try newer version:           http://bugs.php.net/fix.php?id=33256&r=oldversion
Not developer issue:         http://bugs.php.net/fix.php?id=33256&r=support
Expected behavior:           http://bugs.php.net/fix.php?id=33256&r=notwrong
Not enough info:             
http://bugs.php.net/fix.php?id=33256&r=notenoughinfo
Submitted twice:             
http://bugs.php.net/fix.php?id=33256&r=submittedtwice
register_globals:            http://bugs.php.net/fix.php?id=33256&r=globals
PHP 3 support discontinued:  http://bugs.php.net/fix.php?id=33256&r=php3
Daylight Savings:            http://bugs.php.net/fix.php?id=33256&r=dst
IIS Stability:               http://bugs.php.net/fix.php?id=33256&r=isapi
Install GNU Sed:             http://bugs.php.net/fix.php?id=33256&r=gnused
Floating point limitations:  http://bugs.php.net/fix.php?id=33256&r=float
No Zend Extensions:          http://bugs.php.net/fix.php?id=33256&r=nozend
MySQL Configuration Error:   http://bugs.php.net/fix.php?id=33256&r=mysqlcfg

Reply via email to