19126SWyllys.Ingersoll@Sun.COM /* 29126SWyllys.Ingersoll@Sun.COM * The Initial Developer of the Original Code is International 39126SWyllys.Ingersoll@Sun.COM * Business Machines Corporation. Portions created by IBM 49126SWyllys.Ingersoll@Sun.COM * Corporation are Copyright (C) 2005 International Business 59126SWyllys.Ingersoll@Sun.COM * Machines Corporation. All Rights Reserved. 69126SWyllys.Ingersoll@Sun.COM * 79126SWyllys.Ingersoll@Sun.COM * This program is free software; you can redistribute it and/or modify 89126SWyllys.Ingersoll@Sun.COM * it under the terms of the Common Public License as published by 99126SWyllys.Ingersoll@Sun.COM * IBM Corporation; either version 1 of the License, or (at your option) 109126SWyllys.Ingersoll@Sun.COM * any later version. 119126SWyllys.Ingersoll@Sun.COM * 129126SWyllys.Ingersoll@Sun.COM * This program is distributed in the hope that it will be useful, 139126SWyllys.Ingersoll@Sun.COM * but WITHOUT ANY WARRANTY; without even the implied warranty of 149126SWyllys.Ingersoll@Sun.COM * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 159126SWyllys.Ingersoll@Sun.COM * Common Public License for more details. 169126SWyllys.Ingersoll@Sun.COM * 179126SWyllys.Ingersoll@Sun.COM * You should have received a copy of the Common Public License 189126SWyllys.Ingersoll@Sun.COM * along with this program; if not, a copy can be viewed at 199126SWyllys.Ingersoll@Sun.COM * http://www.opensource.org/licenses/cpl1.0.php. 209126SWyllys.Ingersoll@Sun.COM */ 219126SWyllys.Ingersoll@Sun.COM 229126SWyllys.Ingersoll@Sun.COM /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ 239126SWyllys.Ingersoll@Sun.COM /* 249126SWyllys.Ingersoll@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 259126SWyllys.Ingersoll@Sun.COM * Use is subject to license terms. 269126SWyllys.Ingersoll@Sun.COM */ 279126SWyllys.Ingersoll@Sun.COM 289126SWyllys.Ingersoll@Sun.COM #include "tpmtok_int.h" 299126SWyllys.Ingersoll@Sun.COM 309126SWyllys.Ingersoll@Sun.COM static CK_SLOT_INFO slot_info; 319126SWyllys.Ingersoll@Sun.COM 329126SWyllys.Ingersoll@Sun.COM // Function: dlist_add_as_first() 339126SWyllys.Ingersoll@Sun.COM // 349126SWyllys.Ingersoll@Sun.COM // Adds the specified node to the start of the list 359126SWyllys.Ingersoll@Sun.COM // 369126SWyllys.Ingersoll@Sun.COM // Returns: pointer to the start of the list 379126SWyllys.Ingersoll@Sun.COM // 389126SWyllys.Ingersoll@Sun.COM DL_NODE * 399126SWyllys.Ingersoll@Sun.COM dlist_add_as_first(DL_NODE *list, void *data) 409126SWyllys.Ingersoll@Sun.COM { 419126SWyllys.Ingersoll@Sun.COM DL_NODE *node = NULL; 429126SWyllys.Ingersoll@Sun.COM 439126SWyllys.Ingersoll@Sun.COM if (! data) 449126SWyllys.Ingersoll@Sun.COM return (list); 459126SWyllys.Ingersoll@Sun.COM node = (DL_NODE *)malloc(sizeof (DL_NODE)); 469126SWyllys.Ingersoll@Sun.COM if (! node) 479126SWyllys.Ingersoll@Sun.COM return (NULL); 489126SWyllys.Ingersoll@Sun.COM node->data = data; 499126SWyllys.Ingersoll@Sun.COM node->prev = NULL; 509126SWyllys.Ingersoll@Sun.COM node->next = list; 519126SWyllys.Ingersoll@Sun.COM if (list) 529126SWyllys.Ingersoll@Sun.COM list->prev = node; 539126SWyllys.Ingersoll@Sun.COM 549126SWyllys.Ingersoll@Sun.COM return (node); 559126SWyllys.Ingersoll@Sun.COM } 569126SWyllys.Ingersoll@Sun.COM 579126SWyllys.Ingersoll@Sun.COM 589126SWyllys.Ingersoll@Sun.COM // Function: dlist_add_as_last() 599126SWyllys.Ingersoll@Sun.COM // 609126SWyllys.Ingersoll@Sun.COM // Adds the specified node to the end of the list 619126SWyllys.Ingersoll@Sun.COM // 629126SWyllys.Ingersoll@Sun.COM // Returns: pointer to the start of the list 639126SWyllys.Ingersoll@Sun.COM // 649126SWyllys.Ingersoll@Sun.COM DL_NODE * 659126SWyllys.Ingersoll@Sun.COM dlist_add_as_last(DL_NODE *list, void *data) { 669126SWyllys.Ingersoll@Sun.COM DL_NODE *node = NULL; 679126SWyllys.Ingersoll@Sun.COM 689126SWyllys.Ingersoll@Sun.COM if (! data) 699126SWyllys.Ingersoll@Sun.COM return (list); 709126SWyllys.Ingersoll@Sun.COM node = (DL_NODE *)malloc(sizeof (DL_NODE)); 719126SWyllys.Ingersoll@Sun.COM if (! node) 729126SWyllys.Ingersoll@Sun.COM return (NULL); 739126SWyllys.Ingersoll@Sun.COM node->data = data; 749126SWyllys.Ingersoll@Sun.COM node->next = NULL; 759126SWyllys.Ingersoll@Sun.COM 769126SWyllys.Ingersoll@Sun.COM if (! list) { 779126SWyllys.Ingersoll@Sun.COM node->prev = NULL; 789126SWyllys.Ingersoll@Sun.COM return (node); 799126SWyllys.Ingersoll@Sun.COM } else { 809126SWyllys.Ingersoll@Sun.COM DL_NODE *temp = dlist_get_last(list); 819126SWyllys.Ingersoll@Sun.COM temp->next = node; 829126SWyllys.Ingersoll@Sun.COM node->prev = temp; 839126SWyllys.Ingersoll@Sun.COM 849126SWyllys.Ingersoll@Sun.COM return (list); 859126SWyllys.Ingersoll@Sun.COM } 869126SWyllys.Ingersoll@Sun.COM } 879126SWyllys.Ingersoll@Sun.COM 889126SWyllys.Ingersoll@Sun.COM 899126SWyllys.Ingersoll@Sun.COM // Function: dlist_find() 909126SWyllys.Ingersoll@Sun.COM // 919126SWyllys.Ingersoll@Sun.COM DL_NODE * 929126SWyllys.Ingersoll@Sun.COM dlist_find(DL_NODE *list, void *data) 939126SWyllys.Ingersoll@Sun.COM { 949126SWyllys.Ingersoll@Sun.COM DL_NODE *node = list; 959126SWyllys.Ingersoll@Sun.COM 969126SWyllys.Ingersoll@Sun.COM while (node && node->data != data) 979126SWyllys.Ingersoll@Sun.COM node = node->next; 989126SWyllys.Ingersoll@Sun.COM 999126SWyllys.Ingersoll@Sun.COM return (node); 1009126SWyllys.Ingersoll@Sun.COM } 1019126SWyllys.Ingersoll@Sun.COM 1029126SWyllys.Ingersoll@Sun.COM 1039126SWyllys.Ingersoll@Sun.COM // Function: dlist_get_first() 1049126SWyllys.Ingersoll@Sun.COM // 1059126SWyllys.Ingersoll@Sun.COM // Returns the last node in the list or NULL if list is empty 1069126SWyllys.Ingersoll@Sun.COM // 1079126SWyllys.Ingersoll@Sun.COM DL_NODE * 1089126SWyllys.Ingersoll@Sun.COM dlist_get_first(DL_NODE *list) { 1099126SWyllys.Ingersoll@Sun.COM DL_NODE *temp = list; 1109126SWyllys.Ingersoll@Sun.COM 1119126SWyllys.Ingersoll@Sun.COM if (! list) 1129126SWyllys.Ingersoll@Sun.COM return (NULL); 1139126SWyllys.Ingersoll@Sun.COM while (temp->prev != NULL) 1149126SWyllys.Ingersoll@Sun.COM temp = temp->prev; 1159126SWyllys.Ingersoll@Sun.COM 1169126SWyllys.Ingersoll@Sun.COM return (temp); 1179126SWyllys.Ingersoll@Sun.COM } 1189126SWyllys.Ingersoll@Sun.COM 1199126SWyllys.Ingersoll@Sun.COM 1209126SWyllys.Ingersoll@Sun.COM // Function: dlist_get_last() 1219126SWyllys.Ingersoll@Sun.COM // 1229126SWyllys.Ingersoll@Sun.COM // Returns the last node in the list or NULL if list is empty 1239126SWyllys.Ingersoll@Sun.COM // 1249126SWyllys.Ingersoll@Sun.COM DL_NODE * 1259126SWyllys.Ingersoll@Sun.COM dlist_get_last(DL_NODE *list) { 1269126SWyllys.Ingersoll@Sun.COM DL_NODE *temp = list; 1279126SWyllys.Ingersoll@Sun.COM 1289126SWyllys.Ingersoll@Sun.COM if (! list) 1299126SWyllys.Ingersoll@Sun.COM return (NULL); 1309126SWyllys.Ingersoll@Sun.COM while (temp->next != NULL) 1319126SWyllys.Ingersoll@Sun.COM temp = temp->next; 1329126SWyllys.Ingersoll@Sun.COM 1339126SWyllys.Ingersoll@Sun.COM return (temp); 1349126SWyllys.Ingersoll@Sun.COM } 1359126SWyllys.Ingersoll@Sun.COM 1369126SWyllys.Ingersoll@Sun.COM 1379126SWyllys.Ingersoll@Sun.COM // 1389126SWyllys.Ingersoll@Sun.COM // 1399126SWyllys.Ingersoll@Sun.COM CK_ULONG 1409126SWyllys.Ingersoll@Sun.COM dlist_length(DL_NODE *list) { 1419126SWyllys.Ingersoll@Sun.COM DL_NODE *temp = list; 1429126SWyllys.Ingersoll@Sun.COM CK_ULONG len = 0; 1439126SWyllys.Ingersoll@Sun.COM 1449126SWyllys.Ingersoll@Sun.COM while (temp) { 1459126SWyllys.Ingersoll@Sun.COM len++; 1469126SWyllys.Ingersoll@Sun.COM temp = temp->next; 1479126SWyllys.Ingersoll@Sun.COM } 1489126SWyllys.Ingersoll@Sun.COM 1499126SWyllys.Ingersoll@Sun.COM return (len); 1509126SWyllys.Ingersoll@Sun.COM } 1519126SWyllys.Ingersoll@Sun.COM 1529126SWyllys.Ingersoll@Sun.COM 1539126SWyllys.Ingersoll@Sun.COM // 1549126SWyllys.Ingersoll@Sun.COM // 1559126SWyllys.Ingersoll@Sun.COM DL_NODE * 1569126SWyllys.Ingersoll@Sun.COM dlist_next(DL_NODE *node) 1579126SWyllys.Ingersoll@Sun.COM { 1589126SWyllys.Ingersoll@Sun.COM if (! node) 1599126SWyllys.Ingersoll@Sun.COM return (NULL); 1609126SWyllys.Ingersoll@Sun.COM return (node->next); 1619126SWyllys.Ingersoll@Sun.COM } 1629126SWyllys.Ingersoll@Sun.COM 1639126SWyllys.Ingersoll@Sun.COM 1649126SWyllys.Ingersoll@Sun.COM // 1659126SWyllys.Ingersoll@Sun.COM // 1669126SWyllys.Ingersoll@Sun.COM DL_NODE * 1679126SWyllys.Ingersoll@Sun.COM dlist_prev(DL_NODE *node) { 1689126SWyllys.Ingersoll@Sun.COM if (! node) 1699126SWyllys.Ingersoll@Sun.COM return (NULL); 1709126SWyllys.Ingersoll@Sun.COM return (node->prev); 1719126SWyllys.Ingersoll@Sun.COM } 1729126SWyllys.Ingersoll@Sun.COM 1739126SWyllys.Ingersoll@Sun.COM 1749126SWyllys.Ingersoll@Sun.COM // 1759126SWyllys.Ingersoll@Sun.COM // 1769126SWyllys.Ingersoll@Sun.COM void 1779126SWyllys.Ingersoll@Sun.COM dlist_purge(DL_NODE *list) { 1789126SWyllys.Ingersoll@Sun.COM DL_NODE *node; 1799126SWyllys.Ingersoll@Sun.COM 1809126SWyllys.Ingersoll@Sun.COM if (! list) 1819126SWyllys.Ingersoll@Sun.COM return; 1829126SWyllys.Ingersoll@Sun.COM do { 1839126SWyllys.Ingersoll@Sun.COM node = list->next; 1849126SWyllys.Ingersoll@Sun.COM free(list); 1859126SWyllys.Ingersoll@Sun.COM list = node; 1869126SWyllys.Ingersoll@Sun.COM } while (list); 1879126SWyllys.Ingersoll@Sun.COM } 1889126SWyllys.Ingersoll@Sun.COM 1899126SWyllys.Ingersoll@Sun.COM // Function: dlist_remove_node() 1909126SWyllys.Ingersoll@Sun.COM // 1919126SWyllys.Ingersoll@Sun.COM // Attempts to remove the specified node from the list. The caller is 1929126SWyllys.Ingersoll@Sun.COM // responsible for freeing the data associated with the node prior to 1939126SWyllys.Ingersoll@Sun.COM // calling this routine 1949126SWyllys.Ingersoll@Sun.COM // 1959126SWyllys.Ingersoll@Sun.COM DL_NODE * 1969126SWyllys.Ingersoll@Sun.COM dlist_remove_node(DL_NODE *list, DL_NODE *node) { 1979126SWyllys.Ingersoll@Sun.COM DL_NODE *temp = list; 1989126SWyllys.Ingersoll@Sun.COM 1999126SWyllys.Ingersoll@Sun.COM if (! list || ! node) 2009126SWyllys.Ingersoll@Sun.COM return (NULL); 2019126SWyllys.Ingersoll@Sun.COM // special case: removing head of the list 2029126SWyllys.Ingersoll@Sun.COM // 2039126SWyllys.Ingersoll@Sun.COM if (list == node) { 2049126SWyllys.Ingersoll@Sun.COM temp = list->next; 2059126SWyllys.Ingersoll@Sun.COM if (temp) 2069126SWyllys.Ingersoll@Sun.COM temp->prev = NULL; 2079126SWyllys.Ingersoll@Sun.COM 2089126SWyllys.Ingersoll@Sun.COM free(list); 2099126SWyllys.Ingersoll@Sun.COM return (temp); 2109126SWyllys.Ingersoll@Sun.COM } 2119126SWyllys.Ingersoll@Sun.COM 2129126SWyllys.Ingersoll@Sun.COM // we have no guarantee that the node is in the list 2139126SWyllys.Ingersoll@Sun.COM // so search through the list to find it 2149126SWyllys.Ingersoll@Sun.COM // 2159126SWyllys.Ingersoll@Sun.COM while ((temp != NULL) && (temp->next != node)) 2169126SWyllys.Ingersoll@Sun.COM temp = temp->next; 2179126SWyllys.Ingersoll@Sun.COM 2189126SWyllys.Ingersoll@Sun.COM if (temp != NULL) { 2199126SWyllys.Ingersoll@Sun.COM DL_NODE *next = node->next; 2209126SWyllys.Ingersoll@Sun.COM 2219126SWyllys.Ingersoll@Sun.COM temp->next = next; 2229126SWyllys.Ingersoll@Sun.COM if (next) 2239126SWyllys.Ingersoll@Sun.COM next->prev = temp; 2249126SWyllys.Ingersoll@Sun.COM 2259126SWyllys.Ingersoll@Sun.COM free(node); 2269126SWyllys.Ingersoll@Sun.COM } 2279126SWyllys.Ingersoll@Sun.COM 2289126SWyllys.Ingersoll@Sun.COM return (list); 2299126SWyllys.Ingersoll@Sun.COM } 2309126SWyllys.Ingersoll@Sun.COM 2319126SWyllys.Ingersoll@Sun.COM extern void set_perm(int); 2329126SWyllys.Ingersoll@Sun.COM 2339126SWyllys.Ingersoll@Sun.COM void 2349126SWyllys.Ingersoll@Sun.COM CreateXProcLock(void *xproc) 2359126SWyllys.Ingersoll@Sun.COM { 2369126SWyllys.Ingersoll@Sun.COM pthread_mutexattr_t mtxattr; 2379126SWyllys.Ingersoll@Sun.COM 2389126SWyllys.Ingersoll@Sun.COM (void) pthread_mutexattr_init(&mtxattr); 2399126SWyllys.Ingersoll@Sun.COM (void) pthread_mutexattr_setpshared(&mtxattr, PTHREAD_PROCESS_SHARED); 2409126SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_init((pthread_mutex_t *)xproc, &mtxattr); 2419126SWyllys.Ingersoll@Sun.COM } 2429126SWyllys.Ingersoll@Sun.COM 2439126SWyllys.Ingersoll@Sun.COM int 2449126SWyllys.Ingersoll@Sun.COM DestroyXProcLock(void *xproc) 2459126SWyllys.Ingersoll@Sun.COM { 2469126SWyllys.Ingersoll@Sun.COM return (pthread_mutex_destroy((pthread_mutex_t *)xproc)); 2479126SWyllys.Ingersoll@Sun.COM } 2489126SWyllys.Ingersoll@Sun.COM 2499126SWyllys.Ingersoll@Sun.COM int 2509126SWyllys.Ingersoll@Sun.COM XProcLock(void *xproc) 2519126SWyllys.Ingersoll@Sun.COM { 2529126SWyllys.Ingersoll@Sun.COM return (pthread_mutex_lock((pthread_mutex_t *)xproc)); 2539126SWyllys.Ingersoll@Sun.COM } 2549126SWyllys.Ingersoll@Sun.COM 2559126SWyllys.Ingersoll@Sun.COM int 2569126SWyllys.Ingersoll@Sun.COM XProcUnLock(void *xproc) 2579126SWyllys.Ingersoll@Sun.COM { 2589126SWyllys.Ingersoll@Sun.COM return (pthread_mutex_unlock((pthread_mutex_t *)xproc)); 2599126SWyllys.Ingersoll@Sun.COM } 2609126SWyllys.Ingersoll@Sun.COM 2619126SWyllys.Ingersoll@Sun.COM // 2629126SWyllys.Ingersoll@Sun.COM // 2639126SWyllys.Ingersoll@Sun.COM // is_attribute_defined() 2649126SWyllys.Ingersoll@Sun.COM // 2659126SWyllys.Ingersoll@Sun.COM // determine whether the specified attribute is defined by Cryptoki 2669126SWyllys.Ingersoll@Sun.COM // 2679126SWyllys.Ingersoll@Sun.COM CK_BBOOL 2689126SWyllys.Ingersoll@Sun.COM is_attribute_defined(CK_ATTRIBUTE_TYPE type) 2699126SWyllys.Ingersoll@Sun.COM { 2709126SWyllys.Ingersoll@Sun.COM if (type >= CKA_VENDOR_DEFINED) 2719126SWyllys.Ingersoll@Sun.COM return (TRUE); 2729126SWyllys.Ingersoll@Sun.COM switch (type) { 2739126SWyllys.Ingersoll@Sun.COM case CKA_CLASS: 2749126SWyllys.Ingersoll@Sun.COM case CKA_TOKEN: 2759126SWyllys.Ingersoll@Sun.COM case CKA_PRIVATE: 2769126SWyllys.Ingersoll@Sun.COM case CKA_LABEL: 2779126SWyllys.Ingersoll@Sun.COM case CKA_APPLICATION: 2789126SWyllys.Ingersoll@Sun.COM case CKA_VALUE: 2799126SWyllys.Ingersoll@Sun.COM case CKA_CERTIFICATE_TYPE: 2809126SWyllys.Ingersoll@Sun.COM case CKA_ISSUER: 2819126SWyllys.Ingersoll@Sun.COM case CKA_SERIAL_NUMBER: 2829126SWyllys.Ingersoll@Sun.COM case CKA_KEY_TYPE: 2839126SWyllys.Ingersoll@Sun.COM case CKA_SUBJECT: 2849126SWyllys.Ingersoll@Sun.COM case CKA_ID: 2859126SWyllys.Ingersoll@Sun.COM case CKA_SENSITIVE: 2869126SWyllys.Ingersoll@Sun.COM case CKA_ENCRYPT: 2879126SWyllys.Ingersoll@Sun.COM case CKA_DECRYPT: 2889126SWyllys.Ingersoll@Sun.COM case CKA_WRAP: 2899126SWyllys.Ingersoll@Sun.COM case CKA_UNWRAP: 2909126SWyllys.Ingersoll@Sun.COM case CKA_SIGN: 2919126SWyllys.Ingersoll@Sun.COM case CKA_SIGN_RECOVER: 2929126SWyllys.Ingersoll@Sun.COM case CKA_VERIFY: 2939126SWyllys.Ingersoll@Sun.COM case CKA_VERIFY_RECOVER: 2949126SWyllys.Ingersoll@Sun.COM case CKA_DERIVE: 2959126SWyllys.Ingersoll@Sun.COM case CKA_START_DATE: 2969126SWyllys.Ingersoll@Sun.COM case CKA_END_DATE: 2979126SWyllys.Ingersoll@Sun.COM case CKA_MODULUS: 2989126SWyllys.Ingersoll@Sun.COM case CKA_MODULUS_BITS: 2999126SWyllys.Ingersoll@Sun.COM case CKA_PUBLIC_EXPONENT: 3009126SWyllys.Ingersoll@Sun.COM case CKA_PRIVATE_EXPONENT: 3019126SWyllys.Ingersoll@Sun.COM case CKA_PRIME_1: 3029126SWyllys.Ingersoll@Sun.COM case CKA_PRIME_2: 3039126SWyllys.Ingersoll@Sun.COM case CKA_EXPONENT_1: 3049126SWyllys.Ingersoll@Sun.COM case CKA_EXPONENT_2: 3059126SWyllys.Ingersoll@Sun.COM case CKA_COEFFICIENT: 3069126SWyllys.Ingersoll@Sun.COM case CKA_PRIME: 3079126SWyllys.Ingersoll@Sun.COM case CKA_SUBPRIME: 3089126SWyllys.Ingersoll@Sun.COM case CKA_BASE: 3099126SWyllys.Ingersoll@Sun.COM case CKA_VALUE_BITS: 3109126SWyllys.Ingersoll@Sun.COM case CKA_VALUE_LEN: 3119126SWyllys.Ingersoll@Sun.COM case CKA_EXTRACTABLE: 3129126SWyllys.Ingersoll@Sun.COM case CKA_LOCAL: 3139126SWyllys.Ingersoll@Sun.COM case CKA_NEVER_EXTRACTABLE: 3149126SWyllys.Ingersoll@Sun.COM case CKA_ALWAYS_SENSITIVE: 3159126SWyllys.Ingersoll@Sun.COM case CKA_MODIFIABLE: 3169126SWyllys.Ingersoll@Sun.COM case CKA_ECDSA_PARAMS: 3179126SWyllys.Ingersoll@Sun.COM case CKA_EC_POINT: 3189126SWyllys.Ingersoll@Sun.COM case CKA_HW_FEATURE_TYPE: 3199126SWyllys.Ingersoll@Sun.COM case CKA_HAS_RESET: 3209126SWyllys.Ingersoll@Sun.COM case CKA_RESET_ON_INIT: 3219126SWyllys.Ingersoll@Sun.COM case CKA_KEY_GEN_MECHANISM: 3229126SWyllys.Ingersoll@Sun.COM case CKA_PRIME_BITS: 3239126SWyllys.Ingersoll@Sun.COM case CKA_SUBPRIME_BITS: 3249126SWyllys.Ingersoll@Sun.COM case CKA_OBJECT_ID: 3259126SWyllys.Ingersoll@Sun.COM case CKA_AC_ISSUER: 3269126SWyllys.Ingersoll@Sun.COM case CKA_OWNER: 3279126SWyllys.Ingersoll@Sun.COM case CKA_ATTR_TYPES: 3289126SWyllys.Ingersoll@Sun.COM case CKA_TRUSTED: 3299126SWyllys.Ingersoll@Sun.COM return (TRUE); 3309126SWyllys.Ingersoll@Sun.COM } 3319126SWyllys.Ingersoll@Sun.COM 3329126SWyllys.Ingersoll@Sun.COM return (FALSE); 3339126SWyllys.Ingersoll@Sun.COM } 3349126SWyllys.Ingersoll@Sun.COM 3359126SWyllys.Ingersoll@Sun.COM void 3369126SWyllys.Ingersoll@Sun.COM init_slot_info(TOKEN_DATA *td) 3379126SWyllys.Ingersoll@Sun.COM { 3389126SWyllys.Ingersoll@Sun.COM /* 3399126SWyllys.Ingersoll@Sun.COM * Much of the token info is pulled from the TPM itself when 3409126SWyllys.Ingersoll@Sun.COM * C_Initialize is called. 3419126SWyllys.Ingersoll@Sun.COM */ 3429126SWyllys.Ingersoll@Sun.COM (void) (void) memset(&slot_info.slotDescription, ' ', 3439126SWyllys.Ingersoll@Sun.COM sizeof (slot_info.slotDescription) - 1); 3449126SWyllys.Ingersoll@Sun.COM (void) (void) memset(&slot_info.manufacturerID, ' ', 3459126SWyllys.Ingersoll@Sun.COM sizeof (slot_info.manufacturerID) - 1); 3469126SWyllys.Ingersoll@Sun.COM 3479126SWyllys.Ingersoll@Sun.COM (void) (void) memcpy(&slot_info.slotDescription, 3489126SWyllys.Ingersoll@Sun.COM "PKCS#11 Interface for TPM", 3499126SWyllys.Ingersoll@Sun.COM strlen("PKCS#11 Interface for TPM")); 3509126SWyllys.Ingersoll@Sun.COM 3519126SWyllys.Ingersoll@Sun.COM (void) (void) memcpy(&slot_info.manufacturerID, 3529126SWyllys.Ingersoll@Sun.COM td->token_info.manufacturerID, 3539126SWyllys.Ingersoll@Sun.COM strlen((char *)td->token_info.manufacturerID)); 3549126SWyllys.Ingersoll@Sun.COM 3559126SWyllys.Ingersoll@Sun.COM slot_info.hardwareVersion = nv_token_data->token_info.hardwareVersion; 3569126SWyllys.Ingersoll@Sun.COM slot_info.firmwareVersion = nv_token_data->token_info.firmwareVersion; 3579126SWyllys.Ingersoll@Sun.COM slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT; 3589126SWyllys.Ingersoll@Sun.COM } 3599126SWyllys.Ingersoll@Sun.COM 3609126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 3619126SWyllys.Ingersoll@Sun.COM void 3629126SWyllys.Ingersoll@Sun.COM copy_slot_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR sinfo) 3639126SWyllys.Ingersoll@Sun.COM { 3649126SWyllys.Ingersoll@Sun.COM if (sinfo != NULL) 3659126SWyllys.Ingersoll@Sun.COM (void) memcpy(sinfo, &slot_info, sizeof (slot_info)); 3669126SWyllys.Ingersoll@Sun.COM } 3679126SWyllys.Ingersoll@Sun.COM 3689126SWyllys.Ingersoll@Sun.COM static void 3699126SWyllys.Ingersoll@Sun.COM init_token_info(TOKEN_DATA *td) 3709126SWyllys.Ingersoll@Sun.COM { 3719126SWyllys.Ingersoll@Sun.COM CK_TOKEN_INFO *token_info = NULL; 3729126SWyllys.Ingersoll@Sun.COM 3739126SWyllys.Ingersoll@Sun.COM token_info = &td->token_info; 3749126SWyllys.Ingersoll@Sun.COM 3759126SWyllys.Ingersoll@Sun.COM (void) memset(token_info->model, ' ', 3769126SWyllys.Ingersoll@Sun.COM sizeof (token_info->model)); 3779126SWyllys.Ingersoll@Sun.COM (void) memset(token_info->serialNumber, ' ', 3789126SWyllys.Ingersoll@Sun.COM sizeof (token_info->serialNumber)); 3799126SWyllys.Ingersoll@Sun.COM 3809126SWyllys.Ingersoll@Sun.COM // 3819126SWyllys.Ingersoll@Sun.COM // I don't see any API support for changing the clock so 3829126SWyllys.Ingersoll@Sun.COM // we will use the system clock for the token's clock. 3839126SWyllys.Ingersoll@Sun.COM // 3849126SWyllys.Ingersoll@Sun.COM token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN | 3859126SWyllys.Ingersoll@Sun.COM CKF_SO_PIN_TO_BE_CHANGED; 3869126SWyllys.Ingersoll@Sun.COM 3879126SWyllys.Ingersoll@Sun.COM if (memcmp(td->user_pin_sha, "00000000000000000000", 3889126SWyllys.Ingersoll@Sun.COM SHA1_DIGEST_LENGTH) != 0) 3899126SWyllys.Ingersoll@Sun.COM token_info->flags |= CKF_USER_PIN_INITIALIZED; 3909126SWyllys.Ingersoll@Sun.COM else 3919126SWyllys.Ingersoll@Sun.COM token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED; 3929126SWyllys.Ingersoll@Sun.COM 3939126SWyllys.Ingersoll@Sun.COM // For the release, we made these 3949126SWyllys.Ingersoll@Sun.COM // values as CK_UNAVAILABLE_INFORMATION 3959126SWyllys.Ingersoll@Sun.COM // 3969126SWyllys.Ingersoll@Sun.COM token_info->ulMaxSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 3979126SWyllys.Ingersoll@Sun.COM token_info->ulSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 3989126SWyllys.Ingersoll@Sun.COM token_info->ulMaxRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 3999126SWyllys.Ingersoll@Sun.COM token_info->ulRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 4009126SWyllys.Ingersoll@Sun.COM token_info->ulMaxPinLen = MAX_PIN_LEN; 4019126SWyllys.Ingersoll@Sun.COM token_info->ulMinPinLen = MIN_PIN_LEN; 4029126SWyllys.Ingersoll@Sun.COM token_info->ulTotalPublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 4039126SWyllys.Ingersoll@Sun.COM token_info->ulFreePublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 4049126SWyllys.Ingersoll@Sun.COM token_info->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 4059126SWyllys.Ingersoll@Sun.COM token_info->ulFreePrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; 4069126SWyllys.Ingersoll@Sun.COM 4079126SWyllys.Ingersoll@Sun.COM (void) memset(token_info->utcTime, ' ', sizeof (token_info->utcTime)); 4089126SWyllys.Ingersoll@Sun.COM } 4099126SWyllys.Ingersoll@Sun.COM 4109126SWyllys.Ingersoll@Sun.COM CK_RV 4119126SWyllys.Ingersoll@Sun.COM init_token_data(TSS_HCONTEXT hContext, TOKEN_DATA *td) { 4129126SWyllys.Ingersoll@Sun.COM CK_RV rc; 4139126SWyllys.Ingersoll@Sun.COM 4149126SWyllys.Ingersoll@Sun.COM (void) memset((char *)td, 0, sizeof (nv_token_data)); 4159126SWyllys.Ingersoll@Sun.COM // 4169126SWyllys.Ingersoll@Sun.COM // the normal USER pin is not set when the token is initialized 4179126SWyllys.Ingersoll@Sun.COM // 4189126SWyllys.Ingersoll@Sun.COM (void) memcpy(td->user_pin_sha, "00000000000000000000", 4199126SWyllys.Ingersoll@Sun.COM SHA1_DIGEST_LENGTH); 4209126SWyllys.Ingersoll@Sun.COM (void) memcpy(td->so_pin_sha, default_so_pin_sha, 4219126SWyllys.Ingersoll@Sun.COM SHA1_DIGEST_LENGTH); 4229126SWyllys.Ingersoll@Sun.COM 4239126SWyllys.Ingersoll@Sun.COM (void) memset(user_pin_md5, 0x0, MD5_DIGEST_LENGTH); 4249126SWyllys.Ingersoll@Sun.COM (void) memcpy(so_pin_md5, default_so_pin_md5, MD5_DIGEST_LENGTH); 4259126SWyllys.Ingersoll@Sun.COM 4269126SWyllys.Ingersoll@Sun.COM (void) memcpy(td->next_token_object_name, "00000000", 8); 4279126SWyllys.Ingersoll@Sun.COM 4289126SWyllys.Ingersoll@Sun.COM td->tweak_vector.allow_key_mods = TRUE; 4299126SWyllys.Ingersoll@Sun.COM 4309126SWyllys.Ingersoll@Sun.COM init_token_info(td); 4319126SWyllys.Ingersoll@Sun.COM 4329126SWyllys.Ingersoll@Sun.COM rc = token_get_tpm_info(hContext, td); 4339126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) 4349126SWyllys.Ingersoll@Sun.COM return (rc); 4359126SWyllys.Ingersoll@Sun.COM 4369126SWyllys.Ingersoll@Sun.COM rc = save_token_data(td); 4379126SWyllys.Ingersoll@Sun.COM 4389126SWyllys.Ingersoll@Sun.COM return (rc); 4399126SWyllys.Ingersoll@Sun.COM } 4409126SWyllys.Ingersoll@Sun.COM 4419126SWyllys.Ingersoll@Sun.COM // Function: compute_next_token_obj_name() 4429126SWyllys.Ingersoll@Sun.COM // 4439126SWyllys.Ingersoll@Sun.COM // Given a token object name (8 bytes in the range [0 - 9A - Z]) 4449126SWyllys.Ingersoll@Sun.COM // increment by one adjusting as necessary 4459126SWyllys.Ingersoll@Sun.COM // 4469126SWyllys.Ingersoll@Sun.COM // This gives us a namespace of 36^8 = 2, 821, 109, 907, 456 4479126SWyllys.Ingersoll@Sun.COM // objects before wrapping around. 4489126SWyllys.Ingersoll@Sun.COM // 4499126SWyllys.Ingersoll@Sun.COM CK_RV 4509126SWyllys.Ingersoll@Sun.COM compute_next_token_obj_name(CK_BYTE *current, CK_BYTE *next) { 4519126SWyllys.Ingersoll@Sun.COM int val[8]; 4529126SWyllys.Ingersoll@Sun.COM int i; 4539126SWyllys.Ingersoll@Sun.COM 4549126SWyllys.Ingersoll@Sun.COM if (! current || ! next) { 4559126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED); 4569126SWyllys.Ingersoll@Sun.COM } 4579126SWyllys.Ingersoll@Sun.COM // Convert to integral base 36 4589126SWyllys.Ingersoll@Sun.COM // 4599126SWyllys.Ingersoll@Sun.COM for (i = 0; i < 8; i++) { 4609126SWyllys.Ingersoll@Sun.COM if (current[i] >= '0' && current[i] <= '9') 4619126SWyllys.Ingersoll@Sun.COM val[i] = current[i] - '0'; 4629126SWyllys.Ingersoll@Sun.COM 4639126SWyllys.Ingersoll@Sun.COM if (current[i] >= 'A' && current[i] <= 'Z') 4649126SWyllys.Ingersoll@Sun.COM val[i] = current[i] - 'A' + 10; 4659126SWyllys.Ingersoll@Sun.COM } 4669126SWyllys.Ingersoll@Sun.COM 4679126SWyllys.Ingersoll@Sun.COM val[0]++; 4689126SWyllys.Ingersoll@Sun.COM 4699126SWyllys.Ingersoll@Sun.COM i = 0; 4709126SWyllys.Ingersoll@Sun.COM 4719126SWyllys.Ingersoll@Sun.COM while (val[i] > 35) { 4729126SWyllys.Ingersoll@Sun.COM val[i] = 0; 4739126SWyllys.Ingersoll@Sun.COM 4749126SWyllys.Ingersoll@Sun.COM if (i + 1 < 8) { 4759126SWyllys.Ingersoll@Sun.COM val[i + 1]++; 4769126SWyllys.Ingersoll@Sun.COM i++; 4779126SWyllys.Ingersoll@Sun.COM } else { 4789126SWyllys.Ingersoll@Sun.COM val[0]++; 4799126SWyllys.Ingersoll@Sun.COM i = 0; // start pass 2 4809126SWyllys.Ingersoll@Sun.COM } 4819126SWyllys.Ingersoll@Sun.COM } 4829126SWyllys.Ingersoll@Sun.COM 4839126SWyllys.Ingersoll@Sun.COM // now, convert back to [0 - 9A - Z] 4849126SWyllys.Ingersoll@Sun.COM // 4859126SWyllys.Ingersoll@Sun.COM for (i = 0; i < 8; i++) { 4869126SWyllys.Ingersoll@Sun.COM if (val[i] < 10) 4879126SWyllys.Ingersoll@Sun.COM next[i] = '0' + val[i]; 4889126SWyllys.Ingersoll@Sun.COM else 4899126SWyllys.Ingersoll@Sun.COM next[i] = 'A' + val[i] - 10; 4909126SWyllys.Ingersoll@Sun.COM } 4919126SWyllys.Ingersoll@Sun.COM 4929126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 4939126SWyllys.Ingersoll@Sun.COM } 4949126SWyllys.Ingersoll@Sun.COM 4959126SWyllys.Ingersoll@Sun.COM 4969126SWyllys.Ingersoll@Sun.COM // 4979126SWyllys.Ingersoll@Sun.COM // 4989126SWyllys.Ingersoll@Sun.COM CK_RV 4999126SWyllys.Ingersoll@Sun.COM build_attribute(CK_ATTRIBUTE_TYPE type, 5009126SWyllys.Ingersoll@Sun.COM CK_BYTE *data, 5019126SWyllys.Ingersoll@Sun.COM CK_ULONG data_len, 5029126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE **attrib) { 5039126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE *attr = NULL; 5049126SWyllys.Ingersoll@Sun.COM 5059126SWyllys.Ingersoll@Sun.COM attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + data_len); 5069126SWyllys.Ingersoll@Sun.COM if (! attr) { 5079126SWyllys.Ingersoll@Sun.COM return (CKR_DEVICE_MEMORY); 5089126SWyllys.Ingersoll@Sun.COM } 5099126SWyllys.Ingersoll@Sun.COM attr->type = type; 5109126SWyllys.Ingersoll@Sun.COM attr->ulValueLen = data_len; 5119126SWyllys.Ingersoll@Sun.COM 5129126SWyllys.Ingersoll@Sun.COM if (data_len > 0) { 5139126SWyllys.Ingersoll@Sun.COM attr->pValue = (CK_BYTE *)attr + sizeof (CK_ATTRIBUTE); 5149126SWyllys.Ingersoll@Sun.COM (void) memcpy(attr->pValue, data, data_len); 5159126SWyllys.Ingersoll@Sun.COM } 5169126SWyllys.Ingersoll@Sun.COM else 5179126SWyllys.Ingersoll@Sun.COM attr->pValue = NULL; 5189126SWyllys.Ingersoll@Sun.COM 5199126SWyllys.Ingersoll@Sun.COM *attrib = attr; 5209126SWyllys.Ingersoll@Sun.COM 5219126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 5229126SWyllys.Ingersoll@Sun.COM } 5239126SWyllys.Ingersoll@Sun.COM 5249126SWyllys.Ingersoll@Sun.COM CK_RV 5259126SWyllys.Ingersoll@Sun.COM add_pkcs_padding(CK_BYTE * ptr, 526*9651SWyllys.Ingersoll@Sun.COM UINT32 block_size, 527*9651SWyllys.Ingersoll@Sun.COM UINT32 data_len, 528*9651SWyllys.Ingersoll@Sun.COM UINT32 total_len) 5299126SWyllys.Ingersoll@Sun.COM { 530*9651SWyllys.Ingersoll@Sun.COM UINT32 i, pad_len; 5319126SWyllys.Ingersoll@Sun.COM CK_BYTE pad_value; 5329126SWyllys.Ingersoll@Sun.COM 5339126SWyllys.Ingersoll@Sun.COM pad_len = block_size - (data_len % block_size); 5349126SWyllys.Ingersoll@Sun.COM pad_value = (CK_BYTE)pad_len; 5359126SWyllys.Ingersoll@Sun.COM 5369126SWyllys.Ingersoll@Sun.COM if (data_len + pad_len > total_len) { 5379126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED); 5389126SWyllys.Ingersoll@Sun.COM } 5399126SWyllys.Ingersoll@Sun.COM for (i = 0; i < pad_len; i++) 540*9651SWyllys.Ingersoll@Sun.COM ptr[i] = pad_value; 5419126SWyllys.Ingersoll@Sun.COM 5429126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 5439126SWyllys.Ingersoll@Sun.COM } 5449126SWyllys.Ingersoll@Sun.COM 5459126SWyllys.Ingersoll@Sun.COM CK_RV 546*9651SWyllys.Ingersoll@Sun.COM strip_pkcs_padding( 547*9651SWyllys.Ingersoll@Sun.COM CK_BYTE *ptr, 548*9651SWyllys.Ingersoll@Sun.COM UINT32 total_len, 549*9651SWyllys.Ingersoll@Sun.COM UINT32 *data_len) 550*9651SWyllys.Ingersoll@Sun.COM { 5519126SWyllys.Ingersoll@Sun.COM CK_BYTE pad_value; 5529126SWyllys.Ingersoll@Sun.COM 5539126SWyllys.Ingersoll@Sun.COM pad_value = ptr[total_len - 1]; 5549126SWyllys.Ingersoll@Sun.COM 555*9651SWyllys.Ingersoll@Sun.COM /* We have 'pad_value' bytes of 'pad_value' appended to the end */ 556*9651SWyllys.Ingersoll@Sun.COM *data_len = total_len - pad_value; 5579126SWyllys.Ingersoll@Sun.COM 5589126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 5599126SWyllys.Ingersoll@Sun.COM } 5609126SWyllys.Ingersoll@Sun.COM 5619126SWyllys.Ingersoll@Sun.COM CK_RV 5629126SWyllys.Ingersoll@Sun.COM remove_leading_zeros(CK_ATTRIBUTE *attr) 5639126SWyllys.Ingersoll@Sun.COM { 5649126SWyllys.Ingersoll@Sun.COM CK_BYTE *ptr = NULL; 5659126SWyllys.Ingersoll@Sun.COM CK_ULONG new_len, i; 5669126SWyllys.Ingersoll@Sun.COM 5679126SWyllys.Ingersoll@Sun.COM ptr = attr->pValue; 5689126SWyllys.Ingersoll@Sun.COM 5699126SWyllys.Ingersoll@Sun.COM for (i = 0; i < attr->ulValueLen; i++) { 5709126SWyllys.Ingersoll@Sun.COM if (ptr[i] != 0x0) 5719126SWyllys.Ingersoll@Sun.COM break; 5729126SWyllys.Ingersoll@Sun.COM } 5739126SWyllys.Ingersoll@Sun.COM 5749126SWyllys.Ingersoll@Sun.COM new_len = attr->ulValueLen - i; 5759126SWyllys.Ingersoll@Sun.COM 5769126SWyllys.Ingersoll@Sun.COM (void) memcpy(ptr, ptr + i, new_len); 5779126SWyllys.Ingersoll@Sun.COM attr->ulValueLen = new_len; 5789126SWyllys.Ingersoll@Sun.COM 5799126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 5809126SWyllys.Ingersoll@Sun.COM } 5819126SWyllys.Ingersoll@Sun.COM 5829126SWyllys.Ingersoll@Sun.COM CK_RV 5839126SWyllys.Ingersoll@Sun.COM parity_is_odd(CK_BYTE b) { 5849126SWyllys.Ingersoll@Sun.COM b = ((b >> 4) ^ b) & 0x0f; 5859126SWyllys.Ingersoll@Sun.COM b = ((b >> 2) ^ b) & 0x03; 5869126SWyllys.Ingersoll@Sun.COM b = ((b >> 1) ^ b) & 0x01; 5879126SWyllys.Ingersoll@Sun.COM 5889126SWyllys.Ingersoll@Sun.COM if (b == 1) 5899126SWyllys.Ingersoll@Sun.COM return (TRUE); 5909126SWyllys.Ingersoll@Sun.COM else 5919126SWyllys.Ingersoll@Sun.COM return (FALSE); 5929126SWyllys.Ingersoll@Sun.COM } 5939126SWyllys.Ingersoll@Sun.COM 5949126SWyllys.Ingersoll@Sun.COM CK_RV 5959126SWyllys.Ingersoll@Sun.COM attach_shm() { 5969126SWyllys.Ingersoll@Sun.COM if (global_shm != NULL) 5979126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 5989126SWyllys.Ingersoll@Sun.COM 5999126SWyllys.Ingersoll@Sun.COM global_shm = (LW_SHM_TYPE *)malloc(sizeof (LW_SHM_TYPE)); 6009126SWyllys.Ingersoll@Sun.COM if (global_shm == NULL) { 6019126SWyllys.Ingersoll@Sun.COM return (CKR_HOST_MEMORY); 6029126SWyllys.Ingersoll@Sun.COM } 6039126SWyllys.Ingersoll@Sun.COM CreateXProcLock(&global_shm->mutex); 6049126SWyllys.Ingersoll@Sun.COM 6059126SWyllys.Ingersoll@Sun.COM xproclock = (void *)&global_shm->mutex; 6069126SWyllys.Ingersoll@Sun.COM (void) XProcLock(xproclock); 6079126SWyllys.Ingersoll@Sun.COM 6089126SWyllys.Ingersoll@Sun.COM global_shm->num_publ_tok_obj = 0; 6099126SWyllys.Ingersoll@Sun.COM global_shm->num_priv_tok_obj = 0; 6109126SWyllys.Ingersoll@Sun.COM 6119126SWyllys.Ingersoll@Sun.COM (void) memset(&global_shm->publ_tok_objs, 0x0, 6129126SWyllys.Ingersoll@Sun.COM 2048 * sizeof (TOK_OBJ_ENTRY)); 6139126SWyllys.Ingersoll@Sun.COM (void) memset(&global_shm->priv_tok_objs, 0x0, 6149126SWyllys.Ingersoll@Sun.COM 2048 * sizeof (TOK_OBJ_ENTRY)); 6159126SWyllys.Ingersoll@Sun.COM 6169126SWyllys.Ingersoll@Sun.COM (void) XProcUnLock(xproclock); 6179126SWyllys.Ingersoll@Sun.COM 6189126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 6199126SWyllys.Ingersoll@Sun.COM } 6209126SWyllys.Ingersoll@Sun.COM 6219126SWyllys.Ingersoll@Sun.COM CK_RV 6229126SWyllys.Ingersoll@Sun.COM detach_shm() 6239126SWyllys.Ingersoll@Sun.COM { 6249126SWyllys.Ingersoll@Sun.COM if (global_shm != NULL) { 6259126SWyllys.Ingersoll@Sun.COM free(global_shm); 6269126SWyllys.Ingersoll@Sun.COM global_shm = NULL; 6279126SWyllys.Ingersoll@Sun.COM } 6289126SWyllys.Ingersoll@Sun.COM 6299126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 6309126SWyllys.Ingersoll@Sun.COM } 6319126SWyllys.Ingersoll@Sun.COM 6329126SWyllys.Ingersoll@Sun.COM CK_RV 6339126SWyllys.Ingersoll@Sun.COM compute_sha(CK_BYTE *data, 634*9651SWyllys.Ingersoll@Sun.COM CK_ULONG_32 len, 6359126SWyllys.Ingersoll@Sun.COM CK_BYTE * hash) 6369126SWyllys.Ingersoll@Sun.COM { 6379126SWyllys.Ingersoll@Sun.COM SHA1_CTX ctx; 6389126SWyllys.Ingersoll@Sun.COM 6399126SWyllys.Ingersoll@Sun.COM SHA1Init(&ctx); 6409126SWyllys.Ingersoll@Sun.COM 6419126SWyllys.Ingersoll@Sun.COM SHA1Update(&ctx, data, len); 6429126SWyllys.Ingersoll@Sun.COM 6439126SWyllys.Ingersoll@Sun.COM SHA1Final(hash, &ctx); 6449126SWyllys.Ingersoll@Sun.COM return (CKR_OK); 6459126SWyllys.Ingersoll@Sun.COM } 646