static std::wstring sha256()

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;
}