![]() | Cryptographic Token Interface Standard |
PKCS#11 |
Return Value | Meaning |
CKR_ATTRIBUTE_READ_ONLY | attribute cannot be modified |
CKR_ATTRIBUTE_SENSITIVE | attribute is sensitive and cannot be revealed |
CKR_ATTRIBUTE_TYPE_INVALID | attribute type is invalid |
CKR_ATTRIBUTE_VALUE_INVALID | attribute value is invalid |
CKR_CANCEL | function should be canceled |
CKR_DATA_INVALID | data is invalid |
CKR_DATA_LEN_RANGE | data length is out of range |
CKR_DEVICE_ERROR | device error |
CKR_DEVICE_MEMORY | not enough memory on device |
CKR_DEVICE_REMOVED | device has been removed |
CKR_ENCRYPTED_DATA_INVALID | encrypted data is invalid |
CKR_ENCRYPTED_DATA_LEN_RANGE | encrypted data length is out of range |
CKR_FLAGS_INVALID | flags are invalid |
CKR_FUNCTION_CANCELED | function has been canceled |
CKR_FUNCTION_NOT_PARALLEL | no function is executing in parallel |
CKR_FUNCTION_PARALLEL | function is executing in parallel |
CKR_HOST_MEMORY | not enough memory on host |
CKR_KEY_HANDLE_INVALID | key handle is invalid |
CKR_KEY_SENSITIVE | key is sensitive and cannot be revealed |
CKR_KEY_SIZE_RANGE | key size is out of range |
CKR_KEY_TYPE_INCONSISTENT | key type is inconsistent with mechanism |
CKR_MECHANISM_INVALID | mechanism is invalid |
CKR_MECHANISM_PARAM_INVALID | mechanism parameter is invalid |
CKR_OBJECT_CLASS_INCONSISTENT | object class is inconsistent with mechanism |
CKR_OBJECT_CLASS_INVALID | object class is invalid |
CKR_OBJECT_HANDLE_INVALID | object handle is invalid |
CKR_OK | function has completed successfully |
CKR_OPERATION_ACTIVE | another operation is already active |
CKR_OPERATION_NOT_INITIALIZED | operation has not been initialized |
CKR_PIN_INCORRECT | PIN is incorrect |
CKR_PIN_INVALID | new PIN contains invalid characters |
CKR_PIN_LEN_RANGE | new PIN length is out of range (assuming token specifies range) |
CKR_SESSION_CLOSED | session has been closed |
CKR_SESSION_COUNT | session limits have been reached |
CKR_SESSION_EXCLUSIVE_EXISTS | an exclusive session already exists |
CKR_SESSION_HANDLE_INVALID | session handle is invalid |
CKR_SESSION_PARALLEL_NOT_SUPPORTED | parallel execution is not supported |
CKR_SESSION_READ_ONLY | session is read-only |
CKR_SIGNATURE_INVALID | signature is invalid |
CKR_SIGNATURE_LEN_RANGE | signature length is out of range |
CKR_SLOT_ID_INVALID | slot ID is invalid |
CKR_TEMPLATE_INCOMPLETE | template is incomplete |
CKR_TEMPLATE_INCONSISTENT | template is inconsistent |
CKR_TOKEN_NOT_PRESENT | slot does not contain a token |
CKR_TOKEN_NOT_RECOGNIZED | the token was not recognized |
CKR_TOKEN_WRITE_PROTECTED | token is write-protected |
CKR_UNWRAPPING_KEY_HANDLE_INVALID | unwrapping key handle is invalid |
CKR_UNWRAPPING_KEY_SIZE_RANGE | unwrapping key size is out of range |
CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT | unwrapping key type is inconsistent with mechanism |
CKR_USER_ALREADY_LOGGED_IN | a user is already logged in |
CKR_USER_NOT_LOGGED_IN | a user is not logged in |
CKR_USER_PIN_NOT_INITIALIZED | the user's PIN has not been intialized |
CKR_USER_TYPE_INVALID | user type is invalid |
CKR_WRAPPED_KEY_INVALID | wrapped key is invalid |
CKR_WRAPPED_KEY_LEN_RANGE | wrapped key length is out of range |
CKR_WRAPPING_KEY_HANDLE_INVALID | wrapping key handle is invalid |
CKR_WRAPPING_KEY_SIZE_RANGE | wrapping key size is out of range |
CKR_WRAPPING_KEY_TYPE_INCONSISTENT | wrapping key type is inconsistent with mechanism |
General purpose
Cryptoki provides the following general purpose functions.
CK_RV C_Initialize( CK_VOID_PTR pReserved );
C_Initialize initializes the Cryptoki library. C_Initialize should be the first call made by an application. This function is implementation defined; Cryptoki may, for example, initialize its internal memory buffers, or any other resources it may require. The pReserved parameter is reserved for future versions. For this version, it should be set to NULL_PTR.
CK_RV rv; rv = C_Initialize(NULL_PTR);
C_GetInfo returns general information about Cryptoki.
pInfo | points to the location that receives the information. |
CK_INFO info; CK_RV rv; rv = C_GetInfo(&info); if( rv == CKR_OK ){ if( info.version.major == 1 ){ . . . } }
Slot and token management
Cryptoki provides the following functions for slot and token management.
CK_RV C_GetSlotList( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_USHORT_PTR pusCount );
C_GetSlotList obtains a list of slots in the system.
tokenPresent | indicates whether the list includes only those slots with a token present (TRUE), or all slots (FALSE); pSlotList points to the location that receives the list (array) of slot IDs; and pusCount points to the location that receives the number of slots. |
CK_SLOT_ID_PTR pSlotList; CK_USHORT usCount; CK_RV rv; rv = C_GetSlotList(FALSE, NULL_PTR, &usCount); if( (rv == CKR_OK) && (usCount > 0) ){ pSlotList = (CK_SLOT_ID_PTR) malloc(usCount * sizeof(CK_SLOT_ID)); rv = C_GetSlotList(FALSE, pSlotList, &usCount); if( rv == CKR_OK ){ . . . } free(pSlotList); }
CK_RV C_GetSlotInfo( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo );
C_GetSlotInfo obtains information about a particular slot in the system.
slotID | is the ID of the slot; |
pInfo | points to the location that receives the slot information. |
CK_SLOT_ID_PTR pSlotList; CK_USHORT usCount; CK_SLOT_INFO info; CK_RV rv; rv = C_GetSlotList(FALSE, NULL_PTR, &usCount); if( (rv == CKR_OK) && (usCount > 0) ){ pSlotList = (CK_SLOT_ID_PTR) malloc(usCount * sizeof(CK_SLOT_ID)); rv = C_GetSlotList(FALSE, pSlotList, &usCount); if( rv == CKR_OK ){ rv = C_GetSlotInfo(pSlotList[0], &info); . . . } free(pSlotList); }
CK_RV C_GetTokenInfo( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo );
C_GetTokenInfo obtains information about a particular token in the system.
slotID | is the ID of the token's slot; |
pInfo | points to the location that receives the token information. |
CK_SLOT_ID_PTR pSlotList; CK_USHORT usCount; CK_TOKEN_INFO info; CK_RV rv; rv = C_GetSlotList(TRUE, NULL_PTR, &usCount); if( (rv == CKR_OK) && (usCount > 0) ){ pSlotList = (CK_SLOT_ID_PTR) malloc(usCount * sizeof(CK_SLOT_ID)); rv = C_GetSlotList(TRUE, pSlotList, &usCount); if( rv == CKR_OK ){ rv = C_GetTokenInfo(pSlotList[0], &info); . . . } free(pSlotList); }
CK_RV C_GetMechanismList( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_USHORT_PTR pusCount );
C_GetMechanismList obtains a list of mechanism types supported by a token.
slotID | is the ID of the token's slot; pMechanismList points to the location that receives the list (array) of mechanism types; pusCount points to the location that receives the number of mechanisms. |
CK_SLOT_ID slotID; CK_MECHANISM_TYPE_PTR pMechanismList; CK_USHORT usCount; CK_RV rv; rv = C_GetMechanismList(slotID, NULL_PTR, &usCount); if( (rv == CKR_OK) && (usCount > 0) ){ pMechanismList = (CK_MECHANISM_TYPE_PTR) malloc(usCount * sizeof(CK_MECHANISM_TYPE)); rv = C_GetMechanismList(slotID, pMechanismList, &usCount); if( rv == CKR_OK ){ . . . } free(pMechanismList); }
CK_RV C_GetMechanismInfo( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo );
C_GetMechanismInfo obtains information about a particular mechanism possibly supported by a token.
slotID | is the ID of the token's slot; |
type | is the type of mechanism; |
pInfo | points to the location that receives the mechanism information. |
CK_SLOT_ID_PTR pSlotList; CK_USHORT usCount; CK_MECHANISM_INFO info; CK_RV rv; rv = C_GetSlotList(TRUE, NULL_PTR, &usCount); if( (rv == CKR_OK) && (usCount > 0) ){ pSlotList = (CK_SLOT_ID_PTR) malloc(usCount * sizeof(CK_SLOT_ID)); rv = C_GetSlotList(TRUE, pSlotList, &usCount); if( rv == CKR_OK ){ rv = C_GetMechanismInfo(pSlotList[0], CKM_MD2, &info); . . . } free(pSlotList); }
CK_RV C_InitToken( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_USHORT usPinLen, CK_CHAR_PTR pLabel );
C_InitToken initializes a token.
slotID | is the ID of the token's slot; |
pPin | points to the SO's initial PIN; usPinLen is the length in bytes of the PIN; |
pLabel | points to the 32-byte label of the token (must be padded with the blank characters). |
CK_SLOT_ID slotID; CK_CHAR pin[] = {"MyPIN"}; CK_CHAR label[32]; CK_RV rv; memset(label, ' ', sizeof(label)); memcpy(label, "My first token", sizeof("My first token")); rv = C_InitToken(slotID, pin, sizeof(pin), label); if( rv == CKR_OK ){ . . . }
CK_RV C_InitPIN( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_USHORT usPinLen );
C_InitPIN initializes the normal user's PIN.
hSession | is the session's handle; |
pPin | points to the normal user's PIN; and usPinLen is the length in bytes of the PIN. |
CK_SESSION_HANDLE hSession; CK_CHAR newPin[]= {"NewPIN"}; CK_RV rv; rv = C_InitPIN(hSession, newPin, sizeof(newPin)); if( rv == CKR_OK ){ . . . }
CK_RV C_SetPIN( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_USHORT usOldLen, CK_CHAR_PTR pNewPin, CK_USHORT usNewLen );
C_SetPIN modifies the PIN of user that is currently logged in.
hSession | is the session's handle; |
pOldPin | points to the old PIN; usOldLen is the length of the old PIN; pNewPin points to the new PIN; usNewLen is the length of the new PIN. |
CK_SESSION_HANDLE hSession; CK_CHAR oldPin[] = {"OldPIN"}; CK_CHAR newPin[] = {"NewPIN"}; CK_RV rv; rv = C_SetPIN(hSession, oldPin, sizeof(oldPin), newPin, sizeof(newPin)); if( rv == CKR_OK ){ . . . }
Session management
Cryptoki provides the following functions for session management.
A typical application would call C_OpenSession after selecting a token and C_CloseSession after completing all operations with the token. Only in special cases, such as when other applications connected to a token have failed, would an application call C_CloseAllSessions.
An application may have concurrent sessions with more than one token. It is also possible that a token may have concurrent sessions with more than one application.
CK_RV C_OpenSession( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_RV (*Notify)(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession );
C_OpenSession opens a session between an application and a token.
slotID | is the slot's ID; |
flags | indicates the type of session; |
pApplication | is an application-defined pointer to be passed to the notification callback; Notify is the address of the notification callback function; phSession points to the location that receives the handle for the new session. |
In a parallel session, cryptographic functions may return control to the application before completing (the return value CKR_FUNCTION_PARALLEL indicates this condition). The application may call C_GetFunctionStatus to obtain updated status of the function, which will be CKR_FUNCTION_PARALLEL until the function completes, and CKR_OK or another return value indicating an error when the function completes. Alternatively, the application can wait until Cryptoki sends notification that the function has completed through the Notify callback. The application may also call C_CancelFunction to cancel the function.
If an application calls another function (cryptographic or otherwise) before one that is executing in parallel completes, Cryptoki will wait until the one that is executing completes. Thus an application can run only one function at any given time in a given session. (To achieve parallel execution of multiple functions, the application should open additional sessions.)
Cryptographic functions running in serial with the application may surrender control through the Notify callback, so that the application may perform other operations or cancel the function.
Non-cryptographic functions always run in serial with the application, and do not surrender control.
There may be a limit on the number of concurrent sessions with the token, which may depend on whether the session is "read-only" or "read/write." There can only be one exclusive session with a token.
If the token is in "write-protected" (as indicated in the CK_TOKEN_INFO structure), then the session also must be "read-only."
The Notify callback function is used by Cryptoki to notify the application of certain events. If the application does not support the callback, it should pass NULL_PTR as the address. The Notify callback function is described in Section .
CK_SESSION_HANDLE hSession; CK_SLOT_ID slotID; CK_RV rv; CK_BYTE application; CK_RV MyNotify(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication); slotID = 1; rv = C_OpenSession(slotID, CKF_EXCLUSIVE_SESSION, &application, MyNotify, &hSession); if( rv == CKR_OK ){ . . . }
CK_RV C_CloseSession( CK_SESSION_HANDLE hSession );
C_CloseSession closes a session between an application and a token.
hSession | is the session's handle. |
Depending on the token, when the last session with the token is closed, the token may be "ejected" from its reader, assuming this capability exists.
CK_SESSION_HANDLE hSession; CK_SLOT_ID slotID; CK_RV rv; CK_BYTE application; CK_RV MyNotify(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication); slotID = 1; rv = C_OpenSession(slotID, CKF_EXCLUSIVE_SESSION, &application, MyNotify, &hSession); if( rv == CKR_OK ){ . . . C_CloseSession(hSession); }
CK_RV C_CloseAllSessions( CK_SLOT_ID slotID );
C_CloseAllSessions closes all sessions with a token.
slotID | specifies the token's slot. |
Depending on the token, the token may be "ejected" from its reader, assuming this capability exists.
When an application is disconnected from a token in this manner, it receives a CKR_SESSION_CLOSED error on its next call to Cryptoki.
CK_SLOT_ID slotID; CK_RV rv; slotID = 1; rv = C_CloseAllSessions(slotID);
CK_RV C_GetSessionInfo( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo );
C_GetSessionInfo obtains information about the session.
hSession | is the session's handle; |
pInfo | points to the location that receives the session information. |
CK_SESSION_HANDLE hSession; CK_SESSION_INFO info; CK_RV rv; rv = C_GetSessionInfo(hSession, &info); if( rv == CKR_OK ){ . . . }
CK_RV C_Login( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_USHORT usPinLen );
C_Login logs a user into a token.
hSession | is the session's handle; |
userType | is the user type; |
pPin | points to the user's PIN; and usPinLen is the length of the PIN. Depending on the user type and the current session type, the state will become one of the following: "R/W SO Functions", "R/O SO Functions", "R/W User Functions", or "R/O User Functions". |
CK_SESSION_HANDLE hSession; CK_CHAR userPIN[] = {"MyPIN"}; CK_RV rv; rv = C_Login(hSession, CKU_USER, userPIN, sizeof(userPIN)); if( rv == CKR_OK ){ . . . }
CK_RV C_Logout( CK_SESSION_HANDLE hSession );
C_Logout logs a user out from a token.
hSession | is the session's handle. Depending on the current user type and the current session type, the state will become either "R/W Public Session" or "R/O Public Session". |
CK_SESSION_HANDLE hSession; CK_CHAR userPIN[] = {"MyPIN"}; CK_RV rv; rv = C_Login(hSession, CKU_USER, userPIN, sizeof(userPIN)); if( rv == CKR_OK ){ . . . C_Logout(hSession); }
Object management
Cryptoki provides the following functions for managing objects. Additional functions for managing key objects are described in Section ."
CK_RV C_CreateObject( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount, CK_OBJECT_HANDLE_PTR phObject );
C_CreateObject creates a new object.
hSession | is the session's handle; |
pTemplate | points to the object's template; usCount is the number of attributes in the template; |
phObject | points to the location that receives the new object's handle. |
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hData, hCertificate, hKey; CK_OBJECT_CLASS dataClass = CKO_DATA, certificateClass = CKO_CERTIFICATE, keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_CHAR application[] = {"My Application"}; CK_BYTE dataValue[] = {...}; CK_BYTE subject[] = {...}; CK_BYTE id[] = {...}; CK_BYTE certificateValue[] = {...}; CK_BYTE modulus[] = {...}; CK_BYTE exponent[] = {...}; CK_BYTE true = TRUE; CK_ATTRIBUTE dataTemplate[] = { {CKA_CLASS, &dataClass, sizeof(dataClass)}, {CKA_TOKEN, &true, 1}, {CKA_APPLICATION, application, sizeof(application)}, {CKA_VALUE, dataValue, sizeof(dataValue)} }; CK_ATTRIBUTE certificateTemplate[] = { {CKA_CLASS, &certificateClass, sizeof(certificateClass)}, {CKA_TOKEN, &true, 1}, {CKA_SUBJECT, subject, sizeof(subject)}, {CKA_ID, id, sizeof(id)}, {CKA_VALUE, certificateValue, sizeof(certificateValue)} }; CK_ATTRIBUTE keyTemplate[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_WRAP, &true, 1}, {CKA_MODULUS, modulus, sizeof(modulus)}, {CKA_PUBLIC_EXPONENT, exponent, sizeof(exponent)} }; CK_RV rv; /* Create a data object */ rv = C_CreateObject(hSession, &dataTemplate, 4, &hData); if( rv == CKR_OK ){ . . . } /* Create a certificate object */ rv = C_CreateObject(hSession, &certificateTemplate, 5, &hCertificate); if( rv == CKR_OK ){ . . . } /* Create a RSA private key object */ rv = C_CreateObject(hSession, &keyTemplate, 5, &hKey); if( rv == CKR_OK ){ . . . }
CK_RV C_CopyObject( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount, CK_OBJECT_HANDLE_PTR phNewObject );
C_CopyObject copies an object, creating a new object for the copy.
hSession | is the session's handle; |
hObject | is the object's handle; |
pTemplate | points to the template for the new object; usCount is the number of attributes in the template; |
phNewObject | points to the location that receives the handle for the copy of the object. |
Only session objects can be created during a read-only session. Only public objects can be created when no user is logged in.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_OBJECT_HANDLE hNewKey; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_DES; CK_BYTE id[] = {...}; CK_BYTE keyValue[] = {...}; CK_BYTE false = FALSE; CK_BYTE true = TRUE; CK_ATTRIBUTE keyTemplate[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_TOKEN, &false, 1}, {CKA_ID, id, sizeof(id)}, {CKA_VALUE, keyValue, sizeof(keyValue)} }; CK_ATTRIBUTE copyTemplate[] = { {CKA_TOKEN, &true, 1} }; CK_RV rv; /* Create a DES secret key session object */ rv = C_CreateObject(hSession, &keyTemplate, 5, &hKey); if( rv == CKR_OK ){ /* Create a copy on the token */ rv = C_CopyObject(hSession, hKey, ©Template, 1, &hNewKey); . . . }
CK_RV C_DestroyObject( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject );
C_DestroyObject destroys an object.
hSession | is the session's handle; |
hObject | is the object's handle. |
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; CK_OBJECT_CLASS dataClass = CKO_DATA; CK_CHAR application[] = {"My Application"}; CK_BYTE value[] = {...}; CK_BYTE true = TRUE; CK_ATTRIBUTE template[] = { {CKA_CLASS, &dataClass, sizeof(dataClass)}, {CKA_TOKEN, &true, 1}, {CKA_APPLICATION, application, sizeof(application)}, {CKA_VALUE, value, sizeof(value)} }; CK_RV rv; rv = C_CreateObject(hSession, &template, 4, &hObject); if( rv == CKR_OK ){ . . . C_DestroyObject(hSession, hObject); }
CK_RV C_GetObjectSize( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_USHORT_PTR pusSize );
C_GetObjectSize gets the size of an object in bytes.
hSession | is the session's handle; |
hObject | is the object's handle; pusSize points to the location that receives the size in bytes of the object. |
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; CK_OBJECT_CLASS dataClass = CKO_DATA; CK_CHAR application[] = {"My Application"}; CK_BYTE dataValue[] = {...}; CK_BYTE value[] = {...}; CK_BYTE true = TRUE; CK_ATTRIBUTE template[] = { {CKA_CLASS, &dataClass, sizeof(dataClass)}, {CKA_TOKEN, &true, 1}, {CKA_APPLICATION, application, sizeof(application)}, {CKA_VALUE, value, sizeof(value)} }; CK_USHORT usSize; CK_RV rv; rv = C_CreateObject(hSession, &template, 4, &hObject); if( rv == CKR_OK ){ rv = C_GetObjectSize(hSession, hObject, &usSize); . . . C_DestroyObject(hSession, hObject); }
CK_RV C_GetAttributeValue( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount );
C_GetAttributeValue obtains the value of one or more object attributes.
hSession | is the session's handle; |
hObject | is the object's handle; |
pTemplate | points to a template that specifies which attribute values are to be obtained, and receives the attribute values; usCount is the number of attributes in the template. |
If the object is marked "sensitive", it may not be possible to obtain the value of the attribute.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; CK_BYTE_PTR pModulus, pExponent; CK_ATTRIBUTE template[] = { {CKA_MODULUS, NULL_PTR, 0}, {CKA_PUBLIC_EXPONENT, NULL_PTR, 0} }; CK_RV rv; rv = C_GetAttributeValue(hSession, hObject, &template, 2); if( rv == CKR_OK ){ pModulus = (CK_BYTE_PTR) malloc(template[0].usValueLen); template[0].pValue = pModulus; pExponent = (CK_BYTE_PTR) malloc(template[1].usValueLen); template[1].pValue = pExponent; rv = C_GetAttributeValue(hSession, hObject, &template, 2); if( rv == CKR_OK ){ . . . } free(pModulus); free(pExponent); }
CK_RV C_SetAttributeValue( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount );
C_SetAttributeValue modifies the value of one or more attributes of an object.
hSession | is the session's handle; |
hObject | is the object's handle; |
pTemplate | points to a template that specifies which attribute values are to be modified and their new values; usCount is the number of attributes in the template. |
Not all attributes can be modified; see Section for more details.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; CK_CHAR label[] = {"New label"}; CK_ATTRIBUTE template[] = { CKA_LABEL, label, sizeof(label) }; CK_RV rv; rv = C_SetAttributeValue(hSession, hObject, &template, 1); if( rv == CKR_OK ){ . . . }
CK_RV C_FindObjectsInit( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount );
C_FindObjectsInit initializes a search for token and session objects that match a template.
hSession | is the session's handle; |
pTemplate | points to a search template that specifies the attribute values to match; usCount is the number of attributes in the search template. The matching criterion is an exact byte-for-byte match with all attributes in the template. To find all objects, set usCount is 0. |
CK_RV C_FindObjects( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,CK_USHORT usMaxObjectCount, CK_USHORT_PTR pusObjectCount );
C_FindObjects continues a search for token and session objects that match a template, obtaining additional object handles.
hSession | is the session's handle; |
phObject | points to the location that receives the list (array) of additional object handles; usMaxObjectCount is the maximum number of object handles to be returned; pusObjectCount points to the location that receives the actual number of object handles returned. If there are no more objects matching the template, then the location that pusObjectCount points to receives 0. |
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; CK_USHORT usObjectCount; CK_RV rv; rv = C_FindObjectsInit(hSession, NULL_PTR, 0); if( rv == CKR_OK ){ while (1) { rv = C_FindObjects(hSession, &hObject, 1, &usObjectCount); if (rv != CKR_OK || usObjectCount == 0) break; . . . } }
Encryption and decryption
Cryptoki provides the following functions for encrypting and decrypting data. All these functions run in parallel with the application if the session was opened with the CKF_SERIAL_SESSION flag set to FALSE and the token supports parallel execution.
CK_RV C_EncryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_EncryptInit initializes an encryption operation.
hSession | is the session's handle; |
pMechanism | points to the encryption mechanism; |
hKey | is the handle of the encryption key. |
After calling C_EncryptInit, the application may call C_Encrypt to encrypt data in a single part, or C_EncryptUpdate one or more times followed by C_EncryptFinal to encrypt data in multiple parts. The encryption operation is "active" until the application calls C_Encrypt or C_EncryptFinal. To process additional data (in single or multiple parts), the application must call C_EncryptInit again. At most one cryptographic operation may be active at a given time in a given session. C_EncryptInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-2, Encryption Mechanisms
Mechanism | Key type |
PKCS #1 RSA1 | RSA public |
X.509 (raw) RSA1 | RSA public |
RC2 (ECB and CBC mode) | RC2 |
RC4 | RC4 |
DES (ECB and CBC mode) | DES |
triple-DES (ECB and CBC mode) | double or triple-length DES |
1 Single-part only.
Section provides more details on the mechanisms.
CK_RV C_Encrypt( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_USHORT usDataLen, CK_BYTE_PTR pEncryptedData, CK_USHORT_PTR pusEncryptedDataLen );
C_Encrypt encrypts single-part data.
hSession | is the session's handle; |
pData | points to the data; usDataLen is the length in bytes of the data; |
pEncryptedData | points to the location that receives the encrypted data; pusEncryptedData points to the location that receives the length in bytes of the encrypted data. |
For constraints on data length, refer to the description of the encryption mechanism.
C_Encrypt is equivalent to a sequence of C_EncryptUpdate and C_EncryptFinal.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DES_ECB, NULL_PTR, 0 }; CK_BYTE encryptedData[8]; CK_USHORT usEncryptedDataLen; CK_BYTE data[8]; CK_RV rv; memset(data, 'A', sizeof(data)); rv = C_EncryptInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_Encrypt(hSession, data, sizeof(data), encryptedData, &usEncryptedDataLen); }
CK_RV C_EncryptUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_USHORT usPartLen, CK_BYTE_PTR pEncryptedPart, CK_USHORT_PTR pusEncryptedPartLen );
C_EncryptUpdate continues a multiple-part encryption operation, processing another data part.
hSession | is the session's handle; |
pPart | points to the data part; usPartLen is the length of the data part; |
pEncryptedPart | points to the location that receives the encrypted data part; pusEncryptedPart points to the location that receives the length of the encrypted data part. |
For constraints on data length, refer to the description of the encryption mechanism.
CK_RV C_EncryptFinal( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_USHORT_PTR pusEncryptedPartLen );
C_EncryptFinal finishes a multiple-part encryption operation.
hSession | is the session's handle; |
pLastEncryptedPart | points to the location that receives the last encrypted data part, if any; pusLastEncryptedPartLen points to the location that receives the length of the last encrypted data part. |
For constraints on data length, refer to the description of the encryption mechanism.
#define BUF_SZ 512 CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_BYTE iv[8]; CK_MECHANISM mechanism = { CKM_DES_CBC, iv, sizeof(iv) }; CK_BYTE encryptedData[BUF_SZ]; CK_USHORT usEncryptedDataLen; CK_BYTE data[2*BUF_SZ]; CK_RV rv; memset(iv, 0, sizeof(iv)); memset(data, 'A', 2*BUF_SZ); rv = C_EncryptInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ C_EncryptUpdate(hSession, &data[0], BUF_SZ, encryptedData, &usEncryptedDataLen); . . . C_EncryptUpdate(hSession, &data[BUF_SZ], BUF_SZ, encryptedData, &usEncryptedDataLen); . . . C_EncryptFinal(hSession, encryptedData, &usEncryptedDataLen); }
CK_RV C_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_DecryptInit initializes a decryption operation.
hSession | is the session's handle; |
pMechanism | points to the decryption mechanism; |
hKey | is the handle of the decryption key. |
After calling C_DecryptInit, the application may call C_Decrypt to encrypt data in a single part, or C_DecryptUpdate one or more times followed by C_DecryptFinal to encrypt data in multiple parts. The decryption operation is "active" until the application calls C_Decrypt or C_DecryptFinal. To process additional data (in single or multiple parts), the application must call C_DecryptInit again. At most one cryptographic operation may be active at a given time in a given session. C_DecryptInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-3, Decryption Mechanisms
Mechanism | Key type |
PKCS #1 RSA1 | RSA public |
X.509 (raw) RSA1 | RSA public |
RC2 (ECB and CBC mode) | RC2 |
RC4 | RC4 |
DES (ECB and CBC mode) | DES |
triple-DES (ECB and CBC mode) | double or triple-length DES |
1 Single-part only.
Section 10 gives more details on the mechanisms.
CK_RV C_Decrypt( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_USHORT usEncryptedDataLen, CK_BYTE_PTR pData, CK_USHORT_PTR pusDataLen );
C_Decrypt decrypts encrypted data in a single part.
hSession | is the session's handle; |
pEncryptedData | points to the encrypted data; usEncryptedDataLen is the length of the encrypted data; |
pData | points to the location that receives the recovered data; pusDataLen points to the location that receives the length of the recovered data. |
For constraints on data length, refer to the description of the decryption mechanism.
C_Decrypt is equivalent to a sequence of C_DecryptUpdate and C_DecryptFinal.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DES_ECB, NULL_PTR, 0 }; CK_BYTE encryptedData[8]; CK_BYTE data[8]; CK_USHORT usDataLen; CK_RV rv; memset(encryptedData, 'A', sizeof(encryptedData)); rv = C_DecryptInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_Decrypt(hSession, encryptedData, sizeof(encryptedData), data, &usDataLen); }
CK_RV C_DecryptUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_USHORT usEncryptedPartLen, CK_BYTE_PTR pPart, CK_USHORT_PTR pusPartLen );
C_DecryptUpdate continues a multiple-part decryption operation, processing another encrypted data part.
hSession | is the session's handle; |
pEncryptedPart | points to the encrypted data part; usEncryptedPartLen is the length of the encrypted data part; |
pPart | points to the location that receives the recovered data part; pusPartLen points to the location that receives the length of the recovered data part. |
For constraints on data length, refer to the description of the decryption mechanism.
CK_RV C_DecryptFinal( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_USHORT_PTR usLastPartLen );
C_DecryptFinal finishes a multiple-part decryption operation.
hSession | is the session's handle; |
pLastPart | points to the location that receives the last recovered data part, if any; pusLastPartLen points to the location that receives the length of the last recovered data part. |
For constraints on data length, refer to the description of the decryption mechanism.
#define BUF_SZ 512 CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_BYTE iv[8]; CK_MECHANISM mechanism = { CKM_DES_CBC, iv, sizeof(iv) }; CK_BYTE encryptedData[2*BUF_SZ]; CK_BYTE data[BUF_SZ]; CK_USHORT usDataLen; CK_RV rv; memset(iv, 0, sizeof(iv)); memset(encryptedData, 'A', 2*BUF_SZ); rv = C_DecryptInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ C_DecryptUpdate(hSession, &encryptedData[0], BUF_SZ, data, &usDataLen); . . . C_DecryptUpdate(hSession, &encryptedData[BUF_SZ], BUF_SZ, data, &usDataLen); . . . C_DecryptFinal(hSession, data, &usDataLen); }
Message digesting
Cryptoki provides the following functions for digesting data. All these functions run in parallel with the application if the session was opened with the CKF_SERIAL_SESSION flag set to FALSE and the token supports parallel execution.
CK_RV C_DigestInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism );
C_DigestInit initializes a message-digesting operation.
hSession | is the session's handle; |
pMechanism | points to the digesting mechanism. |
The following mechanisms are supported in this version:
Table 9-4, Digesting Mechanisms
Mechanism |
MD2 |
MD5 |
SHA-1 |
Section 10 gives more details on the mechanisms.
CK_RV C_Digest( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_USHORT usDataLen, CK_BYTE_PTR pDigest, CK_USHORT_PTR pusDigestLen );
C_Digest digests data in a single part.
hSession | is the session's handle, pData points to the data; usDataLen is the length of the data; |
pDigest | points to the location that receives the message digest; pusDigestLen points to the location that receives the length of the message digest. |
For constraints on data length, refer to the description of the message-digesting mechanism.
C_Digest is equivalent to a sequence of C_DigestUpdate and C_DigestFinal.
CK_SESSION_HANDLE hSession; CK_MECHANISM mechanism = { CKM_MD2, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_BYTE digest[16]; CK_USHORT usDigestLen; CK_RV rv; rv = C_DigestInit(hSession, &mechanism); if( rv == CKR_OK ){ rv = C_Digest(hSession, data, sizeof(data), digest, &usDigestLen); }
CK_RV C_DigestUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_USHORT usPartLen );
C_DigestUpdate continues a multiple-part message-digesting operation, processing another data part.
hSession | is the session's handle, pPart points to the data part; usPartLen is the length of the data part. |
For constraints on data length, refer to the description of the message-digesting mechanism.
CK_RV C_DigestFinal( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_USHORT_PTR pusDigestLen );
C_DigestFinal finishes a multiple-part message-digesting operation, returning the message digest.
hSession | is the session's handle; |
pDigest | points to the location that receives the message digest; pusDigestLen points to the location that receives the length of the message digest. |
For constraints on data length, refer to the description of the message-digesting mechanism.
CK_SESSION_HANDLE hSession; CK_MECHANISM mechanism = { CKM_MD2, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_BYTE digest[16]; CK_USHORT usDigestLen; CK_RV rv; rv = C_DigestInit(hSession, &mechanism); if( rv == CKR_OK ){ rv = C_DigestUpdate(hSession, data, sizeof(data)); . . . rv = C_DigestFinal(hSession, digest, &usDigestLen); }
Signature and verification
Cryptoki provides the following functions for signing data and verifying signatures. (For the purposes of Cryptoki, these operations also encompass data authentication codes.) All these functions run in parallel with the application if the session was opened with the CKF_SERIAL_SESSION flag set to FALSE and the token supports parallel execution.
CK_RV C_SignInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_SignInit initializes a signature operation, where the signature is an appendix to the data.
hSession | is the session's handle; |
pMechanism | points to the signature mechanism; |
hKey | is the handle of the signature key. |
After calling C_SignInit, the application may call C_Sign to sign in a single part, or C_SignUpdate one or more times followed by C_SignFinal to sign data in multiple parts. The signature operation is "active" until the application calls C_Sign or C_SignFinal. To process additional data (in single or multiple parts), the application must call C_SignInit again. At most one cryptographic operation may be active at a given time in a given session. C_SignInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-5, Signature Mechanisms
Mechanism | Key type |
PKCS #1 RSA1 | RSA private |
ISO/IEC 9796 RSA1 | RSA private |
X.509 (raw) RSA1 | RSA private |
DSA1 | DSA private |
RC2-MAC | RC2 |
DES-MAC | DES |
triple-DES-MAC | double-length or triple-length DES |
1 Single-part only.
Section 10 gives more details on the mechanisms.
CK_RV C_Sign( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_USHORT usDataLen, CK_BYTE_PTR pSignature, CK_USHORT_PTR pusSignatureLen );
C_Sign signs data in a single part, where the signature is an appendix to the data.
hSession | is the session's handle; |
pData | points to the data; usDataLen is the length of the data; |
pSignature | points to the location that receives the signature; pusSignatureLen points to the location that receives the length of the signature. |
For constraints on data length, refer to the description of the signature mechanism.
C_Sign is equivalent to a sequence of C_SignUpdate and C_SignFinal.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 }; CK_BYTE data[20] = {...}; CK_BYTE signature[40]; CK_USHORT usSignatureLen; CK_RV rv; rv = C_SignInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_Sign(hSession, data, sizeof(data), signature, &usSignatureLen); }
CK_RV C_SignUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_USHORT usPartLen );
C_SignUpdate continues a multiple-part signature operation, processing another data part.
hSession | is the session's handle, pPart points to the data part; usPartLen is the length of the data part. |
For constraints on data length, refer to the description of the signature mechanism.
CK_RV C_SignFinal( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_USHORT_PTR pusSignatureLen );
C_SignFinal finishes a multiple-part signature operation, returning the signature.
hSession | is the session's handle; |
pSignature | points to the location that receives the signature; pusSignatureLen points to the location that receives the length of the signature. |
For constraints on data length, refer to the description of the signature mechanism.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DES_MAC, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_BYTE mac[4]; CK_USHORT usMacLen; CK_RV rv; rv = C_SignInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_SignUpdate(hSession, data, sizeof(data)); . . . rv = C_SignFinal(hSession, mac, &usMacLen); }
CK_RV C_SignRecoverInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_SignRecoverInit initializes a signature operation, where the data can be recovered from the signature.
hSession | is the session's handle; |
pMechanism | points to the structure that specifies the signature mechanism; |
hKey | is the handle of the signature key. |
After calling C_SignRecoverInit, the application may call C_SignRecover to sign in a single part. The signature operation is "active" until the application calls C_SignRecover. At most one cryptographic operation may be active at a given time in a given session. C_SignRecoverInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-6, Signature With Recovery Mechanisms
Mechanism | Key type |
PKCS #1 RSA | |
ISO/IEC 9796 RSA | |
X.509 (raw) RSA |
Section 10 gives more details on the mechanisms.
CK_RV C_SignRecover( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_USHORT usDataLen, CK_BYTE_PTR pSignature, CK_USHORT_PTR pusSignatureLen );
C_SignRecover signs data in a single operation, where the data can be recovered from the signature.
hSession | is the session's handle; |
pData | points to the data; usDataLen is the length of the data; |
pSignature | points to the location that receives the signature; pusSignatureLen points to the location that receives the length of the signature. |
For constraints on data length, refer to the description of the signature mechanism.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_RSA_9796, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_BYTE signature[128]; CK_USHORT usSignatureLen; CK_RV rv; rv = C_SignRecoverInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_SignRecover(hSession, data, sizeof(data), signature, &usSignatureLen); }
CK_RV C_VerifyInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_VerifyInit initializes a verification operation, where the signature is an appendix to the data.
hSession | is the session's handle; |
pMechanism | points to the structure that specifies the verification mechanism; |
hKey | is the handle of the verification key. |
After calling C_VerifyInit, the application may call C_Verify to verify a signature on data in a single part, or C_VerifyUpdate one or more times followed by C_VerifyFinal to verify a signature on data in multiple parts. The verification operation is "active" until the application calls C_Verify or C_VerifyFinal. To process additional data (in single or multiple parts), the application must call C_VerifyInit again. At most one cryptographic operation may be active at a given time in a given session. C_VerifyInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-7, Verification Mechanisms
Mechanism | Key type |
PKCS #1 RSA1 | RSA public |
ISO/IEC 9796 RSA1 | RSA public |
X.509 (raw) RSA1 | RSA public |
DSA1 | DSA public |
RC2-MAC | RC2 |
DES-MAC | DES |
triple-DES-MAC | double-length or triple-length DES |
1 Single-part only.
Section 10 gives more details on the mechanisms.
CK_RV C_Verify( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_USHORT usDataLen, CK_BYTE_PTR pSignature, CK_USHORT usSignatureLen );
C_Verify verifies a signature in a single-part operation, where the signature is an appendix to the data.
hSession | is the session's handle; |
pData | points to the data; usDataLen is the length of the data; |
pSignature | points to the signature; usSignatureLen is the length of the signature. |
For constraints on data length, refer to the description of the verification mechanism.
C_Verify is equivalent to a sequence of C_VerifyUpdate and C_VerifyFinal.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 }; CK_BYTE data[20] = {...}; CK_BYTE signature[40]; CK_RV rv; rv = C_VerifyInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_Verify(hSession, data, sizeof(data), signature, sizeof(signature)); }
CK_RV C_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_USHORT usPartLen );
C_VerifyUpdate continues a multiple-part verification operation, processing another data part.
hSession | is the session's handle, pPart points to the data part; usPartLen is the length of the data part. |
For constraints on data length, refer to the description of the verification mechanism.
CK_RV C_VerifyFinal( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_USHORT usSignatureLen );
C_VerifyFinal finishes a multiple-part verification operation, checking the signature.
hSession | is the session's handle; |
pSignature | points to the signature; usSignatureLen is the length of the signature. |
For constraints on data length, refer to the description of the verification mechanism.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DES_MAC, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_BYTE mac[4]; CK_RV rv; rv = C_VerifyInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_VerifyUpdate(hSession, data, sizeof(data)); . . . rv = C_VerifyFinal(hSession, mac, sizeof(mac)); }
CK_RV C_VerifyRecoverInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey );
C_VerifyRecoverInit initializes a signature verification operation, where the data is recovered from the signature.
hSession | is the session's handle; |
pMechanism | points to the structure that specifies the verification mechanism; |
hKey | is the handle of the verification key. |
After calling C_VerifyRecoverInit, the application may call C_VerifyRecover to verify a signature on data in a single part. The verification operation is "active" until the application calls C_VerifyRecover. At most one cryptographic operation may be active at a given time in a given session. C_VerifyRecoverInit cannot initialize a new operation if another is already active.
The following mechanisms are supported in this version:
Table 9-8, Verification With Recovery Mechanisms
Mechanism | Key type |
PKCS #1 RSA | RSA public |
ISO/IEC 9796 RSA | RSA public |
X.509 (raw) RSA | RSA public |
Section 10 gives more details on the mechanisms.
CK_RV C_VerifyRecover( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_USHORT usSignatureLen, CK_BYTE_PTR pData, CK_USHORT_PTR pusDataLen );
C_VerifyRecover verifies a signature in a single-part operation, where the data is recovered from the signature.
hSession | is the session's handle; |
pSignature | points to the signature; usSignatureLen is the length of the signature; |
pData | points to the location that receives the recovered data; pusDataLen points to the location that receives the length of the recovered data. |
For constraints on data length, refer to the description of the verification mechanism.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_RSA_9796, NULL_PTR, 0 }; CK_BYTE data[] = {...}; CK_USHORT usDataLen; CK_BYTE signature[128]; CK_RV rv; rv = C_VerifyRecoverInit(hSession, &mechanism, hKey); if( rv == CKR_OK ){ rv = C_VerifyRecover(hSession, signature, sizeof(signature), data, &usDataLen); }
Key management
Cryptoki provides the following functions for key management. All these functions run in parallel with the application if the session was opened with the CKF_SERIAL_SESSION flag set to FALSE and the token supports parallel execution.
CK_RV C_GenerateKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usCount, CK_OBJECT_HANDLE_PTR phKey );
C_GenerateKey generates a secret key, creating a new key object.
hSession | is the session's handle; |
pMechanism | points to the key generation mechanism; |
pTemplate | points to the template for the new key; usCount is the number of attributes in the template; |
phKey | points to the location that receives the handle of the new key. |
Table 9-9, Key Generation Mechanisms
Mechanism | Key type |
RC2 key generation | RC2 |
RC4 key generation | RC4 |
DES key generation | DES1 |
double-length DES key generation | double-length DES1 |
triple-length DES key generation | triple-length DES1 |
1 No known "weak" or "semi-weak" DES keys are generated (see FIPS PUB 74).
Section 10 provides more details on the mechanisms and on which attributes the template must specify.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hKey; CK_MECHANISM mechanism = { CKM_DES_KEY_GEN, NULL_PTR, 0 }; CK_RV rv; rv = C_GenerateKey(hSession, &mechanism, NULL_PTR, 0, &hKey); if( rv == CKR_OK ){ . . . }
CK_RV C_GenerateKeyPair( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_USHORT usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_USHORT usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey );
C_GenerateKeyPair generates a public-key/private-key pair, creating new key objects. On input, hSession is the session's handle;
pMechanism | points to the key generation mechanism; |
pPublicKeyTemplate | points to the template for the public key; usPublicKeyAttributeCount is the number of attributes in the public-key template; |
pPrivateKeyTemplate | points to the template for the private key; usPrivateKeyAttributeCount is the number of attributes in the private-key template; |
phPublicKey | points to the location that receives the handle of the new public key; |
phPrivateKey | points to the location that receives the handle of the new private key. |
Table 9-10, Key Pair Generation Mechanisms
Mechanism | Key types |
PKCS #1 RSA key pair generation | RSA public and private |
DSA key pair generation | DSA public and private |
PKCS #3 Diffie-Hellman key pair generation | DH public and private |
Section 10 provides more details on the mechanisms and on which attributes the template must specify.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hPublicKey, hPrivateKey; CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_USHORT modulusBits = 768; CK_BYTE publicExponent[] = { 3 }; CK_BYTE subject[] = {...}; CK_BYTE id[] = {123}; CK_BBOOL true = TRUE; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_ENCRYPT, &true, 1}, {CKA_VERIFY, &true, 1}, {CKA_WRAP, &true, 1}, {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)}, {CKA_PUBLIC_EXPONENT, publicExponent, sizeof (publicExponent)} }; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_TOKEN, &true, 1}, {CKA_PRIVATE, &true, 1}, {CKA_SUBJECT, subject, sizeof(subject)}, {CKA_ID, id, sizeof(id)}, {CKA_SENSITIVE, &true, 1}, {CKA_DECRYPT, &true, 1}, {CKA_SIGN, &true, 1}, {CKA_UNWRAP, &true, 1} }; CK_RV rv; rv = C_GenerateKeyPair(hSession, &mechanism, publicKeyTemplate, 5, privateKeyTemplate, 8, &hPublicKey, &hPrivateKey); if( rv == CKR_OK ){ . . . }
CK_RV C_WrapKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_USHORT_PTR pusWrappedKeyLen );
C_WrapKey wraps (i.e., encrypts) a key.
hSession | is the session's handle; |
pMechanism | points to the wrapping mechanism; |
hWrappingKey | is the handle of the wrapping key; hKey is the handle of the key to be wrapped; |
pWrappedKey | points to the location that receives the wrapped key; and pusWrappedKeyLen points to the location that receives the length of the wrapped key. |
The following mechanisms are supported in this version:
Table 9-11, Wrapping Mechanisms
Mechanism | Wrapping key type | Type of key to be wrapped |
PKCS #1 RSA | RSA public | RC2, RC4, DES, double or triple-length DES |
X.509 (raw) RSA | RSA public | RC2, RC4, DES, double or triple-length DES |
RC2 (ECB mode) | RC2 | RC2, RC4, DES, double or triple-length DES |
DES (ECB mode) | DES | RC2, RC4, DES |
triple-DES (ECB mode) | double or triple-length DES | RC2, RC4, DES, double or triple-length DES |
Section 10 provides more details on the mechanisms and on which attributes the template must specify.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hWrappingKey, hKey; CK_MECHANISM mechanism = { CKM_DES3_ECB, NULL_PTR, 0 }; CK_BYTE wrappedKey[8]; CK_USHORT usWrappedKeyLen; CK_RV rv; rv = C_WrapKey(hSession, &mechanism, hWrappingKey, hKey, wrappedKey, &usWrappedKeyLen); if( rv == CKR_OK ){ . . . }
CK_RV C_UnwrapKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_USHORT usWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usAttributeCount, CK_OBJECT_HANDLE_PTR phKey );
C_UnwrapKey unwraps (i.e. decrypts) a wrapped key, creating a new key object.
hSession | is the session's handle; |
pMechanism | points to the unwrapping mechanism; |
hUnwrappingKey | is the handle of the unwrapping key; pWrappedKey points to the wrapped key; usWrappedKeyLen is the length of the wrapped key; |
pTemplate | points to the template for the new key; usAttributeCount is the number of attributes in the template; |
phKey | points to the location that receives the handle of the recovered key. |
The following mechanisms are supported in this version:
Table 9-12, Unwrapping Mechanisms
Mechanism | Unwrapping key type | Recovered key type |
PKCS #1 RSA | RSA private | RC2, RC4, DES, double or triple-length DES |
X.509 (raw) RSA | RSA private | RC2, RC4, DES, double or triple-length DES |
RC2 (ECB mode) | RC2 | RC2, RC4, DES, double or triple-length DES |
DES (ECB mode) | DES | RC2, RC4, DES |
triple-DES (ECB mode) | double or triple-length DES | RC2, RC4, DES, double or triple-length DES |
Section 10 provides more details on the mechanisms and on which attributes the template must specify.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hUnwrappingKey, hKey; CK_MECHANISM mechanism = { CKM_DES3_ECB, NULL_PTR, 0 }; CK_BYTE wrappedKey[8] = {...}; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_DES; CK_BBOOL true = TRUE; CK_ATTRIBUTE template[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_ENCRYPT, &true, 1}, {CKA_DECRYPT, &true, 1} }; CK_RV rv; rv = C_UnwrapKey(hSession, &mechanism, hUnwrappingKey, wrappedKey, sizeof(wrappedKey), template, 4, &hKey); if( rv == CKR_OK ){ . . . }
CK_RV C_DeriveKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_USHORT usAttributeCount, CK_OBJECT_HANDLE_PTR phKey );
C_DeriveKey derives a key from a base key, creating a new key object.
hSession | is the session's handle; |
pMechanism | points to a structure that specifies the key derivation mechanism; |
hBaseKey | is the handle of the base key; |
pTemplate | points to the template for the new key; usAttributeCount is the number of attributes in the template; |
phKey | points to the location that receives the handle of the derived key. |
Table 9-13, Key Derivation Mechanisms
Mechanism | Base key type | Derived key type |
Diffie-Hellman key derivation | DH private | RC2, RC4, DES, double or triple-length DES, or generic |
Section 10 provides more details on the mechanisms and on which attributes the template must specify.
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hPublicKey, hPrivateKey, hKey; CK_MECHANISM keyPairMechanism = { CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_BYTE prime[] = {...}; CK_BYTE base[] = {...}; CK_BYTE publicValue[128]; CK_BYTE otherPublicValue[128]; CK_MECHANISM mechanism = { CKM_DH_PKCS_DERIVE, otherPublicValue, sizeof(otherPublicValue) }; CK_ATTRIBUTE pTemplate[] = { CKA_VALUE, &publicValue, sizeof(publicValue)} }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_DES; CK_BBOOL true = TRUE; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_PRIME, prime, sizeof(prime)}, {CKA_BASE, base, sizeof(base)} }; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_DERIVE, &true, 1} }; CK_ATTRIBUTE template[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_ENCRYPT, &true, 1}, {CKA_DECRYPT, &true, 1} }; CK_RV rv; rv = C_GenerateKeyPair(hSession, &keyPairMechanism, publicKeyTemplate, 2, privateKeyTemplate, 1, &hPublicKey, &hPrivateKey); if( rv == CKR_OK ){ rv = C_GetAttributeValue(hSession, hPublicKey, &pTemplate, 1); if( rv == CKR_OK ){ . /* exchange public values */ . rv = C_DeriveKey(hSession, &mechanism, hPrivateKey, template, 4, &hKey); if( rv == CKR_OK ){ . . . } } }
Random number generation
Cryptoki provides the following functions for generating random numbers. All these functions run in parallel with the application if the session was opened with the CKF_SERIAL_SESSION flag set to FALSE and the token supports parallel execution.
CK_RV C_SeedRandom( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_USHORT usSeedLen );
C_SeedRandom mixes additional seed material into the token's random number generator.
hSession | is the session's handle; |
pSeed | points to the seed material; and usSeedLen is the length in bytes of the seed material. |
CK_SESSION_HANDLE hSession; CK_BYTE seed[] = {...}; CK_RV rv; rv = C_SeedRandom(hSession, seed, sizeof(seed)); if( rv == CKR_OK ){ . . . }
CK_RV C_GenerateRandom( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_USHORT usRandomLen );
C_GenerateRandom generates random data.
hSession | is the session's handle; |
pRandomData | points to the location that receives the random data; and usRandomLen is the length in bytes of the random data to be generated. |
CK_SESSION_HANDLE hSession; CK_BYTE randomData[] = {...}; CK_RV rv; rv = C_GenerateRandom(hSession, randomData, sizeof(randomData)); if( rv == CKR_OK ){ . . . }
Parallel function management
Cryptoki provides the following functions for managing parallel execution of cryptographic functions.
CK_RV C_GetFunctionStatus( CK_SESSION_HANDLE hSession );
C_GetFunctionStatus obtains an updated status of a function running in parallel with an application.
hSession | is the session's handle. |
CK_RV C_CancelFunction( CK_SESSION_HANDLE hSession );
C_CancelFunction cancels a function running in parallel with an application.
hSession | is the session's handle. |
CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hPublicKey, hPrivateKey; CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_USHORT modulusBits = 768; CK_BYTE publicExponent[] = {...}; CK_BYTE subject[] = {...}; CK_BYTE id[] = {123}; CK_BBOOL true = TRUE; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_ENCRYPT, &true, 1}, {CKA_VERIFY, &true, 1}, {CKA_WRAP, &true, 1}, {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)}, {CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)} }; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_TOKEN, &true, 1}, {CKA_PRIVATE, &true, 1}, {CKA_SUBJECT, subject, sizeof(subject)}, {CKA_ID, id, sizeof(id)}, {CKA_SENSITIVE, &true, 1}, {CKA_DECRYPT, &true, 1}, {CKA_SIGN, &true, 1}, {CKA_UNWRAP, &true, 1} }; CK_RV rv; rv = C_GenerateKeyPair(hSession, &mechanism, publicKeyTemplate, 5, privateKeyTemplate, 8, &hPublicKey, &hPrivateKey); while ( rv == CKR_FUNCTION_PARALLEL ) { /* Check if user want to cancel function */ if( kbhit() ){ if( getch() == 27 ){ /* If user hit ESCape key */ C_CancelFunction(hSession); break; } } /* Perform other tasks or delay */ . . . rv = C_GetFunctionStatus(hSession); }
Callback function
Cryptoki uses the following callback function to notify the application of certain events.
CK_RV Notify( CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication );
Notify is an application callback that processes events. hSession is the session's handle; event is the event; and pApplication is an application-defined value (the same as passed to C_OpenSession).
When event is CKN_SURRENDER, the callback may return CKR_CANCEL to cancel the operation that is currently active. If the callback returns CKR_OK, Cryptoki continues the operation. For other events, the callback should return CKR_OK.