CPDeriveKey

The CPDeriveKey function generates cryptographic session keys derived from base data. This function guarantees that all keys generated from the same base data will be identical, provided that the same algorithms are specified. The base data can be a password or any other user data.

BOOL CPDeriveKey(
  HCRYPTPROV hProv,      // in
  ALG_ID Algid,          // in
  HCRYPTHASH hBaseData,  // in
  DWORD dwFlags,         // in
  HCRYPTKEY *phKey       // out
);
 

Parameters

hProv
Handle to a particular key container (or "context") within the CSP. This handle is obtained via a call to CPAcquireContext.
Algid
Identifier for the encryption algorithm for which the key is to be generated. This algorithm must be one of those supported by this CSP.
See CPGenKey.
hBaseData
Handle to a hash object that has been fed exactly the base data.
dwFlags
Flags specifying attributes pertaining to the session key generated. Not all CSPs will support all flags. The flags currently defined are:
CRYPT_EXPORTABLE
If this flag is set, then the session key can be transferred out of the CSP into a key blob through the CPExportKey function. Because keys generally must be exportable, this flag should usually be set.

If this flag is not set, then the session key will not be exportable. This means the key will be available only within the current session and only the application that created it will be able to use it.

This flag does not apply to public/private key pairs.

CRYPT_CREATE_SALT
Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value is 128 bits and the session key is 40 bits, there will be 88 bits left over.

If this flag is set, then the key will be assigned a salt value based on the unused hash value bits. You can retrieve this salt value by using the CPGetKeyParam function with the dwParam parameter set to KP_SALT.

If this flag is not set, then the key will be given a salt value of zero.

When keys with nonzero salt values are exported (by using CPExportKey), the salt value must also be obtained and kept with the key blob.

CRYPT_NO_SALT
Specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Microsoft® Cryptographic Providers--Release Notes.
CRYPT_USER_PROTECTED
If this flag is set, then the user will be notified through a dialog box or another method when this key is used to attempt certain actions. The precise behavior is specified by the CSP being used. Prior to Microsoft Internet Explorer 4.0, the Microsoft Cryptographic Providers ignore this flag. Starting with Microsoft Internet Explorer 4.0, Microsoft Cryptographic Providers support this flag value.
CRYPT_UPDATE_KEY
Some CSPs use session keys that are derived from multiple hash values. When this is the case, CPDeriveKey must be called multiple times.

If this flag is set, a new session key is not generated. Instead, the key specified by phKey is modified. The precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used.

The Microsoft Cryptographic Providers ignore this flag.

phKey
Address to which the function copies the handle of the newly generated 85 key.

Return Values

If the function succeeds, TRUE should be returned; otherwise, return FALSE. When FALSE is returned, the appropriate error code (see the following table) must be set via SetLastError.

Error Description
NTE_BAD_ALGID The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS The dwFlags parameter contains an invalid value.
NTE_BAD_HASH The hBaseData parameter does not contain a valid handle to a hash object.
NTE_BAD_HASH_STATE An attempt was made to add data to a hash object that is already marked "finished."
NTE_FAIL The function failed in some unexpected way.
NTE_BAD_UID The hProv parameter does not contain a valid context handle.

Remarks

If CSP interoperability is important to you, then your session keys must be derived in the precise manner specified by the CSP's type. For example, if your CSP's type is PROV_RSA_FULL or PROV_RSA_SIG, then see Interoperability with RSA CSPs for information on how the key derivation must be performed.

Of course, if you are defining your own CSP type, then you are free to derive session keys in any manner that you see fit.

See Also

CPDestroyKey, CPGenKey, CryptDeriveKey