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