Why is getting the HP_HASHSIZE so weird?

Raymond Chen

Raymond

A comment on the documentation page for Crypt­Get­Hash­Param notes that the “obvious” way to get the HP_HASH­SIZE is incorrect.

// Version 1: wrong.
DWORD size = 0;
if (CryptGetHashParam(hash, HP_HASHSIZE, nullptr, &size, 0)) ...

// Version 2: right.
DWORD size;
DWORD bufferSize = sizeof(size);
if (CryptGetHashParam(hash, HP_HASHSIZE, &size, &bufferSize, 0)) ...

What’s going on here? I mean, the documentation says that if you want to get the size of a parameter, you pass nullptr for the buffer, and the DWORD* parameter gets the size of the buffer. So if I want to get the hash size, I should pass nullptr for the buffer, and the DWORD* parameter gets the size of the hash. But it doesn’t. It always returns 4. What’s going on?

What’s going on is that you are working at the wrong level of indirection. The code in version 1 is not asking for the size of the hash. It’s asking for the size of the HP_HASH­SIZE. In other words, you’re asking for the size of the size. Since HP_HASH­SIZE is a DWORD, its size is 4. You then need to follow up with the code in version 2, which allocates a buffer of size 4 and asks for it to be filled in with the HP_HASH­SIZE.

A third way to get the size of the hash is to ignore HP_HASH­SIZE completely and go straight for the HP_HASH­VAL:

// Version 3: righter
DWORD hashSize = 0;
if (CryptGetHashParam(hash, HP_HASHVAL, nullptr, &hashSize, 0)) ...

I don’t know why the crypto folks bothered to have a HP_HASH­SIZE parameter. Adding it only created confusion.

Raymond Chen
Raymond Chen

Follow Raymond   

0 comments

Comments are closed.