diff options
Diffstat (limited to 'usr/src/uts')
24 files changed, 8 insertions, 7224 deletions
diff --git a/usr/src/uts/Makefile b/usr/src/uts/Makefile index 7e83978de5..b21c920fce 100644 --- a/usr/src/uts/Makefile +++ b/usr/src/uts/Makefile @@ -138,7 +138,6 @@ COMMON_HDRDIRS= common/c2 \ common/klm \ common/inet \ common/inet/ipf/netinet \ - common/inet/kssl \ common/inet/nca \ common/inet/sockmods/netpacket \ common/io/bpf/net \ diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 6151835e1a..0c8c23ead8 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -24,7 +24,7 @@ # Copyright (c) 2011, 2014 by Delphix. All rights reserved. # Copyright (c) 2013 by Saso Kiselkov. All rights reserved. # Copyright 2018 Nexenta Systems, Inc. -# Copyright 2016 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2020 Joyent, Inc. # Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> @@ -1639,13 +1639,6 @@ RSAPROV_OBJS += rsa.o rsa_impl.o pkcs1.o SWRANDPROV_OBJS += swrand.o # -# kernel SSL -# -KSSL_OBJS += kssl.o ksslioctl.o - -KSSL_SOCKFIL_MOD_OBJS += ksslfilter.o ksslapi.o ksslrec.o - -# # misc. modules # diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules index 3439c34ba0..8a535a17ec 100644 --- a/usr/src/uts/common/Makefile.rules +++ b/usr/src/uts/common/Makefile.rules @@ -21,7 +21,7 @@ # # Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2016 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2013 Saso Kiselkov. All rights reserved. # Copyright 2019 Joyent, Inc. # Copyright 2018 Nexenta Systems, Inc. @@ -498,10 +498,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/iptun/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/kssl/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/inet/sctp/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) diff --git a/usr/src/uts/common/c2/audit.c b/usr/src/uts/common/c2/audit.c index 0553cca7b2..15d492bdb5 100644 --- a/usr/src/uts/common/c2/audit.c +++ b/usr/src/uts/common/c2/audit.c @@ -61,7 +61,6 @@ #include <sys/devpolicy.h> #include <sys/crypto/ioctladmin.h> #include <sys/cred_impl.h> -#include <inet/kssl/kssl.h> #include <net/pfpolicy.h> static void add_return_token(caddr_t *, unsigned int scid, int err, int rval); @@ -2003,79 +2002,6 @@ audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names, } /* - * Audit the kernel SSL administration command. The address and the - * port number for the SSL instance, and the proxy port are put in the - * audit trail. - */ -void -audit_kssl(int cmd, void *params, int error) -{ - cred_t *cr = CRED(); - t_audit_data_t *tad; - token_t *ad = NULL; - const auditinfo_addr_t *ainfo = crgetauinfo(cr); - au_kcontext_t *kctx = GET_KCTX_PZ; - - tad = U2A(u); - - if (ainfo == NULL) - return; - - tad->tad_event = AUE_CONFIGKSSL; - - if (audit_success(kctx, tad, error, NULL) != AU_OK) - return; - - /* Add subject information */ - AUDIT_SETSUBJ((caddr_t *)&ad, cr, ainfo, kctx); - - switch (cmd) { - case KSSL_ADD_ENTRY: { - char buf[32]; - kssl_params_t *kp = (kssl_params_t *)params; - struct sockaddr_in6 *saddr = &kp->kssl_addr; - - au_write((caddr_t *)&ad, au_to_text("op=KSSL_ADD_ENTRY")); - au_write((caddr_t *)&ad, - au_to_in_addr_ex((int32_t *)&saddr->sin6_addr)); - (void) snprintf(buf, sizeof (buf), "SSL port=%d", - saddr->sin6_port); - au_write((caddr_t *)&ad, au_to_text(buf)); - - (void) snprintf(buf, sizeof (buf), "proxy port=%d", - kp->kssl_proxy_port); - au_write((caddr_t *)&ad, au_to_text(buf)); - break; - } - - case KSSL_DELETE_ENTRY: { - char buf[32]; - struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)params; - - au_write((caddr_t *)&ad, au_to_text("op=KSSL_DELETE_ENTRY")); - au_write((caddr_t *)&ad, - au_to_in_addr_ex((int32_t *)&saddr->sin6_addr)); - (void) snprintf(buf, sizeof (buf), "SSL port=%d", - saddr->sin6_port); - au_write((caddr_t *)&ad, au_to_text(buf)); - break; - } - - default: - return; - } - - /* add a return token */ - add_return_token((caddr_t *)&ad, tad->tad_scid, error, 0); - - AS_INC(as_generated, 1, kctx); - AS_INC(as_kernel, 1, kctx); - - au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CONFIGKSSL, tad->tad_evmod, - NULL); -} - -/* * Audit the kernel PF_POLICY administration commands. Record command, * zone, policy type (global or tunnel, active or inactive) */ diff --git a/usr/src/uts/common/c2/audit.h b/usr/src/uts/common/c2/audit.h index 27a0388b14..66539662c1 100644 --- a/usr/src/uts/common/c2/audit.h +++ b/usr/src/uts/common/c2/audit.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Garrett D'Amore <garrett@damore.org> */ /* @@ -595,7 +596,6 @@ void audit_psecflags(proc_t *, psecflagwhich_t, const secflagdelta_t *); void audit_devpolicy(int, const struct devplcysys *); void audit_update_context(proc_t *, cred_t *); -void audit_kssl(int, void *, int); void audit_pf_policy(int, cred_t *, netstack_t *, char *, boolean_t, int, pid_t); void audit_sec_attributes(caddr_t *, struct vnode *); diff --git a/usr/src/uts/common/inet/kssl/Makefile b/usr/src/uts/common/inet/kssl/Makefile deleted file mode 100644 index 47df45ba4a..0000000000 --- a/usr/src/uts/common/inet/kssl/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# uts/common/inet/kssl/Makefile -# -# include global definitions -include ../../../../Makefile.master - -HDRS= kssl.h ksslapi.h ksslimpl.h ksslproto.h - -ROOTDIRS= $(ROOT)/usr/include/inet/kssl - -ROOTHDRS= $(HDRS:%=$(ROOT)/usr/include/inet/kssl/%) - -CHECKHDRS= $(HDRS:%.h=%.check) - -$(ROOTDIRS)/%: % - $(INS.file) - -.KEEP_STATE: - -.PARALLEL: $(CHECKHDRS) - -install_h: $(ROOTDIRS) $(ROOTHDRS) - -$(ROOTDIRS): - $(INS.dir) - -check: $(CHECKHDRS) diff --git a/usr/src/uts/common/inet/kssl/kssl.c b/usr/src/uts/common/inet/kssl/kssl.c deleted file mode 100644 index 37d10c6f84..0000000000 --- a/usr/src/uts/common/inet/kssl/kssl.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - - -/* - * The system call and DDI interface for the kernel SSL module - */ - -#include <sys/types.h> -#include <sys/modctl.h> -#include <sys/conf.h> -#include <sys/stat.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/kmem.h> -#include <sys/errno.h> -#include <sys/file.h> -#include <sys/open.h> -#include <sys/cred.h> -#include <sys/proc.h> -#include <sys/task.h> -#include <sys/model.h> -#include <sys/sysmacros.h> -#include <sys/policy.h> -#include <sys/crypto/common.h> -#include <sys/crypto/api.h> -#include <c2/audit.h> -#include <sys/kstat.h> - -#include "kssl.h" -#include "ksslimpl.h" - -/* - * DDI entry points. - */ -static int kssl_attach(dev_info_t *, ddi_attach_cmd_t); -static int kssl_detach(dev_info_t *, ddi_detach_cmd_t); -static int kssl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int kssl_open(dev_t *, int, int, cred_t *); -static int kssl_close(dev_t, int, int, cred_t *); -static int kssl_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); - -static int kssl_constructor(void *buf, void *arg, int kmflags); -static void kssl_destructor(void *buf, void *arg); - -/* - * Module linkage. - */ -static struct cb_ops cbops = { - kssl_open, /* cb_open */ - kssl_close, /* cb_close */ - nodev, /* cb_strategy */ - nodev, /* cb_print */ - nodev, /* cb_dump */ - nodev, /* cb_read */ - nodev, /* cb_write */ - kssl_ioctl, /* cb_ioctl */ - nodev, /* cb_devmap */ - nodev, /* cb_mmap */ - nodev, /* cb_segmap */ - nochpoll, /* cb_chpoll */ - ddi_prop_op, /* cb_prop_op */ - NULL, /* cb_streamtab */ - D_MP, /* cb_flag */ - CB_REV, /* cb_rev */ - nodev, /* cb_aread */ - nodev, /* cb_awrite */ -}; - -static struct dev_ops devops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - kssl_getinfo, /* devo_getinfo */ - nulldev, /* devo_identify */ - nulldev, /* devo_probe */ - kssl_attach, /* devo_attach */ - kssl_detach, /* devo_detach */ - nodev, /* devo_reset */ - &cbops, /* devo_cb_ops */ - NULL, /* devo_bus_ops */ - NULL, /* devo_power */ - ddi_quiesce_not_needed, /* devo_quiesce */ -}; - -static struct modldrv modldrv = { - &mod_driverops, /* drv_modops */ - "Kernel SSL Interface", /* drv_linkinfo */ - &devops, -}; - -static struct modlinkage modlinkage = { - MODREV_1, /* ml_rev */ - &modldrv, /* ml_linkage */ - NULL -}; - -static dev_info_t *kssl_dip = NULL; - -crypto_mechanism_t rsa_x509_mech = {CRYPTO_MECH_INVALID, NULL, 0}; -crypto_mechanism_t hmac_md5_mech = {CRYPTO_MECH_INVALID, NULL, 0}; -crypto_mechanism_t hmac_sha1_mech = {CRYPTO_MECH_INVALID, NULL, 0}; -crypto_call_flag_t kssl_call_flag = CRYPTO_ALWAYS_QUEUE; - -KSSLCipherDef cipher_defs[] = { /* indexed by SSL3BulkCipher */ - /* type bsize keysz crypto_mech_type_t */ - - {type_stream, 0, 0, CRYPTO_MECH_INVALID}, - - /* mech_type to be initialized with CKM_RC4's */ - {type_stream, 0, 16, CRYPTO_MECH_INVALID}, - - /* mech_type to be initialized with CKM_DES_CBC's */ - {type_block, 8, 8, CRYPTO_MECH_INVALID}, - - /* mech_type to be initialized with CKM_DES3_CBC's */ - {type_block, 8, 24, CRYPTO_MECH_INVALID}, - - /* mech_type to be initialized with CKM_AES_CBC with 128-bit key */ - {type_block, 16, 16, CRYPTO_MECH_INVALID}, - - /* mech_type to be initialized with CKM_AES_CBC with 256-bit key */ - {type_block, 16, 32, CRYPTO_MECH_INVALID}, -}; - -struct kmem_cache *kssl_cache; -static crypto_notify_handle_t prov_update_handle = NULL; - -static void kssl_global_init(); -static void kssl_global_fini(); -static void kssl_init_mechs(); -static void kssl_event_callback(uint32_t, void *); - -/* - * DDI entry points. - */ -int -_init(void) -{ - int error; - - kssl_global_init(); - - if ((error = mod_install(&modlinkage)) != 0) { - kssl_global_fini(); - return (error); - } - return (0); -} - -int -_fini(void) -{ - int error; - - if ((error = mod_remove(&modlinkage)) != 0) - return (error); - - if (prov_update_handle != NULL) - crypto_unnotify_events(prov_update_handle); - - kssl_global_fini(); - - return (0); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/* ARGSUSED */ -static int -kssl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) -{ - switch (cmd) { - case DDI_INFO_DEVT2DEVINFO: - *result = kssl_dip; - return (DDI_SUCCESS); - - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)0; - return (DDI_SUCCESS); - } - return (DDI_FAILURE); -} - -static int -kssl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - if (cmd != DDI_ATTACH) { - return (DDI_FAILURE); - } - - if (ddi_get_instance(dip) != 0) { - /* we only allow instance 0 to attach */ - return (DDI_FAILURE); - } - - /* create the minor node */ - if (ddi_create_minor_node(dip, "kssl", S_IFCHR, 0, DDI_PSEUDO, 0) != - DDI_SUCCESS) { - cmn_err(CE_WARN, "kssl_attach: failed creating minor node"); - ddi_remove_minor_node(dip, NULL); - return (DDI_FAILURE); - } - - kssl_dip = dip; - - return (DDI_SUCCESS); -} - -static kstat_t *kssl_ksp = NULL; - -static int -kssl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - if (cmd != DDI_DETACH) - return (DDI_FAILURE); - - if (kssl_entry_tab_nentries != 0) - return (DDI_FAILURE); - - kssl_dip = NULL; - - ddi_remove_minor_node(dip, NULL); - - return (DDI_SUCCESS); -} - -/* ARGSUSED */ -static int -kssl_open(dev_t *devp, int flag, int otyp, cred_t *credp) -{ - if (otyp != OTYP_CHR) - return (ENXIO); - - if (kssl_dip == NULL) - return (ENXIO); - - /* first time here? initialize everything */ - if (rsa_x509_mech.cm_type == CRYPTO_MECH_INVALID) { - kssl_init_mechs(); - prov_update_handle = crypto_notify_events( - kssl_event_callback, CRYPTO_EVENT_MECHS_CHANGED); - } - - /* exclusive opens are not supported */ - if (flag & FEXCL) - return (ENOTSUP); - - return (0); -} - -/* ARGSUSED */ -static int -kssl_close(dev_t dev, int flag, int otyp, cred_t *credp) -{ - return (0); -} - -#define KSSL_MAX_KEYANDCERTS 80000 /* max 64K plus a little margin */ - -/* ARGSUSED */ -static int -kssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, - int *rval) -{ - int error = EINVAL; - uint32_t auditing = AU_AUDITING(); - -#define ARG ((caddr_t)arg) - - if (secpolicy_net_config(c, B_FALSE) != 0) { - return (EPERM); - } - - switch (cmd) { - case KSSL_ADD_ENTRY: { - uint64_t len; - uint32_t ck_rv; - size_t off; - kssl_params_t *kssl_params; - - off = offsetof(kssl_params_t, kssl_params_size); - if (copyin(ARG + off, &len, sizeof (len)) != 0) { - return (EFAULT); - } - - if (len < sizeof (kssl_params_t) || - len > KSSL_MAX_KEYANDCERTS) { - return (EINVAL); - } - - kssl_params = kmem_alloc(len, KM_SLEEP); - - /* Get the whole structure and parameters in one move */ - if (copyin(ARG, kssl_params, len) != 0) { - kmem_free(kssl_params, len); - return (EFAULT); - } - error = kssl_add_entry(kssl_params); - if (auditing) - audit_kssl(KSSL_ADD_ENTRY, kssl_params, error); - off = offsetof(kssl_params_t, kssl_token) + - offsetof(kssl_tokinfo_t, ck_rv); - ck_rv = kssl_params->kssl_token.ck_rv; - if (copyout(&ck_rv, ARG + off, sizeof (ck_rv)) != 0) { - error = EFAULT; - } - - bzero(kssl_params, len); - kmem_free(kssl_params, len); - break; - } - case KSSL_DELETE_ENTRY: { - struct sockaddr_in6 server_addr; - - if (copyin(ARG, &server_addr, sizeof (server_addr)) != 0) { - return (EFAULT); - } - - error = kssl_delete_entry(&server_addr); - if (auditing) - audit_kssl(KSSL_DELETE_ENTRY, &server_addr, error); - break; - } - } - - return (error); -} - -#define NUM_MECHS 7 -static mech_to_cipher_t mech_to_cipher_tab[NUM_MECHS] = { - {CRYPTO_MECH_INVALID, SUN_CKM_RSA_X_509, - {SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, - SSL_RSA_WITH_DES_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, - SSL_RSA_WITH_NULL_SHA}}, - {CRYPTO_MECH_INVALID, SUN_CKM_MD5_HMAC, {SSL_RSA_WITH_RC4_128_MD5}}, - {CRYPTO_MECH_INVALID, SUN_CKM_SHA1_HMAC, - {SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_DES_CBC_SHA, - SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_NULL_SHA, - TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}}, - {CRYPTO_MECH_INVALID, SUN_CKM_RC4, - {SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA}}, - {CRYPTO_MECH_INVALID, SUN_CKM_DES_CBC, {SSL_RSA_WITH_DES_CBC_SHA}}, - {CRYPTO_MECH_INVALID, SUN_CKM_DES3_CBC, - {SSL_RSA_WITH_3DES_EDE_CBC_SHA}}, - {CRYPTO_MECH_INVALID, SUN_CKM_AES_CBC, - {TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}}, -}; - -static void -kssl_init_mechs() -{ - mech_to_cipher_tab[0].mech = rsa_x509_mech.cm_type = - crypto_mech2id(SUN_CKM_RSA_X_509); - mech_to_cipher_tab[1].mech = hmac_md5_mech.cm_type = - crypto_mech2id(SUN_CKM_MD5_HMAC); - mech_to_cipher_tab[2].mech = hmac_sha1_mech.cm_type = - crypto_mech2id(SUN_CKM_SHA1_HMAC); - - mech_to_cipher_tab[3].mech = cipher_defs[cipher_rc4].mech_type = - crypto_mech2id(SUN_CKM_RC4); - mech_to_cipher_tab[4].mech = cipher_defs[cipher_des].mech_type = - crypto_mech2id(SUN_CKM_DES_CBC); - mech_to_cipher_tab[5].mech = cipher_defs[cipher_3des].mech_type = - crypto_mech2id(SUN_CKM_DES3_CBC); - mech_to_cipher_tab[6].mech = cipher_defs[cipher_aes128].mech_type = - cipher_defs[cipher_aes256].mech_type = - crypto_mech2id(SUN_CKM_AES_CBC); -} - -static int -is_in_suites(uint16_t s, uint16_t *sarray) -{ - int i; - - for (i = 0; i < CIPHER_SUITE_COUNT; i++) { - if (s == sarray[i]) - return (1); - } - - return (0); -} - -static int -is_in_mechlist(char *name, crypto_mech_name_t *mechs, int count) -{ - int i; - - for (i = 0; i < count; i++) { - if (strncmp(name, mechs[i], CRYPTO_MAX_MECH_NAME) == 0) - return (1); - } - - return (0); -} - -/* - * Callback function invoked by the crypto framework when a provider's - * mechanism is available/unavailable. This callback updates entries in the - * kssl_entry_tab[] to make changes to the cipher suites of an entry - * which are affected by the mechanism. - */ -static void -kssl_event_callback(uint32_t event, void *event_arg) -{ - int i, j; - int cnt, rcnt; - uint16_t s; - boolean_t changed; - crypto_mech_name_t *mechs; - uint_t mech_count; - mech_to_cipher_t *mc; - kssl_entry_t *old; - kssl_entry_t *new; - uint16_t tmp_suites[CIPHER_SUITE_COUNT]; - uint16_t dis_list[CIPHER_SUITE_COUNT]; - crypto_notify_event_change_t *prov_change = - (crypto_notify_event_change_t *)event_arg; - - /* ignore events for which we didn't register */ - if (event != CRYPTO_EVENT_MECHS_CHANGED) { - return; - } - - for (i = 0; i < NUM_MECHS; i++) { - mc = &(mech_to_cipher_tab[i]); - if (mc->mech == CRYPTO_MECH_INVALID) - continue; - - /* - * Check if this crypto framework provider mechanism being - * added or removed affects us. - */ - if (strncmp(mc->name, prov_change->ec_mech_name, - CRYPTO_MAX_MECH_NAME) == 0) - break; - } - - if (i == NUM_MECHS) - return; - - mechs = crypto_get_mech_list(&mech_count, KM_SLEEP); - if (mechs == NULL) - return; - - mutex_enter(&kssl_tab_mutex); - - for (i = 0; i < kssl_entry_tab_size; i++) { - if ((old = kssl_entry_tab[i]) == NULL) - continue; - - cnt = 0; - rcnt = 0; - changed = B_FALSE; - for (j = 0; j < CIPHER_SUITE_COUNT; j++) { - tmp_suites[j] = CIPHER_NOTSET; - dis_list[j] = CIPHER_NOTSET; - } - - /* - * We start with the saved cipher suite list for the new entry. - * If a mechanism is disabled, resulting in a cipher suite being - * disabled now, we take it out from the list for the new entry. - * If a mechanism is enabled, resulting in a cipher suite being - * enabled now, we don't need to do any thing. - */ - if (!is_in_mechlist(mc->name, mechs, mech_count)) { - for (j = 0; j < CIPHER_SUITE_COUNT; j++) { - s = mc->kssl_suites[j]; - if (s == 0) - break; - if (is_in_suites(s, old->kssl_saved_Suites)) { - /* Disable this cipher suite */ - if (!is_in_suites(s, dis_list)) - dis_list[cnt++] = s; - } - } - } - - for (j = 0; j < CIPHER_SUITE_COUNT; j++) { - s = old->kssl_saved_Suites[j]; - if (!is_in_suites(s, dis_list)) - tmp_suites[rcnt] = s; - - if (!changed && - (tmp_suites[rcnt] != old->kssl_cipherSuites[rcnt])) - changed = B_TRUE; - rcnt++; - } - - if (changed) { - new = kmem_zalloc(sizeof (kssl_entry_t), KM_NOSLEEP); - if (new == NULL) - continue; - - *new = *old; /* Structure copy */ - old->ke_no_freeall = B_TRUE; - new->ke_refcnt = 0; - new->kssl_cipherSuites_nentries = rcnt; - for (j = 0; j < CIPHER_SUITE_COUNT; j++) - new->kssl_cipherSuites[j] = tmp_suites[j]; - - KSSL_ENTRY_REFHOLD(new); - kssl_entry_tab[i] = new; - KSSL_ENTRY_REFRELE(old); - } - } - - mutex_exit(&kssl_tab_mutex); - crypto_free_mech_list(mechs, mech_count); -} - - -kssl_stats_t *kssl_statp; - -static void -kssl_global_init() -{ - mutex_init(&kssl_tab_mutex, NULL, MUTEX_DRIVER, NULL); - - kssl_cache = kmem_cache_create("kssl_cache", sizeof (ssl_t), - 0, kssl_constructor, kssl_destructor, NULL, NULL, NULL, 0); - - if ((kssl_ksp = kstat_create("kssl", 0, "kssl_stats", "crypto", - KSTAT_TYPE_NAMED, sizeof (kssl_stats_t) / sizeof (kstat_named_t), - KSTAT_FLAG_PERSISTENT)) != NULL) { - kssl_statp = kssl_ksp->ks_data; - - kstat_named_init(&kssl_statp->sid_cache_lookups, - "kssl_sid_cache_lookups", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->sid_cache_hits, - "kssl_sid_cache_hits", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->sid_cached, - "kssl_sid_cached", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->sid_uncached, - "kssl_sid_uncached", KSTAT_DATA_UINT64); - - kstat_named_init(&kssl_statp->full_handshakes, - "kssl_full_handshakes", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->resumed_sessions, - "kssl_resumed_sessions", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->fallback_connections, - "kssl_fallback_connections", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->proxy_fallback_failed, - "kssl_proxy_fallback_failed", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->appdata_record_ins, - "kssl_appdata_record_ins", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->appdata_record_outs, - "kssl_appdata_record_outs", KSTAT_DATA_UINT64); - - kstat_named_init(&kssl_statp->alloc_fails, "kssl_alloc_fails", - KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->fatal_alerts, - "kssl_fatal_alerts", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->warning_alerts, - "kssl_warning_alerts", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->no_suite_found, - "kssl_no_suite_found", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->compute_mac_failure, - "kssl_compute_mac_failure", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->verify_mac_failure, - "kssl_verify_mac_failure", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->record_decrypt_failure, - "kssl_record_decrypt_failure", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->bad_pre_master_secret, - "kssl_bad_pre_master_secret", KSTAT_DATA_UINT64); - kstat_named_init(&kssl_statp->internal_errors, - "kssl_internal_errors", KSTAT_DATA_UINT64); - - kstat_install(kssl_ksp); - }; -} - -static void -kssl_global_fini(void) -{ - mutex_destroy(&kssl_tab_mutex); - - if (kssl_cache != NULL) { - kmem_cache_destroy(kssl_cache); - kssl_cache = NULL; - } - - if (kssl_ksp != NULL) { - kstat_delete(kssl_ksp); - kssl_ksp = NULL; - } -} - -/*ARGSUSED*/ -static int -kssl_constructor(void *buf, void *arg, int kmflags) -{ - ssl_t *ssl = buf; - - mutex_init(&ssl->kssl_lock, NULL, MUTEX_DEFAULT, NULL); - cv_init(&ssl->async_cv, NULL, CV_DEFAULT, NULL); - - return (0); -} - -/*ARGSUSED*/ -static void -kssl_destructor(void *buf, void *arg) -{ - ssl_t *ssl = buf; - mutex_destroy(&ssl->kssl_lock); - cv_destroy(&ssl->async_cv); -} - -/* - * Handler routine called by the crypto framework when a - * provider is unregistered or registered. We invalidate the - * private key handle if our provider is unregistered. We set - * a flag to reauthenticate if our provider came back. - */ -void -kssl_prov_evnt(uint32_t event, void *event_arg) -{ - int i, rv; - kssl_entry_t *ep; - kssl_session_info_t *s; - crypto_provider_t prov; - crypto_provider_ext_info_t info; - - if (event != CRYPTO_EVENT_PROVIDER_UNREGISTERED && - event != CRYPTO_EVENT_PROVIDER_REGISTERED) - return; - - prov = (crypto_provider_t)event_arg; - if (event == CRYPTO_EVENT_PROVIDER_REGISTERED) { - rv = crypto_get_provinfo(prov, &info); - if (rv != CRYPTO_SUCCESS) - return; - } - - mutex_enter(&kssl_tab_mutex); - - for (i = 0; i < kssl_entry_tab_size; i++) { - if ((ep = kssl_entry_tab[i]) == NULL) - continue; - - s = ep->ke_sessinfo; - DTRACE_PROBE1(kssl_entry_cycle, kssl_entry_t *, ep); - switch (event) { - case CRYPTO_EVENT_PROVIDER_UNREGISTERED: - if (s->is_valid_handle && s->prov == prov) { - s->is_valid_handle = B_FALSE; - crypto_release_provider(s->prov); - } - break; - - case CRYPTO_EVENT_PROVIDER_REGISTERED: - if (s->is_valid_handle) - break; - if (bcmp(s->toklabel, info.ei_label, - CRYPTO_EXT_SIZE_LABEL) == 0) { - s->do_reauth = B_TRUE; - } - break; - } - } - - mutex_exit(&kssl_tab_mutex); -} diff --git a/usr/src/uts/common/inet/kssl/kssl.conf b/usr/src/uts/common/inet/kssl/kssl.conf deleted file mode 100644 index 4de42d8cb3..0000000000 --- a/usr/src/uts/common/inet/kssl/kssl.conf +++ /dev/null @@ -1,29 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -name="kssl" parent="pseudo" instance=0; -ddi-forceattach=1; diff --git a/usr/src/uts/common/inet/kssl/kssl.h b/usr/src/uts/common/inet/kssl/kssl.h deleted file mode 100644 index 50e592fee7..0000000000 --- a/usr/src/uts/common/inet/kssl/kssl.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _INET_KSSL_KSSL_H -#define _INET_KSSL_KSSL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <netinet/in.h> -#include <sys/crypto/common.h> - -/* These are re-definition from <crypto/ioctl.h> */ -typedef struct kssl_object_attribute { - uint64_t ka_type; /* attribute type */ - uint32_t ka_value_offset; /* offset to attribute value */ - uint32_t ka_value_len; /* length of attribute value */ -} kssl_object_attribute_t; - -typedef struct kssl_key { - crypto_key_format_t ks_format; /* format identifier */ - uint32_t ks_count; /* number of attributes */ - uint32_t ks_attrs_offset; /* offset to the attributes */ -} kssl_key_t; - -typedef struct kssl_certs_s { - uint32_t sc_count; /* number of certificates */ - uint32_t sc_sizes_offset; /* offset to certificates sizes array */ - uint32_t sc_certs_offset; /* offset to certificates array */ -} kssl_certs_t; - -#define MAX_PIN_LENGTH 1024 - -typedef struct kssl_tokinfo_s { - uint8_t toklabel[CRYPTO_EXT_SIZE_LABEL]; - uint32_t pinlen; - uint32_t tokpin_offset; /* offset to the pin */ - uint32_t ck_rv; /* PKCS #11 specific error */ -} kssl_tokinfo_t; - -/* Code point for Signalling Cipher Suite Value (SCSV) */ -#define SSL_SCSV 0x00ff - -/* Cipher suites */ -#define SSL_RSA_WITH_NULL_SHA 0x0002 -#define SSL_RSA_WITH_RC4_128_MD5 0x0004 -#define SSL_RSA_WITH_RC4_128_SHA 0x0005 -#define SSL_RSA_WITH_DES_CBC_SHA 0x0009 -#define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000a -#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f -#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 -/* total number of cipher suites supported */ -#define CIPHER_SUITE_COUNT 7 -#define CIPHER_NOTSET 0xffff - -/* TLS extension types */ -#define TLSEXT_RENEGOTIATION_INFO 0xff01 - -#define DEFAULT_SID_TIMEOUT 86400 /* 24 hours in seconds */ -#define DEFAULT_SID_CACHE_NENTRIES 5000 - -typedef struct kssl_params_s { - uint64_t kssl_params_size; /* total params buf len */ - /* address and port number */ - struct sockaddr_in6 kssl_addr; - uint16_t kssl_proxy_port; - - uint32_t kssl_session_cache_timeout; /* In seconds */ - uint32_t kssl_session_cache_size; - - /* - * Contains ordered list of cipher suites. We do not include - * the one suite with no encryption. Hence the -1. - */ - uint16_t kssl_suites[CIPHER_SUITE_COUNT - 1]; - - uint8_t kssl_is_nxkey; - kssl_tokinfo_t kssl_token; - - /* certificates */ - kssl_certs_t kssl_certs; - - /* private key */ - kssl_key_t kssl_privkey; -} kssl_params_t; - -/* The ioctls to /dev/kssl */ -#define KSSL_IOC(x) (('s' << 24) | ('s' << 16) | ('l' << 8) | (x)) -#define KSSL_ADD_ENTRY KSSL_IOC(1) -#define KSSL_DELETE_ENTRY KSSL_IOC(2) - -#ifdef _KERNEL - -extern int kssl_add_entry(kssl_params_t *); -extern int kssl_delete_entry(struct sockaddr_in6 *); - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_KSSL_KSSL_H */ diff --git a/usr/src/uts/common/inet/kssl/ksslapi.c b/usr/src/uts/common/inet/kssl/ksslapi.c deleted file mode 100644 index 8311794a5a..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslapi.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <sys/types.h> -#include <sys/stream.h> -#include <sys/strsun.h> -#include <sys/kmem.h> -#include <sys/cpuvar.h> -#include <sys/atomic.h> -#include <sys/sysmacros.h> - -#include <inet/common.h> -#include <inet/ip.h> - -#include <sys/systm.h> -#include <sys/param.h> -#include <sys/tihdr.h> - -#include "ksslimpl.h" -#include "ksslproto.h" -#include "ksslapi.h" - -static kssl_cmd_t kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp, - mblk_t **decrmp, kssl_callback_t cbfn, void *arg); -static boolean_t kssl_enqueue(kssl_chain_t **head, void *item); -static void kssl_dequeue(kssl_chain_t **head, void *item); -static kssl_status_t kssl_build_single_record(ssl_t *ssl, mblk_t *mp); - -/* - * The socket bind request is intercepted and re-routed here - * to see is there is SSL relevant job to do, based on the kssl config - * in the kssl_entry_tab. - * Looks up the kernel SSL proxy table, to find an entry that matches the - * same serveraddr, and has one of the following two criteria: - * 1. in_port is an ssl_port. This endpoint can be used later as a fallback - * to complete connections that cannot be handled by the SSL kernel proxy - * (typically non supported ciphersuite). The cookie for the calling client - * is saved with the kssl_entry to be retrieved for the fallback. - * The function returns KSSL_HAS_PROXY. - * - * 2. in_port is a proxy port for another ssl port. The ssl port is then - * substituted to the in_port in the bind_req TPI structure, so that - * the bind falls through to the SSL port. At the end of this operation, - * all the packets arriving to the SSL port will be delivered to an - * accepted endpoint child of this bound socket. - * The kssl_entry_t is returned in *ksslent, for later use by the - * lower modules' SSL hooks that handle the Handshake messages. - * The function returns KSSL_IS_PROXY. - * - * The function returns KSSL_NO_PROXY otherwise. - */ - -kssl_endpt_type_t -kssl_check_proxy(struct sockaddr *addr, socklen_t len, void *cookie, - kssl_ent_t *ksslent) -{ - int i; - kssl_endpt_type_t ret; - kssl_entry_t *ep; - sin_t *sin; - sin6_t *sin6; - in6_addr_t mapped_v4addr; - in6_addr_t *v6addr; - in_port_t in_port; - - if (kssl_entry_tab_nentries == 0) { - return (KSSL_NO_PROXY); - } - - ret = KSSL_NO_PROXY; - sin = (struct sockaddr_in *)addr; - - switch (len) { - case sizeof (sin_t): - in_port = ntohs(sin->sin_port); - IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &mapped_v4addr); - v6addr = &mapped_v4addr; - break; - - case sizeof (sin6_t): - sin6 = (sin6_t *)sin; - in_port = ntohs(sin6->sin6_port); - v6addr = &sin6->sin6_addr; - break; - - default: - return (ret); - } - - mutex_enter(&kssl_tab_mutex); - - for (i = 0; i < kssl_entry_tab_size; i++) { - if ((ep = kssl_entry_tab[i]) == NULL) - continue; - - if (IN6_ARE_ADDR_EQUAL(&ep->ke_laddr, v6addr) || - IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)) { - - /* This is an SSL port to fallback to */ - if (ep->ke_ssl_port == in_port) { - - /* - * Let's see first if there's at least - * an endpoint for a proxy server. - * If there's none, then we return as we have - * no proxy, so that the bind() to the - * transport layer goes through. - * The calling module will ask for this - * cookie if it wants to fall back to it, - * so add this one to the list of fallback - * clients. - */ - if (!kssl_enqueue((kssl_chain_t **) - &(ep->ke_fallback_head), cookie)) { - break; - } - - KSSL_ENTRY_REFHOLD(ep); - *ksslent = (kssl_ent_t)ep; - - ret = KSSL_HAS_PROXY; - break; - } - - /* This is a proxy port. */ - if (ep->ke_proxy_port == in_port) { - /* Add the caller's cookie to proxies list */ - - if (!kssl_enqueue((kssl_chain_t **) - &(ep->ke_proxy_head), cookie)) { - break; - } - - /* - * Make this look like the SSL port to the - * transport below - */ - sin->sin_port = htons(ep->ke_ssl_port); - - KSSL_ENTRY_REFHOLD(ep); - *ksslent = (kssl_ent_t)ep; - - ret = KSSL_IS_PROXY; - break; - } - } - } - - mutex_exit(&kssl_tab_mutex); - return (ret); -} - -/* - * Retrieved an endpoint "bound" to the SSL entry. - * Such endpoint has previously called kssl_check_proxy(), got itself - * linked to the kssl_entry's ke_fallback_head list. - * This routine returns the cookie from that SSL entry ke_fallback_head list. - */ -void * -kssl_find_fallback(kssl_ent_t ksslent) -{ - kssl_entry_t *kssl_entry = (kssl_entry_t *)ksslent; - - if (kssl_entry->ke_fallback_head != NULL) - return (kssl_entry->ke_fallback_head->fallback_bound); - - KSSL_COUNTER(proxy_fallback_failed, 1); - - return (NULL); -} - -/* - * Re-usable code for adding and removing an element to/from a chain that - * matches "item" - * The chain is simple-linked and NULL ended. - */ - -/* - * This routine returns TRUE if the item was either successfully added to - * the chain, or is already there. It returns FALSE otherwise. - */ -static boolean_t -kssl_enqueue(kssl_chain_t **head, void *item) -{ - kssl_chain_t *newchain, *cur; - - /* Lookup the existing entries to avoid duplicates */ - cur = *head; - while (cur != NULL) { - if (cur->item == item) { - return (B_TRUE); - } - cur = cur->next; - } - - newchain = kmem_alloc(sizeof (kssl_chain_t), KM_NOSLEEP); - if (newchain == NULL) { - return (B_FALSE); - } - - newchain->item = item; - newchain->next = *head; - *head = newchain; - return (B_TRUE); -} - -static void -kssl_dequeue(kssl_chain_t **head, void *item) -{ - kssl_chain_t *prev, *cur; - - prev = cur = *head; - while (cur != NULL) { - if (cur->item == item) { - if (cur == *head) - *head = (*head)->next; - else - prev->next = cur->next; - kmem_free(cur, sizeof (kssl_chain_t)); - return; - } - prev = cur; - cur = cur->next; - } -} - -/* - * Holds the kssl_entry - */ -void -kssl_hold_ent(kssl_ent_t ksslent) -{ - KSSL_ENTRY_REFHOLD((kssl_entry_t *)ksslent); -} - -/* - * Releases the kssl_entry - * If the caller passes a cookie, then it should be removed from both - * proxies and fallbacks chains. - */ -void -kssl_release_ent(kssl_ent_t ksslent, void *cookie, kssl_endpt_type_t endpt_type) -{ - kssl_entry_t *kssl_entry = (kssl_entry_t *)ksslent; - - if (cookie != NULL) { - if (endpt_type == KSSL_IS_PROXY) { - ASSERT(kssl_entry->ke_proxy_head != NULL); - kssl_dequeue( - (kssl_chain_t **)&kssl_entry->ke_proxy_head, - cookie); - } - if (endpt_type == KSSL_HAS_PROXY) { - ASSERT(kssl_entry->ke_fallback_head != NULL); - kssl_dequeue( - (kssl_chain_t **)&kssl_entry->ke_fallback_head, - cookie); - } - } - KSSL_ENTRY_REFRELE(kssl_entry); -} - -/* - * Releases the kssl_context - */ -void -kssl_release_ctx(kssl_ctx_t ksslctx) -{ - kssl_free_context((ssl_t *)ksslctx); -} - -/* - * Done with asynchronous processing - */ -void -kssl_async_done(kssl_ctx_t ksslctx) -{ - ssl_t *ssl = (ssl_t *)ksslctx; - - mutex_enter(&ssl->kssl_lock); - if (--ssl->async_ops_pending == 0) - cv_signal(&ssl->async_cv); - mutex_exit(&ssl->kssl_lock); -} - -/* - * Packets are accumulated here, if there are packets already queued, - * or if the context is active. - * The context is active when an incoming record processing function - * is already executing on a different thread. - * Queued packets are handled either when an mblk arrived and completes - * a record, or, when the active context processor finishes the task at - * hand. - * The caller has to keep calling this routine in a loop until it returns - * B_FALSE in *more. The reason for this is SSL3: The protocol - * allows the client to send its first application_data message right - * after it had sent its Finished message, and not wait for the server - * ChangeCipherSpec and Finished. This overlap means we can't batch up - * a returned Handshake message to be sent on the wire - * with a decrypted application_data to be delivered to the application. - */ -kssl_cmd_t -kssl_input(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp, boolean_t *more, - kssl_callback_t cbfn, void *arg) -{ - mblk_t *recmp, *outmp = NULL; - kssl_cmd_t kssl_cmd; - ssl_t *ssl; - uint8_t *rec_sz_p; - int mplen; - SSL3ContentType content_type; - uint16_t rec_sz; - - ASSERT(ctx != NULL); - - if (mp != NULL) { - ASSERT(mp->b_prev == NULL && mp->b_next == NULL); - } - - ssl = (ssl_t *)(ctx); - - *decrmp = NULL; - *more = B_FALSE; - - mutex_enter(&ssl->kssl_lock); - - if (ssl->close_notify_clnt == B_TRUE) { - DTRACE_PROBE(kssl_err__close_notify); - goto sendnewalert; - } - - /* Whomever is currently processing this connection will get to this */ - if (ssl->activeinput) { - if (mp != NULL) { - KSSL_ENQUEUE_MP(ssl, mp); - } - mutex_exit(&ssl->kssl_lock); - return (KSSL_CMD_NONE); - } - - /* - * Fast path for complete incoming application_data records on an empty - * queue. - * This is by far the most frequently encountered case - */ - - if ((!ssl->activeinput) && (ssl->rec_ass_head == NULL) && - ((mp != NULL) && (mplen = MBLKL(mp)) > SSL3_HDR_LEN)) { - - DTRACE_PROBE1(kssl_mblk__fast_path, mblk_t *, mp); - content_type = (SSL3ContentType)mp->b_rptr[0]; - - if ((content_type == content_application_data) && - (ssl->hs_waitstate == idle_handshake)) { - rec_sz_p = SSL3_REC_SIZE(mp); - rec_sz = BE16_TO_U16(rec_sz_p); - - if ((mp->b_cont == NULL) && (mplen == rec_sz)) { - - *decrmp = mp; - mutex_exit(&ssl->kssl_lock); - return (KSSL_CMD_DELIVER_PROXY); - } - } - } - - ssl->activeinput = B_TRUE; - /* Accumulate at least one record */ - if (mp != NULL) { - KSSL_ENQUEUE_MP(ssl, mp); - mp = NULL; - } - recmp = kssl_get_next_record(ssl); - - if (recmp == NULL) { - ssl->activeinput = B_FALSE; - if (ssl->alert_sendbuf != NULL) { - DTRACE_PROBE(kssl_err__alert_to_send); - goto sendalert; - } - /* Not even a complete header yet. wait for the rest */ - mutex_exit(&ssl->kssl_lock); - return (KSSL_CMD_NONE); - } - - do { - DTRACE_PROBE1(kssl_mblk__kssl_input_cycle, mblk_t *, recmp); - content_type = (SSL3ContentType)recmp->b_rptr[0]; - - switch (content_type) { - case content_application_data: - /* - * application_data records are decrypted and - * MAC-verified by the stream head, and in the context - * a read()'ing thread. This avoids unfairly charging - * the cost of handling this record on the whole system, - * and prevents doing it while in the shared IP - * perimeter. - */ - ssl->activeinput = B_FALSE; - if (ssl->hs_waitstate != idle_handshake) { - DTRACE_PROBE(kssl_err__waitstate_not_idle); - goto sendnewalert; - } - outmp = recmp; - kssl_cmd = KSSL_CMD_DELIVER_PROXY; - break; - case content_change_cipher_spec: - case content_alert: - case content_handshake: - case content_handshake_v2: - /* - * If we're past the initial handshake, start letting - * the stream head process all records, in particular - * the close_notify. - * This is needed to avoid processing them out of - * sequence when previous application data packets are - * waiting to be decrypted/MAC'ed and delivered. - */ - if (ssl->hs_waitstate == idle_handshake) { - ssl->activeinput = B_FALSE; - outmp = recmp; - kssl_cmd = KSSL_CMD_DELIVER_PROXY; - } else { - kssl_cmd = kssl_handle_any_record(ssl, recmp, - &outmp, cbfn, arg); - } - break; - default: - ssl->activeinput = B_FALSE; - DTRACE_PROBE(kssl_err__invalid_content_type); - goto sendnewalert; - } - - /* Priority to Alert messages */ - if (ssl->alert_sendbuf != NULL) { - DTRACE_PROBE(kssl_err__alert_to_send_cycle); - goto sendalert; - } - - /* Then handshake messages */ - if (ssl->handshake_sendbuf) { - if (*decrmp != NULL) { - linkb(*decrmp, ssl->handshake_sendbuf); - } else { - *decrmp = ssl->handshake_sendbuf; - } - ssl->handshake_sendbuf = NULL; - - *more = ((ssl->rec_ass_head != NULL) && - (!ssl->activeinput)); - mutex_exit(&ssl->kssl_lock); - return (kssl_cmd); - } - - if (ssl->hs_waitstate == idle_handshake) { - *more = ((ssl->rec_ass_head != NULL) && - (!ssl->activeinput)); - } - - if (outmp != NULL) { - *decrmp = outmp; - /* - * Don't process any packet after an application_data. - * We could well receive the close_notify which should - * be handled separately. - */ - mutex_exit(&ssl->kssl_lock); - return (kssl_cmd); - } - /* - * The current record isn't done yet. Don't start the next one - */ - if (ssl->activeinput) { - mutex_exit(&ssl->kssl_lock); - return (kssl_cmd); - } - } while ((recmp = kssl_get_next_record(ssl)) != NULL); - - mutex_exit(&ssl->kssl_lock); - return (kssl_cmd); - -sendnewalert: - kssl_send_alert(ssl, alert_fatal, unexpected_message); - if (mp != NULL) { - freeb(mp); - } - -sendalert: - *decrmp = ssl->alert_sendbuf; - ssl->alert_sendbuf = NULL; - mutex_exit(&ssl->kssl_lock); - return (KSSL_CMD_SEND); -} - -/* - * Decrypt and verify the MAC of an incoming chain of application_data record. - * Each block has exactly one SSL record. - */ -kssl_cmd_t -kssl_handle_mblk(kssl_ctx_t ctx, mblk_t **mpp, mblk_t **outmp) -{ - uchar_t *recend, *rec_sz_p; - uchar_t *real_recend; - mblk_t *prevmp = NULL, *nextmp, *firstmp, *mp, *copybp; - int mac_sz; - uchar_t version[2]; - uint16_t rec_sz; - SSL3AlertDescription desc; - SSL3ContentType content_type; - ssl_t *ssl; - KSSLCipherSpec *spec; - int error, ret; - kssl_cmd_t kssl_cmd = KSSL_CMD_DELIVER_PROXY; - boolean_t deliverit = B_FALSE; - crypto_data_t cipher_data; - - ASSERT(ctx != NULL); - - ssl = (ssl_t *)(ctx); - - mp = firstmp = *mpp; - *outmp = NULL; -more: - - while (mp != NULL) { - ASSERT(DB_TYPE(mp) == M_DATA); - - if (DB_REF(mp) > 1) { - /* - * Fortunately copyb() preserves the offset, - * tail space and alignment so the copy is - * ready to be made an SSL record. - */ - if ((copybp = copyb(mp)) == NULL) - return (KSSL_CMD_NOT_SUPPORTED); - - copybp->b_cont = mp->b_cont; - if (mp == firstmp) { - *mpp = copybp; - } else if (prevmp != NULL) { - prevmp->b_cont = copybp; - } - freeb(mp); - mp = copybp; - } - - DTRACE_PROBE1(kssl_mblk__handle_record_cycle, mblk_t *, mp); - content_type = (SSL3ContentType)mp->b_rptr[0]; - - switch (content_type) { - case content_application_data: - break; - case content_change_cipher_spec: - case content_alert: - case content_handshake: - case content_handshake_v2: - nextmp = mp->b_cont; - - /* Remove this message */ - if (prevmp != NULL) { - prevmp->b_cont = nextmp; - - /* - * If we had processed blocks that need to - * be delivered, then remember that error code - */ - if (kssl_cmd == KSSL_CMD_DELIVER_PROXY) - deliverit = B_TRUE; - } - - mutex_enter(&ssl->kssl_lock); - /* NOTE: This routine could free mp. */ - kssl_cmd = kssl_handle_any_record(ssl, mp, outmp, - NULL, NULL); - - if (ssl->alert_sendbuf != NULL) { - mp = nextmp; - DTRACE_PROBE(kssl_err__alert_after_handle_any); - goto sendalert; - } - mutex_exit(&ssl->kssl_lock); - - if (deliverit) { - kssl_cmd = KSSL_CMD_DELIVER_PROXY; - } - - mp = nextmp; - continue; /* to the while loop */ - default: - desc = decode_error; - KSSL_COUNTER(internal_errors, 1); - DTRACE_PROBE(kssl_err__decode_error); - goto makealert; - } - - version[0] = mp->b_rptr[1]; - version[1] = mp->b_rptr[2]; - rec_sz_p = SSL3_REC_SIZE(mp); - rec_sz = BE16_TO_U16(rec_sz_p); - - mp->b_rptr += SSL3_HDR_LEN; - recend = mp->b_rptr + rec_sz; - real_recend = recend; - - /* - * Check the assumption that each mblk contains exactly - * one complete SSL record. We bail out if the check fails. - */ - ASSERT(recend == mp->b_wptr); - if (recend != mp->b_wptr) { - desc = decode_error; - KSSL_COUNTER(internal_errors, 1); - DTRACE_PROBE(kssl_err__not_complete_record); - goto makealert; - } - - spec = &ssl->spec[KSSL_READ]; - mac_sz = spec->mac_hashsz; - if (spec->cipher_ctx != 0) { - - /* - * The record length must be a multiple of the - * block size for block ciphers. - * The cipher_bsize is always a power of 2. - */ - if ((spec->cipher_type == type_block) && - ((rec_sz & (spec->cipher_bsize - 1)) != 0)) { - DTRACE_PROBE2(kssl_err__bad_record_size, - uint16_t, rec_sz, - int, spec->cipher_bsize); - KSSL_COUNTER(record_decrypt_failure, 1); - mp->b_rptr = recend; - desc = decrypt_error; - goto makealert; - } - - cipher_data.cd_format = CRYPTO_DATA_RAW; - cipher_data.cd_offset = 0; - cipher_data.cd_length = rec_sz; - cipher_data.cd_miscdata = NULL; - cipher_data.cd_raw.iov_base = (char *)mp->b_rptr; - cipher_data.cd_raw.iov_len = rec_sz; - error = crypto_decrypt_update(spec->cipher_ctx, - &cipher_data, NULL, NULL); - if (CRYPTO_ERR(error)) { - DTRACE_PROBE1( - kssl_err__crypto_decrypt_update_failed, - int, error); - KSSL_COUNTER(record_decrypt_failure, 1); - mp->b_rptr = recend; - desc = decrypt_error; - goto makealert; - } - } - if (spec->cipher_type == type_block) { - uint_t pad_sz = recend[-1]; - pad_sz++; - if (pad_sz + mac_sz > rec_sz) { - DTRACE_PROBE(kssl_err__pad_mac_bigger); - mp->b_rptr = recend; - desc = bad_record_mac; - goto makealert; - } - rec_sz -= pad_sz; - recend -= pad_sz; - } - if (mac_sz != 0) { - uchar_t hash[MAX_HASH_LEN]; - if (rec_sz < mac_sz) { - DTRACE_PROBE(kssl_err__pad_smaller_mac); - mp->b_rptr = real_recend; - desc = bad_record_mac; - goto makealert; - } - rec_sz -= mac_sz; - recend -= mac_sz; - ret = kssl_compute_record_mac(ssl, KSSL_READ, - ssl->seq_num[KSSL_READ], content_type, - version, mp->b_rptr, rec_sz, hash); - if (ret != CRYPTO_SUCCESS || - bcmp(hash, recend, mac_sz)) { - DTRACE_PROBE1(kssl_mblk__MACmismatch_handlerec, - mblk_t *, mp); - mp->b_rptr = real_recend; - desc = bad_record_mac; - DTRACE_PROBE(kssl_err__msg_MAC_mismatch); - KSSL_COUNTER(verify_mac_failure, 1); - goto makealert; - } - ssl->seq_num[KSSL_READ]++; - } - - if (ssl->hs_waitstate != idle_handshake) { - DTRACE_PROBE1(kssl_err__unexpected_msg, - SSL3WaitState, ssl->hs_waitstate); - mp->b_rptr = real_recend; - desc = unexpected_message; - goto makealert; - } - mp->b_wptr = recend; - - DTRACE_PROBE1(kssl_mblk__dblk_cooked, mblk_t *, mp); - KSSL_COUNTER(appdata_record_ins, 1); - - prevmp = mp; - mp = mp->b_cont; - } - - return (kssl_cmd); - -makealert: - nextmp = mp->b_cont; - freeb(mp); - mp = nextmp; - mutex_enter(&ssl->kssl_lock); - kssl_send_alert(ssl, alert_fatal, desc); - - if (ssl->alert_sendbuf == NULL) { - /* internal memory allocation failure. just return. */ - DTRACE_PROBE(kssl_err__alert_msg_alloc_failed); - mutex_exit(&ssl->kssl_lock); - - if (mp) { - prevmp = NULL; - goto more; - } - - return (KSSL_CMD_NONE); - } - kssl_cmd = KSSL_CMD_SEND; -sendalert: - if (*outmp == NULL) { - *outmp = ssl->alert_sendbuf; - } else { - linkb(*outmp, ssl->alert_sendbuf); - } - ssl->alert_sendbuf = NULL; - mutex_exit(&ssl->kssl_lock); - - if (mp) { - prevmp = NULL; - goto more; - } - - return (kssl_cmd); -} -/* - * This is the routine that handles incoming SSL records. - * When called the first time, with a NULL context, this routine expects - * a ClientHello SSL Handshake packet and shall allocate a context - * of a new SSL connection. - * During the rest of the handshake packets, the routine adjusts the - * state of the context according to the record received. - * After the ChangeCipherSpec message is received, the routine first - * decrypts/authenticated the packet using the key materials in the - * connection's context. - * The return code tells the caller what to do with the returned packet. - */ -static kssl_cmd_t -kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp, - kssl_callback_t cbfn, void *arg) -{ - uchar_t *recend, *rec_sz_p; - uchar_t version[2]; - uchar_t *real_recend, *save_rptr, *save_wptr; - int rhsz = SSL3_HDR_LEN; - uint16_t rec_sz; - int sz; - int mac_sz; - SSL3AlertDescription desc; - SSL3AlertLevel level; - SSL3ContentType content_type; - ssl_t *ssl; - KSSLCipherSpec *spec; - int error = 0, ret; - - ASSERT(ctx != NULL); - - ssl = (ssl_t *)(ctx); - - *decrmp = NULL; - - save_rptr = mp->b_rptr; - save_wptr = mp->b_wptr; - - ASSERT(MUTEX_HELD(&ssl->kssl_lock)); - - content_type = (SSL3ContentType)mp->b_rptr[0]; - if (content_type == content_handshake_v2) { - if (ssl->hs_waitstate == wait_client_hello) { - /* V2 compatible ClientHello */ - if (mp->b_rptr[3] == 0x03 && - (mp->b_rptr[4] == 0x01 || - mp->b_rptr[4] == 0x00)) { - ssl->major_version = version[0] = mp->b_rptr[3]; - ssl->minor_version = version[1] = mp->b_rptr[4]; - } else { - /* We don't support "pure" SSLv2 */ - DTRACE_PROBE(kssl_err__no_SSLv2); - ssl->major_version = mp->b_rptr[3]; - ssl->minor_version = mp->b_rptr[4]; - desc = protocol_version; - goto sendalert; - } - } - rec_sz = (uint16_t)mp->b_rptr[1]; - rhsz = 2; - } else { - ssl->major_version = version[0] = mp->b_rptr[1]; - ssl->minor_version = version[1] = mp->b_rptr[2]; - rec_sz_p = SSL3_REC_SIZE(mp); - rec_sz = BE16_TO_U16(rec_sz_p); - } - - mp->b_rptr += rhsz; - recend = mp->b_rptr + rec_sz; - real_recend = recend; - - /* - * Check the assumption that each mblk contains exactly - * one complete SSL record. We bail out if the check fails. - */ - ASSERT(recend == mp->b_wptr); - if (recend != mp->b_wptr) { - DTRACE_PROBE3(kssl_mblk__handle_any_record_recszerr, - mblk_t *, mp, int, rhsz, int, rec_sz); - DTRACE_PROBE(kssl_err__record_size); - desc = decode_error; - KSSL_COUNTER(internal_errors, 1); - goto sendalert; - } - - spec = &ssl->spec[KSSL_READ]; - mac_sz = spec->mac_hashsz; - if (spec->cipher_ctx != 0) { - /* - * The record length must be a multiple of the - * block size for block ciphers. - */ - if ((spec->cipher_type == type_block) && - ((rec_sz & (spec->cipher_bsize - 1)) != 0)) { - DTRACE_PROBE2(kssl_err__bad_record_size, - uint16_t, rec_sz, int, spec->cipher_bsize); - KSSL_COUNTER(record_decrypt_failure, 1); - mp->b_rptr = recend; - desc = decrypt_error; - goto sendalert; - } - - spec->cipher_data.cd_length = rec_sz; - spec->cipher_data.cd_raw.iov_base = (char *)mp->b_rptr; - spec->cipher_data.cd_raw.iov_len = rec_sz; - error = crypto_decrypt_update(spec->cipher_ctx, - &spec->cipher_data, NULL, NULL); - if (CRYPTO_ERR(error)) { - DTRACE_PROBE1(kssl_err__crypto_decrypt_update_failed, - int, error); - KSSL_COUNTER(record_decrypt_failure, 1); - mp->b_rptr = recend; - desc = decrypt_error; - goto sendalert; - } - } - if (spec->cipher_type == type_block) { - uint_t pad_sz = recend[-1]; - pad_sz++; - if (pad_sz + mac_sz > rec_sz) { - DTRACE_PROBE2(kssl_err__pad_mac_mismatch, - int, pad_sz, int, mac_sz); - mp->b_rptr = recend; - desc = bad_record_mac; - goto sendalert; - } - rec_sz -= pad_sz; - recend -= pad_sz; - } - if (mac_sz != 0) { - uchar_t hash[MAX_HASH_LEN]; - if (rec_sz < mac_sz) { - DTRACE_PROBE1(kssl_err__mac_size_too_big, - int, mac_sz); - mp->b_rptr = real_recend; - desc = bad_record_mac; - goto sendalert; - } - rec_sz -= mac_sz; - recend -= mac_sz; - ret = kssl_compute_record_mac(ssl, KSSL_READ, - ssl->seq_num[KSSL_READ], content_type, - version, mp->b_rptr, rec_sz, hash); - if (ret != CRYPTO_SUCCESS || - bcmp(hash, recend, mac_sz)) { - DTRACE_PROBE1(kssl_mblk__MACmismatch_anyrecord, - mblk_t *, mp); - mp->b_rptr = real_recend; - desc = bad_record_mac; - DTRACE_PROBE(kssl_err__msg_MAC_mismatch); - KSSL_COUNTER(verify_mac_failure, 1); - goto sendalert; - } - ssl->seq_num[KSSL_READ]++; - DTRACE_PROBE1(kssl_mblk__after_compute_MAC, - mblk_t *, mp); - } - - switch (content_type) { - case content_handshake: - do { - DTRACE_PROBE1(kssl_mblk__content_handshake_cycle, - mblk_t *, mp); - if (error != 0 || - /* ignore client renegotiation for now */ - ssl->hs_waitstate == idle_handshake) { - mp->b_rptr = recend; - DTRACE_PROBE(kssl_renegotiation_request); - } - if (mp->b_rptr == recend) { - mp->b_rptr = real_recend; - if (error != 0) { - goto error; - } - freeb(mp); - - if (ssl->hs_waitstate == wait_client_key_done) - return (KSSL_CMD_QUEUED); - - return ((ssl->handshake_sendbuf != NULL) ? - KSSL_CMD_SEND : KSSL_CMD_NONE); - } - if (ssl->msg.state < MSG_BODY) { - if (ssl->msg.state == MSG_INIT) { - ssl->msg.type = - (SSL3HandshakeType)*mp->b_rptr++; - ssl->msg.state = MSG_INIT_LEN; - } - if (ssl->msg.state == MSG_INIT_LEN) { - int msglenb = - ssl->msg.msglen_bytes; - int msglen = ssl->msg.msglen; - while (mp->b_rptr < recend && - msglenb < 3) { - msglen = (msglen << 8) + - (uint_t)(*mp->b_rptr++); - msglenb++; - } - ssl->msg.msglen_bytes = msglenb; - ssl->msg.msglen = msglen; - if (msglenb == 3) { - ssl->msg.state = MSG_BODY; - } - } - if (mp->b_rptr == recend) { - mp->b_rptr = real_recend; - freeb(mp); - return (KSSL_CMD_NONE); - } - } - ASSERT(ssl->msg.state == MSG_BODY); - - sz = recend - mp->b_rptr; - - if (ssl->msg.head == NULL && - ssl->msg.msglen <= sz) { - continue; - } - if (ssl->msg.head != NULL) { - sz += msgdsize(ssl->msg.head); - if (ssl->msg.msglen <= sz) { - ssl->msg.tail->b_cont = mp; - mp = ssl->msg.head; - ssl->sslcnt = 100; - ssl->msg.head = NULL; - ssl->msg.tail = NULL; - if (pullupmsg(mp, -1)) { - recend = mp->b_rptr + sz; - ASSERT(recend <= mp->b_wptr); - continue; - } - mp->b_rptr = real_recend; - error = ENOMEM; - KSSL_COUNTER(alloc_fails, 1); - goto error; - } - } - - mp->b_wptr = recend; - - if (ssl->msg.head == NULL) { - ssl->msg.head = mp; - ssl->msg.tail = mp; - return (KSSL_CMD_NONE); - } else { - ssl->msg.tail->b_cont = mp; - ssl->msg.tail = mp; - return (KSSL_CMD_NONE); - } - } while (kssl_handle_handshake_message(ssl, mp, &error, cbfn, - arg)); - if (error == SSL_MISS) { - mp->b_rptr = save_rptr; - mp->b_wptr = save_wptr; - KSSL_COUNTER(fallback_connections, 1); - return (KSSL_CMD_NOT_SUPPORTED); - } - if (ssl->hs_waitstate == wait_client_key_done) { - return (KSSL_CMD_QUEUED); - } else { - return (KSSL_CMD_NONE); - } - case content_alert: - DTRACE_PROBE1(kssl_mblk__content_alert, mblk_t *, mp); - if (rec_sz != 2) { - DTRACE_PROBE(kssl_err__illegal_param); - mp->b_rptr = real_recend; - desc = illegal_parameter; - goto sendalert; - } else { - level = *mp->b_rptr++; - desc = *mp->b_rptr++; - mp->b_rptr = real_recend; - if (level != alert_warning || desc != close_notify) { - if (ssl->sid.cached == B_TRUE) { - kssl_uncache_sid(&ssl->sid, - ssl->kssl_entry); - } - DTRACE_PROBE2(kssl_err__bad_content_alert, - SSL3AlertLevel, level, - SSL3AlertDescription, desc); - ssl->fatal_alert = B_TRUE; - error = EBADMSG; - goto error; - } else { - ssl->close_notify_clnt = B_TRUE; - ssl->activeinput = B_FALSE; - freeb(mp); - return (KSSL_CMD_NONE); - } - } - case content_change_cipher_spec: - DTRACE_PROBE1(kssl_mblk__change_cipher_spec, - mblk_t *, mp); - if (ssl->hs_waitstate != wait_change_cipher) { - desc = unexpected_message; - } else if (rec_sz != 1 || *mp->b_rptr != 1) { - desc = illegal_parameter; - } else { - mp->b_rptr = real_recend; - ssl->hs_waitstate = wait_finished; - ssl->seq_num[KSSL_READ] = 0; - if ((error = kssl_spec_init(ssl, KSSL_READ)) != 0) { - DTRACE_PROBE1(kssl_err__kssl_spec_init_error, - int, error); - goto error; - } - ssl->activeinput = B_FALSE; - freeb(mp); - return (KSSL_CMD_NONE); - } - mp->b_rptr = real_recend; - DTRACE_PROBE(kssl_err__change_cipher_spec); - goto sendalert; - - case content_application_data: - DTRACE_PROBE1(kssl_mblk__content_app_data, - mblk_t *, mp); - if (ssl->hs_waitstate != idle_handshake) { - DTRACE_PROBE(kssl_err__content_app_data); - mp->b_rptr = real_recend; - desc = unexpected_message; - goto sendalert; - } - mp->b_wptr = recend; - *decrmp = mp; - ssl->activeinput = B_FALSE; - return (KSSL_CMD_DELIVER_PROXY); - - case content_handshake_v2: - DTRACE_PROBE1(kssl_mblk__content_handshake_v2, - mblk_t *, mp); - error = kssl_handle_v2client_hello(ssl, mp, rec_sz); - if (error == SSL_MISS) { - mp->b_rptr = save_rptr; - mp->b_wptr = save_wptr; - KSSL_COUNTER(fallback_connections, 1); - return (KSSL_CMD_NOT_SUPPORTED); - } else if (error != 0) { - DTRACE_PROBE(kssl_err__v2client_hello_failed); - goto error; - } - freeb(mp); - return (KSSL_CMD_SEND); - default: - DTRACE_PROBE1(kssl_mblk__unexpected_msg, - mblk_t *, mp); - mp->b_rptr = real_recend; - desc = unexpected_message; - break; - } - -sendalert: - kssl_send_alert(ssl, alert_fatal, desc); - *decrmp = ssl->alert_sendbuf; - ssl->alert_sendbuf = NULL; - freeb(mp); - return ((*decrmp != NULL) ? KSSL_CMD_SEND : KSSL_CMD_NONE); -error: - freeb(mp); - return (KSSL_CMD_NONE); -} - -/* - * Initialize the context of an SSL connection, coming to the specified - * address. The ssl structure is returned held. - */ -kssl_status_t -kssl_init_context(kssl_ent_t kssl_ent, struct sockaddr *addr, int mss, - kssl_ctx_t *kssl_ctxp) -{ - ssl_t *ssl = kmem_cache_alloc(kssl_cache, KM_NOSLEEP); - struct sockaddr_in *sin = (struct sockaddr_in *)addr; - - if (ssl == NULL) { - return (KSSL_STS_ERR); - } - - bzero(ssl, sizeof (ssl_t)); - - ssl->kssl_entry = (kssl_entry_t *)kssl_ent; - KSSL_ENTRY_REFHOLD(ssl->kssl_entry); - - if (sin->sin_family == AF_INET) { - IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &ssl->faddr); - } else { - /* struct assignment */ - ssl->faddr = ((struct sockaddr_in6 *)addr)->sin6_addr; - } - ssl->tcp_mss = mss; - ssl->sendalert_level = alert_warning; - ssl->sendalert_desc = close_notify; - ssl->sid.cached = B_FALSE; - - *kssl_ctxp = (kssl_ctx_t)ssl; - return (KSSL_STS_OK); -} - -void -kssl_set_mss(kssl_ctx_t ctx, uint32_t mss) -{ - ssl_t *ssl = (ssl_t *)ctx; - ssl->tcp_mss = mss; -} - -/* - * Builds SSL records out of the chain of mblks, and returns it. - * Takes a copy of the message before encrypting it if it has another - * reference. - * In case of failure, NULL is returned, and the message will be - * freed by the caller. - * A NULL mp means a close_notify is requested. - */ -mblk_t * -kssl_build_record(kssl_ctx_t ctx, mblk_t *mp) -{ - ssl_t *ssl = (ssl_t *)ctx; - mblk_t *retmp = mp, *bp = mp, *prevbp = mp, *copybp; - - ASSERT(ssl != NULL); - - /* - * Produce new close_notify message. This is necessary to perform - * proper cleanup w.r.t. SSL protocol spec by sending close_notify SSL - * alert record if running with KSSL proxy. - * This should be done prior to sending the FIN so the client side can - * attempt to do graceful cleanup. Ideally, we should wait for client's - * close_notify but not all clients send it which would hang the - * connection. This way of closing the SSL session (Incomplete Close) - * prevents truncation attacks for protocols without end-of-data - * markers (as opposed to the Premature Close). - * Checking the close_notify_srvr flag will prevent from sending the - * close_notify message twice in case of duplicate shutdown() calls. - */ - if (mp == NULL && !ssl->close_notify_srvr) { - kssl_send_alert(ssl, alert_warning, close_notify); - if (ssl->alert_sendbuf == NULL) - return (NULL); - mp = bp = retmp = prevbp = ssl->alert_sendbuf; - ssl->alert_sendbuf = NULL; - ssl->close_notify_srvr = B_TRUE; - } - - ASSERT(mp != NULL); - ASSERT(bp != NULL); - - do { - if (DB_REF(bp) > 1) { - /* - * Fortunately copyb() preserves the offset, - * tail space and alignment so the copy is - * ready to be made an SSL record. - */ - if ((copybp = copyb(bp)) == NULL) - return (NULL); - - copybp->b_cont = bp->b_cont; - if (bp == mp) { - retmp = copybp; - } else { - prevbp->b_cont = copybp; - } - freeb(bp); - bp = copybp; - } - - if (kssl_build_single_record(ssl, bp) != KSSL_STS_OK) - return (NULL); - - prevbp = bp; - bp = bp->b_cont; - } while (bp != NULL); - - return (retmp); -} - -/* - * Builds a single SSL record by prepending SSL header (optional) and performing - * encryption and MAC. The encryption of the record is done in-line. - * Expects an mblk with associated dblk's base to have space for the SSL header - * or an mblk which already has the header present. In both cases it presumes - * that the mblk's dblk limit has space for the MAC + padding. - * If the close_notify_srvr flag is set it is presumed that the mblk already - * contains SSL header in which case only the record length field will be - * adjusted with the MAC/padding size. - */ -static kssl_status_t -kssl_build_single_record(ssl_t *ssl, mblk_t *mp) -{ - int len; - int reclen; - uchar_t *recstart, *versionp; - KSSLCipherSpec *spec; - int mac_sz; - int pad_sz; - - spec = &ssl->spec[KSSL_WRITE]; - mac_sz = spec->mac_hashsz; - - ASSERT(DB_REF(mp) == 1); - /* The dblk must always have space for the padding and MAC suffix. */ - ASSERT(mp->b_datap->db_lim - mp->b_wptr >= mac_sz + spec->cipher_bsize); - - /* kssl_send_alert() constructs the SSL header by itself. */ - if (!ssl->close_notify_srvr) - len = MBLKL(mp) - SSL3_HDR_LEN; - else - len = MBLKL(mp); - - ASSERT(len > 0); - - mutex_enter(&ssl->kssl_lock); - - recstart = mp->b_rptr; - if (!ssl->close_notify_srvr) { - /* The dblk must have space for the SSL header prefix. */ - ASSERT(mp->b_rptr - mp->b_datap->db_base >= SSL3_HDR_LEN); - recstart = mp->b_rptr = mp->b_rptr - SSL3_HDR_LEN; - recstart[0] = content_application_data; - recstart[1] = ssl->major_version; - recstart[2] = ssl->minor_version; - } - versionp = &recstart[1]; - - reclen = len + mac_sz; - if (spec->cipher_type == type_block) { - pad_sz = spec->cipher_bsize - - (reclen & (spec->cipher_bsize - 1)); - ASSERT(reclen + pad_sz <= - SSL3_MAX_RECORD_LENGTH); - reclen += pad_sz; - } - recstart[3] = (reclen >> 8) & 0xff; - recstart[4] = reclen & 0xff; - - if (kssl_mac_encrypt_record(ssl, recstart[0], versionp, - recstart, mp) != 0) { - /* Do we need an internal_error Alert here? */ - mutex_exit(&ssl->kssl_lock); - return (KSSL_STS_ERR); - } - - /* Alert messages are accounted in kssl_send_alert(). */ - if (recstart[0] == content_application_data) - KSSL_COUNTER(appdata_record_outs, 1); - mutex_exit(&ssl->kssl_lock); - return (KSSL_STS_OK); -} diff --git a/usr/src/uts/common/inet/kssl/ksslapi.h b/usr/src/uts/common/inet/kssl/ksslapi.h deleted file mode 100644 index 640e3f53de..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslapi.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _INET_KSSL_KSSLAPI_H -#define _INET_KSSL_KSSLAPI_H - -/* - * The kernel SSL proxy interface - */ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/socket.h> -#include <netinet/in.h> - -/* return status for the kssl API functions */ - -typedef enum { - KSSL_STS_OK, /* No further processing required */ - KSSL_STS_ERR /* bogus argument ... */ -} kssl_status_t; - -/* Endpoint type */ -typedef enum { - KSSL_NO_PROXY = 0, /* Not configured for use with KSSL */ - KSSL_IS_PROXY, /* Acts as a proxy for someone else */ - KSSL_HAS_PROXY /* A proxy is handling its work */ -} kssl_endpt_type_t; - -/* Return codes/commands from kssl_handle_record */ -typedef enum { - KSSL_CMD_NOT_SUPPORTED, /* Not supported */ - KSSL_CMD_SEND, /* send this packet out on the wire */ - KSSL_CMD_DELIVER_PROXY, /* deliver this packet to proxy listener */ - KSSL_CMD_DELIVER_SSL, /* Deliver to the SSL listener */ - KSSL_CMD_NONE, /* consider it consumed. (ACK it, ... */ - KSSL_CMD_QUEUED /* Queued, a call back will finish it */ -} kssl_cmd_t; - -/* Un opaque context of an SSL connection */ -typedef void *kssl_ctx_t; - -/* Un opaque handle for an SSL map entry */ -typedef void *kssl_ent_t; - -#define SSL3_HDR_LEN 5 -#define SSL3_WROFFSET 7 /* 5 hdr + 2 byte-alignment */ -#define SSL3_MAX_TAIL_LEN 36 /* 16 AES blocks + 20 SHA1 digest */ -#define SSL3_MAX_RECORD_LEN 16384 - 1 - SSL3_HDR_LEN - SSL3_MAX_TAIL_LEN - - -kssl_endpt_type_t kssl_check_proxy(struct sockaddr *, socklen_t, void *, - kssl_ent_t *); - -kssl_status_t kssl_init_context(kssl_ent_t, struct sockaddr *, int, - kssl_ctx_t *); -void kssl_set_mss(kssl_ctx_t, uint32_t); - -void kssl_hold_ent(kssl_ent_t); -void kssl_release_ent(kssl_ent_t, void *, kssl_endpt_type_t); -void *kssl_find_fallback(kssl_ent_t); - -void kssl_release_ctx(kssl_ctx_t); -void kssl_async_done(kssl_ctx_t); - -typedef void (*kssl_callback_t)(void *arg, mblk_t *mp, kssl_cmd_t cmd); - -kssl_cmd_t kssl_input(kssl_ctx_t, mblk_t *, mblk_t **, boolean_t *, - kssl_callback_t cbfn, void *arg); - -kssl_cmd_t kssl_handle_mblk(kssl_ctx_t, mblk_t **, mblk_t **); - -mblk_t *kssl_build_record(kssl_ctx_t, mblk_t *); - - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_KSSL_KSSLAPI_H */ diff --git a/usr/src/uts/common/inet/kssl/ksslfilter.c b/usr/src/uts/common/inet/kssl/ksslfilter.c deleted file mode 100644 index ea9e2f9232..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslfilter.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <sys/systm.h> -#include <sys/cmn_err.h> -#include <sys/stropts.h> -#include <sys/strsun.h> -#include <sys/socketvar.h> -#include <sys/sockfilter.h> -#include <inet/kssl/ksslapi.h> -#include <sys/note.h> -#include <sys/taskq.h> - -/* - * Name of the KSSL filter - */ -#define KSSL_FILNAME "ksslf" - -static struct modlmisc ksslf_modlmisc = { - &mod_miscops, - "Kernel SSL socket filter" -}; - -static struct modlinkage ksslf_modlinkage = { - MODREV_1, - &ksslf_modlmisc, - NULL -}; - -/* - * kssl filter cookie - */ -typedef struct ksslf { - boolean_t ksslf_pending; /* waiting for 1st SSL rec. */ - boolean_t ksslf_inhandshake; /* during SSL handshake */ - kssl_ent_t ksslf_ent; /* SSL table entry */ - kssl_ctx_t ksslf_ctx; /* SSL session */ - kssl_endpt_type_t ksslf_type; /* is proxy/is proxied/none */ - struct sockaddr_in6 ksslf_laddr; /* local address */ - socklen_t ksslf_laddrlen; - struct ksslf *ksslf_listener; -} ksslf_t; - -static void kssl_input_callback(void *, mblk_t *, kssl_cmd_t); - -/* - * Allocate kssl state - */ -sof_rval_t -kssl_attach_passive_cb(sof_handle_t handle, sof_handle_t ph, - void *parg, struct sockaddr *laddr, socklen_t laddrlen, - struct sockaddr *faddr, socklen_t faddrlen, void **cookiep) -{ - ksslf_t *listener = (ksslf_t *)parg; - ksslf_t *new; - - _NOTE(ARGUNUSED(handle, ph, faddrlen, laddr, laddrlen)); - - if (listener == NULL || listener->ksslf_ent == NULL) - return (SOF_RVAL_DETACH); - /* - * Only way for a fallback listener to receive connections is when - * a handshake fails and socket is moved from the proxy to the fallback. - * Connections that come in directly on the fallback are denied. - */ - if (listener->ksslf_type == KSSL_HAS_PROXY) - return (SOF_RVAL_EACCES); - - /* Allocate the SSL context for the new connection */ - new = kmem_zalloc(sizeof (ksslf_t), KM_NOSLEEP); - if (new == NULL) - return (SOF_RVAL_ENOMEM); - - /* - * The mss is initialized to SSL3_MAX_RECORD_LEN, but might be - * updated by the mblk_prop callback. - */ - if (kssl_init_context(listener->ksslf_ent, faddr, SSL3_MAX_RECORD_LEN, - &new->ksslf_ctx) != KSSL_STS_OK) - return (SOF_RVAL_ENOMEM); - - new->ksslf_pending = B_TRUE; - new->ksslf_inhandshake = B_TRUE; - ASSERT(laddrlen <= sizeof (new->ksslf_laddr)); - new->ksslf_laddrlen = laddrlen; - bcopy(laddr, &new->ksslf_laddr, laddrlen); - new->ksslf_laddr.sin6_port = listener->ksslf_laddr.sin6_port; - new->ksslf_listener = listener; - - *cookiep = new; - /* - * We are in handshake, defer the notification of this connection - * until it is completed. - */ - return (SOF_RVAL_DEFER); -} - -void -kssl_detach_cb(sof_handle_t handle, void *cookie, cred_t *cr) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - - _NOTE(ARGUNUSED(handle, cr)); - - if (kssl == NULL) - return; - - if (kssl->ksslf_ent != NULL) { - kssl_release_ent(kssl->ksslf_ent, handle, kssl->ksslf_type); - kssl->ksslf_ent = NULL; - } - if (kssl->ksslf_ctx != NULL) { - kssl_release_ctx(kssl->ksslf_ctx); - kssl->ksslf_ctx = NULL; - } - - kmem_free(kssl, sizeof (ksslf_t)); -} - -sof_rval_t -kssl_bind_cb(sof_handle_t handle, void *cookie, struct sockaddr *name, - socklen_t *namelen, cred_t *cr) -{ - kssl_ent_t ent; - kssl_endpt_type_t type; - ksslf_t *kssl; - in_port_t origport; - - _NOTE(ARGUNUSED(cr)); - - if (cookie != NULL) - return (SOF_RVAL_EINVAL); - - if (*namelen < sizeof (struct sockaddr_in)) { - sof_bypass(handle); - return (SOF_RVAL_CONTINUE); - } - - origport = ((struct sockaddr_in *)name)->sin_port; - /* Check if KSSL has been configured for this address */ - type = kssl_check_proxy(name, *namelen, handle, &ent); - - switch (type) { - case KSSL_NO_PROXY: - sof_bypass(handle); - break; - case KSSL_HAS_PROXY: - case KSSL_IS_PROXY: - kssl = kmem_zalloc(sizeof (ksslf_t), KM_SLEEP); - kssl->ksslf_type = type; - kssl->ksslf_ent = ent; - - /* - * In the unlikely event that there are multiple simultaneous - * bind requests, and the cookie was already swapped out, then - * just drop this cookie and let the bind continue unmodified. - */ - if (sof_cas_cookie(handle, cookie, kssl) != cookie) { - kssl_release_ent(ent, handle, type); - kmem_free(kssl, sizeof (ksslf_t)); - ((struct sockaddr_in *)name)->sin_port = origport; - break; - } - - kssl->ksslf_laddrlen = *namelen; - bcopy(name, &kssl->ksslf_laddr, kssl->ksslf_laddrlen); - kssl->ksslf_laddr.sin6_port = origport; - /* - * kssl_check_proxy updated the sockaddr, so just - * pass it along to the protocol. - */ - return ((type == KSSL_HAS_PROXY) ? SOF_RVAL_RETURN : - SOF_RVAL_CONTINUE); - } - return (SOF_RVAL_CONTINUE); -} - -sof_rval_t -kssl_listen_cb(sof_handle_t handle, void *cookie, int *backlog, cred_t *cr) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - - _NOTE(ARGUNUSED(backlog, cr)); - - /* - * The cookie can be NULL in the unlikely event of an application doing - * listen() without binding to an address. Those listeners are of no - * interest. - */ - if (kssl == NULL) { - sof_bypass(handle); - return (SOF_RVAL_CONTINUE); - } - - return (SOF_RVAL_CONTINUE); - -} - -/* - * Outgoing connections are not of interest, so just bypass the filter. - */ -sof_rval_t -kssl_connect_cb(sof_handle_t handle, void *cookie, struct sockaddr *name, - socklen_t *namelen, cred_t *cr) -{ - _NOTE(ARGUNUSED(cookie, name, namelen, cr)); - - sof_bypass(handle); - return (SOF_RVAL_CONTINUE); -} - -static void -kssl_mblk_prop_cb(sof_handle_t handle, void *cookie, ssize_t *maxblk, - ushort_t *wroff, ushort_t *tail) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - - _NOTE(ARGUNUSED(handle)); - - /* only care about passively opened sockets */ - if (kssl == NULL || !kssl->ksslf_pending) - return; - /* - * If this is endpoint is handling SSL, then reserve extra - * offset and space at the end. Also have sockfs allocate - * SSL3_MAX_RECORD_LEN packets, overriding the previous setting. - * The extra cost of signing and encrypting multiple MSS-size - * records (12 of them with Ethernet), instead of a single - * contiguous one by the stream head largely outweighs the - * statistical reduction of ACKs, when applicable. The peer - * will also save on decryption and verification costs. - */ - if (*maxblk == INFPSZ || *maxblk > SSL3_MAX_RECORD_LEN) - *maxblk = SSL3_MAX_RECORD_LEN; - else - kssl_set_mss(kssl->ksslf_ctx, *maxblk); - *wroff += SSL3_WROFFSET; - *tail += SSL3_MAX_TAIL_LEN; -} - -sof_rval_t -kssl_getsockname_cb(sof_handle_t handle, void *cookie, struct sockaddr *addr, - socklen_t *addrlen, cred_t *cr) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - - _NOTE(ARGUNUSED(handle, cr)); - - if (kssl == NULL) - return (SOF_RVAL_CONTINUE); - - if (*addrlen < kssl->ksslf_laddrlen) - return (SOF_RVAL_EINVAL); - - *addrlen = kssl->ksslf_laddrlen; - bcopy(&kssl->ksslf_laddr, addr, kssl->ksslf_laddrlen); - - return (SOF_RVAL_RETURN); -} - -/* - * Called for every packet sent to the protocol. - * If the message is successfully processed, then it is returned. - */ -mblk_t * -kssl_data_out_cb(sof_handle_t handle, void *cookie, mblk_t *mp, - struct nmsghdr *msg, cred_t *cr, sof_rval_t *rv) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - mblk_t *recmp; - - _NOTE(ARGUNUSED(handle, msg, cr)); - - *rv = SOF_RVAL_CONTINUE; - if (kssl == NULL || kssl->ksslf_ctx == NULL) - return (mp); - - if ((recmp = kssl_build_record(kssl->ksslf_ctx, mp)) == NULL) { - freemsg(mp); - *rv = SOF_RVAL_EINVAL; - return (NULL); - } - return (recmp); -} - -/* - * Called from shutdown() processing. This will produce close_notify message - * to indicate the end of data to the client. - */ -sof_rval_t -kssl_shutdown_cb(sof_handle_t handle, void *cookie, int *howp, cred_t *cr) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - mblk_t *outmp; - boolean_t flowctrld; - struct nmsghdr msg; - - _NOTE(ARGUNUSED(cr)); - - if (kssl == NULL || kssl->ksslf_ctx == NULL) - return (SOF_RVAL_CONTINUE); - - /* - * We only want to send close_notify when doing SHUT_WR/SHUT_RDWR - * because it signals that server is done writing data. - */ - if (*howp == SHUT_RD) - return (SOF_RVAL_CONTINUE); - - /* Go on if we fail to build the record. */ - if ((outmp = kssl_build_record(kssl->ksslf_ctx, NULL)) == NULL) - return (SOF_RVAL_CONTINUE); - - bzero(&msg, sizeof (msg)); - (void) sof_inject_data_out(handle, outmp, &msg, - &flowctrld); - - return (SOF_RVAL_CONTINUE); -} - -/* - * Called for each incoming segment. - * - * A packet may carry multiple SSL records, so the function calls - * kssl_input() in a loop, until all records are handled. - */ -mblk_t * -kssl_data_in_cb(sof_handle_t handle, void *cookie, mblk_t *mp, int flags, - size_t *lenp) -{ - ksslf_t *kssl = cookie; - kssl_cmd_t kssl_cmd; - mblk_t *outmp, *retmp = NULL, **tail = &retmp; - boolean_t more = B_FALSE; - boolean_t flowctrld; - - _NOTE(ARGUNUSED(flags)); - - if (kssl == NULL || kssl->ksslf_ctx == NULL) { - sof_bypass(handle); - return (mp); - } - - *lenp = 0; - do { - kssl_cmd = kssl_input(kssl->ksslf_ctx, mp, &outmp, - &more, kssl_input_callback, (void *)handle); - - switch (kssl_cmd) { - case KSSL_CMD_SEND: { - struct nmsghdr msg; - - DTRACE_PROBE(kssl_cmd_send); - bzero(&msg, sizeof (msg)); - (void) sof_inject_data_out(handle, outmp, &msg, - &flowctrld); - } - /* FALLTHROUGH */ - case KSSL_CMD_NONE: - DTRACE_PROBE(kssl_cmd_none); - if (kssl->ksslf_pending) { - kssl->ksslf_pending = B_FALSE; - sof_newconn_ready(handle); - } - break; - - case KSSL_CMD_QUEUED: - DTRACE_PROBE(kssl_cmd_queued); - break; - - case KSSL_CMD_DELIVER_PROXY: - case KSSL_CMD_DELIVER_SSL: - DTRACE_PROBE(kssl_cmd_proxy__ssl); - /* - * We're at a phase where records are sent upstreams, - * past the handshake - */ - kssl->ksslf_inhandshake = B_FALSE; - - *tail = outmp; - *lenp += MBLKL(outmp); - while (outmp->b_cont != NULL) { - outmp = outmp->b_cont; - *lenp += MBLKL(outmp); - } - tail = &outmp->b_cont; - break; - - case KSSL_CMD_NOT_SUPPORTED: { - ksslf_t *listener = kssl->ksslf_listener; - sof_handle_t fallback; - - DTRACE_PROBE(kssl_cmd_not_supported); - /* - * Stop the SSL processing by the proxy, and - * switch to the userland SSL - */ - if (kssl->ksslf_pending) { - kssl->ksslf_pending = B_FALSE; - - DTRACE_PROBE1(kssl_no_can_do, sof_handle_t, - handle); - - sof_bypass(handle); - - ASSERT(listener->ksslf_ent != NULL); - fallback = - kssl_find_fallback(listener->ksslf_ent); - /* - * No fallback: the remote will timeout and - * disconnect. - */ - if (fallback != NULL && - sof_newconn_move(handle, fallback)) - sof_newconn_ready(handle); - } - if (mp != NULL) { - *tail = mp; - *lenp += MBLKL(mp); - while (mp->b_cont != NULL) { - mp = mp->b_cont; - *lenp += MBLKL(mp); - } - tail = &mp->b_cont; - } - break; - } - } - mp = NULL; - } while (more); - - return (retmp); -} - -/* - * Process queued data before it's copied by the user. - * - * If the message is successfully processed, then it is returned. - * A failed message will be freed. - */ -mblk_t * -kssl_data_in_proc_cb(sof_handle_t handle, void *cookie, mblk_t *mp, - cred_t *cr, size_t *lenp) -{ - ksslf_t *kssl = (ksslf_t *)cookie; - kssl_cmd_t kssl_cmd; - mblk_t *out; - - _NOTE(ARGUNUSED(cr)); - - if (kssl == NULL || kssl->ksslf_ctx) - return (mp); - - *lenp = 0; - - kssl_cmd = kssl_handle_mblk(kssl->ksslf_ctx, &mp, &out); - - switch (kssl_cmd) { - case KSSL_CMD_NONE: - return (NULL); - case KSSL_CMD_DELIVER_PROXY: - *lenp = msgdsize(mp); - return (mp); - case KSSL_CMD_SEND: { - struct nmsghdr msg; - boolean_t flowctrld; - - ASSERT(out != NULL); - bzero(&msg, sizeof (msg)); - - (void) sof_inject_data_out(handle, out, &msg, - &flowctrld); - return (NULL); - } - default: - /* transient error. */ - return (NULL); - } -} - -/* - * Continue processing the incoming flow after an asynchronous callback. - */ -static void -kssl_input_asynch(void *arg) -{ - sof_handle_t handle = (sof_handle_t)arg; - ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle); - size_t len = 0; - boolean_t flowctrld; - mblk_t *mp; - - if ((mp = kssl_data_in_cb(handle, kssl, NULL, 0, &len)) != NULL) { - ASSERT(len != 0); - (void) sof_inject_data_in(handle, mp, len, 0, &flowctrld); - } - kssl_async_done(kssl->ksslf_ctx); -} - -/* - * Callback function for the cases kssl_input() had to submit an asynchronous - * job and need to come back when done to carry on the input processing. - * This routine follows the conentions of timeout and interrupt handlers. - * (no blocking, ...) - */ -static void -kssl_input_callback(void *arg, mblk_t *mp, kssl_cmd_t kssl_cmd) -{ - sof_handle_t handle = (sof_handle_t)arg; - ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle); - boolean_t flowctrld; - - ASSERT(kssl != NULL); - - switch (kssl_cmd) { - case KSSL_CMD_SEND: { - struct nmsghdr msg; - - if (mp == NULL) - break; - bzero(&msg, sizeof (msg)); - - (void) sof_inject_data_out(handle, mp, &msg, &flowctrld); - } - /* FALLTHROUGH */ - case KSSL_CMD_NONE: - break; - - case KSSL_CMD_DELIVER_PROXY: - case KSSL_CMD_DELIVER_SSL: - (void) sof_inject_data_in(handle, mp, msgdsize(mp), 0, - &flowctrld); - break; - - case KSSL_CMD_NOT_SUPPORTED: - /* Stop the SSL processing */ - sof_bypass(handle); - } - /* - * Process any input that may have accumulated while we're waiting for - * the call-back. This must be done by a taskq because kssl_input might - * block when handling client_finish messages. - */ - if (taskq_dispatch(system_taskq, kssl_input_asynch, handle, - TQ_NOSLEEP) == TASKQID_INVALID) { - DTRACE_PROBE(kssl_err__taskq_dispatch_failed); - kssl_async_done(kssl->ksslf_ctx); - } -} - -sof_ops_t ksslf_ops = { - .sofop_attach_passive = kssl_attach_passive_cb, - .sofop_detach = kssl_detach_cb, - .sofop_bind = kssl_bind_cb, - .sofop_connect = kssl_connect_cb, - .sofop_listen = kssl_listen_cb, - .sofop_data_in = kssl_data_in_cb, - .sofop_data_in_proc = kssl_data_in_proc_cb, - .sofop_data_out = kssl_data_out_cb, - .sofop_mblk_prop = kssl_mblk_prop_cb, - .sofop_getsockname = kssl_getsockname_cb, - .sofop_shutdown = kssl_shutdown_cb, -}; - -int -_init(void) -{ - int error; - - if ((error = sof_register(SOF_VERSION, KSSL_FILNAME, - &ksslf_ops, 0)) != 0) - return (error); - if ((error = mod_install(&ksslf_modlinkage)) != 0) - (void) sof_unregister(KSSL_FILNAME); - - return (error); -} - -int -_fini(void) -{ - int error; - - if ((error = sof_unregister(KSSL_FILNAME)) != 0) - return (error); - - return (mod_remove(&ksslf_modlinkage)); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&ksslf_modlinkage, modinfop)); -} diff --git a/usr/src/uts/common/inet/kssl/ksslimpl.h b/usr/src/uts/common/inet/kssl/ksslimpl.h deleted file mode 100644 index 95e83ee6b0..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslimpl.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _INET_KSSL_KSSLIMPL_H -#define _INET_KSSL_KSSLIMPL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/atomic.h> -#include <sys/mutex.h> -#include <sys/crypto/common.h> -#include <sys/kstat.h> -#include <sys/sdt.h> -#include <inet/kssl/ksslapi.h> -#include <inet/kssl/ksslproto.h> - -/* - * Certificate structure. The msg field is the BER data of the - * certificate. - */ -typedef struct Certificate { - uchar_t *msg; - int len; -} Certificate_t; - -/* Generic linked chain type */ -typedef struct kssl_chain_s { - struct kssl_chain_s *next; - void *item; -} kssl_chain_t; - -/* Proxies chain. follows the generic kssl_chain_t layout */ -typedef struct kssl_proxy_s { - struct kssl_proxy_s *next; - void *proxy_bound; -} kssl_proxy_t; - -/* Fallback endpoints chain. Ditto. */ -typedef struct kssl_fallback_s { - struct kssl_fallback_s *next; - void *fallback_bound; -} kssl_fallback_t; - -/* - * Structure to support using a non-extractable key in - * a crypto provider. We keep the token label and pin so - * that we can reauthenticate when needed. - */ -typedef struct kssl_session_info_s { - boolean_t is_valid_handle; - boolean_t do_reauth; - crypto_provider_t prov; - crypto_session_id_t sid; - crypto_key_t key; - crypto_notify_handle_t evnt_handle; - char toklabel[CRYPTO_EXT_SIZE_LABEL]; - int pinlen; - char tokpin[1]; -} kssl_session_info_t; - -/* kssl_entry_t structure. */ - -typedef struct kssl_entry_s { - uint_t ke_refcnt; /* for hold/release */ - boolean_t ke_no_freeall; - kmutex_t ke_mutex; - - in6_addr_t ke_laddr; - in_port_t ke_ssl_port; /* SSL port */ - in_port_t ke_proxy_port; /* SSL proxy port */ - - uint32_t sid_cache_timeout; /* In seconds */ - uint32_t sid_cache_nentries; - kssl_sid_ent_t *sid_cache; - - uint16_t kssl_cipherSuites[CIPHER_SUITE_COUNT]; - int kssl_cipherSuites_nentries; - uint16_t kssl_saved_Suites[CIPHER_SUITE_COUNT]; - - boolean_t ke_is_nxkey; - kssl_session_info_t *ke_sessinfo; - - crypto_key_t *ke_private_key; /* instance's private key */ - Certificate_t *ke_server_certificate; - - Certificate_t **ke_cacert_chain; - - kssl_proxy_t *ke_proxy_head; /* Proxies chain */ - kssl_fallback_t *ke_fallback_head; /* Fall-back endpoints chain */ - -} kssl_entry_t; - -typedef struct mech_to_cipher_s { - crypto_mech_type_t mech; - char *name; - uint16_t kssl_suites[CIPHER_SUITE_COUNT]; -} mech_to_cipher_t; - -#define KSSL_ENTRY_REFHOLD(kssl_entry) { \ - atomic_inc_32(&(kssl_entry)->ke_refcnt); \ - ASSERT((kssl_entry)->ke_refcnt != 0); \ -} - -#define KSSL_ENTRY_REFRELE(kssl_entry) { \ - ASSERT((kssl_entry)->ke_refcnt != 0); \ - membar_exit(); \ - if (atomic_dec_32_nv(&(kssl_entry)->ke_refcnt) == 0) { \ - kssl_free_entry((kssl_entry)); \ - } \ -} - -#define CRYPTO_ERR(r) ((r) != CRYPTO_SUCCESS && (r) != CRYPTO_QUEUED) - -/* - * Enqueue mblk into KSSL input queue. Watch for mblk b_cont chains - * returned by tcp_reass() and enqueue them properly. Caller should - * be aware that mp is modified by this macro. - */ -#define KSSL_ENQUEUE_MP(ssl, mp) { \ - DTRACE_PROBE1(kssl_mblk__enqueue_mp, mblk_t *, mp); \ - if ((ssl)->rec_ass_tail == NULL) { \ - (ssl)->rec_ass_head = (mp); \ - while (mp->b_cont) \ - mp = mp->b_cont; \ - (ssl)->rec_ass_tail = (mp); \ - } else { \ - (ssl)->rec_ass_tail->b_cont = (mp); \ - while (mp->b_cont) \ - mp = mp->b_cont; \ - (ssl)->rec_ass_tail = (mp); \ - } \ -} - -#define SSL_MISS 123 /* Internal SSL error */ - -extern crypto_mechanism_t rsa_x509_mech; -extern crypto_mechanism_t hmac_md5_mech; -extern crypto_mechanism_t hmac_sha1_mech; -extern crypto_call_flag_t kssl_call_flag; -extern KSSLCipherDef cipher_defs[]; - -extern struct kmem_cache *kssl_cache; - -#define KSSL_TAB_INITSIZE 4 -extern kssl_entry_t **kssl_entry_tab; -extern int kssl_entry_tab_size; -extern int kssl_entry_tab_nentries; -extern kmutex_t kssl_tab_mutex; - -typedef struct kssl_stats { - kstat_named_t sid_cache_lookups; - kstat_named_t sid_cache_hits; - kstat_named_t sid_cached; - kstat_named_t sid_uncached; - kstat_named_t full_handshakes; - kstat_named_t resumed_sessions; - kstat_named_t fallback_connections; - kstat_named_t proxy_fallback_failed; - kstat_named_t appdata_record_ins; - kstat_named_t appdata_record_outs; - kstat_named_t alloc_fails; - kstat_named_t fatal_alerts; - kstat_named_t warning_alerts; - kstat_named_t no_suite_found; - kstat_named_t compute_mac_failure; - kstat_named_t verify_mac_failure; - kstat_named_t record_decrypt_failure; - kstat_named_t bad_pre_master_secret; - kstat_named_t internal_errors; -} kssl_stats_t; - -extern kssl_stats_t *kssl_statp; - -#define KSSL_COUNTER(p, v) atomic_add_64(&kssl_statp->p.value.ui64, v) - -#define IS_SSL_PORT 1 -#define IS_PROXY_PORT 2 - -extern void kssl_free_entry(kssl_entry_t *); -extern void kssl_free_context(ssl_t *); -extern int kssl_compute_record_mac(ssl_t *, int, uint64_t, SSL3ContentType, - uchar_t *, uchar_t *, int, uchar_t *); -extern int kssl_handle_handshake_message(ssl_t *, mblk_t *, int *, - kssl_callback_t, void *); -extern int kssl_handle_v2client_hello(ssl_t *, mblk_t *, int); -extern void kssl_uncache_sid(sslSessionID *, kssl_entry_t *); -extern int kssl_mac_encrypt_record(ssl_t *, SSL3ContentType, uchar_t *, - uchar_t *, mblk_t *); -extern mblk_t *kssl_get_next_record(ssl_t *); -extern int kssl_get_obj_handle(kssl_entry_t *); -extern void kssl_prov_evnt(uint32_t, void *); - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_KSSL_KSSLIMPL_H */ diff --git a/usr/src/uts/common/inet/kssl/ksslioctl.c b/usr/src/uts/common/inet/kssl/ksslioctl.c deleted file mode 100644 index 5542d13158..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslioctl.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * The kernel SSL module ioctls. - */ - -#include <sys/types.h> -#include <sys/modctl.h> -#include <sys/conf.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/kmem.h> -#include <sys/errno.h> -#include <sys/file.h> -#include <sys/cred.h> -#include <sys/proc.h> -#include <sys/task.h> -#include <sys/model.h> -#include <sys/sysmacros.h> -#include <sys/policy.h> -#include <sys/crypto/common.h> -#include <sys/crypto/api.h> -#include <inet/common.h> -#include <inet/ip.h> - -#include "ksslimpl.h" -#include "kssl.h" -#include "ksslproto.h" - -kssl_entry_t **kssl_entry_tab; -int kssl_entry_tab_size; -int kssl_entry_tab_nentries; -uint_t null_cipher_suite; /* setable in /etc/system */ -kmutex_t kssl_tab_mutex; - -static void -certificate_free(Certificate_t *cert) -{ - kmem_free(cert->msg, cert->len); - kmem_free(cert, sizeof (struct Certificate)); -} - -static void -privateKey_free(crypto_key_t *privkey) -{ - int i; - size_t attrs_size; - crypto_object_attribute_t *attrs; - - attrs = privkey->ck_attrs; - attrs_size = privkey->ck_count * sizeof (crypto_object_attribute_t); - for (i = 0; i < privkey->ck_count; i++) { - bzero(attrs[i].oa_value, attrs[i].oa_value_len); - kmem_free(attrs[i].oa_value, attrs[i].oa_value_len); - } - kmem_free(attrs, attrs_size); - kmem_free(privkey, sizeof (crypto_key_t)); -} - -static void -sess_free(kssl_session_info_t *s) -{ - if (s->is_valid_handle) { - (void) crypto_session_logout(s->prov, s->sid, NULL); - (void) crypto_session_close(s->prov, s->sid, NULL); - crypto_release_provider(s->prov); - s->is_valid_handle = B_FALSE; - } - - if (s->evnt_handle != NULL) { - crypto_unnotify_events(s->evnt_handle); - s->evnt_handle = NULL; - } - - bzero(s->tokpin, s->pinlen); - kmem_free(s, sizeof (kssl_session_info_t) + s->pinlen); -} - -/* - * Frees the space for the entry and the keys and certs - * it carries. - */ -void -kssl_free_entry(kssl_entry_t *kssl_entry) -{ - int i; - Certificate_t *cert; - crypto_key_t *privkey; - kssl_session_info_t *s; - - if (kssl_entry->ke_no_freeall) { - kmem_free(kssl_entry, sizeof (kssl_entry_t)); - return; - } - - if ((cert = kssl_entry->ke_server_certificate) != NULL) { - certificate_free(cert); - } - - if ((privkey = kssl_entry->ke_private_key) != NULL) { - privateKey_free(privkey); - } - - for (i = 0; i < kssl_entry->sid_cache_nentries; i++) - mutex_destroy(&(kssl_entry->sid_cache[i].se_lock)); - - kmem_free(kssl_entry->sid_cache, - kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t)); - - ASSERT(kssl_entry->ke_proxy_head == NULL); - ASSERT(kssl_entry->ke_fallback_head == NULL); - - if ((s = kssl_entry->ke_sessinfo) != NULL) { - ASSERT(kssl_entry->ke_is_nxkey); - sess_free(s); - } - - kmem_free(kssl_entry, sizeof (kssl_entry_t)); -} - -/* - * Returns the index of the entry in kssl_entry_tab[] that matches - * the address and port. Returns -1 if no match is found. - */ -static int -kssl_find_entry(in6_addr_t laddr, in_port_t port, int type, - boolean_t wild_card_match) -{ - int i; - kssl_entry_t *ep; - - ASSERT(MUTEX_HELD(&kssl_tab_mutex)); - - for (i = 0; i < kssl_entry_tab_size; i++) { - ep = kssl_entry_tab[i]; - if (ep == NULL) - continue; - - if (!((type == IS_SSL_PORT && ep->ke_ssl_port == port) || - (type == IS_PROXY_PORT && ep->ke_proxy_port == port))) - continue; - - if (IN6_ARE_ADDR_EQUAL(&laddr, &ep->ke_laddr) || - (wild_card_match && (IN6_IS_ADDR_UNSPECIFIED(&laddr) || - IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)))) - break; - } - - if (i == kssl_entry_tab_size) - return (-1); - - return (i); -} - -static void -copy_int_to_bytearray(int x, uchar_t *buf) -{ - buf[0] = (x >> 16) & 0xff; - buf[1] = (x >> 8) & 0xff; - buf[2] = (x) & 0xff; -} - -static int -extract_certificate(kssl_params_t *kssl_params, Certificate_t **certpp) -{ - int i, len; - uint64_t in_size; - uchar_t *end_pos; - uint32_t ncert; - uint32_t *cert_sizes; - Certificate_t *cert; - char *begin = (char *)kssl_params; - uchar_t *cert_buf; - int cert_buf_len; - uchar_t *cert_from, *cert_to; - - ASSERT(kssl_params); - - in_size = kssl_params->kssl_params_size; - end_pos = (uchar_t *)kssl_params + in_size; - - /* - * Get the certs array. First the array of sizes, then the actual - * certs. - */ - ncert = kssl_params->kssl_certs.sc_count; - - if (ncert == 0) { - /* no certs in here! why did ya call? */ - return (EINVAL); - } - if (in_size < (sizeof (kssl_params_t) + ncert * sizeof (uint32_t))) { - return (EINVAL); - } - - /* Trusting that the system call preserved the 4-byte alignment */ - cert_sizes = (uint32_t *)(begin + - kssl_params->kssl_certs.sc_sizes_offset); - - /* should this be an ASSERT()? */ - if (!IS_P2ALIGNED(cert_sizes, sizeof (uint32_t))) { - return (EINVAL); - } - - len = 0; - for (i = 0; i < ncert; i++) { - if (cert_sizes[i] < 1) { - return (EINVAL); - } - len += cert_sizes[i] + 3; - } - - len += 3; /* length of certificate message without msg header */ - - cert_buf_len = len + 4 + 4; /* add space for msg headers */ - - cert_buf = kmem_alloc(cert_buf_len, KM_SLEEP); - - cert_buf[0] = (uchar_t)certificate; - copy_int_to_bytearray(len, & cert_buf[1]); - copy_int_to_bytearray(len - 3, & cert_buf[4]); - - cert_from = (uchar_t *)(begin + - kssl_params->kssl_certs.sc_certs_offset); - cert_to = &cert_buf[7]; - - for (i = 0; i < ncert; i++) { - copy_int_to_bytearray(cert_sizes[i], cert_to); - cert_to += 3; - - if (cert_from + cert_sizes[i] > end_pos) { - kmem_free(cert_buf, cert_buf_len); - return (EINVAL); - } - - bcopy(cert_from, cert_to, cert_sizes[i]); - cert_from += cert_sizes[i]; - cert_to += cert_sizes[i]; - } - - len += 4; - cert_buf[len] = (uchar_t)server_hello_done; - copy_int_to_bytearray(0, & cert_buf[len + 1]); - - cert = kmem_alloc(sizeof (Certificate_t), KM_SLEEP); - cert->msg = cert_buf; - cert->len = cert_buf_len; - - *certpp = cert; - - return (0); -} - -static int -extract_private_key(kssl_params_t *kssl_params, crypto_key_t **privkey) -{ - char *begin = (char *)kssl_params; - char *end_pos; - int i, j, rv; - size_t attrs_size; - crypto_object_attribute_t *newattrs; - char *mp_attrs; - kssl_object_attribute_t att; - char *attval; - uint32_t attlen; - crypto_key_t *kssl_privkey; - - end_pos = (char *)kssl_params + kssl_params->kssl_params_size; - - kssl_privkey = kmem_alloc(sizeof (crypto_key_t), KM_SLEEP); - - kssl_privkey->ck_format = kssl_params->kssl_privkey.ks_format; - kssl_privkey->ck_count = kssl_params->kssl_privkey.ks_count; - - switch (kssl_privkey->ck_format) { - case CRYPTO_KEY_ATTR_LIST: - break; - case CRYPTO_KEY_RAW: - case CRYPTO_KEY_REFERENCE: - default: - rv = EINVAL; - goto err1; - } - - /* allocate the attributes */ - attrs_size = kssl_privkey->ck_count * - sizeof (crypto_object_attribute_t); - - mp_attrs = begin + kssl_params->kssl_privkey.ks_attrs_offset; - if (mp_attrs + attrs_size > end_pos) { - rv = EINVAL; - goto err1; - } - - newattrs = kmem_alloc(attrs_size, KM_SLEEP); - - /* Now the individual attributes */ - for (i = 0; i < kssl_privkey->ck_count; i++) { - bcopy(mp_attrs, &att, sizeof (kssl_object_attribute_t)); - - mp_attrs += sizeof (kssl_object_attribute_t); - - attval = begin + att.ka_value_offset; - attlen = att.ka_value_len; - - if (attval + attlen > end_pos) { - rv = EINVAL; - goto err2; - } - - newattrs[i].oa_type = att.ka_type; - newattrs[i].oa_value_len = attlen; - newattrs[i].oa_value = kmem_alloc(attlen, KM_SLEEP); - - bcopy(attval, newattrs[i].oa_value, attlen); - } - - kssl_privkey->ck_attrs = newattrs; - - *privkey = kssl_privkey; - - return (0); - -err2: - for (j = 0; j < i; j++) { - bzero(newattrs[j].oa_value, newattrs[j].oa_value_len); - kmem_free(newattrs[j].oa_value, newattrs[j].oa_value_len); - } - kmem_free(newattrs, attrs_size); -err1: - kmem_free(kssl_privkey, sizeof (crypto_key_t)); - return (rv); -} - -static int -create_sessinfo(kssl_params_t *kssl_params, kssl_entry_t *kssl_entry) -{ - int rv; - char *p; - kssl_session_info_t *s; - kssl_tokinfo_t *t; - - t = &kssl_params->kssl_token; - /* Do a sanity check */ - if (t->pinlen > MAX_PIN_LENGTH) { - return (EINVAL); - } - - s = kmem_zalloc(sizeof (kssl_session_info_t) + t->pinlen, KM_SLEEP); - s->pinlen = t->pinlen; - bcopy(t->toklabel, s->toklabel, CRYPTO_EXT_SIZE_LABEL); - p = (char *)kssl_params + t->tokpin_offset; - bcopy(p, s->tokpin, s->pinlen); - ASSERT(kssl_entry->ke_sessinfo == NULL); - kssl_entry->ke_sessinfo = s; - - /* Get the handle to the non extractable key */ - rv = kssl_get_obj_handle(kssl_entry); - kssl_params->kssl_token.ck_rv = rv; - if (rv != CRYPTO_SUCCESS) { - sess_free(s); - kssl_entry->ke_sessinfo = NULL; - return (EINVAL); - } - - kssl_entry->ke_sessinfo->is_valid_handle = B_TRUE; - kssl_entry->ke_sessinfo->do_reauth = B_FALSE; - kssl_entry->ke_sessinfo->evnt_handle = - crypto_notify_events(kssl_prov_evnt, - CRYPTO_EVENT_PROVIDER_REGISTERED | - CRYPTO_EVENT_PROVIDER_UNREGISTERED); - - return (0); -} - -static kssl_entry_t * -create_kssl_entry(kssl_params_t *kssl_params, Certificate_t *cert, - crypto_key_t *privkey) -{ - int i; - uint16_t s; - kssl_entry_t *kssl_entry, *ep; - uint_t cnt, mech_count; - crypto_mech_name_t *mechs; - boolean_t got_rsa, got_md5, got_sha1, got_rc4, got_des, got_3des; - boolean_t got_aes; - - kssl_entry = kmem_zalloc(sizeof (kssl_entry_t), KM_SLEEP); - - kssl_entry->ke_laddr = kssl_params->kssl_addr.sin6_addr; - kssl_entry->ke_ssl_port = kssl_params->kssl_addr.sin6_port; - kssl_entry->ke_proxy_port = kssl_params->kssl_proxy_port; - if (kssl_params->kssl_session_cache_timeout == 0) - kssl_entry->sid_cache_timeout = DEFAULT_SID_TIMEOUT; - else - kssl_entry->sid_cache_timeout = - kssl_params->kssl_session_cache_timeout; - if (kssl_params->kssl_session_cache_size == 0) - kssl_entry->sid_cache_nentries = DEFAULT_SID_CACHE_NENTRIES; - else - kssl_entry->sid_cache_nentries = - kssl_params->kssl_session_cache_size; - kssl_entry->ke_private_key = privkey; - kssl_entry->ke_server_certificate = cert; - - kssl_entry->ke_is_nxkey = kssl_params->kssl_is_nxkey; - if (kssl_entry->ke_is_nxkey) { - if (create_sessinfo(kssl_params, kssl_entry) != 0) { - kmem_free(kssl_entry, sizeof (kssl_entry_t)); - return (NULL); - } - } - - mechs = crypto_get_mech_list(&mech_count, KM_SLEEP); - if (mechs != NULL) { - got_rsa = got_md5 = got_sha1 = got_rc4 = - got_des = got_3des = got_aes = B_FALSE; - for (i = 0; i < mech_count; i++) { - if (strncmp(SUN_CKM_RSA_X_509, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_rsa = B_TRUE; - else if (strncmp(SUN_CKM_MD5_HMAC, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_md5 = B_TRUE; - else if (strncmp(SUN_CKM_SHA1_HMAC, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_sha1 = B_TRUE; - else if (strncmp(SUN_CKM_RC4, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_rc4 = B_TRUE; - else if (strncmp(SUN_CKM_DES_CBC, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_des = B_TRUE; - else if (strncmp(SUN_CKM_DES3_CBC, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_3des = B_TRUE; - else if (strncmp(SUN_CKM_AES_CBC, mechs[i], - CRYPTO_MAX_MECH_NAME) == 0) - got_aes = B_TRUE; - } - - cnt = 0; - ep = kssl_entry; - for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) { - switch (s = kssl_params->kssl_suites[i]) { - case SSL_RSA_WITH_RC4_128_MD5: - if (got_rsa && got_rc4 && got_md5) - ep->kssl_cipherSuites[cnt++] = s; - break; - case SSL_RSA_WITH_RC4_128_SHA: - if (got_rsa && got_rc4 && got_sha1) - ep->kssl_cipherSuites[cnt++] = s; - break; - case SSL_RSA_WITH_DES_CBC_SHA: - if (got_rsa && got_des && got_sha1) - ep->kssl_cipherSuites[cnt++] = s; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - if (got_rsa && got_3des && got_sha1) - ep->kssl_cipherSuites[cnt++] = s; - break; - case TLS_RSA_WITH_AES_128_CBC_SHA: - if (got_rsa && got_aes && got_sha1) - ep->kssl_cipherSuites[cnt++] = s; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - if (got_rsa && got_aes && got_sha1) - ep->kssl_cipherSuites[cnt++] = s; - break; - case CIPHER_NOTSET: - default: - break; - } - } - - crypto_free_mech_list(mechs, mech_count); - } - - /* - * Add the no encryption suite to the end if requested by the - * kssl:null_cipher_suite /etc/system tunable since we do not want - * to be running with it by default. - */ - if (null_cipher_suite && got_rsa && got_sha1) - kssl_entry->kssl_cipherSuites[cnt++] = SSL_RSA_WITH_NULL_SHA; - kssl_entry->kssl_cipherSuites_nentries = cnt; - for (i = 0; i < cnt; i++) - kssl_entry->kssl_saved_Suites[i] = - kssl_entry->kssl_cipherSuites[i]; - - kssl_entry->sid_cache = kmem_alloc( - kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t), KM_SLEEP); - - for (i = 0; i < kssl_entry->sid_cache_nentries; i++) { - mutex_init(&(kssl_entry->sid_cache[i].se_lock), NULL, - MUTEX_DEFAULT, NULL); - kssl_entry->sid_cache[i].se_used = 0; - kssl_entry->sid_cache[i].se_sid.cached = B_FALSE; - } - - KSSL_ENTRY_REFHOLD(kssl_entry); - - return (kssl_entry); -} - -int -kssl_add_entry(kssl_params_t *kssl_params) -{ - int rv, index, i; - Certificate_t *cert; - crypto_key_t *privkey; - kssl_entry_t *kssl_entry; - in6_addr_t laddr; - - if ((rv = extract_certificate(kssl_params, &cert)) != 0) { - return (rv); - } - - if ((rv = extract_private_key(kssl_params, &privkey)) != 0) { - certificate_free(cert); - return (rv); - } - - kssl_entry = create_kssl_entry(kssl_params, cert, privkey); - if (kssl_entry == NULL) { - certificate_free(cert); - privateKey_free(privkey); - return (EINVAL); - } - - laddr = kssl_params->kssl_addr.sin6_addr; - -retry: - mutex_enter(&kssl_tab_mutex); - /* Allocate the array first time here */ - if (kssl_entry_tab == NULL) { - size_t allocsize; - kssl_entry_t **tmp_tab; - int tmp_size; - - tmp_size = KSSL_TAB_INITSIZE; - allocsize = tmp_size * sizeof (kssl_entry_t *); - mutex_exit(&kssl_tab_mutex); - tmp_tab = kmem_zalloc(allocsize, KM_SLEEP); - mutex_enter(&kssl_tab_mutex); - if (kssl_entry_tab != NULL) { - mutex_exit(&kssl_tab_mutex); - kmem_free(tmp_tab, allocsize); - goto retry; - } - kssl_entry_tab_size = tmp_size; - kssl_entry_tab = tmp_tab; - index = 0; - } else { - /* Check if a matching entry exists already */ - index = kssl_find_entry(laddr, - kssl_params->kssl_addr.sin6_port, IS_SSL_PORT, B_TRUE); - - if (index == -1) { - /* Check if an entry with the same proxy port exists */ - if (kssl_find_entry(laddr, kssl_params->kssl_proxy_port, - IS_PROXY_PORT, B_TRUE) != -1) { - mutex_exit(&kssl_tab_mutex); - kssl_free_entry(kssl_entry); - return (EADDRINUSE); - } - - /* No matching entry, find an empty spot */ - for (i = 0; i < kssl_entry_tab_size; i++) { - if (kssl_entry_tab[i] == NULL) - break; - } - /* Table full. Gotta grow it */ - if (i == kssl_entry_tab_size) { - kssl_entry_t **new_tab, **old_tab; - size_t allocsize; - size_t oldtabsize = kssl_entry_tab_size * - sizeof (kssl_entry_t *); - int tmp_size, old_size; - - tmp_size = old_size = kssl_entry_tab_size; - tmp_size += KSSL_TAB_INITSIZE; - allocsize = tmp_size * sizeof (kssl_entry_t *); - mutex_exit(&kssl_tab_mutex); - new_tab = kmem_zalloc(allocsize, KM_SLEEP); - mutex_enter(&kssl_tab_mutex); - if (kssl_entry_tab_size > old_size) { - mutex_exit(&kssl_tab_mutex); - kmem_free(new_tab, allocsize); - goto retry; - } - - kssl_entry_tab_size = tmp_size; - bcopy(kssl_entry_tab, new_tab, oldtabsize); - - old_tab = kssl_entry_tab; - kssl_entry_tab = new_tab; - - kmem_free(old_tab, oldtabsize); - } - index = i; - } else { - kssl_entry_t *ep; - - /* - * We do not want an entry with a specific address and - * an entry with IN_ADDR_ANY to coexist. We could - * replace the existing entry. But, most likely this - * is misconfiguration. Better bail out with an error. - */ - ep = kssl_entry_tab[index]; - - if ((IN6_IS_ADDR_UNSPECIFIED(&laddr) && - !IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)) || - (!IN6_IS_ADDR_UNSPECIFIED(&laddr) && - IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr))) { - mutex_exit(&kssl_tab_mutex); - kssl_free_entry(kssl_entry); - return (EEXIST); - } - - /* Replace the existing entry */ - KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); - kssl_entry_tab[index] = NULL; - kssl_entry_tab_nentries--; - } - } - - kssl_entry_tab[index] = kssl_entry; - kssl_entry_tab_nentries++; - mutex_exit(&kssl_tab_mutex); - - return (0); -} - -int -kssl_delete_entry(struct sockaddr_in6 *kssl_addr) -{ - in6_addr_t laddr; - int index; - - laddr = kssl_addr->sin6_addr; - - mutex_enter(&kssl_tab_mutex); - index = kssl_find_entry(laddr, kssl_addr->sin6_port, - IS_SSL_PORT, B_FALSE); - - if (index == -1) { - mutex_exit(&kssl_tab_mutex); - return (ENOENT); - } - - KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); - kssl_entry_tab[index] = NULL; - kssl_entry_tab_nentries--; - - mutex_exit(&kssl_tab_mutex); - - return (0); -} - -/* - * We care about only one private key object. - * So, set the max count to only 1. - */ -#define MAX_OBJECT_COUNT 1 - -/* - * Open a session to the provider specified by the label and - * authenticate to it. Find the private key object with the - * specified attributes and save the handle. The userland component - * must set all the attributes in the template so as to uniquely - * identify the object. - * - * Note that the handle will be invalid if we logout or close - * the session to the provider. - */ -int -kssl_get_obj_handle(kssl_entry_t *kp) -{ - int rv; - unsigned int count; - void *cookie = NULL; - crypto_provider_t prov; - kssl_session_info_t *s; - crypto_session_id_t sid; - crypto_object_attribute_t *attrs; - crypto_object_id_t ohndl[MAX_OBJECT_COUNT]; - char label[CRYPTO_EXT_SIZE_LABEL + 1]; - - ASSERT(kp->ke_is_nxkey); - s = kp->ke_sessinfo; - - bcopy(s->toklabel, label, CRYPTO_EXT_SIZE_LABEL); - label[CRYPTO_EXT_SIZE_LABEL] = '\0'; - prov = crypto_get_provider(label, NULL, NULL); - if (prov == NULL) - return (CRYPTO_UNKNOWN_PROVIDER); - - rv = crypto_session_open(prov, &sid, NULL); - if (rv != CRYPTO_SUCCESS) { - goto err1; - } - - rv = crypto_session_login(prov, sid, CRYPTO_USER, - s->tokpin, s->pinlen, NULL); - if (rv != CRYPTO_SUCCESS) { - goto err2; - } - - count = kp->ke_private_key->ck_count; - attrs = kp->ke_private_key->ck_attrs; - - rv = crypto_object_find_init(prov, sid, attrs, count, &cookie, NULL); - if (rv != CRYPTO_SUCCESS) { - goto err3; - } - - rv = crypto_object_find(prov, cookie, ohndl, &count, - MAX_OBJECT_COUNT, NULL); - if (rv != CRYPTO_SUCCESS || count == 0) { - if (count == 0) - rv = CRYPTO_FAILED; - goto err3; - } - - (void) crypto_object_find_final(prov, cookie, NULL); - - s->sid = sid; - s->prov = prov; - s->key.ck_format = CRYPTO_KEY_REFERENCE; - /* Keep the handle around for later use */ - s->key.ck_obj_id = ohndl[0]; - - return (CRYPTO_SUCCESS); - -err3: - (void) crypto_session_logout(prov, sid, NULL); -err2: - (void) crypto_session_close(prov, sid, NULL); -err1: - crypto_release_provider(prov); - return (rv); -} diff --git a/usr/src/uts/common/inet/kssl/ksslproto.h b/usr/src/uts/common/inet/kssl/ksslproto.h deleted file mode 100644 index c982fe9dfd..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslproto.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _INET_KSSL_KSSLPROTO_H -#define _INET_KSSL_KSSLPROTO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <sys/stream.h> -#include <sys/md5.h> -#include <sys/sha1.h> -#include <sys/crypto/common.h> -#include <sys/crypto/api.h> -#include <inet/kssl/kssl.h> /* Cipher suite definitions */ -#include <inet/kssl/ksslapi.h> -#include <inet/kssl/ksslimpl.h> - -#define SSL3_RANDOM_LENGTH 32 -#define SSL3_SESSIONID_BYTES 32 -#define SSL3_HDR_LEN 5 -#define SSL3_ALERT_LEN 2 -#define SSL3_MAX_RECORD_LENGTH 16384 -#define SSL3_PRE_MASTER_SECRET_LEN 48 -#define SSL3_MASTER_SECRET_LEN 48 -#define SSL3_MD5_PAD_LEN 48 -#define SSL3_SHA1_PAD_LEN 40 - -#define SSL_MIN_CHALLENGE_BYTES 16 -#define SSL_MAX_CHALLENGE_BYTES 32 - -#define SHA1_HASH_LEN 20 -#define MD5_HASH_LEN 16 -#define MAX_HASH_LEN SHA1_HASH_LEN - -#define KSSL_READ 0 -#define KSSL_WRITE 1 - -#define KSSL_ENCRYPT 0 -#define KSSL_DECRYPT 1 - -#define MSG_INIT 0 -#define MSG_INIT_LEN 1 -#define MSG_BODY 2 - -/* - * More than enough for the cipher suite that needs the - * largest key material (AES_256_CBC_SHA needs 136 bytes). - */ -#define MAX_KEYBLOCK_LENGTH 160 - -#define TLS_MASTER_SECRET_LABEL "master secret" -#define TLS_CLIENT_WRITE_KEY_LABEL "client write key" -#define TLS_SERVER_WRITE_KEY_LABEL "server write key" -#define TLS_CLIENT_FINISHED_LABEL "client finished" -#define TLS_SERVER_FINISHED_LABEL "server finished" -#define TLS_KEY_EXPANSION_LABEL "key expansion" -#define TLS_IV_BLOCK_LABEL "IV block" -#define TLS_MAX_LABEL_SIZE 24 - -#define TLS_FINISHED_SIZE 12 - -/* - * The following constants try to insure an input buffer is optimally aligned - * for MAC hash computation. SHA1/MD5 code prefers 4 byte alignment of each - * 64byte input block to avoid a copy. Our goal is to reach 4 byte alignment - * starting form the 3rd MAC block (input buffer starts in the 3rd block). The - * 3rd block includes the first 53 (MD5 SSL3 MAC) or 57 (SHA1 SSL3 MAC) bytes - * of the input buffer. This means input buffer should start at offset 3 - * within a 4 byte word so that its next block is 4 byte aligned. Since the - * SSL3 record header is 5 bytes long it should start at at offset 2 within a - * 4 byte word. To insure the next record (for buffers that don't fit into 1 - * SSL3 record) also starts at offset 2 within a 4 byte word the previous - * record length should be 3 mod 8 since 5 + 3 mod 8 is 0 i.e. the next record - * starts at the same offset within a 4 byte word as the the previous record. - */ -#define SSL3_MAX_OPTIMAL_RECORD_LENGTH (SSL3_MAX_RECORD_LENGTH - 1) -#define SSL3_OPTIMAL_RECORD_ALIGNMENT 2 - -/* session state */ -typedef struct sslSessionIDStr { - uchar_t session_id[SSL3_SESSIONID_BYTES]; - uchar_t master_secret[SSL3_MASTER_SECRET_LEN]; - clock_t time; - in6_addr_t client_addr; - boolean_t cached; - uint16_t cipher_suite; -} sslSessionID; - -/* An element of the session cache */ -typedef struct kssl_sid_ent { - kmutex_t se_lock; - uint64_t se_used; /* Counter to check hash distribution */ - sslSessionID se_sid; -} kssl_sid_ent_t; - -typedef enum { - content_change_cipher_spec = 20, - content_alert = 21, - content_handshake = 22, - content_application_data = 23, - content_handshake_v2 = 128 -} SSL3ContentType; - -typedef enum { - hello_request = 0, - client_hello = 1, - server_hello = 2, - certificate = 11, - server_key_exchange = 12, - certificate_request = 13, - server_hello_done = 14, - certificate_verify = 15, - client_key_exchange = 16, - finished = 20 -} SSL3HandshakeType; - -typedef struct SSL3HandshakeMsgStr { - int state; - SSL3HandshakeType type; - int msglen; - int msglen_bytes; - mblk_t *head; - mblk_t *tail; -} SSL3HandshakeMsg; - -typedef struct KSSLJOBStr { - struct ssl_s *ssl; - crypto_req_id_t kjob; - char *buf; - size_t buflen; - int status; -} KSSLJOB; - - -typedef struct { - uchar_t md5[MD5_HASH_LEN]; - uchar_t sha1[SHA1_HASH_LEN]; - uchar_t tlshash[TLS_FINISHED_SIZE]; -} SSL3Hashes; - -typedef enum { - close_notify = 0, - unexpected_message = 10, - bad_record_mac = 20, - decompression_failure = 30, - handshake_failure = 40, - no_certificate = 41, - bad_certificate = 42, - unsupported_certificate = 43, - certificate_revoked = 44, - certificate_expired = 45, - certificate_unknown = 46, - illegal_parameter = 47, - unknown_ca = 48, - access_denied = 49, - decode_error = 50, - decrypt_error = 51, - export_restriction = 60, - protocol_version = 70, - insufficient_security = 71, - internal_error = 80, - user_canceled = 90, - no_renegotiation = 100 -} SSL3AlertDescription; - -typedef enum { - alert_warning = 1, - alert_fatal = 2 -} SSL3AlertLevel; - -typedef enum { - wait_client_hello = 0, - wait_client_key = 1, - wait_client_key_done = 2, - wait_change_cipher = 3, - wait_finished = 4, - idle_handshake = 5 -} SSL3WaitState; - -typedef enum { - sender_client = 0x434c4e54, - sender_server = 0x53525652 -} SSL3Sender; - -typedef enum { - mac_md5 = 0, - mac_sha = 1 -} SSL3MACAlgorithm; - -/* The SSL bulk cipher definition */ -typedef enum { - cipher_null = 0, - cipher_rc4 = 1, - cipher_des = 2, - cipher_3des = 3, - cipher_aes128 = 4, - cipher_aes256 = 5, -} SSL3BulkCipher; - -typedef enum { type_stream = 0, type_block = 1 } CipherType; - -typedef struct ssl3CipherSuiteDefStr { - uint16_t suite; - SSL3BulkCipher calg; - SSL3MACAlgorithm malg; - int keyblksz; -} ssl3CipherSuiteDef; - -typedef void (*hashinit_func_t)(void *); -typedef void (*hashupdate_func_t)(void *, uchar_t *, uint32_t); -typedef void (*hashfinal_func_t)(uchar_t *, void *); - -typedef struct KSSLMACDefStr { - int hashsz; - int padsz; - hashinit_func_t HashInit; - hashupdate_func_t HashUpdate; - hashfinal_func_t HashFinal; -} KSSLMACDef; - -typedef struct KSSLCipherDefStr { - CipherType type; - int bsize; - int keysz; - crypto_mech_type_t mech_type; -} KSSLCipherDef; - -typedef union KSSL_HASHCTXUnion { - SHA1_CTX sha; - MD5_CTX md5; -} KSSL_HASHCTX; - -typedef struct KSSLCipherSpecStr { - int mac_hashsz; - int mac_padsz; - void (*MAC_HashInit)(void *); - void (*MAC_HashUpdate)(void *, uchar_t *, uint32_t); - void (*MAC_HashFinal)(uchar_t *, void *); - - CipherType cipher_type; - int cipher_bsize; - int cipher_keysz; - - crypto_mechanism_t cipher_mech; - crypto_mechanism_t hmac_mech; /* for TLS */ - crypto_key_t cipher_key; - crypto_key_t hmac_key; /* for TLS */ - - crypto_context_t cipher_ctx; - crypto_data_t cipher_data; - -} KSSLCipherSpec; - -/* - * SSL connection state. This one hangs off of a ksslf_t structure. - */ -typedef struct ssl_s { - kmutex_t kssl_lock; - struct kssl_entry_s *kssl_entry; - mblk_t *rec_ass_head; - mblk_t *rec_ass_tail; - in6_addr_t faddr; - uint32_t tcp_mss; - SSL3WaitState hs_waitstate; - boolean_t resumed; - boolean_t close_notify_clnt; - boolean_t close_notify_srvr; - boolean_t fatal_alert; - boolean_t fatal_error; - boolean_t alert_sent; - boolean_t appdata_sent; - boolean_t activeinput; - SSL3AlertLevel sendalert_level; - SSL3AlertDescription sendalert_desc; - mblk_t *handshake_sendbuf; - mblk_t *alert_sendbuf; - kssl_callback_t cke_callback_func; - void *cke_callback_arg; - uint16_t pending_cipher_suite; - SSL3MACAlgorithm pending_malg; - SSL3BulkCipher pending_calg; - int pending_keyblksz; - uint64_t seq_num[2]; - SSL3HandshakeMsg msg; - KSSLJOB job; - KSSLCipherSpec spec[2]; - uchar_t pending_keyblock[MAX_KEYBLOCK_LENGTH]; - uchar_t mac_secret[2][MAX_HASH_LEN]; - KSSL_HASHCTX mac_ctx[2][2]; /* inner 'n outer per dir */ - sslSessionID sid; - SHA1_CTX hs_sha1; - MD5_CTX hs_md5; - SSL3Hashes hs_hashes; - uchar_t client_random[SSL3_RANDOM_LENGTH]; - uchar_t server_random[SSL3_RANDOM_LENGTH]; - int sslcnt; - uchar_t major_version; - uchar_t minor_version; - boolean_t secure_renegotiation; - uint_t async_ops_pending; - kcondvar_t async_cv; -} ssl_t; - -#define IS_TLS(s) (s->major_version == 3 && s->minor_version == 1) - -#define SSL3_REC_SIZE(mp) (uint8_t *)(mp)->b_rptr + 3 - -extern int kssl_spec_init(ssl_t *, int); -extern void kssl_send_alert(ssl_t *, SSL3AlertLevel, SSL3AlertDescription); - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_KSSL_KSSLPROTO_H */ diff --git a/usr/src/uts/common/inet/kssl/ksslrec.c b/usr/src/uts/common/inet/kssl/ksslrec.c deleted file mode 100644 index e609893c73..0000000000 --- a/usr/src/uts/common/inet/kssl/ksslrec.c +++ /dev/null @@ -1,2531 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <sys/types.h> -#include <sys/stream.h> -#include <sys/strsubr.h> -#include <sys/stropts.h> -#include <sys/strsun.h> -#define _SUN_TPI_VERSION 2 -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/debug.h> -#include <sys/vtrace.h> -#include <sys/kmem.h> -#include <sys/cpuvar.h> -#include <sys/atomic.h> -#include <sys/sysmacros.h> - -#include <sys/errno.h> -#include <sys/isa_defs.h> -#include <sys/md5.h> -#include <sys/sha1.h> -#include <sys/random.h> -#include <inet/common.h> -#include <netinet/in.h> - -#include <sys/systm.h> -#include <sys/param.h> - -#include "ksslimpl.h" -#include "ksslapi.h" -#include "ksslproto.h" - -static ssl3CipherSuiteDef cipher_suite_defs[] = { - /* 2 X 16 byte keys + 2 x 20 byte MAC secrets, no IVs */ - {SSL_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, 72}, - - /* 2 X 16 byte keys + 2 x 16 byte MAC secrets, no IVs */ - {SSL_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, 64}, - - /* 2 X 8 byte keys + 2 x 20 byte MAC secrets, 2 x 8 byte IVs */ - {SSL_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, 72}, - - /* 2 X 24 byte keys + 2 x 20 byte MAC secrets, 2 x 8 byte IVs */ - {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, 104}, - - /* 2 X 16 byte keys + 2 x 20 byte MAC secrets, 2 x 16 byte IVs */ - {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes128, mac_sha, 104}, - - /* 2 X 32 byte keys + 2 x 20 byte MAC secrets, 2 x 16 byte IVs */ - {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes256, mac_sha, 136}, - - {SSL_RSA_WITH_NULL_SHA, cipher_null, mac_sha, 40} -}; - -static int cipher_suite_defs_nentries = - sizeof (cipher_suite_defs) / sizeof (cipher_suite_defs[0]); - -static void KSSL_SHA1Update(void *, uchar_t *, uint32_t); - -static KSSLMACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ - /* macsz padsz HashInit HashUpdate HashFinal */ - - { - .hashsz = MD5_HASH_LEN, - .padsz = SSL3_MD5_PAD_LEN, - .HashInit = (hashinit_func_t)MD5Init, - .HashUpdate = (hashupdate_func_t)MD5Update, - .HashFinal = (hashfinal_func_t)MD5Final - }, - { - .hashsz = SHA1_HASH_LEN, - .padsz = SSL3_SHA1_PAD_LEN, - .HashInit = (hashinit_func_t)SHA1Init, - .HashUpdate = KSSL_SHA1Update, - .HashFinal = (hashfinal_func_t)SHA1Final - } -}; - -static uchar_t kssl_pad_1[60] = { - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36 -}; -static uchar_t kssl_pad_2[60] = { - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c -}; - -static boolean_t kssl_synchronous = B_FALSE; - -static void kssl_update_handshake_hashes(ssl_t *, uchar_t *, uint_t); -static int kssl_compute_handshake_hashes(ssl_t *, SSL3Hashes *, uint32_t); -static int kssl_handle_client_hello(ssl_t *, mblk_t *, int); -static int kssl_handle_client_key_exchange(ssl_t *, mblk_t *, int, - kssl_callback_t, void *); -static int kssl_send_server_hello(ssl_t *); -static int kssl_send_certificate_and_server_hello_done(ssl_t *); -static int kssl_send_change_cipher_specs(ssl_t *); -static int kssl_send_finished(ssl_t *, int); -static int kssl_handle_finished(ssl_t *, mblk_t *, int); -static void kssl_get_hello_random(uchar_t *); -static uchar_t *kssl_rsa_unwrap(uchar_t *, size_t *); -static void kssl_cache_sid(sslSessionID *, kssl_entry_t *); -static void kssl_lookup_sid(sslSessionID *, uchar_t *, in6_addr_t *, - kssl_entry_t *); -static int kssl_generate_tls_ms(ssl_t *, uchar_t *, size_t); -static void kssl_generate_ssl_ms(ssl_t *, uchar_t *, size_t); -static int kssl_generate_tls_keyblock(ssl_t *); -static void kssl_generate_keyblock(ssl_t *); -static void kssl_ssl3_key_material_derive_step(ssl_t *, uchar_t *, size_t, - int, uchar_t *, int); -static int kssl_tls_PRF(ssl_t *, uchar_t *, size_t, - uchar_t *, size_t, uchar_t *, size_t, uchar_t *, size_t); -static int kssl_tls_P_hash(crypto_mechanism_t *, crypto_key_t *, - size_t, uchar_t *, size_t, uchar_t *, size_t, uchar_t *, size_t); -static void kssl_cke_done(void *, int); - -#define HMAC_INIT(m, k, c) \ - rv = crypto_mac_init(m, k, NULL, c, NULL); if (CRYPTO_ERR(rv)) goto end; - -#define HMAC_UPDATE(c, d, l) \ - dd.cd_raw.iov_base = (char *)d; \ - dd.cd_length = dd.cd_raw.iov_len = l; \ - rv = crypto_mac_update(c, &dd, NULL); if (CRYPTO_ERR(rv)) goto end; - -#define HMAC_FINAL(c, d, l) \ - mac.cd_raw.iov_base = (char *)d; \ - mac.cd_length = mac.cd_raw.iov_len = l; \ - rv = crypto_mac_final(c, &mac, NULL); if (CRYPTO_ERR(rv)) goto end; - -/* - * Wrapper for SHA1Update to translate arguments. We need this because - * the KSSL hash update function expects the size argument to be a - * uint32_t, but SHA1Update uses a size_t. - */ -static void -KSSL_SHA1Update(void *ctx, uchar_t *in, uint32_t size) -{ - SHA1Update(ctx, in, size); -} - -/* - * This hack can go away once we have SSL3 MAC support by KCF - * software providers (See 4873559). - */ -extern int kcf_md5_threshold; - -int -kssl_compute_record_mac( - ssl_t *ssl, - int direction, - uint64_t seq_num, - SSL3ContentType ct, - uchar_t *versionp, - uchar_t *buf, - int len, - uchar_t *digest) -{ - KSSL_HASHCTX mac_ctx; - KSSL_HASHCTX *ctx = &mac_ctx; - uchar_t temp[16], *p; - KSSLCipherSpec *spec; - boolean_t hash_use_ok = B_FALSE; - int rv = 0; - - spec = &ssl->spec[direction]; - - if (spec->mac_hashsz == 0) { - return (1); - } - - p = temp; - - *p++ = (seq_num >> 56) & 0xff; - *p++ = (seq_num >> 48) & 0xff; - *p++ = (seq_num >> 40) & 0xff; - *p++ = (seq_num >> 32) & 0xff; - *p++ = (seq_num >> 24) & 0xff; - *p++ = (seq_num >> 16) & 0xff; - *p++ = (seq_num >> 8) & 0xff; - *p++ = (seq_num) & 0xff; - *p++ = (uchar_t)ct; - if (IS_TLS(ssl)) { - *p++ = versionp[0]; - *p++ = versionp[1]; - } - *p++ = (len >> 8) & 0xff; - *p++ = (len) & 0xff; - - if (IS_TLS(ssl) || (spec->hmac_mech.cm_type != CRYPTO_MECH_INVALID && - len >= kcf_md5_threshold)) { - crypto_data_t dd, mac; - struct uio uio_pt; - struct iovec iovarray_pt[2]; - - /* init the array of iovecs for use in the uio struct */ - iovarray_pt[0].iov_base = (char *)temp; - iovarray_pt[0].iov_len = (p - temp); - iovarray_pt[1].iov_base = (char *)buf; - iovarray_pt[1].iov_len = len; - - /* init the uio struct for use in the crypto_data_t struct */ - bzero(&uio_pt, sizeof (uio_pt)); - uio_pt.uio_iov = iovarray_pt; - uio_pt.uio_iovcnt = 2; - uio_pt.uio_segflg = UIO_SYSSPACE; - - dd.cd_format = CRYPTO_DATA_UIO; - dd.cd_offset = 0; - dd.cd_length = (p - temp) + len; - dd.cd_miscdata = NULL; - dd.cd_uio = &uio_pt; - - mac.cd_format = CRYPTO_DATA_RAW; - mac.cd_offset = 0; - mac.cd_raw.iov_base = (char *)digest; - mac.cd_length = mac.cd_raw.iov_len = spec->mac_hashsz; - - /* - * The calling context can tolerate a blocking call here. - * For outgoing traffic, we are in user context when called - * from kssl_data_out_cb(). For incoming traffic past the - * SSL handshake, we are in user context when called from - * kssl_data_in_proc_cb(). During the SSL handshake, we are - * called for client_finished message handling from a taskq - * thread. - */ - rv = crypto_mac(&spec->hmac_mech, &dd, &spec->hmac_key, - NULL, &mac, NULL); - - if (CRYPTO_ERR(rv)) { - hash_use_ok = (rv == CRYPTO_MECH_NOT_SUPPORTED && - !IS_TLS(ssl)); - if (!hash_use_ok) { - DTRACE_PROBE1(kssl_err__crypto_mac_error, - int, rv); - KSSL_COUNTER(compute_mac_failure, 1); - } - } - } else - hash_use_ok = B_TRUE; - - if (hash_use_ok) { - bcopy(&(ssl->mac_ctx[direction][0]), ctx, - sizeof (KSSL_HASHCTX)); - spec->MAC_HashUpdate((void *)ctx, temp, p - temp); - spec->MAC_HashUpdate((void *)ctx, buf, len); - spec->MAC_HashFinal(digest, (void *)ctx); - - bcopy(&(ssl->mac_ctx[direction][1]), ctx, - sizeof (KSSL_HASHCTX)); - spec->MAC_HashUpdate((void *)ctx, digest, spec->mac_hashsz); - spec->MAC_HashFinal(digest, (void *)ctx); - } - - return (rv); -} - -/* - * Handles handshake messages. - * Messages to be replied are returned in handshake_sendbuf. - */ -int -kssl_handle_handshake_message(ssl_t *ssl, mblk_t *mp, int *err, - kssl_callback_t cbfn, void *arg) -{ - uint32_t msglen; - uchar_t msghdr[4]; - - ASSERT(ssl->msg.state == MSG_BODY); - ASSERT(ssl->msg.msglen_bytes == 3); - ASSERT(mp->b_wptr >= mp->b_rptr + ssl->msg.msglen); - - ssl->sslcnt++; - msglen = ssl->msg.msglen; - - if (ssl->msg.type == client_hello) { - MD5Init(&ssl->hs_md5); - SHA1Init(&ssl->hs_sha1); - } - - if (ssl->msg.type == finished && ssl->resumed == B_FALSE) { - if (kssl_compute_handshake_hashes(ssl, &ssl->hs_hashes, - sender_client) != 0) { - *err = SSL_MISS; - return (0); - } - } - - if (ssl->msg.type != finished || ssl->resumed == B_FALSE) { - msghdr[0] = (uchar_t)ssl->msg.type; - - msghdr[1] = (uchar_t)(msglen >> 16); - msghdr[2] = (uchar_t)(msglen >> 8); - msghdr[3] = (uchar_t)(msglen); - kssl_update_handshake_hashes(ssl, msghdr, 4); - kssl_update_handshake_hashes(ssl, mp->b_rptr, msglen); - } - - ssl->msg.state = MSG_INIT; - ssl->msg.msglen = 0; - ssl->msg.msglen_bytes = 0; - - switch (ssl->msg.type) { - case client_hello: - if (ssl->hs_waitstate != wait_client_hello) { - kssl_send_alert(ssl, alert_fatal, - unexpected_message); - *err = EBADMSG; - ssl->activeinput = B_FALSE; - return (1); - } - *err = kssl_handle_client_hello(ssl, mp, msglen); - if (*err == SSL_MISS) { - ssl->activeinput = B_FALSE; - return (0); - } - return (1); - case client_key_exchange: - if (ssl->hs_waitstate != wait_client_key) { - kssl_send_alert(ssl, alert_fatal, - unexpected_message); - *err = EBADMSG; - ssl->activeinput = B_FALSE; - return (1); - } - *err = kssl_handle_client_key_exchange(ssl, mp, - msglen, cbfn, arg); - return (1); - case finished: - if (ssl->hs_waitstate != wait_finished) { - kssl_send_alert(ssl, alert_fatal, - unexpected_message); - *err = EBADMSG; - ssl->activeinput = B_FALSE; - return (1); - } - *err = kssl_handle_finished(ssl, mp, msglen); - return (1); - default: - kssl_send_alert(ssl, alert_fatal, unexpected_message); - ssl->activeinput = B_FALSE; - *err = EBADMSG; - return (1); - } -} - -static void -kssl_update_handshake_hashes(ssl_t *ssl, uchar_t *buf, uint_t len) -{ - MD5Update(&ssl->hs_md5, buf, len); - SHA1Update(&ssl->hs_sha1, buf, len); -} - -static int -kssl_compute_handshake_hashes( - ssl_t *ssl, - SSL3Hashes *hashes, - uint32_t sender) -{ - MD5_CTX md5 = ssl->hs_md5; /* clone md5 context */ - SHA1_CTX sha1 = ssl->hs_sha1; /* clone sha1 context */ - MD5_CTX *md5ctx = &md5; - SHA1_CTX *sha1ctx = &sha1; - - if (IS_TLS(ssl)) { - uchar_t seed[MD5_HASH_LEN + SHA1_HASH_LEN]; - char *label; - - /* - * Do not take another hash step here. - * Just complete the operation. - */ - MD5Final(hashes->md5, md5ctx); - SHA1Final(hashes->sha1, sha1ctx); - - bcopy(hashes->md5, seed, MD5_HASH_LEN); - bcopy(hashes->sha1, seed + MD5_HASH_LEN, SHA1_HASH_LEN); - - if (sender == sender_client) - label = TLS_CLIENT_FINISHED_LABEL; - else - label = TLS_SERVER_FINISHED_LABEL; - - return (kssl_tls_PRF(ssl, - ssl->sid.master_secret, - (size_t)SSL3_MASTER_SECRET_LEN, - (uchar_t *)label, strlen(label), - seed, (size_t)(MD5_HASH_LEN + SHA1_HASH_LEN), - hashes->tlshash, (size_t)TLS_FINISHED_SIZE)); - } else { - uchar_t s[4]; - s[0] = (sender >> 24) & 0xff; - s[1] = (sender >> 16) & 0xff; - s[2] = (sender >> 8) & 0xff; - s[3] = (sender) & 0xff; - - MD5Update(md5ctx, s, 4); - MD5Update(md5ctx, ssl->sid.master_secret, - SSL3_MASTER_SECRET_LEN); - MD5Update(md5ctx, kssl_pad_1, SSL3_MD5_PAD_LEN); - MD5Final(hashes->md5, md5ctx); - - MD5Init(md5ctx); - MD5Update(md5ctx, ssl->sid.master_secret, - SSL3_MASTER_SECRET_LEN); - MD5Update(md5ctx, kssl_pad_2, SSL3_MD5_PAD_LEN); - MD5Update(md5ctx, hashes->md5, MD5_HASH_LEN); - MD5Final(hashes->md5, md5ctx); - - SHA1Update(sha1ctx, s, 4); - SHA1Update(sha1ctx, ssl->sid.master_secret, - SSL3_MASTER_SECRET_LEN); - SHA1Update(sha1ctx, kssl_pad_1, SSL3_SHA1_PAD_LEN); - SHA1Final(hashes->sha1, sha1ctx); - - SHA1Init(sha1ctx); - SHA1Update(sha1ctx, ssl->sid.master_secret, - SSL3_MASTER_SECRET_LEN); - SHA1Update(sha1ctx, kssl_pad_2, SSL3_SHA1_PAD_LEN); - SHA1Update(sha1ctx, hashes->sha1, SHA1_HASH_LEN); - SHA1Final(hashes->sha1, sha1ctx); - return (0); - } -} - - -/* - * Minimum message length for a client hello = - * 2-byte client_version + - * 32-byte random + - * 1-byte session_id length + - * 2-byte cipher_suites length + - * 1-byte compression_methods length + - * 1-byte CompressionMethod.null - */ -#define KSSL_SSL3_CH_MIN_MSGLEN (39) - -/* - * Process SSL/TLS Client Hello message. Return 0 on success, errno value - * or SSL_MISS if no cipher suite of the server matches the list received - * in the message. - */ -static int -kssl_handle_client_hello(ssl_t *ssl, mblk_t *mp, int msglen) -{ - uchar_t *msgend; - int err; - SSL3AlertDescription desc = illegal_parameter; - uint_t sidlen, cslen, cmlen; - uchar_t *suitesp; - uint_t i, j; - uint16_t suite, selected_suite; - int ch_msglen = KSSL_SSL3_CH_MIN_MSGLEN; - boolean_t suite_found = B_FALSE; - - ASSERT(mp->b_wptr >= mp->b_rptr + msglen); - ASSERT(ssl->msg.type == client_hello); - ASSERT(ssl->hs_waitstate == wait_client_hello); - ASSERT(ssl->resumed == B_FALSE); - - if (msglen < ch_msglen) { - DTRACE_PROBE2(kssl_err__msglen_less_than_minimum, - int, msglen, int, ch_msglen); - goto falert; - } - - msgend = mp->b_rptr + msglen; - - /* Support SSLv3 (version == 3.0) or TLS (version == 3.1) */ - if (ssl->major_version != 3 || (ssl->major_version == 3 && - ssl->minor_version != 0 && ssl->minor_version != 1)) { - DTRACE_PROBE2(kssl_err__SSL_version_not_supported, - uchar_t, ssl->major_version, - uchar_t, ssl->minor_version); - desc = handshake_failure; - goto falert; - } - mp->b_rptr += 2; /* skip the version bytes */ - - /* read client random field */ - bcopy(mp->b_rptr, ssl->client_random, SSL3_RANDOM_LENGTH); - mp->b_rptr += SSL3_RANDOM_LENGTH; - - /* read session ID length */ - ASSERT(ssl->sid.cached == B_FALSE); - sidlen = *mp->b_rptr++; - ch_msglen += sidlen; - if (msglen < ch_msglen) { - DTRACE_PROBE2(kssl_err__invalid_message_length_after_ver, - int, msglen, int, ch_msglen); - goto falert; - } - if (sidlen != SSL3_SESSIONID_BYTES) { - mp->b_rptr += sidlen; - } else { - kssl_lookup_sid(&ssl->sid, mp->b_rptr, &ssl->faddr, - ssl->kssl_entry); - mp->b_rptr += SSL3_SESSIONID_BYTES; - } - - /* read cipher suite length */ - cslen = ((uint_t)mp->b_rptr[0] << 8) + (uint_t)mp->b_rptr[1]; - mp->b_rptr += 2; - ch_msglen += cslen; - - /* - * This check can't be a "!=" since there can be - * compression methods other than CompressionMethod.null. - * Also, there can be extra data (TLS extensions) after the - * compression methods field. - */ - if (msglen < ch_msglen) { - DTRACE_PROBE2(kssl_err__invalid_message_length_after_cslen, - int, msglen, int, ch_msglen); - goto falert; - } - - /* The length has to be even since a cipher suite is 2-byte long. */ - if (cslen & 0x1) { - DTRACE_PROBE1(kssl_err__uneven_cipher_suite_length, - uint_t, cslen); - goto falert; - } - suitesp = mp->b_rptr; - - /* session resumption checks */ - if (ssl->sid.cached == B_TRUE) { - suite = ssl->sid.cipher_suite; - for (j = 0; j < cslen; j += 2) { - DTRACE_PROBE2(kssl_cipher_suite_check_resumpt, - uint16_t, suite, - uint16_t, - (uint16_t)((suitesp[j] << 8) + suitesp[j+1])); - /* Check for regular (true) cipher suite. */ - if (suitesp[j] == ((suite >> 8) & 0xff) && - suitesp[j + 1] == (suite & 0xff)) { - DTRACE_PROBE1(kssl_cipher_suite_found_resumpt, - uint16_t, suite); - suite_found = B_TRUE; - selected_suite = suite; - } - - /* Check for SCSV. */ - if (suitesp[j] == ((SSL_SCSV >> 8) & 0xff) && - suitesp[j + 1] == (SSL_SCSV & 0xff)) { - DTRACE_PROBE(kssl_scsv_found_resumpt); - ssl->secure_renegotiation = B_TRUE; - } - - /* - * If we got cipher suite match and SCSV we can - * terminate the cycle now. - */ - if (suite_found && ssl->secure_renegotiation) - break; - } - if (suite_found) - goto suite_found; - kssl_uncache_sid(&ssl->sid, ssl->kssl_entry); - } - - /* Check if this server is capable of the cipher suite. */ - for (i = 0; i < ssl->kssl_entry->kssl_cipherSuites_nentries; i++) { - suite = ssl->kssl_entry->kssl_cipherSuites[i]; - for (j = 0; j < cslen; j += 2) { - DTRACE_PROBE2(kssl_cipher_suite_check, uint16_t, suite, - uint16_t, - (uint16_t)((suitesp[j] << 8) + suitesp[j+1])); - /* Check for regular (true) cipher suite. */ - if (suitesp[j] == ((suite >> 8) & 0xff) && - suitesp[j + 1] == (suite & 0xff)) { - DTRACE_PROBE1(kssl_cipher_suite_found, - uint16_t, suite); - suite_found = B_TRUE; - selected_suite = suite; - } - - /* Check for SCSV. */ - if (suitesp[j] == ((SSL_SCSV >> 8) & 0xff) && - suitesp[j + 1] == (SSL_SCSV & 0xff)) { - DTRACE_PROBE(kssl_scsv_found); - ssl->secure_renegotiation = B_TRUE; - } - - /* - * If we got cipher suite match and SCSV or went - * through the whole list of client cipher suites - * (hence we know if SCSV was present or not) we - * can terminate the cycle now. - */ - if (suite_found && - (ssl->secure_renegotiation || (i > 0))) - break; - } - if (suite_found) - break; - } - if (!suite_found) { - if (ssl->sslcnt == 1) { - DTRACE_PROBE(kssl_no_cipher_suite_found); - KSSL_COUNTER(no_suite_found, 1); - /* - * If there is no fallback point terminate the - * handshake with SSL alert otherwise return with - * SSL_MISS. - */ - if (ssl->kssl_entry->ke_fallback_head == NULL) { - DTRACE_PROBE(kssl_no_fallback); - desc = handshake_failure; - goto falert; - } else { - return (SSL_MISS); - } - } - desc = handshake_failure; - DTRACE_PROBE(kssl_err__no_cipher_suites_found); - goto falert; - } - -suite_found: - mp->b_rptr += cslen; - - /* - * Check for the mandatory CompressionMethod.null. We do not - * support any other compression methods. - */ - cmlen = *mp->b_rptr++; - ch_msglen += cmlen - 1; /* -1 accounts for the null method */ - if (msglen < ch_msglen) { - DTRACE_PROBE2(kssl_err__invalid_message_length_after_complen, - int, msglen, int, ch_msglen); - goto falert; - } - - /* - * Search for null compression method (encoded as 0 byte) in the - * compression methods field. - */ - while (cmlen >= 1) { - if (*mp->b_rptr++ == 0) - break; - cmlen--; - } - - if (cmlen == 0) { - desc = handshake_failure; - DTRACE_PROBE(kssl_err__no_null_compression_method); - goto falert; - } - - /* Find the suite in the internal cipher suite table. */ - for (i = 0; i < cipher_suite_defs_nentries; i++) { - if (selected_suite == cipher_suite_defs[i].suite) { - break; - } - } - - /* Get past the remaining compression methods (minus null method). */ - mp->b_rptr += cmlen - 1; - - ASSERT(i < cipher_suite_defs_nentries); - - ssl->pending_cipher_suite = selected_suite; - ssl->pending_malg = cipher_suite_defs[i].malg; - ssl->pending_calg = cipher_suite_defs[i].calg; - ssl->pending_keyblksz = cipher_suite_defs[i].keyblksz; - - /* Parse TLS extensions (if any). */ - if (ch_msglen + 2 < msglen) { - /* Get the length of the extensions. */ - uint16_t ext_total_len = ((uint_t)mp->b_rptr[0] << 8) + - (uint_t)mp->b_rptr[1]; - DTRACE_PROBE1(kssl_total_length_extensions, uint16_t, - ext_total_len); - /* - * Consider zero extensions length as invalid extension - * encoding. - */ - if (ext_total_len == 0) { - DTRACE_PROBE1(kssl_err__zero_extensions_length, - mblk_t *, mp); - goto falert; - } - ch_msglen += 2; - if (ch_msglen + ext_total_len > msglen) { - DTRACE_PROBE2(kssl_err__invalid_extensions_length, - int, msglen, int, ch_msglen); - goto falert; - } - mp->b_rptr += 2; - - /* - * Go through the TLS extensions. This is only done to check - * for the presence of renegotiation_info extension. We do not - * support any other TLS extensions and hence ignore them. - */ - while (mp->b_rptr < msgend) { - uint16_t ext_len, ext_type; - - /* - * Check that the extension has at least type and - * length (2 + 2 bytes). - */ - if (ch_msglen + 4 > msglen) { - DTRACE_PROBE(kssl_err__invalid_ext_format); - goto falert; - } - - /* Get extension type and length */ - ext_type = ((uint_t)mp->b_rptr[0] << 8) + - (uint_t)mp->b_rptr[1]; - mp->b_rptr += 2; - ext_len = ((uint_t)mp->b_rptr[0] << 8) + - (uint_t)mp->b_rptr[1]; - mp->b_rptr += 2; - ch_msglen += 4; - DTRACE_PROBE3(kssl_ext_detected, uint16_t, ext_type, - uint16_t, ext_len, mblk_t *, mp); - - /* - * Make sure the contents of the extension are - * accessible. - */ - if (ch_msglen + ext_len > msglen) { - DTRACE_PROBE1( - kssl_err__invalid_ext_len, - uint16_t, ext_len); - goto falert; - } - - switch (ext_type) { - case TLSEXT_RENEGOTIATION_INFO: - /* - * Search for empty "renegotiation_info" - * extension (encoded as ff 01 00 01 00). - */ - DTRACE_PROBE(kssl_reneg_info_found); - if ((ext_len != 1) || - (*mp->b_rptr != 0)) { - DTRACE_PROBE2( - kssl_err__non_empty_reneg_info, - uint16_t, ext_len, - mblk_t *, mp); - goto falert; - } - ssl->secure_renegotiation = B_TRUE; - break; - default: - /* FALLTHRU */ - break; - } - - /* jump to the next extension */ - ch_msglen += ext_len; - mp->b_rptr += ext_len; - } - } - - mp->b_rptr = msgend; - - if (ssl->sid.cached == B_TRUE) { - err = kssl_send_server_hello(ssl); - if (err != 0) { - return (err); - } - if (IS_TLS(ssl)) - err = kssl_generate_tls_keyblock(ssl); - else - kssl_generate_keyblock(ssl); - - err = kssl_send_change_cipher_specs(ssl); - if (err != 0) { - return (err); - } - - err = kssl_send_finished(ssl, 1); - if (err != 0) - return (err); - - err = kssl_compute_handshake_hashes(ssl, &ssl->hs_hashes, - sender_client); - if (err != 0) - return (err); - - ssl->hs_waitstate = wait_change_cipher; - ssl->resumed = B_TRUE; - ssl->activeinput = B_FALSE; - KSSL_COUNTER(resumed_sessions, 1); - return (0); - } - - (void) random_get_pseudo_bytes(ssl->sid.session_id, - SSL3_SESSIONID_BYTES); - ssl->sid.client_addr = ssl->faddr; - ssl->sid.cipher_suite = selected_suite; - - err = kssl_send_server_hello(ssl); - if (err != 0) { - return (err); - } - err = kssl_send_certificate_and_server_hello_done(ssl); - if (err != 0) { - return (err); - } - KSSL_COUNTER(full_handshakes, 1); - ssl->hs_waitstate = wait_client_key; - ssl->activeinput = B_FALSE; - return (0); - -falert: - kssl_send_alert(ssl, alert_fatal, desc); - return (EBADMSG); -} - -#define SET_HASH_INDEX(index, s, clnt_addr) { \ - int addr; \ - \ - IN6_V4MAPPED_TO_IPADDR(clnt_addr, addr); \ - index = addr ^ (((int)(s)[0] << 24) | ((int)(s)[1] << 16) | \ - ((int)(s)[2] << 8) | (int)(s)[SSL3_SESSIONID_BYTES - 1]); \ -} - -/* - * Creates a cache entry. Sets the sid->cached flag - * and sid->time fields. So, the caller should not set them. - */ -static void -kssl_cache_sid(sslSessionID *sid, kssl_entry_t *kssl_entry) -{ - uint_t index; - uchar_t *s = sid->session_id; - kmutex_t *lock; - - ASSERT(sid->cached == B_FALSE); - - /* set the values before creating the cache entry */ - sid->cached = B_TRUE; - sid->time = ddi_get_lbolt(); - - SET_HASH_INDEX(index, s, &sid->client_addr); - index %= kssl_entry->sid_cache_nentries; - - lock = &(kssl_entry->sid_cache[index].se_lock); - mutex_enter(lock); - kssl_entry->sid_cache[index].se_used++; - bcopy(sid, &(kssl_entry->sid_cache[index].se_sid), sizeof (*sid)); - mutex_exit(lock); - - KSSL_COUNTER(sid_cached, 1); -} - -/* - * Invalidates the cache entry, if any. Clears the sid->cached flag - * as a side effect. - */ -void -kssl_uncache_sid(sslSessionID *sid, kssl_entry_t *kssl_entry) -{ - uint_t index; - uchar_t *s = sid->session_id; - sslSessionID *csid; - kmutex_t *lock; - - ASSERT(sid->cached == B_TRUE); - sid->cached = B_FALSE; - - SET_HASH_INDEX(index, s, &sid->client_addr); - index %= kssl_entry->sid_cache_nentries; - - lock = &(kssl_entry->sid_cache[index].se_lock); - mutex_enter(lock); - csid = &(kssl_entry->sid_cache[index].se_sid); - if (!(IN6_ARE_ADDR_EQUAL(&csid->client_addr, &sid->client_addr)) || - bcmp(csid->session_id, s, SSL3_SESSIONID_BYTES)) { - mutex_exit(lock); - return; - } - csid->cached = B_FALSE; - mutex_exit(lock); - - KSSL_COUNTER(sid_uncached, 1); -} - -static void -kssl_lookup_sid(sslSessionID *sid, uchar_t *s, in6_addr_t *faddr, - kssl_entry_t *kssl_entry) -{ - uint_t index; - kmutex_t *lock; - sslSessionID *csid; - - KSSL_COUNTER(sid_cache_lookups, 1); - - SET_HASH_INDEX(index, s, faddr); - index %= kssl_entry->sid_cache_nentries; - - lock = &(kssl_entry->sid_cache[index].se_lock); - mutex_enter(lock); - csid = &(kssl_entry->sid_cache[index].se_sid); - if (csid->cached == B_FALSE || - !IN6_ARE_ADDR_EQUAL(&csid->client_addr, faddr) || - bcmp(csid->session_id, s, SSL3_SESSIONID_BYTES)) { - mutex_exit(lock); - return; - } - - if (TICK_TO_SEC(ddi_get_lbolt() - csid->time) > - kssl_entry->sid_cache_timeout) { - csid->cached = B_FALSE; - mutex_exit(lock); - return; - } - - bcopy(csid, sid, sizeof (*sid)); - mutex_exit(lock); - ASSERT(sid->cached == B_TRUE); - - KSSL_COUNTER(sid_cache_hits, 1); -} - -static uchar_t * -kssl_rsa_unwrap(uchar_t *buf, size_t *lenp) -{ - size_t len = *lenp; - int i = 2; - - if (buf[0] != 0 || buf[1] != 2) { - return (NULL); - } - - while (i < len) { - if (buf[i++] == 0) { - *lenp = len - i; - break; - } - } - - if (i == len) { - return (NULL); - } - - return (buf + i); -} - - -#define KSSL_SSL3_SH_RECLEN (74) -#define KSSL_SSL3_FIN_MSGLEN (36) -#define KSSL_EMPTY_RENEG_INFO_LEN (7) - -#define KSSL_SSL3_MAX_CCP_FIN_MSGLEN (128) /* comfortable upper bound */ - -/* - * Send ServerHello record to the client. - */ -static int -kssl_send_server_hello(ssl_t *ssl) -{ - mblk_t *mp; - uchar_t *buf; - uchar_t *msgstart; - uint16_t reclen = KSSL_SSL3_SH_RECLEN; - - mp = allocb(ssl->tcp_mss, BPRI_HI); - if (mp == NULL) { - KSSL_COUNTER(alloc_fails, 1); - return (ENOMEM); - } - ssl->handshake_sendbuf = mp; - buf = mp->b_wptr; - - if (ssl->secure_renegotiation) - reclen += KSSL_EMPTY_RENEG_INFO_LEN; - - /* 5 byte record header */ - buf[0] = content_handshake; - buf[1] = ssl->major_version; - buf[2] = ssl->minor_version; - buf[3] = reclen >> 8; - buf[4] = reclen & 0xff; - buf += SSL3_HDR_LEN; - - msgstart = buf; - - /* 6 byte message header */ - buf[0] = (uchar_t)server_hello; /* message type */ - buf[1] = 0; /* message len byte 0 */ - buf[2] = ((reclen - 4) >> 8) & - 0xff; /* message len byte 1 */ - buf[3] = (reclen - 4) & 0xff; /* message len byte 2 */ - - buf[4] = ssl->major_version; /* version byte 0 */ - buf[5] = ssl->minor_version; /* version byte 1 */ - - buf += 6; - - kssl_get_hello_random(ssl->server_random); - bcopy(ssl->server_random, buf, SSL3_RANDOM_LENGTH); - buf += SSL3_RANDOM_LENGTH; - - buf[0] = SSL3_SESSIONID_BYTES; - bcopy(ssl->sid.session_id, buf + 1, SSL3_SESSIONID_BYTES); - buf += SSL3_SESSIONID_BYTES + 1; - - buf[0] = (ssl->pending_cipher_suite >> 8) & 0xff; - buf[1] = ssl->pending_cipher_suite & 0xff; - - buf[2] = 0; /* No compression */ - buf += 3; - - /* - * Add "renegotiation_info" extension if the ClientHello message - * contained either SCSV value in cipher suite list or - * "renegotiation_info" extension. This is per RFC 5746, section 3.6. - */ - if (ssl->secure_renegotiation) { - /* Extensions length */ - buf[0] = 0x00; - buf[1] = 0x05; - /* empty renegotiation_info extension encoding (section 3.2) */ - buf[2] = 0xff; - buf[3] = 0x01; - buf[4] = 0x00; - buf[5] = 0x01; - buf[6] = 0x00; - buf += KSSL_EMPTY_RENEG_INFO_LEN; - } - - mp->b_wptr = buf; - ASSERT(mp->b_wptr < mp->b_datap->db_lim); - - kssl_update_handshake_hashes(ssl, msgstart, reclen); - return (0); -} - -static void -kssl_get_hello_random(uchar_t *buf) -{ - timestruc_t ts; - time_t sec; - - gethrestime(&ts); - sec = ts.tv_sec; - - buf[0] = (sec >> 24) & 0xff; - buf[1] = (sec >> 16) & 0xff; - buf[2] = (sec >> 8) & 0xff; - buf[3] = (sec) & 0xff; - - (void) random_get_pseudo_bytes(&buf[4], SSL3_RANDOM_LENGTH - 4); - - /* Should this be caching? */ -} - -static int -kssl_tls_P_hash(crypto_mechanism_t *mech, crypto_key_t *key, size_t hashlen, - uchar_t *label, size_t label_len, uchar_t *seed, size_t seedlen, - uchar_t *data, size_t datalen) -{ - int rv = 0; - uchar_t A1[MAX_HASH_LEN], result[MAX_HASH_LEN]; - int bytes_left = (int)datalen; - crypto_data_t dd, mac; - crypto_context_t ctx; - - dd.cd_format = CRYPTO_DATA_RAW; - dd.cd_offset = 0; - mac.cd_format = CRYPTO_DATA_RAW; - mac.cd_offset = 0; - - /* - * A(i) = HMAC_hash(secret, seed + A(i-1)); - * A(0) = seed; - * - * Compute A(1): - * A(1) = HMAC_hash(secret, label + seed) - * - */ - HMAC_INIT(mech, key, &ctx); - HMAC_UPDATE(ctx, label, label_len); - HMAC_UPDATE(ctx, seed, seedlen); - HMAC_FINAL(ctx, A1, hashlen); - - /* Compute A(2) ... A(n) */ - while (bytes_left > 0) { - HMAC_INIT(mech, key, &ctx); - HMAC_UPDATE(ctx, A1, hashlen); - HMAC_UPDATE(ctx, label, label_len); - HMAC_UPDATE(ctx, seed, seedlen); - HMAC_FINAL(ctx, result, hashlen); - - /* - * The A(i) value is stored in "result". - * Save the results of the MAC so it can be input to next - * iteration. - */ - if (bytes_left > hashlen) { - /* Store the chunk result */ - bcopy(result, data, hashlen); - data += hashlen; - - bytes_left -= hashlen; - - /* Update A1 for next iteration */ - HMAC_INIT(mech, key, &ctx); - HMAC_UPDATE(ctx, A1, hashlen); - HMAC_FINAL(ctx, A1, hashlen); - - } else { - bcopy(result, data, bytes_left); - data += bytes_left; - bytes_left = 0; - } - } -end: - if (CRYPTO_ERR(rv)) { - DTRACE_PROBE1(kssl_err__crypto_mac_error, int, rv); - KSSL_COUNTER(compute_mac_failure, 1); - } - return (rv); -} - -/* ARGSUSED */ -static int -kssl_tls_PRF(ssl_t *ssl, uchar_t *secret, size_t secret_len, uchar_t *label, - size_t label_len, uchar_t *seed, size_t seed_len, uchar_t *prfresult, - size_t prfresult_len) -{ - /* - * RFC 2246: - * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR - * P_SHA1(S2, label + seed); - * S1 = 1st half of secret. - * S1 = 2nd half of secret. - * - */ - - int rv, i; - uchar_t psha1[MAX_KEYBLOCK_LENGTH]; - crypto_key_t S1, S2; - - /* length of secret keys is ceil(length/2) */ - size_t slen = roundup(secret_len, 2) / 2; - - if (prfresult_len > MAX_KEYBLOCK_LENGTH) { - DTRACE_PROBE1(kssl_err__unexpected_keyblock_size, - size_t, prfresult_len); - return (CRYPTO_ARGUMENTS_BAD); - } - - ASSERT(prfresult != NULL); - ASSERT(label != NULL); - ASSERT(seed != NULL); - - S1.ck_data = secret; - S1.ck_length = slen * 8; /* bits */ - S1.ck_format = CRYPTO_KEY_RAW; - - S2.ck_data = secret + slen; - S2.ck_length = slen * 8; /* bits */ - S2.ck_format = CRYPTO_KEY_RAW; - - rv = kssl_tls_P_hash(&hmac_md5_mech, &S1, MD5_HASH_LEN, - label, label_len, - seed, seed_len, - prfresult, prfresult_len); - if (CRYPTO_ERR(rv)) - goto end; - - rv = kssl_tls_P_hash(&hmac_sha1_mech, &S2, SHA1_HASH_LEN, - label, label_len, - seed, seed_len, - psha1, prfresult_len); - if (CRYPTO_ERR(rv)) - goto end; - - for (i = 0; i < prfresult_len; i++) - prfresult[i] ^= psha1[i]; - -end: - if (CRYPTO_ERR(rv)) - bzero(prfresult, prfresult_len); - - return (rv); -} - -#define IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl) \ - (pms == NULL || pmslen != SSL3_PRE_MASTER_SECRET_LEN || \ - pms[0] != ssl->major_version || pms[1] != ssl->minor_version) - -#define FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf) { \ - KSSL_COUNTER(bad_pre_master_secret, 1); \ - pms = buf; \ - pmslen = SSL3_PRE_MASTER_SECRET_LEN; \ - pms[0] = ssl->major_version; \ - pms[1] = ssl->minor_version; \ - (void) random_get_pseudo_bytes(&buf[2], pmslen - 2); \ -} - -static int -kssl_generate_tls_ms(ssl_t *ssl, uchar_t *pms, size_t pmslen) -{ - uchar_t buf[SSL3_PRE_MASTER_SECRET_LEN]; - uchar_t seed[SSL3_RANDOM_LENGTH * 2]; - - /* - * Computing the master secret: - * ---------------------------- - * master_secret = PRF (pms, "master secret", - * ClientHello.random + ServerHello.random); - */ - bcopy(ssl->client_random, seed, SSL3_RANDOM_LENGTH); - bcopy(ssl->server_random, seed + SSL3_RANDOM_LENGTH, - SSL3_RANDOM_LENGTH); - - /* if pms is bad fake it to thwart Bleichenbacher attack */ - if (IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl)) { - DTRACE_PROBE(kssl_err__under_Bleichenbacher_attack); - FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf); - } - - return (kssl_tls_PRF(ssl, - pms, pmslen, - (uchar_t *)TLS_MASTER_SECRET_LABEL, - (size_t)strlen(TLS_MASTER_SECRET_LABEL), - seed, sizeof (seed), - ssl->sid.master_secret, - (size_t)sizeof (ssl->sid.master_secret))); -} - - -static void -kssl_generate_ssl_ms(ssl_t *ssl, uchar_t *pms, size_t pmslen) -{ - uchar_t buf[SSL3_PRE_MASTER_SECRET_LEN]; - uchar_t *ms; - int hlen = MD5_HASH_LEN; - - ms = ssl->sid.master_secret; - - /* if pms is bad fake it to thwart Bleichenbacher attack */ - if (IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl)) { - DTRACE_PROBE(kssl_err__under_Bleichenbacher_attack); - FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf); - } - - kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 1, ms, 0); - kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 2, ms + hlen, 0); - kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 3, ms + 2 * hlen, - 0); -} - -static int -kssl_generate_tls_keyblock(ssl_t *ssl) -{ - uchar_t seed[2 * SSL3_RANDOM_LENGTH]; - - bcopy(ssl->server_random, seed, SSL3_RANDOM_LENGTH); - bcopy(ssl->client_random, seed + SSL3_RANDOM_LENGTH, - SSL3_RANDOM_LENGTH); - - return (kssl_tls_PRF(ssl, ssl->sid.master_secret, - (size_t)SSL3_MASTER_SECRET_LEN, - (uchar_t *)TLS_KEY_EXPANSION_LABEL, - (size_t)strlen(TLS_KEY_EXPANSION_LABEL), - seed, (size_t)sizeof (seed), - ssl->pending_keyblock, - (size_t)ssl->pending_keyblksz)); - -} - -static void -kssl_generate_keyblock(ssl_t *ssl) -{ - uchar_t *ms; - size_t mslen = SSL3_MASTER_SECRET_LEN; - int hlen = MD5_HASH_LEN; - uchar_t *keys = ssl->pending_keyblock; - int steps = howmany(ssl->pending_keyblksz, hlen); - int i; - - ms = ssl->sid.master_secret; - - ASSERT(hlen * steps <= MAX_KEYBLOCK_LENGTH); - - for (i = 1; i <= steps; i++) { - kssl_ssl3_key_material_derive_step(ssl, ms, mslen, i, keys, 1); - keys += hlen; - } -} - -static char *ssl3_key_derive_seeds[9] = {"A", "BB", "CCC", "DDDD", "EEEEE", - "FFFFFF", "GGGGGGG", "HHHHHHHH", "IIIIIIIII"}; - -static void -kssl_ssl3_key_material_derive_step(ssl_t *ssl, uchar_t *secret, - size_t secretlen, int step, uchar_t *dst, int sr_first) -{ - SHA1_CTX sha1, *sha1ctx; - MD5_CTX md5, *md5ctx; - uchar_t sha1_hash[SHA1_HASH_LEN]; - - sha1ctx = &sha1; - md5ctx = &md5; - - ASSERT(step <= - sizeof (ssl3_key_derive_seeds) / - sizeof (ssl3_key_derive_seeds[0])); - step--; - - SHA1Init(sha1ctx); - SHA1Update(sha1ctx, (uchar_t *)ssl3_key_derive_seeds[step], - step + 1); - SHA1Update(sha1ctx, secret, secretlen); - if (sr_first) { - SHA1Update(sha1ctx, ssl->server_random, SSL3_RANDOM_LENGTH); - SHA1Update(sha1ctx, ssl->client_random, SSL3_RANDOM_LENGTH); - } else { - SHA1Update(sha1ctx, ssl->client_random, SSL3_RANDOM_LENGTH); - SHA1Update(sha1ctx, ssl->server_random, SSL3_RANDOM_LENGTH); - } - SHA1Final(sha1_hash, sha1ctx); - - MD5Init(md5ctx); - MD5Update(md5ctx, secret, secretlen); - MD5Update(md5ctx, sha1_hash, SHA1_HASH_LEN); - MD5Final(dst, md5ctx); -} - -static int -kssl_send_certificate_and_server_hello_done(ssl_t *ssl) -{ - int cur_reclen; - int mss; - int len, copylen; - mblk_t *mp; - uchar_t *cert_buf; - int cert_len; - uchar_t *msgbuf; - Certificate_t *cert; - uint16_t reclen = KSSL_SSL3_SH_RECLEN; - - cert = ssl->kssl_entry->ke_server_certificate; - if (cert == NULL) { - return (ENOENT); - } - cert_buf = cert->msg; - cert_len = cert->len; - - if (ssl->secure_renegotiation) - reclen += KSSL_EMPTY_RENEG_INFO_LEN; - - mp = ssl->handshake_sendbuf; - mss = ssl->tcp_mss; - ASSERT(mp != NULL); - cur_reclen = mp->b_wptr - mp->b_rptr - SSL3_HDR_LEN; - ASSERT(cur_reclen == reclen); - /* Assume MSS is at least 80 bytes */ - ASSERT(mss > cur_reclen + SSL3_HDR_LEN); - ASSERT(cur_reclen < SSL3_MAX_RECORD_LENGTH); /* XXX */ - - copylen = mss - (cur_reclen + SSL3_HDR_LEN); - len = cert_len; - copylen = MIN(copylen, len); - copylen = MIN(copylen, SSL3_MAX_RECORD_LENGTH - cur_reclen); - - /* new record always starts in a new mblk for simplicity */ - msgbuf = cert_buf; - for (;;) { - ASSERT(mp->b_wptr + copylen <= mp->b_datap->db_lim); - bcopy(msgbuf, mp->b_wptr, copylen); - msgbuf += copylen; - mp->b_wptr += copylen; - cur_reclen += copylen; - len -= copylen; - if (len == 0) { - break; - } - if (cur_reclen == SSL3_MAX_RECORD_LENGTH) { - cur_reclen = 0; - } - copylen = MIN(len, mss); - copylen = MIN(copylen, SSL3_MAX_RECORD_LENGTH - cur_reclen); - mp->b_cont = allocb(copylen, BPRI_HI); - if (mp->b_cont == NULL) { - KSSL_COUNTER(alloc_fails, 1); - freemsg(ssl->handshake_sendbuf); - ssl->handshake_sendbuf = NULL; - return (ENOMEM); - } - mp = mp->b_cont; - if (cur_reclen == 0) { - mp->b_wptr[0] = content_handshake; - mp->b_wptr[1] = ssl->major_version; - mp->b_wptr[2] = ssl->minor_version; - cur_reclen = MIN(len, reclen); - mp->b_wptr[3] = (cur_reclen >> 8) & 0xff; - mp->b_wptr[4] = (cur_reclen) & 0xff; - mp->b_wptr += SSL3_HDR_LEN; - cur_reclen = 0; - copylen = MIN(copylen, mss - SSL3_HDR_LEN); - } - } - - /* adjust the record length field for the first record */ - mp = ssl->handshake_sendbuf; - cur_reclen = MIN(reclen + cert_len, SSL3_MAX_RECORD_LENGTH); - mp->b_rptr[3] = (cur_reclen >> 8) & 0xff; - mp->b_rptr[4] = (cur_reclen) & 0xff; - - kssl_update_handshake_hashes(ssl, cert_buf, cert_len); - - return (0); -} - -static int -kssl_send_change_cipher_specs(ssl_t *ssl) -{ - mblk_t *mp, *newmp; - uchar_t *buf; - - mp = ssl->handshake_sendbuf; - - /* We're most likely to hit the fast path for resumed sessions */ - if ((mp != NULL) && - (mp->b_datap->db_lim - mp->b_wptr > KSSL_SSL3_MAX_CCP_FIN_MSGLEN)) { - buf = mp->b_wptr; - } else { - newmp = allocb(KSSL_SSL3_MAX_CCP_FIN_MSGLEN, BPRI_HI); - - if (newmp == NULL) - return (ENOMEM); /* need to do better job! */ - - if (mp == NULL) { - ssl->handshake_sendbuf = newmp; - } else { - linkb(ssl->handshake_sendbuf, newmp); - } - mp = newmp; - buf = mp->b_rptr; - } - - /* 5 byte record header */ - buf[0] = content_change_cipher_spec; - buf[1] = ssl->major_version; - buf[2] = ssl->minor_version; - buf[3] = 0; - buf[4] = 1; - buf += SSL3_HDR_LEN; - - buf[0] = 1; - - mp->b_wptr = buf + 1; - ASSERT(mp->b_wptr < mp->b_datap->db_lim); - - ssl->seq_num[KSSL_WRITE] = 0; - return (kssl_spec_init(ssl, KSSL_WRITE)); -} - -int -kssl_spec_init(ssl_t *ssl, int dir) -{ - KSSL_HASHCTX *ctx; - KSSLCipherSpec *spec = &ssl->spec[dir]; - int ret = 0; - - spec->mac_hashsz = mac_defs[ssl->pending_malg].hashsz; - spec->mac_padsz = mac_defs[ssl->pending_malg].padsz; - - spec->MAC_HashInit = mac_defs[ssl->pending_malg].HashInit; - spec->MAC_HashUpdate = mac_defs[ssl->pending_malg].HashUpdate; - spec->MAC_HashFinal = mac_defs[ssl->pending_malg].HashFinal; - - if (dir == KSSL_READ) { - bcopy(ssl->pending_keyblock, ssl->mac_secret[dir], - spec->mac_hashsz); - } else { - bcopy(&(ssl->pending_keyblock[spec->mac_hashsz]), - ssl->mac_secret[dir], spec->mac_hashsz); - } - - /* Pre-compute these here. will save cycles on each record later */ - if (!IS_TLS(ssl)) { - ctx = &ssl->mac_ctx[dir][0]; - spec->MAC_HashInit((void *)ctx); - spec->MAC_HashUpdate((void *)ctx, ssl->mac_secret[dir], - spec->mac_hashsz); - spec->MAC_HashUpdate((void *)ctx, kssl_pad_1, - spec->mac_padsz); - - ctx = &ssl->mac_ctx[dir][1]; - spec->MAC_HashInit((void *)ctx); - spec->MAC_HashUpdate((void *)ctx, ssl->mac_secret[dir], - spec->mac_hashsz); - spec->MAC_HashUpdate((void *)ctx, kssl_pad_2, - spec->mac_padsz); - } - - spec->cipher_type = cipher_defs[ssl->pending_calg].type; - spec->cipher_mech.cm_type = cipher_defs[ssl->pending_calg].mech_type; - spec->cipher_bsize = cipher_defs[ssl->pending_calg].bsize; - spec->cipher_keysz = cipher_defs[ssl->pending_calg].keysz; - - if (spec->cipher_ctx != NULL) { - crypto_cancel_ctx(spec->cipher_ctx); - spec->cipher_ctx = 0; - } - - /* - * Initialize HMAC keys for TLS and SSL3 HMAC keys - * for SSL 3.0. - */ - if (IS_TLS(ssl)) { - if (ssl->pending_malg == mac_md5) { - spec->hmac_mech = hmac_md5_mech; - } else if (ssl->pending_malg == mac_sha) { - spec->hmac_mech = hmac_sha1_mech; - } - - spec->hmac_key.ck_format = CRYPTO_KEY_RAW; - spec->hmac_key.ck_data = ssl->mac_secret[dir]; - spec->hmac_key.ck_length = spec->mac_hashsz * 8; - } else { - static uint32_t param; - - spec->hmac_mech.cm_type = CRYPTO_MECH_INVALID; - spec->hmac_mech.cm_param = (caddr_t)¶m; - spec->hmac_mech.cm_param_len = sizeof (param); - if (ssl->pending_malg == mac_md5) { - spec->hmac_mech.cm_type = - crypto_mech2id("CKM_SSL3_MD5_MAC"); - param = MD5_HASH_LEN; - } else if (ssl->pending_malg == mac_sha) { - spec->hmac_mech.cm_type = - crypto_mech2id("CKM_SSL3_SHA1_MAC"); - param = SHA1_HASH_LEN; - } - - spec->hmac_key.ck_format = CRYPTO_KEY_RAW; - spec->hmac_key.ck_data = ssl->mac_secret[dir]; - spec->hmac_key.ck_length = spec->mac_hashsz * 8; - } - - /* We're done if this is the nil cipher */ - if (spec->cipher_keysz == 0) { - return (0); - } - - /* Initialize the key and the active context */ - spec->cipher_key.ck_format = CRYPTO_KEY_RAW; - spec->cipher_key.ck_length = 8 * spec->cipher_keysz; /* in bits */ - - if (cipher_defs[ssl->pending_calg].bsize > 0) { - /* client_write_IV */ - spec->cipher_mech.cm_param = - (caddr_t)&(ssl->pending_keyblock[2 * spec->mac_hashsz + - 2 * spec->cipher_keysz]); - spec->cipher_mech.cm_param_len = spec->cipher_bsize; - } - spec->cipher_data.cd_format = CRYPTO_DATA_RAW; - if (dir == KSSL_READ) { - spec->cipher_mech.cm_param_len = - cipher_defs[ssl->pending_calg].bsize; - - /* client_write_key */ - spec->cipher_key.ck_data = - &(ssl->pending_keyblock[2 * spec->mac_hashsz]); - - ret = crypto_decrypt_init(&(spec->cipher_mech), - &(spec->cipher_key), NULL, &spec->cipher_ctx, NULL); - if (CRYPTO_ERR(ret)) { - DTRACE_PROBE1(kssl_err__crypto_decrypt_init_read, - int, ret); - } - } else { - if (cipher_defs[ssl->pending_calg].bsize > 0) { - /* server_write_IV */ - spec->cipher_mech.cm_param += spec->cipher_bsize; - } - - /* server_write_key */ - spec->cipher_key.ck_data = - &(ssl->pending_keyblock[2 * spec->mac_hashsz + - spec->cipher_keysz]); - - ret = crypto_encrypt_init(&(spec->cipher_mech), - &(spec->cipher_key), NULL, &spec->cipher_ctx, NULL); - if (CRYPTO_ERR(ret)) - DTRACE_PROBE1(kssl_err__crypto_encrypt_init_non_read, - int, ret); - } - return (ret); -} - -static int -kssl_send_finished(ssl_t *ssl, int update_hsh) -{ - mblk_t *mp; - uchar_t *buf; - uchar_t *rstart; - uchar_t *versionp; - SSL3Hashes ssl3hashes; - uchar_t finish_len; - int ret; - uint16_t adj_len = 0; - - mp = ssl->handshake_sendbuf; - ASSERT(mp != NULL); - buf = mp->b_wptr; - if (ssl->secure_renegotiation) - adj_len = KSSL_EMPTY_RENEG_INFO_LEN; - /* - * It should be either a message with Server Hello record or just plain - * SSL header (data packet). - */ - ASSERT(buf - mp->b_rptr == - SSL3_HDR_LEN + KSSL_SSL3_SH_RECLEN + SSL3_HDR_LEN + 1 + adj_len || - buf - mp->b_rptr == SSL3_HDR_LEN + 1); - - rstart = buf; - - if (IS_TLS(ssl)) - finish_len = TLS_FINISHED_SIZE; - else - finish_len = KSSL_SSL3_FIN_MSGLEN; - - /* 5 byte record header */ - buf[0] = content_handshake; - buf[1] = ssl->major_version; - buf[2] = ssl->minor_version; - buf[3] = 0; - buf[4] = 4 + finish_len; - - versionp = &buf[1]; - - buf += SSL3_HDR_LEN; - - /* 4 byte message header */ - buf[0] = (uchar_t)finished; /* message type */ - buf[1] = 0; /* message len byte 0 */ - buf[2] = 0; /* message len byte 1 */ - buf[3] = finish_len; /* message len byte 2 */ - buf += 4; - - if (IS_TLS(ssl)) { - bcopy(ssl->hs_hashes.md5, ssl3hashes.md5, - sizeof (ssl3hashes.md5)); - bcopy(ssl->hs_hashes.sha1, ssl3hashes.sha1, - sizeof (ssl3hashes.sha1)); - } - - /* Compute hashes for the SENDER side */ - ret = kssl_compute_handshake_hashes(ssl, &ssl3hashes, sender_server); - if (ret != 0) - return (ret); - - if (IS_TLS(ssl)) { - bcopy(ssl3hashes.tlshash, buf, sizeof (ssl3hashes.tlshash)); - } else { - bcopy(ssl3hashes.md5, buf, MD5_HASH_LEN); - bcopy(ssl3hashes.sha1, buf + MD5_HASH_LEN, SHA1_HASH_LEN); - } - - if (update_hsh) { - kssl_update_handshake_hashes(ssl, buf - 4, finish_len + 4); - } - - mp->b_wptr = buf + finish_len; - - ret = kssl_mac_encrypt_record(ssl, content_handshake, versionp, - rstart, mp); - ASSERT(mp->b_wptr <= mp->b_datap->db_lim); - - return (ret); -} - -int -kssl_mac_encrypt_record(ssl_t *ssl, SSL3ContentType ct, uchar_t *versionp, - uchar_t *rstart, mblk_t *mp) -{ - KSSLCipherSpec *spec; - int mac_sz; - int ret = 0; - uint16_t rec_sz; - int pad_sz; - int i; - - ASSERT(ssl != NULL); - ASSERT(rstart >= mp->b_rptr); - ASSERT(rstart < mp->b_wptr); - - spec = &ssl->spec[KSSL_WRITE]; - mac_sz = spec->mac_hashsz; - - rec_sz = (mp->b_wptr - rstart) - SSL3_HDR_LEN; - ASSERT(rec_sz > 0); - - if (mac_sz != 0) { - ASSERT(mp->b_wptr + mac_sz <= mp->b_datap->db_lim); - ret = kssl_compute_record_mac(ssl, KSSL_WRITE, - ssl->seq_num[KSSL_WRITE], ct, versionp, - rstart + SSL3_HDR_LEN, rec_sz, mp->b_wptr); - if (ret == CRYPTO_SUCCESS) { - ssl->seq_num[KSSL_WRITE]++; - mp->b_wptr += mac_sz; - rec_sz += mac_sz; - } else { - return (ret); - } - } - - if (spec->cipher_type == type_block) { - pad_sz = spec->cipher_bsize - - (rec_sz & (spec->cipher_bsize - 1)); - ASSERT(mp->b_wptr + pad_sz <= mp->b_datap->db_lim); - for (i = 0; i < pad_sz; i++) { - mp->b_wptr[i] = pad_sz - 1; - } - mp->b_wptr += pad_sz; - rec_sz += pad_sz; - } - - ASSERT(rec_sz <= SSL3_MAX_RECORD_LENGTH); - - U16_TO_BE16(rec_sz, rstart + 3); - - if (spec->cipher_ctx == 0) - return (ret); - - spec->cipher_data.cd_length = rec_sz; - spec->cipher_data.cd_raw.iov_base = (char *)(rstart + SSL3_HDR_LEN); - spec->cipher_data.cd_raw.iov_len = rec_sz; - /* One record at a time. Otherwise, gotta allocate the crypt_data_t */ - ret = crypto_encrypt_update(spec->cipher_ctx, &spec->cipher_data, - NULL, NULL); - if (CRYPTO_ERR(ret)) { - DTRACE_PROBE1(kssl_err__crypto_encrypt_update, - int, ret); - } - return (ret); -} - -/* - * Produce SSL alert message (SSLv3/TLS) or error message (SSLv2). For SSLv2 - * it is only done to tear down the SSL connection so it has fixed encoding. - */ -void -kssl_send_alert(ssl_t *ssl, SSL3AlertLevel level, SSL3AlertDescription desc) -{ - mblk_t *mp; - uchar_t *buf; - KSSLCipherSpec *spec; - size_t len; - - ASSERT(ssl != NULL); - - ssl->sendalert_level = level; - ssl->sendalert_desc = desc; - - if (level == alert_fatal) { - DTRACE_PROBE2(kssl_sending_alert, - SSL3AlertLevel, level, SSL3AlertDescription, desc); - if (ssl->sid.cached == B_TRUE) { - kssl_uncache_sid(&ssl->sid, ssl->kssl_entry); - } - ssl->fatal_alert = B_TRUE; - KSSL_COUNTER(fatal_alerts, 1); - } else - KSSL_COUNTER(warning_alerts, 1); - - spec = &ssl->spec[KSSL_WRITE]; - - ASSERT(ssl->alert_sendbuf == NULL); - if (ssl->major_version == 0x03) { - len = SSL3_HDR_LEN + SSL3_ALERT_LEN; - } else { - /* KSSL generates 5 byte SSLv2 alert messages only. */ - len = 5; - } - ssl->alert_sendbuf = mp = allocb(len + spec->mac_hashsz + - spec->cipher_bsize, BPRI_HI); - if (mp == NULL) { - KSSL_COUNTER(alloc_fails, 1); - return; - } - buf = mp->b_wptr; - - /* SSLv3/TLS */ - if (ssl->major_version == 0x03) { - /* 5 byte record header */ - buf[0] = content_alert; - buf[1] = ssl->major_version; - buf[2] = ssl->minor_version; - buf[3] = 0; - buf[4] = 2; - buf += SSL3_HDR_LEN; - - /* alert contents */ - buf[0] = (uchar_t)level; - buf[1] = (uchar_t)desc; - buf += SSL3_ALERT_LEN; - } else { - /* SSLv2 has different encoding. */ - /* 2-byte encoding of the length */ - buf[0] = 0x80; - buf[1] = 0x03; - buf += 2; - - /* Protocol Message Code = Error */ - buf[0] = 0; - /* Error Message Code = Undefined Error */ - buf[1] = 0; - buf[2] = 0; - buf += 3; - } - - mp->b_wptr = buf; -} - -/* Assumes RSA encryption */ -static int -kssl_handle_client_key_exchange(ssl_t *ssl, mblk_t *mp, int msglen, - kssl_callback_t cbfn, void *arg) -{ - char *buf; - uchar_t *pms; - size_t pmslen; - int allocated; - int err, rverr = ENOMEM; - kssl_entry_t *ep; - crypto_key_t *privkey; - crypto_data_t *wrapped_pms_data, *pms_data; - crypto_call_req_t creq, *creqp; - - ep = ssl->kssl_entry; - privkey = ep->ke_private_key; - if (privkey == NULL) { - return (ENOENT); - } - - ASSERT(ssl->msg.type == client_key_exchange); - ASSERT(ssl->hs_waitstate == wait_client_key); - - /* - * TLS adds an extra 2 byte length field before the data. - */ - if (IS_TLS(ssl)) { - msglen = (mp->b_rptr[0] << 8) | mp->b_rptr[1]; - mp->b_rptr += 2; - } - - /* - * Allocate all we need in one shot. about 300 bytes total, for - * 1024 bit RSA modulus. - * The buffer layout will be: pms_data, wrapped_pms_data, the - * value of the wrapped pms from the client, then room for the - * resulting decrypted premaster secret. - */ - allocated = 2 * (sizeof (crypto_data_t) + msglen); - buf = kmem_alloc(allocated, KM_NOSLEEP); - if (buf == NULL) { - return (ENOMEM); - } - - pms_data = (crypto_data_t *)buf; - wrapped_pms_data = &(((crypto_data_t *)buf)[1]); - - wrapped_pms_data->cd_format = pms_data->cd_format = CRYPTO_DATA_RAW; - wrapped_pms_data->cd_offset = pms_data->cd_offset = 0; - wrapped_pms_data->cd_length = pms_data->cd_length = msglen; - wrapped_pms_data->cd_miscdata = pms_data->cd_miscdata = NULL; - wrapped_pms_data->cd_raw.iov_len = pms_data->cd_raw.iov_len = msglen; - wrapped_pms_data->cd_raw.iov_base = buf + 2 * sizeof (crypto_data_t); - pms_data->cd_raw.iov_base = wrapped_pms_data->cd_raw.iov_base + msglen; - - bcopy(mp->b_rptr, wrapped_pms_data->cd_raw.iov_base, msglen); - mp->b_rptr += msglen; - - /* Proceed synchronously if out of interrupt and configured to do so */ - if ((kssl_synchronous) && (!servicing_interrupt())) { - creqp = NULL; - } else { - ssl->cke_callback_func = cbfn; - ssl->cke_callback_arg = arg; - creq.cr_flag = kssl_call_flag; - creq.cr_callback_func = kssl_cke_done; - creq.cr_callback_arg = ssl; - - creqp = &creq; - } - - if (ep->ke_is_nxkey) { - kssl_session_info_t *s; - - s = ep->ke_sessinfo; - err = CRYPTO_SUCCESS; - if (!s->is_valid_handle) { - /* Reauthenticate to the provider */ - if (s->do_reauth) { - err = kssl_get_obj_handle(ep); - if (err == CRYPTO_SUCCESS) { - s->is_valid_handle = B_TRUE; - s->do_reauth = B_FALSE; - } - } else - err = CRYPTO_FAILED; - } - - if (err == CRYPTO_SUCCESS) { - ASSERT(s->is_valid_handle); - err = crypto_decrypt_prov(s->prov, s->sid, - &rsa_x509_mech, wrapped_pms_data, &s->key, - NULL, pms_data, creqp); - } - - /* - * Deal with session specific errors. We translate to - * the closest errno. - */ - switch (err) { - case CRYPTO_KEY_HANDLE_INVALID: - case CRYPTO_SESSION_HANDLE_INVALID: - s->is_valid_handle = B_FALSE; - s->do_reauth = B_TRUE; - rverr = EINVAL; - break; - case CRYPTO_PIN_EXPIRED: - case CRYPTO_PIN_LOCKED: - rverr = EACCES; - break; - case CRYPTO_UNKNOWN_PROVIDER: - rverr = ENXIO; - break; - } - } else { - err = crypto_decrypt(&rsa_x509_mech, wrapped_pms_data, - privkey, NULL, pms_data, creqp); - } - - switch (err) { - case CRYPTO_SUCCESS: - break; - - case CRYPTO_QUEUED: - /* - * Finish the master secret then the rest of key material - * derivation later. - */ - ssl->job.kjob = creq.cr_reqid; - ssl->job.buf = buf; - ssl->job.buflen = allocated; - ssl->hs_waitstate = wait_client_key_done; - return (0); - default: - DTRACE_PROBE1(kssl_err__crypto_decrypt, int, err); - kmem_free(buf, allocated); - return (rverr); - } - - pmslen = pms_data->cd_length; - pms = kssl_rsa_unwrap((uchar_t *)pms_data->cd_raw.iov_base, &pmslen); - - /* generate master key and save it in the ssl sid structure */ - if (IS_TLS(ssl)) { - err = kssl_generate_tls_ms(ssl, pms, pmslen); - if (!CRYPTO_ERR(err)) - err = kssl_generate_tls_keyblock(ssl); - } else { - kssl_generate_ssl_ms(ssl, pms, pmslen); - kssl_generate_keyblock(ssl); - } - - if (err == CRYPTO_SUCCESS) - ssl->hs_waitstate = wait_change_cipher; - - ssl->activeinput = B_FALSE; - - kmem_free(buf, allocated); - - return (0); -} - -static int -kssl_handle_finished(ssl_t *ssl, mblk_t *mp, int msglen) -{ - int err; - size_t finish_len; - int hashcompare; - - ASSERT(ssl->msg.type == finished); - ASSERT(ssl->hs_waitstate == wait_finished); - - if (IS_TLS(ssl)) - finish_len = TLS_FINISHED_SIZE; - else - finish_len = KSSL_SSL3_FIN_MSGLEN; - - if (msglen != finish_len) { - kssl_send_alert(ssl, alert_fatal, illegal_parameter); - return (EBADMSG); - } - - if (IS_TLS(ssl)) { - hashcompare = bcmp(mp->b_rptr, ssl->hs_hashes.tlshash, - finish_len); - } else { - hashcompare = bcmp(mp->b_rptr, &ssl->hs_hashes, finish_len); - } - - /* The handshake hashes should be computed by now */ - if (hashcompare != 0) { - kssl_send_alert(ssl, alert_fatal, handshake_failure); - return (EBADMSG); - } - - mp->b_rptr += msglen; - - ssl->hs_waitstate = idle_handshake; - - if (ssl->resumed == B_TRUE) { - ssl->activeinput = B_FALSE; - return (0); - } - - err = kssl_send_change_cipher_specs(ssl); - if (err != 0) { - return (err); - } - err = kssl_send_finished(ssl, 0); - if (err != 0) { - return (err); - } - - kssl_cache_sid(&ssl->sid, ssl->kssl_entry); - ssl->activeinput = B_FALSE; - - return (0); -} - -#define KSSL2_CH_MIN_RECSZ (9) - -/* - * This method is needed to handle clients which send the - * SSLv2/SSLv3 handshake for backwards compat with SSLv2 servers. - * We are not really doing SSLv2 here, just handling the header - * and then switching to SSLv3. - */ -int -kssl_handle_v2client_hello(ssl_t *ssl, mblk_t *mp, int recsz) -{ - uchar_t *recend; - int err; - SSL3AlertDescription desc = illegal_parameter; - uint_t randlen; - uint_t sidlen; - uint_t cslen; - uchar_t *suitesp; - uchar_t *rand; - uint_t i, j; - uint16_t suite, selected_suite; - int ch_recsz = KSSL2_CH_MIN_RECSZ; - boolean_t suite_found = B_FALSE; - - ASSERT(mp->b_wptr >= mp->b_rptr + recsz); - ASSERT(ssl->hs_waitstate == wait_client_hello); - ASSERT(ssl->resumed == B_FALSE); - - if (recsz < ch_recsz) { - DTRACE_PROBE2(kssl_err__reclen_less_than_minimum, - int, recsz, int, ch_recsz); - goto falert; - } - - MD5Init(&ssl->hs_md5); - SHA1Init(&ssl->hs_sha1); - - kssl_update_handshake_hashes(ssl, mp->b_rptr, recsz); - - recend = mp->b_rptr + recsz; - - if (*mp->b_rptr != 1) { - DTRACE_PROBE1(kssl_err__invalid_version, uint_t, *mp->b_rptr); - goto falert; - } - mp->b_rptr += 3; - - cslen = ((uint_t)mp->b_rptr[0] << 8) + (uint_t)mp->b_rptr[1]; - sidlen = ((uint_t)mp->b_rptr[2] << 8) + (uint_t)mp->b_rptr[3]; - randlen = ((uint_t)mp->b_rptr[4] << 8) + (uint_t)mp->b_rptr[5]; - if (cslen % 3 != 0) { - DTRACE_PROBE1(kssl_err__cipher_suites_len_error, uint_t, cslen); - goto falert; - } - if (randlen < SSL_MIN_CHALLENGE_BYTES || - randlen > SSL_MAX_CHALLENGE_BYTES) { - DTRACE_PROBE1(kssl_err__randlen_out_of_range, - uint_t, randlen); - goto falert; - } - mp->b_rptr += 6; - ch_recsz += cslen + sidlen + randlen; - if (recsz != ch_recsz) { - DTRACE_PROBE2(kssl_err__invalid_message_len_sum, - int, recsz, int, ch_recsz); - goto falert; - } - suitesp = mp->b_rptr; - rand = suitesp + cslen + sidlen; - if (randlen < SSL3_RANDOM_LENGTH) { - bzero(ssl->client_random, SSL3_RANDOM_LENGTH); - } - bcopy(rand, &ssl->client_random[SSL3_RANDOM_LENGTH - randlen], - randlen); - - for (i = 0; i < ssl->kssl_entry->kssl_cipherSuites_nentries; i++) { - suite = ssl->kssl_entry->kssl_cipherSuites[i]; - for (j = 0; j < cslen; j += 3) { - DTRACE_PROBE2(kssl_cipher_suite_check_v2, - uint16_t, suite, - uint16_t, - (uint16_t)((suitesp[j+1] << 8) + suitesp[j+2])); - if (suitesp[j] != 0) { - continue; - } - - /* Check for regular (true) cipher suite. */ - if (suitesp[j + 1] == ((suite >> 8) & 0xff) && - suitesp[j + 2] == (suite & 0xff)) { - DTRACE_PROBE1(kssl_cipher_suite_found, - uint16_t, suite); - suite_found = B_TRUE; - selected_suite = suite; - } - - /* Check for SCSV. */ - if (suitesp[j + 1] == ((SSL_SCSV >> 8) & 0xff) && - suitesp[j + 2] == (SSL_SCSV & 0xff)) { - DTRACE_PROBE(kssl_scsv_found); - ssl->secure_renegotiation = B_TRUE; - } - /* - * If we got cipher suite match and SCSV or went - * through the whole list of client cipher suites - * (hence we know if SCSV was present or not) we - * can terminate the cycle now. - */ - if (suite_found && - (ssl->secure_renegotiation || (i > 0))) - break; - } - if (suite_found) - break; - } - if (!suite_found) { - DTRACE_PROBE(kssl_err__no_SSLv2_cipher_suite); - ssl->activeinput = B_FALSE; - /* - * If there is no fallback point terminate the handshake with - * SSL alert otherwise return with SSL_MISS. - */ - if (ssl->kssl_entry->ke_fallback_head == NULL) { - DTRACE_PROBE(kssl_no_fallback); - desc = handshake_failure; - goto falert; - } else { - return (SSL_MISS); - } - } - - mp->b_rptr = recend; - - for (i = 0; i < cipher_suite_defs_nentries; i++) { - if (selected_suite == cipher_suite_defs[i].suite) { - break; - } - } - - ASSERT(i < cipher_suite_defs_nentries); - - ssl->pending_cipher_suite = selected_suite; - ssl->pending_malg = cipher_suite_defs[i].malg; - ssl->pending_calg = cipher_suite_defs[i].calg; - ssl->pending_keyblksz = cipher_suite_defs[i].keyblksz; - - ASSERT(ssl->sid.cached == B_FALSE); - - (void) random_get_pseudo_bytes(ssl->sid.session_id, - SSL3_SESSIONID_BYTES); - ssl->sid.client_addr = ssl->faddr; - ssl->sid.cipher_suite = selected_suite; - - err = kssl_send_server_hello(ssl); - if (err != 0) { - return (err); - } - err = kssl_send_certificate_and_server_hello_done(ssl); - if (err != 0) { - return (err); - } - KSSL_COUNTER(full_handshakes, 1); - ssl->hs_waitstate = wait_client_key; - ssl->activeinput = B_FALSE; - return (0); - -falert: - kssl_send_alert(ssl, alert_fatal, desc); - ssl->activeinput = B_FALSE; - return (EBADMSG); -} - -/* - * Call back routine for asynchronously submitted RSA decryption jobs. - * This routine retrieves the pre-master secret, and proceeds to generate - * the remaining key materials. - */ -static void -kssl_cke_done(void *arg, int status) -{ - int ret = 0; - uchar_t *pms; - size_t pmslen; - crypto_data_t *pms_data; - kssl_cmd_t kssl_cmd = KSSL_CMD_NONE; - ssl_t *ssl = (ssl_t *)arg; - mblk_t *alertmp; - kssl_callback_t cbfn; - void *cbarg; - - mutex_enter(&ssl->kssl_lock); - - ASSERT(ssl->msg.type == client_key_exchange); - ASSERT(ssl->hs_waitstate == wait_client_key_done); - - if (status != CRYPTO_SUCCESS) { - kssl_send_alert(ssl, alert_fatal, decrypt_error); - kssl_cmd = KSSL_CMD_SEND; - goto out; - } - - pms_data = (crypto_data_t *)(ssl->job.buf); - - ASSERT(pms_data != NULL); - - pmslen = pms_data->cd_length; - pms = kssl_rsa_unwrap((uchar_t *)pms_data->cd_raw.iov_base, &pmslen); - - /* generate master key and save it in the ssl sid structure */ - if (IS_TLS(ssl)) { - ret = kssl_generate_tls_ms(ssl, pms, pmslen); - if (!CRYPTO_ERR(ret)) - ret = kssl_generate_tls_keyblock(ssl); - } else { - kssl_generate_ssl_ms(ssl, pms, pmslen); - kssl_generate_keyblock(ssl); - } - - if (ret == CRYPTO_SUCCESS) - ssl->hs_waitstate = wait_change_cipher; - -out: - kmem_free(ssl->job.buf, ssl->job.buflen); - - ssl->job.kjob = 0; - ssl->job.buf = NULL; - ssl->job.buflen = 0; - - ssl->activeinput = B_FALSE; - - cbfn = ssl->cke_callback_func; - cbarg = ssl->cke_callback_arg; - alertmp = ssl->alert_sendbuf; - ssl->alert_sendbuf = NULL; - - /* dropped by callback when it has completed */ - ssl->async_ops_pending++; - mutex_exit(&ssl->kssl_lock); - - /* Now call the callback routine */ - (*(cbfn))(cbarg, alertmp, kssl_cmd); -} - -/* - * Returns the first complete contiguous record out of rec_ass_head - * The record is returned in a separate contiguous mblk, rec_ass_head is - * left pointing to the next record in the queue. - * - * The output looks as follows: - * - * |--------|---------- .... -----|<---------->|<----------->|--- ... ---| - * ^ ^ ^ mac_size pad_size ^ - * | |___ b_rptr b_wptr __| | - * | | - * |___ db_base db_lim ___| - */ -mblk_t * -kssl_get_next_record(ssl_t *ssl) -{ - mblk_t *mp, *retmp; - int rhsz = SSL3_HDR_LEN; - uint16_t rec_sz; - int mpsz, total_size; - SSL3ContentType content_type; - - ASSERT(MUTEX_HELD(&ssl->kssl_lock)); - - mp = ssl->rec_ass_head; - if (mp == NULL) - return (NULL); - - /* Fast path: when mp has at least a complete record */ - if (MBLKL(mp) < rhsz) { - DTRACE_PROBE1(kssl_mblk__incomplete_header, - mblk_t *, mp); - /* Not even a complete header in there yet */ - if (msgdsize(mp) < rhsz) { - return (NULL); - } - - if (!pullupmsg(mp, rhsz)) { - kssl_send_alert(ssl, alert_fatal, internal_error); - freemsg(mp); - ssl->rec_ass_head = ssl->rec_ass_tail = NULL; - return (NULL); - } - } - content_type = (SSL3ContentType)mp->b_rptr[0]; - if (content_type == content_handshake_v2) { - DTRACE_PROBE1(kssl_mblk__ssl_v2, mblk_t *, mp); - rec_sz = (uint16_t)mp->b_rptr[1]; - rhsz = 2; - } else { - DTRACE_PROBE1(kssl_mblk__ssl_v3, mblk_t *, mp); - uint8_t *rec_sz_p = (uint8_t *)mp->b_rptr + 3; - rec_sz = BE16_TO_U16(rec_sz_p); - } - - /* - * same tests as above. Only rare very fragmented cases will - * incur the cost of msgdsize() and msgpullup(). Well formed - * packets will fall in the most frequent fast path. - */ - total_size = rhsz + rec_sz; - - /* - * Missing: defensive against record fabricated with longer than - * MAX record length. - */ - if (MBLKL(mp) < total_size) { - DTRACE_PROBE2(kssl_mblk__smaller_than_total_size, - mblk_t *, mp, int, total_size); - /* Not a complete record yet. Keep accumulating */ - if (msgdsize(mp) < total_size) { - return (NULL); - } - - if (!pullupmsg(mp, total_size)) { - kssl_send_alert(ssl, alert_fatal, internal_error); - freemsg(mp); - ssl->rec_ass_head = ssl->rec_ass_tail = NULL; - return (NULL); - } - } - mpsz = MBLKL(mp); /* could've changed after the pullup */ - - if (mpsz > total_size) { - DTRACE_PROBE2(kssl_mblk__bigger_than_total_size, - mblk_t *, mp, int, total_size); - /* gotta allocate a new block */ - if ((retmp = dupb(mp)) == NULL) { - kssl_send_alert(ssl, alert_fatal, internal_error); - freemsg(mp); - ssl->rec_ass_head = ssl->rec_ass_tail = NULL; - return (NULL); - } - - retmp->b_wptr = retmp->b_rptr + total_size; - mp->b_rptr += total_size; - ssl->rec_ass_head = mp; - } else { - DTRACE_PROBE2(kssl_mblk__equal_to_total_size, - mblk_t *, mp, int, total_size); - ASSERT(mpsz == total_size); - ssl->rec_ass_head = mp->b_cont; - mp->b_cont = NULL; - retmp = mp; - } - /* Adjust the tail */ - if ((mp = ssl->rec_ass_tail = ssl->rec_ass_head) != NULL) { - for (; mp->b_cont != NULL; mp = mp->b_cont) { - ssl->rec_ass_tail = mp->b_cont; - } - } - - return (retmp); -} - - -static void -kssl_mblksfree(ssl_t *ssl) -{ - - ASSERT(ssl != NULL); - - if (ssl->rec_ass_head != NULL) { - freemsg(ssl->rec_ass_head); - } - ssl->rec_ass_head = NULL; - ssl->rec_ass_tail = NULL; - - if (ssl->msg.head != NULL) { - freemsg(ssl->msg.head); - } - ssl->msg.head = NULL; - ssl->msg.tail = NULL; - - if (ssl->handshake_sendbuf != NULL) { - freemsg(ssl->handshake_sendbuf); - ssl->handshake_sendbuf = NULL; - } - if (ssl->alert_sendbuf != NULL) { - freemsg(ssl->alert_sendbuf); - ssl->alert_sendbuf = NULL; - } -} - -static void -kssl_specsfree(ssl_t *ssl) -{ - KSSLCipherSpec *spec = &ssl->spec[KSSL_READ]; - - if (spec->cipher_ctx != NULL) { - crypto_cancel_ctx(spec->cipher_ctx); - spec->cipher_ctx = 0; - } - - spec = &ssl->spec[KSSL_WRITE]; - - if (spec->cipher_ctx != NULL) { - crypto_cancel_ctx(spec->cipher_ctx); - spec->cipher_ctx = 0; - } -} - -/* - * Frees the ssl structure (aka the context of an SSL session). - * Any pending crypto jobs are cancelled. - * Any initiated crypto contexts are freed as well. - */ -void -kssl_free_context(ssl_t *ssl) -{ - crypto_req_id_t reqid; - - ASSERT(ssl != NULL); - if (!(MUTEX_HELD(&ssl->kssl_lock))) { - /* we're coming from an external API entry point */ - mutex_enter(&ssl->kssl_lock); - } - - /* - * Cancel any active crypto request and wait for pending async - * operations to complete. We loop here because the async thread - * might submit a new cryto request. - */ - do { - if (ssl->job.kjob != 0) { - /* - * Drop the lock before canceling the request; - * otherwise we might deadlock if the completion - * callback is running. - */ - reqid = ssl->job.kjob; - mutex_exit(&ssl->kssl_lock); - crypto_cancel_req(reqid); - mutex_enter(&ssl->kssl_lock); - - /* completion callback might have done the cleanup */ - if (ssl->job.kjob != 0) { - kmem_free(ssl->job.buf, ssl->job.buflen); - ssl->job.kjob = 0; - ssl->job.buf = NULL; - ssl->job.buflen = 0; - } - } - while (ssl->async_ops_pending > 0) - cv_wait(&ssl->async_cv, &ssl->kssl_lock); - } while (ssl->job.kjob != 0); - - kssl_mblksfree(ssl); - kssl_specsfree(ssl); - - KSSL_ENTRY_REFRELE(ssl->kssl_entry); - ssl->kssl_entry = NULL; - - mutex_exit(&ssl->kssl_lock); - - kmem_cache_free(kssl_cache, ssl); -} diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index baeb7b4f05..a3708e086a 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -23,7 +23,7 @@ # Copyright (c) 2013 Andrew Stormont. All rights reserved. # Copyright (c) 2014 by Delphix. All rights reserved. # Copyright 2019 Joyent, Inc. -# Copyright 2016 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2018 Nexenta Systems, Inc. # Copyright 2019 RackTop Systems # Copyright 2019 Peter Tribble. @@ -264,7 +264,6 @@ DRV_KMODS += iwp DRV_KMODS += iwscn DRV_KMODS += kb8042 DRV_KMODS += keysock -DRV_KMODS += kssl DRV_KMODS += kstat DRV_KMODS += ksyms DRV_KMODS += kmdb @@ -713,7 +712,6 @@ SOCKET_KMODS += sockpfp SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds -SOCKET_KMODS += ksslf # # kiconv modules (/kernel/kiconv): diff --git a/usr/src/uts/intel/kssl/Makefile b/usr/src/uts/intel/kssl/Makefile deleted file mode 100644 index b3ec5ff0a0..0000000000 --- a/usr/src/uts/intel/kssl/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# -# This makefile drives the production of the kernel SSL driver -# kernel module. -# -# intel architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = kssl -OBJECTS = $(KSSL_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/inet/kssl - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) - -LDFLAGS += -Nmisc/md5 -Nmisc/kcf - -# -# For now, disable these warnings; maintainers should endeavor -# to investigate and remove these for maximum coverage. -# Please do not carry these forward to new Makefiles. -# - -CERRWARN += $(CNOWARN_UNINIT) - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ diff --git a/usr/src/uts/intel/ksslf/Makefile b/usr/src/uts/intel/ksslf/Makefile deleted file mode 100644 index d574e450cc..0000000000 --- a/usr/src/uts/intel/ksslf/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# -# This makefile drives the production of the kssl socket filter -# kernel module. -# -# intel architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = ksslf -OBJECTS = $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_SOCK_DIR)/$(MODULE) - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -LDFLAGS += -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs - -# -# For now, disable these warnings; maintainers should endeavor -# to investigate and remove these for maximum coverage. -# Please do not carry these forward to new Makefiles. -# -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-switch -CERRWARN += $(CNOWARN_UNINIT) - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ diff --git a/usr/src/uts/intel/ml/modstubs.s b/usr/src/uts/intel/ml/modstubs.s index 4143c181a3..0f97c21ac6 100644 --- a/usr/src/uts/intel/ml/modstubs.s +++ b/usr/src/uts/intel/ml/modstubs.s @@ -23,6 +23,7 @@ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 Joyent, Inc. * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Garrett D'Amore <garrett@damore.org> */ #include <sys/asm_linkage.h> @@ -858,7 +859,6 @@ fcnname/**/_info: \ NO_UNLOAD_STUB(c2audit, audit_devpolicy, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_setfsat_path, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_cryptoadm, nomod_zero); - NO_UNLOAD_STUB(c2audit, audit_kssl, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_pf_policy, nomod_zero); NO_UNLOAD_STUB(c2audit, au_doormsg, nomod_zero); NO_UNLOAD_STUB(c2audit, au_uwrite, nomod_zero); diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc index 879d6dc1d9..a031e1606c 100644 --- a/usr/src/uts/sparc/Makefile.sparc +++ b/usr/src/uts/sparc/Makefile.sparc @@ -28,6 +28,7 @@ # Copyright 2016 Nexenta Systems, Inc. # Copyright 2019 Peter Tribble. # Copyright 2019 RackTop Systems +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # # @@ -206,7 +207,7 @@ DRV_KMODS += dtrace fasttrap fbt lockstat profile sdt systrace dcpc DRV_KMODS += fssnap icmp icmp6 ip ip6 ipnet ipsecah DRV_KMODS += ipsecesp iptun iwscn keysock kmdb kstat ksyms llc1 DRV_KMODS += lofi -DRV_KMODS += log logindmux kssl mm nca physmem pm poll pool +DRV_KMODS += log logindmux mm nca physmem pm poll pool DRV_KMODS += pseudo ptc ptm pts ptsl ramdisk random rsm rts sad DRV_KMODS += simnet softmac sppp sppptun sy sysevent sysmsg DRV_KMODS += spdsock @@ -497,7 +498,6 @@ SOCKET_KMODS += sockpfp SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds -SOCKET_KMODS += ksslf # # kiconv modules (/kernel/kiconv): diff --git a/usr/src/uts/sparc/kssl/Makefile b/usr/src/uts/sparc/kssl/Makefile deleted file mode 100644 index 93f85f46ee..0000000000 --- a/usr/src/uts/sparc/kssl/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# -# This makefile drives the production of the kernel SSL driver -# kernel module. -# -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = kssl -OBJECTS = $(KSSL_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/common/inet/kssl - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFFILE) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE) - -LDFLAGS += -Nmisc/md5 -Nmisc/kcf - -# -# For now, disable these warnings; maintainers should endeavor -# to investigate and remove these for maximum coverage. -# Please do not carry these forward to new Makefiles. -# -CFLAGS += $(CCVERBOSE) -CERRWARN += $(CNOWARN_UNINIT) - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ diff --git a/usr/src/uts/sparc/ksslf/Makefile b/usr/src/uts/sparc/ksslf/Makefile deleted file mode 100644 index def63e8420..0000000000 --- a/usr/src/uts/sparc/ksslf/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# -# This makefile drives the production of the kssl socket filter -# kernel module. -# -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = ksslf -OBJECTS = $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%) -ROOTMODULE = $(ROOT_SOCK_DIR)/$(MODULE) - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# Define targets -# -ALL_TARGET = $(BINARY) -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -LDFLAGS += -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs - -# -# For now, disable these warnings; maintainers should endeavor -# to investigate and remove these for maximum coverage. -# Please do not carry these forward to new Makefiles. -# -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-switch -CERRWARN += $(CNOWARN_UNINIT) - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s index 07de0dffff..f43346fd48 100644 --- a/usr/src/uts/sparc/ml/modstubs.s +++ b/usr/src/uts/sparc/ml/modstubs.s @@ -23,6 +23,7 @@ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. * Copyright (c) 2017, Joyent, Inc. All rights reserved. + * Copyright 2022 Garrett D'Amore <garrett@damore.org> */ #include "assym.h" @@ -891,7 +892,6 @@ stubs_base: NO_UNLOAD_STUB(c2audit, audit_devpolicy, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_setfsat_path, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_cryptoadm, nomod_zero); - NO_UNLOAD_STUB(c2audit, audit_kssl, nomod_zero); NO_UNLOAD_STUB(c2audit, audit_pf_policy, nomod_zero); NO_UNLOAD_STUB(c2audit, au_doormsg, nomod_zero); NO_UNLOAD_STUB(c2audit, au_uwrite, nomod_zero); |