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

The top level API CA_MigrateKeys() is defined below. 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.

	CK_RV CA_MigrateKeys(
		CK_SESSION_HANDLE 	sourceSession;		// input
		CK_SESSION_HANDLE 	targetSession;		// input
		CK_ULONG		migrationFlags;	        // input
		CK_ULONG 		numberOfObjects;	// input
		CK_MIGRATION_DATA_PTR 	migrationData;		// input/output
	);


The function parameters have the following meaning:

sourceSession an authenticated session on the source partition.
targetSession an authenticated session on the target partition.
migrationFlags flags used to define the behavior the migration protocol.
numberOfObjects the number of objects to migrate. Implicitly defines the size of the array pointed to by “migrationData”. This parameter cannot be 0.
migrationData an array of CK_MIGRATION_DATA objects whose length is defined by “numberOfObjects”. This parameter cannot be NULL.

Migration Flags:

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.

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.

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


The fields of the CK_OBJECT_MIGRATION_DATA structure have the following meanings:

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

handle of the object to be cloned.

targetHandle

Handle of the object after it has been cloned to the target device.

rv

result of the clone operation for this specific object. This field is initialized to CKR_CLONE_NOT_ATTEMPTED for every object.

In all cases, if any object fails to clone, then the rv field for that object is populated with the specific error code for that failure. If the CKF_CONTINUE_ON_ERR is specified, the API continues to attempt to clone objects, otherwise the API stops attempting to clone objects. If the failure occurs in the context of cloning an individual object, the API 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 for all objects that were not attempted to be cloned, their error code is left at CKR_CLONE_NOT_ATTEMPTED in the CK_OBJECT_MIGRATION_DATA structure.

Callers of this API should verify the rv field for each object to determine if the object was successfully 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 the CA_MigrateKeys API. 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. The input parameter is currently not used and is defined for future-proofing.

CK_RV CA_MigrationStartSessionNegotiation (
  CK_SESSION_HANDLE	sessionHandle;	// input
  CK_ULONG		inputLength;	// input
  CK_BYTE_PTR		input;		// input
  CK_ULONG_PTR		step;		// output
  CK_ULONG_PTR		outputLength;	// intput/output
  CK_BYTE_PTR		output;		// output
)

The function parameters have the following meaning:

sessionHandle

an authenticated session on the partition on HSM B.

inputLength

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

input

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

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”.

outputLength

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

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, however when it is first called on the second HSM, technically it starts the negotiation on the second HSM.

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 CA_MigrationContinueSessionNegotiation are required to pass in the same session ID.

When the negotiation is complete, status=done 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.

CK_RV MigrationContinueSessionNegotiation (
  CK_SESSION_HANDLE	sessionHandle;
  CK_ULONG		inputStep;
  CK_ULONG		inputLength;
  CK_BYTE_PTR		input;
  CK_ULONG_PTR		sessionIdInputLength;	// input
  CK_BYTE		sessionIdInput;	        // input
  CK_ULONG_PTR		outputStep;		// output
  CK_ULONG_PTR		outputLength;		// input/output
  CK_BYTE_PTR		output;			// output
  CK_ULONG		status;			// output
  CK_ULONG_PTR		sessionIdOutputLength;	// output
  CK_BYTE		sessionIdOutput;	// output
)

The function parameters have the following meaning:

sessionHandle

an authenticated session on the partition on HSM A or HSM B 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.

sessionIdInputLength

defines the length of the memory buffer pointed to by “sessionIdInput.

sessionIdInput

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 sessionIdOutput and sessionIdOutputLength parameters should be passed in via this length+value pair.

outputStep

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

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.

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. tmp tmp

status tmp
sessionIdOutputLength

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

sessionIdOutput

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. CKR_SESSION_ID_INVALID is returned.

CK_RV CA_MigrationSessionKeyDelete (
  CK_SESSION_HANDLE	sessionHandle;
  CK_ULONG_PTR		sessionIdLength;
  CK_BYTE		sessionId;
)

The function parameters have the following meaning:

sessionHandle

an authenticated session on the partition on HSM A or HSM B depending on which step of the protocol is being implemented.

sessionIdLength

the length of the session ID.

