Edit report at http://bugs.php.net/bug.php?id=51146&edit=1

 ID:                 51146
 Comment by:         me at haravikk dot com
 Reported by:        zelnaga at gmail dot com
 Summary:            mcrypt doesn't do OFB mode correctly
 Status:             Open
 Type:               Bug
 Package:            mcrypt related
 Operating System:   Windows XP
 PHP Version:        5.3.1
 Block user comment: N
 Private report:     N

 New Comment:

To answer your first question, performing the encryption per-byte is
kind of odd, I haven't done much 

testing but I don't think it actually consumes the entire input vector,
only the first byte, just think of 

it as running with an 8-bit wide state, rather than the more typical
128-bit wide state.

I've never had the time to confirm that this is the exact case, though,
but I believe it's compatible with 

other cryptography solutions that can operate per-byte.





For your second point; sorry I should have pointed out that there is no
predefined constant for 

MCRYPT_MODE_NCFB, you can however just enter it manually as 'ncfb' like
so:



mcrypt_module_open('rijndael-128', '', 'ncfb', '');





So if there's a failing on the PHP side it's that we need an
MCRYPT_MODE_NCFB, and that MCRYPT_MODE_CFB 

and MCRYPT_MODE_OFB should be properly documented so people don't keep
using them expecting different 

results!


Previous Comments:
------------------------------------------------------------------------
[2010-06-19 15:42:52] zelnaga at gmail dot com

Also, there's still the matter of CFB.  So NOFB is what most everything
else refers to as OFB but CFB'a wrong, as well, and it has no NCFB
counter part.

------------------------------------------------------------------------
[2010-06-19 15:40:10] zelnaga at gmail dot com

What does it even mean to do OFB at the byte-level?  Per
<http://en.wikipedia.org/wiki/File:Ofb_encryption.png>, in OFB, you
encrypt the IV with the key with the chosen block cipher algorithm and
then XOR that against the plaintext to get the ciphertext.   How do you
do that at the "byte level"?  Do you do substrings or something?

------------------------------------------------------------------------
[2010-06-01 12:22:07] me at haravikk dot com

You're using the wrong OFB mode, you need to use MCRYPT_MODE_NOFB.

MCRYPT_MODE_OFB is per-byte, while MCRYPT_MODE_NOFB is per-block and
gives the 

result you were expecting.

------------------------------------------------------------------------
[2010-04-13 23:36:44] zelnaga at gmail dot com

I was comparing mcrypt against openssl_encrypt() and...  well, either
OpenSSL is wrong or mcrypt is wrong:



<?php

$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_OFB, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo bin2hex(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CFB, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo bin2hex(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



echo bin2hex(openssl_encrypt("\0\0\0\0\0\0\0\0", 'DES-OFB', 'aaaaaaaa',
true)) . "\r\n";

echo bin2hex(openssl_encrypt("\0\0\0\0\0\0\0\0", 'DES-CFB', 'aaaaaaaa',
true)) . "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo bin2hex(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo bin2hex(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', 'ctr', '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo bin2hex(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));

?>



ie. mcrypt, in CTR, CBC and ECB modes equal OpenSSL in OFB and CFB modes
but not mcrypt in OFB and CFB modes.  In other words, OpenSSL's OFB !=
mcrypt's OFB and they should.

------------------------------------------------------------------------
[2010-02-26 16:16:56] zelnaga at gmail dot com

As far as I know, the IV is also used for the first round, so I am not

sure if your statement holds up.



Ummm...  the IV - as defined in mcrypt_generic_init - is only used in
the first round.  Per wikipedia, the first block against which the
plaintext is XOR'd is the IV encrypted with the key.  That's true in
both CFB and OFB modes of operation.  The difference between CFB and OFB
is what subsequent blocks encrypt for the keystream.  So, per that, the
first block should be the same.  And as for my first bug report...



<?php

$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_OFB, '');

mcrypt_generic_init($td, 'aaaaaaaa', 'bbbbbbbb');

echo urlencode(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CFB, '');

mcrypt_generic_init($td, 'aaaaaaaa', 'bbbbbbbb');

echo urlencode(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo urlencode(mcrypt_generic($td, 'bbbbbbbb'));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');

mcrypt_generic_init($td, 'aaaaaaaa', "\0\0\0\0\0\0\0\0");

echo urlencode(mcrypt_generic($td, 'bbbbbbbb'));



echo "\r\n";



$td = mcrypt_module_open(MCRYPT_DES, '', 'ctr', '');

mcrypt_generic_init($td, 'aaaaaaaa', 'bbbbbbbb');

echo urlencode(mcrypt_generic($td, "\0\0\0\0\0\0\0\0"));

?>



All of those should produce the same ciphertext.  As it stands, only
ecb, cbc and ctr produce the same ciphertext.  ofb and cfb produce the
same thing as each other (and, for the first block, they should, as I
already mentioned), however, they're not producing the same thing as any
of the other modes when, in fact, they should be.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=51146


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51146&edit=1

Reply via email to