xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/utility.c (revision 9126:6acea8ac53c8)
1*9126SWyllys.Ingersoll@Sun.COM /*
2*9126SWyllys.Ingersoll@Sun.COM  * The Initial Developer of the Original Code is International
3*9126SWyllys.Ingersoll@Sun.COM  * Business Machines Corporation. Portions created by IBM
4*9126SWyllys.Ingersoll@Sun.COM  * Corporation are Copyright (C) 2005 International Business
5*9126SWyllys.Ingersoll@Sun.COM  * Machines Corporation. All Rights Reserved.
6*9126SWyllys.Ingersoll@Sun.COM  *
7*9126SWyllys.Ingersoll@Sun.COM  * This program is free software; you can redistribute it and/or modify
8*9126SWyllys.Ingersoll@Sun.COM  * it under the terms of the Common Public License as published by
9*9126SWyllys.Ingersoll@Sun.COM  * IBM Corporation; either version 1 of the License, or (at your option)
10*9126SWyllys.Ingersoll@Sun.COM  * any later version.
11*9126SWyllys.Ingersoll@Sun.COM  *
12*9126SWyllys.Ingersoll@Sun.COM  * This program is distributed in the hope that it will be useful,
13*9126SWyllys.Ingersoll@Sun.COM  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*9126SWyllys.Ingersoll@Sun.COM  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*9126SWyllys.Ingersoll@Sun.COM  * Common Public License for more details.
16*9126SWyllys.Ingersoll@Sun.COM  *
17*9126SWyllys.Ingersoll@Sun.COM  * You should have received a copy of the Common Public License
18*9126SWyllys.Ingersoll@Sun.COM  * along with this program; if not, a copy can be viewed at
19*9126SWyllys.Ingersoll@Sun.COM  * http://www.opensource.org/licenses/cpl1.0.php.
20*9126SWyllys.Ingersoll@Sun.COM  */
21*9126SWyllys.Ingersoll@Sun.COM 
22*9126SWyllys.Ingersoll@Sun.COM /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
23*9126SWyllys.Ingersoll@Sun.COM /*
24*9126SWyllys.Ingersoll@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25*9126SWyllys.Ingersoll@Sun.COM  * Use is subject to license terms.
26*9126SWyllys.Ingersoll@Sun.COM  */
27*9126SWyllys.Ingersoll@Sun.COM 
28*9126SWyllys.Ingersoll@Sun.COM #include "tpmtok_int.h"
29*9126SWyllys.Ingersoll@Sun.COM 
30*9126SWyllys.Ingersoll@Sun.COM static CK_SLOT_INFO    slot_info;
31*9126SWyllys.Ingersoll@Sun.COM 
32*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_add_as_first()
33*9126SWyllys.Ingersoll@Sun.COM //
34*9126SWyllys.Ingersoll@Sun.COM // Adds the specified node to the start of the list
35*9126SWyllys.Ingersoll@Sun.COM //
36*9126SWyllys.Ingersoll@Sun.COM // Returns:  pointer to the start of the list
37*9126SWyllys.Ingersoll@Sun.COM //
38*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
39*9126SWyllys.Ingersoll@Sun.COM dlist_add_as_first(DL_NODE *list, void *data)
40*9126SWyllys.Ingersoll@Sun.COM {
41*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *node = NULL;
42*9126SWyllys.Ingersoll@Sun.COM 
43*9126SWyllys.Ingersoll@Sun.COM 	if (! data)
44*9126SWyllys.Ingersoll@Sun.COM 		return (list);
45*9126SWyllys.Ingersoll@Sun.COM 	node = (DL_NODE *)malloc(sizeof (DL_NODE));
46*9126SWyllys.Ingersoll@Sun.COM 	if (! node)
47*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
48*9126SWyllys.Ingersoll@Sun.COM 	node->data = data;
49*9126SWyllys.Ingersoll@Sun.COM 	node->prev = NULL;
50*9126SWyllys.Ingersoll@Sun.COM 	node->next = list;
51*9126SWyllys.Ingersoll@Sun.COM 	if (list)
52*9126SWyllys.Ingersoll@Sun.COM 		list->prev = node;
53*9126SWyllys.Ingersoll@Sun.COM 
54*9126SWyllys.Ingersoll@Sun.COM 	return (node);
55*9126SWyllys.Ingersoll@Sun.COM }
56*9126SWyllys.Ingersoll@Sun.COM 
57*9126SWyllys.Ingersoll@Sun.COM 
58*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_add_as_last()
59*9126SWyllys.Ingersoll@Sun.COM //
60*9126SWyllys.Ingersoll@Sun.COM // Adds the specified node to the end of the list
61*9126SWyllys.Ingersoll@Sun.COM //
62*9126SWyllys.Ingersoll@Sun.COM // Returns:  pointer to the start of the list
63*9126SWyllys.Ingersoll@Sun.COM //
64*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
65*9126SWyllys.Ingersoll@Sun.COM dlist_add_as_last(DL_NODE *list, void *data) {
66*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *node = NULL;
67*9126SWyllys.Ingersoll@Sun.COM 
68*9126SWyllys.Ingersoll@Sun.COM 	if (! data)
69*9126SWyllys.Ingersoll@Sun.COM 		return (list);
70*9126SWyllys.Ingersoll@Sun.COM 	node = (DL_NODE *)malloc(sizeof (DL_NODE));
71*9126SWyllys.Ingersoll@Sun.COM 	if (! node)
72*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
73*9126SWyllys.Ingersoll@Sun.COM 	node->data = data;
74*9126SWyllys.Ingersoll@Sun.COM 	node->next = NULL;
75*9126SWyllys.Ingersoll@Sun.COM 
76*9126SWyllys.Ingersoll@Sun.COM 	if (! list) {
77*9126SWyllys.Ingersoll@Sun.COM 		node->prev = NULL;
78*9126SWyllys.Ingersoll@Sun.COM 		return (node);
79*9126SWyllys.Ingersoll@Sun.COM 	} else {
80*9126SWyllys.Ingersoll@Sun.COM 		DL_NODE *temp = dlist_get_last(list);
81*9126SWyllys.Ingersoll@Sun.COM 		temp->next = node;
82*9126SWyllys.Ingersoll@Sun.COM 		node->prev = temp;
83*9126SWyllys.Ingersoll@Sun.COM 
84*9126SWyllys.Ingersoll@Sun.COM 		return (list);
85*9126SWyllys.Ingersoll@Sun.COM 	}
86*9126SWyllys.Ingersoll@Sun.COM }
87*9126SWyllys.Ingersoll@Sun.COM 
88*9126SWyllys.Ingersoll@Sun.COM 
89*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_find()
90*9126SWyllys.Ingersoll@Sun.COM //
91*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
92*9126SWyllys.Ingersoll@Sun.COM dlist_find(DL_NODE *list, void *data)
93*9126SWyllys.Ingersoll@Sun.COM {
94*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *node = list;
95*9126SWyllys.Ingersoll@Sun.COM 
96*9126SWyllys.Ingersoll@Sun.COM 	while (node && node->data != data)
97*9126SWyllys.Ingersoll@Sun.COM 	node = node->next;
98*9126SWyllys.Ingersoll@Sun.COM 
99*9126SWyllys.Ingersoll@Sun.COM 	return (node);
100*9126SWyllys.Ingersoll@Sun.COM }
101*9126SWyllys.Ingersoll@Sun.COM 
102*9126SWyllys.Ingersoll@Sun.COM 
103*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_get_first()
104*9126SWyllys.Ingersoll@Sun.COM //
105*9126SWyllys.Ingersoll@Sun.COM // Returns the last node in the list or NULL if list is empty
106*9126SWyllys.Ingersoll@Sun.COM //
107*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
108*9126SWyllys.Ingersoll@Sun.COM dlist_get_first(DL_NODE *list) {
109*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *temp = list;
110*9126SWyllys.Ingersoll@Sun.COM 
111*9126SWyllys.Ingersoll@Sun.COM 	if (! list)
112*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
113*9126SWyllys.Ingersoll@Sun.COM 	while (temp->prev != NULL)
114*9126SWyllys.Ingersoll@Sun.COM 	temp = temp->prev;
115*9126SWyllys.Ingersoll@Sun.COM 
116*9126SWyllys.Ingersoll@Sun.COM 	return (temp);
117*9126SWyllys.Ingersoll@Sun.COM }
118*9126SWyllys.Ingersoll@Sun.COM 
119*9126SWyllys.Ingersoll@Sun.COM 
120*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_get_last()
121*9126SWyllys.Ingersoll@Sun.COM //
122*9126SWyllys.Ingersoll@Sun.COM // Returns the last node in the list or NULL if list is empty
123*9126SWyllys.Ingersoll@Sun.COM //
124*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
125*9126SWyllys.Ingersoll@Sun.COM dlist_get_last(DL_NODE *list) {
126*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *temp = list;
127*9126SWyllys.Ingersoll@Sun.COM 
128*9126SWyllys.Ingersoll@Sun.COM 	if (! list)
129*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
130*9126SWyllys.Ingersoll@Sun.COM 	while (temp->next != NULL)
131*9126SWyllys.Ingersoll@Sun.COM 	temp = temp->next;
132*9126SWyllys.Ingersoll@Sun.COM 
133*9126SWyllys.Ingersoll@Sun.COM 	return (temp);
134*9126SWyllys.Ingersoll@Sun.COM }
135*9126SWyllys.Ingersoll@Sun.COM 
136*9126SWyllys.Ingersoll@Sun.COM 
137*9126SWyllys.Ingersoll@Sun.COM //
138*9126SWyllys.Ingersoll@Sun.COM //
139*9126SWyllys.Ingersoll@Sun.COM CK_ULONG
140*9126SWyllys.Ingersoll@Sun.COM dlist_length(DL_NODE *list) {
141*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE  *temp = list;
142*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  len  = 0;
143*9126SWyllys.Ingersoll@Sun.COM 
144*9126SWyllys.Ingersoll@Sun.COM 	while (temp) {
145*9126SWyllys.Ingersoll@Sun.COM 		len++;
146*9126SWyllys.Ingersoll@Sun.COM 		temp = temp->next;
147*9126SWyllys.Ingersoll@Sun.COM 	}
148*9126SWyllys.Ingersoll@Sun.COM 
149*9126SWyllys.Ingersoll@Sun.COM 	return (len);
150*9126SWyllys.Ingersoll@Sun.COM }
151*9126SWyllys.Ingersoll@Sun.COM 
152*9126SWyllys.Ingersoll@Sun.COM 
153*9126SWyllys.Ingersoll@Sun.COM //
154*9126SWyllys.Ingersoll@Sun.COM //
155*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
156*9126SWyllys.Ingersoll@Sun.COM dlist_next(DL_NODE *node)
157*9126SWyllys.Ingersoll@Sun.COM {
158*9126SWyllys.Ingersoll@Sun.COM 	if (! node)
159*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
160*9126SWyllys.Ingersoll@Sun.COM 	return (node->next);
161*9126SWyllys.Ingersoll@Sun.COM }
162*9126SWyllys.Ingersoll@Sun.COM 
163*9126SWyllys.Ingersoll@Sun.COM 
164*9126SWyllys.Ingersoll@Sun.COM //
165*9126SWyllys.Ingersoll@Sun.COM //
166*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
167*9126SWyllys.Ingersoll@Sun.COM dlist_prev(DL_NODE *node) {
168*9126SWyllys.Ingersoll@Sun.COM 	if (! node)
169*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
170*9126SWyllys.Ingersoll@Sun.COM 	return (node->prev);
171*9126SWyllys.Ingersoll@Sun.COM }
172*9126SWyllys.Ingersoll@Sun.COM 
173*9126SWyllys.Ingersoll@Sun.COM 
174*9126SWyllys.Ingersoll@Sun.COM //
175*9126SWyllys.Ingersoll@Sun.COM //
176*9126SWyllys.Ingersoll@Sun.COM void
177*9126SWyllys.Ingersoll@Sun.COM dlist_purge(DL_NODE *list) {
178*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *node;
179*9126SWyllys.Ingersoll@Sun.COM 
180*9126SWyllys.Ingersoll@Sun.COM 	if (! list)
181*9126SWyllys.Ingersoll@Sun.COM 		return;
182*9126SWyllys.Ingersoll@Sun.COM 	do {
183*9126SWyllys.Ingersoll@Sun.COM 		node = list->next;
184*9126SWyllys.Ingersoll@Sun.COM 		free(list);
185*9126SWyllys.Ingersoll@Sun.COM 		list = node;
186*9126SWyllys.Ingersoll@Sun.COM 	} while (list);
187*9126SWyllys.Ingersoll@Sun.COM }
188*9126SWyllys.Ingersoll@Sun.COM 
189*9126SWyllys.Ingersoll@Sun.COM // Function:  dlist_remove_node()
190*9126SWyllys.Ingersoll@Sun.COM //
191*9126SWyllys.Ingersoll@Sun.COM // Attempts to remove the specified node from the list.  The caller is
192*9126SWyllys.Ingersoll@Sun.COM // responsible for freeing the data associated with the node prior to
193*9126SWyllys.Ingersoll@Sun.COM // calling this routine
194*9126SWyllys.Ingersoll@Sun.COM //
195*9126SWyllys.Ingersoll@Sun.COM DL_NODE *
196*9126SWyllys.Ingersoll@Sun.COM dlist_remove_node(DL_NODE *list, DL_NODE *node) {
197*9126SWyllys.Ingersoll@Sun.COM 	DL_NODE *temp  = list;
198*9126SWyllys.Ingersoll@Sun.COM 
199*9126SWyllys.Ingersoll@Sun.COM 	if (! list || ! node)
200*9126SWyllys.Ingersoll@Sun.COM 		return (NULL);
201*9126SWyllys.Ingersoll@Sun.COM 	// special case:  removing head of the list
202*9126SWyllys.Ingersoll@Sun.COM 	//
203*9126SWyllys.Ingersoll@Sun.COM 	if (list == node) {
204*9126SWyllys.Ingersoll@Sun.COM 		temp = list->next;
205*9126SWyllys.Ingersoll@Sun.COM 		if (temp)
206*9126SWyllys.Ingersoll@Sun.COM 			temp->prev = NULL;
207*9126SWyllys.Ingersoll@Sun.COM 
208*9126SWyllys.Ingersoll@Sun.COM 		free(list);
209*9126SWyllys.Ingersoll@Sun.COM 		return (temp);
210*9126SWyllys.Ingersoll@Sun.COM 	}
211*9126SWyllys.Ingersoll@Sun.COM 
212*9126SWyllys.Ingersoll@Sun.COM 	// we have no guarantee that the node is in the list
213*9126SWyllys.Ingersoll@Sun.COM 	// so search through the list to find it
214*9126SWyllys.Ingersoll@Sun.COM 	//
215*9126SWyllys.Ingersoll@Sun.COM 	while ((temp != NULL) && (temp->next != node))
216*9126SWyllys.Ingersoll@Sun.COM 	temp = temp->next;
217*9126SWyllys.Ingersoll@Sun.COM 
218*9126SWyllys.Ingersoll@Sun.COM 	if (temp != NULL) {
219*9126SWyllys.Ingersoll@Sun.COM 		DL_NODE *next = node->next;
220*9126SWyllys.Ingersoll@Sun.COM 
221*9126SWyllys.Ingersoll@Sun.COM 		temp->next = next;
222*9126SWyllys.Ingersoll@Sun.COM 		if (next)
223*9126SWyllys.Ingersoll@Sun.COM 			next->prev = temp;
224*9126SWyllys.Ingersoll@Sun.COM 
225*9126SWyllys.Ingersoll@Sun.COM 		free(node);
226*9126SWyllys.Ingersoll@Sun.COM 	}
227*9126SWyllys.Ingersoll@Sun.COM 
228*9126SWyllys.Ingersoll@Sun.COM 	return (list);
229*9126SWyllys.Ingersoll@Sun.COM }
230*9126SWyllys.Ingersoll@Sun.COM 
231*9126SWyllys.Ingersoll@Sun.COM extern void set_perm(int);
232*9126SWyllys.Ingersoll@Sun.COM 
233*9126SWyllys.Ingersoll@Sun.COM void
234*9126SWyllys.Ingersoll@Sun.COM CreateXProcLock(void *xproc)
235*9126SWyllys.Ingersoll@Sun.COM {
236*9126SWyllys.Ingersoll@Sun.COM 	pthread_mutexattr_t  mtxattr;
237*9126SWyllys.Ingersoll@Sun.COM 
238*9126SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutexattr_init(&mtxattr);
239*9126SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutexattr_setpshared(&mtxattr, PTHREAD_PROCESS_SHARED);
240*9126SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_init((pthread_mutex_t *)xproc, &mtxattr);
241*9126SWyllys.Ingersoll@Sun.COM }
242*9126SWyllys.Ingersoll@Sun.COM 
243*9126SWyllys.Ingersoll@Sun.COM int
244*9126SWyllys.Ingersoll@Sun.COM DestroyXProcLock(void *xproc)
245*9126SWyllys.Ingersoll@Sun.COM {
246*9126SWyllys.Ingersoll@Sun.COM 	return (pthread_mutex_destroy((pthread_mutex_t *)xproc));
247*9126SWyllys.Ingersoll@Sun.COM }
248*9126SWyllys.Ingersoll@Sun.COM 
249*9126SWyllys.Ingersoll@Sun.COM int
250*9126SWyllys.Ingersoll@Sun.COM XProcLock(void *xproc)
251*9126SWyllys.Ingersoll@Sun.COM {
252*9126SWyllys.Ingersoll@Sun.COM 	return (pthread_mutex_lock((pthread_mutex_t *)xproc));
253*9126SWyllys.Ingersoll@Sun.COM }
254*9126SWyllys.Ingersoll@Sun.COM 
255*9126SWyllys.Ingersoll@Sun.COM int
256*9126SWyllys.Ingersoll@Sun.COM XProcUnLock(void *xproc)
257*9126SWyllys.Ingersoll@Sun.COM {
258*9126SWyllys.Ingersoll@Sun.COM 	return (pthread_mutex_unlock((pthread_mutex_t *)xproc));
259*9126SWyllys.Ingersoll@Sun.COM }
260*9126SWyllys.Ingersoll@Sun.COM 
261*9126SWyllys.Ingersoll@Sun.COM //
262*9126SWyllys.Ingersoll@Sun.COM //
263*9126SWyllys.Ingersoll@Sun.COM // is_attribute_defined()
264*9126SWyllys.Ingersoll@Sun.COM //
265*9126SWyllys.Ingersoll@Sun.COM // determine whether the specified attribute is defined by Cryptoki
266*9126SWyllys.Ingersoll@Sun.COM //
267*9126SWyllys.Ingersoll@Sun.COM CK_BBOOL
268*9126SWyllys.Ingersoll@Sun.COM is_attribute_defined(CK_ATTRIBUTE_TYPE type)
269*9126SWyllys.Ingersoll@Sun.COM {
270*9126SWyllys.Ingersoll@Sun.COM 	if (type >= CKA_VENDOR_DEFINED)
271*9126SWyllys.Ingersoll@Sun.COM 		return (TRUE);
272*9126SWyllys.Ingersoll@Sun.COM 	switch (type) {
273*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_CLASS:
274*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_TOKEN:
275*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIVATE:
276*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_LABEL:
277*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_APPLICATION:
278*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_VALUE:
279*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_CERTIFICATE_TYPE:
280*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ISSUER:
281*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SERIAL_NUMBER:
282*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_KEY_TYPE:
283*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SUBJECT:
284*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ID:
285*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SENSITIVE:
286*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ENCRYPT:
287*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_DECRYPT:
288*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_WRAP:
289*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_UNWRAP:
290*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SIGN:
291*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SIGN_RECOVER:
292*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_VERIFY:
293*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_VERIFY_RECOVER:
294*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_DERIVE:
295*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_START_DATE:
296*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_END_DATE:
297*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_MODULUS:
298*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_MODULUS_BITS:
299*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PUBLIC_EXPONENT:
300*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIVATE_EXPONENT:
301*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIME_1:
302*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIME_2:
303*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_EXPONENT_1:
304*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_EXPONENT_2:
305*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_COEFFICIENT:
306*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIME:
307*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SUBPRIME:
308*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_BASE:
309*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_VALUE_BITS:
310*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_VALUE_LEN:
311*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_EXTRACTABLE:
312*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_LOCAL:
313*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_NEVER_EXTRACTABLE:
314*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ALWAYS_SENSITIVE:
315*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_MODIFIABLE:
316*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ECDSA_PARAMS:
317*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_EC_POINT:
318*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_HW_FEATURE_TYPE:
319*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_HAS_RESET:
320*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_RESET_ON_INIT:
321*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_KEY_GEN_MECHANISM:
322*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_PRIME_BITS:
323*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_SUBPRIME_BITS:
324*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_OBJECT_ID:
325*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_AC_ISSUER:
326*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_OWNER:
327*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_ATTR_TYPES:
328*9126SWyllys.Ingersoll@Sun.COM 		case  CKA_TRUSTED:
329*9126SWyllys.Ingersoll@Sun.COM 		return (TRUE);
330*9126SWyllys.Ingersoll@Sun.COM 	}
331*9126SWyllys.Ingersoll@Sun.COM 
332*9126SWyllys.Ingersoll@Sun.COM 	return (FALSE);
333*9126SWyllys.Ingersoll@Sun.COM }
334*9126SWyllys.Ingersoll@Sun.COM 
335*9126SWyllys.Ingersoll@Sun.COM void
336*9126SWyllys.Ingersoll@Sun.COM init_slot_info(TOKEN_DATA *td)
337*9126SWyllys.Ingersoll@Sun.COM {
338*9126SWyllys.Ingersoll@Sun.COM 	/*
339*9126SWyllys.Ingersoll@Sun.COM 	 * Much of the token info is pulled from the TPM itself when
340*9126SWyllys.Ingersoll@Sun.COM 	 * C_Initialize is called.
341*9126SWyllys.Ingersoll@Sun.COM 	 */
342*9126SWyllys.Ingersoll@Sun.COM 	(void) (void) memset(&slot_info.slotDescription, ' ',
343*9126SWyllys.Ingersoll@Sun.COM 	    sizeof (slot_info.slotDescription) - 1);
344*9126SWyllys.Ingersoll@Sun.COM 	(void) (void) memset(&slot_info.manufacturerID,  ' ',
345*9126SWyllys.Ingersoll@Sun.COM 	    sizeof (slot_info.manufacturerID) - 1);
346*9126SWyllys.Ingersoll@Sun.COM 
347*9126SWyllys.Ingersoll@Sun.COM 	(void) (void) memcpy(&slot_info.slotDescription,
348*9126SWyllys.Ingersoll@Sun.COM 	    "PKCS#11 Interface for TPM",
349*9126SWyllys.Ingersoll@Sun.COM 	    strlen("PKCS#11 Interface for TPM"));
350*9126SWyllys.Ingersoll@Sun.COM 
351*9126SWyllys.Ingersoll@Sun.COM 	(void) (void) memcpy(&slot_info.manufacturerID,
352*9126SWyllys.Ingersoll@Sun.COM 	    td->token_info.manufacturerID,
353*9126SWyllys.Ingersoll@Sun.COM 	    strlen((char *)td->token_info.manufacturerID));
354*9126SWyllys.Ingersoll@Sun.COM 
355*9126SWyllys.Ingersoll@Sun.COM 	slot_info.hardwareVersion = nv_token_data->token_info.hardwareVersion;
356*9126SWyllys.Ingersoll@Sun.COM 	slot_info.firmwareVersion = nv_token_data->token_info.firmwareVersion;
357*9126SWyllys.Ingersoll@Sun.COM 	slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT;
358*9126SWyllys.Ingersoll@Sun.COM }
359*9126SWyllys.Ingersoll@Sun.COM 
360*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
361*9126SWyllys.Ingersoll@Sun.COM void
362*9126SWyllys.Ingersoll@Sun.COM copy_slot_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR sinfo)
363*9126SWyllys.Ingersoll@Sun.COM {
364*9126SWyllys.Ingersoll@Sun.COM 	if (sinfo != NULL)
365*9126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(sinfo, &slot_info, sizeof (slot_info));
366*9126SWyllys.Ingersoll@Sun.COM }
367*9126SWyllys.Ingersoll@Sun.COM 
368*9126SWyllys.Ingersoll@Sun.COM static void
369*9126SWyllys.Ingersoll@Sun.COM init_token_info(TOKEN_DATA *td)
370*9126SWyllys.Ingersoll@Sun.COM {
371*9126SWyllys.Ingersoll@Sun.COM 	CK_TOKEN_INFO    *token_info = NULL;
372*9126SWyllys.Ingersoll@Sun.COM 
373*9126SWyllys.Ingersoll@Sun.COM 	token_info = &td->token_info;
374*9126SWyllys.Ingersoll@Sun.COM 
375*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(token_info->model, ' ',
376*9126SWyllys.Ingersoll@Sun.COM 	    sizeof (token_info->model));
377*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(token_info->serialNumber, ' ',
378*9126SWyllys.Ingersoll@Sun.COM 	    sizeof (token_info->serialNumber));
379*9126SWyllys.Ingersoll@Sun.COM 
380*9126SWyllys.Ingersoll@Sun.COM 	//
381*9126SWyllys.Ingersoll@Sun.COM 	// I don't see any API support for changing the clock so
382*9126SWyllys.Ingersoll@Sun.COM 	// we will use the system clock for the token's clock.
383*9126SWyllys.Ingersoll@Sun.COM 	//
384*9126SWyllys.Ingersoll@Sun.COM 	token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN |
385*9126SWyllys.Ingersoll@Sun.COM 	    CKF_SO_PIN_TO_BE_CHANGED;
386*9126SWyllys.Ingersoll@Sun.COM 
387*9126SWyllys.Ingersoll@Sun.COM 	if (memcmp(td->user_pin_sha, "00000000000000000000",
388*9126SWyllys.Ingersoll@Sun.COM 	    SHA1_DIGEST_LENGTH) != 0)
389*9126SWyllys.Ingersoll@Sun.COM 		token_info->flags |= CKF_USER_PIN_INITIALIZED;
390*9126SWyllys.Ingersoll@Sun.COM 	else
391*9126SWyllys.Ingersoll@Sun.COM 		token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED;
392*9126SWyllys.Ingersoll@Sun.COM 
393*9126SWyllys.Ingersoll@Sun.COM 	// For the release, we made these
394*9126SWyllys.Ingersoll@Sun.COM 	// values as CK_UNAVAILABLE_INFORMATION
395*9126SWyllys.Ingersoll@Sun.COM 	//
396*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulMaxSessionCount    = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
397*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulSessionCount	= (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
398*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulMaxRwSessionCount  = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
399*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulRwSessionCount	= (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
400*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulMaxPinLen	  = MAX_PIN_LEN;
401*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulMinPinLen	  = MIN_PIN_LEN;
402*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulTotalPublicMemory  = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
403*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulFreePublicMemory   = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
404*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
405*9126SWyllys.Ingersoll@Sun.COM 	token_info->ulFreePrivateMemory  = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
406*9126SWyllys.Ingersoll@Sun.COM 
407*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(token_info->utcTime, ' ', sizeof (token_info->utcTime));
408*9126SWyllys.Ingersoll@Sun.COM }
409*9126SWyllys.Ingersoll@Sun.COM 
410*9126SWyllys.Ingersoll@Sun.COM CK_RV
411*9126SWyllys.Ingersoll@Sun.COM init_token_data(TSS_HCONTEXT hContext, TOKEN_DATA *td) {
412*9126SWyllys.Ingersoll@Sun.COM 	CK_RV rc;
413*9126SWyllys.Ingersoll@Sun.COM 
414*9126SWyllys.Ingersoll@Sun.COM 	(void) memset((char *)td, 0, sizeof (nv_token_data));
415*9126SWyllys.Ingersoll@Sun.COM 	//
416*9126SWyllys.Ingersoll@Sun.COM 	// the normal USER pin is not set when the token is initialized
417*9126SWyllys.Ingersoll@Sun.COM 	//
418*9126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(td->user_pin_sha, "00000000000000000000",
419*9126SWyllys.Ingersoll@Sun.COM 	    SHA1_DIGEST_LENGTH);
420*9126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(td->so_pin_sha, default_so_pin_sha,
421*9126SWyllys.Ingersoll@Sun.COM 	    SHA1_DIGEST_LENGTH);
422*9126SWyllys.Ingersoll@Sun.COM 
423*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(user_pin_md5, 0x0, MD5_DIGEST_LENGTH);
424*9126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(so_pin_md5, default_so_pin_md5, MD5_DIGEST_LENGTH);
425*9126SWyllys.Ingersoll@Sun.COM 
426*9126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(td->next_token_object_name, "00000000", 8);
427*9126SWyllys.Ingersoll@Sun.COM 
428*9126SWyllys.Ingersoll@Sun.COM 	td->tweak_vector.allow_key_mods   = TRUE;
429*9126SWyllys.Ingersoll@Sun.COM 
430*9126SWyllys.Ingersoll@Sun.COM 	init_token_info(td);
431*9126SWyllys.Ingersoll@Sun.COM 
432*9126SWyllys.Ingersoll@Sun.COM 	rc = token_get_tpm_info(hContext, td);
433*9126SWyllys.Ingersoll@Sun.COM 	if (rc != CKR_OK)
434*9126SWyllys.Ingersoll@Sun.COM 		return (rc);
435*9126SWyllys.Ingersoll@Sun.COM 
436*9126SWyllys.Ingersoll@Sun.COM 	rc = save_token_data(td);
437*9126SWyllys.Ingersoll@Sun.COM 
438*9126SWyllys.Ingersoll@Sun.COM 	return (rc);
439*9126SWyllys.Ingersoll@Sun.COM }
440*9126SWyllys.Ingersoll@Sun.COM 
441*9126SWyllys.Ingersoll@Sun.COM // Function:  compute_next_token_obj_name()
442*9126SWyllys.Ingersoll@Sun.COM //
443*9126SWyllys.Ingersoll@Sun.COM // Given a token object name (8 bytes in the range [0 - 9A - Z])
444*9126SWyllys.Ingersoll@Sun.COM // increment by one adjusting as necessary
445*9126SWyllys.Ingersoll@Sun.COM //
446*9126SWyllys.Ingersoll@Sun.COM // This gives us a namespace of 36^8 = 2, 821, 109, 907, 456
447*9126SWyllys.Ingersoll@Sun.COM // objects before wrapping around.
448*9126SWyllys.Ingersoll@Sun.COM //
449*9126SWyllys.Ingersoll@Sun.COM CK_RV
450*9126SWyllys.Ingersoll@Sun.COM compute_next_token_obj_name(CK_BYTE *current, CK_BYTE *next) {
451*9126SWyllys.Ingersoll@Sun.COM 	int val[8];
452*9126SWyllys.Ingersoll@Sun.COM 	int i;
453*9126SWyllys.Ingersoll@Sun.COM 
454*9126SWyllys.Ingersoll@Sun.COM 	if (! current || ! next) {
455*9126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
456*9126SWyllys.Ingersoll@Sun.COM 	}
457*9126SWyllys.Ingersoll@Sun.COM 	// Convert to integral base 36
458*9126SWyllys.Ingersoll@Sun.COM 	//
459*9126SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < 8; i++) {
460*9126SWyllys.Ingersoll@Sun.COM 		if (current[i] >= '0' && current[i] <= '9')
461*9126SWyllys.Ingersoll@Sun.COM 			val[i] = current[i] - '0';
462*9126SWyllys.Ingersoll@Sun.COM 
463*9126SWyllys.Ingersoll@Sun.COM 		if (current[i] >= 'A' && current[i] <= 'Z')
464*9126SWyllys.Ingersoll@Sun.COM 			val[i] = current[i] - 'A' + 10;
465*9126SWyllys.Ingersoll@Sun.COM 	}
466*9126SWyllys.Ingersoll@Sun.COM 
467*9126SWyllys.Ingersoll@Sun.COM 	val[0]++;
468*9126SWyllys.Ingersoll@Sun.COM 
469*9126SWyllys.Ingersoll@Sun.COM 	i = 0;
470*9126SWyllys.Ingersoll@Sun.COM 
471*9126SWyllys.Ingersoll@Sun.COM 	while (val[i] > 35) {
472*9126SWyllys.Ingersoll@Sun.COM 		val[i] = 0;
473*9126SWyllys.Ingersoll@Sun.COM 
474*9126SWyllys.Ingersoll@Sun.COM 		if (i + 1 < 8) {
475*9126SWyllys.Ingersoll@Sun.COM 			val[i + 1]++;
476*9126SWyllys.Ingersoll@Sun.COM 			i++;
477*9126SWyllys.Ingersoll@Sun.COM 		} else {
478*9126SWyllys.Ingersoll@Sun.COM 			val[0]++;
479*9126SWyllys.Ingersoll@Sun.COM 			i = 0;   // start pass 2
480*9126SWyllys.Ingersoll@Sun.COM 		}
481*9126SWyllys.Ingersoll@Sun.COM 	}
482*9126SWyllys.Ingersoll@Sun.COM 
483*9126SWyllys.Ingersoll@Sun.COM 	// now, convert back to [0 - 9A - Z]
484*9126SWyllys.Ingersoll@Sun.COM 	//
485*9126SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < 8; i++) {
486*9126SWyllys.Ingersoll@Sun.COM 		if (val[i] < 10)
487*9126SWyllys.Ingersoll@Sun.COM 			next[i] = '0' + val[i];
488*9126SWyllys.Ingersoll@Sun.COM 		else
489*9126SWyllys.Ingersoll@Sun.COM 			next[i] = 'A' + val[i] - 10;
490*9126SWyllys.Ingersoll@Sun.COM 	}
491*9126SWyllys.Ingersoll@Sun.COM 
492*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
493*9126SWyllys.Ingersoll@Sun.COM }
494*9126SWyllys.Ingersoll@Sun.COM 
495*9126SWyllys.Ingersoll@Sun.COM 
496*9126SWyllys.Ingersoll@Sun.COM //
497*9126SWyllys.Ingersoll@Sun.COM //
498*9126SWyllys.Ingersoll@Sun.COM CK_RV
499*9126SWyllys.Ingersoll@Sun.COM build_attribute(CK_ATTRIBUTE_TYPE  type,
500*9126SWyllys.Ingersoll@Sun.COM 	CK_BYTE	   *data,
501*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	   data_len,
502*9126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	**attrib) {
503*9126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE *attr = NULL;
504*9126SWyllys.Ingersoll@Sun.COM 
505*9126SWyllys.Ingersoll@Sun.COM 	attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + data_len);
506*9126SWyllys.Ingersoll@Sun.COM 	if (! attr) {
507*9126SWyllys.Ingersoll@Sun.COM 		return (CKR_DEVICE_MEMORY);
508*9126SWyllys.Ingersoll@Sun.COM 	}
509*9126SWyllys.Ingersoll@Sun.COM 	attr->type  = type;
510*9126SWyllys.Ingersoll@Sun.COM 	attr->ulValueLen = data_len;
511*9126SWyllys.Ingersoll@Sun.COM 
512*9126SWyllys.Ingersoll@Sun.COM 	if (data_len > 0) {
513*9126SWyllys.Ingersoll@Sun.COM 		attr->pValue = (CK_BYTE *)attr + sizeof (CK_ATTRIBUTE);
514*9126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(attr->pValue, data, data_len);
515*9126SWyllys.Ingersoll@Sun.COM 	}
516*9126SWyllys.Ingersoll@Sun.COM 	else
517*9126SWyllys.Ingersoll@Sun.COM 		attr->pValue = NULL;
518*9126SWyllys.Ingersoll@Sun.COM 
519*9126SWyllys.Ingersoll@Sun.COM 	 *attrib = attr;
520*9126SWyllys.Ingersoll@Sun.COM 
521*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
522*9126SWyllys.Ingersoll@Sun.COM }
523*9126SWyllys.Ingersoll@Sun.COM 
524*9126SWyllys.Ingersoll@Sun.COM 
525*9126SWyllys.Ingersoll@Sun.COM //
526*9126SWyllys.Ingersoll@Sun.COM //
527*9126SWyllys.Ingersoll@Sun.COM CK_RV
528*9126SWyllys.Ingersoll@Sun.COM add_pkcs_padding(CK_BYTE  * ptr,
529*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG   block_size,
530*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG   data_len,
531*9126SWyllys.Ingersoll@Sun.COM CK_ULONG   total_len)
532*9126SWyllys.Ingersoll@Sun.COM {
533*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG i, pad_len;
534*9126SWyllys.Ingersoll@Sun.COM 	CK_BYTE  pad_value;
535*9126SWyllys.Ingersoll@Sun.COM 
536*9126SWyllys.Ingersoll@Sun.COM 	pad_len = block_size - (data_len % block_size);
537*9126SWyllys.Ingersoll@Sun.COM 	pad_value = (CK_BYTE)pad_len;
538*9126SWyllys.Ingersoll@Sun.COM 
539*9126SWyllys.Ingersoll@Sun.COM 	if (data_len + pad_len > total_len) {
540*9126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
541*9126SWyllys.Ingersoll@Sun.COM 	}
542*9126SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < pad_len; i++)
543*9126SWyllys.Ingersoll@Sun.COM 	ptr[i] = pad_value;
544*9126SWyllys.Ingersoll@Sun.COM 
545*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
546*9126SWyllys.Ingersoll@Sun.COM }
547*9126SWyllys.Ingersoll@Sun.COM 
548*9126SWyllys.Ingersoll@Sun.COM 
549*9126SWyllys.Ingersoll@Sun.COM //
550*9126SWyllys.Ingersoll@Sun.COM //
551*9126SWyllys.Ingersoll@Sun.COM CK_RV
552*9126SWyllys.Ingersoll@Sun.COM strip_pkcs_padding(CK_BYTE   * ptr,
553*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    total_len,
554*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  * data_len) {
555*9126SWyllys.Ingersoll@Sun.COM 	CK_BYTE  pad_value;
556*9126SWyllys.Ingersoll@Sun.COM 
557*9126SWyllys.Ingersoll@Sun.COM 	pad_value = ptr[total_len - 1];
558*9126SWyllys.Ingersoll@Sun.COM 
559*9126SWyllys.Ingersoll@Sun.COM 	// thus, we have 'pad_value' bytes of 'pad_value' appended to the end
560*9126SWyllys.Ingersoll@Sun.COM 	//
561*9126SWyllys.Ingersoll@Sun.COM 	 *data_len = total_len - pad_value;
562*9126SWyllys.Ingersoll@Sun.COM 
563*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
564*9126SWyllys.Ingersoll@Sun.COM }
565*9126SWyllys.Ingersoll@Sun.COM 
566*9126SWyllys.Ingersoll@Sun.COM 
567*9126SWyllys.Ingersoll@Sun.COM //
568*9126SWyllys.Ingersoll@Sun.COM //
569*9126SWyllys.Ingersoll@Sun.COM CK_RV
570*9126SWyllys.Ingersoll@Sun.COM remove_leading_zeros(CK_ATTRIBUTE *attr)
571*9126SWyllys.Ingersoll@Sun.COM {
572*9126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   *ptr = NULL;
573*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG   new_len, i;
574*9126SWyllys.Ingersoll@Sun.COM 
575*9126SWyllys.Ingersoll@Sun.COM 	ptr = attr->pValue;
576*9126SWyllys.Ingersoll@Sun.COM 
577*9126SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < attr->ulValueLen; i++) {
578*9126SWyllys.Ingersoll@Sun.COM 		if (ptr[i] != 0x0)
579*9126SWyllys.Ingersoll@Sun.COM 			break;
580*9126SWyllys.Ingersoll@Sun.COM 	}
581*9126SWyllys.Ingersoll@Sun.COM 
582*9126SWyllys.Ingersoll@Sun.COM 	new_len = attr->ulValueLen - i;
583*9126SWyllys.Ingersoll@Sun.COM 
584*9126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(ptr, ptr + i, new_len);
585*9126SWyllys.Ingersoll@Sun.COM 	attr->ulValueLen = new_len;
586*9126SWyllys.Ingersoll@Sun.COM 
587*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
588*9126SWyllys.Ingersoll@Sun.COM }
589*9126SWyllys.Ingersoll@Sun.COM 
590*9126SWyllys.Ingersoll@Sun.COM CK_RV
591*9126SWyllys.Ingersoll@Sun.COM parity_is_odd(CK_BYTE b) {
592*9126SWyllys.Ingersoll@Sun.COM 	b = ((b >> 4) ^ b) & 0x0f;
593*9126SWyllys.Ingersoll@Sun.COM 	b = ((b >> 2) ^ b) & 0x03;
594*9126SWyllys.Ingersoll@Sun.COM 	b = ((b >> 1) ^ b) & 0x01;
595*9126SWyllys.Ingersoll@Sun.COM 
596*9126SWyllys.Ingersoll@Sun.COM 	if (b == 1)
597*9126SWyllys.Ingersoll@Sun.COM 		return (TRUE);
598*9126SWyllys.Ingersoll@Sun.COM 	else
599*9126SWyllys.Ingersoll@Sun.COM 		return (FALSE);
600*9126SWyllys.Ingersoll@Sun.COM }
601*9126SWyllys.Ingersoll@Sun.COM 
602*9126SWyllys.Ingersoll@Sun.COM CK_RV
603*9126SWyllys.Ingersoll@Sun.COM attach_shm() {
604*9126SWyllys.Ingersoll@Sun.COM 	if (global_shm != NULL)
605*9126SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
606*9126SWyllys.Ingersoll@Sun.COM 
607*9126SWyllys.Ingersoll@Sun.COM 	global_shm = (LW_SHM_TYPE *)malloc(sizeof (LW_SHM_TYPE));
608*9126SWyllys.Ingersoll@Sun.COM 	if (global_shm == NULL) {
609*9126SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
610*9126SWyllys.Ingersoll@Sun.COM 	}
611*9126SWyllys.Ingersoll@Sun.COM 	CreateXProcLock(&global_shm->mutex);
612*9126SWyllys.Ingersoll@Sun.COM 
613*9126SWyllys.Ingersoll@Sun.COM 	xproclock = (void *)&global_shm->mutex;
614*9126SWyllys.Ingersoll@Sun.COM 	(void) XProcLock(xproclock);
615*9126SWyllys.Ingersoll@Sun.COM 
616*9126SWyllys.Ingersoll@Sun.COM 	global_shm->num_publ_tok_obj = 0;
617*9126SWyllys.Ingersoll@Sun.COM 	global_shm->num_priv_tok_obj = 0;
618*9126SWyllys.Ingersoll@Sun.COM 
619*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(&global_shm->publ_tok_objs, 0x0,
620*9126SWyllys.Ingersoll@Sun.COM 	    2048 * sizeof (TOK_OBJ_ENTRY));
621*9126SWyllys.Ingersoll@Sun.COM 	(void) memset(&global_shm->priv_tok_objs, 0x0,
622*9126SWyllys.Ingersoll@Sun.COM 	    2048 * sizeof (TOK_OBJ_ENTRY));
623*9126SWyllys.Ingersoll@Sun.COM 
624*9126SWyllys.Ingersoll@Sun.COM 	(void) XProcUnLock(xproclock);
625*9126SWyllys.Ingersoll@Sun.COM 
626*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
627*9126SWyllys.Ingersoll@Sun.COM }
628*9126SWyllys.Ingersoll@Sun.COM 
629*9126SWyllys.Ingersoll@Sun.COM CK_RV
630*9126SWyllys.Ingersoll@Sun.COM detach_shm()
631*9126SWyllys.Ingersoll@Sun.COM {
632*9126SWyllys.Ingersoll@Sun.COM 	if (global_shm != NULL) {
633*9126SWyllys.Ingersoll@Sun.COM 		free(global_shm);
634*9126SWyllys.Ingersoll@Sun.COM 		global_shm = NULL;
635*9126SWyllys.Ingersoll@Sun.COM 	}
636*9126SWyllys.Ingersoll@Sun.COM 
637*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
638*9126SWyllys.Ingersoll@Sun.COM }
639*9126SWyllys.Ingersoll@Sun.COM 
640*9126SWyllys.Ingersoll@Sun.COM CK_RV
641*9126SWyllys.Ingersoll@Sun.COM compute_sha(CK_BYTE  *data,
642*9126SWyllys.Ingersoll@Sun.COM 	CK_ULONG   len,
643*9126SWyllys.Ingersoll@Sun.COM 	CK_BYTE  * hash)
644*9126SWyllys.Ingersoll@Sun.COM {
645*9126SWyllys.Ingersoll@Sun.COM 	SHA1_CTX	ctx;
646*9126SWyllys.Ingersoll@Sun.COM 
647*9126SWyllys.Ingersoll@Sun.COM 	SHA1Init(&ctx);
648*9126SWyllys.Ingersoll@Sun.COM 
649*9126SWyllys.Ingersoll@Sun.COM 	SHA1Update(&ctx, data, len);
650*9126SWyllys.Ingersoll@Sun.COM 
651*9126SWyllys.Ingersoll@Sun.COM 	SHA1Final(hash, &ctx);
652*9126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
653*9126SWyllys.Ingersoll@Sun.COM }
654