Some cryptographic algorithms needs a parameter to be executed. The simplest example is the CKM_DES_CBC_ENCRYPT_DATA algo. In this case the mechanism to pass to the EncryptInit function must contain a parameter with the initial vector (needed for CBC mode) and initial data.
The PKCS#11 specification defines this C struct to declare such parameter:
typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
CK_BYTE iv8;
CK_BYTE_PTR pData;
CK_ULONG length;
} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
The above struct contains an 8 byte Initialization Vector (IV) value followed by the data. The data value part must be a multiple of 8 bytes long.
Now, how can I convert and pass this struct in an NCryptoki mechanism?
This is the answer for the version 1.4.6 and later
First of all you should declare your param structure in C#:
StructLayout(LayoutKind.Sequential)
public struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
MarshalAs(UnmanagedType.ByValArray, SizeConst=8)
public byte[] iv;
MarshalAs(UnmanagedType.ByValArray, SizeConst=8)
public byte[] data;
public int length;
}
Note that I specified SizeCont=8, considering for example a DES key. If
your key has different length you should specify the exact length.
Then, you should instantiate your structure with the actual values:
CK_DES_CBC_ENCRYPT_DATA_PARAMS param = new CK_DES_CBC_ENCRYPT_DATA_PARAMS();
param.iv = new byte[]{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
param.data = new byte[]{0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
param.length = 8;
Finally you can instantiate you mechanism:
Mechanism mechanism = new Mechanism(CKM_DES_CBC_ENCRYPT_DATA, param);