in src/Windows/local_cache.cpp [93:184]
static std::wstring sha256(size_t data_size, const void* data)
{
wil::unique_bcrypt_algorithm hAlg;
wil::unique_bcrypt_hash hHash;
NTSTATUS status = STATUS_UNSUCCESSFUL;
std::string errorString;
DWORD cbData = 0;
DWORD cbHash = 0;
std::vector<BYTE> pbHash;
PBYTE pHashItr = nullptr;
std::string retval;
//open an algorithm handle
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
hAlg.addressof(),
BCRYPT_SHA256_ALGORITHM,
nullptr,
0)))
{
errorString = "Error 0x" + std::to_string(status) + "returned by BCryptOpenAlgorithmProvider\n";
goto Cleanup;
}
//calculate the length of the hash
if (!NT_SUCCESS(status = BCryptGetProperty(
hAlg.get(),
BCRYPT_HASH_LENGTH,
(PBYTE)&cbHash,
sizeof(DWORD),
&cbData,
0)))
{
errorString = "Error 0x" + std::to_string(status) + "returned by BCryptGetProperty\n";
goto Cleanup;
}
//allocate the hash buffer on the heap
pbHash = std::vector<BYTE>(cbHash);
//create a hash
if (!NT_SUCCESS(status = BCryptCreateHash(
hAlg.get(),
hHash.addressof(),
nullptr,
0,
nullptr,
0,
0)))
{
errorString = "Error 0x" + std::to_string(status) + "returned by BCryptCreateHash\n";
goto Cleanup;
}
//hash some data
if (!NT_SUCCESS(status = BCryptHashData(
hHash.get(),
(PBYTE)data,
(ULONG)data_size,
0)))
{
errorString = "Error 0x" + std::to_string(status) + "returned by BCryptHashData\n";
goto Cleanup;
}
//close the hash
if (!NT_SUCCESS(status = BCryptFinishHash(
hHash.get(),
pbHash.data(),
cbHash,
0)))
{
errorString = "Error 0x" + std::to_string(status) + "returned by BCryptFinishHash\n";
goto Cleanup;
}
pHashItr = pbHash.data();
retval.reserve(2 * cbHash + 1);
for (size_t i = 0; i < cbHash; i++)
{
char buf[3];
snprintf(buf, sizeof(buf), "%02x", pHashItr[i]);
retval += buf;
}
Cleanup:
throw_if(!NT_SUCCESS(status), errorString);
std::wstring wretval(retval.begin(), retval.end());
return wretval;
}