sessionId

the Identifier for the session to be closed.

CA_Extract

This API extracts objects or internal CSPs using the specified session id.

This is the same API used for SIM3 in the past. 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 re-use for the CPv4 extract/insert operations and is consistent with the PKCS#11 API.

CK_RV CA_Extract (
  CK_SESSION_HANDLE	sessionHandle; 	        // input
  CK_MECHANISM		pMechanism; 	        // input/output
)

Mechanism and parameter structure.

#define CKM_CPV4_EXTRACT			0x80000208
CK_CPV4_EXTRACT_PARAMS {
  CK_ULONG_PTR		sessionIdLength;	// input
  CK_BYTE		sessionId;		// input
  CK_ULONG		inputLength;		// input
  CK_BYTE_PTR		input;			// input
  CK_ULONG		extractionFlags;	// input
  CK_ULONG		numberOfObjects	        // input
  CK_ULONG_PTR		objectType; 		// input
  CK_ULONG_PTR		objectHandle;		// input
  CK_RV_PTR		result;			// output
  CK_ULONG_PTR		keyBlobLength;		// output
  CK_BYTE_PTR_PTR	keyBlob; 		// output
}

The mechanism parameters have the following meanings:

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 flag CKF_CONTINUE_ON_ERR (0x01) can be specified to indicate that the HSM should proceed trying to extract objects if any single object fails.

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.

objectHandles

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

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.

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 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.

If during the first call to CA_Extract, the final step of session key negotiation fails, then a number of possible error codes might be returned, depending on specific implementation details. The following CPv4 specific error codes are expected:

>CKR_SESSION_NEGOTIATION_NO_PSK

>CKR_SESSION_NEGOTIATION_NO_ROOTS

>CKR_SESSION_NEGOTIATION_NO_ALGS

>CKR_SESSION_NEGOTIATION_EXPIRED

>CKR_SESSION_NEGOTIATION_NOT_STARTED

If a specified session ID does not exist, CKR_SESSION_ID_INVALID is returned.

If the specified session ID exists but is expired, CKR_SESSION_ID_EXPIRED is returned.

The “extractionFlags” field, reuses the migration flag CKF_CONTINUE_ON_ERR (0x01), which if it is specified, causes the API to continue attempting to extract objects if an individual object fails. If the flag is not specified, the API fails after the first failure is encountered.

If an error is encountered trying to extract an object, then that error is set in the result field that corresponds to that object. If the CKF_CONTINUE_ON_ERR is specified, then the API continues attempting to extract objects. Otherwise, the API stops and returns CKR_OK. If an error is encountered in the core logic of CA_Extract, than the error code for that event is returned by the API and, for all objects that were not attempted to be cloned, they have their error code set to CKR_CLONE_NOT_ATTEMPTED in the ”result” array.

Callers of this API should verify the rv field for each object to determine if the object was successfully extracted.

CA_Insert

This API inserts objects, or internal CPS, using the specified session id.

This is the same API that is used for SIM3. The API functionality is defined by a mechanism parameter that allows for “any” functionality to be defined.

CK_RV CA_Insert (
  CK_SESSION_HANDLE	sessionHandle; 	        // input
  CK_MECHANISM		pMechanism; 		// input/output
)

Define Mech and param structure.

#define CKM_CPV4_INSERT				0x80000209
CK_CPV4_INSERT_PARAMS {
  CK_ULONG_PTR		sessionIdLength;	// input
  CK_BYTE		sessionId;	        // input
  CK_ULONG		insertionFlags;	        // input
  CK_ULONG		numberOfObjects; 	// input
  CK_ULONG_PTR		storageType;		// input
  CK_ULONG_PTR		objectType; 		// input
  CK_ULONG_PTR		keyBlobLength;		// input
  CK_BYTE_PTR_PTR	keyBlob; 		// input
  CK_RV_PTR		result;			// output
  CK_ULONG_PTR		objectHandle;		// output
}

The mechanism parameters have the following meanings:

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 extraction. The default value is 0, which is to return on the first error. The flag CKF_CONTINUE_ON_ERR (0x01) can be specified to indicate that the HSM should proceed trying to extract objects if any single object fails.

