Re-encrypting data with a mechanism

The vendor-specific function C_IBM_ReencryptSingle() is available in openCryptoki and is supported by all tokens. You can use it to re-encrypt data encrypted with a given key and mechanism with another key and mechanism. This function is useful for secure key encryption with an EP11 token or a CCA token, because during the process, the data is never visible in the clear anywhere outside the cryptographic coprocessor.

The C_IBM_ReencryptSingle function has the following signature:


CK_RV C_IBM_ReencryptSingle(CK_SESSION_HANDLE hSession,
                            CK_MECHANISM_PTR pDecrMech,
                            CK_OBJECT_HANDLE hDecrKey,
                            CK_MECHANISM_PTR pEncrMech,     
                            CK_OBJECT_HANDLE hEncrKey,
                            CK_BYTE_PTR pEncryptedData,
                            CK_ULONG ulEncryptedDataLen,
                            CK_BYTE_PTR pReencryptedData,
                            CK_ULONG_PTR pulReencryptedDataLen);

Because the new function is non-standard, it does not appear in the PKCS #11 CK_FUNCTION_LIST structure returned by C_GetFunctionList(). To invoke this function, you must either locate the desired function in the main DLL using dlsym(), or link the application program with the main DLL. You can also use C_GetInterface() to get the interface called Vendor IBM. This interface also provides the C_IBM_ReencryptSingle() function.

Like other PKCS #11 functions, this function returns output in a variable-length buffer, conforming to the convention defined by PKCS #11.

If pReencryptedData is NULL_PTR, then the function only uses parameter *pulReencryptedDataLen to return a number of bytes which would suffice to hold the cryptographic output produced from the input to the function. This number may exceed the precise number of bytes needed, but not to a very high extent.

If pReencryptedData is not NULL_PTR, then *pulReencryptedDataLen must contain the size in bytes of the buffer pointed to by pReencryptedData. If that buffer is large enough to hold the cryptographic output produced by the function, then that cryptographic output is placed there, and CKR_OK is returned. If the buffer is not large enough, then CKR_BUFFER_TOO_SMALL is returned. In either case, *pulReencryptedDataLen is set to hold the exact number of bytes needed to hold the produced cryptographic output.

The function generally allows to specify any combination of decryption and encryption mechanisms. However, not all combinations work with all data sizes. Mechanisms that do not perform any padding, require that the data to be encrypted is a multiple of the block size. Also some mechanisms have certain size limitations (for example, RSA). If the data size after decryption with the decryption mechanism conflicts with the requirements of the encryption mechanisms, then the re-encrypt operation may fail with CKR_DATA_LEN_RANGE. Also, not all tokens may support all mechanism combinations. CKR_MECHANISM_INVALID is returned if one of the mechanisms specified is not supported for the re-encrypt operation.