Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HMAC-SHA256

609 views
Skip to first unread message

Gabi

unread,
Mar 20, 2008, 5:20:47 AM3/20/08
to
Hi,

I'm trying to implement HMAC-SHA256 using Crypto API. The results are
not the same using the test vectors described in RFC 4231.

I'm not expert in using Crypto Api so I have added the code below. I
may do something wrong, but I'm not sure what.
Here is the code:

/*
* Hash the password key using HMAC-SHA-256
* Test cases are defined in rfc4231.txt
* Encrypt-then-MAC
*/
long CWinNativeCrypt::HashKey(void *szKey, DWORD cbKey,
void *pbData, DWORD cbData,
LPBYTE *pbHMAC, LPDWORD pcbHMAC)
{


long err = ERROR_OK;

HCRYPTPROV hCryptProv = 0;
err = InitializeCryptoApi(&hCryptProv);

// Create an empty hash object.
HCRYPTHASH hKeyHash = 0;

if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hKeyHash))
{
err = E_FAIL;
// NTE_BAD_ALGID
DWORD dwError = GetLastError();
LOG(L"Error during CryptCreateHash!");
}

if (SUCCEEDED(err))
{
// Hash the password string.

if(!CryptHashData(hKeyHash, (BYTE*)szKey, cbKey, 0))
{
err = E_FAIL;
LOG(L"Error during CryptHashData!");
}
}

if (SUCCEEDED(err))
{
HCRYPTKEY hKey = 0;
HCRYPTHASH hHash = 0;
if (CryptDeriveKey(hCryptProv, CALG_RC4, hKeyHash, 0, &hKey))
{
if ( CryptCreateHash(hCryptProv, CALG_HMAC, hKey, 0,
&hHash))
{
HMAC_INFO hmacInfo;
ZeroMemory(&hmacInfo, sizeof(HMAC_INFO));
hmacInfo.HashAlgid = CALG_SHA_256;

if ( CryptSetHashParam(hHash, HP_HMAC_INFO,
(BYTE*)&hmacInfo, 0))
{
BYTE *data = (BYTE*)pbData;
if (CryptHashData(hHash, data, cbData, 0))
{
// Allocate memory, and get the HMAC.
DWORD cbHMAC = 0;
if(CryptGetHashParam(hHash, HP_HASHVAL, NULL,
&cbHMAC, 0))
{
// Retrieve the size of the hash.
*pcbHMAC = cbHMAC;
*pbHMAC = new BYTE[cbHMAC];

if(!CryptGetHashParam(hHash,
HP_HASHVAL, *pbHMAC, &cbHMAC, 0))
{
// could not get the hmac
err = E_FAIL;
}


}
else
{
// error GetHashParam()
err = E_FAIL;
}
}
else
{
// error CryptHashData();
err = E_FAIL;
}
}
else
{
// error CryptSetHashParam();
err = E_FAIL;
}
}
else
{
// error CreateHash
err = E_FAIL;
}
}
else
{
// error CryptDeriveKey
err = E_FAIL;
}

// Destroy the hash object.

if(hHash)
{
CryptDestroyHash(hHash);
}
if (hKey)
{
CryptDestroyKey(hKey);
}

}

if (hKeyHash)
{
CryptDestroyHash(hKeyHash);
}

if (hCryptProv)
err = ReleaseCryptoApi(hCryptProv);


return err;
}

Thanks,
Gabi

Andrew Tucker [MSFT]

unread,
Apr 1, 2008, 11:40:11 PM4/1/08
to

You are testing HMAC(SHA-256(Key), Data) instead of HMAC(Key, Data)
that is specified in the RFC test vectors. To use a plaintext HMAC
key instead of a hashed key you need to create the key with
CryptImportKey - see the description of CRYPT_IPSEC_HMAC_KEY at
http://msdn2.microsoft.com/en-us/library/aa380207.aspx for details.

0 new messages