numberOfObjects

number of objects to be extracted

storageType

an array of storage type identifiers used to define how the inserted 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.

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.

objectHandle

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

If during the first call to CA_Insert, the final step of session key negotiation fails, then a number of possible error codes might be returned depending on specific implementation details. The following CPV4 specific error codes are expected:

>CKR_SESSION_NEGOTIATION_NO_PSK

>CKR_SESSION_NEGOTIATION_NO_ROOTS

>CKR_SESSION_NEGOTIATION_NO_ALGS

>CKR_SESSION_NEGOTIATION_EXPIRED

>CKR_SESSION_NEGOTIATION_NOT_STARTED

The “insertionFlags” field, reuses the migration flag CKF_CONTINUE_ON_ERR (0x01), which if it is 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.

If an error is encountered trying to insert an object, then that error is set in the result field that corresponds to that object. If the CKF_CONTINUE_ON_ERR is specified, then the API continues attempting to insert objects, otherwise the API stops and returns CKR_OK. If an error is encountered in the core logic of CA_Insert, then the error code for that event is returned by the API and, for all objects that were not attempted to be cloned, their error code is set to CKR_CLONE_NOT_ATTEMPTED in the ”result” array.

Callers of this API should verify the rv field for each object to determine if the object was successfully inserted.

New 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.

>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_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_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_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_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_PROTOCOL_DISABLED

This error is returned when requested protocol (CPv3 or CPv4) is disabled at the partition configuration level.

>CKR_SESSION_NEGOTIATION_NO_SESSION_DURATION

This error is returned when no commonly supported session duration can be found during session negotiation.

>CKR_SESSION_NEGOTIATION_NO_KDF

This error is returned when no commonly supported KDF can 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_CHAIN_ATT

This error is returned when the required certification chain attestation mechanisms cannot 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_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.

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.

Co-existence with Existing PKCS#11 APIs

The pre-existing cloning protocols (CPv1 and CPv3) have two sets of APIs; the low level API and a top level API.

Top Level: CA_ClonePrivateKey
 

CA_CloneObject

Low Level:

CA_CloneAsSourceInit

 

CA_CloneAsTargetInit

 

CA_CloneAsSource

 

CA_CloneAsTarget

In the pre-CPv4 client library, all calls to the top level APIs end up in a block of logic that determines which key migration method is supported by both devices (CPv1, CPv3, SKS), and uses the correct low level APIs to execute the key transfer.

CPv4 adheres to this model. The top level API for CPv4 also calls in to the same logic that determines which key migration method is supported by both devices (CPv1, CPv3, SKS, CPv4), and uses the correct low level APIs to execute the key transfer.

The pre-CPv4 low level APIs for cloning include logic to remap the calls to use SKS, in order to increase compatibility with old applications. The CPv4 low level APIs do not include any remapping as they are new APIs and new applications are encouraged to use the CPv4 APIs correctly, and strongly encouraged to use only the top level CPv4 API.

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

The CA_AddKCV API can be used by the partition’s security officer to add additional domains to the partition. If the “Allow Extended Domain Management” policy is disabled, then any attempt to use this API to add more than one domain returns CKR_DOMAIN_MANAGMENT_NOT_ALLOWED. If the provided domain label already exists, this API returns CKR_DOMAIN_LABEL_ALREADY_EXISTS.

CK_RV CA_AddKCV (
  CK_SESSION_HANDLE 	session;		// input
  CK_ULONG		ulKCVLength; 		// input
  CK_BYTE_PTR		pKCV; 			// input
  CK_ULONG		ulLabelLength; 	        // input
  CK_BYTE_PTR		pLabel;			// input
  CK_BBOOL		bMakePrimary		// input
);

The function parameters have the following meaning:

session

a session on the partition authenticated by the partition’s security officer

ulKCVLength

the length of the KCV pointed to by pKCV. If the KCV is to be entered via a PED, then the length must be zero.

pKCV

a pointer to a byte array the contains the KCV value. If the KCV is to be entered via a 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

flag to indicate that the new domain should be the primary domain.

CA_ChangeKCVLabel

