Files
2017-09-23 14:38:53 -04:00

204 lines
5.8 KiB
C++

#include "ClrGuard.h"
//
// Calculates the sha256 from a block of data. Copy
// pasta from https://msdn.microsoft.com/en-us/library/windows/desktop/aa382379(v=vs.85).aspx
//
bool GetSha256(void * data, size_t dataSize, char * sha256, size_t hashSize)
{
HCRYPTPROV hProv = NULL;
HCRYPTHASH hHash = NULL;
PBYTE pbHash = NULL;
DWORD dwDataLen = 0;
bool retCode = false;
if (hashSize < 65)
{
goto cleanup;
}
if (!CryptAcquireContext(
&hProv, // handle of the CSP
NULL, // key container name
NULL, // CSP name
PROV_RSA_AES, // provider type
CRYPT_VERIFYCONTEXT)) // no key access is requested
{
printf(" Error in AcquireContext 0x%08x \n",
GetLastError());
goto cleanup;
}
if (!CryptCreateHash(
hProv, // handle of the CSP
CALG_SHA_256, // hash algorithm to use
0, // hash key
0, // reserved
&hHash)) // address of hash object handle
{
printf("Error in CryptCreateHash 0x%08x \n",
GetLastError());
goto cleanup;
}
if (!CryptHashData(
hHash, // handle of the hash object
(const BYTE*)data, // password to hash
(DWORD)dataSize, // number of bytes of data to add
0)) // flags
{
printf("Error in CryptHashData 0x%08x \n",
GetLastError());
goto cleanup;
}
if (!CryptGetHashParam(
hHash, // handle of the hash object
HP_HASHVAL, // query on the hash value
NULL, // filled on second call
&dwDataLen, // length, in bytes, of the hash
0))
{
printf("Error in CryptGetHashParam 0x%08x \n",
GetLastError());
goto cleanup;
}
pbHash = (BYTE*)malloc(dwDataLen);
if (NULL == pbHash)
{
printf("unable to allocate memory\n");
goto cleanup;
}
if (!CryptGetHashParam(
hHash, // handle of the hash object
HP_HASHVAL, // query on the hash value
pbHash, // pointer to the hash value
&dwDataLen, // length, in bytes, of the hash
0))
{
printf("Error in CryptGetHashParam 0x%08x \n", GetLastError());
goto cleanup;
}
retCode = true;
ZeroMemory(sha256, hashSize);
for (DWORD i = 0; i < dwDataLen; i++)
{
sprintf_s(&sha256[i * 2], 3, "%2.2X", pbHash[i]);
}
// Free resources.
cleanup:
if (hHash)
CryptDestroyHash(hHash);
if (hProv)
CryptReleaseContext(hProv, 0);
if (pbHash)
free(pbHash);
return retCode;
}
bool InitHash(HCRYPTPROV & hProv, HCRYPTHASH & hHash)
{
bool retCode = false;
if (!CryptAcquireContext(
&hProv, // handle of the CSP
NULL, // key container name
NULL, // CSP name
PROV_RSA_AES, // provider type
CRYPT_VERIFYCONTEXT)) // no key access is requested
{
printf(" Error in AcquireContext 0x%08x \n",
GetLastError());
goto cleanup;
}
if (!CryptCreateHash(
hProv, // handle of the CSP
CALG_SHA_256, // hash algorithm to use
0, // hash key
0, // reserved
&hHash)) // address of hash object handle
{
printf("Error in CryptCreateHash 0x%08x \n",
GetLastError());
goto cleanup;
}
retCode = true;
cleanup:
return retCode;
}
bool UpdateHash(HCRYPTHASH hHash, void * data, size_t dataSize)
{
if (!CryptHashData(
hHash, // handle of the hash object
(const BYTE*)data, // password to hash
(DWORD)dataSize, // number of bytes of data to add
0)) // flags
{
printf("Error in CryptHashData 0x%08x \n",
GetLastError());
return false;
}
return true;
}
bool FinishHash(HCRYPTPROV hProv, HCRYPTHASH hHash, char * sha256, size_t hashSize)
{
bool retCode = false;
DWORD dwDataLen = 0;
PBYTE pbHash = NULL;
if (!CryptGetHashParam(
hHash, // handle of the hash object
HP_HASHVAL, // query on the hash value
NULL, // filled on second call
&dwDataLen, // length, in bytes, of the hash
0))
{
printf("Error in CryptGetHashParam 0x%08x \n",
GetLastError());
goto cleanup;
}
pbHash = (BYTE*)malloc(dwDataLen);
if (NULL == pbHash)
{
printf("unable to allocate memory\n");
goto cleanup;
}
if (!CryptGetHashParam(
hHash, // handle of the hash object
HP_HASHVAL, // query on the hash value
pbHash, // pointer to the hash value
&dwDataLen, // length, in bytes, of the hash
0))
{
printf("Error in CryptGetHashParam 0x%08x \n", GetLastError());
goto cleanup;
}
ZeroMemory(sha256, hashSize);
for (DWORD i = 0; i < dwDataLen; i++)
{
sprintf_s(&sha256[i * 2], 3, "%2.2X", pbHash[i]);
}
retCode = true;
cleanup:
if (pbHash)
free(pbHash);
return retCode;
}