Luna HSM Cloning API CPv4 Extensions to PKCS#11

Similar to earlier cloning protocols, CPv4 has two sets of APIs; a single top level API that performs the full key migration and a set of low level APIs that can break the protocol into two parts;

>session key establishment
vs

>key extraction/insertion.

The low level APIs can also be used to execute the protocol on two partitions that are not directly accessible by a single client application.

Diagram showing API flow

Top-Level API: CA_MigrateKeys

This API clones one-or-more objects from a source session to a target session. The API can clone user objects (a.k.a. CryptokiObjects) or parameters like the SMK (a.k.a. ParamObjects). The API also supports a “flags” field to alter/change the behavior of the API when errors are encountered.

In addition to implementing CPv4, the top level API takes on the behavior that allows it to use existing key migration methods.

CA_MigrateKeys(CK_SESSION_HANDLE            sourceSession, 
               CK_SESSION_HANDLE            targetSession, 
               CK_ULONG                     migrationFlags, 
               CK_ULONG                     numberOfObjects, 
               CK_OBJECT_MIGRATION_DATA_PTR migrationData); 
I/O Argument Description
In sourceSession An authenticated session on the source partition.
targetSession An authenticated session on the target partition.
migrationFlags

Flags used to define the behavior of the migration protocol. The following flag is accepted:

>CKF_CONTINUE_ON_ERR (0x01): If specified, the API continues attempting to clone objects if an individual object fails to clone. If the flag is not specified, the API fails after the first failure is encountered.

numberOfObjects The number of objects to migrate. Implicitly defines the size of the array pointed to by “migrationData”. This parameter cannot be 0.
In/Out migrationData

An array of CK_MIGRATION_DATA objects whose length is defined by “numberOfObjects”. This parameter cannot be NULL. The array is defined by the following structure:

typedef struct CK_OBJECT_MIGRATION_DATA (
   CK_ULONG   objectType;
   CK_OBJECT_HANDLE sourceHandle;
   CK_OBJECT_HANDLE targetHandle;
   CK_RV  rv
} CK_OBJECT_MIGRATION_DATA;

Fields:

>objectType: used to specify if the object is a CryptokiObject or a ParamObject.

>sourceHandle: the handle of the object to be cloned.

>targetHandle: the handle of the object after it has been cloned to the target device.

>rv: the result of the clone operation for this specific object. This field is initialized to CKR_CLONE_NOT_ATTEMPTED for every object. If an object fails to clone, then the rv field for that object is populated with the specific error code for the failure. Callers of CA_MigrateKeys should verify the rv field for each object to determine if the object was successfully cloned.

If an individual object fails to clone, CA_MigrateKeys returns CKR_OK. If an error is encountered in the core logic of CA_MigrateKeys, then the error code for that event is returned by the API, and the value of rv remains CKR_CLONE_NOT_ATTEMPTED for all objects that were not attempted to be cloned.

Low-Level APIs

This section defines the low-level APIs. The low-level APIs map to the internal APIs defined within the client library, that are used by the top level CA_MigrateKeys API.

If an application does not have access (is unable to open a session) to both the target and source HSM, then the low level APIs can be used and the application must propagate the parameters from one device to the other. Essentially, this mimics the exchange implemented by CA_MigrateKeys. The low level APIs should not be used under any other circumstances as their use increases the effort and complexity of maintaining backward compatibility.

Session key negotiation is intended to be an atomic operation. To avoid resource leaking, if the session key negotiation is not completed within 10 minutes the HSM cleans up resources associated with the negotiation. If no other CPv4 related calls have been made, CKR_SESSION_NEGOTIATION_EXPIRED is returned if an attempt is made to continue the negotiation after it has expired. If other CPv4 related calls have been made, the HSM might have already cleaned up the resources and CKR_SESSION_NEGOTIATION_NOT_STARTED is returned. Applications that are using the low-level APIs must be able to handle these error scenarios. The resource clean-up is described later.

Once established, a session expires after 1 hour. Any attempt to use an expired session results in CKR_SESSION_ID_EXPIRED. Applications using the low level API must be able to handle this error and are required to re-negotiate a new session.

