BCrypt API with MD5 algorithm produces unexpected results

Hi list,

I’ve implemented MD5 hashing in a kernel driver using the BCrypt / CNG
API but I’m having some trouble with the results its giving me. As an
example, when I hash ‘calc.exe’ from Windows 7 I get the following using
HashMyFiles or md5sum on linux:
10e4a1d2132ccb5c6759f038cdb6f3c9

But when I do the same using BCrypt I get:
d20b2c9aa06380acf88048f47403b9a6

To give you an idea of what I’m doing:

  • I read a file using the ZwCreateFile, ZwReadFile API’s:

    ZwCreateFile( &hFile, GENERIC_READ,
    &objAttr, &ioStatusBlock,
    NULL, FILE_ATTRIBUTE_NORMAL,
    FILE_SHARE_READ, FILE_OPEN,
    FILE_NON_DIRECTORY_FILE,
    NULL, 0);
    …snip…
    ZwReadFile( hFile, NULL,
    NULL, NULL,
    &ioStatusBlock, fData,
    fileStdInfo.AllocationSize.LowPart,
    &byteOffset, NULL);

In between I check for STATUS_PENDING to ensure that all data is
completely read. In the shown code I read the whole file at once, I’ve
also used an implementation where I read small chunks to feed to
BCryptHashData instead of giving it all at once, it gave no difference
in output. I also confirmed the data being read into fData, I checked it
against the file data itself and it matches.

  • I hash the data read from the file:
    BCryptHashData(hHash, fData, fileStdInfo.AllocationSize.LowPart, 0);

  • I finish the hash and obtain the hash result:
    BCryptFinishHash( hHash, pbHash, cbHash, 0);

On finishing this information is passed from the driver to a client
running in userland, I confirmed no changes between the data transfer
from kernel to userland.

One thing I did notice although I don’t think its that important; when
not hashing / digesting data the default hash (as seen in the
implementations of md5sum and others) is:
d41d8cd98f00b204e9800998ecf8427e BCrypt in this case gives back:
1dd4d98c8f4b280e99809f8ec7e42. I dont know if its relevant for my problem.

Has anyone ever encountered something like this before ? I’m confused on
why there is a difference in output from BCrypt in regards to other
crypto API’s. All other implementations I used give me the hash
HashMyFiles and md5sum also give me, BCrypt seems to be the only one
giving a different result.

Regards,
-Yonathan

Hello Yonathan,

have you already seen this example?
http://msdn.microsoft.com/en-us/library/windows/desktop/aa376217(v=vs.85).aspx
Looks like this gives correct hashes, including the case of an empty data buffer.

And it supposed with the BCrypt it’s possible to develop and debug your crypting function at the user mode, and then move it into a driver. Would you like to use such a possibility?

Hi kt133a,

Yes, I’ve actually worked from that example when first implementing my hashing.

I will port my current code to user mode and see if I can pinpoint the problem there (a lot easier to debug). I’ll get back to you with the results on that.

I just copied the hashing code to a usermode application and ran it, this time it does produce the correct results:

\MD5check_bcrypt\Debug>MD5check_bcrypt.exe calc.exe
10e4a1d2132ccb5c6759f038cdb6f3c9

Interestingly, it is a 1:1 copy except for the file read… this I do with fopen() instead of the ZwReadFile as I do in the kernel. I expect this to be the culprit but I have no clue how this could be. I compared filebuffers and the complete file was read into memory as expected.

I’ll do more checking into the file IO by porting the ReadFile code to the usermode application as well, I don’t have any other leads to go on right now.

i’ve just compiled the msdn-example for the user-mode and then for the kernel and the ‘MD5’ for the ‘0/0 buffer’ in both cases is:
d41d8cd98f00b204e9800998ecf8427e
as expected.

So perhaps you should fix for the default MD5-hash is to be correct with your kernel crypt-engine before dealing with files.

Have you seen the similarity between your last numbers:

d41d 8cd9 8f00 b204 e980 0998 ecf8 427e
1dd4 d98c 8f 4 b2 80e9 9809 f8ec 7e42

Beside some missing characters,
it looks like endian is different???

Yeah I was just looking at it going “looks like all characters are in
there.” Time to fix this…
On May 24, 2014 6:17 PM, wrote:

> Have you seen the similarity between your last numbers:
>
> d41d 8cd9 8f00 b204 e980 0998 ecf8 427e
> 1dd4 d98c 8f 4 b2 80e9 9809 f8ec 7e42
>
> Beside some missing characters,
> it looks like endian is different???
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Sharp look, Mr.Maurer!

Indeed, forgot to mention I run under x64.
On May 24, 2014 6:24 PM, wrote:

> Sharp look, Mr.Maurer!
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

>- I hash the data read from the file: BCryptHashData(hHash, fData, fileStdInfo.AllocationSize.LowPart, 0);

how i understand you use ‘FILE_STANDARD_INFORMATION fileStdInfo;’
but need use real file size - fileStdInfo.EndOfFile not AllocationSize !!