Skip to content

Instantly share code, notes, and snippets.

@ben221199
Last active January 26, 2026 00:56
Show Gist options
  • Select an option

  • Save ben221199/ac259c071ab742c3369f4e46b94f3567 to your computer and use it in GitHub Desktop.

Select an option

Save ben221199/ac259c071ab742c3369f4e46b94f3567 to your computer and use it in GitHub Desktop.
KMIP PCKS#11 Profile

Parameters

This document cites and describes how PKCS#11 are encoded before transmission over KMIP.

Rules

The rules, as defined in 5.18.1, connotated with extra clarification.

Scalar types

For scalar types, CK_BYTE is represented as a single byte, while CK_ULONG and CK_LONG values are transmitted as 8 bytes, network byte order (big-endian). Other PKCS#11 types are built upon those base types as defined in [PKCS#11]. For example, a CK_DATE is a four-byte year followed by a two-byte month and a two-byte day, each byte representing an ASCII character. Strings are either space padded, or null terminated as defined in [PKCS#11].

Type Transmission
CK_BYTE single byte
CK_ULONG 8 bytes (Big Endian)
CK_LONG 8 bytes (Big Endian)

A CK_DATE holds a ASCII value in the form YYYYMMDD, also 8 bytes (Big Endian).

When it comes to strings:

  • Space padded
  • Null terminated

Structure

If a parameter or element of a structure represents a pointer to a structure, then the elements of that structure are inserted in line, with its input or output elements listed recursively. If a parameter represents a fixed length array, then the elements appear in order. If the length is variable, then the count of the number of elements is provided immediately before the array and removed from its original position in the parameter list or structure. CK_ULONGs that represent a count or length are represented as 4 bytes big-endian values.

Technically, the parameter list of a function should be seen as a struct too, because encoding happens in the same way.

Type What to do? Example
Pointer of Structure Dereference and handle structure elements recursively in the same way as the parameter list. CK_SLOT_INFO_PTR (only used in C_GetSlotInfo)
Fixed array In order as is. Seems almost not used. Think about [32]byte, it will always be size 32. Not yet.
Variable array Length is prepended and removed from its own position in the parameter list of structure. CK_SLOT_ID_PTR (used in C_GetSlotList)

(Also, it seems that "arrays" are mostly pointers; in some cases (strings) an array is really a array: the byte array.)

Note about lengths:

Type Transmission
CK_ULONG 8 bytes (Big Endian)
CK_ULONG (as length) 4 bytes (Big Endian)

Variable length and NULL pointers

PKCS#11 functions that handle variable length data structures use a pattern in which the caller first calls with null pointers and the library then fills in the required length. This enables the caller to allocate sufficient memory for the result and call the function a second time with non-null pointers. An additional byte is inserted before such parameters in requests to indicate whether the values are required, or just the lengths.

So, if theree is a pointer that is used for output, and it accepts a NULL pointer, it is prepended with a boolean byte, even before the prepended length. Then 0x00 = NULL pointer and 0x01 is ALLOCATED pointer.

Templates (TODO)

Templates are represented by a 4-byte big-endian count of attributes followed by the attributes themselves. They may be encoded with or without the values for C_GetAttributeValue which reflects whether it has been called with null pointers or has maximum lengths already determined.

Attributes (TODO)

For each attribute a one-byte value indicator flag that indicates whether a value was defined via the pValue field of the attribute. This is followed by a second one-byte count indicator flag that indicates if a multiple of the count of values was defined via the ulValueLen field of the attribute. If the count indicator is set to false (0), then the value indicator SHALL be set to false (0) also. In the case of a C_GetAttributeValue input request, the value indicator SHALL be set to false (0) unless the value is an array attribute other than CKA_ALLOWED_MECHANISMS.

Attributes 2 (TODO)

Fixed length attributes (attributes of type CK_ULONG, CK_BYTE, CK_BOOL, CK_CHAR and fixed length arrays of those types) are provided in line, with an implicit count of the number of elements which is not present in the encoding. Byte strings are also provided in line but preceded by a 4-byte big-endian count of the number of bytes. CKA_ALLOWED_MECHANISMS attribute values are preceded by a count of the number of elements followed by the values themselves; all other array attributes are stored recursively in the same manner as the encapsulating template.

Mechanisms