Expired sessions are cleaned up by the HSM, as the HSM is not required to maintain expired sessions any longer than it needs for its own internal implementation reasons. Therefore, it is expected that if multiple threads/processes are using the same session, and are not synchronizing during expiry and re-negotiation scenarios, an attempt to use an expired session can result in CKR_SESSION_ID_INVALID as the HSM no longer knows about the session ID. Applications using the low level APIs must be able to handle this error scenario. As one session ID can be used/shared for an entire access, care should be taken so that each thread does not end up re-negotiating their own session ID as this would be extremely inefficient for the application and HSM.

CA_MigrationStartSessionNegotiation

This API starts a session key negotiation with a partition on the source or target HSM.

CA_MigrationStartSessionNegotiation(CK_SESSION_HANDLE hSession, 
                                    CK_ULONG          inputLength, 
                                    CK_BYTE_PTR       input, 
                                    CK_ULONG_PTR      step, 
                                    CK_ULONG_PTR      outputLength, 
                                    CK_BYTE_PTR       output); 
I/O Argument Description
In hSession The authenticated session handle.
inputLength

The length of the buffer pointed to by “input”. Using CPv4, this value must be 0, but the APIs and library support passing this value to the HSM. If this value is not zero, a valid memory buffer must be pointed to by “input”.

input

This parameter is not currently used and is defined for future use.

A memory buffer of size “inputLength”. Using CPv4, this value must be NULL, but the APIs and library support passing this value to the HSM. If “inputLength” is not zero, this pointer must point to a valid memory buffer.

Out step

A “step” identifier used by the HSM to identify the step of the protocol being returned by the specific call to this API. The value is used by the HSM to identify the content of the opaque blob referred to by “output”.

In/Out outputLength

Defines the length of the memory buffer pointed to by “output”. This parameter cannot be NULL. If “output” is NULL, this parameter is updated with the size of the memory buffer required.

Out output

A pointer to a memory buffer of size “outputLength”. This pointer can be set to NULL to request the length of the required buffer.

CA_MigrationContinueSessionNegotiation

This is called to continue the negotiation; when it is first called on the second HSM, it technically starts the negotiation there. As the API is called from one HSM to the next, all of the output values are passed to the “other” HSM as input values.

The first call to CA_MigrationContinueSessionNegotiation invokes a session ID for the session being negotiation. All following calls to this API are required to pass in the same session ID.

When the negotiation is complete, status=2 is returned. The content of the output values must be passed in to the other HSM as input to the first call to either CA_Extract or CA_Insert to complete the negotiation on the other HSM.

CA_MigrationContinueSessionNegotiation(CK_SESSION_HANDLE hSession, 
                                       CK_ULONG          inputStep, 
                                       CK_ULONG          inputLength, 
                                       CK_BYTE_PTR       input, 
                                       CK_ULONG          sessionUidInputLen, 
                                       CK_BYTE_PTR       sessionUidInput, 
                                       CK_ULONG_PTR      outputStep, 
                                       CK_ULONG_PTR      outputLength, 
                                       CK_BYTE_PTR       output, 
                                       CK_ULONG_PTR      status, 
                                       CK_ULONG_PTR      sessionUidOutputLen, 
                                       CK_BYTE_PTR       sessionUidOutput); 
I/O Argument Description
In hSession

The authenticated session on the partition on the source or target HSM, depending on which step of the protocol is being implemented.

inputStep

The step identifier used by the HSM to identify the content of the input memory buffer.

inputLength

The length of the buffer pointed to by input. This value cannot be 0.

input

A memory buffer of size inputLength. This value cannot be NULL.

sessionUidInputLen

Defines the length of the memory buffer pointed to by sessionUidInput.

sessionUidInput

The Identifier for the session used to extract/insert key blobs. During a negotiation phase, the first time this API is called, this length+value pair can be NULL and zero. For all following calls to this API, the value returned via the sessionUidOutput and sessionUidOutputLength parameters should be passed in via this length+value pair.

Out outputStep

The step identifier used by the HSM to identify the content of the output.

In/Out outputLength

Defines the length of the memory buffer pointed to by output. This parameter cannot be NULL. If output is NULL, this parameter is updated with the size of the memory buffer required.

Out output

A pointer to a memory buffer of size outputLength. This pointer can be set to NULL to request the length of the required buffer.

status The status of the negotiation. This field is set to either 1 (MORE) or 2 (DONE), which indicates if CA_MigrationContinueSessionNegotiation needs to be called again on the other member.
sessionUidOutputLen

