CryptSetKeyParam

This function customizes various aspects of a key's operations.

Generally, this function is used to set session-specific parameters on symmetric keys.

The Microsoft Base Cryptographic Provider has no parameters that can be set on key exchange or signature keys. However, custom providers may define parameters that can be set on these keys.

At a Glance

Header file: Wincrypt.h
Windows CE versions: 2.10 and later

Syntax

BOOL WINAPI CryptSetKeyParam( HCRYPTKEY hKey,
DWORD dwParam, BYTE *pbData, DWORD dwFlags );

Parameters

hKey

[in] Handle to the key on which to set parameters.

dwParam

[in] Specifies the parameter number. See the "Remarks" section for a list of valid parameters.

pbData

[in] Pointer to the parameter data buffer. Place the parameter data in this buffer before calling CryptSetKeyParam. The form of this data will vary, depending on the parameter number.

dwFlags

[in] Specifies a bitmask of flags. This parameter is reserved for future use; set to 0.

Return Values

TRUE indicates success. FALSE indicates failure. To get extended error information, call GetLastError. Common values for GetLastError are described in the following table. The error values prefaced by "NTE" are generated by the particular CSP you are using.

Value Description
ERROR_INVALID_HANDLE One of the parameters specifies an invalid handle.
ERROR_BUSY The CSP context is currently being used by another process.
ERROR_INVALID_PARAMETER One of the parameters contains an invalid value. This is most often an illegal pointer.
NTE_BAD_FLAGS The dwFlags parameter is nonzero or the pbData buffer contains an invalid value.
NTE_BAD_DATA Either the algorithm that works with the public key you are trying to import is not supported by this CSP, or an attempt was made to import a session key that was encrypted with something other than one of your public keys.
NTE_BAD_KEY The hKey parameter does not contain a valid handle to a key.
NTE_BAD_TYPE The dwParam parameter specifies an unknown parameter.
NTE_BAD_UID The CSP context that was specified when the hKey key was created cannot be found.
NTE_FAIL The function failed in some unexpected way.
NTE_FIXEDPARAMETERS Some CSPs will have hard coded P, Q, and G values. If this is the case, then using the KP_P, KP_Q, and KP_G for the value of dwParam will cause this error.

Remarks

For all session key types, the dwParam value can be set to one of the following key parameter types.

KP_SALT

The salt value. The pbData buffer should contain a BYTE array specifying a new salt value. This value is made part of the session key. The size of the salt value will vary depending on the CSP being used, so before setting this parameter, it should be read by using CryptGetKeyParam in order to determine its size.

When you suspect that the base data used for derived keys is less than ideal, salt values are often used to make the session keys more unique. This makes dictionary attacks more difficult.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to zero.

KP_SALT_EX

To set a salt value, a user can call the CryptSetKeyParam function with the KP_SALT_EX parameter value specified and with the pbData parameter pointing to a CRYPTOAPI_BLOB structure containing the salt.

KP_PERMISSIONS

The key permissions flags. The pbData buffer should contain a DWORD value specifying zero or more permission flags. Refer to the CryptGetKeyParam function for a description of these flags.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to 0xFFFFFFFF.

If a DSS key is specified by hKey, the dwParam value can also be set to one of the following parameter types.

KP_P

The pbData buffer should contain a pointer to the prime modulus P from the DSS key BLOB that is to be set. The data is in the form of a BLOB structure where the pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little endian form.

KP_Q

The pbData buffer should contain a pointer to the prime Q from the DSS key BLOB that is to be set. The data is in the form of a BLOB structure where the pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little endian form.

KP_G

The pbData buffer should contain a pointer to the generator G from the DSS key BLOB that is to be set The data is in the form of a BLOB structure, where the pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little endian form.

KP_X

Once the P, Q, and G values have been set, a call can be made to CryptSetKeyParam specifying the KP_X value for dwParam and NULL for the pbData parameter. This will cause the X and Y values to be generated.

If a block cipher session key is specified by hKey, the dwParam value can also be set to one of the following parameter types.

KP_EFFECTIVE_KEYLEN

This parameter may be used only with RC2 keys and has been added due to the previous implementation of CryptSetKeyParam in the Microsoft® Windows NT® version 4.0 Service Pack 2 MS Enhanced Provider. In that implementation the RC2 keys in the Enhanced Provider were 128 bits in strength, but the effective key length used to expand keys into the key table was only 40 bits. This reduced the strength of the algorithm to 40 bits.

To maintain backward compatibility, the previous implementation will remain as is. However, the effective key length may be set to be greater than 40 bits by using this parameter value in the CryptSetKeyParam call. The effective key length is passed in the pbData parameter as a pointer to a DWORD with the effective key length value. The minimum effective key length on the Microsoft Base Cryptographic Provider is 1 and the maximum is 40. In the MS Enhanced Provider the minimum is 1 and the maximum is 1024. The key length must be set prior to encrypting or decrypting with the key.

KP_IV

The initialization vector. The pbData buffer should contain a BYTE array specifying the initialization vector. This array should contain block_length/8 elements. For example, if the block length is 64 bits, the initialization vector will consist of eight bytes.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to zero.

KP_PADDING

The padding mode. The pbData buffer should contain a DWORD value specifying the padding method to be used by the cipher. Following are the padding modes currently defined:

PKCS5_PADDING. PKCS 5 (sec 6.2) padding method.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to PKCS5_PADDING.

KP_MODE

The cipher mode. The pbData buffer should contain a DWORD value specifying the cipher mode to be used. Refer to the CryptGetKeyParam function for a list of the defined cipher modes.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to CRYPT_MODE_CBC.

KP_MODE_BITS

The number of bits to feed back. The pbData buffer contains a DWORD value indicating the number of bits that are processed per cycle when the OFB or CFB cipher mode is used.

When using the Microsoft Base Cryptographic Provider, this parameter defaults to eight.

Example

#include <wincrypt.h>

HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
DWORD dwMode;
BYTE pbData[16];
DWORD dwCount;
DWORD i;

// Get a handle to the user default provider.
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
 printf("Error %x during CryptAcquireContext!\n", GetLastError());
 goto done;
}

// Create a random block cipher session key.
if(!CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey)) {
 printf("Error %x during CryptGenKey!\n", GetLastError());
 goto done;
}

// Set the cipher mode.
dwMode = CRYPT_MODE_ECB;
if(!CryptSetKeyParam(hKey, KP_MODE, &dwMode, 0)) {
 printf("Error %x during CryptSetKeyParam!\n", GetLastError());
 goto done;
}

// Generate a random initialization vector.
if(!CryptGenRandom(hProv, 8, pbData)) {
 printf("Error %x during CryptGenRandom!\n", GetLastError());
 goto done;
}

// Set the initialization vector.
if(!CryptSetKeyParam(hKey, KP_IV, pbData, 0)) {
 printf("Error %x during CryptSetKeyParam!\n", GetLastError());
 goto done;
}

// Use 'hKey' to encrypt a message.
...

done:

// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);

// Release the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);

See Also

CryptGenKey, CryptGetKeyParam