php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #70312 HAVAL gives wrong hashes in specific cases
Submitted: 2015-08-20 15:00 UTC Modified: 2015-08-30 13:17 UTC
From: letsgolee at naver dot com Assigned:
Status: Closed Package: hash related
PHP Version: 5.4.44 OS: Windows/linux
Private report: No CVE-ID:
 [2015-08-20 15:00 UTC] letsgolee at naver dot com
Description:
------------
HAVAL pads a string with a wrong pad length, if the remaining string is over 64 and under 118 bytes length. The suspect code is:

index = (unsigned int) ((context->count[0] >> 3) & 0x3f);

when the remaining string is under 63 bytes long then there seems no problem, but when a string is over 64 and under 118 then it seems to have a wrong padding length.

If you test "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ0123456789" then, it will give you right hash value, because the string length is 183 and it is above 128 and the remaining string length is 55. And 55 is under 64 so it will give a right result.

Test script:
---------------
hash('haval256,5', '1234567890123456789012345678901234567890123456789012345678901234');



Expected result:
----------------
fb73c19300b14d5cb393d929bf005e6c2d459a4c9c009e9813af1d2d3637ee8f

Actual result:
--------------
498f3710ed9373908405d608e15df8157ef777abe85794b67f590347b4506fb2

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-20 21:56 UTC] cmb@php.net
-Type: Bug +Type: Security -Private report: No +Private report: Yes
 [2015-08-20 21:56 UTC] cmb@php.net
Indeed, the 0x3f should be 0x7f in the 5 PHP_HAVAL*Final()
functions; see Yuliang Zheng's reference implementation:
<https://www.schneier.com/sccd/HAVAL.ZIP>.

It seems to me this bug is a security issue, so marking as such.
 [2015-08-21 01:40 UTC] letsgolee at naver dot com
To work properly, 0x3f should be 0x7f in line:
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
in PHP_HAVAL###Final function. ### can be 128, 160, 192, 224, 256.

Because of 0x3f, the last PHP_HAVALUpdate function is not working properly, for the last string will be less than 128.
 [2015-08-21 02:00 UTC] letsgolee at naver dot com
I'm sorry but I cannot change the bug type. It is not "Security". I don't know why the value is changed.

Anyway, this bug can be seen all of versions of php including 7.x.x and 5.x.x.
 [2015-08-30 05:55 UTC] stas@php.net
I'm kind of confused by this one, because I can't find a reference implementation that generates expected results, in order to test it. The links from here: https://en.wikipedia.org/wiki/HAVAL are dead, and the program I download from https://www.schneier.com/books/applied_cryptography/source.html produces this:

HAVAL("1234567890123456789012345678901234567890123456789012345678901234") = 996F9F548AE2313501DD2576D62EB8CCD424D43703FD5AF3AC46BC58A2224D84

and I could not find any authoritative source for what it should return. Is this algorithm used/supported? Where one should find the correct certification data?
 [2015-08-30 13:17 UTC] cmb@php.net
The reference implementation which can be downloaded from
www.schneier.com is apparently meant for 32bit systems only (see
haval.h line 45, for instance). There are some certification data
available in cert.data; running ./haval -c is supposed to
reproduce these.

Anyhow, building on 32bit Debian Jessie with PASS=5 and FPTLEN=256
(LITTLE_ENDIAN is irrelevant for the result) produces:
HAVAL("1234567890123456789012345678901234567890123456789012345678901234")
= FB73C19300B14D5CB393D929BF005E6C2D459A4C9C009E9813AF1D2D3637EE8F
 [2015-09-01 18:55 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1390a5812b151e0ea8f74e64bfeaa5df4dd5b801
Log: Fix bug #70312 - HAVAL gives wrong hashes in specific cases
 [2015-09-01 18:55 UTC] stas@php.net
-Status: Open +Status: Closed
 [2015-09-01 19:04 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1390a5812b151e0ea8f74e64bfeaa5df4dd5b801
Log: Fix bug #70312 - HAVAL gives wrong hashes in specific cases
 [2015-09-01 19:07 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1390a5812b151e0ea8f74e64bfeaa5df4dd5b801
Log: Fix bug #70312 - HAVAL gives wrong hashes in specific cases
 [2015-09-02 08:29 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1390a5812b151e0ea8f74e64bfeaa5df4dd5b801
Log: Fix bug #70312 - HAVAL gives wrong hashes in specific cases
 [2015-09-03 18:10 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1390a5812b151e0ea8f74e64bfeaa5df4dd5b801
Log: Fix bug #70312 - HAVAL gives wrong hashes in specific cases
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Mon Feb 20 22:01:35 2017 UTC