Defines the length of the memory buffer pointed to by sessionUidOutput. This parameter cannot be NULL. If sessionUidOutput is NULL, this parameter is updated with the size of the memory buffer required.

sessionUidOutput

The Identifier for the session used to extract/insert key blobs. If this parameter is not NULL, then this buffer receives the session identifier for the session being negotiated.

This API can return more than one piece of output data. Simplify the application and the API implementation, when querying the required buffer size, by providing a NULL pointer; all possible output fields must be queried at the same time.

CA_MigrationCloseSession

This API terminates a session. When it is called, the session key and all of its context/state is deleted. If the session key does not exist, no error is returned. This is because some implementations might proactively clean up sessions that have expired, so it is expected that by the time this API is called, the session might no longer exist. In this case, CKR_SESSION_ID_INVALID is returned.

CA_MigrationCloseSession(CK_SESSION_HANDLE hSession, 
                         CK_ULONG          sessionUidLen, 
                         CK_BYTE_PTR       sessionUid); 
I/O Argument Description
In hSession The authenticated session handle.
sessionUidLen

The length of the session ID.

sessionUid

The identifier for the session to be closed.

CA_Extract

This API extracts objects or internal CSPs using the specified session id. The API functionality is defined by a mechanism and a mechanism parameter which allows for any functionality to be defined on a per-mechanism basis. This makes it ideal for the CPv4 extract/insert operations and is consistent with the PKCS#11 API. Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_Extract(CK_SESSION_HANDLE hSession, 
           CK_MECHANISM_PTR  pMechanism); 
I/O Argument Description
In hSession The authenticated session handle.
In/Out pMechanism

Specify CKM_CPV4_EXTRACT (0x80000208) for CPv4 extract operations. It takes a parameter, CK_CPV4_EXTRACT_PARAMS (see below).

The parameter CK_CPV4_EXTRACT_PARAMS is structured as follows:

CK_CPV4_EXTRACT_PARAMS {
  CK_ULONG_PTR		sessionIdLength;
  CK_BYTE		sessionId;
  CK_ULONG		inputLength;
  CK_BYTE_PTR		input;
  CK_ULONG		extractionFlags;
  CK_ULONG		numberOfObjects;
  CK_ULONG_PTR		objectType; 
  CK_ULONG_PTR		objectHandle;
  CK_RV_PTR		result;
  CK_ULONG_PTR		keyBlobLength;
  CK_BYTE_PTR_PTR	keyBlob; 
}
I/O Argument Description
In sessionIdLength

The length of the session ID.

sessionId

The identifier for the session to be used to extract the key blob(s).

inputLength

The length of data pointed by “input”.

input

When executing step 4 in the API flow, “input” and “inputLength” must refer to a valid memory location with a non-zero size; specifically the output of the final call to CA_MigrationContinueSessionNegotiation. All other calls to this API should be NULL and 0.

extractionFlags

Flags used to define how errors are handled during extraction. The default value is 0, which is to return on the first error. The following flag is accepted:

>CKF_CONTINUE_ON_ERR (0x01): If specified, the API continues attempting to extract objects if an individual object fails. If the flag is not specified, the API fails after the first failure is encountered.

numberOfObjects

Number of objects to be extracted.

objectType

An array of object types to define the type of objects pointed to by the array of object handles. Possible values are CK_CRYPTOKI_ELEMENT and CK_PARAM_ELEMENT.

objectHandle

An array of object handles, defining the objects to be extracted.

Out result An array of result codes defining the result of each object extraction. This field should be initialized to CKR_CLONE_NOT_ATTEMPTED for all objects. If an error is encountered trying to extract an object, then that error is set in the result field that corresponds to that object. Callers of this API should verify the result field for each object to determine if the object was successfully extracted.
keyBlobLength

An array of length fields that correspond to the array of memory buffers pointed by “keyBlob”. This value and the value pointed to by each array cannot be NULL.

keyBlob

An array of the memory buffers to receive the extracted key blobs. This value cannot be NULL. If all of the array elements are NULL, then the required buffer size is returned in keyBlobLength array. Otherwise all values in the array must be non-NULL.

CA_Insert

