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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25
26 /*
27 * The system call and DDI interface for the kernel SSL module
28 */
29
30 #include <sys/types.h>
31 #include <sys/modctl.h>
32 #include <sys/conf.h>
33 #include <sys/stat.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/kmem.h>
37 #include <sys/errno.h>
38 #include <sys/file.h>
39 #include <sys/open.h>
40 #include <sys/cred.h>
41 #include <sys/proc.h>
42 #include <sys/task.h>
43 #include <sys/model.h>
44 #include <sys/sysmacros.h>
45 #include <sys/policy.h>
46 #include <sys/crypto/common.h>
47 #include <sys/crypto/api.h>
48 #include <c2/audit.h>
49 #include <sys/kstat.h>
50
51 #include "kssl.h"
52 #include "ksslimpl.h"
53
54 /*
55 * DDI entry points.
56 */
57 static int kssl_attach(dev_info_t *, ddi_attach_cmd_t);
58 static int kssl_detach(dev_info_t *, ddi_detach_cmd_t);
59 static int kssl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
60 static int kssl_open(dev_t *, int, int, cred_t *);
61 static int kssl_close(dev_t, int, int, cred_t *);
62 static int kssl_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
63
64 static int kssl_constructor(void *buf, void *arg, int kmflags);
65 static void kssl_destructor(void *buf, void *arg);
66
67 /*
68 * Module linkage.
69 */
70 static struct cb_ops cbops = {
71 kssl_open, /* cb_open */
72 kssl_close, /* cb_close */
73 nodev, /* cb_strategy */
74 nodev, /* cb_print */
75 nodev, /* cb_dump */
76 nodev, /* cb_read */
77 nodev, /* cb_write */
78 kssl_ioctl, /* cb_ioctl */
79 nodev, /* cb_devmap */
80 nodev, /* cb_mmap */
81 nodev, /* cb_segmap */
82 nochpoll, /* cb_chpoll */
83 ddi_prop_op, /* cb_prop_op */
84 NULL, /* cb_streamtab */
85 D_MP, /* cb_flag */
86 CB_REV, /* cb_rev */
87 nodev, /* cb_aread */
88 nodev, /* cb_awrite */
89 };
90
91 static struct dev_ops devops = {
92 DEVO_REV, /* devo_rev */
93 0, /* devo_refcnt */
94 kssl_getinfo, /* devo_getinfo */
95 nulldev, /* devo_identify */
96 nulldev, /* devo_probe */
97 kssl_attach, /* devo_attach */
98 kssl_detach, /* devo_detach */
99 nodev, /* devo_reset */
100 &cbops, /* devo_cb_ops */
101 NULL, /* devo_bus_ops */
102 NULL, /* devo_power */
103 ddi_quiesce_not_needed, /* devo_quiesce */
104 };
105
106 static struct modldrv modldrv = {
107 &mod_driverops, /* drv_modops */
108 "Kernel SSL Interface", /* drv_linkinfo */
109 &devops,
110 };
111
112 static struct modlinkage modlinkage = {
113 MODREV_1, /* ml_rev */
114 &modldrv, /* ml_linkage */
115 NULL
116 };
117
118 static dev_info_t *kssl_dip = NULL;
119
120 crypto_mechanism_t rsa_x509_mech = {CRYPTO_MECH_INVALID, NULL, 0};
121 crypto_mechanism_t hmac_md5_mech = {CRYPTO_MECH_INVALID, NULL, 0};
122 crypto_mechanism_t hmac_sha1_mech = {CRYPTO_MECH_INVALID, NULL, 0};
123 crypto_call_flag_t kssl_call_flag = CRYPTO_ALWAYS_QUEUE;
124
125 KSSLCipherDef cipher_defs[] = { /* indexed by SSL3BulkCipher */
126 /* type bsize keysz crypto_mech_type_t */
127
128 {type_stream, 0, 0, CRYPTO_MECH_INVALID},
129
130 /* mech_type to be initialized with CKM_RC4's */
131 {type_stream, 0, 16, CRYPTO_MECH_INVALID},
132
133 /* mech_type to be initialized with CKM_DES_CBC's */
134 {type_block, 8, 8, CRYPTO_MECH_INVALID},
135
136 /* mech_type to be initialized with CKM_DES3_CBC's */
137 {type_block, 8, 24, CRYPTO_MECH_INVALID},
138
139 /* mech_type to be initialized with CKM_AES_CBC with 128-bit key */
140 {type_block, 16, 16, CRYPTO_MECH_INVALID},
141
142 /* mech_type to be initialized with CKM_AES_CBC with 256-bit key */
143 {type_block, 16, 32, CRYPTO_MECH_INVALID},
144 };
145
146 struct kmem_cache *kssl_cache;
147 static crypto_notify_handle_t prov_update_handle = NULL;
148
149 static void kssl_global_init();
150 static void kssl_global_fini();
151 static void kssl_init_mechs();
152 static void kssl_event_callback(uint32_t, void *);
153
154 /*
155 * DDI entry points.
156 */
157 int
_init(void)158 _init(void)
159 {
160 int error;
161
162 kssl_global_init();
163
164 if ((error = mod_install(&modlinkage)) != 0) {
165 kssl_global_fini();
166 return (error);
167 }
168 return (0);
169 }
170
171 int
_fini(void)172 _fini(void)
173 {
174 int error;
175
176 if ((error = mod_remove(&modlinkage)) != 0)
177 return (error);
178
179 if (prov_update_handle != NULL)
180 crypto_unnotify_events(prov_update_handle);
181
182 kssl_global_fini();
183
184 return (0);
185 }
186
187 int
_info(struct modinfo * modinfop)188 _info(struct modinfo *modinfop)
189 {
190 return (mod_info(&modlinkage, modinfop));
191 }
192
193 /* ARGSUSED */
194 static int
kssl_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)195 kssl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
196 {
197 switch (cmd) {
198 case DDI_INFO_DEVT2DEVINFO:
199 *result = kssl_dip;
200 return (DDI_SUCCESS);
201
202 case DDI_INFO_DEVT2INSTANCE:
203 *result = (void *)0;
204 return (DDI_SUCCESS);
205 }
206 return (DDI_FAILURE);
207 }
208
209 static int
kssl_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)210 kssl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
211 {
212 if (cmd != DDI_ATTACH) {
213 return (DDI_FAILURE);
214 }
215
216 if (ddi_get_instance(dip) != 0) {
217 /* we only allow instance 0 to attach */
218 return (DDI_FAILURE);
219 }
220
221 /* create the minor node */
222 if (ddi_create_minor_node(dip, "kssl", S_IFCHR, 0, DDI_PSEUDO, 0) !=
223 DDI_SUCCESS) {
224 cmn_err(CE_WARN, "kssl_attach: failed creating minor node");
225 ddi_remove_minor_node(dip, NULL);
226 return (DDI_FAILURE);
227 }
228
229 kssl_dip = dip;
230
231 return (DDI_SUCCESS);
232 }
233
234 static kstat_t *kssl_ksp = NULL;
235
236 static int
kssl_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)237 kssl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
238 {
239 if (cmd != DDI_DETACH)
240 return (DDI_FAILURE);
241
242 if (kssl_entry_tab_nentries != 0)
243 return (DDI_FAILURE);
244
245 kssl_dip = NULL;
246
247 ddi_remove_minor_node(dip, NULL);
248
249 return (DDI_SUCCESS);
250 }
251
252 /* ARGSUSED */
253 static int
kssl_open(dev_t * devp,int flag,int otyp,cred_t * credp)254 kssl_open(dev_t *devp, int flag, int otyp, cred_t *credp)
255 {
256 if (otyp != OTYP_CHR)
257 return (ENXIO);
258
259 if (kssl_dip == NULL)
260 return (ENXIO);
261
262 /* first time here? initialize everything */
263 if (rsa_x509_mech.cm_type == CRYPTO_MECH_INVALID) {
264 kssl_init_mechs();
265 prov_update_handle = crypto_notify_events(
266 kssl_event_callback, CRYPTO_EVENT_MECHS_CHANGED);
267 }
268
269 /* exclusive opens are not supported */
270 if (flag & FEXCL)
271 return (ENOTSUP);
272
273 return (0);
274 }
275
276 /* ARGSUSED */
277 static int
kssl_close(dev_t dev,int flag,int otyp,cred_t * credp)278 kssl_close(dev_t dev, int flag, int otyp, cred_t *credp)
279 {
280 return (0);
281 }
282
283 #define KSSL_MAX_KEYANDCERTS 80000 /* max 64K plus a little margin */
284
285 /* ARGSUSED */
286 static int
kssl_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * c,int * rval)287 kssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
288 int *rval)
289 {
290 int error = EINVAL;
291 uint32_t auditing = AU_AUDITING();
292
293 #define ARG ((caddr_t)arg)
294
295 if (secpolicy_net_config(c, B_FALSE) != 0) {
296 return (EPERM);
297 }
298
299 switch (cmd) {
300 case KSSL_ADD_ENTRY: {
301 uint64_t len;
302 uint32_t ck_rv;
303 size_t off;
304 kssl_params_t *kssl_params;
305
306 off = offsetof(kssl_params_t, kssl_params_size);
307 if (copyin(ARG + off, &len, sizeof (len)) != 0) {
308 return (EFAULT);
309 }
310
311 if (len < sizeof (kssl_params_t) ||
312 len > KSSL_MAX_KEYANDCERTS) {
313 return (EINVAL);
314 }
315
316 kssl_params = kmem_alloc(len, KM_SLEEP);
317
318 /* Get the whole structure and parameters in one move */
319 if (copyin(ARG, kssl_params, len) != 0) {
320 kmem_free(kssl_params, len);
321 return (EFAULT);
322 }
323 error = kssl_add_entry(kssl_params);
324 if (auditing)
325 audit_kssl(KSSL_ADD_ENTRY, kssl_params, error);
326 off = offsetof(kssl_params_t, kssl_token) +
327 offsetof(kssl_tokinfo_t, ck_rv);
328 ck_rv = kssl_params->kssl_token.ck_rv;
329 if (copyout(&ck_rv, ARG + off, sizeof (ck_rv)) != 0) {
330 error = EFAULT;
331 }
332
333 bzero(kssl_params, len);
334 kmem_free(kssl_params, len);
335 break;
336 }
337 case KSSL_DELETE_ENTRY: {
338 struct sockaddr_in6 server_addr;
339
340 if (copyin(ARG, &server_addr, sizeof (server_addr)) != 0) {
341 return (EFAULT);
342 }
343
344 error = kssl_delete_entry(&server_addr);
345 if (auditing)
346 audit_kssl(KSSL_DELETE_ENTRY, &server_addr, error);
347 break;
348 }
349 }
350
351 return (error);
352 }
353
354 #define NUM_MECHS 7
355 static mech_to_cipher_t mech_to_cipher_tab[NUM_MECHS] = {
356 {CRYPTO_MECH_INVALID, SUN_CKM_RSA_X_509,
357 {SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA,
358 SSL_RSA_WITH_DES_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA,
359 TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA,
360 SSL_RSA_WITH_NULL_SHA}},
361 {CRYPTO_MECH_INVALID, SUN_CKM_MD5_HMAC, {SSL_RSA_WITH_RC4_128_MD5}},
362 {CRYPTO_MECH_INVALID, SUN_CKM_SHA1_HMAC,
363 {SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_DES_CBC_SHA,
364 SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_NULL_SHA,
365 TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}},
366 {CRYPTO_MECH_INVALID, SUN_CKM_RC4,
367 {SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA}},
368 {CRYPTO_MECH_INVALID, SUN_CKM_DES_CBC, {SSL_RSA_WITH_DES_CBC_SHA}},
369 {CRYPTO_MECH_INVALID, SUN_CKM_DES3_CBC,
370 {SSL_RSA_WITH_3DES_EDE_CBC_SHA}},
371 {CRYPTO_MECH_INVALID, SUN_CKM_AES_CBC,
372 {TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}},
373 };
374
375 static void
kssl_init_mechs()376 kssl_init_mechs()
377 {
378 mech_to_cipher_tab[0].mech = rsa_x509_mech.cm_type =
379 crypto_mech2id(SUN_CKM_RSA_X_509);
380 mech_to_cipher_tab[1].mech = hmac_md5_mech.cm_type =
381 crypto_mech2id(SUN_CKM_MD5_HMAC);
382 mech_to_cipher_tab[2].mech = hmac_sha1_mech.cm_type =
383 crypto_mech2id(SUN_CKM_SHA1_HMAC);
384
385 mech_to_cipher_tab[3].mech = cipher_defs[cipher_rc4].mech_type =
386 crypto_mech2id(SUN_CKM_RC4);
387 mech_to_cipher_tab[4].mech = cipher_defs[cipher_des].mech_type =
388 crypto_mech2id(SUN_CKM_DES_CBC);
389 mech_to_cipher_tab[5].mech = cipher_defs[cipher_3des].mech_type =
390 crypto_mech2id(SUN_CKM_DES3_CBC);
391 mech_to_cipher_tab[6].mech = cipher_defs[cipher_aes128].mech_type =
392 cipher_defs[cipher_aes256].mech_type =
393 crypto_mech2id(SUN_CKM_AES_CBC);
394 }
395
396 static int
is_in_suites(uint16_t s,uint16_t * sarray)397 is_in_suites(uint16_t s, uint16_t *sarray)
398 {
399 int i;
400
401 for (i = 0; i < CIPHER_SUITE_COUNT; i++) {
402 if (s == sarray[i])
403 return (1);
404 }
405
406 return (0);
407 }
408
409 static int
is_in_mechlist(char * name,crypto_mech_name_t * mechs,int count)410 is_in_mechlist(char *name, crypto_mech_name_t *mechs, int count)
411 {
412 int i;
413
414 for (i = 0; i < count; i++) {
415 if (strncmp(name, mechs[i], CRYPTO_MAX_MECH_NAME) == 0)
416 return (1);
417 }
418
419 return (0);
420 }
421
422 /*
423 * Callback function invoked by the crypto framework when a provider's
424 * mechanism is available/unavailable. This callback updates entries in the
425 * kssl_entry_tab[] to make changes to the cipher suites of an entry
426 * which are affected by the mechanism.
427 */
428 static void
kssl_event_callback(uint32_t event,void * event_arg)429 kssl_event_callback(uint32_t event, void *event_arg)
430 {
431 int i, j;
432 int cnt, rcnt;
433 uint16_t s;
434 boolean_t changed;
435 crypto_mech_name_t *mechs;
436 uint_t mech_count;
437 mech_to_cipher_t *mc;
438 kssl_entry_t *old;
439 kssl_entry_t *new;
440 uint16_t tmp_suites[CIPHER_SUITE_COUNT];
441 uint16_t dis_list[CIPHER_SUITE_COUNT];
442 crypto_notify_event_change_t *prov_change =
443 (crypto_notify_event_change_t *)event_arg;
444
445 /* ignore events for which we didn't register */
446 if (event != CRYPTO_EVENT_MECHS_CHANGED) {
447 return;
448 }
449
450 for (i = 0; i < NUM_MECHS; i++) {
451 mc = &(mech_to_cipher_tab[i]);
452 if (mc->mech == CRYPTO_MECH_INVALID)
453 continue;
454
455 /*
456 * Check if this crypto framework provider mechanism being
457 * added or removed affects us.
458 */
459 if (strncmp(mc->name, prov_change->ec_mech_name,
460 CRYPTO_MAX_MECH_NAME) == 0)
461 break;
462 }
463
464 if (i == NUM_MECHS)
465 return;
466
467 mechs = crypto_get_mech_list(&mech_count, KM_SLEEP);
468 if (mechs == NULL)
469 return;
470
471 mutex_enter(&kssl_tab_mutex);
472
473 for (i = 0; i < kssl_entry_tab_size; i++) {
474 if ((old = kssl_entry_tab[i]) == NULL)
475 continue;
476
477 cnt = 0;
478 rcnt = 0;
479 changed = B_FALSE;
480 for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
481 tmp_suites[j] = CIPHER_NOTSET;
482 dis_list[j] = CIPHER_NOTSET;
483 }
484
485 /*
486 * We start with the saved cipher suite list for the new entry.
487 * If a mechanism is disabled, resulting in a cipher suite being
488 * disabled now, we take it out from the list for the new entry.
489 * If a mechanism is enabled, resulting in a cipher suite being
490 * enabled now, we don't need to do any thing.
491 */
492 if (!is_in_mechlist(mc->name, mechs, mech_count)) {
493 for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
494 s = mc->kssl_suites[j];
495 if (s == 0)
496 break;
497 if (is_in_suites(s, old->kssl_saved_Suites)) {
498 /* Disable this cipher suite */
499 if (!is_in_suites(s, dis_list))
500 dis_list[cnt++] = s;
501 }
502 }
503 }
504
505 for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
506 s = old->kssl_saved_Suites[j];
507 if (!is_in_suites(s, dis_list))
508 tmp_suites[rcnt] = s;
509
510 if (!changed &&
511 (tmp_suites[rcnt] != old->kssl_cipherSuites[rcnt]))
512 changed = B_TRUE;
513 rcnt++;
514 }
515
516 if (changed) {
517 new = kmem_zalloc(sizeof (kssl_entry_t), KM_NOSLEEP);
518 if (new == NULL)
519 continue;
520
521 *new = *old; /* Structure copy */
522 old->ke_no_freeall = B_TRUE;
523 new->ke_refcnt = 0;
524 new->kssl_cipherSuites_nentries = rcnt;
525 for (j = 0; j < CIPHER_SUITE_COUNT; j++)
526 new->kssl_cipherSuites[j] = tmp_suites[j];
527
528 KSSL_ENTRY_REFHOLD(new);
529 kssl_entry_tab[i] = new;
530 KSSL_ENTRY_REFRELE(old);
531 }
532 }
533
534 mutex_exit(&kssl_tab_mutex);
535 crypto_free_mech_list(mechs, mech_count);
536 }
537
538
539 kssl_stats_t *kssl_statp;
540
541 static void
kssl_global_init()542 kssl_global_init()
543 {
544 mutex_init(&kssl_tab_mutex, NULL, MUTEX_DRIVER, NULL);
545
546 kssl_cache = kmem_cache_create("kssl_cache", sizeof (ssl_t),
547 0, kssl_constructor, kssl_destructor, NULL, NULL, NULL, 0);
548
549 if ((kssl_ksp = kstat_create("kssl", 0, "kssl_stats", "crypto",
550 KSTAT_TYPE_NAMED, sizeof (kssl_stats_t) / sizeof (kstat_named_t),
551 KSTAT_FLAG_PERSISTENT)) != NULL) {
552 kssl_statp = kssl_ksp->ks_data;
553
554 kstat_named_init(&kssl_statp->sid_cache_lookups,
555 "kssl_sid_cache_lookups", KSTAT_DATA_UINT64);
556 kstat_named_init(&kssl_statp->sid_cache_hits,
557 "kssl_sid_cache_hits", KSTAT_DATA_UINT64);
558 kstat_named_init(&kssl_statp->sid_cached,
559 "kssl_sid_cached", KSTAT_DATA_UINT64);
560 kstat_named_init(&kssl_statp->sid_uncached,
561 "kssl_sid_uncached", KSTAT_DATA_UINT64);
562
563 kstat_named_init(&kssl_statp->full_handshakes,
564 "kssl_full_handshakes", KSTAT_DATA_UINT64);
565 kstat_named_init(&kssl_statp->resumed_sessions,
566 "kssl_resumed_sessions", KSTAT_DATA_UINT64);
567 kstat_named_init(&kssl_statp->fallback_connections,
568 "kssl_fallback_connections", KSTAT_DATA_UINT64);
569 kstat_named_init(&kssl_statp->proxy_fallback_failed,
570 "kssl_proxy_fallback_failed", KSTAT_DATA_UINT64);
571 kstat_named_init(&kssl_statp->appdata_record_ins,
572 "kssl_appdata_record_ins", KSTAT_DATA_UINT64);
573 kstat_named_init(&kssl_statp->appdata_record_outs,
574 "kssl_appdata_record_outs", KSTAT_DATA_UINT64);
575
576 kstat_named_init(&kssl_statp->alloc_fails, "kssl_alloc_fails",
577 KSTAT_DATA_UINT64);
578 kstat_named_init(&kssl_statp->fatal_alerts,
579 "kssl_fatal_alerts", KSTAT_DATA_UINT64);
580 kstat_named_init(&kssl_statp->warning_alerts,
581 "kssl_warning_alerts", KSTAT_DATA_UINT64);
582 kstat_named_init(&kssl_statp->no_suite_found,
583 "kssl_no_suite_found", KSTAT_DATA_UINT64);
584 kstat_named_init(&kssl_statp->compute_mac_failure,
585 "kssl_compute_mac_failure", KSTAT_DATA_UINT64);
586 kstat_named_init(&kssl_statp->verify_mac_failure,
587 "kssl_verify_mac_failure", KSTAT_DATA_UINT64);
588 kstat_named_init(&kssl_statp->record_decrypt_failure,
589 "kssl_record_decrypt_failure", KSTAT_DATA_UINT64);
590 kstat_named_init(&kssl_statp->bad_pre_master_secret,
591 "kssl_bad_pre_master_secret", KSTAT_DATA_UINT64);
592 kstat_named_init(&kssl_statp->internal_errors,
593 "kssl_internal_errors", KSTAT_DATA_UINT64);
594
595 kstat_install(kssl_ksp);
596 };
597 }
598
599 static void
kssl_global_fini(void)600 kssl_global_fini(void)
601 {
602 mutex_destroy(&kssl_tab_mutex);
603
604 if (kssl_cache != NULL) {
605 kmem_cache_destroy(kssl_cache);
606 kssl_cache = NULL;
607 }
608
609 if (kssl_ksp != NULL) {
610 kstat_delete(kssl_ksp);
611 kssl_ksp = NULL;
612 }
613 }
614
615 /*ARGSUSED*/
616 static int
kssl_constructor(void * buf,void * arg,int kmflags)617 kssl_constructor(void *buf, void *arg, int kmflags)
618 {
619 ssl_t *ssl = buf;
620
621 mutex_init(&ssl->kssl_lock, NULL, MUTEX_DEFAULT, NULL);
622 cv_init(&ssl->async_cv, NULL, CV_DEFAULT, NULL);
623
624 return (0);
625 }
626
627 /*ARGSUSED*/
628 static void
kssl_destructor(void * buf,void * arg)629 kssl_destructor(void *buf, void *arg)
630 {
631 ssl_t *ssl = buf;
632 mutex_destroy(&ssl->kssl_lock);
633 cv_destroy(&ssl->async_cv);
634 }
635
636 /*
637 * Handler routine called by the crypto framework when a
638 * provider is unregistered or registered. We invalidate the
639 * private key handle if our provider is unregistered. We set
640 * a flag to reauthenticate if our provider came back.
641 */
642 void
kssl_prov_evnt(uint32_t event,void * event_arg)643 kssl_prov_evnt(uint32_t event, void *event_arg)
644 {
645 int i, rv;
646 kssl_entry_t *ep;
647 kssl_session_info_t *s;
648 crypto_provider_t prov;
649 crypto_provider_ext_info_t info;
650
651 if (event != CRYPTO_EVENT_PROVIDER_UNREGISTERED &&
652 event != CRYPTO_EVENT_PROVIDER_REGISTERED)
653 return;
654
655 prov = (crypto_provider_t)event_arg;
656 if (event == CRYPTO_EVENT_PROVIDER_REGISTERED) {
657 rv = crypto_get_provinfo(prov, &info);
658 if (rv != CRYPTO_SUCCESS)
659 return;
660 }
661
662 mutex_enter(&kssl_tab_mutex);
663
664 for (i = 0; i < kssl_entry_tab_size; i++) {
665 if ((ep = kssl_entry_tab[i]) == NULL)
666 continue;
667
668 s = ep->ke_sessinfo;
669 DTRACE_PROBE1(kssl_entry_cycle, kssl_entry_t *, ep);
670 switch (event) {
671 case CRYPTO_EVENT_PROVIDER_UNREGISTERED:
672 if (s->is_valid_handle && s->prov == prov) {
673 s->is_valid_handle = B_FALSE;
674 crypto_release_provider(s->prov);
675 }
676 break;
677
678 case CRYPTO_EVENT_PROVIDER_REGISTERED:
679 if (s->is_valid_handle)
680 break;
681 if (bcmp(s->toklabel, info.ei_label,
682 CRYPTO_EXT_SIZE_LABEL) == 0) {
683 s->do_reauth = B_TRUE;
684 }
685 break;
686 }
687 }
688
689 mutex_exit(&kssl_tab_mutex);
690 }
691