Mechanisms are encoded by an 8-byte big-endian mechanism number followed by a one-byte flag that indicates whether the parameter field follows. If the flag is set (to 1), it is followed by a 4-byte big-endian field that stores the length in bytes of any mechanism parameter followed by the parameter itself. If the parameter is a byte string such as an Initialization Vector it is preceded by a second 4-byte big-endian length. The fields in structured parameters such as CK_GCM_PARAMS are simply stored sequentially, with any contained byte strings also preceded by a 4-byte big-endian length.

Field Transmission
Mechanism number 8 bytes (Big Endian)
Parameter field follows 1 byte (Boolean)
<IF 0x01>: <IF 0x01>:
Structure length 4 bytes (Big Endian; parameter and optionally second length field)
Parameter length 4 bytes (Big Endian; only if parameter is byte string)
Parameter Possibly a byte string

Note: Mechanism clearly have a distinct coding format. Structures like CK_GCM_PARAMS follow the normal rules.

Functions

Function Parameters KMIP Input Parameters KMIP Output Parameters
C_EncryptFinal - [0] hSession: CK_SESSION_HANDLE
- [1] pLastEncryptedPart: CK_BYTE_PTR
- [2] pulLastEncryptedPartLen: CK_ULONG_PTR
- [0] uint64(hSession)
- [1] bool(pLastEncryptedPart!==null) (indicator byte)
- [2] uint32(*pulLastEncryptedPartLen) (length)
- [0] uint64(hSession)
- [2^] uint32(*pulLastEncryptedPartLen) (length)
- [1] *pLastEncryptedPart
C_EncryptInit - [0] hSession: CK_SESSION_HANDLE
- [1] pMechanism: CK_MECHANISM_PTR
- [2] hKey: CK_OBJECT_HANDLE
- [0] uint64(hSession)
- [1] *pMechanism (STRUCT: special processing)
- [2] uint64(hKey)
None.
C_EncryptUpdate - [0] hSession: CK_SESSION_HANDLE
- [1] pPart: CK_BYTE_PTR
- [2] ulPartLen: CK_ULONG
- [3] pEncryptedPart: CK_BYTE_PTR
- [4] pulEncryptedPartLen: CK_ULONG_PTR
- [0] uint64(hSession)
- [2^] uint32(ulPartLen) (length)
- [1] *pPart (Length: ulPartLen)
- [3] bool(pEncryptedPart!==null) (indicator byte)
- [4] uint32(*pulEncryptedPartLen) (length)
- [4^] uint32(*pulEncryptedPartLen) (length)
- [3] *pEncryptedPart
C_GetAttributeValue - [0] hSession: CK_SESSION_HANDLE
- [1] hObject: CK_OBJECT_HANDLE
- [2] pTemplate: CK_ATTRIBUTE_PTR
- [3] ulCount: CK_ULONG
- [0] uint64(hSession)
- [1] uint64(hObject)
- [3^] uint32(ulCount) (length)
- [2] pTemplate (STRUCT: special processing)
- [3^] uint32(ulCount) (length)
- [2] pTemplate (STRUCT: special processing)
C_GetInfo - [0] pInfo: CK_INFO_PTR None. - [0] *pInfo (STRUCT: special processing)
C_GetSlotList - [0] tokenPresent: CK_BBOOL
- [1] pSlotList: CK_SLOT_ID_PTR
- [2] pulCount CK_ULONG_PTR
- [0] bool(tokenPresent) (byte)
- [1] bool(pSlotList!==null) (indicator byte)
- [2] uint32(*pulCount) (length)
- [1] bool(pSlotList!==null) (indicator byte)
- [2^] uint32(*pulCount) (length)
- [1] *pSlotList

Modified functions

Function Parameters KMIP Input Parameters KMIP Output Parameters
C_Finalize (*) - pReserved: CK_VOID_PTR None. None.
C_Initialize (*) - pInitArgs: CK_VOID_PTR - 0x01 (PKCS#11 Profile) None.

Non-applicable functions

Function Parameters KMIP Input Parameters KMIP Output Parameters
C_GetFunctionList (*) - ppFunctionList: CK_FUNCTION_LIST_PTR_PTR N/A. STUB!!! N/A. STUB!!!
C_GetInterface (*) - pInterfaceName: CK_UTF8CHAR_PTR
- pVersion: CK_VERSION_PTR
- ppInterface: CK_INTERFACE_PTR_PTR
- flags: CK_FLAGS
N/A. STUB!!! N/A. STUB!!!
C_WaitForSlotEvent (*) - flags: CK_FLAGS
- pSlot: CK_SLOT_ID_PTR
- pReserved CK_VOID_PTR
N/A. NOT USED!!! N/A. NOT USED!!!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment