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