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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <errno.h> 30 #include <security/cryptoki.h> 31 #include <sys/crypto/ioctl.h> 32 #include "kernelGlobal.h" 33 #include "kernelSlot.h" 34 35 CK_ULONG slot_count = 0; 36 kernel_slot_t **slot_table; 37 38 static CK_RV 39 kernel_get_slot_number() 40 { 41 CK_RV rv; 42 crypto_get_provider_list_t *pl; 43 int r; 44 45 pl = malloc(sizeof (crypto_get_provider_list_t)); 46 if (pl == NULL) 47 return (CKR_HOST_MEMORY); 48 49 pl->pl_count = 0; 50 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) { 51 if (errno != EINTR) 52 break; 53 } 54 if (r < 0) { 55 rv = CKR_FUNCTION_FAILED; 56 } else { 57 if (pl->pl_return_value != CRYPTO_SUCCESS) { 58 rv = crypto2pkcs11_error_number(pl->pl_return_value); 59 } else { 60 rv = CKR_OK; 61 } 62 } 63 64 if (rv == CKR_OK) { 65 slot_count = pl->pl_count; 66 } 67 68 (void) free(pl); 69 return (rv); 70 } 71 72 /* 73 * To retrieve the crypto_function_list structure with boolean entries 74 * indicating which functions are supported by the hardware provider which 75 * is specified by the slot ID. 76 */ 77 static CK_RV 78 kernel_get_func_list(kernel_slot_t *pslot) 79 { 80 CK_RV rv = CKR_OK; 81 crypto_get_function_list_t fl; 82 int r; 83 84 fl.fl_provider_id = pslot->sl_provider_id; 85 86 while ((r = ioctl(kernel_fd, CRYPTO_GET_FUNCTION_LIST, &fl)) < 0) { 87 if (errno != EINTR) 88 break; 89 } 90 if (r < 0) { 91 rv = CKR_FUNCTION_FAILED; 92 } else { 93 if (fl.fl_return_value == 0) { 94 rv = CKR_OK; 95 } else { 96 rv = crypto2pkcs11_error_number(fl.fl_return_value); 97 } 98 } 99 100 if (rv != CKR_OK) { 101 return (rv); 102 } 103 104 pslot->sl_func_list.fl_digest_init = fl.fl_list.fl_digest_init; 105 pslot->sl_func_list.fl_digest = fl.fl_list.fl_digest; 106 pslot->sl_func_list.fl_digest_update = fl.fl_list.fl_digest_update; 107 pslot->sl_func_list.fl_digest_key = fl.fl_list.fl_digest_key; 108 pslot->sl_func_list.fl_digest_final = fl.fl_list.fl_digest_final; 109 pslot->sl_func_list.fl_encrypt_init = fl.fl_list.fl_encrypt_init; 110 pslot->sl_func_list.fl_encrypt = fl.fl_list.fl_encrypt; 111 pslot->sl_func_list.fl_encrypt_update = fl.fl_list.fl_encrypt_update; 112 pslot->sl_func_list.fl_encrypt_final = fl.fl_list.fl_encrypt_final; 113 pslot->sl_func_list.fl_decrypt_init = fl.fl_list.fl_decrypt_init; 114 pslot->sl_func_list.fl_decrypt = fl.fl_list.fl_decrypt; 115 pslot->sl_func_list.fl_decrypt_update = fl.fl_list.fl_decrypt_update; 116 pslot->sl_func_list.fl_decrypt_final = fl.fl_list.fl_decrypt_final; 117 pslot->sl_func_list.fl_mac_init = fl.fl_list.fl_mac_init; 118 pslot->sl_func_list.fl_mac = fl.fl_list.fl_mac; 119 pslot->sl_func_list.fl_mac_update = fl.fl_list.fl_mac_update; 120 pslot->sl_func_list.fl_mac_final = fl.fl_list.fl_mac_final; 121 pslot->sl_func_list.fl_sign_init = fl.fl_list.fl_sign_init; 122 pslot->sl_func_list.fl_sign = fl.fl_list.fl_sign; 123 pslot->sl_func_list.fl_sign_update = fl.fl_list.fl_sign_update; 124 pslot->sl_func_list.fl_sign_final = fl.fl_list.fl_sign_final; 125 pslot->sl_func_list.fl_sign_recover_init = 126 fl.fl_list.fl_sign_recover_init; 127 pslot->sl_func_list.fl_sign_recover = fl.fl_list.fl_sign_recover; 128 pslot->sl_func_list.fl_digest_encrypt_update = 129 fl.fl_list.fl_digest_encrypt_update; 130 pslot->sl_func_list.fl_decrypt_digest_update = 131 fl.fl_list.fl_decrypt_digest_update; 132 pslot->sl_func_list.fl_sign_encrypt_update = 133 fl.fl_list.fl_sign_encrypt_update; 134 pslot->sl_func_list.fl_decrypt_verify_update = 135 fl.fl_list.fl_decrypt_verify_update; 136 pslot->sl_func_list.fl_seed_random = fl.fl_list.fl_seed_random; 137 pslot->sl_func_list.fl_generate_random = fl.fl_list.fl_generate_random; 138 pslot->sl_func_list.fl_session_open = fl.fl_list.fl_session_open; 139 pslot->sl_func_list.fl_session_close = fl.fl_list.fl_session_close; 140 pslot->sl_func_list.fl_session_login = fl.fl_list.fl_session_login; 141 pslot->sl_func_list.fl_session_logout = fl.fl_list.fl_session_logout; 142 pslot->sl_func_list.fl_object_create = fl.fl_list.fl_object_create; 143 pslot->sl_func_list.fl_object_copy = fl.fl_list.fl_object_copy; 144 pslot->sl_func_list.fl_object_destroy = fl.fl_list.fl_object_destroy; 145 pslot->sl_func_list.fl_object_get_size = fl.fl_list.fl_object_get_size; 146 pslot->sl_func_list.fl_object_get_attribute_value = 147 fl.fl_list.fl_object_get_attribute_value; 148 pslot->sl_func_list.fl_object_set_attribute_value = 149 fl.fl_list.fl_object_set_attribute_value; 150 pslot->sl_func_list.fl_object_find_init = 151 fl.fl_list.fl_object_find_init; 152 pslot->sl_func_list.fl_object_find = fl.fl_list.fl_object_find; 153 pslot->sl_func_list.fl_object_find_final = 154 fl.fl_list.fl_object_find_final; 155 pslot->sl_func_list.fl_key_generate = fl.fl_list.fl_key_generate; 156 pslot->sl_func_list.fl_key_generate_pair = 157 fl.fl_list.fl_key_generate_pair; 158 pslot->sl_func_list.fl_key_wrap = fl.fl_list.fl_key_wrap; 159 pslot->sl_func_list.fl_key_unwrap = fl.fl_list.fl_key_unwrap; 160 pslot->sl_func_list.fl_init_token = fl.fl_list.fl_init_token; 161 pslot->sl_func_list.fl_init_pin = fl.fl_list.fl_init_pin; 162 pslot->sl_func_list.fl_set_pin = fl.fl_list.fl_set_pin; 163 164 return (CKR_OK); 165 } 166 167 /* 168 * Initialize the slot table. 169 * 170 * This function is called from C_Initialize() only. Since C_Initialize() 171 * holds the global mutex lock, there is no need to acquire another lock 172 * in this routine to protect the slot table. 173 */ 174 CK_RV 175 kernel_slottable_init() 176 { 177 int i, cur_slot_num = 0; 178 CK_RV rv = CKR_OK; 179 crypto_get_provider_list_t *pl = NULL; 180 int r; 181 182 /* 183 * Find out how many slots are presented from kernel hardware 184 * providers. If there is no slot presented, just return. 185 */ 186 rv = kernel_get_slot_number(); 187 if (rv != CKR_OK || slot_count == 0) { 188 return (rv); 189 } 190 191 /* Allocate space for the slot table */ 192 slot_table = malloc(sizeof (kernel_slot_t *) * slot_count); 193 if (slot_table == NULL) { 194 return (CKR_HOST_MEMORY); 195 } 196 197 /* For each slot, allocate space and initialize the slot's mutex. */ 198 for (i = 0; i < slot_count; i++) { 199 slot_table[i] = malloc(sizeof (kernel_slot_t)); 200 if (slot_table[i] == NULL) { 201 rv = CKR_HOST_MEMORY; 202 goto failed; 203 } 204 205 slot_table[i]->sl_sess_list = NULL; 206 slot_table[i]->sl_tobj_list = NULL; 207 slot_table[i]->sl_state = CKU_PUBLIC; 208 209 /* Initialize this slot's mutex */ 210 if (pthread_mutex_init(&slot_table[i]->sl_mutex, NULL) != 0) { 211 rv = CKR_FUNCTION_FAILED; 212 (void) free(slot_table[i]); 213 goto failed; 214 } 215 216 cur_slot_num = i; 217 } 218 219 /* 220 * Get the provider ID for each slot from kernel and save it in the 221 * slot table. 222 */ 223 pl = malloc(slot_count * sizeof (crypto_get_provider_list_t)); 224 if (pl == NULL) { 225 rv = CKR_HOST_MEMORY; 226 goto failed; 227 } 228 229 pl->pl_count = slot_count; 230 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_LIST, pl)) < 0) { 231 if (errno != EINTR) 232 break; 233 } 234 if (r < 0) { 235 rv = CKR_FUNCTION_FAILED; 236 goto failed; 237 } else { 238 if (pl->pl_return_value != CRYPTO_SUCCESS) { 239 rv = crypto2pkcs11_error_number(pl->pl_return_value); 240 goto failed; 241 } else { 242 rv = CKR_OK; 243 } 244 } 245 246 for (i = 0; i < slot_count; i++) { 247 slot_table[i]->sl_provider_id = pl->pl_list[i].pe_provider_id; 248 } 249 250 /* 251 * Get the function list for each slot from kernel and save it in 252 * the slot table. 253 */ 254 for (i = 0; i < slot_count; i++) { 255 rv = kernel_get_func_list(slot_table[i]); 256 if (rv != CKR_OK) { 257 goto failed; 258 } 259 } 260 261 (void) free(pl); 262 return (CKR_OK); 263 264 failed: 265 for (i = 0; i < cur_slot_num; i++) { 266 (void) pthread_mutex_destroy(&slot_table[i]->sl_mutex); 267 (void) free(slot_table[i]); 268 } 269 270 (void) free(slot_table); 271 (void) free(pl); 272 return (rv); 273 } 274