C, Programming

Calculate SHA 512 hash using C and CryptoAPI

SHA-2 (Secure Hash Algorithm 2) is a set of cryptographic hash functions designed by the National Security Agency (NSA).[3] SHA stands for Secure Hash Algorithm. Cryptographic hash functions are mathematical operations run on digital data; by comparing the computed “hash” (the output from execution of the algorithm) to a known and expected hash value, a person can determine the data’s integrity. For example, computing the hash of a downloaded file and comparing the result to a previously published hash result can show whether the download has been modified or tampered with.[4] A key aspect of cryptographic hash functions is their collision resistance: nobody should be able to find two different input values that result in the same hash output.

SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of six hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256. – Wikipedia

CryptAcquireContextW
The CryptAcquireContext function is used to acquire a handle to a particular key container within a particular cryptographic service provider (CSP). This returned handle is used in calls to CryptoAPI functions that use the selected CSP. This function first attempts to find a CSP with the characteristics described in the dwProvType and pszProvider parameters. If the CSP is found, the function attempts to find a key container within the CSP that matches the name specified by the pszContainer parameter. – MSDN

CryptCreateHash
The CryptCreateHash function initiates the hashing of a stream of data. It creates and returns to the calling application a handle to a cryptographic service provider (CSP) hash object. – MSDN

CryptHashData
The CryptHashData function adds data to a specified hash object. This function can be called multiple times to compute the hash of long or discontinuous data streams. Before calling this function, CryptCreateHash must be called to create a handle of a hash object. – MSDN

CryptGetHashParam
The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be retrieved by using this function. – MSDN

CryptDestroyHash
The CryptDestroyHash function destroys the hash object referenced by the hHash parameter. After a hash object has been destroyed, it can no longer be used. – MSDN

CryptReleaseContext
The CryptReleaseContext function releases the handle of a cryptographic service provider (CSP) and a key container. At each call to this function, the reference count on the CSP is reduced by one. When the reference count reaches zero, the context is fully released and it can no longer be used by any function in the application. An application calls this function after finishing the use of the CSP. After this function is called, the released CSP handle is no longer valid. This function does not destroy key containers or key pairs. – MSDN

Initializing

bool HashInit(HCRYPTHASH *hCryptHash, HCRYPTPROV *hCryptProv)
{
	if (!CryptAcquireContextW(hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
	{
		printf("Error: %d\n", GetLastError());
		return false;
	}
 
	if (!CryptCreateHash(*hCryptProv, CALG_SHA_512, 0, 0, hCryptHash))
	{
		printf("Error: %d\n", GetLastError());
		CryptReleaseContext(hCryptProv, 0);
		hCryptProv = NULL;
		return false;
	}
 
	return true;
}

Calculate hash

bool GenerateHash(HCRYPTHASH hCryptHash, unsigned char *hash, unsigned long hashLen, const unsigned char *data, unsigned long dataLen)
{
	if (hCryptHash == NULL || data == NULL)
		return false;
 
	if (!CryptHashData(hCryptHash, data, dataLen, 0))
	{
		printf("Error: %d\n", GetLastError());
		return false;
	}
 
	if (hCryptHash == NULL)
		return false;
 
	if (!CryptGetHashParam(hCryptHash, HP_HASHVAL, hash, &hashLen, 0))
	{
		printf("Error: %d\n", GetLastError());
		return false;
	}
 
	return true;
}

Terminating

void HashUninit(HCRYPTHASH hCryptHash, HCRYPTPROV hCryptProv)
{
	if (hCryptHash)	if (!CryptDestroyHash(hCryptHash)) printf("Error: %d\n", GetLastError());
	if (hCryptProv)	if (!CryptReleaseContext(hCryptProv, 0)) printf("Error: %d\n", GetLastError());
}

Download full source code from Github.

git clone https://github.com/maldevel/HashSHA512