CryptDuplicateHash function (wincrypt.h)

The CryptDuplicateHash function makes an exact copy of a hash to the point when the duplication is done. The duplicate hash includes the state of the hash.

A hash can be created in a piece-by-piece way. The CryptDuplicateHash function can be used to create separate hashes of two different contents that begin with the same content.

Syntax

BOOL CryptDuplicateHash(
  [in]  HCRYPTHASH hHash,
  [in]  DWORD      *pdwReserved,
  [in]  DWORD      dwFlags,
  [out] HCRYPTHASH *phHash
);

Parameters

[in] hHash

Handle of the hash to be duplicated.

[in] pdwReserved

Reserved for future use and must be zero.

[in] dwFlags

Reserved for future use and must be zero.

[out] phHash

Address of the handle of the duplicated hash. When you have finished using the hash, release the handle by calling the CryptDestroyHash function.

Return value

If the function succeeds, the function returns TRUE.

If the function fails, it returns FALSE. For extended error information, call GetLastError.

The error code prefaced by "NTE" is generated by the particular cryptographic service provider (CSP) that you are using. Some possible error codes follow.

Return code Description
ERROR_CALL_NOT_IMPLEMENTED
Because this is a new function, existing CSPs cannot implement it. This error is returned if the CSP does not support this function.
ERROR_INVALID_PARAMETER
One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.
NTE_BAD_HASH
A handle to the original hash is not valid.

Remarks

CryptDuplicateHash makes a copy of a hash and the exact state of the hash. This function might be used if a calling application needed to generate two hashes but both hashes had to start with some common data hashed. For example, a hash might be created, the common data hashed, a duplicate made with the CryptDuplicateHash function, and then the data unique to each hash would be added.

The CryptDestroyHash function must be called to destroy any hashes that are created with CryptDuplicateHash. Destroying the original hash does not cause the duplicate hash to be destroyed. After a duplicate hash is made, it is separate from the original hash. There is no shared state between the two hashes.

Examples

The following example shows making an exact copy of a hash. For an example that includes the complete context for this example, see Example C Program: Duplicating a Hash.

//-------------------------------------------------------------------
//  Declare and initialize variables.

HCRYPTPROV   hCryptProv = NULL;
HCRYPTHASH   hOriginalHash = NULL;
HCRYPTHASH   hDuplicateHash = NULL;

//-------------------------------------------------------------------
// Acquire a CSP context.

if(CryptAcquireContext(
   &hCryptProv, 
   NULL, 
   NULL, 
   PROV_RSA_FULL, 
   0)) 
{
    printf("CryptAcquireContext succeeded. \n");
}
else
{
    printf("Error during CryptAcquireContext.\n");
    exit(1);
}
//-------------------------------------------------------------------
// Create a hash.

if (CryptCreateHash(
    hCryptProv, 
    CALG_SHA1, 
    0, 
    0,
    &hOriginalHash))
{
   printf("An empty hash object has been created. \n");
}
else
{
   printf("Error during CryptCreateHash.\n");
   exit(1);
}
//-------------------------------------------------------------------
// Hash a BYTE string.

if (CryptHashData(
    hOriginalHash, 
    (BYTE*)"Some Common Data", 
    sizeof("Some Common Data"), 0))
{
   printf("An original hash has been created. \n");
}
else
{
   printf("Error during CryptHashData.\n");
   exit(1);
}
//-------------------------------------------------------------------
// Duplicate the hash.

if (CryptDuplicateHash(
   hOriginalHash, 
   NULL, 
   0, 
   &hDuplicateHash))
{
   printf("The hash has been duplicated. \n");
}
else
{
   printf("Error during CryptDuplicateHash.\n");
   exit(1);
}
//-------------------------------------------------------------------
// At this point, the two hash objects are exactly the same.
// The two hash objects can be handled separately.
// When all processing on the hash object is completed, 
// both objects should be destroyed, and the cryptographic
// context should be released.

//-------------------------------------------------------------------
// Destroy the original hash.

if(CryptDestroyHash(hOriginalHash))
{
   printf("The original hash has been destroyed. \n");
}
else
{
   printf("Error during CryptDestroyHash on the original "
       "hash object.\n");
   exit(1);
}
//-------------------------------------------------------------------
// Destroy the duplicate hash.

if (CryptDestroyHash(hDuplicateHash))
{
   printf("The duplicate hash has been destroyed. \n");
}
else
{
   printf("Error during CryptDestroyHash on the duplicated hash object.\n");
   exit(1);
}

//-------------------------------------------------------------------
// Release the CSP.

if(hCryptProv) 
   CryptReleaseContext(hCryptProv,0);

Requirements

Requirement Value
Minimum supported client Windows XP [desktop apps only]
Minimum supported server Windows Server 2003 [desktop apps only]
Target Platform Windows
Header wincrypt.h
Library Advapi32.lib
DLL Advapi32.dll

See also

CryptDestroyHash

Hash and Digital Signature Functions