2025-11-28 00:35:46 +09:00

200 lines
6.4 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// File: HashComputation.cpp
//
// Contents: This sample shows how to compute SHA 256 hash of a message(s) using CNG.
//
//
//
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <winternl.h>
#include <ntstatus.h>
#include <winerror.h>
#include <stdio.h>
#include <bcrypt.h>
#include <sal.h>
static const
BYTE Message[] =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
};
//
// Utilities and helper functions
//
//----------------------------------------------------------------------------
//
// ReportError
// Prints error information to the console
//
//----------------------------------------------------------------------------
void
ReportError(
_In_ DWORD dwErrCode
)
{
wprintf( L"Error: 0x%08x (%d)\n", dwErrCode, dwErrCode );
}
//-----------------------------------------------------------------------------
//
// wmain
//
//-----------------------------------------------------------------------------
DWORD
__cdecl
wmain(
_In_ int argc,
_In_reads_(argc) LPWSTR argv[]
)
{
NTSTATUS Status;
BCRYPT_ALG_HANDLE AlgHandle = NULL;
BCRYPT_HASH_HANDLE HashHandle = NULL;
PBYTE Hash = NULL;
DWORD HashLength = 0;
DWORD ResultLength = 0;
//
// Open an algorithm handle
// This sample passes BCRYPT_HASH_REUSABLE_FLAG with BCryptAlgorithmProvider(...) to load a provider which supports reusable hash
//
Status = BCryptOpenAlgorithmProvider(
&AlgHandle, // Alg Handle pointer
BCRYPT_SHA256_ALGORITHM, // Cryptographic Algorithm name (null terminated unicode string)
NULL, // Provider name; if null, the default provider is loaded
BCRYPT_HASH_REUSABLE_FLAG); // Flags; Loads a provider which supports reusable hash
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// Obtain the length of the hash
//
Status = BCryptGetProperty(
AlgHandle, // Handle to a CNG object
BCRYPT_HASH_LENGTH, // Property name (null terminated unicode string)
(PBYTE)&HashLength, // Address of the output buffer which recieves the property value
sizeof(HashLength), // Size of the buffer in bytes
&ResultLength, // Number of bytes that were copied into the buffer
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// Allocate the hash buffer on the heap
//
Hash = (PBYTE)HeapAlloc (GetProcessHeap (), 0, HashLength);
if( NULL == Hash )
{
Status = STATUS_NO_MEMORY;
ReportError(Status);
goto cleanup;
}
//
// Create a hash handle
//
Status = BCryptCreateHash(
AlgHandle, // Handle to an algorithm provider
&HashHandle, // A pointer to a hash handle - can be a hash or hmac object
NULL, // Pointer to the buffer that recieves the hash/hmac object
0, // Size of the buffer in bytes
NULL, // A pointer to a key to use for the hash or MAC
0, // Size of the key in bytes
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// Hash the message(s)
// More than one message can be hashed by calling BCryptHashData
//
Status = BCryptHashData(
HashHandle, // Handle to the hash or MAC object
(PBYTE)Message, // A pointer to a buffer that contains the data to hash
sizeof (Message), // Size of the buffer in bytes
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// Obtain the hash of the message(s) into the hash buffer
//
Status = BCryptFinishHash(
HashHandle, // Handle to the hash or MAC object
Hash, // A pointer to a buffer that receives the hash or MAC value
HashLength, // Size of the buffer in bytes
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
Status = STATUS_SUCCESS;
cleanup:
if( NULL != Hash)
{
HeapFree(GetProcessHeap(), 0, Hash);
}
if (NULL != HashHandle)
{
BCryptDestroyHash(HashHandle); // Handle to hash/MAC object which needs to be destroyed
}
if( NULL != AlgHandle )
{
BCryptCloseAlgorithmProvider(
AlgHandle, // Handle to the algorithm provider which needs to be closed
0); // Flags
}
return (DWORD)Status;
UNREFERENCED_PARAMETER( argc );
UNREFERENCED_PARAMETER( argv );
}