diff options
Diffstat (limited to 'snmplib/pkcs.c')
-rw-r--r-- | snmplib/pkcs.c | 777 |
1 files changed, 777 insertions, 0 deletions
diff --git a/snmplib/pkcs.c b/snmplib/pkcs.c new file mode 100644 index 0000000..ee4ed92 --- /dev/null +++ b/snmplib/pkcs.c @@ -0,0 +1,777 @@ +/* + * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms specified in the COPYING file + * distributed with the Net-SNMP package. + */ + +/* + * pkcs.c + */ + +#include <net-snmp/net-snmp-config.h> +#ifdef NETSNMP_USE_PKCS11 +#include <net-snmp/types.h> +#include <net-snmp/output_api.h> +#include <net-snmp/config_api.h> +#include <net-snmp/library/snmp_api.h> +#include <net-snmp/library/tools.h> +#include <net-snmp/library/keytools.h> +#include <net-snmp/library/scapi.h> +#include <net-snmp/library/callback.h> +#include <security/cryptoki.h> + +typedef struct netsnmp_pkcs_slot_session_s { + CK_SLOT_ID sid; + CK_SESSION_HANDLE hdl; +} netsnmp_pkcs_slot_session; + +typedef struct netsnmp_pkcs_slot_info_s { + int count; + netsnmp_pkcs_slot_session *pSession; +} netsnmp_pkcs_slot_info; + +static CK_RV get_session_handle(CK_MECHANISM_TYPE, CK_FLAGS,\ + CK_SESSION_HANDLE_PTR); +static CK_RV get_slot_session_handle(netsnmp_pkcs_slot_session *,\ + CK_SESSION_HANDLE_PTR); +static char *pkcserr_string(CK_RV); +static int free_slots(int, int, void *, void *); + +static netsnmp_pkcs_slot_info *pSlot = NULL; + +/* + * initialize the Cryptoki library. + */ +int +pkcs_init(void) +{ + CK_RV rv; + CK_ULONG slotcount; + CK_SLOT_ID_PTR pSlotList = NULL; + netsnmp_pkcs_slot_session *tmp; + int i, rval = SNMPERR_SUCCESS; + /* Initialize pkcs */ + if ((rv = C_Initialize(NULL)) != CKR_OK) { + DEBUGMSGTL(("pkcs_init", "C_Initialize failed: %s", + pkcserr_string(rv))); + return SNMPERR_SC_NOT_CONFIGURED; + } + + /* Get slot count */ + rv = C_GetSlotList(1, NULL_PTR, &slotcount); + if (rv != CKR_OK || slotcount == 0) { + DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", + pkcserr_string(rv))); + QUITFUN(SNMPERR_GENERR, pkcs_init_quit); + } + + /* Found at least one slot, allocate memory for slot list */ + pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID)); + pSlot = malloc(sizeof (netsnmp_pkcs_slot_info)); + pSlot->pSession = malloc(slotcount * sizeof (netsnmp_pkcs_slot_session)); + + if (pSlotList == NULL_PTR || + pSlot == NULL_PTR || + pSlot->pSession == NULL_PTR) { + DEBUGMSGTL(("pkcs_init","malloc failed.")); + QUITFUN(SNMPERR_GENERR, pkcs_init_quit); + } + + /* Get the list of slots */ + if ((rv = C_GetSlotList(1, pSlotList, &slotcount)) != CKR_OK) { + DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", + pkcserr_string(rv))); + QUITFUN(SNMPERR_GENERR, pkcs_init_quit); + } + + /* initialize Slots structure */ + pSlot->count = slotcount; + for (i = 0, tmp = pSlot->pSession; i < slotcount; i++, tmp++) { + tmp->sid = pSlotList[i]; + tmp->hdl = NULL; + } + + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN, + free_slots, NULL); + + pkcs_init_quit: + SNMP_FREE(pSlotList); + return rval; +} + +/* + * close all the opened sessions when finished with Cryptoki library. + */ +static int +free_slots(int majorID, int minorID, void *serverarg, void *clientarg) +{ + int slotcount, i; + + if (pSlot != NULL) { + slotcount = pSlot->count; + for (i = 0; i < slotcount; i++) { + if (pSlot->pSession->hdl != NULL) { + free(pSlot->pSession->hdl); + } + } + free(pSlot); + } + + (void) C_Finalize(NULL); + return 0; +} + +/* + * generate random data + */ +int +pkcs_random(u_char * buf, size_t buflen) +{ + CK_SESSION_HANDLE hSession; + + if (pSlot != NULL && + get_slot_session_handle(pSlot->pSession, &hSession) == CKR_OK && + C_GenerateRandom(hSession, buf, buflen) == CKR_OK) { + return SNMPERR_SUCCESS; + } + + return SNMPERR_GENERR; +} + +/* + * retrieve the session handle from the first slot that supports the specified + * mechanism. + */ +static CK_RV +get_session_handle(CK_MECHANISM_TYPE mech_type, CK_FLAGS flag, + CK_SESSION_HANDLE_PTR sess) +{ + CK_RV rv = CKR_OK; + CK_MECHANISM_INFO info; + netsnmp_pkcs_slot_session *p = NULL; + int i, slotcount = 0; + + if (pSlot) { + slotcount = pSlot->count; + p = pSlot->pSession; + } + + /* Find a slot with matching mechanism */ + for (i = 0; i < slotcount; i++, p++) { + rv = C_GetMechanismInfo(p->sid, mech_type, &info); + + if (rv != CKR_OK) { + continue; /* to the next slot */ + } else { + if (info.flags & flag) { + rv = get_slot_session_handle(p, sess); + break; /* found */ + } + } + } + + /* Show error if no matching mechanism found */ + if (i == slotcount) { + DEBUGMSGTL(("pkcs_init","No cryptographic provider for %s", + mech_type)); + return CKR_SESSION_HANDLE_INVALID; + } + + return rv; +} + +/* + * retrieve the session handle from the specified slot. + */ +static CK_RV +get_slot_session_handle(netsnmp_pkcs_slot_session *p, + CK_SESSION_HANDLE_PTR sess) +{ + CK_RV rv = CKR_OK; + if (p == NULL) { + *sess = NULL; + return CKR_SESSION_HANDLE_INVALID; + } + + if (p->hdl == NULL) { + /* Open a session */ + rv = C_OpenSession(p->sid, CKF_SERIAL_SESSION, + NULL_PTR, NULL, &p->hdl); + + if (rv != CKR_OK) { + DEBUGMSGTL(("get_slot_session_handle","can not open PKCS #11 session: %s", + pkcserr_string(rv))); + } + } + *sess = p->hdl; + + return rv; +} + +/* + * perform a signature operation to generate MAC. + */ +int +pkcs_sign(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen, + u_char * msg, u_int msglen, u_char * mac, size_t * maclen) +{ + /* + * Key template + */ + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + CK_KEY_TYPE keytype = CKK_GENERIC_SECRET; + CK_BBOOL truevalue = TRUE; + CK_BBOOL falsevalue= FALSE; + CK_ATTRIBUTE template[] = { + {CKA_CLASS, &class, sizeof (class)}, + {CKA_KEY_TYPE, &keytype, sizeof (keytype)}, + {CKA_SIGN, &truevalue, sizeof (truevalue)}, + {CKA_TOKEN, &falsevalue, sizeof (falsevalue)}, + {CKA_VALUE, key, keylen} + }; + CK_SESSION_HANDLE hSession; + CK_MECHANISM mech; + CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0; + int rval = SNMPERR_SUCCESS; + if (get_session_handle(mech_type, CKF_SIGN, &hSession) != CKR_OK || + hSession == NULL) { + QUITFUN(SNMPERR_GENERR, pkcs_sign_quit); + } + + /* create a key object */ + if (C_CreateObject(hSession, template, + (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_sign_quit); + } + + mech.mechanism = mech_type; + mech.pParameter = NULL_PTR; + mech.ulParameterLen = 0; + + /* initialize a signature operation */ + if (C_SignInit(hSession, &mech, hkey) != CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_sign_quit); + } + /* continue a multiple-part signature operation */ + if (C_SignUpdate(hSession, msg, msglen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_sign_quit); + } + /* finish a multiple-part signature operation */ + if (C_SignFinal(hSession, mac, maclen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_sign_quit); + } + + pkcs_sign_quit: + + if (key != (CK_OBJECT_HANDLE) 0) { + (void) C_DestroyObject(hSession, hkey); + } + return rval; +} + +/* + * perform a message-digesting operation. + */ +int +pkcs_digest(CK_MECHANISM_TYPE mech_type, u_char * msg, u_int msglen, + u_char * digest, size_t * digestlen) +{ + int rval = SNMPERR_SUCCESS; + CK_SESSION_HANDLE hSession; + CK_MECHANISM mech; + if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK || + hSession == NULL) { + QUITFUN(SNMPERR_GENERR, pkcs_digest_quit); + } + + mech.mechanism = mech_type; + mech.pParameter = NULL_PTR; + mech.ulParameterLen = 0; + + /* initialize a message-digesting operation */ + if (C_DigestInit(hSession, &mech)!= CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_digest_quit); + } + /* continue a multiple-part message-digesting operation */ + if (C_DigestUpdate(hSession, msg, msglen) != CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_digest_quit); + } + /* finish a multiple-part message-digesting operation */ + if (C_DigestFinal(hSession, digest, digestlen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_digest_quit); + } + + pkcs_digest_quit: + return rval; +} + +/* + * encrypt plaintext into ciphertext using key and iv. + */ +int +pkcs_encrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen, + u_char * iv, u_int ivlen, + u_char * plaintext, u_int ptlen, + u_char * ciphertext, size_t * ctlen) +{ + int rval = SNMPERR_SUCCESS; + int pad_size, offset; + /* + * Key template + */ + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + CK_KEY_TYPE keytype = CKK_DES; + /* CK_KEY_TYPE AESkeytype = CKK_AES; */ + CK_BBOOL truevalue = TRUE; + CK_BBOOL falsevalue = FALSE; + + CK_ATTRIBUTE template[] = { + {CKA_CLASS, &class, sizeof (class)}, + {CKA_KEY_TYPE, &keytype, sizeof (keytype)}, + {CKA_ENCRYPT, &truevalue, sizeof (truevalue)}, + {CKA_TOKEN, &falsevalue, sizeof (falsevalue)}, + {CKA_VALUE, key, keylen} + }; + + CK_SESSION_HANDLE hSession; + CK_MECHANISM mech; + CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0; + + if (get_session_handle(mech_type, CKF_ENCRYPT, + &hSession) != CKR_OK || + hSession == NULL) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + + if (C_CreateObject(hSession, template, + (sizeof (template) / sizeof (CK_ATTRIBUTE)), + &hkey) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + + mech.mechanism = mech_type; + mech.pParameter = iv; + mech.ulParameterLen = ivlen; + + /* initialize an encryption operation */ + if (C_EncryptInit(hSession, &mech, hkey) != CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + + /* for DES */ + pad_size = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES); + + if (ptlen + pad_size - ptlen % pad_size > *ctlen) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + + for (offset = 0; offset < ptlen; offset += pad_size) { + /* continue a multiple-part encryption operation */ + if (C_EncryptUpdate(hSession, plaintext + offset, pad_size, + ciphertext + offset, ctlen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + } + + /* finish a multiple-part encryption operation */ + if (C_EncryptFinal(hSession, ciphertext + offset, ctlen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit); + } + *ctlen = offset; + + pkcs_encrypt_quit: + if (key != (CK_OBJECT_HANDLE) 0) { + (void) C_DestroyObject(hSession, hkey); + } + return rval; +} + +/* + * decrypt ciphertext into plaintext using key and iv. + */ +int +pkcs_decrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen, + u_char * iv, u_int ivlen, + u_char * ciphertext, u_int ctlen, + u_char * plaintext, size_t * ptlen) +{ + int rval = SNMPERR_SUCCESS; + /* + * Key template + */ + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + CK_KEY_TYPE keytype = CKK_DES; + /* CK_KEY_TYPE AESkeytype = CKK_AES; */ + CK_BBOOL truevalue = TRUE; + CK_BBOOL falsevalue= FALSE; + CK_ATTRIBUTE template[] = { + {CKA_CLASS, &class, sizeof (class)}, + {CKA_KEY_TYPE, &keytype, sizeof (keytype)}, + {CKA_DECRYPT, &truevalue, sizeof (truevalue)}, + {CKA_TOKEN, &falsevalue, sizeof (falsevalue)}, + {CKA_VALUE, key, keylen} + }; + CK_SESSION_HANDLE hSession; + CK_MECHANISM mech; + CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0; + + if (get_session_handle(mech_type, CKF_DECRYPT, &hSession) != CKR_OK || + hSession == NULL) { + QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit); + } + + if (C_CreateObject(hSession, template, + (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit); + } + + mech.mechanism = mech_type; + mech.pParameter = iv; + mech.ulParameterLen = ivlen; + + /* initialize a decryption operation */ + if (C_DecryptInit(hSession, &mech, hkey) != CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit); + } + /* continue a multiple-part decryption operation */ + if (C_DecryptUpdate(hSession, ciphertext, ctlen, plaintext, + ptlen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit); + } + /* finish a multiple-part decryption operation */ + if (C_DecryptFinal(hSession, plaintext, ptlen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit); + } + + pkcs_decrypt_quit: + if (key != (CK_OBJECT_HANDLE) 0) { + (void) C_DestroyObject(hSession, hkey); + } + return rval; +} + +/* + * Convert a passphrase into a master user key, Ku, according to the + * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM) + */ +int +pkcs_generate_Ku(CK_MECHANISM_TYPE mech_type, u_char * passphrase, u_int pplen, + u_char * Ku, size_t * kulen) +{ + int rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE; + CK_SESSION_HANDLE hSession; + CK_MECHANISM mech; + u_int i, pindex = 0; + u_char buf[USM_LENGTH_KU_HASHBLOCK], *bufp; + + if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK || + hSession == NULL) { + QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit); + } + + mech.mechanism = mech_type; + mech.pParameter = NULL_PTR; + mech.ulParameterLen = 0; + + /* initialize a message-digesting operation */ + if (C_DigestInit(hSession, &mech)!= CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit); + } + + while (nbytes > 0) { + bufp = buf; + for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) { + /* + * fill a buffer with the supplied passphrase. When the end + * of the passphrase is reachedcycle back to the beginning. + */ + *bufp++ = passphrase[pindex++ % pplen]; + } + /* continue a multiple-part message-digesting operation */ + if (C_DigestUpdate(hSession, buf, USM_LENGTH_KU_HASHBLOCK) != CKR_OK ) { + QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit); + } + nbytes -= USM_LENGTH_KU_HASHBLOCK; + } + /* finish a multiple-part message-digesting operation */ + if (C_DigestFinal(hSession, Ku, kulen) != CKR_OK) { + QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit); + } + + pkcs_generate_Ku_quit: + return rval; +} + +/* + * pkcserr_stringor: returns a string representation of the given + * return code. + */ +static char * +pkcserr_string(CK_RV rv) +{ + static char errstr[128]; + switch (rv) { + case CKR_OK: + return ("CKR_OK"); + break; + case CKR_CANCEL: + return ("CKR_CANCEL"); + break; + case CKR_HOST_MEMORY: + return ("CKR_HOST_MEMORY"); + break; + case CKR_SLOT_ID_INVALID: + return ("CKR_SLOT_ID_INVALID"); + break; + case CKR_GENERAL_ERROR: + return ("CKR_GENERAL_ERROR"); + break; + case CKR_FUNCTION_FAILED: + return ("CKR_FUNCTION_FAILED"); + break; + case CKR_ARGUMENTS_BAD: + return ("CKR_ARGUMENTS_BAD"); + break; + case CKR_NO_EVENT: + return ("CKR_NO_EVENT"); + break; + case CKR_NEED_TO_CREATE_THREADS: + return ("CKR_NEED_TO_CREATE_THREADS"); + break; + case CKR_CANT_LOCK: + return ("CKR_CANT_LOCK"); + break; + case CKR_ATTRIBUTE_READ_ONLY: + return ("CKR_ATTRIBUTE_READ_ONLY"); + break; + case CKR_ATTRIBUTE_SENSITIVE: + return ("CKR_ATTRIBUTE_SENSITIVE"); + break; + case CKR_ATTRIBUTE_TYPE_INVALID: + return ("CKR_ATTRIBUTE_TYPE_INVALID"); + break; + case CKR_ATTRIBUTE_VALUE_INVALID: + return ("CKR_ATTRIBUTE_VALUE_INVALID"); + break; + case CKR_DATA_INVALID: + return ("CKR_DATA_INVALID"); + break; + case CKR_DATA_LEN_RANGE: + return ("CKR_DATA_LEN_RANGE"); + break; + case CKR_DEVICE_ERROR: + return ("CKR_DEVICE_ERROR"); + break; + case CKR_DEVICE_MEMORY: + return ("CKR_DEVICE_MEMORY"); + break; + case CKR_DEVICE_REMOVED: + return ("CKR_DEVICE_REMOVED"); + break; + case CKR_ENCRYPTED_DATA_INVALID: + return ("CKR_ENCRYPTED_DATA_INVALID"); + break; + case CKR_ENCRYPTED_DATA_LEN_RANGE: + return ("CKR_ENCRYPTED_DATA_LEN_RANGE"); + break; + case CKR_FUNCTION_CANCELED: + return ("CKR_FUNCTION_CANCELED"); + break; + case CKR_FUNCTION_NOT_PARALLEL: + return ("CKR_FUNCTION_NOT_PARALLEL"); + break; + case CKR_FUNCTION_NOT_SUPPORTED: + return ("CKR_FUNCTION_NOT_SUPPORTED"); + break; + case CKR_KEY_HANDLE_INVALID: + return ("CKR_KEY_HANDLE_INVALID"); + break; + case CKR_KEY_SIZE_RANGE: + return ("CKR_KEY_SIZE_RANGE"); + break; + case CKR_KEY_TYPE_INCONSISTENT: + return ("CKR_KEY_TYPE_INCONSISTENT"); + break; + case CKR_KEY_NOT_NEEDED: + return ("CKR_KEY_NOT_NEEDED"); + break; + case CKR_KEY_CHANGED: + return ("CKR_KEY_CHANGED"); + break; + case CKR_KEY_NEEDED: + return ("CKR_KEY_NEEDED"); + break; + case CKR_KEY_INDIGESTIBLE: + return ("CKR_KEY_INDIGESTIBLE"); + break; + case CKR_KEY_FUNCTION_NOT_PERMITTED: + return ("CKR_KEY_FUNCTION_NOT_PERMITTED"); + break; + case CKR_KEY_NOT_WRAPPABLE: + return ("CKR_KEY_NOT_WRAPPABLE"); + break; + case CKR_KEY_UNEXTRACTABLE: + return ("CKR_KEY_UNEXTRACTABLE"); + break; + case CKR_MECHANISM_INVALID: + return ("CKR_MECHANISM_INVALID"); + break; + case CKR_MECHANISM_PARAM_INVALID: + return ("CKR_MECHANISM_PARAM_INVALID"); + break; + case CKR_OBJECT_HANDLE_INVALID: + return ("CKR_OBJECT_HANDLE_INVALID"); + break; + case CKR_OPERATION_ACTIVE: + return ("CKR_OPERATION_ACTIVE"); + break; + case CKR_OPERATION_NOT_INITIALIZED: + return ("CKR_OPERATION_NOT_INITIALIZED"); + break; + case CKR_PIN_INCORRECT: + return ("CKR_PIN_INCORRECT"); + break; + case CKR_PIN_INVALID: + return ("CKR_PIN_INVALID"); + break; + case CKR_PIN_LEN_RANGE: + return ("CKR_PIN_LEN_RANGE"); + break; + case CKR_PIN_EXPIRED: + return ("CKR_PIN_EXPIRED"); + break; + case CKR_PIN_LOCKED: + return ("CKR_PIN_LOCKED"); + break; + case CKR_SESSION_CLOSED: + return ("CKR_SESSION_CLOSED"); + break; + case CKR_SESSION_COUNT: + return ("CKR_SESSION_COUNT"); + break; + case CKR_SESSION_HANDLE_INVALID: + return ("CKR_SESSION_HANDLE_INVALID"); + break; + case CKR_SESSION_PARALLEL_NOT_SUPPORTED: + return ("CKR_SESSION_PARALLEL_NOT_SUPPORTED"); + break; + case CKR_SESSION_READ_ONLY: + return ("CKR_SESSION_READ_ONLY"); + break; + case CKR_SESSION_EXISTS: + return ("CKR_SESSION_EXISTS"); + break; + case CKR_SESSION_READ_ONLY_EXISTS: + return ("CKR_SESSION_READ_ONLY_EXISTS"); + break; + case CKR_SESSION_READ_WRITE_SO_EXISTS: + return ("CKR_SESSION_READ_WRITE_SO_EXISTS"); + break; + case CKR_SIGNATURE_INVALID: + return ("CKR_SIGNATURE_INVALID"); + break; + case CKR_SIGNATURE_LEN_RANGE: + return ("CKR_SIGNATURE_LEN_RANGE"); + break; + case CKR_TEMPLATE_INCOMPLETE: + return ("CKR_TEMPLATE_INCOMPLETE"); + break; + case CKR_TEMPLATE_INCONSISTENT: + return ("CKR_TEMPLATE_INCONSISTENT"); + break; + case CKR_TOKEN_NOT_PRESENT: + return ("CKR_TOKEN_NOT_PRESENT"); + break; + case CKR_TOKEN_NOT_RECOGNIZED: + return ("CKR_TOKEN_NOT_RECOGNIZED"); + break; + case CKR_TOKEN_WRITE_PROTECTED: + return ("CKR_TOKEN_WRITE_PROTECTED"); + break; + case CKR_UNWRAPPING_KEY_HANDLE_INVALID: + return ("CKR_UNWRAPPING_KEY_HANDLE_INVALID"); + break; + case CKR_UNWRAPPING_KEY_SIZE_RANGE: + return ("CKR_UNWRAPPING_KEY_SIZE_RANGE"); + break; + case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: + return ("CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"); + break; + case CKR_USER_ALREADY_LOGGED_IN: + return ("CKR_USER_ALREADY_LOGGED_IN"); + break; + case CKR_USER_NOT_LOGGED_IN: + return ("CKR_USER_NOT_LOGGED_IN"); + break; + case CKR_USER_PIN_NOT_INITIALIZED: + return ("CKR_USER_PIN_NOT_INITIALIZED"); + break; + case CKR_USER_TYPE_INVALID: + return ("CKR_USER_TYPE_INVALID"); + break; + case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: + return ("CKR_USER_ANOTHER_ALREADY_LOGGED_IN"); + break; + case CKR_USER_TOO_MANY_TYPES: + return ("CKR_USER_TOO_MANY_TYPES"); + break; + case CKR_WRAPPED_KEY_INVALID: + return ("CKR_WRAPPED_KEY_INVALID"); + break; + case CKR_WRAPPED_KEY_LEN_RANGE: + return ("CKR_WRAPPED_KEY_LEN_RANGE"); + break; + case CKR_WRAPPING_KEY_HANDLE_INVALID: + return ("CKR_WRAPPING_KEY_HANDLE_INVALID"); + break; + case CKR_WRAPPING_KEY_SIZE_RANGE: + return ("CKR_WRAPPING_KEY_SIZE_RANGE"); + break; + case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: + return ("CKR_WRAPPING_KEY_TYPE_INCONSISTENT"); + break; + case CKR_RANDOM_SEED_NOT_SUPPORTED: + return ("CKR_RANDOM_SEED_NOT_SUPPORTED"); + break; + case CKR_RANDOM_NO_RNG: + return ("CKR_RANDOM_NO_RNG"); + break; + case CKR_DOMAIN_PARAMS_INVALID: + return ("CKR_DOMAIN_PARAMS_INVALID"); + break; + case CKR_BUFFER_TOO_SMALL: + return ("CKR_BUFFER_TOO_SMALL"); + break; + case CKR_SAVED_STATE_INVALID: + return ("CKR_SAVED_STATE_INVALID"); + break; + case CKR_INFORMATION_SENSITIVE: + return ("CKR_INFORMATION_SENSITIVE"); + break; + case CKR_STATE_UNSAVEABLE: + return ("CKR_STATE_UNSAVEABLE"); + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + return ("CKR_CRYPTOKI_NOT_INITIALIZED"); + break; + case CKR_CRYPTOKI_ALREADY_INITIALIZED: + return ("CKR_CRYPTOKI_ALREADY_INITIALIZED"); + break; + case CKR_MUTEX_BAD: + return ("CKR_MUTEX_BAD"); + break; + case CKR_MUTEX_NOT_LOCKED: + return ("CKR_MUTEX_NOT_LOCKED"); + break; + case CKR_VENDOR_DEFINED: + return ("CKR_VENDOR_DEFINED"); + break; + default: + /* rv not found */ + snprintf(errstr, sizeof (errstr), + "Unknown return code: 0x%x", rv); + return (errstr); + break; + } +} +#endif |