This API inserts objects, or internal CPS, using the specified session id. The API functionality is defined by a mechanism and a mechanism parameter which allows for any functionality to be defined on a per-mechanism basis. This makes it ideal for the CPv4 extract/insert operations and is consistent with the PKCS#11 API. Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_Insert(CK_SESSION_HANDLE hSession, 
          CK_MECHANISM_PTR  pMechanism); 
I/O Argument Description
In hSession The authenticated session handle.
In/Out pMechanism

Specify CKM_CPV4_INSERT (0x80000209) for CPv4 insert operations. It takes a parameter, CK_CPV4_INSERT_PARAMS (see below).

The parameter CK_CPV4_INSERT_PARAMS is structured as follows:

CK_CPV4_INSERT_PARAMS {
  CK_ULONG_PTR		sessionIdLength;
  CK_BYTE		sessionId;
  CK_ULONG		insertionFlags;
  CK_ULONG		numberOfObjects;
  CK_ULONG_PTR		storageType;
  CK_ULONG_PTR		objectType;
  CK_ULONG_PTR		keyBlobLength;
  CK_BYTE_PTR_PTR	keyBlob;
  CK_RV_PTR		result;
  CK_ULONG_PTR		objectHandle;
}
I/O Argument Description
In sessionIdLength

The length of the session ID.

sessionId

The identifier for the session to be used to insert the key blob(s).

insertionFlags

Flags used to define how errors are handled during insertion. The default value is 0, which is to return on the first error. The following flag is accepted:

>CKF_CONTINUE_ON_ERR (0x01): If specified, the API continues attempting to insert objects if an individual object fails. If the flag is not specified, the API fails after the first failure is encountered.

numberOfObjects

Number of objects to be inserted

storageType

An array of storage type identifiers used to define how the object should be inserted.

objectType

An array of object types to define the type of objects pointed to by the array of object handles. Possible values are CK_CRYPTOKI_ELEMENT and CK_PARAM_ELEMENT.

keyBlobLength

An array of length fields that correspond to the array of memory buffers pointed by “keyBlobs”. This value and the value pointed to by each array cannot be NULL.

keyBlob

An array of the memory buffers that contain key blob. This value and each array element cannot be NULL.

Out result

An array of result codes defining the result of each object insertion. This field should be initialized to CKR_CLONE_NOT_ATTEMPTED for all objects. If an error is encountered trying to insert an object, then that error is set in the result field that corresponds to that object. Callers of this API should verify the result field for each object to determine if the object was successfully inserted.

objectHandle

An array of object handles, to receive the object handle for the inserted objects.

CPv4 PKCS#11 Error Code Summary

This section provides a summary of all of the error codes introduced by the CPv4 APIs, and their intended meanings.

Return Code Hex Description
CKR_ATTESTATION_EXPIRED   This error is returned when an expired attestation message is encountered.
CKR_CLONE_NOT_ATTEMPTED   If no attempt is made to clone an object, which could happen due to negotiation failure or other errors unrelated to the core CPv4 logic and implementation, this error is returned.
CKR_PROTOCOL_DISABLED   This error is returned when requested protocol (CPv3 or CPv4) is disabled at the partition configuration level.
CKR_SESSION_ID_EXISTS   This error is returned when an attempt is made to negotiate a session (the NegotiateRequest message) using a session UID that already exists in the device.
CKR_SESSION_ID_EXPIRED   This error is returned when an attempt is made to use extract/insert key blobs using a session ID that is expired. This error will rarely occur on Luna HSMs as Luna HSMs perform cleanup of expired sessions on every CPv4-related command.
CKR_SESSION_ID_INVALID   This error is returned when an attempt is made to extract/insert key blobs with a session ID that is not known by the device.
CKR_SESSION_NEGOTIATION_EXPIRED   This error is returned when an attempt is made to continue session negotiation after the session negotiation state has expired.
CKR_SESSION_NEGOTIATION_INVALID   This error is returned when unexpected/invalid messages are encountered during negotiation. This can happen when an attempt is made to continue session negotiation, using a session UID that does not exist. This can also occur when an attempt to extract objects from HSM B is made before an object is inserted.
CKR_SESSION_NEGOTIATION_NO_ALGS   This error is returned when one device cannot find a supported algorithm suite in the provided algorithms suites in the relevant step of the protocol. This can also be returned if an unsupported algorithm suite is found in the NegotiationRequest.
CKR_SESSION_NEGOTIATION_NO_CHAIN_ATT   This error is returned when the required certification chain attestation mechanisms cannot be found during session negotiation.
CKR_SESSION_NEGOTIATION_NO_ENCODING   This error is returned when no commonly supported object encoding can be found during session negotiation.
CKR_SESSION_NEGOTIATION_NO_EPHERMAL_KEY   This error is returned when the provided ephemeral key blob is invalid; invalid type, invalid curve or invalid ECC point.
CKR_SESSION_NEGOTIATION_NO_KDF   This error is returned when no commonly supported KDF can be found during session negotiation.
CKR_SESSION_NEGOTIATION_NO_PSK   This error is returned when no common PSK (pre-shared key) can be found. It is returned when both devices provide PSK IDs and no matching ID can be found, as well as when one-or-both devices provide LEET and no cryptographic match can be found.
CKR_SESSION_NEGOTIATION_NO_ROOTS   This error is returned when a device cannot find a known/supported Root.
CKR_SESSION_NEGOTIATION_NO_SESSION_DURATION   This error is returned when no commonly supported session duration can be found during session negotiation.
CKR_TIME_NOT_INITIALIZED   The source and target HSMs must have their time within 3 seconds of each other, or CPv4 negotiation fails. If your HSMs' hosts are synchronized with a reliable time source, you can use HSM Policy 57: Allow Sync with Host Time to prevent drift.