The CA_ChangeKCVLabel API can be used by the partition’s security officer to change the label of a KCV. 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. If the provided domain label already exists, this API returns CKR_DOMAIN_LABEL_ALREADY_EXISTS. If the specified domain label does not exist, this API returns CKR_DOMAIN_LABEL_INVALID. To change a domain that does not have a label, the “old” label parameters must be set to 0 and NULL.

CK_RV CA_ChangeKCVLabel (
  CK_SESSION_HANDLE 	session;		// input
  CK_ULONG		ulOldLabelLength; 	// input
  CK_BYTE_PTR		pOldLabel;		// input
  CK_ULONG		ulNewLabelLength; 	// input
  CK_BYTE_PTR		pNewLabel		// input
);

The function parameters have the following meaning:

session

a session on the partition authenticated by the partition’s security officer

ulOldLabelLength

the length of the label pointed to by pOldLabel. If pOldLabel is NULL, then this value must be 0. Otherwise this value must be set to the length of the label pointed to by pOldLabel.

pOldLabel

a pointer to a buffer that contains the label for the domain to be re-labelled. If ulOldLabelLength is 0, then this value must be NULL. Otherwise this value must point to a buffer containing a label that is between 1 and 32-bytes in length.

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.

CA_DeleteKCV

The CA_DeleteKCV API can be used by the partition’s security officer (PO) to delete domains on the partition. If the “Allow Extended Domain Management” policy is disabled, then any attempt to use this API returns CKR_DOMAIN_MANAGMENT_NOT_ALLOWED. If the specified domain label does not exist, this API returns CKR_DOMAIN_LABEL_INVALID. To delete a domain that does not have a label, the label parameters must be set to 0 and NULL.

CK_RV CA_DeleteKCV (
  CK_SESSION_HANDLE 	session;		// input
  CK_ULONG		ulLabelLength; 	// input
  CK_BYTE_PTR		pLabel			// input
);

The function parameters have the following meaning:

session

a session on the partition authenticated by the partition’s security officer

ulLabelLength

the length of the label pointed to by pLabel. If pLabel is NULL, then this parameter must be set to 0. Otherwise this parameter must be set to the length of the label pointed to by pLabel.

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. Otherwise this parameter must point to a buffer that containers the label.

CA_GetKCVLabels

The CA_GetKCVLabels API can be used by any role to retrieve the domain labels.

CK_RV CA_GetKCVLabels (
  CK_SESSION_HANDLE 	session;		// input
  CK_ULONG_PTR		ulNumberOfLabels; 	// input/output
  CK_ULONG_PTR		ulLabelLengths; 	// input/output
  CK_BYTE_PTR*		pLabels			// input/output
);

The function parameters have the following meaning:

session

a session on the partition authenticated by the partition’s security officer

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 provides is too small, then CKR_BUFFER_TOO_SMALL is returned and this parameter will be populated with the number of labels.

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.

Error Codes

Here are the error codes introduced by the domain management APIs.

>CKR_DOMAIN_MANAGEMENT_NOT_ALLOWED

This error is returned when extended domain management features are attempted and the “Allow Extended Domain Management” partition policy is disabled. Specifically, this error is returned when adding more than one domain, deleting a domain or attempting to assign a domain that is of a different authentication type than the HSM (i.e. specifying a PED domain on a pwd-auth HSM).

>CKR_DOMAIN_LABEL_INVALID

This error is returned when the provided domain label does not match a domain that is currently assigned to the partition.

>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 as well as removing a domain’s label when there is already a domain with no label.

>CKR_DOMAIN_MAX_REACHED

This error is returned when an attempt to add a domain is made, but the limit has already been reached. The current limit is 3.

>CKR_DOMAIN_NO_PRIMARY

This error is returned when the HSM is unable to locate the primary domain of a partition. This error is unexpected and should never happen in a production environment.

>CKR_DOMAIN_EXTRA_PRIMARY

This error is returned when the HSM finds more than one primary domain in a partition. This error is unexpected and should never happen in a production environment.

When processing parameters, at the API level in the client or in the HSM, the error codes that have previously been available for Luna might be returned when invalid parameters are detected (DATA_INVALID, and/or INVALID_POINTER when validating input parameters, USER_NOT_AUTHORIZED, etc.).