pkcs.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:23k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  3.  * Use is subject to license terms specified in the COPYING file
  4.  * distributed with the Net-SNMP package.
  5.  */
  6. /*
  7.  * pkcs.c
  8.  */
  9. #include <net-snmp/net-snmp-config.h>
  10. #ifdef USE_PKCS
  11. #include <net-snmp/types.h>
  12. #include <net-snmp/output_api.h>
  13. #include <net-snmp/config_api.h>
  14. #include <net-snmp/library/snmp_api.h>
  15. #include <net-snmp/library/tools.h>
  16. #include <net-snmp/library/keytools.h>
  17. #include <net-snmp/library/scapi.h>
  18. #include <net-snmp/library/callback.h>
  19. #include <security/cryptoki.h>
  20. typedef struct netsnmp_pkcs_slot_session_s {
  21.     CK_SLOT_ID        sid;
  22.     CK_SESSION_HANDLE hdl;
  23. } netsnmp_pkcs_slot_session; 
  24. typedef struct netsnmp_pkcs_slot_info_s {
  25.     int count;
  26.     netsnmp_pkcs_slot_session *pSession; 
  27. } netsnmp_pkcs_slot_info;
  28. static CK_RV get_session_handle(CK_MECHANISM_TYPE, CK_FLAGS,
  29.                                 CK_SESSION_HANDLE_PTR);
  30. static CK_RV get_slot_session_handle(netsnmp_pkcs_slot_session *,
  31.                                      CK_SESSION_HANDLE_PTR);
  32. static char *pkcserr_string(CK_RV);
  33. static int free_slots(int, int, void *, void *);
  34. static netsnmp_pkcs_slot_info *pSlot = NULL;
  35. /*
  36.  * initialize the Cryptoki library.
  37.  */
  38. int
  39. pkcs_init(void)
  40. {
  41.     CK_RV          rv;
  42.     CK_ULONG       slotcount;
  43.     CK_SLOT_ID_PTR pSlotList = NULL;
  44.     netsnmp_pkcs_slot_session    *tmp;
  45.     int            i, rval = SNMPERR_SUCCESS;
  46.     /* Initialize pkcs */
  47.     if ((rv = C_Initialize(NULL)) != CKR_OK) {
  48.         DEBUGMSGTL(("pkcs_init", "C_Initialize failed: %s",
  49.                 pkcserr_string(rv)));
  50.         return SNMPERR_SC_NOT_CONFIGURED;
  51.     }
  52.     /* Get slot count */
  53.     rv = C_GetSlotList(1, NULL_PTR, &slotcount);
  54.     if (rv != CKR_OK || slotcount == 0) {
  55.         DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", 
  56.                 pkcserr_string(rv)));
  57.         QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
  58.     }
  59.     /* Found at least one slot, allocate memory for slot list */
  60.     pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
  61.     pSlot = malloc(sizeof (netsnmp_pkcs_slot_info));
  62.     pSlot->pSession = malloc(slotcount * sizeof (netsnmp_pkcs_slot_session));
  63.     if (pSlotList == NULL_PTR ||
  64.         pSlot == NULL_PTR ||
  65.         pSlot->pSession == NULL_PTR) {
  66.         DEBUGMSGTL(("pkcs_init","malloc failed.")); 
  67.         QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
  68.     }
  69.     /* Get the list of slots */
  70.     if ((rv = C_GetSlotList(1, pSlotList, &slotcount)) != CKR_OK) {
  71.         DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", 
  72.                 pkcserr_string(rv)));
  73.         QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
  74.     }
  75.     /* initialize Slots structure */
  76.     pSlot->count = slotcount;
  77.     for (i = 0, tmp = pSlot->pSession; i < slotcount; i++, tmp++) {
  78.         tmp->sid = pSlotList[i]; 
  79.         tmp->hdl = NULL;
  80.     }
  81.     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
  82.                         free_slots, NULL);
  83.   pkcs_init_quit:
  84.     SNMP_FREE(pSlotList);
  85.     return rval;
  86. }
  87. /*
  88.  * close all the opened sessions when finished with Cryptoki library.
  89.  */
  90. static int
  91. free_slots(int majorID, int minorID, void *serverarg, void *clientarg)
  92. {
  93.     int            slotcount, i;
  94.     if (pSlot != NULL) {
  95.         slotcount = pSlot->count;
  96.         for (i = 0; i < slotcount; i++) {
  97.             if (pSlot->pSession->hdl != NULL) {
  98.                 free(pSlot->pSession->hdl);
  99.             }
  100.         }
  101.         free(pSlot);
  102.     }
  103.     (void) C_Finalize(NULL);
  104.     return 0;
  105. }
  106. /*
  107.  * generate random data
  108.  */
  109. int
  110. pkcs_random(u_char * buf, size_t buflen)
  111. {
  112.     CK_SESSION_HANDLE hSession;
  113.     if (pSlot != NULL &&
  114.         get_slot_session_handle(pSlot->pSession, &hSession) == CKR_OK &&
  115.         C_GenerateRandom(hSession, buf, buflen) == CKR_OK) {
  116.         return SNMPERR_SUCCESS;
  117.     }
  118.     return SNMPERR_GENERR;
  119. }
  120. /*
  121.  * retrieve the session handle from the first slot that supports the specified
  122.  * mechanism.
  123.  */
  124. static CK_RV
  125. get_session_handle(CK_MECHANISM_TYPE mech_type, CK_FLAGS flag,
  126.                 CK_SESSION_HANDLE_PTR sess)
  127. {
  128.     CK_RV             rv = CKR_OK;
  129.     CK_MECHANISM_INFO info;
  130.     netsnmp_pkcs_slot_session       *p = NULL;
  131.     int               i, slotcount = 0;
  132.             
  133.     if (pSlot) {
  134.         slotcount = pSlot->count;
  135.         p = pSlot->pSession;
  136.     }
  137.     /* Find a slot with matching mechanism */
  138.     for (i = 0; i < slotcount; i++, p++) {
  139.         rv = C_GetMechanismInfo(p->sid, mech_type, &info);
  140.         if (rv != CKR_OK) {
  141.             continue; /* to the next slot */
  142.         } else {
  143.             if (info.flags & flag) {
  144.                 rv = get_slot_session_handle(p, sess);
  145.                 break; /* found */
  146.             }
  147.         }
  148.     }
  149.     /* Show error if no matching mechanism found */
  150.     if (i == slotcount) {
  151.         DEBUGMSGTL(("pkcs_init","No cryptographic provider for %s",
  152.                 mech_type)); 
  153.         return CKR_SESSION_HANDLE_INVALID;
  154.     }
  155.     return rv;
  156. }
  157. /*
  158.  * retrieve the session handle from the specified slot.
  159.  */
  160. static CK_RV
  161. get_slot_session_handle(netsnmp_pkcs_slot_session *p,
  162.                         CK_SESSION_HANDLE_PTR sess)
  163. {
  164.     CK_RV rv = CKR_OK;
  165.     if (p == NULL) {
  166.         *sess = NULL;
  167.         return CKR_SESSION_HANDLE_INVALID;
  168.     }
  169.     if (p->hdl == NULL) {
  170.         /* Open a session */
  171.         rv = C_OpenSession(p->sid, CKF_SERIAL_SESSION,
  172.                 NULL_PTR, NULL, &p->hdl);
  173.         if (rv != CKR_OK) {
  174.             DEBUGMSGTL(("get_slot_session_handle","can not open PKCS #11 session: %s",
  175.                         pkcserr_string(rv)));
  176.         }
  177.     }
  178.     *sess = p->hdl;
  179.     return rv;
  180. }
  181. /*
  182.  * perform a signature operation to generate MAC.
  183.  */
  184. int
  185. pkcs_sign(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
  186.           u_char * msg, u_int msglen, u_char * mac, size_t * maclen)
  187. {
  188.     /*
  189.      * Key template 
  190.      */
  191.     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
  192.     CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
  193.     CK_BBOOL truevalue = TRUE;
  194.     CK_BBOOL falsevalue= FALSE;
  195.     CK_ATTRIBUTE template[] = {
  196.         {CKA_CLASS, &class, sizeof (class)},
  197.         {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
  198.         {CKA_SIGN, &truevalue, sizeof (truevalue)},
  199.         {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
  200.         {CKA_VALUE, key, keylen}
  201.     };
  202.     CK_SESSION_HANDLE hSession;
  203.     CK_MECHANISM mech;
  204.     CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
  205.     int                rval = SNMPERR_SUCCESS;
  206.     if (get_session_handle(mech_type, CKF_SIGN, &hSession) != CKR_OK ||
  207.         hSession == NULL) {
  208.         QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
  209.     }
  210.     /* create a key object */
  211.     if (C_CreateObject(hSession, template,
  212.         (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
  213.         QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
  214.     }
  215.     mech.mechanism = mech_type;
  216.     mech.pParameter = NULL_PTR;
  217.     mech.ulParameterLen = 0;
  218.     /* initialize a signature operation */
  219.     if (C_SignInit(hSession, &mech, hkey) != CKR_OK ) {
  220.         QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
  221.     }
  222.     /* continue a multiple-part signature operation */
  223.     if (C_SignUpdate(hSession, msg, msglen) != CKR_OK) {
  224.         QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
  225.     }
  226.     /* finish a multiple-part signature operation */
  227.     if (C_SignFinal(hSession, mac, maclen) != CKR_OK) {
  228.         QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
  229.     }
  230.   pkcs_sign_quit:
  231.     if (key != (CK_OBJECT_HANDLE) 0) {
  232.         (void) C_DestroyObject(hSession, hkey);
  233.     }
  234.     return rval;
  235. }
  236. /*
  237.  * perform a message-digesting operation.
  238.  */
  239. int
  240. pkcs_digest(CK_MECHANISM_TYPE mech_type, u_char * msg, u_int msglen,
  241.             u_char * digest, size_t * digestlen)
  242. {
  243.     int               rval = SNMPERR_SUCCESS;
  244.     CK_SESSION_HANDLE hSession;
  245.     CK_MECHANISM      mech;
  246.     if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
  247.         hSession == NULL) {
  248.         QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
  249.     }
  250.     mech.mechanism = mech_type;
  251.     mech.pParameter = NULL_PTR;
  252.     mech.ulParameterLen = 0;
  253.     /* initialize a message-digesting operation */
  254.     if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
  255.         QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
  256.     }
  257.     /* continue a multiple-part message-digesting operation */
  258.     if (C_DigestUpdate(hSession, msg, msglen) != CKR_OK ) {
  259.         QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
  260.     }
  261.     /* finish a multiple-part message-digesting operation */
  262.     if (C_DigestFinal(hSession, digest, digestlen) != CKR_OK) {
  263.         QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
  264.     }
  265.   pkcs_digest_quit:
  266.     return rval;
  267. }
  268. /*
  269.  * encrypt plaintext into ciphertext using key and iv.   
  270.  */
  271. int
  272. pkcs_encrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
  273.              u_char * iv, u_int ivlen,
  274.              u_char * plaintext, u_int ptlen,
  275.              u_char * ciphertext, size_t * ctlen)
  276. {
  277.     int                rval = SNMPERR_SUCCESS;
  278.     int                pad_size, offset;
  279.     /*
  280.      * Key template 
  281.      */
  282.     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
  283.     CK_KEY_TYPE keytype = CKK_DES;
  284.     /* CK_KEY_TYPE AESkeytype = CKK_AES; */
  285.     CK_BBOOL truevalue = TRUE;
  286.     CK_BBOOL falsevalue = FALSE;
  287.     CK_ATTRIBUTE template[] = {
  288.         {CKA_CLASS, &class, sizeof (class)},
  289.         {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
  290.         {CKA_ENCRYPT, &truevalue, sizeof (truevalue)},
  291.         {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
  292.         {CKA_VALUE, key, keylen} 
  293.     };
  294.     CK_SESSION_HANDLE hSession;
  295.     CK_MECHANISM mech;
  296.     CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
  297.     if (get_session_handle(mech_type, CKF_ENCRYPT,
  298.                            &hSession) != CKR_OK ||
  299.         hSession == NULL) {
  300.         QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
  301.     }
  302.     if (C_CreateObject(hSession, template,
  303.         (sizeof (template) / sizeof (CK_ATTRIBUTE)),
  304.                                 &hkey) != CKR_OK) {
  305.         QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
  306.     }
  307.     mech.mechanism = mech_type;
  308.     mech.pParameter = iv;
  309.     mech.ulParameterLen = ivlen;
  310.     /* initialize an encryption operation */
  311.     if (C_EncryptInit(hSession, &mech, hkey) != CKR_OK ) {
  312.         QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
  313.     }
  314.     /* for DES */
  315.     pad_size = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
  316.     if (ptlen + pad_size - ptlen % pad_size > *ctlen) {
  317.         QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);    
  318.     }
  319.     for (offset = 0; offset < ptlen; offset += pad_size) {
  320.         /* continue a multiple-part encryption operation */
  321.         if (C_EncryptUpdate(hSession, plaintext + offset, pad_size,
  322.                             ciphertext + offset, ctlen) != CKR_OK) {
  323.             QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
  324.         }
  325.     }
  326.     /* finish a multiple-part encryption operation */
  327.     if (C_EncryptFinal(hSession, ciphertext + offset, ctlen) != CKR_OK) {
  328.         QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
  329.     }
  330.     *ctlen = offset;
  331.   pkcs_encrypt_quit:
  332.     if (key != (CK_OBJECT_HANDLE) 0) {
  333.         (void) C_DestroyObject(hSession, hkey);
  334.     }
  335.     return rval;
  336. }
  337. /* 
  338.  * decrypt ciphertext into plaintext using key and iv.
  339.  */
  340. int
  341. pkcs_decrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
  342.              u_char * iv, u_int ivlen,
  343.              u_char * ciphertext, u_int ctlen,
  344.              u_char * plaintext, size_t * ptlen)
  345. {
  346.     int            rval = SNMPERR_SUCCESS;
  347.     /*
  348.      * Key template 
  349.      */
  350.     CK_OBJECT_CLASS class = CKO_SECRET_KEY;
  351.     CK_KEY_TYPE keytype = CKK_DES;
  352.     /* CK_KEY_TYPE AESkeytype = CKK_AES; */
  353.     CK_BBOOL truevalue = TRUE;
  354.     CK_BBOOL falsevalue= FALSE;
  355.     CK_ATTRIBUTE template[] = {
  356.         {CKA_CLASS, &class, sizeof (class)},
  357.         {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
  358.         {CKA_DECRYPT, &truevalue, sizeof (truevalue)},
  359.         {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
  360.         {CKA_VALUE, key, keylen}
  361.     };
  362.     CK_SESSION_HANDLE hSession;
  363.     CK_MECHANISM mech;
  364.     CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
  365.     if (get_session_handle(mech_type, CKF_DECRYPT, &hSession) != CKR_OK ||
  366.         hSession == NULL) {
  367.         QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
  368.     }
  369.     if (C_CreateObject(hSession, template,
  370.         (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
  371.         QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
  372.     }
  373.     mech.mechanism = mech_type;
  374.     mech.pParameter = iv;
  375.     mech.ulParameterLen = ivlen;
  376.     /* initialize a decryption operation */
  377.     if (C_DecryptInit(hSession, &mech, hkey) != CKR_OK ) {
  378.         QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
  379.     }
  380.     /* continue a multiple-part decryption operation */
  381.     if (C_DecryptUpdate(hSession, ciphertext, ctlen, plaintext,
  382.                                         ptlen) != CKR_OK) {
  383.         QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
  384.     }
  385.     /* finish a multiple-part decryption operation */
  386.     if (C_DecryptFinal(hSession, plaintext, ptlen) != CKR_OK) {
  387.         QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
  388.     }
  389.   pkcs_decrypt_quit:
  390.     if (key != (CK_OBJECT_HANDLE) 0) {
  391.         (void) C_DestroyObject(hSession, hkey);
  392.     }
  393.     return rval;
  394. }
  395. /*
  396.  * Convert a passphrase into a master user key, Ku, according to the
  397.  * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
  398.  */
  399. int
  400. pkcs_generate_Ku(CK_MECHANISM_TYPE mech_type, u_char * passphrase, u_int pplen,
  401.                  u_char * Ku, size_t * kulen)
  402. {
  403.     int                rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
  404.     CK_SESSION_HANDLE hSession;
  405.     CK_MECHANISM mech;
  406.     u_int        i, pindex = 0;
  407.     u_char        buf[USM_LENGTH_KU_HASHBLOCK], *bufp;
  408.     if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
  409.         hSession == NULL) {
  410.         QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
  411.     }
  412.     mech.mechanism = mech_type;
  413.     mech.pParameter = NULL_PTR;
  414.     mech.ulParameterLen = 0;
  415.     /* initialize a message-digesting operation */
  416.     if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
  417.         QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
  418.     }
  419.     while (nbytes > 0) {
  420.         bufp = buf;
  421.         for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
  422.            /*
  423.     * fill a buffer with the supplied passphrase.  When the end
  424.             * of the passphrase is reachedcycle back to the beginning.
  425.             */
  426.             *bufp++ = passphrase[pindex++ % pplen];
  427.         }
  428.         /* continue a multiple-part message-digesting operation */
  429.         if (C_DigestUpdate(hSession, buf, USM_LENGTH_KU_HASHBLOCK) != CKR_OK ) {
  430.             QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
  431.         }
  432.         nbytes -= USM_LENGTH_KU_HASHBLOCK;
  433.     }
  434.     /* finish a multiple-part message-digesting operation */
  435.     if (C_DigestFinal(hSession, Ku, kulen) != CKR_OK) {
  436.         QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
  437.     }
  438.   pkcs_generate_Ku_quit:
  439.     return rval;
  440. }
  441.    
  442. /*
  443.  * pkcserr_stringor: returns a string representation of the given 
  444.  * return code.
  445.  */
  446. static char *
  447. pkcserr_string(CK_RV rv)
  448. {
  449.     static char errstr[128];
  450.     switch (rv) {
  451.     case CKR_OK:
  452.         return ("CKR_OK");
  453.         break;
  454.     case CKR_CANCEL:
  455.         return ("CKR_CANCEL");
  456.         break;
  457.     case CKR_HOST_MEMORY:
  458.         return ("CKR_HOST_MEMORY");
  459.         break;
  460.     case CKR_SLOT_ID_INVALID:
  461.         return ("CKR_SLOT_ID_INVALID");
  462.         break;
  463.     case CKR_GENERAL_ERROR:
  464.         return ("CKR_GENERAL_ERROR");
  465.         break;
  466.     case CKR_FUNCTION_FAILED:
  467.         return ("CKR_FUNCTION_FAILED");
  468.         break;
  469.     case CKR_ARGUMENTS_BAD:
  470.         return ("CKR_ARGUMENTS_BAD");
  471.         break;
  472.     case CKR_NO_EVENT:
  473.         return ("CKR_NO_EVENT");
  474.         break;
  475.     case CKR_NEED_TO_CREATE_THREADS:
  476.         return ("CKR_NEED_TO_CREATE_THREADS");
  477.         break;
  478.     case CKR_CANT_LOCK:
  479.         return ("CKR_CANT_LOCK");
  480.         break;
  481.     case CKR_ATTRIBUTE_READ_ONLY:
  482.         return ("CKR_ATTRIBUTE_READ_ONLY");
  483.         break;
  484.     case CKR_ATTRIBUTE_SENSITIVE:
  485.         return ("CKR_ATTRIBUTE_SENSITIVE");
  486.         break;
  487.     case CKR_ATTRIBUTE_TYPE_INVALID:
  488.         return ("CKR_ATTRIBUTE_TYPE_INVALID");
  489.         break;
  490.     case CKR_ATTRIBUTE_VALUE_INVALID:
  491.         return ("CKR_ATTRIBUTE_VALUE_INVALID");
  492.         break;
  493.     case CKR_DATA_INVALID:
  494.         return ("CKR_DATA_INVALID");
  495.         break;
  496.     case CKR_DATA_LEN_RANGE:
  497.         return ("CKR_DATA_LEN_RANGE");
  498.         break;
  499.     case CKR_DEVICE_ERROR:
  500.         return ("CKR_DEVICE_ERROR");
  501.         break;
  502.     case CKR_DEVICE_MEMORY:
  503.         return ("CKR_DEVICE_MEMORY");
  504.         break;
  505.     case CKR_DEVICE_REMOVED:
  506.         return ("CKR_DEVICE_REMOVED");
  507.         break;
  508.     case CKR_ENCRYPTED_DATA_INVALID:
  509.         return ("CKR_ENCRYPTED_DATA_INVALID");
  510.         break;
  511.     case CKR_ENCRYPTED_DATA_LEN_RANGE:
  512.         return ("CKR_ENCRYPTED_DATA_LEN_RANGE");
  513.         break;
  514.     case CKR_FUNCTION_CANCELED:
  515.         return ("CKR_FUNCTION_CANCELED");
  516.         break;
  517.     case CKR_FUNCTION_NOT_PARALLEL:
  518.         return ("CKR_FUNCTION_NOT_PARALLEL");
  519.         break;
  520.     case CKR_FUNCTION_NOT_SUPPORTED:
  521.         return ("CKR_FUNCTION_NOT_SUPPORTED");
  522.         break;
  523.     case CKR_KEY_HANDLE_INVALID:
  524.         return ("CKR_KEY_HANDLE_INVALID");
  525.         break;
  526.     case CKR_KEY_SIZE_RANGE:
  527.         return ("CKR_KEY_SIZE_RANGE");
  528.         break;
  529.     case CKR_KEY_TYPE_INCONSISTENT:
  530.         return ("CKR_KEY_TYPE_INCONSISTENT");
  531.         break;
  532.     case CKR_KEY_NOT_NEEDED:
  533.         return ("CKR_KEY_NOT_NEEDED");
  534.         break;
  535.     case CKR_KEY_CHANGED:
  536.         return ("CKR_KEY_CHANGED");
  537.         break;
  538.     case CKR_KEY_NEEDED:
  539.         return ("CKR_KEY_NEEDED");
  540.         break;
  541.     case CKR_KEY_INDIGESTIBLE:
  542.         return ("CKR_KEY_INDIGESTIBLE");
  543.         break;
  544.     case CKR_KEY_FUNCTION_NOT_PERMITTED:
  545.         return ("CKR_KEY_FUNCTION_NOT_PERMITTED");
  546.         break;
  547.     case CKR_KEY_NOT_WRAPPABLE:
  548.         return ("CKR_KEY_NOT_WRAPPABLE");
  549.         break;
  550.     case CKR_KEY_UNEXTRACTABLE:
  551.         return ("CKR_KEY_UNEXTRACTABLE");
  552.         break;
  553.     case CKR_MECHANISM_INVALID:
  554.         return ("CKR_MECHANISM_INVALID");
  555.         break;
  556.     case CKR_MECHANISM_PARAM_INVALID:
  557.         return ("CKR_MECHANISM_PARAM_INVALID");
  558.         break;
  559.     case CKR_OBJECT_HANDLE_INVALID:
  560.         return ("CKR_OBJECT_HANDLE_INVALID");
  561.         break;
  562.     case CKR_OPERATION_ACTIVE:
  563.         return ("CKR_OPERATION_ACTIVE");
  564.         break;
  565.     case CKR_OPERATION_NOT_INITIALIZED:
  566.         return ("CKR_OPERATION_NOT_INITIALIZED");
  567.         break;
  568.     case CKR_PIN_INCORRECT:
  569.         return ("CKR_PIN_INCORRECT");
  570.         break;
  571.     case CKR_PIN_INVALID:
  572.         return ("CKR_PIN_INVALID");
  573.         break;
  574.     case CKR_PIN_LEN_RANGE:
  575.         return ("CKR_PIN_LEN_RANGE");
  576.         break;
  577.     case CKR_PIN_EXPIRED:
  578.         return ("CKR_PIN_EXPIRED");
  579.         break;
  580.     case CKR_PIN_LOCKED:
  581.         return ("CKR_PIN_LOCKED");
  582.         break;
  583.     case CKR_SESSION_CLOSED:
  584.         return ("CKR_SESSION_CLOSED");
  585.         break;
  586.     case CKR_SESSION_COUNT:
  587.         return ("CKR_SESSION_COUNT");
  588.         break;
  589.     case CKR_SESSION_HANDLE_INVALID:
  590.         return ("CKR_SESSION_HANDLE_INVALID");
  591.         break;
  592.     case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
  593.         return ("CKR_SESSION_PARALLEL_NOT_SUPPORTED");
  594.         break;
  595.     case CKR_SESSION_READ_ONLY:
  596.         return ("CKR_SESSION_READ_ONLY");
  597.         break;
  598.     case CKR_SESSION_EXISTS:
  599.         return ("CKR_SESSION_EXISTS");
  600.         break;
  601.     case CKR_SESSION_READ_ONLY_EXISTS:
  602.         return ("CKR_SESSION_READ_ONLY_EXISTS");
  603.         break;
  604.     case CKR_SESSION_READ_WRITE_SO_EXISTS:
  605.         return ("CKR_SESSION_READ_WRITE_SO_EXISTS");
  606.         break;
  607.     case CKR_SIGNATURE_INVALID:
  608.         return ("CKR_SIGNATURE_INVALID");
  609.         break;
  610.     case CKR_SIGNATURE_LEN_RANGE:
  611.         return ("CKR_SIGNATURE_LEN_RANGE");
  612.         break;
  613.     case CKR_TEMPLATE_INCOMPLETE:
  614.         return ("CKR_TEMPLATE_INCOMPLETE");
  615.         break;
  616.     case CKR_TEMPLATE_INCONSISTENT:
  617.         return ("CKR_TEMPLATE_INCONSISTENT");
  618.         break;
  619.     case CKR_TOKEN_NOT_PRESENT:
  620.         return ("CKR_TOKEN_NOT_PRESENT");
  621.         break;
  622.     case CKR_TOKEN_NOT_RECOGNIZED:
  623.         return ("CKR_TOKEN_NOT_RECOGNIZED");
  624.         break;
  625.     case CKR_TOKEN_WRITE_PROTECTED:
  626.         return ("CKR_TOKEN_WRITE_PROTECTED");
  627.         break;
  628.     case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
  629.         return ("CKR_UNWRAPPING_KEY_HANDLE_INVALID");
  630.         break;
  631.     case CKR_UNWRAPPING_KEY_SIZE_RANGE:
  632.         return ("CKR_UNWRAPPING_KEY_SIZE_RANGE");
  633.         break;
  634.     case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
  635.         return ("CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT");
  636.         break;
  637.     case CKR_USER_ALREADY_LOGGED_IN:
  638.         return ("CKR_USER_ALREADY_LOGGED_IN");
  639.         break;
  640.     case CKR_USER_NOT_LOGGED_IN:
  641.         return ("CKR_USER_NOT_LOGGED_IN");
  642.         break;
  643.     case CKR_USER_PIN_NOT_INITIALIZED:
  644.         return ("CKR_USER_PIN_NOT_INITIALIZED");
  645.         break;
  646.     case CKR_USER_TYPE_INVALID:
  647.         return ("CKR_USER_TYPE_INVALID");
  648.         break;
  649.     case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
  650.         return ("CKR_USER_ANOTHER_ALREADY_LOGGED_IN");
  651.         break;
  652.     case CKR_USER_TOO_MANY_TYPES:
  653.         return ("CKR_USER_TOO_MANY_TYPES");
  654.         break;
  655.     case CKR_WRAPPED_KEY_INVALID:
  656.         return ("CKR_WRAPPED_KEY_INVALID");
  657.         break;
  658.     case CKR_WRAPPED_KEY_LEN_RANGE:
  659.         return ("CKR_WRAPPED_KEY_LEN_RANGE");
  660.         break;
  661.     case CKR_WRAPPING_KEY_HANDLE_INVALID:
  662.         return ("CKR_WRAPPING_KEY_HANDLE_INVALID");
  663.         break;
  664.     case CKR_WRAPPING_KEY_SIZE_RANGE:
  665.         return ("CKR_WRAPPING_KEY_SIZE_RANGE");
  666.         break;
  667.     case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
  668.         return ("CKR_WRAPPING_KEY_TYPE_INCONSISTENT");
  669.         break;
  670.     case CKR_RANDOM_SEED_NOT_SUPPORTED:
  671.         return ("CKR_RANDOM_SEED_NOT_SUPPORTED");
  672.         break;
  673.     case CKR_RANDOM_NO_RNG:
  674.         return ("CKR_RANDOM_NO_RNG");
  675.         break;
  676.     case CKR_DOMAIN_PARAMS_INVALID:
  677.         return ("CKR_DOMAIN_PARAMS_INVALID");
  678.         break;
  679.     case CKR_BUFFER_TOO_SMALL:
  680.         return ("CKR_BUFFER_TOO_SMALL");
  681.         break;
  682.     case CKR_SAVED_STATE_INVALID:
  683.         return ("CKR_SAVED_STATE_INVALID");
  684.         break;
  685.     case CKR_INFORMATION_SENSITIVE:
  686.         return ("CKR_INFORMATION_SENSITIVE");
  687.         break;
  688.     case CKR_STATE_UNSAVEABLE:
  689.         return ("CKR_STATE_UNSAVEABLE");
  690.         break;
  691.     case CKR_CRYPTOKI_NOT_INITIALIZED:
  692.         return ("CKR_CRYPTOKI_NOT_INITIALIZED");
  693.         break;
  694.     case CKR_CRYPTOKI_ALREADY_INITIALIZED:
  695.         return ("CKR_CRYPTOKI_ALREADY_INITIALIZED");
  696.         break;
  697.     case CKR_MUTEX_BAD:
  698.         return ("CKR_MUTEX_BAD");
  699.         break;
  700.     case CKR_MUTEX_NOT_LOCKED:
  701.         return ("CKR_MUTEX_NOT_LOCKED");
  702.         break;
  703.     case CKR_VENDOR_DEFINED:
  704.         return ("CKR_VENDOR_DEFINED");
  705.         break;
  706.     default:
  707.         /* rv not found */
  708.         snprintf(errstr, sizeof (errstr),
  709.             "Unknown return code: 0x%x", rv);
  710.         return (errstr);
  711.         break;
  712.     }
  713. }
  714. #endif