When processing parameters, at the API level in the client or in the HSM, error codes defined for operations and features of prior releases might also be returned when invalid parameters are detected.

PSK APIs

This section defines the APIs and ICD commands that are defined to support the domain management functionality.

PKCS#11 Extension APIs

This section defines the PKCS#11 Extension APIs.

PWD vs Local and Remote PED

Similar to existing APIs like C_Login, CA_ResetPIN, etc, these APIs can receive a value (the KCV) as a typed string (like a password) or from a PED key.

When providing a PED key-based KCV, the KCV parameters defined below must be set to NULL and 0. If the KCV is being entered from a local PED, that is all that is required. If the KCV is to be entered via a Remote PED, then a Remote PED connection must be setup and a PED ID defined for the connection. Just like the other APIs that may make use of a Remote PED, the APIs defined in this section will pick up and use whichever PED ID is defined. Setting up Remote PED connections and PEDs is covered elsewhere, in the management/administration sections of these docs.

CA_AddKCV

Allows the Partition Security Officer to add an additional Key Cloning Vector (KCV or cloning domain) to the partition. See also Universal Cloning and Luna HSM Cloning API CPv4 Extensions to PKCS#11.

Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_AddKCV(CK_SESSION_HANDLE hSession, 
          CK_ULONG          ulKCVLength, 
          CK_BYTE_PTR       pKCV, 
          CK_ULONG          ulLabelLength, 
          CK_BYTE_PTR       pLabel, 
          CK_BBOOL          bMakePrimary); 
I/O Argument Description
In hSession A session on the partition authenticated by the Partition Security Officer.
ulKCVLength The length of the KCV pointed to by pKCV. If the KCV is to be entered via a Luna PED, the length must be zero.
pKCV A pointer to a byte array that contains the KCV value. If the KCV is to be entered via a Luna PED, this pointer must be set to NULL.
ulLabelLength The length of the label pointed to by pLabel. The label length cannot be 0.
pLabel A pointer to a buffer that contains the label for the domain to be added. The label must be between 1 and 32 bytes in length and is NOT a NULL terminated string. This parameter cannot be NULL.
bMakePrimary Boolean flag to indicate that the new domain should be the primary domain.
Return Code Hex Description
CKR_DOMAIN_LABEL_ALREADY_EXISTS   This error is returned when the label provided for a new domain, or when changing the label of an existing domain, already exists. This includes trying to create a domain with no label when there is already a domain with no label.
CKR_DOMAIN_MANAGEMENT_NOT_ALLOWED   Partition policy 44: Allow Extended Domain Management is disabled, or the domain specified is of a different authentication type than the HSM (specifying a multifactor quorum domain on a password-authenticated HSM or vice-versa).
CKR_DOMAIN_MAX_REACHED   This error is returned when an attempt to add a domain is made, but the limit has already been reached.

CA_ChangeKCVLabel

