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.
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 |
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 |
|
| inputLength |
The length of the buffer pointed to by |
|
| input |
A memory buffer of size |
|
| sessionUidInputLen |
Defines the length of the memory buffer pointed to by |
|
| 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 |
| In/Out | outputLength |
Defines the length of the memory buffer pointed to by |
| Out | output |
A pointer to a memory buffer of size |
| 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 |
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 |
| 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 |
| 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 |
|
| 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 |
| Return Code | Hex | Description |
|---|---|---|
| CKR_BUFFER_TOO_SMALL | The non-zero value provided for ulNumberOfLabels is too small. |