Skip to content

Instantly share code, notes, and snippets.

@daiakushi
Last active December 13, 2022 02:41
Show Gist options
  • Save daiakushi/374e867a438f828b8d26eb710185150d to your computer and use it in GitHub Desktop.
Save daiakushi/374e867a438f828b8d26eb710185150d to your computer and use it in GitHub Desktop.
Creating a Hash with CNG
// Client should release HashData with HeapFree()
// e.g. HeapFree(GetProcessHeap(), 0, HashData);
// Ref. https://learn.microsoft.com/en-us/windows/win32/seccng/creating-a-hash-with-cng
NTSTATUS HashCreate (
LPCWSTR HashAlg,
PBYTE RawData,
DWORD RawDataSize,
PBYTE *HashData,
DWORD *HashDataSize
)
{
BCRYPT_ALG_HANDLE hAlg = NULL;
BCRYPT_HASH_HANDLE hHash = NULL;
DWORD cbData = 0, cbHash = 0, cbHashObject = 0;
PBYTE pbHashObject = NULL, pbHash = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
if (!HashData || !HashDataSize) return status;
// open an algorithm handle
status = BCryptOpenAlgorithmProvider(
&hAlg,
HashAlg,
NULL,
0);
if (!NT_SUCCESS(status)) goto error;
// calculate the size of the buffer to hold the hash object
status = BCryptGetProperty(
hAlg,
BCRYPT_OBJECT_LENGTH,
(PBYTE)&cbHashObject,
sizeof(DWORD),
&cbData,
0);
if (!NT_SUCCESS(status)) goto error;
// allocate the hash object on the heap
pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
if (NULL == pbHashObject) goto error;
// calculate the length of the hash
status = BCryptGetProperty(
hAlg,
BCRYPT_HASH_LENGTH,
(PBYTE)&cbHash,
sizeof(DWORD),
&cbData,
0);
if (!NT_SUCCESS(status)) goto error;
// allocate the hash buffer on the heap
pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHash);
if (NULL == pbHash) goto error;
// create hash
status = BCryptCreateHash(
hAlg,
&hHash,
pbHashObject,
cbHashObject,
NULL,
0,
0);
if (!NT_SUCCESS(status)) goto error;
// hash some data
status = BCryptHashData(
hHash,
RawData,
RawDataSize,
0);
if (!NT_SUCCESS(status)) goto error;
// close the hash
status = BCryptFinishHash(
hHash,
pbHash,
cbHash,
0);
if (NT_SUCCESS(status)) {
*HashData = pbHash;
*HashDataSize = cbHash;
}
error:
if (hAlg) BCryptCloseAlgorithmProvider(hAlg, 0);
if (hHash) BCryptDestroyHash(hHash);
if (pbHashObject) HeapFree(GetProcessHeap(), 0, pbHashObject);
return status;
}
@daiakushi
Copy link
Author

int main(int argc, char *argv[])
{
	PBYTE buffer, hashVal;
	DWORD bufferSize, hashValSize;

	if (argc < 2) return 1;

	FileRead(argv[1], &buffer, &bufferSize);

	printf("SHA256 :\n    ");
	if (NT_SUCCESS(HashCreate(
					BCRYPT_SHA256_ALGORITHM,
					buffer,
					bufferSize,
					&hashVal,
					&hashValSize)))
	{
		for (int index = 0; index < hashValSize; index++) {
			printf("%02X", hashVal[index]);
			printf("%s", (index + 1) % 16 ? " " : "\n    ");
		}
		HeapFree(GetProcessHeap(), 0, hashVal);
	}
	HeapFree(GetProcessHeap(), 0, buffer);

	return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment