c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER START
c28749e97052f09388969427adf7df641cdcdc22kais * The contents of this file are subject to the terms of the
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Common Development and Distribution License (the "License").
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * You may not use this file except in compliance with the License.
c28749e97052f09388969427adf7df641cdcdc22kais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c28749e97052f09388969427adf7df641cdcdc22kais * See the License for the specific language governing permissions
c28749e97052f09388969427adf7df641cdcdc22kais * and limitations under the License.
c28749e97052f09388969427adf7df641cdcdc22kais * When distributing Covered Code, include this CDDL HEADER in each
c28749e97052f09388969427adf7df641cdcdc22kais * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c28749e97052f09388969427adf7df641cdcdc22kais * If applicable, add the following below this CDDL HEADER, with the
c28749e97052f09388969427adf7df641cdcdc22kais * fields enclosed by brackets "[]" replaced with your own identifying
c28749e97052f09388969427adf7df641cdcdc22kais * information: Portions Copyright [yyyy] [name of copyright owner]
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER END
dd49f125507979bb2ab505a8daf2a46d1be27051Anders Persson * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
c28749e97052f09388969427adf7df641cdcdc22kais * The system call and DDI interface for the kernel SSL module
c28749e97052f09388969427adf7df641cdcdc22kais * DDI entry points.
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int kssl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int kssl_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int kssl_constructor(void *buf, void *arg, int kmflags);
c28749e97052f09388969427adf7df641cdcdc22kais * Module linkage.
c28749e97052f09388969427adf7df641cdcdc22kais 0, /* devo_refcnt */
c28749e97052f09388969427adf7df641cdcdc22kaiscrypto_mechanism_t rsa_x509_mech = {CRYPTO_MECH_INVALID, NULL, 0};
c28749e97052f09388969427adf7df641cdcdc22kaiscrypto_mechanism_t hmac_md5_mech = {CRYPTO_MECH_INVALID, NULL, 0};
c28749e97052f09388969427adf7df641cdcdc22kaiscrypto_mechanism_t hmac_sha1_mech = {CRYPTO_MECH_INVALID, NULL, 0};
c28749e97052f09388969427adf7df641cdcdc22kaiscrypto_call_flag_t kssl_call_flag = CRYPTO_ALWAYS_QUEUE;
c28749e97052f09388969427adf7df641cdcdc22kaisKSSLCipherDef cipher_defs[] = { /* indexed by SSL3BulkCipher */
c28749e97052f09388969427adf7df641cdcdc22kais /* type bsize keysz crypto_mech_type_t */
c28749e97052f09388969427adf7df641cdcdc22kais /* mech_type to be initialized with CKM_RC4's */
c28749e97052f09388969427adf7df641cdcdc22kais /* mech_type to be initialized with CKM_DES_CBC's */
c28749e97052f09388969427adf7df641cdcdc22kais /* mech_type to be initialized with CKM_DES3_CBC's */
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna /* mech_type to be initialized with CKM_AES_CBC with 128-bit key */
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna /* mech_type to be initialized with CKM_AES_CBC with 256-bit key */
dd49f125507979bb2ab505a8daf2a46d1be27051Anders Perssonstatic crypto_notify_handle_t prov_update_handle = NULL;
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void kssl_global_init();
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void kssl_init_mechs();
c28749e97052f09388969427adf7df641cdcdc22kais * DDI entry points.
dd49f125507979bb2ab505a8daf2a46d1be27051Anders Persson if ((error = mod_install(&modlinkage)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais/* ARGSUSED */
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
c28749e97052f09388969427adf7df641cdcdc22kais switch (cmd) {
c28749e97052f09388969427adf7df641cdcdc22kais *result = (void *)0;
c28749e97052f09388969427adf7df641cdcdc22kais /* we only allow instance 0 to attach */
c28749e97052f09388969427adf7df641cdcdc22kais /* create the minor node */
c28749e97052f09388969427adf7df641cdcdc22kais if (ddi_create_minor_node(dip, "kssl", S_IFCHR, 0, DDI_PSEUDO, 0) !=
c28749e97052f09388969427adf7df641cdcdc22kais cmn_err(CE_WARN, "kssl_attach: failed creating minor node");
c28749e97052f09388969427adf7df641cdcdc22kais/* ARGSUSED */
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_open(dev_t *devp, int flag, int otyp, cred_t *credp)
c28749e97052f09388969427adf7df641cdcdc22kais /* first time here? initialize everything */
c28749e97052f09388969427adf7df641cdcdc22kais /* exclusive opens are not supported */
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais/* ARGSUSED */
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_close(dev_t dev, int flag, int otyp, cred_t *credp)
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais#define KSSL_MAX_KEYANDCERTS 80000 /* max 64K plus a little margin */
c28749e97052f09388969427adf7df641cdcdc22kais/* ARGSUSED */
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
c28749e97052f09388969427adf7df641cdcdc22kais switch (cmd) {
c28749e97052f09388969427adf7df641cdcdc22kais /* Get the whole structure and parameters in one move */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (copyout(&ck_rv, ARG + off, sizeof (ck_rv)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais if (copyin(ARG, &server_addr, sizeof (server_addr)) != 0) {
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduristatic mech_to_cipher_t mech_to_cipher_tab[NUM_MECHS] = {
c28749e97052f09388969427adf7df641cdcdc22kais SSL_RSA_WITH_DES_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA,
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA,
c28749e97052f09388969427adf7df641cdcdc22kais {CRYPTO_MECH_INVALID, SUN_CKM_MD5_HMAC, {SSL_RSA_WITH_RC4_128_MD5}},
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_NULL_SHA,
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}},
c28749e97052f09388969427adf7df641cdcdc22kais {CRYPTO_MECH_INVALID, SUN_CKM_DES_CBC, {SSL_RSA_WITH_DES_CBC_SHA}},
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna {TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}},
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kais mech_to_cipher_tab[3].mech = cipher_defs[cipher_rc4].mech_type =
c28749e97052f09388969427adf7df641cdcdc22kais mech_to_cipher_tab[4].mech = cipher_defs[cipher_des].mech_type =
c28749e97052f09388969427adf7df641cdcdc22kais mech_to_cipher_tab[5].mech = cipher_defs[cipher_3des].mech_type =
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna mech_to_cipher_tab[6].mech = cipher_defs[cipher_aes128].mech_type =
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < CIPHER_SUITE_COUNT; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (s == sarray[i])
c28749e97052f09388969427adf7df641cdcdc22kais return (1);
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kaisis_in_mechlist(char *name, crypto_mech_name_t *mechs, int count)
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (strncmp(name, mechs[i], CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais return (1);
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais * Callback function invoked by the crypto framework when a provider's
c28749e97052f09388969427adf7df641cdcdc22kais * mechanism is available/unavailable. This callback updates entries in the
c28749e97052f09388969427adf7df641cdcdc22kais * kssl_entry_tab[] to make changes to the cipher suites of an entry
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri * which are affected by the mechanism.
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kais /* ignore events for which we didn't register */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < NUM_MECHS; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais * Check if this crypto framework provider mechanism being
c28749e97052f09388969427adf7df641cdcdc22kais * added or removed affects us.
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry_tab_size; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
c28749e97052f09388969427adf7df641cdcdc22kais * We start with the saved cipher suite list for the new entry.
c28749e97052f09388969427adf7df641cdcdc22kais * If a mechanism is disabled, resulting in a cipher suite being
c28749e97052f09388969427adf7df641cdcdc22kais * disabled now, we take it out from the list for the new entry.
c28749e97052f09388969427adf7df641cdcdc22kais * If a mechanism is enabled, resulting in a cipher suite being
c28749e97052f09388969427adf7df641cdcdc22kais * enabled now, we don't need to do any thing.
c28749e97052f09388969427adf7df641cdcdc22kais for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (s == 0)
c28749e97052f09388969427adf7df641cdcdc22kais /* Disable this cipher suite */
c28749e97052f09388969427adf7df641cdcdc22kais for (j = 0; j < CIPHER_SUITE_COUNT; j++) {
c28749e97052f09388969427adf7df641cdcdc22kais for (j = 0; j < CIPHER_SUITE_COUNT; j++)
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kais kssl_cache = kmem_cache_create("kssl_cache", sizeof (ssl_t),
c28749e97052f09388969427adf7df641cdcdc22kais 0, kssl_constructor, kssl_destructor, NULL, NULL, NULL, 0);
5cd9bd63ac79b9a1a6c7a09230426e181988d09akrishna if ((kssl_ksp = kstat_create("kssl", 0, "kssl_stats", "crypto",
c28749e97052f09388969427adf7df641cdcdc22kais KSTAT_TYPE_NAMED, sizeof (kssl_stats_t) / sizeof (kstat_named_t),
c28749e97052f09388969427adf7df641cdcdc22kais kstat_named_init(&kssl_statp->alloc_fails, "kssl_alloc_fails",
c28749e97052f09388969427adf7df641cdcdc22kais/*ARGSUSED*/
c28749e97052f09388969427adf7df641cdcdc22kais mutex_init(&ssl->kssl_lock, NULL, MUTEX_DEFAULT, NULL);
dd49f125507979bb2ab505a8daf2a46d1be27051Anders Persson cv_init(&ssl->async_cv, NULL, CV_DEFAULT, NULL);
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais/*ARGSUSED*/
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Handler routine called by the crypto framework when a
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * provider is unregistered or registered. We invalidate the
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * private key handle if our provider is unregistered. We set
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * a flag to reauthenticate if our provider came back.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna for (i = 0; i < kssl_entry_tab_size; i++) {