17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 56f3f1c68Skrishna * Common Development and Distribution License (the "License"). 66f3f1c68Skrishna * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*e8ab7b17SZdenek Kotala * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <stdlib.h> 267c478bd9Sstevel@tonic-gate #include <string.h> 277c478bd9Sstevel@tonic-gate #include <strings.h> 282321aa36Sda73024 #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <cryptoutil.h> 307c478bd9Sstevel@tonic-gate #include <errno.h> 317c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 327c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h> 337c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctl.h> 347c478bd9Sstevel@tonic-gate #include "kernelGlobal.h" 357c478bd9Sstevel@tonic-gate #include "kernelObject.h" 367c478bd9Sstevel@tonic-gate #include "kernelSlot.h" 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #define ENCODE_ATTR(type, value, len) { \ 397c478bd9Sstevel@tonic-gate cur_attr->oa_type = type; \ 407c478bd9Sstevel@tonic-gate (void) memcpy(ptr, value, len); \ 417c478bd9Sstevel@tonic-gate cur_attr->oa_value = ptr; \ 427c478bd9Sstevel@tonic-gate cur_attr->oa_value_len = len; \ 437c478bd9Sstevel@tonic-gate cur_attr++; \ 447c478bd9Sstevel@tonic-gate } 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * In order to fit everything on one line, the 'CRYPTO_' prefix 487c478bd9Sstevel@tonic-gate * has been dropped from the KCF #defines, e.g. 497c478bd9Sstevel@tonic-gate * CRYPTO_SUCCESS becomes SUCCESS. 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate 52*e8ab7b17SZdenek Kotala static CK_RV error_number_table[CRYPTO_LAST_ERROR+1] = { 537c478bd9Sstevel@tonic-gate CKR_OK, /* SUCCESS */ 547c478bd9Sstevel@tonic-gate CKR_CANCEL, /* CANCEL */ 557c478bd9Sstevel@tonic-gate CKR_HOST_MEMORY, /* HOST_MEMORY */ 567c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* GENERAL_ERROR */ 577c478bd9Sstevel@tonic-gate CKR_FUNCTION_FAILED, /* FAILED */ 587c478bd9Sstevel@tonic-gate CKR_ARGUMENTS_BAD, /* ARGUMENTS_BAD */ 597c478bd9Sstevel@tonic-gate CKR_ATTRIBUTE_READ_ONLY, /* ATTRIBUTE_READ_ONLY */ 607c478bd9Sstevel@tonic-gate CKR_ATTRIBUTE_SENSITIVE, /* ATTRIBUTE_SENSITIVE */ 617c478bd9Sstevel@tonic-gate CKR_ATTRIBUTE_TYPE_INVALID, /* ATTRIBUTE_TYPE_INVALID */ 627c478bd9Sstevel@tonic-gate CKR_ATTRIBUTE_VALUE_INVALID, /* ATTRIBUTE_VALUE_INVALID */ 637c478bd9Sstevel@tonic-gate CKR_FUNCTION_FAILED, /* CANCELED */ 647c478bd9Sstevel@tonic-gate CKR_DATA_INVALID, /* DATA_INVALID */ 657c478bd9Sstevel@tonic-gate CKR_DATA_LEN_RANGE, /* DATA_LEN_RANGE */ 667c478bd9Sstevel@tonic-gate CKR_DEVICE_ERROR, /* DEVICE_ERROR */ 677c478bd9Sstevel@tonic-gate CKR_DEVICE_MEMORY, /* DEVICE_MEMORY */ 687c478bd9Sstevel@tonic-gate CKR_DEVICE_REMOVED, /* DEVICE_REMOVED */ 697c478bd9Sstevel@tonic-gate CKR_ENCRYPTED_DATA_INVALID, /* ENCRYPTED_DATA_INVALID */ 707c478bd9Sstevel@tonic-gate CKR_ENCRYPTED_DATA_LEN_RANGE, /* ENCRYPTED_DATA_LEN_RANGE */ 717c478bd9Sstevel@tonic-gate CKR_KEY_HANDLE_INVALID, /* KEY_HANDLE_INVALID */ 727c478bd9Sstevel@tonic-gate CKR_KEY_SIZE_RANGE, /* KEY_SIZE_RANGE */ 737c478bd9Sstevel@tonic-gate CKR_KEY_TYPE_INCONSISTENT, /* KEY_TYPE_INCONSISTENT */ 747c478bd9Sstevel@tonic-gate CKR_KEY_NOT_NEEDED, /* KEY_NOT_NEEDED */ 757c478bd9Sstevel@tonic-gate CKR_KEY_CHANGED, /* KEY_CHANGED */ 767c478bd9Sstevel@tonic-gate CKR_KEY_NEEDED, /* KEY_NEEDED */ 777c478bd9Sstevel@tonic-gate CKR_KEY_INDIGESTIBLE, /* KEY_INDIGESTIBLE */ 787c478bd9Sstevel@tonic-gate CKR_KEY_FUNCTION_NOT_PERMITTED, /* KEY_FUNCTION_NOT_PERMITTED */ 797c478bd9Sstevel@tonic-gate CKR_KEY_NOT_WRAPPABLE, /* KEY_NOT_WRAPPABLE */ 807c478bd9Sstevel@tonic-gate CKR_KEY_UNEXTRACTABLE, /* KEY_UNEXTRACTABLE */ 817c478bd9Sstevel@tonic-gate CKR_MECHANISM_INVALID, /* MECHANISM_INVALID */ 827c478bd9Sstevel@tonic-gate CKR_MECHANISM_PARAM_INVALID, /* MECHANISM_PARAM_INVALID */ 837c478bd9Sstevel@tonic-gate CKR_OBJECT_HANDLE_INVALID, /* OBJECT_HANDLE_INVALID */ 847c478bd9Sstevel@tonic-gate CKR_OPERATION_ACTIVE, /* OPERATION_ACTIVE */ 857c478bd9Sstevel@tonic-gate CKR_OPERATION_NOT_INITIALIZED, /* OPERATION_NOT_INITIALIZED */ 867c478bd9Sstevel@tonic-gate CKR_PIN_INCORRECT, /* PIN_INCORRECT */ 877c478bd9Sstevel@tonic-gate CKR_PIN_INVALID, /* PIN_INVALID */ 887c478bd9Sstevel@tonic-gate CKR_PIN_LEN_RANGE, /* PIN_LEN_RANGE */ 897c478bd9Sstevel@tonic-gate CKR_PIN_EXPIRED, /* PIN_EXPIRED */ 907c478bd9Sstevel@tonic-gate CKR_PIN_LOCKED, /* PIN_LOCKED */ 917c478bd9Sstevel@tonic-gate CKR_SESSION_CLOSED, /* SESSION_CLOSED */ 927c478bd9Sstevel@tonic-gate CKR_SESSION_COUNT, /* SESSION_COUNT */ 937c478bd9Sstevel@tonic-gate CKR_SESSION_HANDLE_INVALID, /* SESSION_HANDLE_INVALID */ 947c478bd9Sstevel@tonic-gate CKR_SESSION_READ_ONLY, /* SESSION_READ_ONLY */ 957c478bd9Sstevel@tonic-gate CKR_SESSION_EXISTS, /* SESSION_EXISTS */ 967c478bd9Sstevel@tonic-gate CKR_SESSION_READ_ONLY_EXISTS, /* SESSION_READ_ONLY_EXISTS */ 977c478bd9Sstevel@tonic-gate CKR_SESSION_READ_WRITE_SO_EXISTS, /* SESSION_READ_WRITE_SO_EXISTS */ 987c478bd9Sstevel@tonic-gate CKR_SIGNATURE_INVALID, /* SIGNATURE_INVALID */ 997c478bd9Sstevel@tonic-gate CKR_SIGNATURE_LEN_RANGE, /* SIGNATURE_LEN_RANGE */ 1007c478bd9Sstevel@tonic-gate CKR_TEMPLATE_INCOMPLETE, /* TEMPLATE_INCOMPLETE */ 1017c478bd9Sstevel@tonic-gate CKR_TEMPLATE_INCONSISTENT, /* TEMPLATE_INCONSISTENT */ 1027c478bd9Sstevel@tonic-gate CKR_UNWRAPPING_KEY_HANDLE_INVALID, /* UNWRAPPING_KEY_HANDLE_INVALID */ 1037c478bd9Sstevel@tonic-gate CKR_UNWRAPPING_KEY_SIZE_RANGE, /* UNWRAPPING_KEY_SIZE_RANGE */ 1047c478bd9Sstevel@tonic-gate CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, /* UNWRAPPING_KEY_TYPE_INCONSISTENT */ 1057c478bd9Sstevel@tonic-gate CKR_USER_ALREADY_LOGGED_IN, /* USER_ALREADY_LOGGED_IN */ 1067c478bd9Sstevel@tonic-gate CKR_USER_NOT_LOGGED_IN, /* USER_NOT_LOGGED_IN */ 1077c478bd9Sstevel@tonic-gate CKR_USER_PIN_NOT_INITIALIZED, /* USER_PIN_NOT_INITIALIZED */ 1087c478bd9Sstevel@tonic-gate CKR_USER_TYPE_INVALID, /* USER_TYPE_INVALID */ 1097c478bd9Sstevel@tonic-gate CKR_USER_ANOTHER_ALREADY_LOGGED_IN, /* USER_ANOTHER_ALREADY_LOGGED_IN */ 1107c478bd9Sstevel@tonic-gate CKR_USER_TOO_MANY_TYPES, /* USER_TOO_MANY_TYPES */ 1117c478bd9Sstevel@tonic-gate CKR_WRAPPED_KEY_INVALID, /* WRAPPED_KEY_INVALID */ 1127c478bd9Sstevel@tonic-gate CKR_WRAPPED_KEY_LEN_RANGE, /* WRAPPED_KEY_LEN_RANGE */ 1137c478bd9Sstevel@tonic-gate CKR_WRAPPING_KEY_HANDLE_INVALID, /* WRAPPING_KEY_HANDLE_INVALID */ 1147c478bd9Sstevel@tonic-gate CKR_WRAPPING_KEY_SIZE_RANGE, /* WRAPPING_KEY_SIZE_RANGE */ 1157c478bd9Sstevel@tonic-gate CKR_WRAPPING_KEY_TYPE_INCONSISTENT, /* WRAPPING_KEY_TYPE_INCONSISTENT */ 1167c478bd9Sstevel@tonic-gate CKR_RANDOM_SEED_NOT_SUPPORTED, /* RANDOM_SEED_NOT_SUPPORTED */ 1177c478bd9Sstevel@tonic-gate CKR_RANDOM_NO_RNG, /* RANDOM_NO_RNG */ 1187c478bd9Sstevel@tonic-gate CKR_DOMAIN_PARAMS_INVALID, /* DOMAIN_PARAMS_INVALID */ 1197c478bd9Sstevel@tonic-gate CKR_BUFFER_TOO_SMALL, /* BUFFER_TOO_SMALL */ 1207c478bd9Sstevel@tonic-gate CKR_INFORMATION_SENSITIVE, /* INFORMATION_SENSITIVE */ 1217c478bd9Sstevel@tonic-gate CKR_FUNCTION_NOT_SUPPORTED, /* NOT_SUPPORTED */ 1227c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* QUEUED */ 1237c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* BUFFER_TOO_BIG */ 1247c478bd9Sstevel@tonic-gate CKR_OPERATION_NOT_INITIALIZED, /* INVALID_CONTEXT */ 1257c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* INVALID_MAC */ 1267c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* MECH_NOT_SUPPORTED */ 1277c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* INCONSISTENT_ATTRIBUTE */ 1287c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* NO_PERMISSION */ 1297c478bd9Sstevel@tonic-gate CKR_SLOT_ID_INVALID, /* INVALID_PROVIDER_ID */ 1307c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* VERSION_MISMATCH */ 1317c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* BUSY */ 1327c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* UNKNOWN_PROVIDER */ 1337c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* MODVERIFICATION_FAILED */ 1347c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* OLD_CTX_TEMPLATE */ 1357c478bd9Sstevel@tonic-gate CKR_GENERAL_ERROR, /* WEAK_KEY */ 136*e8ab7b17SZdenek Kotala CKR_GENERAL_ERROR /* FIPS140_ERROR */ 1377c478bd9Sstevel@tonic-gate }; 1387c478bd9Sstevel@tonic-gate 139*e8ab7b17SZdenek Kotala #if CRYPTO_LAST_ERROR != CRYPTO_FIPS140_ERROR 140*e8ab7b17SZdenek Kotala #error "Crypto to PKCS11 error mapping table needs to be updated!" 141*e8ab7b17SZdenek Kotala #endif 142*e8ab7b17SZdenek Kotala 1437c478bd9Sstevel@tonic-gate /* 1447c478bd9Sstevel@tonic-gate * Map KCF error codes into PKCS11 error codes. 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate CK_RV 1477c478bd9Sstevel@tonic-gate crypto2pkcs11_error_number(uint_t n) 1487c478bd9Sstevel@tonic-gate { 149*e8ab7b17SZdenek Kotala if (n >= sizeof (error_number_table) / sizeof (error_number_table[0])) 1507c478bd9Sstevel@tonic-gate return (CKR_GENERAL_ERROR); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate return (error_number_table[n]); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate 1556f3f1c68Skrishna #define MECH_HASH(type) (((uintptr_t)type) % KMECH_HASHTABLE_SIZE) 1566f3f1c68Skrishna /* 1576f3f1c68Skrishna * Serialize writes to the hash table. We don't need a per bucket lock as 1586f3f1c68Skrishna * there are only a few writes and we don't need the lock for reads. 1596f3f1c68Skrishna */ 1601f49a79aSZdenek Kotala pthread_mutex_t mechhash_mutex = PTHREAD_MUTEX_INITIALIZER; 1616f3f1c68Skrishna 1626f3f1c68Skrishna static CK_RV 1636f3f1c68Skrishna kmech_hash_insert(CK_MECHANISM_TYPE type, crypto_mech_type_t kmech) 1646f3f1c68Skrishna { 1656f3f1c68Skrishna uint_t h; 1666f3f1c68Skrishna kmh_elem_t *elem, *cur; 1676f3f1c68Skrishna 1686f3f1c68Skrishna elem = malloc(sizeof (kmh_elem_t)); 1696f3f1c68Skrishna if (elem == NULL) 1706f3f1c68Skrishna return (CKR_HOST_MEMORY); 1716f3f1c68Skrishna 1726f3f1c68Skrishna h = MECH_HASH(type); 1736f3f1c68Skrishna elem->type = type; 1746f3f1c68Skrishna elem->kmech = kmech; 1756f3f1c68Skrishna 1766f3f1c68Skrishna (void) pthread_mutex_lock(&mechhash_mutex); 1776f3f1c68Skrishna for (cur = kernel_mechhash[h]; cur != NULL; cur = cur->knext) { 1786f3f1c68Skrishna if (type == cur->type) { 1796f3f1c68Skrishna /* Some other thread beat us to it. */ 1806f3f1c68Skrishna (void) pthread_mutex_unlock(&mechhash_mutex); 1816f3f1c68Skrishna free(elem); 1826f3f1c68Skrishna return (CKR_OK); 1836f3f1c68Skrishna } 1846f3f1c68Skrishna } 1856f3f1c68Skrishna elem->knext = kernel_mechhash[h]; 1866f3f1c68Skrishna kernel_mechhash[h] = elem; 1876f3f1c68Skrishna (void) pthread_mutex_unlock(&mechhash_mutex); 1886f3f1c68Skrishna 1896f3f1c68Skrishna return (CKR_OK); 1906f3f1c68Skrishna } 1916f3f1c68Skrishna 1927c478bd9Sstevel@tonic-gate CK_RV 1937c478bd9Sstevel@tonic-gate kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number) 1947c478bd9Sstevel@tonic-gate { 1957c478bd9Sstevel@tonic-gate crypto_get_mechanism_number_t get_number; 1962321aa36Sda73024 const char *string; 1977c478bd9Sstevel@tonic-gate CK_RV rv; 1987c478bd9Sstevel@tonic-gate int r; 1996f3f1c68Skrishna kmh_elem_t *elem; 2006f3f1c68Skrishna uint_t h; 2012321aa36Sda73024 char buf[11]; /* Num chars for representing ulong in ASCII */ 2026f3f1c68Skrishna 2036f3f1c68Skrishna /* 2046f3f1c68Skrishna * Search for an existing entry. No need to lock since we are 2056f3f1c68Skrishna * just a reader and we never free the entries in the hash table. 2066f3f1c68Skrishna */ 2076f3f1c68Skrishna h = MECH_HASH(type); 2086f3f1c68Skrishna for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) { 2096f3f1c68Skrishna if (type == elem->type) { 2106f3f1c68Skrishna *k_number = elem->kmech; 2116f3f1c68Skrishna return (CKR_OK); 2126f3f1c68Skrishna } 2136f3f1c68Skrishna } 2147c478bd9Sstevel@tonic-gate 21576d1b5a9Sda73024 if (type >= CKM_VENDOR_DEFINED) { 2162321aa36Sda73024 (void) snprintf(buf, sizeof (buf), "%#lx", type); 2172321aa36Sda73024 string = buf; 2182321aa36Sda73024 } else { 2197c478bd9Sstevel@tonic-gate string = pkcs11_mech2str(type); 2202321aa36Sda73024 } 2212321aa36Sda73024 2227c478bd9Sstevel@tonic-gate if (string == NULL) 2237c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID); 2247c478bd9Sstevel@tonic-gate 2252321aa36Sda73024 get_number.pn_mechanism_string = (char *)string; 2267c478bd9Sstevel@tonic-gate get_number.pn_mechanism_len = strlen(string) + 1; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER, 2297c478bd9Sstevel@tonic-gate &get_number)) < 0) { 2307c478bd9Sstevel@tonic-gate if (errno != EINTR) 2317c478bd9Sstevel@tonic-gate break; 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate if (r < 0) { 2347c478bd9Sstevel@tonic-gate rv = CKR_MECHANISM_INVALID; 2357c478bd9Sstevel@tonic-gate } else { 2367c478bd9Sstevel@tonic-gate if (get_number.pn_return_value != CRYPTO_SUCCESS) { 2377c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number( 2387c478bd9Sstevel@tonic-gate get_number.pn_return_value); 2397c478bd9Sstevel@tonic-gate } else { 2407c478bd9Sstevel@tonic-gate rv = CKR_OK; 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2446f3f1c68Skrishna if (rv == CKR_OK) { 2457c478bd9Sstevel@tonic-gate *k_number = get_number.pn_internal_number; 2466f3f1c68Skrishna /* Add this to the hash table */ 2476f3f1c68Skrishna (void) kmech_hash_insert(type, *k_number); 2486f3f1c68Skrishna } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate return (rv); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * Return the value of a secret key object. 2567c478bd9Sstevel@tonic-gate * This routine allocates memory for the value. 2577c478bd9Sstevel@tonic-gate * A null pointer is returned on error. 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate unsigned char * 2607c478bd9Sstevel@tonic-gate get_symmetric_key_value(kernel_object_t *key_p) 2617c478bd9Sstevel@tonic-gate { 2627c478bd9Sstevel@tonic-gate uint8_t *cipherKey; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate switch (key_p->class) { 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate case CKO_SECRET_KEY: 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len); 2697c478bd9Sstevel@tonic-gate if (cipherKey == NULL) 2707c478bd9Sstevel@tonic-gate return (NULL); 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate (void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value, 2737c478bd9Sstevel@tonic-gate OBJ_SEC(key_p)->sk_value_len); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate return (cipherKey); 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate default: 2787c478bd9Sstevel@tonic-gate return (NULL); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* 2837c478bd9Sstevel@tonic-gate * Convert a RSA private key object into a crypto_key structure. 2847c478bd9Sstevel@tonic-gate * Memory is allocated for each attribute stored in the crypto_key 2857c478bd9Sstevel@tonic-gate * structure. Memory for the crypto_key structure is not 2867c478bd9Sstevel@tonic-gate * allocated. Attributes can be freed by free_key_attributes(). 2877c478bd9Sstevel@tonic-gate */ 2887c478bd9Sstevel@tonic-gate CK_RV 2897c478bd9Sstevel@tonic-gate get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 2907c478bd9Sstevel@tonic-gate { 2917c478bd9Sstevel@tonic-gate biginteger_t *big; 2927c478bd9Sstevel@tonic-gate crypto_object_attribute_t *attrs, *cur_attr; 2937c478bd9Sstevel@tonic-gate char *ptr; 2947c478bd9Sstevel@tonic-gate CK_RV rv; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex); 2977c478bd9Sstevel@tonic-gate if (object_p->key_type != CKK_RSA || 2987c478bd9Sstevel@tonic-gate object_p->class != CKO_PRIVATE_KEY) { 2997c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 3007c478bd9Sstevel@tonic-gate return (CKR_ATTRIBUTE_TYPE_INVALID); 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate attrs = calloc(1, 3047c478bd9Sstevel@tonic-gate RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 3057c478bd9Sstevel@tonic-gate if (attrs == NULL) { 3067c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 3077c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate key->ck_format = CRYPTO_KEY_ATTR_LIST; 3117c478bd9Sstevel@tonic-gate key->ck_attrs = attrs; 3127c478bd9Sstevel@tonic-gate cur_attr = attrs; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * Allocate memory for each key attribute and set up the value 3167c478bd9Sstevel@tonic-gate * value length. 3177c478bd9Sstevel@tonic-gate */ 3187c478bd9Sstevel@tonic-gate key->ck_count = 0; 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* CKA_MODULUS is required. */ 3217c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_MOD(object_p); 3227c478bd9Sstevel@tonic-gate if (big->big_value == NULL) { 3237c478bd9Sstevel@tonic-gate rv = CKR_ATTRIBUTE_TYPE_INVALID; 3247c478bd9Sstevel@tonic-gate goto fail_cleanup; 3257c478bd9Sstevel@tonic-gate } else { 3267c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3277c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3287c478bd9Sstevel@tonic-gate goto fail_cleanup; 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 3317c478bd9Sstevel@tonic-gate key->ck_count++; 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate /* CKA_PRIVATE_EXPONENT is required. */ 3357c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIEXPO(object_p); 3367c478bd9Sstevel@tonic-gate if (big->big_value == NULL) { 3377c478bd9Sstevel@tonic-gate rv = CKR_ATTRIBUTE_TYPE_INVALID; 3387c478bd9Sstevel@tonic-gate goto fail_cleanup; 3397c478bd9Sstevel@tonic-gate } else { 3407c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3417c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3427c478bd9Sstevel@tonic-gate goto fail_cleanup; 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value, 3457c478bd9Sstevel@tonic-gate big->big_value_len); 3467c478bd9Sstevel@tonic-gate key->ck_count++; 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* CKA_PRIME_1 is optional. */ 3507c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIME1(object_p); 3517c478bd9Sstevel@tonic-gate if (big->big_value != NULL) { 3527c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3537c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3547c478bd9Sstevel@tonic-gate goto fail_cleanup; 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len); 3577c478bd9Sstevel@tonic-gate key->ck_count++; 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /* CKA_PRIME_2 is optional. */ 3617c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_PRIME2(object_p); 3627c478bd9Sstevel@tonic-gate if (big->big_value != NULL) { 3637c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3647c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3657c478bd9Sstevel@tonic-gate goto fail_cleanup; 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len); 3687c478bd9Sstevel@tonic-gate key->ck_count++; 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* CKA_EXPONENT_1 is optional. */ 3727c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_EXPO1(object_p); 3737c478bd9Sstevel@tonic-gate if (big->big_value != NULL) { 3747c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3757c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3767c478bd9Sstevel@tonic-gate goto fail_cleanup; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_EXPONENT_1, big->big_value, 3797c478bd9Sstevel@tonic-gate big->big_value_len); 3807c478bd9Sstevel@tonic-gate key->ck_count++; 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* CKA_EXPONENT_2 is optional. */ 3847c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_EXPO2(object_p); 3857c478bd9Sstevel@tonic-gate if (big->big_value != NULL) { 3867c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3877c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 3887c478bd9Sstevel@tonic-gate goto fail_cleanup; 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_EXPONENT_2, big->big_value, 3917c478bd9Sstevel@tonic-gate big->big_value_len); 3927c478bd9Sstevel@tonic-gate key->ck_count++; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate /* CKA_COEFFICIENT is optional. */ 3967c478bd9Sstevel@tonic-gate big = OBJ_PRI_RSA_COEF(object_p); 3977c478bd9Sstevel@tonic-gate if (big->big_value != NULL) { 3987c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) { 3997c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 4007c478bd9Sstevel@tonic-gate goto fail_cleanup; 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_COEFFICIENT, big->big_value, 4037c478bd9Sstevel@tonic-gate big->big_value_len); 4047c478bd9Sstevel@tonic-gate key->ck_count++; 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4087c478bd9Sstevel@tonic-gate return (CKR_OK); 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate fail_cleanup: 4117c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4127c478bd9Sstevel@tonic-gate free_key_attributes(key); 4137c478bd9Sstevel@tonic-gate return (rv); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * Convert a RSA public key object into a crypto_key structure. 4187c478bd9Sstevel@tonic-gate * Memory is allocated for each attribute stored in the crypto_key 4197c478bd9Sstevel@tonic-gate * structure. Memory for the crypto_key structure is not 4207c478bd9Sstevel@tonic-gate * allocated. Attributes can be freed by free_key_attributes(). 4217c478bd9Sstevel@tonic-gate */ 4227c478bd9Sstevel@tonic-gate CK_RV 4237c478bd9Sstevel@tonic-gate get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 4247c478bd9Sstevel@tonic-gate { 4257c478bd9Sstevel@tonic-gate biginteger_t *big; 4267c478bd9Sstevel@tonic-gate crypto_object_attribute_t *attrs, *cur_attr; 4277c478bd9Sstevel@tonic-gate char *ptr; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex); 4307c478bd9Sstevel@tonic-gate if (object_p->key_type != CKK_RSA || 4317c478bd9Sstevel@tonic-gate object_p->class != CKO_PUBLIC_KEY) { 4327c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4337c478bd9Sstevel@tonic-gate return (CKR_ATTRIBUTE_TYPE_INVALID); 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate attrs = calloc(1, 4377c478bd9Sstevel@tonic-gate RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 4387c478bd9Sstevel@tonic-gate if (attrs == NULL) { 4397c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4407c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate key->ck_format = CRYPTO_KEY_ATTR_LIST; 4447c478bd9Sstevel@tonic-gate key->ck_count = RSA_PUB_ATTR_COUNT; 4457c478bd9Sstevel@tonic-gate key->ck_attrs = attrs; 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate cur_attr = attrs; 4487c478bd9Sstevel@tonic-gate big = OBJ_PUB_RSA_PUBEXPO(object_p); 4497c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 4507c478bd9Sstevel@tonic-gate goto mem_failure; 4517c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len); 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate big = OBJ_PUB_RSA_MOD(object_p); 4547c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 4557c478bd9Sstevel@tonic-gate goto mem_failure; 4567c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len); 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate if ((ptr = malloc(sizeof (CK_ULONG))) == NULL) 4597c478bd9Sstevel@tonic-gate goto mem_failure; 4607c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p), 4617c478bd9Sstevel@tonic-gate sizeof (CK_ULONG)); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4647c478bd9Sstevel@tonic-gate return (CKR_OK); 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate mem_failure: 4677c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 4687c478bd9Sstevel@tonic-gate free_key_attributes(key); 4697c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate /* 4737c478bd9Sstevel@tonic-gate * Free attribute storage in a crypto_key structure. 4747c478bd9Sstevel@tonic-gate */ 4757c478bd9Sstevel@tonic-gate void 4767c478bd9Sstevel@tonic-gate free_key_attributes(crypto_key_t *key) 4777c478bd9Sstevel@tonic-gate { 4787c478bd9Sstevel@tonic-gate int i; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate if (key->ck_format == CRYPTO_KEY_ATTR_LIST && 4817c478bd9Sstevel@tonic-gate (key->ck_count > 0) && key->ck_attrs != NULL) { 4827c478bd9Sstevel@tonic-gate for (i = 0; i < key->ck_count; i++) { 4837c478bd9Sstevel@tonic-gate if (key->ck_attrs[i].oa_value != NULL) { 4847c478bd9Sstevel@tonic-gate bzero(key->ck_attrs[i].oa_value, 4857c478bd9Sstevel@tonic-gate key->ck_attrs[i].oa_value_len); 4867c478bd9Sstevel@tonic-gate free(key->ck_attrs[i].oa_value); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate free(key->ck_attrs); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate /* 4957c478bd9Sstevel@tonic-gate * Convert a DSA private key object into a crypto_key structure. 4967c478bd9Sstevel@tonic-gate * Memory is allocated for each attribute stored in the crypto_key 4977c478bd9Sstevel@tonic-gate * structure. Memory for the crypto_key structure is not 4987c478bd9Sstevel@tonic-gate * allocated. Attributes can be freed by free_dsa_key_attributes(). 4997c478bd9Sstevel@tonic-gate */ 5007c478bd9Sstevel@tonic-gate CK_RV 5017c478bd9Sstevel@tonic-gate get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key) 5027c478bd9Sstevel@tonic-gate { 5037c478bd9Sstevel@tonic-gate biginteger_t *big; 5047c478bd9Sstevel@tonic-gate crypto_object_attribute_t *attrs, *cur_attr; 5057c478bd9Sstevel@tonic-gate char *ptr; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex); 5087c478bd9Sstevel@tonic-gate if (object_p->key_type != CKK_DSA || 5097c478bd9Sstevel@tonic-gate object_p->class != CKO_PRIVATE_KEY) { 5107c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5117c478bd9Sstevel@tonic-gate return (CKR_ATTRIBUTE_TYPE_INVALID); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate attrs = calloc(1, 5157c478bd9Sstevel@tonic-gate DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 5167c478bd9Sstevel@tonic-gate if (attrs == NULL) { 5177c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5187c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate key->ck_format = CRYPTO_KEY_ATTR_LIST; 5227c478bd9Sstevel@tonic-gate key->ck_count = DSA_ATTR_COUNT; 5237c478bd9Sstevel@tonic-gate key->ck_attrs = attrs; 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate cur_attr = attrs; 5267c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_PRIME(object_p); 5277c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5287c478bd9Sstevel@tonic-gate goto mem_failure; 5297c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_SUBPRIME(object_p); 5327c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5337c478bd9Sstevel@tonic-gate goto mem_failure; 5347c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_BASE(object_p); 5377c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5387c478bd9Sstevel@tonic-gate goto mem_failure; 5397c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate big = OBJ_PRI_DSA_VALUE(object_p); 5427c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5437c478bd9Sstevel@tonic-gate goto mem_failure; 5447c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5477c478bd9Sstevel@tonic-gate return (CKR_OK); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate mem_failure: 5507c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5517c478bd9Sstevel@tonic-gate free_key_attributes(key); 5527c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Convert a DSA public key object into a crypto_key structure. 5587c478bd9Sstevel@tonic-gate * Memory is allocated for each attribute stored in the crypto_key 5597c478bd9Sstevel@tonic-gate * structure. Memory for the crypto_key structure is not 5607c478bd9Sstevel@tonic-gate * allocated. Attributes can be freed by free_dsa_key_attributes(). 5617c478bd9Sstevel@tonic-gate */ 5627c478bd9Sstevel@tonic-gate CK_RV 5637c478bd9Sstevel@tonic-gate get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key) 5647c478bd9Sstevel@tonic-gate { 5657c478bd9Sstevel@tonic-gate biginteger_t *big; 5667c478bd9Sstevel@tonic-gate crypto_object_attribute_t *attrs, *cur_attr; 5677c478bd9Sstevel@tonic-gate char *ptr; 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object_p->object_mutex); 5707c478bd9Sstevel@tonic-gate if (object_p->key_type != CKK_DSA || 5717c478bd9Sstevel@tonic-gate object_p->class != CKO_PUBLIC_KEY) { 5727c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5737c478bd9Sstevel@tonic-gate return (CKR_ATTRIBUTE_TYPE_INVALID); 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate attrs = calloc(1, 5777c478bd9Sstevel@tonic-gate DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t)); 5787c478bd9Sstevel@tonic-gate if (attrs == NULL) { 5797c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 5807c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate key->ck_format = CRYPTO_KEY_ATTR_LIST; 5847c478bd9Sstevel@tonic-gate key->ck_count = DSA_ATTR_COUNT; 5857c478bd9Sstevel@tonic-gate key->ck_attrs = attrs; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate cur_attr = attrs; 5887c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_PRIME(object_p); 5897c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5907c478bd9Sstevel@tonic-gate goto mem_failure; 5917c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len); 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_SUBPRIME(object_p); 5947c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 5957c478bd9Sstevel@tonic-gate goto mem_failure; 5967c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len); 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_BASE(object_p); 5997c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 6007c478bd9Sstevel@tonic-gate goto mem_failure; 6017c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len); 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate big = OBJ_PUB_DSA_VALUE(object_p); 6047c478bd9Sstevel@tonic-gate if ((ptr = malloc(big->big_value_len)) == NULL) 6057c478bd9Sstevel@tonic-gate goto mem_failure; 6067c478bd9Sstevel@tonic-gate ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 6097c478bd9Sstevel@tonic-gate return (CKR_OK); 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate mem_failure: 6127c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object_p->object_mutex); 6137c478bd9Sstevel@tonic-gate free_key_attributes(key); 6147c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate /* 619034448feSmcpowers * Convert a EC private key object into a crypto_key structure. 620034448feSmcpowers * Memory is allocated for each attribute stored in the crypto_key 621034448feSmcpowers * structure. Memory for the crypto_key structure is not 622034448feSmcpowers * allocated. Attributes can be freed by free_ec_key_attributes(). 623034448feSmcpowers */ 624034448feSmcpowers CK_RV 625034448feSmcpowers get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key) 626034448feSmcpowers { 627034448feSmcpowers biginteger_t *big; 628034448feSmcpowers crypto_object_attribute_t *attrs, *cur_attr; 629034448feSmcpowers CK_ATTRIBUTE tmp; 630034448feSmcpowers char *ptr; 631034448feSmcpowers int rv; 632034448feSmcpowers 633034448feSmcpowers (void) pthread_mutex_lock(&object_p->object_mutex); 634034448feSmcpowers if (object_p->key_type != CKK_EC || 635034448feSmcpowers object_p->class != CKO_PRIVATE_KEY) { 636034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 637034448feSmcpowers return (CKR_ATTRIBUTE_TYPE_INVALID); 638034448feSmcpowers } 639034448feSmcpowers 640d2b32306Smcpowers attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 641034448feSmcpowers if (attrs == NULL) { 642034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 643034448feSmcpowers return (CKR_HOST_MEMORY); 644034448feSmcpowers } 645034448feSmcpowers 646034448feSmcpowers key->ck_format = CRYPTO_KEY_ATTR_LIST; 647d2b32306Smcpowers key->ck_count = EC_ATTR_COUNT; 648034448feSmcpowers key->ck_attrs = attrs; 649034448feSmcpowers 650034448feSmcpowers cur_attr = attrs; 651034448feSmcpowers big = OBJ_PRI_EC_VALUE(object_p); 652034448feSmcpowers if ((ptr = malloc(big->big_value_len)) == NULL) { 653034448feSmcpowers rv = CKR_HOST_MEMORY; 654034448feSmcpowers goto fail; 655034448feSmcpowers } 656034448feSmcpowers ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len); 657034448feSmcpowers 658034448feSmcpowers tmp.type = CKA_EC_PARAMS; 659034448feSmcpowers tmp.pValue = NULL; 660034448feSmcpowers rv = kernel_get_attribute(object_p, &tmp); 661034448feSmcpowers if (rv != CKR_OK) { 662034448feSmcpowers goto fail; 663034448feSmcpowers } 664034448feSmcpowers 665034448feSmcpowers tmp.pValue = malloc(tmp.ulValueLen); 666034448feSmcpowers if (tmp.pValue == NULL) { 667034448feSmcpowers rv = CKR_HOST_MEMORY; 668034448feSmcpowers goto fail; 669034448feSmcpowers } 670034448feSmcpowers 671034448feSmcpowers rv = kernel_get_attribute(object_p, &tmp); 672034448feSmcpowers if (rv != CKR_OK) { 673034448feSmcpowers free(tmp.pValue); 674034448feSmcpowers goto fail; 675034448feSmcpowers } 676034448feSmcpowers 677034448feSmcpowers cur_attr->oa_type = tmp.type; 678034448feSmcpowers cur_attr->oa_value = tmp.pValue; 679034448feSmcpowers cur_attr->oa_value_len = tmp.ulValueLen; 680034448feSmcpowers 681034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 682034448feSmcpowers return (CKR_OK); 683034448feSmcpowers 684034448feSmcpowers fail: 685034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 686034448feSmcpowers free_key_attributes(key); 687034448feSmcpowers return (rv); 688034448feSmcpowers } 689034448feSmcpowers 690034448feSmcpowers /* 691034448feSmcpowers * Convert an EC public key object into a crypto_key structure. 692034448feSmcpowers * Memory is allocated for each attribute stored in the crypto_key 693034448feSmcpowers * structure. Memory for the crypto_key structure is not 694034448feSmcpowers * allocated. Attributes can be freed by free_ec_key_attributes(). 695034448feSmcpowers */ 696034448feSmcpowers CK_RV 697034448feSmcpowers get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key) 698034448feSmcpowers { 699034448feSmcpowers biginteger_t *big; 700034448feSmcpowers crypto_object_attribute_t *attrs, *cur_attr; 701d2b32306Smcpowers CK_ATTRIBUTE tmp; 702034448feSmcpowers char *ptr; 703d2b32306Smcpowers int rv; 704034448feSmcpowers 705034448feSmcpowers (void) pthread_mutex_lock(&object_p->object_mutex); 706034448feSmcpowers if (object_p->key_type != CKK_EC || 707034448feSmcpowers object_p->class != CKO_PUBLIC_KEY) { 708034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 709034448feSmcpowers return (CKR_ATTRIBUTE_TYPE_INVALID); 710034448feSmcpowers } 711034448feSmcpowers 712d2b32306Smcpowers attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t)); 713034448feSmcpowers if (attrs == NULL) { 714034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 715034448feSmcpowers return (CKR_HOST_MEMORY); 716034448feSmcpowers } 717034448feSmcpowers 718034448feSmcpowers key->ck_format = CRYPTO_KEY_ATTR_LIST; 719034448feSmcpowers key->ck_count = EC_ATTR_COUNT; 720034448feSmcpowers key->ck_attrs = attrs; 721034448feSmcpowers 722034448feSmcpowers cur_attr = attrs; 723034448feSmcpowers big = OBJ_PUB_EC_POINT(object_p); 724034448feSmcpowers if ((ptr = malloc(big->big_value_len)) == NULL) { 725d2b32306Smcpowers rv = CKR_HOST_MEMORY; 726d2b32306Smcpowers goto fail; 727034448feSmcpowers } 728034448feSmcpowers ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len); 729034448feSmcpowers 730d2b32306Smcpowers tmp.type = CKA_EC_PARAMS; 731d2b32306Smcpowers tmp.pValue = NULL; 732d2b32306Smcpowers rv = kernel_get_attribute(object_p, &tmp); 733d2b32306Smcpowers if (rv != CKR_OK) { 734d2b32306Smcpowers goto fail; 735d2b32306Smcpowers } 736d2b32306Smcpowers 737d2b32306Smcpowers tmp.pValue = malloc(tmp.ulValueLen); 738d2b32306Smcpowers if (tmp.pValue == NULL) { 739d2b32306Smcpowers rv = CKR_HOST_MEMORY; 740d2b32306Smcpowers goto fail; 741d2b32306Smcpowers } 742d2b32306Smcpowers 743d2b32306Smcpowers rv = kernel_get_attribute(object_p, &tmp); 744d2b32306Smcpowers if (rv != CKR_OK) { 745d2b32306Smcpowers free(tmp.pValue); 746d2b32306Smcpowers goto fail; 747d2b32306Smcpowers } 748d2b32306Smcpowers 749d2b32306Smcpowers cur_attr->oa_type = tmp.type; 750d2b32306Smcpowers cur_attr->oa_value = tmp.pValue; 751d2b32306Smcpowers cur_attr->oa_value_len = tmp.ulValueLen; 752d2b32306Smcpowers 753034448feSmcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 754034448feSmcpowers return (CKR_OK); 755d2b32306Smcpowers 756d2b32306Smcpowers fail: 757d2b32306Smcpowers (void) pthread_mutex_unlock(&object_p->object_mutex); 758d2b32306Smcpowers free_key_attributes(key); 759d2b32306Smcpowers return (rv); 760034448feSmcpowers } 761034448feSmcpowers 762034448feSmcpowers /* 7637c478bd9Sstevel@tonic-gate * Convert an attribute template into an obj_attrs array. 7647c478bd9Sstevel@tonic-gate * Memory is allocated for each attribute stored in the obj_attrs. 7657c478bd9Sstevel@tonic-gate * The memory can be freed by free_object_attributes(). 7667c478bd9Sstevel@tonic-gate * 7677c478bd9Sstevel@tonic-gate * If the boolean pointer is_token_obj is not NULL, the caller wants to 7687c478bd9Sstevel@tonic-gate * retrieve the value of the CKA_TOKEN attribute if it is specified in the 7697c478bd9Sstevel@tonic-gate * template. 7707c478bd9Sstevel@tonic-gate * - When this routine is called thru C_CreateObject(), C_CopyObject(), or 7717c478bd9Sstevel@tonic-gate * any key management function, is_token_obj should NOT be NULL. 7727c478bd9Sstevel@tonic-gate * - When this routine is called thru C_GetAttributeValue() or 7737c478bd9Sstevel@tonic-gate * C_SetAttributeValue(), "is_token_obj" should be NULL. 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate CK_RV 7767c478bd9Sstevel@tonic-gate process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 7777c478bd9Sstevel@tonic-gate caddr_t *obj_attrs, CK_BBOOL *is_token_obj) 7787c478bd9Sstevel@tonic-gate { 7797c478bd9Sstevel@tonic-gate crypto_object_attribute_t *attrs, *cur_attr; 7807c478bd9Sstevel@tonic-gate int i, cur_i; 7817c478bd9Sstevel@tonic-gate char *ptr; 7827c478bd9Sstevel@tonic-gate CK_RV rv; 7837c478bd9Sstevel@tonic-gate ssize_t value_len; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate if (ulCount == 0) { 7867c478bd9Sstevel@tonic-gate obj_attrs = NULL; 7877c478bd9Sstevel@tonic-gate return (CKR_OK); 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t)); 7917c478bd9Sstevel@tonic-gate if (attrs == NULL) { 7927c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate cur_attr = attrs; 7967c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) { 7977c478bd9Sstevel@tonic-gate /* 7987c478bd9Sstevel@tonic-gate * The length of long attributes must be set correctly 7997c478bd9Sstevel@tonic-gate * so providers can determine whether they came from 32 8007c478bd9Sstevel@tonic-gate * or 64-bit applications. 8017c478bd9Sstevel@tonic-gate */ 8027c478bd9Sstevel@tonic-gate switch (pTemplate[i].type) { 8037c478bd9Sstevel@tonic-gate case CKA_CLASS: 8047c478bd9Sstevel@tonic-gate case CKA_CERTIFICATE_TYPE: 8057c478bd9Sstevel@tonic-gate case CKA_KEY_TYPE: 806034448feSmcpowers case CKA_MODULUS_BITS: 8077c478bd9Sstevel@tonic-gate case CKA_HW_FEATURE_TYPE: 8087c478bd9Sstevel@tonic-gate value_len = sizeof (ulong_t); 809894b2776Smcpowers if (pTemplate[i].pValue != NULL && 810894b2776Smcpowers (pTemplate[i].ulValueLen < value_len)) { 8117739299dSAnthony Scarpino rv = CKR_ATTRIBUTE_VALUE_INVALID; 8127c478bd9Sstevel@tonic-gate cur_i = i; 8137c478bd9Sstevel@tonic-gate goto fail_cleanup; 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate break; 8167c478bd9Sstevel@tonic-gate default: 8177c478bd9Sstevel@tonic-gate value_len = pTemplate[i].ulValueLen; 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate cur_attr->oa_type = pTemplate[i].type; 8217c478bd9Sstevel@tonic-gate cur_attr->oa_value_len = value_len; 8227c478bd9Sstevel@tonic-gate cur_attr->oa_value = NULL; 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate if ((pTemplate[i].pValue != NULL) && 8257c478bd9Sstevel@tonic-gate (pTemplate[i].ulValueLen > 0)) { 8267c478bd9Sstevel@tonic-gate ptr = malloc(pTemplate[i].ulValueLen); 8277c478bd9Sstevel@tonic-gate if (ptr == NULL) { 8287c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 8297c478bd9Sstevel@tonic-gate cur_i = i; 8307c478bd9Sstevel@tonic-gate goto fail_cleanup; 8317c478bd9Sstevel@tonic-gate } else { 8327c478bd9Sstevel@tonic-gate (void) memcpy(ptr, pTemplate[i].pValue, 8337c478bd9Sstevel@tonic-gate pTemplate[i].ulValueLen); 8347c478bd9Sstevel@tonic-gate cur_attr->oa_value = ptr; 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate if ((is_token_obj != NULL) && 8397c478bd9Sstevel@tonic-gate (pTemplate[i].type == CKA_TOKEN)) { 8407c478bd9Sstevel@tonic-gate /* Get the CKA_TOKEN attribute value. */ 8417c478bd9Sstevel@tonic-gate if (pTemplate[i].pValue == NULL) { 8427c478bd9Sstevel@tonic-gate rv = CKR_ATTRIBUTE_VALUE_INVALID; 8437c478bd9Sstevel@tonic-gate cur_i = i; 8447c478bd9Sstevel@tonic-gate goto fail_cleanup; 8457c478bd9Sstevel@tonic-gate } else { 8467c478bd9Sstevel@tonic-gate *is_token_obj = 8477c478bd9Sstevel@tonic-gate *(CK_BBOOL *)pTemplate[i].pValue; 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate cur_attr++; 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate *obj_attrs = (char *)attrs; 8557c478bd9Sstevel@tonic-gate return (CKR_OK); 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate fail_cleanup: 8587c478bd9Sstevel@tonic-gate cur_attr = attrs; 8597c478bd9Sstevel@tonic-gate for (i = 0; i < cur_i; i++) { 8607c478bd9Sstevel@tonic-gate if (cur_attr->oa_value != NULL) { 8617c478bd9Sstevel@tonic-gate (void) free(cur_attr->oa_value); 8627c478bd9Sstevel@tonic-gate } 8637c478bd9Sstevel@tonic-gate cur_attr++; 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate (void) free(attrs); 8677c478bd9Sstevel@tonic-gate return (rv); 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate /* 8727c478bd9Sstevel@tonic-gate * Copy the attribute values from obj_attrs to pTemplate. 8737c478bd9Sstevel@tonic-gate * The obj_attrs is an image of the Template and is expected to have the 8747c478bd9Sstevel@tonic-gate * same attributes in the same order and each one of the attribute pValue 8757c478bd9Sstevel@tonic-gate * in obj_attr has enough space allocated for the corresponding valueLen 8767c478bd9Sstevel@tonic-gate * in pTemplate. 8777c478bd9Sstevel@tonic-gate */ 8787c478bd9Sstevel@tonic-gate CK_RV 8797c478bd9Sstevel@tonic-gate get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 8807c478bd9Sstevel@tonic-gate caddr_t obj_attrs) 8817c478bd9Sstevel@tonic-gate { 8827c478bd9Sstevel@tonic-gate crypto_object_attribute_t *cur_attr; 8837c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 8847c478bd9Sstevel@tonic-gate int i; 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate /* LINTED */ 8877c478bd9Sstevel@tonic-gate cur_attr = (crypto_object_attribute_t *)obj_attrs; 8887c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) { 8897c478bd9Sstevel@tonic-gate if (pTemplate[i].type != cur_attr->oa_type) { 8907c478bd9Sstevel@tonic-gate /* The attribute type doesn't match, this is bad. */ 8917c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 8927c478bd9Sstevel@tonic-gate return (rv); 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate pTemplate[i].ulValueLen = cur_attr->oa_value_len; 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate if ((pTemplate[i].pValue != NULL) && 8987c478bd9Sstevel@tonic-gate ((CK_LONG)pTemplate[i].ulValueLen != -1)) { 8997c478bd9Sstevel@tonic-gate (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value, 9007c478bd9Sstevel@tonic-gate pTemplate[i].ulValueLen); 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate cur_attr++; 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate return (rv); 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate /* 9097c478bd9Sstevel@tonic-gate * Free the attribute storage in a crypto_object_attribute_t structure. 9107c478bd9Sstevel@tonic-gate */ 9117c478bd9Sstevel@tonic-gate void 9127c478bd9Sstevel@tonic-gate free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount) 9137c478bd9Sstevel@tonic-gate { 9147c478bd9Sstevel@tonic-gate crypto_object_attribute_t *cur_attr; 9157c478bd9Sstevel@tonic-gate int i; 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate if ((ulCount == 0) || (obj_attrs == NULL)) { 9187c478bd9Sstevel@tonic-gate return; 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate /* LINTED */ 9227c478bd9Sstevel@tonic-gate cur_attr = (crypto_object_attribute_t *)obj_attrs; 9237c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) { 924034448feSmcpowers /* XXX check that oa_value > 0 */ 9257c478bd9Sstevel@tonic-gate if (cur_attr->oa_value != NULL) { 9267c478bd9Sstevel@tonic-gate free(cur_attr->oa_value); 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate cur_attr++; 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate free(obj_attrs); 9327c478bd9Sstevel@tonic-gate } 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate /* 9357c478bd9Sstevel@tonic-gate * This function is called by process_found_objects(). It will check the 9367c478bd9Sstevel@tonic-gate * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then 9377c478bd9Sstevel@tonic-gate * initialize all the necessary fields in the object wrapper "objp". 9387c478bd9Sstevel@tonic-gate */ 9397c478bd9Sstevel@tonic-gate static CK_RV 9407c478bd9Sstevel@tonic-gate create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp, 9417c478bd9Sstevel@tonic-gate kernel_object_t *objp, crypto_object_id_t oid) 9427c478bd9Sstevel@tonic-gate { 9437c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 9447c478bd9Sstevel@tonic-gate crypto_object_get_attribute_value_t obj_ga; 9457c478bd9Sstevel@tonic-gate boolean_t is_pri_obj; 9467c478bd9Sstevel@tonic-gate boolean_t is_token_obj; 9477c478bd9Sstevel@tonic-gate CK_BBOOL pri_value, token_value; 9487c478bd9Sstevel@tonic-gate CK_ATTRIBUTE pTemplate[2]; 9497c478bd9Sstevel@tonic-gate int r; 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate /* 9527c478bd9Sstevel@tonic-gate * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this 9537c478bd9Sstevel@tonic-gate * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN. 9547c478bd9Sstevel@tonic-gate */ 9557c478bd9Sstevel@tonic-gate obj_ga.og_session = sp->k_session; 9567c478bd9Sstevel@tonic-gate obj_ga.og_handle = oid; 9577c478bd9Sstevel@tonic-gate obj_ga.og_count = 2; 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate pTemplate[0].type = CKA_PRIVATE; 9607c478bd9Sstevel@tonic-gate pTemplate[0].pValue = &pri_value; 9617c478bd9Sstevel@tonic-gate pTemplate[0].ulValueLen = sizeof (pri_value); 9627c478bd9Sstevel@tonic-gate pTemplate[1].type = CKA_TOKEN; 9637c478bd9Sstevel@tonic-gate pTemplate[1].pValue = &token_value; 9647c478bd9Sstevel@tonic-gate pTemplate[1].ulValueLen = sizeof (token_value); 9657c478bd9Sstevel@tonic-gate rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes, 9667c478bd9Sstevel@tonic-gate NULL); 9677c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 9687c478bd9Sstevel@tonic-gate return (rv); 9697c478bd9Sstevel@tonic-gate } 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 9727c478bd9Sstevel@tonic-gate &obj_ga)) < 0) { 9737c478bd9Sstevel@tonic-gate if (errno != EINTR) 9747c478bd9Sstevel@tonic-gate break; 9757c478bd9Sstevel@tonic-gate } 9767c478bd9Sstevel@tonic-gate if (r < 0) { 9777c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 9787c478bd9Sstevel@tonic-gate } else { 9797c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 9807c478bd9Sstevel@tonic-gate } 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 9837c478bd9Sstevel@tonic-gate rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes); 9847c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 9857c478bd9Sstevel@tonic-gate is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue; 9867c478bd9Sstevel@tonic-gate is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue; 9877c478bd9Sstevel@tonic-gate } 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate free_object_attributes(obj_ga.og_attributes, 2); 9917c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 9927c478bd9Sstevel@tonic-gate return (rv); 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate 9957c478bd9Sstevel@tonic-gate /* Make sure it is a token object. */ 9967c478bd9Sstevel@tonic-gate if (!is_token_obj) { 9977c478bd9Sstevel@tonic-gate rv = CKR_ATTRIBUTE_VALUE_INVALID; 9987c478bd9Sstevel@tonic-gate return (rv); 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate /* If it is a private object, make sure the user has logged in. */ 10027c478bd9Sstevel@tonic-gate if (is_pri_obj && (pslot->sl_state != CKU_USER)) { 10037c478bd9Sstevel@tonic-gate rv = CKR_ATTRIBUTE_VALUE_INVALID; 10047c478bd9Sstevel@tonic-gate return (rv); 10057c478bd9Sstevel@tonic-gate } 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate objp->is_lib_obj = B_FALSE; 10087c478bd9Sstevel@tonic-gate objp->k_handle = oid; 10097c478bd9Sstevel@tonic-gate objp->bool_attr_mask |= TOKEN_BOOL_ON; 10107c478bd9Sstevel@tonic-gate if (is_pri_obj) { 10117c478bd9Sstevel@tonic-gate objp->bool_attr_mask |= PRIVATE_BOOL_ON; 10127c478bd9Sstevel@tonic-gate } else { 10137c478bd9Sstevel@tonic-gate objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&objp->object_mutex, NULL); 10177c478bd9Sstevel@tonic-gate objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC; 10187c478bd9Sstevel@tonic-gate objp->session_handle = (CK_SESSION_HANDLE) sp; 10197c478bd9Sstevel@tonic-gate 10207c478bd9Sstevel@tonic-gate return (CKR_OK); 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate /* 10247c478bd9Sstevel@tonic-gate * This function processes the kernel object handles returned from the 10257c478bd9Sstevel@tonic-gate * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list 10267c478bd9Sstevel@tonic-gate * and the number of object handles to the caller - C_FindObjects(). 10277c478bd9Sstevel@tonic-gate * The caller acquires the slot lock and the session lock. 10287c478bd9Sstevel@tonic-gate */ 10297c478bd9Sstevel@tonic-gate CK_RV 10307c478bd9Sstevel@tonic-gate process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found, 10317c478bd9Sstevel@tonic-gate CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu) 10327c478bd9Sstevel@tonic-gate { 10337c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 10347c478bd9Sstevel@tonic-gate crypto_object_id_t *oid_p; 10357c478bd9Sstevel@tonic-gate kernel_slot_t *pslot; 10367c478bd9Sstevel@tonic-gate kernel_object_t *objp; 10377c478bd9Sstevel@tonic-gate kernel_object_t *objp1; 10387c478bd9Sstevel@tonic-gate kernel_object_t *new_tobj_list = NULL; 10397c478bd9Sstevel@tonic-gate kernel_session_t *sp; 10407c478bd9Sstevel@tonic-gate CK_ULONG num_obj_found = 0; 10417c478bd9Sstevel@tonic-gate boolean_t is_in_lib; 10427c478bd9Sstevel@tonic-gate int i; 10437c478bd9Sstevel@tonic-gate 10447c478bd9Sstevel@tonic-gate if (obj_fu.fu_count == 0) { 10457c478bd9Sstevel@tonic-gate *found_obj_count = 0; 10467c478bd9Sstevel@tonic-gate return (CKR_OK); 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate pslot = slot_table[cur_sp->ses_slotid]; 10507c478bd9Sstevel@tonic-gate 10517c478bd9Sstevel@tonic-gate /* LINTED */ 10527c478bd9Sstevel@tonic-gate oid_p = (crypto_object_id_t *)obj_fu.fu_handles; 10537c478bd9Sstevel@tonic-gate for (i = 0; i < obj_fu.fu_count; i++) { 10547c478bd9Sstevel@tonic-gate is_in_lib = B_FALSE; 10557c478bd9Sstevel@tonic-gate /* 10567c478bd9Sstevel@tonic-gate * Check if this oid has an object wrapper in the library 10577c478bd9Sstevel@tonic-gate * already. First, search the slot's token object list. 10587c478bd9Sstevel@tonic-gate */ 10597c478bd9Sstevel@tonic-gate objp = pslot->sl_tobj_list; 10607c478bd9Sstevel@tonic-gate while (!is_in_lib && objp) { 10617c478bd9Sstevel@tonic-gate if (objp->k_handle == *oid_p) { 10627c478bd9Sstevel@tonic-gate is_in_lib = B_TRUE; 10637c478bd9Sstevel@tonic-gate } else { 10647c478bd9Sstevel@tonic-gate objp = objp->next; 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate /* 10697c478bd9Sstevel@tonic-gate * If it is not in the slot's token object list, 10707c478bd9Sstevel@tonic-gate * search it in all the sessions. 10717c478bd9Sstevel@tonic-gate */ 10727c478bd9Sstevel@tonic-gate if (!is_in_lib) { 10737c478bd9Sstevel@tonic-gate sp = pslot->sl_sess_list; 10747c478bd9Sstevel@tonic-gate while (!is_in_lib && sp) { 10757c478bd9Sstevel@tonic-gate objp = sp->object_list; 10767c478bd9Sstevel@tonic-gate while (!is_in_lib && objp) { 10777c478bd9Sstevel@tonic-gate if (objp->k_handle == *oid_p) { 10787c478bd9Sstevel@tonic-gate is_in_lib = B_TRUE; 10797c478bd9Sstevel@tonic-gate } else { 10807c478bd9Sstevel@tonic-gate objp = objp->next; 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate sp = sp->next; 10847c478bd9Sstevel@tonic-gate } 10857c478bd9Sstevel@tonic-gate } 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate /* 10887c478bd9Sstevel@tonic-gate * If this object is in the library already, add its object 10897c478bd9Sstevel@tonic-gate * wrapper to the returned find object list. 10907c478bd9Sstevel@tonic-gate */ 10917c478bd9Sstevel@tonic-gate if (is_in_lib) { 10927c478bd9Sstevel@tonic-gate obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate /* 10967c478bd9Sstevel@tonic-gate * If we still do not find it in the library. This object 10977c478bd9Sstevel@tonic-gate * must be a token object pre-existed in the HW provider. 10987c478bd9Sstevel@tonic-gate * We need to create an object wrapper for it in the library. 10997c478bd9Sstevel@tonic-gate */ 11007c478bd9Sstevel@tonic-gate if (!is_in_lib) { 11017c478bd9Sstevel@tonic-gate objp1 = calloc(1, sizeof (kernel_object_t)); 11027c478bd9Sstevel@tonic-gate if (objp1 == NULL) { 11037c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 11047c478bd9Sstevel@tonic-gate goto failed_exit; 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate rv = create_new_tobj_in_lib(pslot, cur_sp, objp1, 11077c478bd9Sstevel@tonic-gate *oid_p); 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 11107c478bd9Sstevel@tonic-gate /* Save the new object to the new_tobj_list. */ 11117c478bd9Sstevel@tonic-gate if (new_tobj_list == NULL) { 11127c478bd9Sstevel@tonic-gate new_tobj_list = objp1; 11137c478bd9Sstevel@tonic-gate objp1->next = NULL; 11147c478bd9Sstevel@tonic-gate objp1->prev = NULL; 11157c478bd9Sstevel@tonic-gate } else { 11167c478bd9Sstevel@tonic-gate new_tobj_list->prev = objp1; 11177c478bd9Sstevel@tonic-gate objp1->next = new_tobj_list; 11187c478bd9Sstevel@tonic-gate objp1->prev = NULL; 11197c478bd9Sstevel@tonic-gate new_tobj_list = objp1; 11207c478bd9Sstevel@tonic-gate } 11217c478bd9Sstevel@tonic-gate } else { 11227c478bd9Sstevel@tonic-gate /* 11237c478bd9Sstevel@tonic-gate * If create_new_tobj_in_lib() doesn't fail 11247c478bd9Sstevel@tonic-gate * with CKR_HOST_MEMORY, the failure should be 11257c478bd9Sstevel@tonic-gate * caused by the attributes' checking. We will 11267c478bd9Sstevel@tonic-gate * just ignore this object and continue on. 11277c478bd9Sstevel@tonic-gate */ 11287c478bd9Sstevel@tonic-gate free(objp1); 11297c478bd9Sstevel@tonic-gate if (rv == CKR_HOST_MEMORY) { 11307c478bd9Sstevel@tonic-gate goto failed_exit; 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate } 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate /* Process next one */ 11367c478bd9Sstevel@tonic-gate oid_p++; 11377c478bd9Sstevel@tonic-gate } 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate /* 11407c478bd9Sstevel@tonic-gate * Add the newly created token object wrappers to the found object 11417c478bd9Sstevel@tonic-gate * list and to the slot's token object list. 11427c478bd9Sstevel@tonic-gate */ 11437c478bd9Sstevel@tonic-gate if (new_tobj_list != NULL) { 11447c478bd9Sstevel@tonic-gate /* Add to the obj_found array. */ 11457c478bd9Sstevel@tonic-gate objp = new_tobj_list; 11467c478bd9Sstevel@tonic-gate while (objp) { 11477c478bd9Sstevel@tonic-gate obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp; 11487c478bd9Sstevel@tonic-gate if (objp->next == NULL) { 11497c478bd9Sstevel@tonic-gate break; 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate objp = objp->next; 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate /* Add to the beginning of the slot's token object list. */ 11557c478bd9Sstevel@tonic-gate if (pslot->sl_tobj_list != NULL) { 11567c478bd9Sstevel@tonic-gate objp->next = pslot->sl_tobj_list; 11577c478bd9Sstevel@tonic-gate pslot->sl_tobj_list->prev = objp; 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate pslot->sl_tobj_list = new_tobj_list; 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate *found_obj_count = num_obj_found; 11637c478bd9Sstevel@tonic-gate return (CKR_OK); 11647c478bd9Sstevel@tonic-gate 11657c478bd9Sstevel@tonic-gate failed_exit: 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate /* Free the newly created token object wrappers. */ 11687c478bd9Sstevel@tonic-gate objp = new_tobj_list; 11697c478bd9Sstevel@tonic-gate while (objp) { 11707c478bd9Sstevel@tonic-gate objp1 = objp->next; 11717c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&objp->object_mutex); 11727c478bd9Sstevel@tonic-gate free(objp); 11737c478bd9Sstevel@tonic-gate objp = objp1; 11747c478bd9Sstevel@tonic-gate } 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate return (rv); 11777c478bd9Sstevel@tonic-gate } 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate /* 11817c478bd9Sstevel@tonic-gate * Get the value of the CKA_PRIVATE attribute for the object just returned 11827c478bd9Sstevel@tonic-gate * from the HW provider. This function will be called by any function 11837c478bd9Sstevel@tonic-gate * that creates a new object, because the CKA_PRIVATE value of an object is 11842321aa36Sda73024 * token specific. The CKA_PRIVATE attribute value of the new object will be 11857c478bd9Sstevel@tonic-gate * stored in the object structure in the library, which will be used later at 11867c478bd9Sstevel@tonic-gate * C_Logout to clean up all private objects. 11877c478bd9Sstevel@tonic-gate */ 11887c478bd9Sstevel@tonic-gate CK_RV 11897c478bd9Sstevel@tonic-gate get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid, 11907c478bd9Sstevel@tonic-gate CK_BBOOL *is_pri_obj) 11917c478bd9Sstevel@tonic-gate { 11927c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 11937c478bd9Sstevel@tonic-gate crypto_object_get_attribute_value_t obj_ga; 11947c478bd9Sstevel@tonic-gate crypto_object_attribute_t obj_attr; 11957c478bd9Sstevel@tonic-gate CK_BBOOL pri_value; 11967c478bd9Sstevel@tonic-gate int r; 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate obj_ga.og_session = sp->k_session; 11997c478bd9Sstevel@tonic-gate obj_ga.og_handle = oid; 12007c478bd9Sstevel@tonic-gate obj_ga.og_count = 1; 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate obj_attr.oa_type = CKA_PRIVATE; 12037c478bd9Sstevel@tonic-gate obj_attr.oa_value = (char *)&pri_value; 12047c478bd9Sstevel@tonic-gate obj_attr.oa_value_len = sizeof (CK_BBOOL); 12057c478bd9Sstevel@tonic-gate obj_ga.og_attributes = (char *)&obj_attr; 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE, 12087c478bd9Sstevel@tonic-gate &obj_ga)) < 0) { 12097c478bd9Sstevel@tonic-gate if (errno != EINTR) 12107c478bd9Sstevel@tonic-gate break; 12117c478bd9Sstevel@tonic-gate } 12127c478bd9Sstevel@tonic-gate if (r < 0) { 12137c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 12147c478bd9Sstevel@tonic-gate } else { 12157c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number(obj_ga.og_return_value); 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 12197c478bd9Sstevel@tonic-gate *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value; 12207c478bd9Sstevel@tonic-gate } 12217c478bd9Sstevel@tonic-gate 12227c478bd9Sstevel@tonic-gate return (rv); 12237c478bd9Sstevel@tonic-gate } 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate 12267c478bd9Sstevel@tonic-gate CK_RV 12277c478bd9Sstevel@tonic-gate get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type, 12287c478bd9Sstevel@tonic-gate CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags) 12297c478bd9Sstevel@tonic-gate { 12307c478bd9Sstevel@tonic-gate crypto_get_provider_mechanism_info_t mechanism_info; 12312321aa36Sda73024 const char *string; 12327c478bd9Sstevel@tonic-gate CK_FLAGS flags, mi_flags; 12337c478bd9Sstevel@tonic-gate CK_RV rv; 12347c478bd9Sstevel@tonic-gate int r; 12352321aa36Sda73024 char buf[11]; /* Num chars for representing ulong in ASCII */ 12367c478bd9Sstevel@tonic-gate 123776d1b5a9Sda73024 if (type >= CKM_VENDOR_DEFINED) { 12382321aa36Sda73024 /* allocate/build a string containing the mechanism number */ 12392321aa36Sda73024 (void) snprintf(buf, sizeof (buf), "%#lx", type); 12402321aa36Sda73024 string = buf; 12412321aa36Sda73024 } else { 12427c478bd9Sstevel@tonic-gate string = pkcs11_mech2str(type); 12432321aa36Sda73024 } 12442321aa36Sda73024 12457c478bd9Sstevel@tonic-gate if (string == NULL) 12467c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID); 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate (void) strcpy(mechanism_info.mi_mechanism_name, string); 12497c478bd9Sstevel@tonic-gate mechanism_info.mi_provider_id = pslot->sl_provider_id; 12507c478bd9Sstevel@tonic-gate 12517c478bd9Sstevel@tonic-gate while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO, 12527c478bd9Sstevel@tonic-gate &mechanism_info)) < 0) { 12537c478bd9Sstevel@tonic-gate if (errno != EINTR) 12547c478bd9Sstevel@tonic-gate break; 12557c478bd9Sstevel@tonic-gate } 12567c478bd9Sstevel@tonic-gate if (r < 0) { 12577c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 12587c478bd9Sstevel@tonic-gate } else { 12597c478bd9Sstevel@tonic-gate rv = crypto2pkcs11_error_number( 12607c478bd9Sstevel@tonic-gate mechanism_info.mi_return_value); 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate 12637c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 12642321aa36Sda73024 return (rv); 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate /* 12687c478bd9Sstevel@tonic-gate * Atomic flags are not part of PKCS#11 so we filter 12697c478bd9Sstevel@tonic-gate * them out here. 12707c478bd9Sstevel@tonic-gate */ 12717c478bd9Sstevel@tonic-gate mi_flags = mechanism_info.mi_flags; 12727c478bd9Sstevel@tonic-gate mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC | 12737c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC | 12747c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 12757c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER_ATOMIC | 12767c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER_ATOMIC | 12777c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 12787c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC); 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate if (mi_flags == 0) { 12812321aa36Sda73024 return (CKR_MECHANISM_INVALID); 12827c478bd9Sstevel@tonic-gate } 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 12857c478bd9Sstevel@tonic-gate /* set the value of k_mi_flags first */ 12867c478bd9Sstevel@tonic-gate *k_mi_flags = mi_flags; 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate /* convert KEF flags into pkcs11 flags */ 12897c478bd9Sstevel@tonic-gate flags = CKF_HW; 12907c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_ENCRYPT) 12917c478bd9Sstevel@tonic-gate flags |= CKF_ENCRYPT; 12927c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_DECRYPT) { 12937c478bd9Sstevel@tonic-gate flags |= CKF_DECRYPT; 12947c478bd9Sstevel@tonic-gate /* 12957c478bd9Sstevel@tonic-gate * Since we'll be emulating C_UnwrapKey() for some 12967c478bd9Sstevel@tonic-gate * cases, we can go ahead and claim CKF_UNWRAP 12977c478bd9Sstevel@tonic-gate */ 12987c478bd9Sstevel@tonic-gate flags |= CKF_UNWRAP; 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_DIGEST) 13017c478bd9Sstevel@tonic-gate flags |= CKF_DIGEST; 13027c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_SIGN) 13037c478bd9Sstevel@tonic-gate flags |= CKF_SIGN; 13047c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_SIGN_RECOVER) 13057c478bd9Sstevel@tonic-gate flags |= CKF_SIGN_RECOVER; 13067c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_VERIFY) 13077c478bd9Sstevel@tonic-gate flags |= CKF_VERIFY; 13087c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_VERIFY_RECOVER) 13097c478bd9Sstevel@tonic-gate flags |= CKF_VERIFY_RECOVER; 13107c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_GENERATE) 13117c478bd9Sstevel@tonic-gate flags |= CKF_GENERATE; 13127c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR) 13137c478bd9Sstevel@tonic-gate flags |= CKF_GENERATE_KEY_PAIR; 13147c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_WRAP) 13157c478bd9Sstevel@tonic-gate flags |= CKF_WRAP; 13167c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_UNWRAP) 13177c478bd9Sstevel@tonic-gate flags |= CKF_UNWRAP; 13187c478bd9Sstevel@tonic-gate if (mi_flags & CRYPTO_FG_DERIVE) 13197c478bd9Sstevel@tonic-gate flags |= CKF_DERIVE; 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate pInfo->ulMinKeySize = mechanism_info.mi_min_key_size; 13227c478bd9Sstevel@tonic-gate pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size; 13237c478bd9Sstevel@tonic-gate pInfo->flags = flags; 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate } 13267c478bd9Sstevel@tonic-gate 13277c478bd9Sstevel@tonic-gate return (rv); 13287c478bd9Sstevel@tonic-gate } 1329