xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c (revision fd71220ba0fafcc9cf5ea0785db206f3f31336e7)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2018, Joyent, Inc.
24  * Copyright 2023 RackTop Systems, Inc.
25  */
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <stdio.h>
31 #include <cryptoutil.h>
32 #include <errno.h>
33 #include <security/cryptoki.h>
34 #include <sys/crypto/common.h>
35 #include <sys/crypto/ioctl.h>
36 #include "kernelGlobal.h"
37 #include "kernelObject.h"
38 #include "kernelSlot.h"
39 
40 #define	ENCODE_ATTR(type, value, len) {		\
41 	cur_attr->oa_type = type;		\
42 	(void) memcpy(ptr, value, len);		\
43 	cur_attr->oa_value = ptr;		\
44 	cur_attr->oa_value_len = len;		\
45 	cur_attr++;				\
46 }
47 
48 #define	MECH_HASH(type)	(((uintptr_t)type) % KMECH_HASHTABLE_SIZE)
49 /*
50  * Serialize writes to the hash table. We don't need a per bucket lock as
51  * there are only a few writes and we don't need the lock for reads.
52  */
53 pthread_mutex_t mechhash_mutex = PTHREAD_MUTEX_INITIALIZER;
54 
55 static CK_RV
56 kmech_hash_insert(CK_MECHANISM_TYPE type, crypto_mech_type_t kmech)
57 {
58 	uint_t h;
59 	kmh_elem_t *elem, *cur;
60 
61 	elem = malloc(sizeof (kmh_elem_t));
62 	if (elem == NULL)
63 		return (CKR_HOST_MEMORY);
64 
65 	h = MECH_HASH(type);
66 	elem->type = type;
67 	elem->kmech = kmech;
68 
69 	(void) pthread_mutex_lock(&mechhash_mutex);
70 	for (cur = kernel_mechhash[h]; cur != NULL; cur = cur->knext) {
71 		if (type == cur->type) {
72 			/* Some other thread beat us to it. */
73 			(void) pthread_mutex_unlock(&mechhash_mutex);
74 			free(elem);
75 			return (CKR_OK);
76 		}
77 	}
78 	elem->knext = kernel_mechhash[h];
79 	kernel_mechhash[h] = elem;
80 	(void) pthread_mutex_unlock(&mechhash_mutex);
81 
82 	return (CKR_OK);
83 }
84 
85 CK_RV
86 kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number)
87 {
88 	crypto_get_mechanism_number_t get_number;
89 	const char *string;
90 	CK_RV rv;
91 	int r;
92 	kmh_elem_t *elem;
93 	uint_t h;
94 	char buf[11];   /* Num chars for representing ulong in ASCII */
95 
96 	/*
97 	 * Search for an existing entry. No need to lock since we are
98 	 * just a reader and we never free the entries in the hash table.
99 	 */
100 	h = MECH_HASH(type);
101 	for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) {
102 		if (type == elem->type) {
103 			*k_number = elem->kmech;
104 			return (CKR_OK);
105 		}
106 	}
107 
108 	if (type >= CKM_VENDOR_DEFINED) {
109 		(void) snprintf(buf, sizeof (buf), "%#lx", type);
110 		string = buf;
111 	} else {
112 		string = pkcs11_mech2str(type);
113 	}
114 
115 	if (string == NULL)
116 		return (CKR_MECHANISM_INVALID);
117 
118 	get_number.pn_mechanism_string = (char *)string;
119 	get_number.pn_mechanism_len = strlen(string) + 1;
120 
121 	while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER,
122 	    &get_number)) < 0) {
123 		if (errno != EINTR)
124 			break;
125 	}
126 	if (r < 0) {
127 		rv = CKR_MECHANISM_INVALID;
128 	} else {
129 		if (get_number.pn_return_value != CRYPTO_SUCCESS) {
130 			rv = crypto2pkcs11_error_number(
131 			    get_number.pn_return_value);
132 		} else {
133 			rv = CKR_OK;
134 		}
135 	}
136 
137 	if (rv == CKR_OK) {
138 		*k_number = get_number.pn_internal_number;
139 		/* Add this to the hash table */
140 		(void) kmech_hash_insert(type, *k_number);
141 	}
142 
143 	return (rv);
144 }
145 
146 
147 /*
148  * Return the value of a secret key object.
149  * This routine allocates memory for the value.
150  * A null pointer is returned on error.
151  */
152 unsigned char *
153 get_symmetric_key_value(kernel_object_t *key_p)
154 {
155 	uint8_t *cipherKey;
156 
157 	switch (key_p->class) {
158 
159 	case CKO_SECRET_KEY:
160 
161 		cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len);
162 		if (cipherKey == NULL)
163 			return (NULL);
164 
165 		(void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value,
166 		    OBJ_SEC(key_p)->sk_value_len);
167 
168 		return (cipherKey);
169 
170 	default:
171 		return (NULL);
172 	}
173 }
174 
175 /*
176  * Convert a RSA private key object into a crypto_key structure.
177  * Memory is allocated for each attribute stored in the crypto_key
178  * structure.  Memory for the crypto_key structure is not
179  * allocated.  Attributes can be freed by free_key_attributes().
180  */
181 CK_RV
182 get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
183 {
184 	biginteger_t *big;
185 	crypto_object_attribute_t *attrs, *cur_attr;
186 	char *ptr;
187 	CK_RV rv;
188 
189 	(void) pthread_mutex_lock(&object_p->object_mutex);
190 	if (object_p->key_type != CKK_RSA ||
191 	    object_p->class != CKO_PRIVATE_KEY) {
192 		(void) pthread_mutex_unlock(&object_p->object_mutex);
193 		return (CKR_ATTRIBUTE_TYPE_INVALID);
194 	}
195 
196 	attrs = calloc(1,
197 	    RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t));
198 	if (attrs == NULL) {
199 		(void) pthread_mutex_unlock(&object_p->object_mutex);
200 		return (CKR_HOST_MEMORY);
201 	}
202 
203 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
204 	key->ck_attrs = attrs;
205 	cur_attr = attrs;
206 
207 	/*
208 	 * Allocate memory for each key attribute and set up the value
209 	 * value length.
210 	 */
211 	key->ck_count = 0;
212 
213 	/* CKA_MODULUS is required. */
214 	big = OBJ_PRI_RSA_MOD(object_p);
215 	if (big->big_value == NULL) {
216 		rv = CKR_ATTRIBUTE_TYPE_INVALID;
217 		goto fail_cleanup;
218 	} else {
219 		if ((ptr = malloc(big->big_value_len)) == NULL) {
220 			rv = CKR_HOST_MEMORY;
221 			goto fail_cleanup;
222 		}
223 		ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
224 		key->ck_count++;
225 	}
226 
227 	/* CKA_PRIVATE_EXPONENT is required. */
228 	big = OBJ_PRI_RSA_PRIEXPO(object_p);
229 	if (big->big_value == NULL) {
230 		rv = CKR_ATTRIBUTE_TYPE_INVALID;
231 		goto fail_cleanup;
232 	} else {
233 		if ((ptr = malloc(big->big_value_len)) == NULL) {
234 			rv = CKR_HOST_MEMORY;
235 			goto fail_cleanup;
236 		}
237 		ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value,
238 		    big->big_value_len);
239 		key->ck_count++;
240 	}
241 
242 	/* CKA_PRIME_1 is optional. */
243 	big = OBJ_PRI_RSA_PRIME1(object_p);
244 	if (big->big_value != NULL) {
245 		if ((ptr = malloc(big->big_value_len)) == NULL) {
246 			rv = CKR_HOST_MEMORY;
247 			goto fail_cleanup;
248 		}
249 		ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len);
250 		key->ck_count++;
251 	}
252 
253 	/* CKA_PRIME_2 is optional. */
254 	big = OBJ_PRI_RSA_PRIME2(object_p);
255 	if (big->big_value != NULL) {
256 		if ((ptr = malloc(big->big_value_len)) == NULL) {
257 			rv = CKR_HOST_MEMORY;
258 			goto fail_cleanup;
259 		}
260 		ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len);
261 		key->ck_count++;
262 	}
263 
264 	/* CKA_EXPONENT_1 is optional. */
265 	big = OBJ_PRI_RSA_EXPO1(object_p);
266 	if (big->big_value != NULL) {
267 		if ((ptr = malloc(big->big_value_len)) == NULL) {
268 			rv = CKR_HOST_MEMORY;
269 			goto fail_cleanup;
270 		}
271 		ENCODE_ATTR(CKA_EXPONENT_1, big->big_value,
272 		    big->big_value_len);
273 		key->ck_count++;
274 	}
275 
276 	/* CKA_EXPONENT_2 is optional. */
277 	big = OBJ_PRI_RSA_EXPO2(object_p);
278 	if (big->big_value != NULL) {
279 		if ((ptr = malloc(big->big_value_len)) == NULL) {
280 			rv = CKR_HOST_MEMORY;
281 			goto fail_cleanup;
282 		}
283 		ENCODE_ATTR(CKA_EXPONENT_2, big->big_value,
284 		    big->big_value_len);
285 		key->ck_count++;
286 	}
287 
288 	/* CKA_COEFFICIENT is optional. */
289 	big = OBJ_PRI_RSA_COEF(object_p);
290 	if (big->big_value != NULL) {
291 		if ((ptr = malloc(big->big_value_len)) == NULL) {
292 			rv = CKR_HOST_MEMORY;
293 			goto fail_cleanup;
294 		}
295 		ENCODE_ATTR(CKA_COEFFICIENT, big->big_value,
296 		    big->big_value_len);
297 		key->ck_count++;
298 	}
299 
300 	(void) pthread_mutex_unlock(&object_p->object_mutex);
301 	return (CKR_OK);
302 
303 fail_cleanup:
304 	(void) pthread_mutex_unlock(&object_p->object_mutex);
305 	free_key_attributes(key);
306 	return (rv);
307 }
308 
309 /*
310  * Convert a RSA public key object into a crypto_key structure.
311  * Memory is allocated for each attribute stored in the crypto_key
312  * structure.  Memory for the crypto_key structure is not
313  * allocated.  Attributes can be freed by free_key_attributes().
314  */
315 CK_RV
316 get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
317 {
318 	biginteger_t *big;
319 	crypto_object_attribute_t *attrs, *cur_attr;
320 	char *ptr;
321 
322 	(void) pthread_mutex_lock(&object_p->object_mutex);
323 	if (object_p->key_type != CKK_RSA ||
324 	    object_p->class != CKO_PUBLIC_KEY) {
325 		(void) pthread_mutex_unlock(&object_p->object_mutex);
326 		return (CKR_ATTRIBUTE_TYPE_INVALID);
327 	}
328 
329 	attrs = calloc(1,
330 	    RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t));
331 	if (attrs == NULL) {
332 		(void) pthread_mutex_unlock(&object_p->object_mutex);
333 		return (CKR_HOST_MEMORY);
334 	}
335 
336 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
337 	key->ck_count = RSA_PUB_ATTR_COUNT;
338 	key->ck_attrs = attrs;
339 
340 	cur_attr = attrs;
341 	big = OBJ_PUB_RSA_PUBEXPO(object_p);
342 	if ((ptr = malloc(big->big_value_len)) == NULL)
343 		goto mem_failure;
344 	ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len);
345 
346 	big = OBJ_PUB_RSA_MOD(object_p);
347 	if ((ptr = malloc(big->big_value_len)) == NULL)
348 		goto mem_failure;
349 	ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
350 
351 	if ((ptr = malloc(sizeof (CK_ULONG))) == NULL)
352 		goto mem_failure;
353 	ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p),
354 	    sizeof (CK_ULONG));
355 
356 	(void) pthread_mutex_unlock(&object_p->object_mutex);
357 	return (CKR_OK);
358 
359 mem_failure:
360 	(void) pthread_mutex_unlock(&object_p->object_mutex);
361 	free_key_attributes(key);
362 	return (CKR_HOST_MEMORY);
363 }
364 
365 /*
366  * Free attribute storage in a crypto_key structure.
367  */
368 void
369 free_key_attributes(crypto_key_t *key)
370 {
371 	int i;
372 
373 	if (key->ck_format == CRYPTO_KEY_ATTR_LIST &&
374 	    (key->ck_count > 0) && key->ck_attrs != NULL) {
375 		for (i = 0; i < key->ck_count; i++) {
376 			freezero(key->ck_attrs[i].oa_value,
377 			    key->ck_attrs[i].oa_value_len);
378 		}
379 		free(key->ck_attrs);
380 	}
381 }
382 
383 
384 /*
385  * Convert a DSA private key object into a crypto_key structure.
386  * Memory is allocated for each attribute stored in the crypto_key
387  * structure.  Memory for the crypto_key structure is not
388  * allocated.  Attributes can be freed by free_dsa_key_attributes().
389  */
390 CK_RV
391 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
392 {
393 	biginteger_t *big;
394 	crypto_object_attribute_t *attrs, *cur_attr;
395 	char *ptr;
396 
397 	(void) pthread_mutex_lock(&object_p->object_mutex);
398 	if (object_p->key_type != CKK_DSA ||
399 	    object_p->class != CKO_PRIVATE_KEY) {
400 		(void) pthread_mutex_unlock(&object_p->object_mutex);
401 		return (CKR_ATTRIBUTE_TYPE_INVALID);
402 	}
403 
404 	attrs = calloc(1,
405 	    DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
406 	if (attrs == NULL) {
407 		(void) pthread_mutex_unlock(&object_p->object_mutex);
408 		return (CKR_HOST_MEMORY);
409 	}
410 
411 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
412 	key->ck_count = DSA_ATTR_COUNT;
413 	key->ck_attrs = attrs;
414 
415 	cur_attr = attrs;
416 	big = OBJ_PRI_DSA_PRIME(object_p);
417 	if ((ptr = malloc(big->big_value_len)) == NULL)
418 		goto mem_failure;
419 	ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
420 
421 	big = OBJ_PRI_DSA_SUBPRIME(object_p);
422 	if ((ptr = malloc(big->big_value_len)) == NULL)
423 		goto mem_failure;
424 	ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
425 
426 	big = OBJ_PRI_DSA_BASE(object_p);
427 	if ((ptr = malloc(big->big_value_len)) == NULL)
428 		goto mem_failure;
429 	ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
430 
431 	big = OBJ_PRI_DSA_VALUE(object_p);
432 	if ((ptr = malloc(big->big_value_len)) == NULL)
433 		goto mem_failure;
434 	ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
435 
436 	(void) pthread_mutex_unlock(&object_p->object_mutex);
437 	return (CKR_OK);
438 
439 mem_failure:
440 	(void) pthread_mutex_unlock(&object_p->object_mutex);
441 	free_key_attributes(key);
442 	return (CKR_HOST_MEMORY);
443 }
444 
445 
446 /*
447  * Convert a DSA public key object into a crypto_key structure.
448  * Memory is allocated for each attribute stored in the crypto_key
449  * structure.  Memory for the crypto_key structure is not
450  * allocated.  Attributes can be freed by free_dsa_key_attributes().
451  */
452 CK_RV
453 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
454 {
455 	biginteger_t *big;
456 	crypto_object_attribute_t *attrs, *cur_attr;
457 	char *ptr;
458 
459 	(void) pthread_mutex_lock(&object_p->object_mutex);
460 	if (object_p->key_type != CKK_DSA ||
461 	    object_p->class != CKO_PUBLIC_KEY) {
462 		(void) pthread_mutex_unlock(&object_p->object_mutex);
463 		return (CKR_ATTRIBUTE_TYPE_INVALID);
464 	}
465 
466 	attrs = calloc(1,
467 	    DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
468 	if (attrs == NULL) {
469 		(void) pthread_mutex_unlock(&object_p->object_mutex);
470 		return (CKR_HOST_MEMORY);
471 	}
472 
473 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
474 	key->ck_count = DSA_ATTR_COUNT;
475 	key->ck_attrs = attrs;
476 
477 	cur_attr = attrs;
478 	big = OBJ_PUB_DSA_PRIME(object_p);
479 	if ((ptr = malloc(big->big_value_len)) == NULL)
480 		goto mem_failure;
481 	ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
482 
483 	big = OBJ_PUB_DSA_SUBPRIME(object_p);
484 	if ((ptr = malloc(big->big_value_len)) == NULL)
485 		goto mem_failure;
486 	ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
487 
488 	big = OBJ_PUB_DSA_BASE(object_p);
489 	if ((ptr = malloc(big->big_value_len)) == NULL)
490 		goto mem_failure;
491 	ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
492 
493 	big = OBJ_PUB_DSA_VALUE(object_p);
494 	if ((ptr = malloc(big->big_value_len)) == NULL)
495 		goto mem_failure;
496 	ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
497 
498 	(void) pthread_mutex_unlock(&object_p->object_mutex);
499 	return (CKR_OK);
500 
501 mem_failure:
502 	(void) pthread_mutex_unlock(&object_p->object_mutex);
503 	free_key_attributes(key);
504 	return (CKR_HOST_MEMORY);
505 }
506 
507 
508 /*
509  * Convert a EC private key object into a crypto_key structure.
510  * Memory is allocated for each attribute stored in the crypto_key
511  * structure.  Memory for the crypto_key structure is not
512  * allocated.  Attributes can be freed by free_ec_key_attributes().
513  */
514 CK_RV
515 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key)
516 {
517 	biginteger_t *big;
518 	crypto_object_attribute_t *attrs, *cur_attr;
519 	CK_ATTRIBUTE tmp;
520 	char *ptr;
521 	int rv;
522 
523 	(void) pthread_mutex_lock(&object_p->object_mutex);
524 	if (object_p->key_type != CKK_EC ||
525 	    object_p->class != CKO_PRIVATE_KEY) {
526 		(void) pthread_mutex_unlock(&object_p->object_mutex);
527 		return (CKR_ATTRIBUTE_TYPE_INVALID);
528 	}
529 
530 	attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
531 	if (attrs == NULL) {
532 		(void) pthread_mutex_unlock(&object_p->object_mutex);
533 		return (CKR_HOST_MEMORY);
534 	}
535 
536 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
537 	key->ck_count = EC_ATTR_COUNT;
538 	key->ck_attrs = attrs;
539 
540 	cur_attr = attrs;
541 	big = OBJ_PRI_EC_VALUE(object_p);
542 	if ((ptr = malloc(big->big_value_len)) == NULL) {
543 		rv = CKR_HOST_MEMORY;
544 		goto fail;
545 	}
546 	ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
547 
548 	tmp.type = CKA_EC_PARAMS;
549 	tmp.pValue = NULL;
550 	rv = kernel_get_attribute(object_p, &tmp);
551 	if (rv != CKR_OK) {
552 		goto fail;
553 	}
554 
555 	tmp.pValue = malloc(tmp.ulValueLen);
556 	if (tmp.pValue == NULL) {
557 		rv = CKR_HOST_MEMORY;
558 		goto fail;
559 	}
560 
561 	rv = kernel_get_attribute(object_p, &tmp);
562 	if (rv != CKR_OK) {
563 		free(tmp.pValue);
564 		goto fail;
565 	}
566 
567 	cur_attr->oa_type = tmp.type;
568 	cur_attr->oa_value = tmp.pValue;
569 	cur_attr->oa_value_len = tmp.ulValueLen;
570 
571 	(void) pthread_mutex_unlock(&object_p->object_mutex);
572 	return (CKR_OK);
573 
574 fail:
575 	(void) pthread_mutex_unlock(&object_p->object_mutex);
576 	free_key_attributes(key);
577 	return (rv);
578 }
579 
580 /*
581  * Convert an EC public key object into a crypto_key structure.
582  * Memory is allocated for each attribute stored in the crypto_key
583  * structure.  Memory for the crypto_key structure is not
584  * allocated.  Attributes can be freed by free_ec_key_attributes().
585  */
586 CK_RV
587 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key)
588 {
589 	biginteger_t *big;
590 	crypto_object_attribute_t *attrs, *cur_attr;
591 	CK_ATTRIBUTE tmp;
592 	char *ptr;
593 	int rv;
594 
595 	(void) pthread_mutex_lock(&object_p->object_mutex);
596 	if (object_p->key_type != CKK_EC ||
597 	    object_p->class != CKO_PUBLIC_KEY) {
598 		(void) pthread_mutex_unlock(&object_p->object_mutex);
599 		return (CKR_ATTRIBUTE_TYPE_INVALID);
600 	}
601 
602 	attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
603 	if (attrs == NULL) {
604 		(void) pthread_mutex_unlock(&object_p->object_mutex);
605 		return (CKR_HOST_MEMORY);
606 	}
607 
608 	key->ck_format = CRYPTO_KEY_ATTR_LIST;
609 	key->ck_count = EC_ATTR_COUNT;
610 	key->ck_attrs = attrs;
611 
612 	cur_attr = attrs;
613 	big = OBJ_PUB_EC_POINT(object_p);
614 	if ((ptr = malloc(big->big_value_len)) == NULL) {
615 		rv = CKR_HOST_MEMORY;
616 		goto fail;
617 	}
618 	ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len);
619 
620 	tmp.type = CKA_EC_PARAMS;
621 	tmp.pValue = NULL;
622 	rv = kernel_get_attribute(object_p, &tmp);
623 	if (rv != CKR_OK) {
624 		goto fail;
625 	}
626 
627 	tmp.pValue = malloc(tmp.ulValueLen);
628 	if (tmp.pValue == NULL) {
629 		rv = CKR_HOST_MEMORY;
630 		goto fail;
631 	}
632 
633 	rv = kernel_get_attribute(object_p, &tmp);
634 	if (rv != CKR_OK) {
635 		free(tmp.pValue);
636 		goto fail;
637 	}
638 
639 	cur_attr->oa_type = tmp.type;
640 	cur_attr->oa_value = tmp.pValue;
641 	cur_attr->oa_value_len = tmp.ulValueLen;
642 
643 	(void) pthread_mutex_unlock(&object_p->object_mutex);
644 	return (CKR_OK);
645 
646 fail:
647 	(void) pthread_mutex_unlock(&object_p->object_mutex);
648 	free_key_attributes(key);
649 	return (rv);
650 }
651 
652 /*
653  * Convert an attribute template into an obj_attrs array.
654  * Memory is allocated for each attribute stored in the obj_attrs.
655  * The memory can be freed by free_object_attributes().
656  *
657  * If the boolean pointer is_token_obj is not NULL, the caller wants to
658  * retrieve the value of the CKA_TOKEN attribute if it is specified in the
659  * template.
660  * - When this routine is called thru C_CreateObject(), C_CopyObject(), or
661  *   any key management function, is_token_obj should NOT be NULL.
662  * - When this routine is called thru C_GetAttributeValue() or
663  *   C_SetAttributeValue(), "is_token_obj" should be NULL.
664  */
665 CK_RV
666 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
667     caddr_t *obj_attrs, CK_BBOOL *is_token_obj)
668 {
669 	crypto_object_attribute_t *attrs, *cur_attr;
670 	int i, cur_i;
671 	char *ptr;
672 	CK_RV rv;
673 	ssize_t value_len;
674 
675 	if (ulCount == 0) {
676 		obj_attrs = NULL;
677 		return (CKR_OK);
678 	}
679 
680 	attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t));
681 	if (attrs == NULL) {
682 		return (CKR_HOST_MEMORY);
683 	}
684 
685 	cur_attr = attrs;
686 	for (i = 0; i < ulCount; i++) {
687 		/*
688 		 * The length of long attributes must be set correctly
689 		 * so providers can determine whether they came from 32
690 		 * or 64-bit applications.
691 		 */
692 		switch (pTemplate[i].type) {
693 		case CKA_CLASS:
694 		case CKA_CERTIFICATE_TYPE:
695 		case CKA_KEY_TYPE:
696 		case CKA_MODULUS_BITS:
697 		case CKA_HW_FEATURE_TYPE:
698 			value_len = sizeof (ulong_t);
699 			if (pTemplate[i].pValue != NULL &&
700 			    (pTemplate[i].ulValueLen < value_len)) {
701 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
702 				cur_i = i;
703 				goto fail_cleanup;
704 			}
705 			break;
706 		default:
707 			value_len = pTemplate[i].ulValueLen;
708 		}
709 
710 		cur_attr->oa_type = pTemplate[i].type;
711 		cur_attr->oa_value_len = value_len;
712 		cur_attr->oa_value = NULL;
713 
714 		if ((pTemplate[i].pValue != NULL) &&
715 		    (pTemplate[i].ulValueLen > 0)) {
716 			ptr = malloc(pTemplate[i].ulValueLen);
717 			if (ptr == NULL) {
718 				rv = CKR_HOST_MEMORY;
719 				cur_i = i;
720 				goto fail_cleanup;
721 			} else {
722 				(void) memcpy(ptr, pTemplate[i].pValue,
723 				    pTemplate[i].ulValueLen);
724 				cur_attr->oa_value = ptr;
725 			}
726 		}
727 
728 		if ((is_token_obj != NULL) &&
729 		    (pTemplate[i].type == CKA_TOKEN)) {
730 			/* Get the CKA_TOKEN attribute value. */
731 			if (pTemplate[i].pValue == NULL) {
732 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
733 				cur_i = i;
734 				goto fail_cleanup;
735 			} else {
736 				*is_token_obj =
737 				    *(CK_BBOOL *)pTemplate[i].pValue;
738 			}
739 		}
740 
741 		cur_attr++;
742 	}
743 
744 	*obj_attrs = (char *)attrs;
745 	return (CKR_OK);
746 
747 fail_cleanup:
748 	cur_attr = attrs;
749 	for (i = 0; i < cur_i; i++) {
750 		if (cur_attr->oa_value != NULL) {
751 			(void) free(cur_attr->oa_value);
752 		}
753 		cur_attr++;
754 	}
755 
756 	(void) free(attrs);
757 	return (rv);
758 }
759 
760 
761 /*
762  * Copy the attribute values from obj_attrs to pTemplate.
763  * The obj_attrs is an image of the Template and is expected to have the
764  * same attributes in the same order and each one of the attribute pValue
765  * in obj_attr has enough space allocated for the corresponding valueLen
766  * in pTemplate.
767  */
768 CK_RV
769 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulCount,
770     caddr_t obj_attrs)
771 {
772 	crypto_object_attribute_t *cur_attr;
773 	CK_RV rv = CKR_OK;
774 	int i;
775 
776 	/* LINTED */
777 	cur_attr = (crypto_object_attribute_t *)obj_attrs;
778 	for (i = 0; i < ulCount; i++) {
779 		if (pTemplate[i].type != cur_attr->oa_type) {
780 			/* The attribute type doesn't match, this is bad. */
781 			rv = CKR_FUNCTION_FAILED;
782 			return (rv);
783 		}
784 
785 		pTemplate[i].ulValueLen = cur_attr->oa_value_len;
786 
787 		if ((pTemplate[i].pValue != NULL) &&
788 		    ((CK_LONG)pTemplate[i].ulValueLen != -1)) {
789 			(void) memcpy(pTemplate[i].pValue, cur_attr->oa_value,
790 			    pTemplate[i].ulValueLen);
791 		}
792 		cur_attr++;
793 	}
794 
795 	return (rv);
796 }
797 
798 /*
799  * Free the attribute storage in a crypto_object_attribute_t structure.
800  */
801 void
802 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount)
803 {
804 	crypto_object_attribute_t *cur_attr;
805 	int i;
806 
807 	if ((ulCount == 0) || (obj_attrs == NULL)) {
808 		return;
809 	}
810 
811 	/* LINTED */
812 	cur_attr = (crypto_object_attribute_t *)obj_attrs;
813 	for (i = 0; i < ulCount; i++) {
814 		/* XXX check that oa_value > 0 */
815 		if (cur_attr->oa_value != NULL) {
816 			free(cur_attr->oa_value);
817 		}
818 		cur_attr++;
819 	}
820 
821 	free(obj_attrs);
822 }
823 
824 /*
825  * This function is called by process_found_objects().  It will check the
826  * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then
827  * initialize all the necessary fields in the object wrapper "objp".
828  */
829 static CK_RV
830 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp,
831     kernel_object_t *objp,  crypto_object_id_t oid)
832 {
833 	CK_RV  rv = CKR_OK;
834 	crypto_object_get_attribute_value_t obj_ga;
835 	boolean_t is_pri_obj;
836 	boolean_t is_token_obj;
837 	CK_BBOOL pri_value, token_value;
838 	CK_ATTRIBUTE  pTemplate[2];
839 	int r;
840 
841 	/*
842 	 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this
843 	 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN.
844 	 */
845 	obj_ga.og_session = sp->k_session;
846 	obj_ga.og_handle = oid;
847 	obj_ga.og_count = 2;
848 
849 	pTemplate[0].type = CKA_PRIVATE;
850 	pTemplate[0].pValue = &pri_value;
851 	pTemplate[0].ulValueLen = sizeof (pri_value);
852 	pTemplate[1].type = CKA_TOKEN;
853 	pTemplate[1].pValue = &token_value;
854 	pTemplate[1].ulValueLen = sizeof (token_value);
855 	rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes,
856 	    NULL);
857 	if (rv != CKR_OK) {
858 		return (rv);
859 	}
860 
861 	while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
862 	    &obj_ga)) < 0) {
863 		if (errno != EINTR)
864 			break;
865 	}
866 	if (r < 0) {
867 		rv = CKR_FUNCTION_FAILED;
868 	} else {
869 		rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
870 	}
871 
872 	if (rv == CKR_OK) {
873 		rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes);
874 		if (rv == CKR_OK) {
875 			is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue;
876 			is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue;
877 		}
878 	}
879 
880 	free_object_attributes(obj_ga.og_attributes, 2);
881 	if (rv != CKR_OK) {
882 		return (rv);
883 	}
884 
885 	/* Make sure it is a token object. */
886 	if (!is_token_obj) {
887 		rv = CKR_ATTRIBUTE_VALUE_INVALID;
888 		return (rv);
889 	}
890 
891 	/* If it is a private object, make sure the user has logged in. */
892 	if (is_pri_obj && (pslot->sl_state != CKU_USER)) {
893 		rv = CKR_ATTRIBUTE_VALUE_INVALID;
894 		return (rv);
895 	}
896 
897 	objp->is_lib_obj = B_FALSE;
898 	objp->k_handle = oid;
899 	objp->bool_attr_mask |= TOKEN_BOOL_ON;
900 	if (is_pri_obj) {
901 		objp->bool_attr_mask |= PRIVATE_BOOL_ON;
902 	} else {
903 		objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;
904 	}
905 
906 	(void) pthread_mutex_init(&objp->object_mutex, NULL);
907 	objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;
908 	objp->session_handle = (CK_SESSION_HANDLE) sp;
909 
910 	return (CKR_OK);
911 }
912 
913 /*
914  * This function processes the kernel object handles returned from the
915  * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list
916  * and the number of object handles to the caller - C_FindObjects().
917  * The caller acquires the slot lock and the session lock.
918  */
919 CK_RV
920 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found,
921     CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu)
922 {
923 	CK_RV rv = CKR_OK;
924 	crypto_object_id_t  *oid_p;
925 	kernel_slot_t *pslot;
926 	kernel_object_t *objp;
927 	kernel_object_t *objp1;
928 	kernel_object_t *new_tobj_list = NULL;
929 	kernel_session_t  *sp;
930 	CK_ULONG num_obj_found = 0;
931 	boolean_t is_in_lib;
932 	int i;
933 
934 	if (obj_fu.fu_count == 0) {
935 		*found_obj_count = 0;
936 		return (CKR_OK);
937 	}
938 
939 	pslot = slot_table[cur_sp->ses_slotid];
940 
941 	/* LINTED */
942 	oid_p = (crypto_object_id_t *)obj_fu.fu_handles;
943 	for (i = 0; i < obj_fu.fu_count; i++) {
944 		is_in_lib = B_FALSE;
945 		/*
946 		 * Check if this oid has an object wrapper in the library
947 		 * already.  First, search the slot's token object list.
948 		 */
949 		objp = pslot->sl_tobj_list;
950 		while (!is_in_lib && objp) {
951 			if (objp->k_handle == *oid_p) {
952 				is_in_lib = B_TRUE;
953 			} else {
954 				objp = objp->next;
955 			}
956 		}
957 
958 		/*
959 		 * If it is not in the slot's token object list,
960 		 * search it in all the sessions.
961 		 */
962 		if (!is_in_lib) {
963 			sp = pslot->sl_sess_list;
964 			while (!is_in_lib && sp) {
965 				objp = sp->object_list;
966 				while (!is_in_lib && objp) {
967 					if (objp->k_handle == *oid_p) {
968 						is_in_lib = B_TRUE;
969 					} else {
970 						objp = objp->next;
971 					}
972 				}
973 				sp = sp->next;
974 			}
975 		}
976 
977 		/*
978 		 * If this object is in the library already, add its object
979 		 * wrapper to the returned find object list.
980 		 */
981 		if (is_in_lib) {
982 			obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
983 		}
984 
985 		/*
986 		 * If we still do not find it in the library.  This object
987 		 * must be a token object pre-existed in the HW provider.
988 		 * We need to create an object wrapper for it in the library.
989 		 */
990 		if (!is_in_lib) {
991 			objp1 = calloc(1, sizeof (kernel_object_t));
992 			if (objp1 == NULL) {
993 				rv = CKR_HOST_MEMORY;
994 				goto failed_exit;
995 			}
996 			rv = create_new_tobj_in_lib(pslot, cur_sp, objp1,
997 			    *oid_p);
998 
999 			if (rv == CKR_OK) {
1000 				/* Save the new object to the new_tobj_list. */
1001 				if (new_tobj_list == NULL) {
1002 					new_tobj_list = objp1;
1003 					objp1->next = NULL;
1004 					objp1->prev = NULL;
1005 				} else {
1006 					new_tobj_list->prev = objp1;
1007 					objp1->next = new_tobj_list;
1008 					objp1->prev = NULL;
1009 					new_tobj_list = objp1;
1010 				}
1011 			} else {
1012 				/*
1013 				 * If create_new_tobj_in_lib() doesn't fail
1014 				 * with CKR_HOST_MEMORY, the failure should be
1015 				 * caused by the attributes' checking. We will
1016 				 * just ignore this object and continue on.
1017 				 */
1018 				free(objp1);
1019 				if (rv == CKR_HOST_MEMORY) {
1020 					goto failed_exit;
1021 				}
1022 			}
1023 		}
1024 
1025 		/* Process next one */
1026 		oid_p++;
1027 	}
1028 
1029 	/*
1030 	 * Add the newly created token object wrappers to the found object
1031 	 * list and to the slot's token object list.
1032 	 */
1033 	if (new_tobj_list != NULL) {
1034 		/* Add to the obj_found array. */
1035 		objp = new_tobj_list;
1036 		while (objp) {
1037 			obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1038 			if (objp->next == NULL) {
1039 				break;
1040 			}
1041 			objp = objp->next;
1042 		}
1043 
1044 		/* Add to the beginning of the slot's token object list. */
1045 		if (pslot->sl_tobj_list != NULL) {
1046 			objp->next = pslot->sl_tobj_list;
1047 			pslot->sl_tobj_list->prev = objp;
1048 		}
1049 		pslot->sl_tobj_list = new_tobj_list;
1050 	}
1051 
1052 	*found_obj_count = num_obj_found;
1053 	return (CKR_OK);
1054 
1055 failed_exit:
1056 
1057 	/* Free the newly created token object wrappers. */
1058 	objp = new_tobj_list;
1059 	while (objp) {
1060 		objp1 = objp->next;
1061 		(void) pthread_mutex_destroy(&objp->object_mutex);
1062 		free(objp);
1063 		objp = objp1;
1064 	}
1065 
1066 	return (rv);
1067 }
1068 
1069 
1070 /*
1071  * Get the value of the CKA_PRIVATE attribute for the object just returned
1072  * from the HW provider.  This function will be called by any function
1073  * that creates a new object, because the CKA_PRIVATE value of an object is
1074  * token specific.  The CKA_PRIVATE attribute value of the new object will be
1075  * stored in the object structure in the library, which will be used later at
1076  * C_Logout to clean up all private objects.
1077  */
1078 CK_RV
1079 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid,
1080     CK_BBOOL *is_pri_obj)
1081 {
1082 	CK_RV  rv = CKR_OK;
1083 	crypto_object_get_attribute_value_t obj_ga;
1084 	crypto_object_attribute_t obj_attr;
1085 	CK_BBOOL pri_value;
1086 	int r;
1087 
1088 	obj_ga.og_session = sp->k_session;
1089 	obj_ga.og_handle = oid;
1090 	obj_ga.og_count = 1;
1091 
1092 	obj_attr.oa_type = CKA_PRIVATE;
1093 	obj_attr.oa_value = (char *)&pri_value;
1094 	obj_attr.oa_value_len = sizeof (CK_BBOOL);
1095 	obj_ga.og_attributes = (char *)&obj_attr;
1096 
1097 	while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
1098 	    &obj_ga)) < 0) {
1099 		if (errno != EINTR)
1100 			break;
1101 	}
1102 	if (r < 0) {
1103 		rv = CKR_FUNCTION_FAILED;
1104 	} else {
1105 		rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
1106 	}
1107 
1108 	if (rv == CKR_OK) {
1109 		*is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value;
1110 	}
1111 
1112 	return (rv);
1113 }
1114 
1115 
1116 CK_RV
1117 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type,
1118     CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags)
1119 {
1120 	crypto_get_provider_mechanism_info_t mechanism_info;
1121 	const char *string;
1122 	CK_FLAGS flags, mi_flags;
1123 	CK_RV rv;
1124 	int r;
1125 	char buf[11];   /* Num chars for representing ulong in ASCII */
1126 
1127 	if (type >= CKM_VENDOR_DEFINED) {
1128 		/* allocate/build a string containing the mechanism number */
1129 		(void) snprintf(buf, sizeof (buf), "%#lx", type);
1130 		string = buf;
1131 	} else {
1132 		string = pkcs11_mech2str(type);
1133 	}
1134 
1135 	if (string == NULL)
1136 		return (CKR_MECHANISM_INVALID);
1137 
1138 	(void) strcpy(mechanism_info.mi_mechanism_name, string);
1139 	mechanism_info.mi_provider_id = pslot->sl_provider_id;
1140 
1141 	while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO,
1142 	    &mechanism_info)) < 0) {
1143 		if (errno != EINTR)
1144 			break;
1145 	}
1146 	if (r < 0) {
1147 		rv = CKR_FUNCTION_FAILED;
1148 	} else {
1149 		rv = crypto2pkcs11_error_number(
1150 		    mechanism_info.mi_return_value);
1151 	}
1152 
1153 	if (rv != CKR_OK) {
1154 		return (rv);
1155 	}
1156 
1157 	/*
1158 	 * Atomic flags are not part of PKCS#11 so we filter
1159 	 * them out here.
1160 	 * Neither is CRYPTO_FG_MAC.
1161 	 */
1162 	mi_flags = mechanism_info.mi_flags;
1163 	mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC |
1164 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC |
1165 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
1166 	    CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1167 	    CRYPTO_FG_VERIFY_RECOVER_ATOMIC |
1168 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
1169 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC |
1170 	    CRYPTO_FG_MAC);
1171 
1172 	if (mi_flags == 0) {
1173 		return (CKR_MECHANISM_INVALID);
1174 	}
1175 
1176 	if (rv == CKR_OK) {
1177 		/* set the value of k_mi_flags first */
1178 		*k_mi_flags = mi_flags;
1179 
1180 		/* convert KEF flags into pkcs11 flags */
1181 		flags = CKF_HW;
1182 		if (mi_flags & CRYPTO_FG_ENCRYPT)
1183 			flags |= CKF_ENCRYPT;
1184 		if (mi_flags & CRYPTO_FG_DECRYPT) {
1185 			flags |= CKF_DECRYPT;
1186 			/*
1187 			 * Since we'll be emulating C_UnwrapKey() for some
1188 			 * cases, we can go ahead and claim CKF_UNWRAP
1189 			 */
1190 			flags |= CKF_UNWRAP;
1191 		}
1192 		if (mi_flags & CRYPTO_FG_DIGEST)
1193 			flags |= CKF_DIGEST;
1194 		if (mi_flags & CRYPTO_FG_SIGN)
1195 			flags |= CKF_SIGN;
1196 		if (mi_flags & CRYPTO_FG_SIGN_RECOVER)
1197 			flags |= CKF_SIGN_RECOVER;
1198 		if (mi_flags & CRYPTO_FG_VERIFY)
1199 			flags |= CKF_VERIFY;
1200 		if (mi_flags & CRYPTO_FG_VERIFY_RECOVER)
1201 			flags |= CKF_VERIFY_RECOVER;
1202 		if (mi_flags & CRYPTO_FG_GENERATE)
1203 			flags |= CKF_GENERATE;
1204 		if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR)
1205 			flags |= CKF_GENERATE_KEY_PAIR;
1206 		if (mi_flags & CRYPTO_FG_WRAP)
1207 			flags |= CKF_WRAP;
1208 		if (mi_flags & CRYPTO_FG_UNWRAP)
1209 			flags |= CKF_UNWRAP;
1210 		if (mi_flags & CRYPTO_FG_DERIVE)
1211 			flags |= CKF_DERIVE;
1212 
1213 		pInfo->ulMinKeySize = mechanism_info.mi_min_key_size;
1214 		pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size;
1215 		pInfo->flags = flags;
1216 
1217 	}
1218 
1219 	return (rv);
1220 }
1221 
1222 /*
1223  * Unfortunately the kernel and PKCS#11 use a slightly different struct to
1224  * specify CCM parameters.
1225  */
1226 void
1227 p11_to_kernel_ccm_params(const CK_CCM_PARAMS *in, CK_AES_CCM_PARAMS *out)
1228 {
1229 	out->ulMACSize = in->ulMACLen;
1230 	out->ulNonceSize = in->ulNonceLen;
1231 	out->ulAuthDataSize = in->ulAADLen;
1232 	out->ulDataSize = in->ulDataLen;
1233 	out->nonce = in->pNonce;
1234 	out->authData = in->pAAD;
1235 }
1236