Allows the Partition Security Officer to change the label of a KCV (cloning domain). The primary use of this API is to add a label to a pre-existing KCV that does not already have a label. It can also be used to change an existing label of a KCV, which may be useful when merging/splitting domains and the same domain label has been used for different KCV values. See also Universal Cloning and Luna HSM Cloning API CPv4 Extensions to PKCS#11.

Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_ChangeKCVLabel(CK_SESSION_HANDLE hSession, 
                  CK_ULONG          ulOldLabelLength, 
                  CK_BYTE_PTR       pOldLabel, 
                  CK_ULONG          ulNewLabelLength, 
                  CK_BYTE_PTR       pNewLabel); 
I/O Argument Description
In hSession A session on the partition authenticated by the Partition Security Officer.
ulOldLabelLength The length of the label pointed to by pOldLabel. If pOldLabel is NULL, then this value must be 0.
pOldLabel A pointer to a buffer that contains the label for the domain to be re-labelled. To add a label to a domain that does not already have one, this value must be NULL.
ulNewLabelLength The length of the label pointed to by pNewLabel. The label length cannot be 0.
pNewLabel

A pointer to a buffer that contains the new label for the domain. The label must be between 1 and 32 bytes in length and is NOT a NULL terminated string. This parameter cannot be NULL.

Return Code Hex Description
CKR_DOMAIN_LABEL_ALREADY_EXISTS   This error is returned when the label provided for a new domain, or when changing the label of an existing domain, already exists. This includes removing a domain’s label when there is already a domain with no label.
CKR_DOMAIN_LABEL_INVALID   The specified domain label does not match a domain that is currently assigned to the partition, or the new label does not meet the length requirement.

CA_DeleteKCV

Allows the Partition Security Officer to delete domains on the partition. See also Universal Cloning and Luna HSM Cloning API CPv4 Extensions to PKCS#11.

Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_DeleteKCV(CK_SESSION_HANDLE hSession, 
             CK_ULONG          ulLabelLength, 
             CK_BYTE_PTR       pLabel); 
I/O Argument Description
In hSession A session on the partition authenticated by the Partition Security Officer.
ulLabelLength The length of the label pointed to by pLabel. If pLabel is NULL, then this parameter must be set to 0.
pLabel A pointer to a buffer that contains the label for the domain to be deleted. If ulLabelLength is 0, then this parameter must be set to NULL.
Return Code Hex Description
CKR_DOMAIN_MANAGEMENT_NOT_ALLOWED   Partition policy 44: Allow Extended Domain Management is disabled, or the domain specified is of a different authentication type than the HSM (specifying a multifactor quorum domain on a password-authenticated HSM or vice-versa).
CKR_DOMAIN_LABEL_INVALID   The specified domain label does not does not match a domain that is currently assigned to the partition.

CA_GetKCVLabels

Allows any logged-in role to retrieve the domain labels. See also Universal Cloning and Luna HSM Cloning API CPv4 Extensions to PKCS#11.

Requires minimum Luna HSM Firmware 7.8.0 and Luna HSM Client 10.5.0.

CA_GetKCVLabels(CK_SLOT_ID   slotID, 
                CK_ULONG_PTR ulNumberOfLabels, 
                CK_ULONG_PTR ulFlags, 
                CK_ULONG_PTR ulLabelLengths, 
                CK_BYTE_PTR  pLabels); 
I/O Argument Description
In slotID

The slot number.

In/Out ulNumberOfLabels

A pointer to receive the number of labels. This parameter cannot be NULL. When requesting the number of labels, this parameter must be set to CK_ULONG value that is set to 0 and it will be populated with the number of labels. If a non-zero value is provided, then it must define the size of the ulLabelLengths and pLabels arrays. If the non-zero value provided is too small, this parameter will be populated with the number of labels.

ulFlags  
ulLabelLengths

A pointer to an array to receive the lengths of each label. When retrieving the number of labels, this parameter is ignored. Otherwise, it must be set to an array of ulNumberOfLabels CK_ULONG values. On output, the array will be populated with the length of each label.

pLabels

A pointer to an array of CK_BYTE_PTR. When retrieving the number of labels, this parameter is ignored. Otherwise, it must be set to an array of length ulNumberOfLabels, where each element of the array is at least 32 bytes in size. On output, each element of the array is populated with the domain label.

Return Code Hex Description
CKR_BUFFER_TOO_SMALL   The non-zero value provided for ulNumberOfLabels is too small.