xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/utility.c (revision 10346:9f0b25e42dc5)
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 *
dlist_add_as_first(DL_NODE * list,void * data)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 *
dlist_add_as_last(DL_NODE * list,void * data)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 *
dlist_find(DL_NODE * list,void * data)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 *
dlist_get_first(DL_NODE * list)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 *
dlist_get_last(DL_NODE * list)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
dlist_length(DL_NODE * list)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 *
dlist_next(DL_NODE * 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 *
dlist_prev(DL_NODE * 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
dlist_purge(DL_NODE * list)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 *
dlist_remove_node(DL_NODE * list,DL_NODE * 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
CreateXProcLock(void * xproc)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
DestroyXProcLock(void * xproc)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
XProcLock(void * xproc)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
XProcUnLock(void * xproc)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
is_attribute_defined(CK_ATTRIBUTE_TYPE type)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
init_slot_info(TOKEN_DATA * td)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
copy_slot_info(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR sinfo)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
init_token_info(TOKEN_DATA * td)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
init_token_data(TSS_HCONTEXT hContext,TOKEN_DATA * td)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
compute_next_token_obj_name(CK_BYTE * current,CK_BYTE * next)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
build_attribute(CK_ATTRIBUTE_TYPE type,CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** attrib)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
add_pkcs_padding(CK_BYTE * ptr,UINT32 block_size,UINT32 data_len,UINT32 total_len)5259126SWyllys.Ingersoll@Sun.COM add_pkcs_padding(CK_BYTE  * ptr,
5269651SWyllys.Ingersoll@Sun.COM 	UINT32   block_size,
5279651SWyllys.Ingersoll@Sun.COM 	UINT32   data_len,
5289651SWyllys.Ingersoll@Sun.COM 	UINT32   total_len)
5299126SWyllys.Ingersoll@Sun.COM {
5309651SWyllys.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++)
5409651SWyllys.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
strip_pkcs_padding(CK_BYTE * ptr,UINT32 total_len,UINT32 * data_len)5469651SWyllys.Ingersoll@Sun.COM strip_pkcs_padding(
5479651SWyllys.Ingersoll@Sun.COM 	CK_BYTE *ptr,
5489651SWyllys.Ingersoll@Sun.COM 	UINT32  total_len,
5499651SWyllys.Ingersoll@Sun.COM 	UINT32  *data_len)
5509651SWyllys.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 
5559651SWyllys.Ingersoll@Sun.COM 	/* We have 'pad_value' bytes of 'pad_value' appended to the end */
5569651SWyllys.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
remove_leading_zeros(CK_ATTRIBUTE * attr)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
parity_is_odd(CK_BYTE b)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
attach_shm()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 
599*10346Swyllys.ingersoll@sun.com 	global_shm = (LW_SHM_TYPE *)calloc(1, 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 
6079126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
6089126SWyllys.Ingersoll@Sun.COM }
6099126SWyllys.Ingersoll@Sun.COM 
6109126SWyllys.Ingersoll@Sun.COM CK_RV
detach_shm()6119126SWyllys.Ingersoll@Sun.COM detach_shm()
6129126SWyllys.Ingersoll@Sun.COM {
6139126SWyllys.Ingersoll@Sun.COM 	if (global_shm != NULL) {
6149126SWyllys.Ingersoll@Sun.COM 		free(global_shm);
6159126SWyllys.Ingersoll@Sun.COM 		global_shm = NULL;
6169126SWyllys.Ingersoll@Sun.COM 	}
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
compute_sha(CK_BYTE * data,CK_ULONG_32 len,CK_BYTE * hash)6229126SWyllys.Ingersoll@Sun.COM compute_sha(CK_BYTE  *data,
6239651SWyllys.Ingersoll@Sun.COM 	CK_ULONG_32   len,
6249126SWyllys.Ingersoll@Sun.COM 	CK_BYTE  * hash)
6259126SWyllys.Ingersoll@Sun.COM {
6269126SWyllys.Ingersoll@Sun.COM 	SHA1_CTX	ctx;
6279126SWyllys.Ingersoll@Sun.COM 
6289126SWyllys.Ingersoll@Sun.COM 	SHA1Init(&ctx);
6299126SWyllys.Ingersoll@Sun.COM 
6309126SWyllys.Ingersoll@Sun.COM 	SHA1Update(&ctx, data, len);
6319126SWyllys.Ingersoll@Sun.COM 
6329126SWyllys.Ingersoll@Sun.COM 	SHA1Final(hash, &ctx);
6339126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
6349126SWyllys.Ingersoll@Sun.COM }
635