diff options
author | Dan McDonald <danmcd@mnx.io> | 2022-07-05 16:54:46 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@mnx.io> | 2022-07-05 16:54:46 -0400 |
commit | 586824c5d718609e395e15b0a92824ba9794397d (patch) | |
tree | 7be304e8ef8a0894d5dc93f94d87df32cab92390 | |
parent | 4fb2ab974a5dc6aeb68146a4f5ff4c7ccbe90667 (diff) | |
parent | 2c0ebdee8f56c8a9d9e34e30367999396b38fec9 (diff) | |
download | illumos-joyent-586824c5d718609e395e15b0a92824ba9794397d.tar.gz |
[illumos-gate merge]
commit 2c0ebdee8f56c8a9d9e34e30367999396b38fec9
14273 Want MAC ring manual pages
commit ceb3ef192e9bccf08d1bcd0ae5ed520cecccff3d
12389 loader should consult with ACPI SPCR table for serial console
commit 6446bd46ed1b4e9f69da153665f82181ccaedad5
14770 ld(1) should be 64bit only
commit 7d10cd4ddf12f982d3bc7edcd01cc8b8d1dcc464
14767 retire kssl
commit 33b27906b01ade9752c1935377f3fefdf49b8f95
14764 AHCI DEVSLEEP 1.3.1 problematic
Conflicts:
usr/src/cmd/devfsadm/misc_link.c
usr/src/cmd/truss/codes.c
usr/src/uts/common/Makefile.files
usr/src/uts/intel/Makefile.intel
usr/src/uts/sparc/Makefile.sparc
104 files changed, 3089 insertions, 11663 deletions
diff --git a/.gitignore b/.gitignore index 315aa5adf6..c4a7e96451 100644 --- a/.gitignore +++ b/.gitignore @@ -817,8 +817,6 @@ usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ikecert usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipsecalgs usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipsecconf usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipseckey -usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm -usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg usr/src/cmd/cmd-inet/usr.sbin/ndd usr/src/cmd/cmd-inet/usr.sbin/nwamadm/nwamadm usr/src/cmd/cmd-inet/usr.sbin/nwamcfg/nwamcfg diff --git a/exception_lists/packaging b/exception_lists/packaging index dc81d8238c..3c49866785 100644 --- a/exception_lists/packaging +++ b/exception_lists/packaging @@ -22,7 +22,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2012 OmniTI Computer Consulting, Inc. All rights reserved. -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> # Copyright 2017 Toomas Soome <tsoome@me.com> # Copyright 2017 RackTop Systems. @@ -267,9 +267,6 @@ usr/lib/mdb/proc/sparcv9/mdb_test.so sparc # # SNCA project exception list # -usr/include/inet/kssl/kssl.h -usr/include/inet/kssl/ksslimpl.h -usr/include/inet/kssl/ksslproto.h usr/include/inet/nca # # these are "removed" from the source product build because the only @@ -106,7 +106,6 @@ s dev/kbd=../devices/pseudo/conskbd@0:kbd s dev/keysock=../devices/pseudo/keysock@0:keysock s dev/kmdb=../devices/pseudo/kmdb@0:kmdb s dev/kmem=../devices/pseudo/mm@0:kmem -s dev/kssl=../devices/pseudo/kssl@0:kssl s dev/kstat=../devices/pseudo/kstat@0:kstat s dev/ksyms=../devices/pseudo/ksyms@0:ksyms s dev/llc1=../devices/pseudo/clone@0:llc1 @@ -712,7 +711,6 @@ f kernel/drv/amd64/kb8042 0755 root sys f kernel/drv/amd64/keysock 0755 root sys f kernel/drv/amd64/ksensor 0755 root sys f kernel/drv/amd64/kmdb 0755 root sys -f kernel/drv/amd64/kssl 0755 root sys f kernel/drv/amd64/llc1 0755 root sys f kernel/drv/amd64/lockstat 0755 root sys f kernel/drv/amd64/lofi 0755 root sys @@ -886,7 +884,6 @@ f kernel/drv/ixgbe.conf 0644 root sys f kernel/drv/keysock.conf 0644 root sys f kernel/drv/kmdb.conf 0644 root sys f kernel/drv/ksensor.conf 0644 root sys -f kernel/drv/kssl.conf 0644 root sys f kernel/drv/llc1.conf 0644 root sys f kernel/drv/lockstat.conf 0644 root sys f kernel/drv/lofi.conf 0644 root sys @@ -1190,7 +1187,6 @@ d kernel/socketmod 0755 root sys d kernel/socketmod/amd64 0755 root sys f kernel/socketmod/amd64/datafilt 0755 root sys h kernel/socketmod/amd64/icmp=kernel/drv/amd64/icmp -f kernel/socketmod/amd64/ksslf 0755 root sys f kernel/socketmod/amd64/lx_netlink 0755 root sys f kernel/socketmod/amd64/rts 0755 root sys f kernel/socketmod/amd64/sockrds 0755 root sys @@ -2496,7 +2492,7 @@ f usr/bin/amd64/ficl-sys 0555 root bin f usr/bin/amd64/gcore 0555 root bin f usr/bin/amd64/ksh93 0555 root bin h usr/bin/amd64/ksh=usr/bin/amd64/ksh93 -f usr/bin/amd64/ld 0755 root bin +s usr/bin/amd64/ld=usr/bin/ld f usr/bin/amd64/ldd 0555 root bin f usr/bin/amd64/ls 0555 root bin f usr/bin/amd64/mac 0555 root bin @@ -3329,11 +3325,6 @@ f usr/include/inet/ipsecah.h 0644 root bin f usr/include/inet/ipsecesp.h 0644 root bin f usr/include/inet/iptun.h 0644 root bin f usr/include/inet/keysock.h 0644 root bin -d usr/include/inet/kssl 0755 root bin -f usr/include/inet/kssl/kssl.h 0644 root bin -f usr/include/inet/kssl/ksslapi.h 0644 root bin -f usr/include/inet/kssl/ksslimpl.h 0644 root bin -f usr/include/inet/kssl/ksslproto.h 0644 root bin f usr/include/inet/led.h 0644 root bin f usr/include/inet/mi.h 0644 root bin f usr/include/inet/mib2.h 0644 root bin @@ -6652,7 +6643,6 @@ d usr/lib/krb5/plugins 0755 root bin d usr/lib/krb5/plugins/preauth 0755 root bin f usr/lib/krb5/plugins/preauth/pkinit.so.1 0755 root bin s usr/lib/krb5/plugins/preauth/pkinit.so=pkinit.so.1 -f usr/lib/kssladm 0555 root bin f usr/lib/labeld 0555 root bin d usr/lib/ld 0755 root bin s usr/lib/ld.so.1=../../lib/ld.so.1 @@ -10970,7 +10960,6 @@ f usr/sbin/iscsiadm 0555 root bin f usr/sbin/itadm 0555 root bin f usr/sbin/keyserv 0555 root sys f usr/sbin/killall 0555 root bin -f usr/sbin/ksslcfg 0555 root bin s usr/sbin/labelit=clri f usr/sbin/ldapaddent 0555 root bin f usr/sbin/ldapclient 0555 root bin @@ -19681,7 +19670,6 @@ f usr/share/man/man8/itadm.8 0444 root bin f usr/share/man/man8/kernel.8 0444 root bin f usr/share/man/man8/keyserv.8 0444 root bin f usr/share/man/man8/killall.8 0444 root bin -f usr/share/man/man8/ksslcfg.8 0444 root bin f usr/share/man/man8/kstat.8 0444 root bin f usr/share/man/man8/labelit.8 0444 root bin f usr/share/man/man8/labelit_hsfs.8 0444 root bin @@ -19962,7 +19950,9 @@ f usr/share/man/man9e/ks_snapshot.9e 0444 root bin f usr/share/man/man9e/ks_update.9e 0444 root bin f usr/share/man/man9e/mac.9e 0444 root bin f usr/share/man/man9e/mac_capab_led.9e 0444 root bin +f usr/share/man/man9e/mac_capab_rings.9e 0444 root bin f usr/share/man/man9e/mac_capab_transceiver.9e 0444 root bin +f usr/share/man/man9e/mac_filter.9e 0444 root bin s usr/share/man/man9e/mc_close.9e=mc_open.9e f usr/share/man/man9e/mc_getcapab.9e 0444 root bin f usr/share/man/man9e/mc_getprop.9e 0444 root bin @@ -19980,6 +19970,21 @@ f usr/share/man/man9e/mc_unicst.9e 0444 root bin s usr/share/man/man9e/mcl_set.9e=mac_capab_led.9e s usr/share/man/man9e/mct_info.9e=mac_capab_transceiver.9e s usr/share/man/man9e/mct_read.9e=mac_capab_transceiver.9e +s usr/share/man/man9e/mgi_addmac.9e=mac_filter.9e +s usr/share/man/man9e/mgi_addvlan.9e=mac_filter.9e +s usr/share/man/man9e/mgi_remmac.9e=mac_filter.9e +s usr/share/man/man9e/mgi_remvlan.9e=mac_filter.9e +f usr/share/man/man9e/mgi_start.9e 0444 root bin +s usr/share/man/man9e/mgi_stop.9e=mgi_start.9e +s usr/share/man/man9e/mi_disable.9e=mi_enable.9e +f usr/share/man/man9e/mi_enable.9e 0444 root bin +f usr/share/man/man9e/mr_gget.9e 0444 root bin +f usr/share/man/man9e/mr_rget.9e 0444 root bin +f usr/share/man/man9e/mri_poll.9e 0444 root bin +s usr/share/man/man9e/mri_start.9e=mgi_start.9e +f usr/share/man/man9e/mri_stat.9e 0444 root bin +s usr/share/man/man9e/mri_stop.9e=mgi_start.9e +s usr/share/man/man9e/mri_tx.9e=mc_tx.9e f usr/share/man/man9e/mmap.9e 0444 root bin f usr/share/man/man9e/open.9e 0444 root bin f usr/share/man/man9e/power.9e 0444 root bin @@ -20830,10 +20835,12 @@ s usr/share/man/man9f/mac_prop_info_set_default_uint8.9f=mac_prop_info.9f s usr/share/man/man9f/mac_prop_info_set_perm.9f=mac_prop_info.9f s usr/share/man/man9f/mac_prop_info_set_range_uint32.9f=mac_prop_info.9f f usr/share/man/man9f/mac_register.9f 0444 root bin +s usr/share/man/man9f/mac_ring_rx.9f=mac_rx.9f f usr/share/man/man9f/mac_rx.9f 0444 root bin f usr/share/man/man9f/mac_transceiver_info.9f 0444 root bin s usr/share/man/man9f/mac_transceiver_info_set_present.9f=mac_transceiver_info.9f s usr/share/man/man9f/mac_transceiver_info_set_usable.9f=mac_transceiver_info.9f +s usr/share/man/man9f/mac_tx_ring_update.9f=mac_tx_update.9f f usr/share/man/man9f/mac_tx_update.9f 0444 root bin s usr/share/man/man9f/mac_unregister.9f=mac_register.9f f usr/share/man/man9f/makecom.9f 0444 root bin @@ -21387,8 +21394,14 @@ f usr/share/man/man9s/kstat_named.9s 0444 root bin f usr/share/man/man9s/linkblk.9s 0444 root bin f usr/share/man/man9s/mac_callbacks.9s 0444 root bin s usr/share/man/man9s/mac_callbacks_t.9s=mac_callbacks.9s +f usr/share/man/man9s/mac_group_info.9s 0444 root bin +s usr/share/man/man9s/mac_group_info_t.9s=mac_group_info.9s +f usr/share/man/man9s/mac_intr.9s 0444 root bin +s usr/share/man/man9s/mac_intr_t.9s=mac_intr.9s f usr/share/man/man9s/mac_register.9s 0444 root bin s usr/share/man/man9s/mac_register_t.9s=mac_register.9s +f usr/share/man/man9s/mac_ring_info.9s 0444 root bin +s usr/share/man/man9s/mac_ring_info_t.9s=mac_ring_info.9s s usr/share/man/man9s/mblk.9s=msgb.9s f usr/share/man/man9s/modldrv.9s 0444 root bin f usr/share/man/man9s/modlinkage.9s 0444 root bin diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs index 79d2990e95..6dcd346271 100644 --- a/usr/src/Targetdirs +++ b/usr/src/Targetdirs @@ -24,7 +24,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright (c) 2012, Igor Kozhukhov <ikozhukhov@gmail.com> # Copyright 2012 OmniTI Computer Consulting, Inc. All rights reserved. -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> # Copyright 2017 Nexenta Systems, Inc. # Copyright 2017 RackTop Systems. @@ -227,7 +227,6 @@ DIRS= \ /lib/svc/manifest/network/rpc \ /lib/svc/manifest/network/security \ /lib/svc/manifest/network/shares \ - /lib/svc/manifest/network/ssl \ /lib/svc/manifest/application \ /lib/svc/manifest/application/management \ /lib/svc/manifest/application/security \ @@ -441,7 +440,6 @@ DIRS= \ /var/svc/manifest/network/routing \ /var/svc/manifest/network/security \ /var/svc/manifest/network/shares \ - /var/svc/manifest/network/ssl \ /var/svc/manifest/application \ /var/svc/manifest/application/management \ /var/svc/manifest/application/print \ diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index ee48155eb7..6ec72af057 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -34,4 +34,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2022.05.27.1 +BOOT_VERSION = $(LOADER_VERSION)-2022.06.27.1 diff --git a/usr/src/boot/i386/gptzfsboot/sio.S b/usr/src/boot/i386/gptzfsboot/sio.S index ca9d0a2406..27c25006b2 100644 --- a/usr/src/boot/i386/gptzfsboot/sio.S +++ b/usr/src/boot/i386/gptzfsboot/sio.S @@ -11,13 +11,14 @@ * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. - * - * $FreeBSD$ */ - .set SIO_PRT,SIOPRT # Base port .set SIO_FMT,SIOFMT # 8N1 +/* int sio_port */ +sio_port: .long SIOPRT # Base port + + .globl sio_port .globl sio_init .globl sio_flush .globl sio_putc @@ -27,13 +28,15 @@ /* int sio_init(int div) */ sio_init: pushl %eax - movw $SIO_PRT+0x3,%dx # Data format reg + movl (sio_port),%edx + addl $0x3,%edx # Data format reg movb $SIO_FMT|0x80,%al # Set format outb %al,(%dx) # and DLAB subb $0x3,%dl # Divisor latch reg popl %eax outw %ax,(%dx) # BPS - movw $SIO_PRT+0x3,%dx # Data format reg + movl (sio_port),%edx + addl $0x3,%edx # Data format reg movb $SIO_FMT,%al # Clear outb %al,(%dx) # DLAB incl %edx # Modem control reg @@ -55,7 +58,8 @@ sio_flush.2: ret # To caller /* void sio_putc(int c) */ sio_putc: pushl %eax - movw $SIO_PRT+0x5,%dx # Line status reg + movl (sio_port),%edx + addl $0x5,%edx # Line status reg xor %ecx,%ecx # Timeout movb $0x40,%ch # counter sio_putc.1: inb (%dx),%al # Transmitter @@ -77,7 +81,8 @@ sio_getc.1: subb $0x5,%dl # Receiver buffer reg /* int sio_ischar(void) */ -sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register +sio_ischar: movl (sio_port),%edx + addl $0x5,%edx # Line status register xorl %eax,%eax # Zero inb (%dx),%al # Received data andb $0x1,%al # ready? diff --git a/usr/src/boot/i386/gptzfsboot/zfsboot.c b/usr/src/boot/i386/gptzfsboot/zfsboot.c index 37ab14ccd9..aa2f2ef341 100644 --- a/usr/src/boot/i386/gptzfsboot/zfsboot.c +++ b/usr/src/boot/i386/gptzfsboot/zfsboot.c @@ -105,6 +105,7 @@ static const struct string { }; static const unsigned char dev_maj[NDEV] = {30, 4, 2}; +extern int sio_port; static struct i386_devdesc *bdev; static char cmd[512]; @@ -155,6 +156,7 @@ main(void) bool auto_boot; bool nextboot = false; struct disk_devdesc devdesc; + char *ptr; bios_getmem(); @@ -169,6 +171,40 @@ main(void) setheap(heap_bottom, heap_top); /* + * detect ACPI for future reference. This may set console to comconsole + * if we do have ACPI SPCR table. + */ + biosacpi_detect(); + ptr = getenv("console"); + if (ptr != NULL && strcmp(ptr, "text") != 0) { + char mode[10]; + + ioctrl = IO_SERIAL; + snprintf(mode, sizeof (mode), "%s-mode", ptr); + + switch (ptr[3]) { + case 'a': + sio_port = 0x3F8; + break; + case 'b': + sio_port = 0x2F8; + break; + case 'c': + sio_port = 0x3E8; + break; + case 'd': + sio_port = 0x2E8; + break; + } + ptr = getenv(mode); + if (ptr != NULL) { + comspeed = strtoul(ptr, NULL, 0); + if (sio_init(115200 / comspeed) != 0) + ioctrl |= IO_KEYBOARD; + } + } + + /* * Initialise the block cache. Set the upper limit. */ bcache_init(32768, 512); diff --git a/usr/src/boot/i386/libi386/biosacpi.c b/usr/src/boot/i386/libi386/biosacpi.c index a82862dd3f..8de99f0c95 100644 --- a/usr/src/boot/i386/libi386/biosacpi.c +++ b/usr/src/boot/i386/libi386/biosacpi.c @@ -37,6 +37,7 @@ #define ACPI_SYSTEM_XFACE #include "actypes.h" #include "actbl.h" +#include "actbl3.h" /* * Detect ACPI and export information about the ACPI BIOS into the @@ -49,37 +50,165 @@ static ACPI_TABLE_RSDP *biosacpi_search_rsdp(char *base, int length); #define RSDP_CHECKSUM_LENGTH 20 +static ACPI_TABLE_SPCR * +find_spcr(ACPI_TABLE_RSDP *rsdp) +{ + unsigned count, i; + ACPI_TABLE_XSDT *xsdt; + ACPI_TABLE_RSDT *rsdt; + void *ptr; + + if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { + xsdt = (ACPI_TABLE_XSDT *) + PTOV((uintptr_t)rsdp->XsdtPhysicalAddress); + + count = xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER); + count /= sizeof (xsdt->TableOffsetEntry[0]); + for (i = 0; i < count; i++) { + ptr = PTOV((uintptr_t)xsdt->TableOffsetEntry[i]); + if (memcmp(ptr, ACPI_SIG_SPCR, + sizeof (ACPI_SIG_SPCR) - 1) == 0) { + return (ptr); + } + } + } + if (rsdp->RsdtPhysicalAddress != 0) { + rsdt = (ACPI_TABLE_RSDT *)PTOV(rsdp->RsdtPhysicalAddress); + + count = rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER); + count /= sizeof (rsdt->TableOffsetEntry[0]); + for (i = 0; i < count; i++) { + ptr = PTOV(rsdt->TableOffsetEntry[i]); + if (memcmp(ptr, ACPI_SIG_SPCR, + sizeof (ACPI_SIG_SPCR) - 1) == 0) { + return (ptr); + } + } + } + return (NULL); +} + +/* + * Find and parse SPCR table to set up serial console. + */ +static void +biosacpi_setup_spcr(ACPI_TABLE_SPCR *spcr) +{ + unsigned baudrate; + const char *port; + char *name, *value; + + if (spcr == NULL) + return; + + switch (spcr->BaudRate) { + case 0: + /* Use current port setting. */ + baudrate = 0; + break; + case 3: + baudrate = 9600; + break; + case 4: + baudrate = 19200; + break; + case 6: + baudrate = 57600; + break; + case 7: + baudrate = 115200; + break; + default: + return; + } + + port = NULL; + name = NULL; + value = NULL; + + switch (spcr->SerialPort.SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_IO: + if (baudrate == 0) + baudrate = comc_getspeed(spcr->SerialPort.Address); + + if (asprintf(&value, "%u,8,N,1,-", baudrate) < 0) + return; + + switch (spcr->SerialPort.Address) { + case 0x3F8: + port = "ttya"; + break; + case 0x2F8: + port = "ttyb"; + break; + case 0x3E8: + port = "ttyc"; + break; + case 0x2E8: + port = "ttyd"; + break; + default: + break; + } + break; + default: + /* XXX not implemented. */ + break; + } + + /* + * We want to set console according to SPCR. Also + * we need to store the SPCR reference value. + */ + if (port != NULL) { + if (asprintf(&name, "%s,text", port) > 0) { + setenv("console", name, 1); + free(name); + } + if (asprintf(&name, "%s-mode", port) > 0) { + setenv(name, value, 1); + free(name); + } + if (asprintf(&name, "%s-spcr-mode", port) > 0) { + setenv(name, value, 1); + free(name); + } + } + free(value); +} + void biosacpi_detect(void) { - char buf[24]; - int revision; - - /* locate and validate the RSDP */ - if ((rsdp = biosacpi_find_rsdp()) == NULL) - return; - - /* export values from the RSDP */ - sprintf(buf, "0x%08x", (unsigned int)VTOP(rsdp)); - setenv("acpi.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("acpi.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("acpi.oem", buf, 1); - sprintf(buf, "0x%08x", rsdp->RsdtPhysicalAddress); - setenv("acpi.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("acpi.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("acpi.xsdt_length", buf, 1); - } + char buf[24]; + int revision; + + /* locate and validate the RSDP */ + if ((rsdp = biosacpi_find_rsdp()) == NULL) + return; + + /* export values from the RSDP */ + sprintf(buf, "0x%08x", (unsigned int)VTOP(rsdp)); + setenv("acpi.rsdp", buf, 1); + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + snprintf(buf, sizeof (buf), "%d", revision); + setenv("acpi.revision", buf, 1); + strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); + buf[sizeof (rsdp->OemId)] = '\0'; + setenv("acpi.oem", buf, 1); + snprintf(buf, sizeof (buf), "0x%08x", rsdp->RsdtPhysicalAddress); + setenv("acpi.rsdt", buf, 1); + if (revision >= 2) { + /* XXX extended checksum? */ + snprintf(buf, sizeof (buf), "0x%016llx", + (unsigned long long)rsdp->XsdtPhysicalAddress); + setenv("acpi.xsdt", buf, 1); + sprintf(buf, "%d", rsdp->Length); + setenv("acpi.xsdt_length", buf, 1); + } + biosacpi_setup_spcr(find_spcr(rsdp)); } /* diff --git a/usr/src/boot/i386/libi386/comconsole.c b/usr/src/boot/i386/libi386/comconsole.c index 4c351d16bf..1a9e788e88 100644 --- a/usr/src/boot/i386/libi386/comconsole.c +++ b/usr/src/boot/i386/libi386/comconsole.c @@ -77,7 +77,7 @@ static void comc_probe(struct console *); static int comc_init(struct console *, int); static void comc_putchar(struct console *, int); static int comc_getchar(struct console *); -static int comc_getspeed(struct serial *); +int comc_getspeed(int); static int comc_ischar(struct console *); static int comc_ioctl(struct console *, int, void *); static uint32_t comc_parse_pcidev(const char *); @@ -164,7 +164,7 @@ comc_probe(struct console *cp) struct serial *port; char name[20]; char value[20]; - char *cons, *env; + char *env; if (cp->c_private != NULL) return; @@ -190,17 +190,11 @@ comc_probe(struct console *cp) * Assume that the speed was set by an earlier boot loader if * comconsole is already the preferred console. */ - cons = getenv("console"); - if ((cons != NULL && strcmp(cons, cp->c_name) == 0) || - getenv("boot_multicons") != NULL) { - port->speed = comc_getspeed(port); - } - snprintf(name, sizeof (name), "%s-mode", cp->c_name); env = getenv(name); - if (env != NULL) { - (void) comc_parse_mode(port, env); + /* (void) comc_parse_mode(port, env);*/ + port->speed = comc_getspeed(port->ioaddr); } env = comc_asprint_mode(port); @@ -422,6 +416,7 @@ static int comc_mode_set(struct env_var *ev, int flags, const void *value) { struct console *cp; + char name[15]; if (value == NULL) return (CMD_ERROR); @@ -429,12 +424,14 @@ comc_mode_set(struct env_var *ev, int flags, const void *value) if ((cp = get_console(ev->ev_name)) == NULL) return (CMD_ERROR); - if (comc_parse_mode(cp->c_private, value) == CMD_ERROR) - return (CMD_ERROR); - - (void) comc_setup(cp); - - env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + /* Do not override serial setup from SPCR */ + snprintf(name, sizeof (name), "%s-spcr-mode", cp->c_name); + if (getenv(name) == NULL) { + if (comc_parse_mode(cp->c_private, value) == CMD_ERROR) + return (CMD_ERROR); + (void) comc_setup(cp); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + } return (CMD_OK); } @@ -635,21 +632,21 @@ comc_setup(struct console *cp) return (true); } -static int -comc_getspeed(struct serial *sp) +int +comc_getspeed(int ioaddr) { uint_t divisor; uchar_t dlbh; uchar_t dlbl; uchar_t cfcr; - cfcr = inb(sp->ioaddr + com_cfcr); - outb(sp->ioaddr + com_cfcr, CFCR_DLAB | cfcr); + cfcr = inb(ioaddr + com_cfcr); + outb(ioaddr + com_cfcr, CFCR_DLAB | cfcr); - dlbl = inb(sp->ioaddr + com_dlbl); - dlbh = inb(sp->ioaddr + com_dlbh); + dlbl = inb(ioaddr + com_dlbl); + dlbh = inb(ioaddr + com_dlbh); - outb(sp->ioaddr + com_cfcr, cfcr); + outb(ioaddr + com_cfcr, cfcr); divisor = dlbh << 8 | dlbl; diff --git a/usr/src/boot/i386/libi386/libi386.h b/usr/src/boot/i386/libi386/libi386.h index 3f769ee688..866a6590b8 100644 --- a/usr/src/boot/i386/libi386/libi386.h +++ b/usr/src/boot/i386/libi386/libi386.h @@ -130,6 +130,7 @@ uint32_t biospci_locator(int8_t bus, uint8_t device, uint8_t function); int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val); void biosacpi_detect(void); +int comc_getspeed(int); int i386_autoload(void); vm_offset_t i386_loadaddr(u_int type, void *data, vm_offset_t addr); diff --git a/usr/src/boot/i386/loader/main.c b/usr/src/boot/i386/loader/main.c index dc21e0d2b3..8fba0e1a04 100644 --- a/usr/src/boot/i386/loader/main.c +++ b/usr/src/boot/i386/loader/main.c @@ -115,6 +115,9 @@ main(void) } setheap(heap_bottom, heap_top); + /* detect ACPI for future reference */ + biosacpi_detect(); + /* * XXX Chicken-and-egg problem; we want to have console output early, * but some console attributes may depend on reading from eg. the boot @@ -182,9 +185,6 @@ main(void) initial_bootinfo->bi_extmem = bios_extmem / 1024; } - /* detect ACPI for future reference */ - biosacpi_detect(); - /* detect SMBIOS for future reference */ smbios_detect(NULL); diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index 3158bdb9a5..ba624dfc73 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -21,7 +21,7 @@ # # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2019 Peter Tribble # Copyright 2021 Tintri by DDN, Inc. All rights reserved. # @@ -100,7 +100,6 @@ MANIFEST_SUBDIRS= \ cmd-inet/usr.sbin/in.routed \ cmd-inet/usr.sbin/in.talkd \ cmd-inet/usr.sbin/ipsecutils \ - cmd-inet/usr.sbin/kssl/ksslcfg \ cmd-inet/usr.sbin/routeadm \ dcs/sparc/sun4u \ dfs.cmds/sharemgr \ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/Makefile index da9625bf85..3f794a331a 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile +++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile @@ -21,7 +21,7 @@ # # Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2019, Joyent, Inc. # @@ -33,7 +33,7 @@ PROG= 6to4relay arp if_mpadm \ ndd ndp $(SYNCPROG) MANIFEST= rarp.xml telnet.xml comsat.xml finger.xml \ - login.xml shell.xml rexec.xml socket-filter-kssl.xml + login.xml shell.xml rexec.xml SVCMETHOD= svc-sockfilter ROOTFS_PROG= hostconfig route soconfig @@ -64,12 +64,12 @@ SRCS= $(PROGSRCS) $(OTHERSRC) SUBDIRS= ifconfig ilbadm in.rdisc in.routed \ in.talkd inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \ - kssl/kssladm kssl/ksslcfg nwamadm nwamcfg ping routeadm \ + nwamadm nwamcfg ping routeadm \ snoop sppptun traceroute wificonfig MSGSUBDIRS= ifconfig ilbadm in.routed in.talkd \ inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \ - kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop wificonfig + nwamadm nwamcfg routeadm sppptun snoop wificonfig # This controls the degree of compiler warnings emitted, and is named for # 'lint' for historical reasons. Eventually this hack should go away, and all diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile deleted file mode 100644 index 00f4ffdb2e..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile +++ /dev/null @@ -1,66 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile -# - -PROG= kssladm - -include $(SRC)/cmd/Makefile.cmd - -OBJS = \ - kssladm.o \ - kssladm_create.o \ - kssladm_delete.o \ - ksslutil.o - -SRCS = $(OBJS:%.o=%.c) - -ROOTUSRLIBPROG = $(PROG:%=$(ROOTLIB)/%) - -.KEEP_STATE: - -CFLAGS += $(CCVERBOSE) -CERRWARN += $(CNOWARN_UNINIT) -CERRWARN += -_gcc=-Wno-address - -LDLIBS += -lkmf -lpkcs11 -lcryptoutil -lnsl -lsocket - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTUSRLIBPROG) - -clean: - $(RM) $(OBJS) - -check: - $(CSTYLE) -pP $(SRCS) - -lint: lint_SRCS - -include ../../../../Makefile.targ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.c deleted file mode 100644 index 7eab57d0cc..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.c +++ /dev/null @@ -1,166 +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. - */ - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <strings.h> -#include <libscf.h> -#include <sys/errno.h> -#include <errno.h> -#include <sys/stropts.h> -#include "kssladm.h" - - -/* - * kssladm(8) - * - * Command to manage the entries in kernel SSL proxy table. This is - * a private command called indirectly from ksslcfg(8). - */ - -boolean_t verbose = B_FALSE; - -static void -usage_all(void) -{ - (void) fprintf(stderr, "Usage:\n"); - usage_create(B_FALSE); - usage_delete(B_FALSE); -} - -int -main(int argc, char **argv) -{ - int rv = SUCCESS; - - if (argc < 2) { - usage_all(); - return (SMF_EXIT_ERR_CONFIG); - } - - if (strcmp(argv[1], "create") == 0) { - rv = do_create(argc, argv); - } else if (strcmp(argv[1], "delete") == 0) { - rv = do_delete(argc, argv); - } else { - (void) fprintf(stderr, "Unknown sub-command: %s\n", argv[1]); - usage_all(); - rv = SMF_EXIT_ERR_CONFIG; - } - - return (rv); -} - - -/* - * Read a passphrase from the file into the supplied buffer. - * A space character and the characters that follow - * the space character will be ignored. - * Return 0 when no valid passphrase was found in the file. - */ -static int -read_pass_from_file(const char *filename, char *buffer, size_t bufsize) -{ - char *line; - char *p; - FILE *fp; - - fp = fopen(filename, "r"); - if (fp == NULL) { - (void) fprintf(stderr, - "Unable to open password file for reading"); - return (1); - } - - line = fgets(buffer, bufsize, fp); - (void) fclose(fp); - if (line == NULL) { - return (0); - } - - for (p = buffer; *p != '\0'; p++) { - if (isspace(*p)) { - *p = '\0'; - break; - } - } - - return (p - buffer); -} - - -int -get_passphrase(const char *password_file, char *buf, int buf_size) -{ - if (password_file == NULL) { - char *passphrase = getpassphrase("Enter passphrase: "); - if (passphrase) { - return (strlcpy(buf, passphrase, buf_size)); - } - - return (0); - } - - return (read_pass_from_file(password_file, buf, buf_size)); -} - - -int -kssl_send_command(char *buf, int cmd) -{ - int ksslfd; - int rv; - - ksslfd = open("/dev/kssl", O_RDWR); - if (ksslfd < 0) { - perror("Cannot open /dev/kssl"); - return (-1); - } - - if ((rv = ioctl(ksslfd, cmd, buf)) < 0) { - switch (errno) { - case EEXIST: - (void) fprintf(stderr, - "Error: Can not create a INADDR_ANY instance" - " while another instance exists.\n"); - break; - case EADDRINUSE: - (void) fprintf(stderr, - "Error: Another instance with the same" - " proxy port exists.\n"); - break; - default: - perror("ioctl failure"); - break; - } - } - - (void) close(ksslfd); - - return (rv); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h deleted file mode 100644 index 2029365f56..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h +++ /dev/null @@ -1,77 +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. - */ - -#ifndef _KSSLADM_H -#define _KSSLADM_H - -/* - * Common routines and variables used by kssladm files. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <netinet/in.h> -#include <kmfapi.h> - -#define SUCCESS 0 -#define FAILURE 1 -#define ERROR_USAGE 2 - -#define MAX_CHAIN_LENGTH 12 -#define REPORT_KMF_ERROR(r, t, e) { \ - (void) kmf_get_kmf_error_str(r, &e); \ - (void) fprintf(stderr, t ": %s\n", \ - (e != NULL ? e : "<unknown error>")); \ - if (e) free(e); \ -} - -#define MAX_ATTR_CNT 8 - -extern boolean_t verbose; - -extern int do_create(int argc, char *argv[]); -extern int do_delete(int argc, char *argv[]); -extern void usage_create(boolean_t do_print); -extern void usage_delete(boolean_t do_print); - -extern int PEM_get_rsa_key_certs(KMF_HANDLE_T, const char *, - char *, KMF_RAW_KEY_DATA **, KMF_X509_DER_CERT **); - -extern int PKCS12_get_rsa_key_certs(KMF_HANDLE_T, const char *, - const char *, KMF_RAW_KEY_DATA **, KMF_X509_DER_CERT **); - -extern int get_passphrase(const char *password_file, char *buf, int buf_size); -extern int kssl_send_command(char *buf, int cmd); -extern int parse_and_set_addr(char *arg1, char *arg2, - struct sockaddr_in6 *addr); - -#ifdef __cplusplus -} -#endif - -#endif /* _KSSLADM_H */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c deleted file mode 100644 index 7f3233154f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c +++ /dev/null @@ -1,1224 +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 <errno.h> -#include <sys/sysmacros.h> -#include <security/cryptoki.h> -#include <security/pkcs11.h> -#include <stdio.h> -#include <strings.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <fcntl.h> -#include <inet/kssl/kssl.h> -#include <cryptoutil.h> -#include <libscf.h> -#include "kssladm.h" - -#include <kmfapi.h> - -void -usage_create(boolean_t do_print) -{ - if (do_print) - (void) fprintf(stderr, "Usage:\n"); - (void) fprintf(stderr, "kssladm create" - " -f pkcs11 [-d softtoken_directory] -T <token_label>" - " -C <certificate_label> -x <proxy_port>" - " [-h <ca_certchain_file>]" - " [options] [<server_address>] [<server_port>]\n"); - - (void) fprintf(stderr, "kssladm create" - " -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>" - " [options] [<server_address>] [<server_port>]\n"); - - (void) fprintf(stderr, "kssladm create" - " -f pem -i <cert_and_key_pemfile> -x <proxy_port>" - " [options] [<server_address>] [<server_port>]\n"); - - (void) fprintf(stderr, "options are:\n" - "\t[-c <ciphersuites>]\n" - "\t[-p <password_file>]\n" - "\t[-t <ssl_session_cache_timeout>]\n" - "\t[-z <ssl_session_cache_size>]\n" - "\t[-v]\n"); -} - -/* - * Everything is allocated in one single contiguous buffer. - * The layout is the following: - * . the kssl_params_t structure - * . optional buffer containing pin (if key is non extractable) - * . the array of key attribute structs, (value of ck_attrs) - * . the key attributes values (values of ck_attrs[i].ck_value); - * . the array of sizes of the certificates, (referred to as sc_sizes[]) - * . the certificates values (referred to as sc_certs[]) - * - * The address of the certs and key attributes values are offsets - * from the beginning of the big buffer. sc_sizes_offset points - * to sc_sizes[0] and sc_certs_offset points to sc_certs[0]. - */ -static kssl_params_t * -kmf_to_kssl(int nxkey, KMF_RAW_KEY_DATA *rsa, int ncerts, - KMF_X509_DER_CERT *certs, int *paramsize, - char *token_label, KMF_DATA *idstr, - KMF_CREDENTIAL *creds) -{ - int i, tcsize; - kssl_params_t *kssl_params; - kssl_key_t *key; - char *buf; - uint32_t bufsize; - static CK_BBOOL true = TRUE; - static CK_BBOOL false = FALSE; - static CK_OBJECT_CLASS class = CKO_PRIVATE_KEY; - static CK_KEY_TYPE keytype = CKK_RSA; - kssl_object_attribute_t kssl_attrs[MAX_ATTR_CNT]; - CK_ATTRIBUTE exkey_attrs[MAX_ATTR_CNT] = { - {CKA_TOKEN, &true, sizeof (true)}, - {CKA_EXTRACTABLE, &false, sizeof (false)}, - {CKA_CLASS, &class, sizeof (class) }, - {CKA_KEY_TYPE, &keytype, sizeof (keytype) }, - {CKA_ID, NULL, 0} - }; - kssl_object_attribute_t kssl_tmpl_attrs[MAX_ATTR_CNT] = { - {SUN_CKA_MODULUS, 0, 0}, - {SUN_CKA_PUBLIC_EXPONENT, 0, 0}, - {SUN_CKA_PRIVATE_EXPONENT, 0, 0}, - {SUN_CKA_PRIME_1, 0, 0}, - {SUN_CKA_PRIME_2, 0, 0}, - {SUN_CKA_EXPONENT_1, 0, 0}, - {SUN_CKA_EXPONENT_2, 0, 0}, - {SUN_CKA_COEFFICIENT, 0, 0} - }; - KMF_BIGINT priv_key_bignums[MAX_ATTR_CNT]; - int attr_cnt; - - if (nxkey && idstr != NULL) { - exkey_attrs[4].pValue = idstr->Data; - exkey_attrs[4].ulValueLen = idstr->Length; - } - tcsize = 0; - for (i = 0; i < ncerts; i++) - tcsize += certs[i].certificate.Length; - - bufsize = sizeof (kssl_params_t); - bufsize += (tcsize + (MAX_CHAIN_LENGTH * sizeof (uint32_t))); - - if (!nxkey) { - bzero(priv_key_bignums, sizeof (KMF_BIGINT) * - MAX_ATTR_CNT); - /* and the key attributes */ - priv_key_bignums[0] = rsa->rawdata.rsa.mod; - priv_key_bignums[1] = rsa->rawdata.rsa.pubexp; - priv_key_bignums[2] = rsa->rawdata.rsa.priexp; - priv_key_bignums[3] = rsa->rawdata.rsa.prime1; - priv_key_bignums[4] = rsa->rawdata.rsa.prime2; - priv_key_bignums[5] = rsa->rawdata.rsa.exp1; - priv_key_bignums[6] = rsa->rawdata.rsa.exp2; - priv_key_bignums[7] = rsa->rawdata.rsa.coef; - - if (rsa->rawdata.rsa.mod.val == NULL || - rsa->rawdata.rsa.priexp.val == NULL) { - (void) fprintf(stderr, - "missing required attributes in private key.\n"); - return (NULL); - } - - attr_cnt = 0; - for (i = 0; i < MAX_ATTR_CNT; i++) { - if (priv_key_bignums[i].val == NULL) - continue; - kssl_attrs[attr_cnt].ka_type = - kssl_tmpl_attrs[i].ka_type; - kssl_attrs[attr_cnt].ka_value_len = - priv_key_bignums[i].len; - bufsize += sizeof (crypto_object_attribute_t) + - kssl_attrs[attr_cnt].ka_value_len; - attr_cnt++; - } - } else { - /* - * Compute space for the attributes and values that the - * kssl kernel module will need in order to search for - * the private key. - */ - for (attr_cnt = 0; attr_cnt < 5; attr_cnt++) { - bufsize += sizeof (crypto_object_attribute_t) + - exkey_attrs[attr_cnt].ulValueLen; - } - if (creds) - bufsize += creds->credlen; - } - - /* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */ - bufsize += sizeof (uint32_t); - - /* Now the big memory allocation */ - if ((buf = calloc(bufsize, 1)) == NULL) { - (void) fprintf(stderr, - "Cannot allocate memory for the kssl_params " - "and values\n"); - return (NULL); - } - - /* LINTED */ - kssl_params = (kssl_params_t *)buf; - - buf = (char *)(kssl_params + 1); - - if (!nxkey) { - /* the keys attributes structs array */ - key = &kssl_params->kssl_privkey; - key->ks_format = CRYPTO_KEY_ATTR_LIST; - key->ks_count = attr_cnt; - key->ks_attrs_offset = buf - (char *)kssl_params; - buf += attr_cnt * sizeof (kssl_object_attribute_t); - - attr_cnt = 0; - /* then the key attributes values */ - for (i = 0; i < MAX_ATTR_CNT; i++) { - if (priv_key_bignums[i].val == NULL) - continue; - (void) memcpy(buf, priv_key_bignums[i].val, - priv_key_bignums[i].len); - kssl_attrs[attr_cnt].ka_value_offset = - buf - (char *)kssl_params; - buf += kssl_attrs[attr_cnt].ka_value_len; - attr_cnt++; - } - } else { - char tlabel[CRYPTO_EXT_SIZE_LABEL]; - bzero(tlabel, sizeof (tlabel)); - (void) strlcpy(tlabel, token_label, sizeof (tlabel)); - - /* - * For a non-extractable key, we must provide the PIN - * so the kssl module can access the token to find - * the key handle. - */ - kssl_params->kssl_is_nxkey = 1; - bcopy(tlabel, kssl_params->kssl_token.toklabel, - CRYPTO_EXT_SIZE_LABEL); - kssl_params->kssl_token.pinlen = creds->credlen; - kssl_params->kssl_token.tokpin_offset = - buf - (char *)kssl_params; - kssl_params->kssl_token.ck_rv = 0; - bcopy(creds->cred, buf, creds->credlen); - buf += creds->credlen; - - /* - * Next in the buffer, we must provide the attributes - * that the kssl module will use to search in the - * token to find the protected key handle. - */ - key = &kssl_params->kssl_privkey; - key->ks_format = CRYPTO_KEY_ATTR_LIST; - key->ks_count = attr_cnt; - key->ks_attrs_offset = buf - (char *)kssl_params; - - buf += attr_cnt * sizeof (kssl_object_attribute_t); - for (i = 0; i < attr_cnt; i++) { - bcopy(exkey_attrs[i].pValue, buf, - exkey_attrs[i].ulValueLen); - - kssl_attrs[i].ka_type = exkey_attrs[i].type; - kssl_attrs[i].ka_value_offset = - buf - (char *)kssl_params; - kssl_attrs[i].ka_value_len = exkey_attrs[i].ulValueLen; - - buf += exkey_attrs[i].ulValueLen; - } - } - /* Copy the key attributes array here */ - bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset, - attr_cnt * sizeof (kssl_object_attribute_t)); - - buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t)); - - /* - * Finally, add the certificate chain to the buffer. - */ - kssl_params->kssl_certs.sc_count = ncerts; - - /* First, an array of certificate sizes */ - for (i = 0; i < ncerts; i++) { - uint32_t certsz = (uint32_t)certs[i].certificate.Length; - char *p = buf + (i * sizeof (uint32_t)); - bcopy(&certsz, p, sizeof (uint32_t)); - } - - kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params; - buf += MAX_CHAIN_LENGTH * sizeof (uint32_t); - - kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params; - - /* Now add the certificate data (ASN.1 DER encoded) */ - for (i = 0; i < ncerts; i++) { - bcopy(certs[i].certificate.Data, buf, - certs[i].certificate.Length); - buf += certs[i].certificate.Length; - } - - *paramsize = bufsize; - return (kssl_params); -} - -/* - * Extract a sensitive key via wrap/unwrap operations. - * - * This function requires that we call PKCS#11 API directly since - * KMF does not yet support wrapping/unwrapping of keys. By extracting - * a sensitive key in wrapped form, we then unwrap it into a session key - * object. KMF is then used to find the session key and return it in - * KMF_RAW_KEY format which is then passed along to KSSL by the caller. - */ -static KMF_RETURN -get_sensitive_key_data(KMF_HANDLE_T kmfh, - KMF_CREDENTIAL *creds, char *keylabel, - char *idstr, KMF_KEY_HANDLE *key, KMF_KEY_HANDLE *rawkey) -{ - KMF_RETURN rv = KMF_OK; - static CK_BYTE aes_param[16]; - static CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY; - static CK_KEY_TYPE privkey_type = CKK_RSA; - static CK_BBOOL false = FALSE; - boolean_t kmftrue = B_TRUE; - boolean_t kmffalse = B_FALSE; - char *err = NULL; - char wrapkey_label[BUFSIZ]; - int fd; - uint32_t nkeys = 0; - CK_RV ckrv; - CK_SESSION_HANDLE pk11session; - CK_BYTE aes_key_val[16]; - int numattr = 0; - int idx; - KMF_ATTRIBUTE attrlist[16]; - KMF_KEYSTORE_TYPE kstype; - KMF_KEY_CLASS kclass; - KMF_ENCODE_FORMAT format; - - CK_MECHANISM aes_cbc_pad_mech = {CKM_AES_CBC_PAD, aes_param, - sizeof (aes_param)}; - CK_OBJECT_HANDLE aes_key_obj = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE sess_privkey_obj = CK_INVALID_HANDLE; - CK_BYTE *wrapped_privkey = NULL; - CK_ULONG wrapped_privkey_len = 0; - - CK_ATTRIBUTE unwrap_tmpl[] = { - /* code below depends on the following attribute order */ - {CKA_TOKEN, &false, sizeof (false)}, - {CKA_CLASS, &privkey_class, sizeof (privkey_class)}, - {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)}, - {CKA_SENSITIVE, &false, sizeof (false)}, - {CKA_PRIVATE, &false, sizeof (false)}, - {CKA_LABEL, NULL, 0} - }; - - /* - * Create a wrap key with random data. - */ - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) { - perror("Error reading /dev/urandom"); - return (KMF_ERR_INTERNAL); - } - if (read(fd, aes_key_val, sizeof (aes_key_val)) != - sizeof (aes_key_val)) { - perror("Error reading from /dev/urandom"); - (void) close(fd); - return (KMF_ERR_INTERNAL); - } - (void) close(fd); - - pk11session = kmf_get_pk11_handle(kmfh); - - /* - * Login to create the wrap key stuff. - */ - ckrv = C_Login(pk11session, CKU_USER, - (CK_UTF8CHAR_PTR)creds->cred, creds->credlen); - if (ckrv != CKR_OK && ckrv != CKR_USER_ALREADY_LOGGED_IN) { - (void) fprintf(stderr, - "Cannot login to the token. error = %s\n", - pkcs11_strerror(ckrv)); - return (KMF_ERR_INTERNAL); - } - - /* - * Turn the random key into a PKCS#11 session object. - */ - ckrv = SUNW_C_KeyToObject(pk11session, CKM_AES_CBC_PAD, aes_key_val, - sizeof (aes_key_val), &aes_key_obj); - if (ckrv != CKR_OK) { - (void) fprintf(stderr, - "Cannot create wrapping key. error = %s\n", - pkcs11_strerror(ckrv)); - return (KMF_ERR_INTERNAL); - } - - /* - * Find the original private key that we are going to wrap. - */ - kstype = KMF_KEYSTORE_PK11TOKEN; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - kclass = KMF_ASYM_PRI; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, - &kclass, sizeof (kclass)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, - creds, sizeof (KMF_CREDENTIAL)); - numattr++; - - if (keylabel) { - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, - keylabel, strlen(keylabel)); - numattr++; - } - if (idstr) { - kmf_set_attr_at_index(attrlist, numattr, KMF_IDSTR_ATTR, - idstr, strlen(idstr)); - numattr++; - } - format = KMF_FORMAT_NATIVE; - kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, - &format, sizeof (format)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, - &kmftrue, sizeof (kmftrue)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR, - &kmftrue, sizeof (kmftrue)); - numattr++; - - nkeys = 1; - kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, - &nkeys, sizeof (nkeys)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, - key, sizeof (KMF_KEY_HANDLE)); - numattr++; - - rv = kmf_find_key(kmfh, numattr, attrlist); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error finding private key", err); - goto out; - } - - /* - * Get the size of the wrapped private key. - */ - bzero(aes_param, sizeof (aes_param)); - ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech, - aes_key_obj, (CK_OBJECT_HANDLE)key->keyp, - NULL, &wrapped_privkey_len); - if (ckrv != CKR_OK) { - /* - * Most common error here is that the token doesn't - * support the wrapping mechanism or the key is - * marked non-extractable. Return an error and let - * the caller deal with it gracefully. - */ - (void) fprintf(stderr, - "Cannot get wrap key size. error = %s\n", - pkcs11_strerror(ckrv)); - rv = KMF_ERR_INTERNAL; - goto out; - } - wrapped_privkey = malloc(wrapped_privkey_len); - if (wrapped_privkey == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - /* - * Now get the actual wrapped key data. - */ - ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech, - aes_key_obj, (CK_OBJECT_HANDLE)key->keyp, - wrapped_privkey, &wrapped_privkey_len); - if (ckrv != CKR_OK) { - (void) fprintf(stderr, - "Cannot wrap private key. error = %s\n", - pkcs11_strerror(ckrv)); - rv = KMF_ERR_INTERNAL; - goto out; - } - /* - * Create a label for the wrapped session key so we can find - * it easier later. - */ - (void) snprintf(wrapkey_label, sizeof (wrapkey_label), "ksslprikey_%d", - getpid()); - - unwrap_tmpl[5].pValue = wrapkey_label; - unwrap_tmpl[5].ulValueLen = strlen(wrapkey_label); - - /* - * Unwrap the key into the template and create a temporary - * session private key. - */ - ckrv = C_UnwrapKey(pk11session, &aes_cbc_pad_mech, aes_key_obj, - wrapped_privkey, wrapped_privkey_len, - unwrap_tmpl, 6, &sess_privkey_obj); - if (ckrv != CKR_OK) { - (void) fprintf(stderr, - "Cannot unwrap private key. error = %s\n", - pkcs11_strerror(ckrv)); - rv = KMF_ERR_INTERNAL; - goto out; - } - - /* - * Use KMF to find the session key and return it as RAW data - * so we can pass it along to KSSL. - */ - kclass = KMF_ASYM_PRI; - if ((idx = kmf_find_attr(KMF_KEYCLASS_ATTR, attrlist, numattr)) != -1) { - attrlist[idx].pValue = &kclass; - } - - format = KMF_FORMAT_RAWKEY; - if ((idx = kmf_find_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, - numattr)) != -1) { - attrlist[idx].pValue = &format; - } - if (wrapkey_label != NULL && - (idx = kmf_find_attr(KMF_KEYLABEL_ATTR, attrlist, numattr)) != -1) { - attrlist[idx].pValue = wrapkey_label; - attrlist[idx].valueLen = strlen(wrapkey_label); - } - - if ((idx = kmf_find_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, - numattr)) != -1) { - attrlist[idx].pValue = &kmffalse; - } - if ((idx = kmf_find_attr(KMF_TOKEN_BOOL_ATTR, attrlist, - numattr)) != -1) { - attrlist[idx].pValue = &kmffalse; - } - - if ((idx = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, - numattr)) != -1) { - attrlist[idx].pValue = rawkey; - } - /* - * Clear the IDSTR attribute since it is not part of the - * wrapped session key. - */ - if ((idx = kmf_find_attr(KMF_IDSTR_ATTR, attrlist, - numattr)) != -1) { - attrlist[idx].pValue = NULL; - attrlist[idx].valueLen = 0; - } - - /* The wrapped key should not be sensitive. */ - kmf_set_attr_at_index(attrlist, numattr, KMF_SENSITIVE_BOOL_ATTR, - &false, sizeof (false)); - numattr++; - - rv = kmf_find_key(kmfh, numattr, attrlist); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error finding raw private key", err); - goto out; - } -out: - if (wrapped_privkey) - free(wrapped_privkey); - - if (aes_key_obj != CK_INVALID_HANDLE) - (void) C_DestroyObject(pk11session, aes_key_obj); - - if (sess_privkey_obj != CK_INVALID_HANDLE) - (void) C_DestroyObject(pk11session, sess_privkey_obj); - - return (rv); -} - -static kssl_params_t * -load_from_pkcs11(KMF_HANDLE_T kmfh, - const char *token_label, const char *password_file, - const char *certname, int *bufsize) -{ - KMF_RETURN rv; - KMF_X509_DER_CERT cert; - KMF_KEY_HANDLE key, rawkey; - KMF_CREDENTIAL creds; - KMF_DATA iddata = { 0, NULL }; - kssl_params_t *kssl_params = NULL; - uint32_t ncerts, nkeys; - char *err, *idstr = NULL; - char password_buf[1024]; - int nxkey = 0; - int numattr = 0; - KMF_ATTRIBUTE attrlist[16]; - KMF_KEYSTORE_TYPE kstype; - KMF_KEY_CLASS kclass; - KMF_ENCODE_FORMAT format; - boolean_t false = B_FALSE; - boolean_t true = B_TRUE; - - if (get_passphrase(password_file, password_buf, - sizeof (password_buf)) <= 0) { - perror("Unable to read passphrase"); - goto done; - } - creds.cred = password_buf; - creds.credlen = strlen(password_buf); - - (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); - (void) memset(&rawkey, 0, sizeof (KMF_KEY_HANDLE)); - - kstype = KMF_KEYSTORE_PK11TOKEN; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - if (token_label && strlen(token_label)) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_TOKEN_LABEL_ATTR, - (void *)token_label, strlen(token_label)); - numattr++; - } - - kmf_set_attr_at_index(attrlist, numattr, KMF_READONLY_ATTR, - &false, sizeof (false)); - numattr++; - - rv = kmf_configure_keystore(kmfh, numattr, attrlist); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error configuring KMF keystore", err); - goto done; - } - - /* - * Find the certificate matching the given label. - */ - numattr = 0; - kstype = KMF_KEYSTORE_PK11TOKEN; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - if (certname) { - kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, - (void *)certname, strlen(certname)); - numattr++; - } - ncerts = 1; - - kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, - &ncerts, sizeof (ncerts)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR, - &cert, sizeof (cert)); - numattr++; - - rv = kmf_find_cert(kmfh, numattr, attrlist); - if (rv != KMF_OK || ncerts == 0) - goto done; - - /* - * Find the associated private key for this cert by - * keying off of the label and the ASCII ID string. - */ - rv = kmf_get_cert_id_str(&cert.certificate, &idstr); - if (rv != KMF_OK) - goto done; - - numattr = 1; /* attrlist[0] is already set to kstype */ - - kclass = KMF_ASYM_PRI; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, - &kclass, sizeof (kclass)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, - &creds, sizeof (KMF_CREDENTIAL)); - numattr++; - - format = KMF_FORMAT_RAWKEY; - kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, - &format, sizeof (format)); - numattr++; - - if (certname) { - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, - (void *)certname, strlen(certname)); - numattr++; - } - if (idstr) { - kmf_set_attr_at_index(attrlist, numattr, KMF_IDSTR_ATTR, - (void *)idstr, strlen(idstr)); - numattr++; - } - kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, - &true, sizeof (true)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR, - &true, sizeof (true)); - numattr++; - - /* We only expect to find 1 key at most */ - nkeys = 1; - kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, - &nkeys, sizeof (nkeys)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, - &key, sizeof (KMF_KEY_HANDLE)); - numattr++; - - rv = kmf_find_key(kmfh, numattr, attrlist); - if (rv == KMF_ERR_SENSITIVE_KEY) { - kmf_free_kmf_key(kmfh, &key); - /* - * Get a normal key handle and then do a wrap/unwrap - * in order to get the necessary raw data fields needed - * to send to KSSL. - */ - format = KMF_FORMAT_NATIVE; - rv = get_sensitive_key_data(kmfh, &creds, - (char *)certname, idstr, &key, &rawkey); - if (rv == KMF_OK) { - /* Swap "key" for "rawkey" */ - kmf_free_kmf_key(kmfh, &key); - - key = rawkey; - } else { - kmf_free_kmf_key(kmfh, &key); - - /* Let kssl try to find the key. */ - nxkey = 1; - rv = kmf_get_cert_id_data(&cert.certificate, &iddata); - } - } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { - kmf_free_kmf_key(kmfh, &key); - - /* Let kssl try to find the key. */ - nxkey = 1; - rv = kmf_get_cert_id_data(&cert.certificate, &iddata); - } else if (rv != KMF_OK || nkeys == 0) - goto done; - - if (rv == KMF_OK) - kssl_params = kmf_to_kssl(nxkey, (KMF_RAW_KEY_DATA *)key.keyp, - 1, &cert, bufsize, (char *)token_label, &iddata, &creds); -done: - if (ncerts != 0) - kmf_free_kmf_cert(kmfh, &cert); - if (nkeys != 0) - kmf_free_kmf_key(kmfh, &key); - if (idstr) - free(idstr); - - return (kssl_params); -} - -/* - * add_cacerts - * - * Load a chain of certificates from a PEM file. - */ -static kssl_params_t * -add_cacerts(KMF_HANDLE_T kmfh, - kssl_params_t *old_params, const char *cacert_chain_file) -{ - int i, newlen; - uint32_t certlen = 0, ncerts; - char *buf; - KMF_RETURN rv; - KMF_X509_DER_CERT *certs = NULL; - kssl_params_t *kssl_params; - char *err = NULL; - int numattr = 0; - KMF_ATTRIBUTE attrlist[16]; - KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; - - kstype = KMF_KEYSTORE_OPENSSL; - - ncerts = 0; - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (KMF_KEYSTORE_TYPE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, - (void *)cacert_chain_file, strlen(cacert_chain_file)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, - &ncerts, sizeof (ncerts)); - numattr++; - - rv = kmf_find_cert(kmfh, numattr, attrlist); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error finding CA certificates", err); - return (0); - } - certs = (KMF_X509_DER_CERT *)malloc(ncerts * - sizeof (KMF_X509_DER_CERT)); - if (certs == NULL) { - (void) fprintf(stderr, "memory allocation error.\n"); - return (NULL); - } - bzero(certs, ncerts * sizeof (KMF_X509_DER_CERT)); - - /* add new attribute for the cert list to be returned */ - kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR, - certs, (ncerts * sizeof (KMF_X509_DER_CERT))); - numattr++; - rv = kmf_find_cert(kmfh, numattr, attrlist); - - if (rv != KMF_OK || ncerts == 0) { - bzero(old_params, old_params->kssl_params_size); - free(old_params); - return (NULL); - } - - if (verbose) { - (void) printf("%d certificates read successfully\n", ncerts); - } - - newlen = old_params->kssl_params_size; - for (i = 0; i < ncerts; i++) - newlen += certs[i].certificate.Length; - - /* - * Get a bigger structure and update the - * fields to account for the additional certs. - */ - kssl_params = realloc(old_params, newlen); - - kssl_params->kssl_params_size = newlen; - kssl_params->kssl_certs.sc_count += ncerts; - - /* Put the cert size info starting from sc_sizes[1] */ - buf = (char *)kssl_params; - buf += kssl_params->kssl_certs.sc_sizes_offset; - bcopy(buf, &certlen, sizeof (uint32_t)); - buf += sizeof (uint32_t); - for (i = 0; i < ncerts; i++) { - uint32_t size = (uint32_t)certs[i].certificate.Length; - bcopy(&size, buf, sizeof (uint32_t)); - buf += sizeof (uint32_t); - } - - /* Put the cert_bufs starting from sc_certs[1] */ - buf = (char *)kssl_params; - buf += kssl_params->kssl_certs.sc_certs_offset; - buf += certlen; - - /* now the certs values */ - for (i = 0; i < ncerts; i++) { - bcopy(certs[i].certificate.Data, buf, - certs[i].certificate.Length); - buf += certs[i].certificate.Length; - } - - for (i = 0; i < ncerts; i++) - kmf_free_kmf_cert(kmfh, &certs[i]); - free(certs); - - return (kssl_params); -} - -/* - * Find a key and certificate(s) from a single PEM file. - */ -static kssl_params_t * -load_from_pem(KMF_HANDLE_T kmfh, const char *filename, - const char *password_file, int *paramsize) -{ - int ncerts = 0, i; - kssl_params_t *kssl_params; - KMF_RAW_KEY_DATA *rsa = NULL; - KMF_X509_DER_CERT *certs = NULL; - - ncerts = PEM_get_rsa_key_certs(kmfh, - filename, (char *)password_file, &rsa, &certs); - if (rsa == NULL || certs == NULL || ncerts == 0) { - return (NULL); - } - - if (verbose) - (void) printf("%d certificates read successfully\n", ncerts); - - kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL, - NULL, NULL); - - for (i = 0; i < ncerts; i++) - kmf_free_kmf_cert(kmfh, &certs[i]); - free(certs); - kmf_free_raw_key(rsa); - - return (kssl_params); -} - -/* - * Load a raw key and certificate(s) from a PKCS#12 file. - */ -static kssl_params_t * -load_from_pkcs12(KMF_HANDLE_T kmfh, const char *filename, - const char *password_file, int *paramsize) -{ - KMF_RAW_KEY_DATA *rsa = NULL; - kssl_params_t *kssl_params; - KMF_X509_DER_CERT *certs = NULL; - int ncerts = 0, i; - - ncerts = PKCS12_get_rsa_key_certs(kmfh, filename, - password_file, &rsa, &certs); - - if (certs == NULL || ncerts == 0) { - (void) fprintf(stderr, - "Unable to read cert and/or key from %s\n", filename); - return (NULL); - } - - if (verbose) - (void) printf("%d certificates read successfully\n", ncerts); - - kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL, - NULL, NULL); - - for (i = 0; i < ncerts; i++) - kmf_free_kmf_cert(kmfh, &certs[i]); - free(certs); - - kmf_free_raw_key(rsa); - return (kssl_params); -} - -int -parse_and_set_addr(char *server_address, char *server_port, - struct sockaddr_in6 *addr) -{ - long long tmp_port; - char *ep; - - if (server_port == NULL) { - return (-1); - } - - if (server_address == NULL) { - addr->sin6_addr = in6addr_any; - } else { - struct hostent *hp; - int error_num; - - if ((hp = (getipnodebyname(server_address, AF_INET6, - AI_DEFAULT, &error_num))) == NULL) { - (void) fprintf(stderr, "Error: Unknown host: %s\n", - server_address); - return (-1); - } - - (void) memcpy((caddr_t)&addr->sin6_addr, hp->h_addr, - hp->h_length); - freehostent(hp); - } - - errno = 0; - tmp_port = strtoll(server_port, &ep, 10); - if (server_port == ep || *ep != '\0' || errno != 0) { - (void) fprintf(stderr, "Error: Invalid Port value: %s\n", - server_port); - return (-1); - } - if (tmp_port < 1 || tmp_port > 65535) { - (void) fprintf(stderr, "Error: Port out of range: %s\n", - server_port); - return (-1); - } - /* It is safe to convert since the value is inside the boundaries. */ - addr->sin6_port = tmp_port; - - return (0); -} - -/* - * The order of the ciphers is important. It is used as the - * default order (when -c is not specified). - */ -struct csuite { - const char *suite; - uint16_t val; - boolean_t seen; -} cipher_suites[CIPHER_SUITE_COUNT - 1] = { - {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, B_FALSE}, - {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, B_FALSE}, - {"rsa_aes_256_cbc_sha", TLS_RSA_WITH_AES_256_CBC_SHA, B_FALSE}, - {"rsa_aes_128_cbc_sha", TLS_RSA_WITH_AES_128_CBC_SHA, B_FALSE}, - {"rsa_3des_ede_cbc_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, B_FALSE}, - {"rsa_des_cbc_sha", SSL_RSA_WITH_DES_CBC_SHA, B_FALSE}, -}; - -static int -check_suites(char *suites, uint16_t *sarray) -{ - int i; - int err = 0; - char *suite; - int sindx = 0; - - if (suites != NULL) { - for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) - sarray[i] = CIPHER_NOTSET; - } else { - for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) - sarray[i] = cipher_suites[i].val; - return (err); - } - - suite = strtok(suites, ","); - do { - for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) { - if (strcasecmp(suite, cipher_suites[i].suite) == 0) { - if (!cipher_suites[i].seen) { - sarray[sindx++] = cipher_suites[i].val; - cipher_suites[i].seen = B_TRUE; - } - break; - } - } - - if (i == (CIPHER_SUITE_COUNT - 1)) { - (void) fprintf(stderr, - "Unknown Cipher suite name: %s\n", suite); - err++; - } - } while ((suite = strtok(NULL, ",")) != NULL); - - return (err); -} - -int -do_create(int argc, char *argv[]) -{ - const char *softtoken_dir = NULL; - const char *token_label = NULL; - const char *password_file = NULL; - const char *cert_key_file = NULL; - const char *cacert_chain_file = NULL; - const char *certname = NULL; - char *suites = NULL; - uint32_t timeout = DEFAULT_SID_TIMEOUT; - uint32_t scache_size = DEFAULT_SID_CACHE_NENTRIES; - uint16_t kssl_suites[CIPHER_SUITE_COUNT - 1]; - int proxy_port = -1; - struct sockaddr_in6 server_addr; - char *format = NULL; - char *port, *addr; - char c; - int pcnt; - kssl_params_t *kssl_params; - int bufsize; - KMF_HANDLE_T kmfh = NULL; - KMF_RETURN rv = KMF_OK; - char *err = NULL; - - argc -= 1; - argv += 1; - - while ((c = getopt(argc, argv, "vT:d:f:h:i:p:c:C:t:x:z:")) != -1) { - switch (c) { - case 'd': - softtoken_dir = optarg; - break; - case 'c': - suites = optarg; - break; - case 'C': - certname = optarg; - break; - case 'f': - format = optarg; - break; - case 'h': - cacert_chain_file = optarg; - break; - case 'i': - cert_key_file = optarg; - break; - case 'T': - token_label = optarg; - break; - case 'p': - password_file = optarg; - break; - case 't': - timeout = atoi(optarg); - break; - case 'x': - proxy_port = atoi(optarg); - break; - case 'v': - verbose = B_TRUE; - break; - case 'z': - scache_size = atoi(optarg); - break; - default: - goto err; - } - } - - pcnt = argc - optind; - if (pcnt == 0) { - port = "443"; /* default SSL port */ - addr = NULL; - } else if (pcnt == 1) { - port = argv[optind]; - addr = NULL; - } else if (pcnt == 2) { - addr = argv[optind]; - port = argv[optind + 1]; - } else { - goto err; - } - - if (parse_and_set_addr(addr, port, &server_addr) < 0) { - goto err; - } - - if (verbose) { - char buffer[128]; - - (void) inet_ntop(AF_INET6, &server_addr.sin6_addr, buffer, - sizeof (buffer)); - (void) printf("addr = %s, port = %d\n", buffer, - server_addr.sin6_port); - } - - if (format == NULL || proxy_port == -1) { - goto err; - } - - if (check_suites(suites, kssl_suites) != 0) { - goto err; - } - - rv = kmf_initialize(&kmfh, NULL, NULL); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error initializing KMF", err); - return (0); - } - - if (strcmp(format, "pkcs11") == 0) { - if (token_label == NULL || certname == NULL) { - goto err; - } - if (softtoken_dir != NULL) { - (void) setenv("SOFTTOKEN_DIR", softtoken_dir, 1); - if (verbose) { - (void) printf( - "SOFTTOKEN_DIR=%s\n", - getenv("SOFTTOKEN_DIR")); - } - } - kssl_params = load_from_pkcs11(kmfh, - token_label, password_file, certname, &bufsize); - } else if (strcmp(format, "pkcs12") == 0) { - if (cert_key_file == NULL) { - goto err; - } - kssl_params = load_from_pkcs12(kmfh, - cert_key_file, password_file, &bufsize); - } else if (strcmp(format, "pem") == 0) { - if (cert_key_file == NULL) { - goto err; - } - kssl_params = load_from_pem(kmfh, - cert_key_file, password_file, &bufsize); - } else { - (void) fprintf(stderr, "Unsupported cert format: %s\n", format); - goto err; - } - - if (kssl_params == NULL) { - (void) kmf_finalize(kmfh); - return (FAILURE); - } - - /* - * Add the list of supported ciphers to the buffer. - */ - bcopy(kssl_suites, kssl_params->kssl_suites, - sizeof (kssl_params->kssl_suites)); - kssl_params->kssl_params_size = bufsize; - kssl_params->kssl_addr = server_addr; - kssl_params->kssl_session_cache_timeout = timeout; - kssl_params->kssl_proxy_port = proxy_port; - kssl_params->kssl_session_cache_size = scache_size; - - if (cacert_chain_file != NULL) { - kssl_params = add_cacerts(kmfh, kssl_params, cacert_chain_file); - if (kssl_params == NULL) { - bzero(kssl_params, bufsize); - free(kssl_params); - (void) kmf_finalize(kmfh); - return (FAILURE); - } - } - - if (kssl_send_command((char *)kssl_params, KSSL_ADD_ENTRY) < 0) { - int err = CRYPTO_FAILED; - - if (kssl_params->kssl_is_nxkey) - err = kssl_params->kssl_token.ck_rv; - (void) fprintf(stderr, - "Error loading cert and key: 0x%x\n", err); - bzero(kssl_params, bufsize); - free(kssl_params); - (void) kmf_finalize(kmfh); - return (FAILURE); - } - - if (verbose) - (void) printf("Successfully loaded cert and key\n"); - - bzero(kssl_params, bufsize); - free(kssl_params); - (void) kmf_finalize(kmfh); - return (SUCCESS); - -err: - usage_create(B_TRUE); - (void) kmf_finalize(kmfh); - return (SMF_EXIT_ERR_CONFIG); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_delete.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_delete.c deleted file mode 100644 index bd5a6b45a4..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_delete.c +++ /dev/null @@ -1,95 +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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <netinet/in.h> /* struct sockaddr_in */ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <libscf.h> -#include <inet/kssl/kssl.h> -#include "kssladm.h" - -void -usage_delete(boolean_t do_print) -{ - if (do_print) - (void) fprintf(stderr, "Usage:\n"); - (void) fprintf(stderr, - "kssladm delete [-v] [<server_address>] <server_port>\n"); -} - -int -do_delete(int argc, char *argv[]) -{ - struct sockaddr_in6 server_addr; - char c; - char *port, *addr; - int pcnt; - - if (argc < 3) { - goto err; - } - - argc -= 1; - argv += 1; - - while ((c = getopt(argc, argv, "v")) != -1) { - switch (c) { - case 'v': - verbose = B_TRUE; - break; - default: - goto err; - } - } - - pcnt = argc - optind; - if (pcnt == 1) { - port = argv[optind]; - addr = NULL; - } else if (pcnt == 2) { - addr = argv[optind]; - port = argv[optind + 1]; - } - - if (parse_and_set_addr(addr, port, &server_addr) < 0) { - goto err; - } - - if (kssl_send_command((char *)&server_addr, KSSL_DELETE_ENTRY) < 0) { - perror("Error deleting entry"); - return (FAILURE); - } - - if (verbose) - (void) printf("Successfully loaded cert and key\n"); - - return (SUCCESS); - -err: - usage_delete(B_TRUE); - return (SMF_EXIT_ERR_CONFIG); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c deleted file mode 100644 index dae4d83a2e..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c +++ /dev/null @@ -1,156 +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 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <assert.h> -#include <strings.h> - -#include <kmfapi.h> -#include "kssladm.h" - -/* - * Extract the Certificate and raw key data from a PKCS#12 file. - * The password needed for decrypting the PKCS#12 PDU is stored - * in plaintext in the given "password_file" parameter. - */ -int -PKCS12_get_rsa_key_certs(KMF_HANDLE_T kmfh, - const char *filename, const char *password_file, - KMF_RAW_KEY_DATA **rsa, KMF_X509_DER_CERT **certs) -{ - char password_buf[1024]; - KMF_RETURN rv = KMF_OK; - KMF_CREDENTIAL pk12cred; - KMF_X509_DER_CERT *tcerts; - KMF_RAW_KEY_DATA *keys; - int ncerts, nkeys; - char *err = NULL; - - tcerts = NULL; - keys = NULL; - ncerts = 0; - nkeys = 0; - - if (get_passphrase(password_file, password_buf, - sizeof (password_buf)) <= 0) { - perror("Unable to read passphrase"); - goto done; - } - pk12cred.cred = password_buf; - pk12cred.credlen = strlen(password_buf); - - rv = kmf_import_objects(kmfh, (char *)filename, &pk12cred, &tcerts, - &ncerts, &keys, &nkeys); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error importing PKCS12 data", err); - } - -done: - if (rv != KMF_OK) { - int i; - if (tcerts != NULL) { - for (i = 0; i < ncerts; i++) - kmf_free_kmf_cert(kmfh, &tcerts[i]); - free(tcerts); - } - tcerts = NULL; - ncerts = 0; - if (keys != NULL) { - for (i = 0; i < nkeys; i++) - kmf_free_raw_key(&keys[i]); - free(keys); - } - keys = NULL; - } - *certs = tcerts; - *rsa = keys; - - return (ncerts); -} - -/* - * Parse a PEM file which should contain RSA private keys and - * their associated X.509v3 certificates. More than 1 may - * be present in the file. - */ -int -PEM_get_rsa_key_certs(KMF_HANDLE_T kmfh, - const char *filename, char *password_file, - KMF_RAW_KEY_DATA **rsa, KMF_X509_DER_CERT **certs) -{ - KMF_RETURN rv = KMF_OK; - KMF_CREDENTIAL creds; - KMF_X509_DER_CERT *tcerts; - KMF_RAW_KEY_DATA *keys; - int ncerts, nkeys; - char *err = NULL; - char password_buf[1024]; - - tcerts = NULL; - keys = NULL; - ncerts = 0; - nkeys = 0; - - if (get_passphrase(password_file, password_buf, - sizeof (password_buf)) <= 0) { - perror("Unable to read passphrase"); - goto done; - } - creds.cred = password_buf; - creds.credlen = strlen(password_buf); - - rv = kmf_import_objects(kmfh, (char *)filename, &creds, &tcerts, - &ncerts, &keys, &nkeys); - if (rv != KMF_OK) { - REPORT_KMF_ERROR(rv, "Error importing key data", err); - } - -done: - if (rv != KMF_OK) { - int i; - if (tcerts != NULL) { - for (i = 0; i < ncerts; i++) - kmf_free_kmf_cert(kmfh, &tcerts[i]); - free(tcerts); - } - tcerts = NULL; - ncerts = 0; - if (keys != NULL) { - for (i = 0; i < nkeys; i++) - kmf_free_raw_key(&keys[i]); - free(keys); - } - keys = NULL; - } - if (certs != NULL) - *certs = tcerts; - if (rsa != NULL) - *rsa = keys; - - return (ncerts); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/Makefile deleted file mode 100644 index 7adf6a121a..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/Makefile +++ /dev/null @@ -1,77 +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. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile -# - -PROG= ksslcfg -MANIFEST= kssl-proxy.xml - -include $(SRC)/cmd/Makefile.cmd - -OBJS = \ - ksslcfg.o \ - ksslcfg_create.o \ - ksslcfg_delete.o - -POFILES = $(OBJS:%.o=%.po) -POFILE = $(PROG)_all.po - -SRCS = $(OBJS:%.o=%.c) - -ROOTMANIFESTDIR= $(ROOTSVCNETWORKSSL) - -.KEEP_STATE: - -CFLAGS += $(CCVERBOSE) - -LDLIBS += -lscf -lnsl - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@; cat $(POFILES) > $@ - -install: all $(ROOTUSRSBINPROG) $(ROOTMANIFEST) - -clean: - $(RM) $(OBJS) - -check: $(CHKMANIFEST) - $(CSTYLE) -pP $(SRCS) - -lint: lint_SRCS - -$(ROOTUSRSBINPROG): $(ROOTUSRSBIN) - -$(ROOTUSRSBIN): - $(MKDIR) -p $@ - -include ../../../../Makefile.targ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml deleted file mode 100644 index 3728239974..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - - 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 - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. ---> - -<service_bundle type='manifest' name='SUNWcsr:kssl-proxy'> - -<service - name='network/ssl/proxy' - type='service' - version='1'> - - <dependency - name='socket-filter' - grouping='require_all' - restart_on='restart' - type='service'> - <service_fmri value='svc:/network/socket-filter:kssl' /> - </dependency> - - <dependency - name='cryptosvc' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/cryptosvc' /> - </dependency> - - <dependency - name='name-services' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/milestone/name-services' /> - </dependency> - - <property_group name='startd' type='framework'> - <propval name='duration' type='astring' value='transient' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - kernel ssl proxy configuration - </loctext> - </common_name> - <documentation> - <manpage title='ksslcfg' section='8' - manpath='/usr/share/man' /> - </documentation> - </template> - -</service> - -</service_bundle> diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.c deleted file mode 100644 index 84336d0923..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.c +++ /dev/null @@ -1,272 +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 <arpa/inet.h> /* inet_addr() */ -#include <ctype.h> -#include <libscf.h> -#include <netdb.h> /* hostent */ -#include <netinet/in.h> /* ip_addr_t */ -#include <stdio.h> -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <fcntl.h> -#include <strings.h> -#include <sys/varargs.h> -#include <zone.h> -#include "ksslcfg.h" - -/* - * ksslcfg(8) - * - * ksslcfg manages smf(7) instances for the Kernel SSL proxy module. - * It makes use of kssladm(8) which does the grunt work. - */ - -/* - * This version number is rather meaningless. In any case, - * version 2.0 adds support for IPv6 addresses. - */ -#define KSSLCFG_VERSION "Version 2.0" - -boolean_t verbose = B_FALSE; -const char *SERVICE_NAME = "network/ssl/proxy"; - -void -KSSL_DEBUG(const char *format, ...) -{ - va_list ap; - - if (verbose) { - va_start(ap, format); - (void) vprintf(format, ap); - va_end(ap); - } -} - -/* - * Convert string to port number and check for errors. Return 0 on error, - * 1 on success. - */ -int -get_portnum(const char *s, ushort_t *rport) -{ - long long tmp_port; - char *ep; - - errno = 0; - tmp_port = strtoll(s, &ep, 10); - if (s == ep || *ep != '\0' || errno != 0) - return (0); - if (tmp_port < 1 || tmp_port > 65535) - return (0); - - if (rport != NULL) - *rport = (ushort_t)tmp_port; - - return (1); -} - -#define ANY_ADDR "INADDR_ANY" - -/* - * An instance name is formed using either the host name in the fully - * qualified domain name form (FQDN) which should map to a specific IP address - * or using INADDR_ANY which means all IP addresses. - * - * We do a lookup or reverse lookup to get the host name. It is assumed that - * the returned name is in the FQDN form. i.e. DNS is used. - */ -char * -create_instance_name(const char *arg, char **inaddr_any_name, - boolean_t is_create) -{ - int len; - uint16_t port; - char *cname; - char *instance_name; - const char *prefix = "kssl-"; - char *first_space; - - first_space = strchr(arg, ' '); - if (first_space == NULL) { /* No host name. Use INADDR_ANY. */ - if (get_portnum(arg, &port) == 0) { - (void) fprintf(stderr, - gettext("Error: Invalid port value -- %s\n"), - arg); - return (NULL); - } - KSSL_DEBUG("port=%d\n", port); - if ((cname = strdup(ANY_ADDR)) == NULL) - return (NULL); - } else { - char *temp_str; - char *ptr; - struct hostent *hp; - boolean_t do_warn; - int error_num; - in_addr_t v4addr; - in6_addr_t v6addr; - - if (get_portnum(first_space + 1, &port) == 0) { - (void) fprintf(stderr, - gettext("Error: Invalid port value -- %s\n"), - first_space + 1); - return (NULL); - } - KSSL_DEBUG("port=%d\n", port); - - if ((temp_str = strdup(arg)) == NULL) - return (NULL); - *(strchr(temp_str, ' ')) = '\0'; - - if (inet_pton(AF_INET6, temp_str, &v6addr) == 1) { - /* Do a reverse lookup for the IPv6 address */ - hp = getipnodebyaddr(&v6addr, sizeof (v6addr), - AF_INET6, &error_num); - } else if (inet_pton(AF_INET, temp_str, &v4addr) == 1) { - /* Do a reverse lookup for the IPv4 address */ - hp = getipnodebyaddr(&v4addr, sizeof (v4addr), - AF_INET, &error_num); - } else { - /* Do a lookup for the host name */ - hp = getipnodebyname(temp_str, AF_INET6, AI_DEFAULT, - &error_num); - } - - if (hp == NULL) { - (void) fprintf(stderr, - gettext("Error: Unknown host -- %s\n"), temp_str); - free(temp_str); - return (NULL); - } - - if ((ptr = cname = strdup(hp->h_name)) == NULL) { - freehostent(hp); - free(temp_str); - return (NULL); - } - - freehostent(hp); - - do_warn = B_TRUE; - /* "s/./-/g" */ - while ((ptr = strchr(ptr, '.')) != NULL) { - if (do_warn) - do_warn = B_FALSE; - *ptr = '-'; - ptr++; - } - - if (do_warn && is_create) { - (void) fprintf(stderr, - gettext("Warning: %s does not appear to have a" - " registered DNS name.\n"), temp_str); - } - - free(temp_str); - } - - KSSL_DEBUG("Cannonical host name =%s\n", cname); - - len = strlen(prefix) + strlen(cname) + 10; - if ((instance_name = malloc(len)) == NULL) { - (void) fprintf(stderr, - gettext("Error: memory allocation failure.\n")); - return (NULL); - } - (void) snprintf(instance_name, len, "%s%s-%d", prefix, cname, port); - - if (is_create) { - len = strlen(prefix) + strlen(ANY_ADDR) + 10; - if ((*inaddr_any_name = malloc(len)) == NULL) { - (void) fprintf(stderr, - gettext("Error: memory allocation failure.\n")); - free(instance_name); - free(cname); - return (NULL); - } - - (void) snprintf(*inaddr_any_name, len, - "%s%s-%d", prefix, ANY_ADDR, port); - } - - free(cname); - KSSL_DEBUG("instance_name=%s\n", instance_name); - return (instance_name); -} - -static void -usage_all(void) -{ - (void) fprintf(stderr, gettext("Usage:\n")); - usage_create(B_FALSE); - usage_delete(B_FALSE); - (void) fprintf(stderr, "ksslcfg -V\n"); - (void) fprintf(stderr, "ksslcfg -?\n"); -} - - -int -main(int argc, char **argv) -{ - int rv = SUCCESS; - - (void) setlocale(LC_ALL, ""); -#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ -#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ -#endif - (void) textdomain(TEXT_DOMAIN); - - /* Running from within a non-global zone is not supported yet. */ - if (getzoneid() != GLOBAL_ZONEID) { - (void) fprintf(stderr, - gettext("Error: Configuring KSSL from within a non-global " - "zone is not supported.\nPlease run the command from " - "the global zone.\n")); - return (ERROR_USAGE); - } - - if (argc < 2) { - usage_all(); - return (ERROR_USAGE); - } - - if (strcmp(argv[1], "create") == 0) { - rv = do_create(argc, argv); - } else if (strcmp(argv[1], "delete") == 0) { - rv = do_delete(argc, argv); - } else if (strcmp(argv[1], "-V") == 0) { - (void) printf("%s\n", KSSLCFG_VERSION); - } else if (strcmp(argv[1], "-?") == 0) { - usage_all(); - } else { - (void) fprintf(stderr, - gettext("Error: Unknown subcommand -- %s\n"), argv[1]); - usage_all(); - rv = ERROR_USAGE; - } - - return (rv); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h deleted file mode 100644 index 9ebbfba989..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h +++ /dev/null @@ -1,67 +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 _KSSLCFG_H -#define _KSSLCFG_H - -/* - * Common routines and variables used by ksslcfg files. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <libintl.h> -#include <locale.h> - -#define MAX_ADRPORT_LEN 128 /* sufficient for host name/IP address + port */ - -#define SUCCESS 0 -#define FAILURE 1 -#define ERROR_USAGE 2 -#define INSTANCE_ANY_EXISTS 3 -#define INSTANCE_OTHER_EXISTS 4 - -#define KSSL_FILTER_SVC_NAME "svc:/network/socket-filter:kssl" - -extern const char *SERVICE_NAME; -extern boolean_t verbose; - -extern char *create_instance_name(const char *arg, char **inaddr_any_name, - boolean_t is_create); -int get_portnum(const char *, ushort_t *); -extern void KSSL_DEBUG(const char *format, ...); -extern int do_create(int argc, char *argv[]); -extern int do_delete(int argc, char *argv[]); -extern int delete_instance(const char *instance_name); -extern void usage_create(boolean_t do_print); -extern void usage_delete(boolean_t do_print); - -#ifdef __cplusplus -} -#endif - -#endif /* _KSSLCFG_H */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c deleted file mode 100644 index 87c789fd92..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c +++ /dev/null @@ -1,677 +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 <libscf.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <strings.h> -#include <sys/types.h> -#include "ksslcfg.h" - -void -usage_create(boolean_t do_print) -{ - if (do_print) - (void) fprintf(stderr, gettext("Usage:\n")); - (void) fprintf(stderr, "ksslcfg create" - " -f pkcs11 [-d softtoken_directory] -T <token_label>" - " -C <certificate_label> -x <proxy_port>" - " [-h <ca_certchain_file>]" - " [options] [<server_address>] <server_port>\n"); - - (void) fprintf(stderr, "ksslcfg create" - " -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>" - " [options] [<server_address>] <server_port>\n"); - - (void) fprintf(stderr, "ksslcfg create" - " -f pem -i <cert_and_key_pemfile> -x <proxy_port>" - " [options] [<server_address>] <server_port>\n"); - - (void) fprintf(stderr, gettext("options are:\n")); - (void) fprintf(stderr, "\t[-c <ciphersuites>]\n" - "\t[-p <password_file>]\n" - "\t[-t <ssl_session_cache_timeout>]\n" - "\t[-u <username>]\n" - "\t[-z <ssl_session_cache_size>]\n" - "\t[-v]\n"); -} - -static scf_propertygroup_t * -add_property_group_to_instance(scf_handle_t *handle, scf_instance_t *instance, - const char *pg_name, const char *pg_type) -{ - scf_propertygroup_t *pg; - - pg = scf_pg_create(handle); - if (pg == NULL) { - KSSL_DEBUG("scf_pg_create failed: %s\n", - scf_strerror(scf_error())); - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (NULL); - } - - if (scf_instance_add_pg(instance, pg_name, pg_type, 0, pg) != 0) { - KSSL_DEBUG("ERROR: scf_instance_add_pg failed: %s\n", - scf_strerror(scf_error())); - if (scf_error() == SCF_ERROR_EXISTS) - (void) fprintf(stderr, gettext( - "Error: another process is modifying this instance." - " Exiting.\n")); - else - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - scf_pg_destroy(pg); - return (NULL); - } else { - KSSL_DEBUG("property group created\n"); - } - - return (pg); -} - -static int -add_new_property(scf_handle_t *handle, const char *prop_name, - scf_type_t type, const char *val, scf_transaction_t *tx) -{ - scf_value_t *value = NULL; - scf_transaction_entry_t *entry = NULL; - int status = FAILURE; - - entry = scf_entry_create(handle); - if (entry == NULL) { - KSSL_DEBUG("scf_entry_create failed: %s\n", - scf_strerror(scf_error())); - goto out; - } - KSSL_DEBUG("scf_entry_create succeeded\n"); - - value = scf_value_create(handle); - if (value == NULL) { - goto out; - } - KSSL_DEBUG("scf_value_create succeeded\n"); - - if (scf_transaction_property_new(tx, entry, prop_name, type) != 0) { - goto out; - } - KSSL_DEBUG("scf_transaction_property_new succeeded\n"); - - if (scf_value_set_from_string(value, type, val) != 0) { - goto out; - } - KSSL_DEBUG("scf_value_set_from_string \'%s\' succeeded\n", val); - - if (scf_entry_add_value(entry, value) != 0) { - KSSL_DEBUG( - "scf_entry_add_value failed: %s\n", - scf_strerror(scf_error())); - goto out; - } - KSSL_DEBUG("scf_entry_add_value succeeded\n"); - - status = SUCCESS; - -out: - if (status != SUCCESS) - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (status); -} - -static int -set_method_context(scf_handle_t *handle, scf_transaction_t *tran, - const char *value_str) -{ - if ((add_new_property(handle, SCF_PROPERTY_USE_PROFILE, - SCF_TYPE_BOOLEAN, "false", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_USER, SCF_TYPE_ASTRING, - value_str, tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_GROUP, SCF_TYPE_ASTRING, - ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_LIMIT_PRIVILEGES, - SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_WORKING_DIRECTORY, - SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_SUPP_GROUPS, - SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_RESOURCE_POOL, - SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_PROJECT, SCF_TYPE_ASTRING, - ":default", tran) != SUCCESS) || - (add_new_property(handle, SCF_PROPERTY_PRIVILEGES, - SCF_TYPE_ASTRING, "basic,sys_net_config", tran) != SUCCESS)) - return (FAILURE); - - return (SUCCESS); -} - -static int -add_pg_method(scf_handle_t *handle, scf_instance_t *instance, - const char *kssl_entry, const char *pg_name, const char *flags, - const char *value_str) -{ - int len, rv; - char *command; - const char *base_command; - int status = FAILURE; - boolean_t errflag = B_FALSE; - scf_transaction_t *tran; - scf_propertygroup_t *pg; - - pg = add_property_group_to_instance(handle, instance, - pg_name, SCF_GROUP_METHOD); - if (pg == NULL) { - /* flag is false to suppress duplicate error messages */ - errflag = B_FALSE; - goto out0; - } - KSSL_DEBUG("%s method added\n", pg_name); - - tran = scf_transaction_create(handle); - if (tran == NULL) { - KSSL_DEBUG("scf_transaction_create failed: %s\n", - scf_strerror(scf_error())); - errflag = B_TRUE; - goto out0; - } - KSSL_DEBUG("scf_transaction_create succeeded\n"); - - do { - if (scf_transaction_start(tran, pg) != 0) { - KSSL_DEBUG("scf_transaction_start failed: %s\n", - scf_strerror(scf_error())); - if (scf_error() == SCF_ERROR_PERMISSION_DENIED) { - (void) fprintf(stderr, gettext( - "Error: Permission denied.\n")); - errflag = B_FALSE; - } else if (scf_error() == SCF_ERROR_DELETED) { - (void) fprintf(stderr, gettext( - "Error: property group %s has" - " been deleted.\n"), pg_name); - errflag = B_FALSE; - } else - errflag = B_TRUE; - goto out1; - } - KSSL_DEBUG("scf_transaction_start succeeded\n"); - - if (strcmp(pg_name, "stop") == 0) - base_command = "/usr/lib/kssladm delete"; - else - base_command = "/usr/lib/kssladm create"; - - len = strlen(base_command) + strlen(flags) + - strlen(kssl_entry) + 3; - - command = malloc(len); - if (command == NULL) { - goto out2; - } - - (void) snprintf(command, len, "%s %s %s", - base_command, flags, kssl_entry); - KSSL_DEBUG("command=%s\n", command); - - if (add_new_property(handle, SCF_PROPERTY_EXEC, - SCF_TYPE_ASTRING, command, tran) != SUCCESS) { - free(command); - goto out2; - } - free(command); - - if (add_new_property(handle, SCF_PROPERTY_TIMEOUT, - SCF_TYPE_COUNT, "60", tran) != SUCCESS) - goto out2; - - if (set_method_context(handle, tran, value_str) != SUCCESS) - goto out2; - - rv = scf_transaction_commit(tran); - switch (rv) { - case 1: - KSSL_DEBUG("scf_transaction_commit succeeded\n"); - status = SUCCESS; - goto out2; - case 0: - scf_transaction_reset(tran); - if (scf_pg_update(pg) == -1) { - goto out2; - } - break; - case -1: - default: - KSSL_DEBUG("ERROR: scf_transaction_commit failed: %s\n", - scf_strerror(scf_error())); - if (scf_error() == SCF_ERROR_PERMISSION_DENIED) { - (void) fprintf(stderr, gettext( - "Error: Permission denied.\n")); - errflag = B_FALSE; - } else { - errflag = B_TRUE; - } - goto out2; - } - } while (rv == 0); - -out2: - scf_transaction_reset(tran); -out1: - scf_transaction_destroy_children(tran); - scf_transaction_destroy(tran); -out0: - if (pg != NULL) - scf_pg_destroy(pg); - if (errflag) - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (status); -} - -static int -create_instance(scf_handle_t *handle, scf_service_t *svc, - const char *instance_name, const char *kssl_entry, const char *command, - const char *username, char *inaddr_any_name) -{ - int status = FAILURE; - char *buf; - boolean_t errflag = B_FALSE; - ssize_t max_fmri_len; - scf_instance_t *instance; - - instance = scf_instance_create(handle); - if (instance == NULL) { - errflag = B_TRUE; - KSSL_DEBUG("scf_instance_create failed: %s\n", - scf_strerror(scf_error())); - goto out; - } - KSSL_DEBUG("scf_instance_create succeeded\n"); - - if (scf_service_get_instance(svc, inaddr_any_name, instance) == 0) { - /* Let the caller deal with the duplicate instance */ - status = INSTANCE_ANY_EXISTS; - goto out; - } - - if (scf_service_add_instance(svc, instance_name, instance) != 0) { - if (scf_error() == SCF_ERROR_EXISTS) { - /* Let the caller deal with the duplicate instance */ - status = INSTANCE_OTHER_EXISTS; - goto out; - } - - errflag = B_TRUE; - KSSL_DEBUG("scf_service_add_instance failed: %s\n", - scf_strerror(scf_error())); - goto out; - } - KSSL_DEBUG("scf_service_add_instance succeeded\n"); - - if ((add_pg_method(handle, instance, kssl_entry, "start", - command, username) != SUCCESS) || - (add_pg_method(handle, instance, kssl_entry, "refresh", - command, username) != SUCCESS) || - (add_pg_method(handle, instance, kssl_entry, "stop", - "", username) != SUCCESS)) { - scf_instance_destroy(instance); - return (status); - } - - /* enabling the instance */ - max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); - if ((buf = malloc(max_fmri_len + 1)) == NULL) - goto out; - - if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { - KSSL_DEBUG("instance_fmri=%s\n", buf); - if (smf_enable_instance(buf, 0) != 0) { - errflag = B_TRUE; - KSSL_DEBUG( - "smf_enable_instance failed: %s\n", - scf_strerror(scf_error())); - goto out; - } - status = SUCCESS; - } - -out: - if (instance != NULL) - scf_instance_destroy(instance); - if (errflag) - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (status); -} - -static int -create_service(const char *instance_name, const char *kssl_entry, - const char *command, const char *username, char *inaddr_any_name) -{ - int status = FAILURE; - scf_scope_t *scope; - scf_service_t *svc; - scf_handle_t *handle; - boolean_t errflag = B_TRUE; - - handle = scf_handle_create(SCF_VERSION); - if (handle == NULL) { - KSSL_DEBUG("scf_handle_create failed: %s\n", - scf_strerror(scf_error())); - goto out1; - } - KSSL_DEBUG("scf_handle_create succeeded\n"); - - if (scf_handle_bind(handle) == -1) { - KSSL_DEBUG("scf_handle_bind failed: %s\n", - scf_strerror(scf_error())); - goto out1; - } - KSSL_DEBUG("scf_handle_bind succeeded\n"); - - if ((scope = scf_scope_create(handle)) == NULL) { - KSSL_DEBUG("scf_scope_create failed: %s\n", - scf_strerror(scf_error())); - goto out2; - } - KSSL_DEBUG("scf_scope_create succeeded\n"); - - if ((svc = scf_service_create(handle)) == NULL) { - KSSL_DEBUG("scf_service_create failed: %s\n", - scf_strerror(scf_error())); - goto out3; - } - KSSL_DEBUG("scf_service_create succeeded\n"); - - if (scf_handle_decode_fmri(handle, SERVICE_NAME, NULL, svc, - NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0) { - KSSL_DEBUG("scf_handle_decode_fmri failed: %s\n", - scf_strerror(scf_error())); - if (scf_error() == SCF_ERROR_NOT_FOUND) { - (void) fprintf(stderr, gettext( - "service %s not found in the repository." - " Exiting.\n"), SERVICE_NAME); - errflag = B_FALSE; - } - goto out4; - } - - status = create_instance(handle, svc, instance_name, kssl_entry, - command, username, inaddr_any_name); - -out4: - scf_service_destroy(svc); -out3: - scf_scope_destroy(scope); -out2: - (void) scf_handle_unbind(handle); -out1: - if (handle != NULL) - scf_handle_destroy(handle); - - if (status != SUCCESS && status != INSTANCE_OTHER_EXISTS && - status != INSTANCE_ANY_EXISTS && errflag) - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (status); -} - -int -do_create(int argc, char *argv[]) -{ - char c; - char *buf, *ptr, *instance_name; - char *inaddr_any_name = NULL; - int i, status, len, pcnt; - const char *token_label = NULL; - const char *filename = NULL; - const char *certname = NULL; - const char *username = NULL; - const char *proxy_port = NULL; - char *format = NULL; - boolean_t quote_next; - char address_port[MAX_ADRPORT_LEN + 1]; - - argc -= 1; - argv += 1; - - /* - * Many of these arguments are passed on to kssladm command - * in the start method of the SMF instance created. So, we do only - * the basic usage checks here and let kssladm check the validity - * of the arguments. This is the reason we ignore optarg - * for some of the cases below. - */ - while ((c = getopt(argc, argv, "vT:d:f:h:i:p:c:C:t:u:x:z:")) != -1) { - switch (c) { - case 'd': - break; - case 'c': - break; - case 'C': - certname = optarg; - break; - case 'f': - format = optarg; - break; - case 'h': - break; - case 'i': - filename = optarg; - break; - case 'T': - token_label = optarg; - break; - case 'p': - break; - case 't': - break; - case 'u': - username = optarg; - break; - case 'x': - proxy_port = optarg; - break; - case 'v': - verbose = B_TRUE; - break; - case 'z': - break; - default: - goto err; - } - } - - if (format == NULL || proxy_port == NULL) { - goto err; - } - - if (get_portnum(proxy_port, NULL) == 0) { - (void) fprintf(stderr, - gettext("Error: Invalid proxy port value %s\n"), - proxy_port); - goto err; - } - - if (strcmp(format, "pkcs11") == 0) { - if (token_label == NULL || certname == NULL) { - goto err; - } - } else if (strcmp(format, "pkcs12") == 0 || - strcmp(format, "pem") == 0) { - if (filename == NULL) { - goto err; - } - } else { - goto err; - } - - pcnt = argc - optind; - if (pcnt == 1) { - if (strlen(argv[optind]) < MAX_ADRPORT_LEN) { - (void) strcpy(address_port, argv[optind]); - } else { - (void) fprintf(stderr, gettext( - "argument too long -- %s\n"), - argv[optind]); - return (FAILURE); - } - } else if (pcnt == 2) { - if ((len = strlen(argv[optind])) + - (strlen(argv[optind + 1])) < MAX_ADRPORT_LEN) { - (void) strcpy(address_port, argv[optind]); - address_port[len] = ' '; - (void) strcpy(address_port + len + 1, argv[optind + 1]); - } else { - (void) fprintf(stderr, gettext( - "arguments too long -- %s %s\n"), - argv[optind], argv[optind + 1]); - return (FAILURE); - } - } else { - goto err; - } - - /* - * We need to create the kssladm command line in - * the SMF instance from the current arguments. - * - * Construct a buffer with all the arguments except - * the -u argument. We have to quote the string arguments, - * -T and -C, as they can contain white space. - */ - len = 0; - for (i = 1; i < optind; i++) { - len += strlen(argv[i]) + 3; - } - - if ((buf = malloc(len)) == NULL) { - return (FAILURE); - } - - ptr = buf; - quote_next = B_FALSE; - for (i = 1; i < optind; i++) { - int arglen = strlen(argv[i]) + 1; - - if (strncmp(argv[i], "-u", 2) == 0) { - i++; - continue; - } - - if (quote_next) { - (void) snprintf(ptr, len, "\"%s\" ", argv[i]); - quote_next = B_FALSE; - arglen += 2; - } else { - (void) snprintf(ptr, len, "%s ", argv[i]); - } - - quote_next = (strncmp(argv[i], "-T", 2) == 0 || - strncmp(argv[i], "-C", 2) == 0); - - ptr += arglen; - len -= arglen; - } - KSSL_DEBUG("buf=%s\n", buf); - - instance_name = create_instance_name(address_port, - &inaddr_any_name, B_TRUE); - if (instance_name == NULL || inaddr_any_name == NULL) { - free(buf); - return (FAILURE); - } - KSSL_DEBUG("instance_name=%s\n", instance_name); - KSSL_DEBUG("inaddr_any_name=%s\n", inaddr_any_name); - - if (username == NULL) - username = "root"; - status = create_service(instance_name, address_port, - buf, username, inaddr_any_name); - if (status == INSTANCE_OTHER_EXISTS || status == INSTANCE_ANY_EXISTS) { - if (status == INSTANCE_ANY_EXISTS && - (strcmp(instance_name, inaddr_any_name) != SUCCESS)) { - /* - * The following could result in a misconfiguration. - * Better bail out with an error. - */ - (void) fprintf(stderr, - gettext("Error: INADDR_ANY instance exists." - " Can not create a new instance %s.\n"), - instance_name); - free(instance_name); - free(inaddr_any_name); - free(buf); - return (status); - } - - /* - * Delete the existing instance and create a new instance - * with the supplied arguments. - */ - KSSL_DEBUG("Deleting duplicate instance\n"); - if (delete_instance(instance_name) != SUCCESS) { - (void) fprintf(stderr, - gettext( - "Error: Can not delete existing instance %s.\n"), - instance_name); - } else { - (void) fprintf(stdout, gettext( - "Note: reconfiguring the existing instance %s.\n"), - instance_name); - status = create_service(instance_name, address_port, - buf, username, inaddr_any_name); - } - } - - /* - * network/ssl/proxy depends on network/socket-filter:kssl; - * enable that service now. - */ - if (smf_enable_instance(KSSL_FILTER_SVC_NAME, 0) != 0) { - KSSL_DEBUG( - "smf_enable_instance failed: %s\n" KSSL_FILTER_SVC_NAME); - (void) fprintf(stderr, gettext( - "Unable to enable required service \"%s\". Error: %s"), - KSSL_FILTER_SVC_NAME, scf_strerror(scf_error())); - status = FAILURE; - } - - free(instance_name); - free(inaddr_any_name); - free(buf); - return (status); - -err: - usage_create(B_TRUE); - return (ERROR_USAGE); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c deleted file mode 100644 index 31553002f4..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c +++ /dev/null @@ -1,327 +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 <libscf.h> -#include <libscf_priv.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <strings.h> -#include <sys/types.h> -#include "ksslcfg.h" - -void -usage_delete(boolean_t do_print) -{ - if (do_print) - (void) fprintf(stderr, gettext("Usage:\n")); - (void) fprintf(stderr, - "ksslcfg delete [-v] [<server_address>] <server_port>\n"); -} - -#define DEFAULT_TIMEOUT 60000000 -#define INIT_WAIT_USECS 50000 - -void -wait_till_to(char *fmri) -{ - char *state; - useconds_t max; - useconds_t usecs; - uint64_t *cp = NULL; - scf_simple_prop_t *sp = NULL; - - max = DEFAULT_TIMEOUT; - - if (((sp = scf_simple_prop_get(NULL, fmri, "stop", - SCF_PROPERTY_TIMEOUT)) != NULL) && - ((cp = scf_simple_prop_next_count(sp)) != NULL) && (*cp != 0)) - max = (*cp) * 1000000; /* convert to usecs */ - - if (sp != NULL) - scf_simple_prop_free(sp); - - for (usecs = INIT_WAIT_USECS; max > 0; max -= usecs) { - /* incremental wait */ - usecs *= 2; - usecs = (usecs > max) ? max : usecs; - - (void) usleep(usecs); - - /* Check state after the wait */ - if ((state = smf_get_state(fmri)) != NULL) { - if (strcmp(state, "disabled") == 0) - return; - } - } - - (void) fprintf(stderr, gettext("Warning: delete %s timed out.\n"), - fmri); -} - -static int -count_inst_cb(void *arg, scf_walkinfo_t *wip) -{ - int *num_inst = arg; - - if (wip->inst != NULL) - (*num_inst)++; - - return (0); -} - -/*ARGSUSED*/ -static void -ign_err(const char *unused, ...) -{ -} - -int -delete_instance(const char *instance_name) -{ - int status = FAILURE; - char *buf; - boolean_t errflag = B_FALSE; - ssize_t max_fmri_len; - scf_scope_t *scope; - scf_service_t *svc; - scf_handle_t *handle; - scf_instance_t *instance; - int num_inst = 0, exit_status = 0; - - handle = scf_handle_create(SCF_VERSION); - if (handle == NULL) { - errflag = B_TRUE; - KSSL_DEBUG("scf_handle_create failed: %s\n", - scf_strerror(scf_error())); - goto out1; - } - KSSL_DEBUG("scf_handle_create succeeded\n"); - - if (scf_handle_bind(handle) == -1) { - errflag = B_TRUE; - KSSL_DEBUG("scf_handle_bind failed: %s\n", - scf_strerror(scf_error())); - goto out1; - } - KSSL_DEBUG("scf_handle_bind succeeded\n"); - - if ((scope = scf_scope_create(handle)) == NULL) { - errflag = B_TRUE; - KSSL_DEBUG("scf_scope_create failed: %s\n", - scf_strerror(scf_error())); - goto out2; - } - KSSL_DEBUG("scf_scope_create succeeded\n"); - - if ((svc = scf_service_create(handle)) == NULL) { - errflag = B_TRUE; - KSSL_DEBUG("scf_service_create failed: %s\n", - scf_strerror(scf_error())); - goto out3; - } - KSSL_DEBUG("scf_service_create succeeded\n"); - - if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1) { - errflag = B_TRUE; - KSSL_DEBUG("scf_handle_get_scope failed: %s\n", - scf_strerror(scf_error())); - goto out4; - } - KSSL_DEBUG("scf_handle_get_scope succeeded\n"); - - if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0) { - scf_error_t scf_errnum = scf_error(); - - if (scf_errnum != SCF_ERROR_NOT_FOUND) { - errflag = B_TRUE; - KSSL_DEBUG( - "ERROR scf_scope_get_service failed: %s\n", - scf_strerror(scf_errnum)); - } - goto out4; - } else { - KSSL_DEBUG("scf_scope_get_service succeeded\n"); - } - - instance = scf_instance_create(handle); - if (instance == NULL) { - errflag = B_TRUE; - KSSL_DEBUG("scf_instance_create failed: %s\n", - scf_strerror(scf_error())); - goto out4; - } - - if (scf_service_get_instance(svc, instance_name, instance) != 0) { - scf_error_t scf_errnum = scf_error(); - - if (scf_errnum == SCF_ERROR_NOT_FOUND) { - status = SUCCESS; - } else { - errflag = B_TRUE; - KSSL_DEBUG( - "ERROR scf_scope_get_service failed: %s\n", - scf_strerror(scf_errnum)); - } - scf_instance_destroy(instance); - goto out4; - } - - max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); - if ((buf = malloc(max_fmri_len + 1)) == NULL) - goto out4; - - if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { - char *state; - - KSSL_DEBUG("instance_fmri=%s\n", buf); - state = smf_get_state(buf); - if (state) - KSSL_DEBUG("state=%s\n", state); - if (state && strcmp(state, "online") == 0) { - if (smf_disable_instance(buf, 0) != 0) { - errflag = B_TRUE; - KSSL_DEBUG( - "smf_disable_instance failed: %s\n", - scf_strerror(scf_error())); - } else { - /* - * Wait for some time till timeout to avoid - * a race with scf_instance_delete() below. - */ - wait_till_to(buf); - } - } - } - - if (scf_instance_delete(instance) != 0) { - errflag = B_TRUE; - KSSL_DEBUG( - "ERROR scf_instance_delete failed: %s\n", - scf_strerror(scf_error())); - goto out4; - } else { - KSSL_DEBUG("deleted %s\n", instance_name); - } - - if (scf_walk_fmri(handle, 1, (char **)&SERVICE_NAME, - SCF_WALK_MULTIPLE, count_inst_cb, &num_inst, &exit_status, - ign_err) == 0) { - /* - * Disable the kssl socket filter if this is the last - * kssl instance. - */ - if (num_inst == 0) { - if (smf_disable_instance(KSSL_FILTER_SVC_NAME, 0) != 0) - (void) fprintf(stderr, - gettext("Unable to disable service \"%s\". " - "Error: %s"), KSSL_FILTER_SVC_NAME, - scf_strerror(scf_error())); - } - } - - status = SUCCESS; - -out4: - scf_service_destroy(svc); -out3: - scf_scope_destroy(scope); -out2: - (void) scf_handle_unbind(handle); -out1: - if (handle != NULL) - scf_handle_destroy(handle); - if (errflag) - (void) fprintf(stderr, gettext( - "Unexpected fatal libscf error: %s. Exiting.\n"), - scf_strerror(scf_error())); - return (status); -} - -int -do_delete(int argc, char *argv[]) -{ - char c; - int status, len, pcnt; - char address_port[MAX_ADRPORT_LEN + 1]; - char *instance_name; - - if (argc < 3) { - goto err; - } - - argc -= 1; - argv += 1; - - while ((c = getopt(argc, argv, "v")) != -1) { - switch (c) { - case 'v': - verbose = B_TRUE; - break; - default: - goto err; - } - } - - pcnt = argc - optind; - if (pcnt == 1) { - if (strlen(argv[optind]) < MAX_ADRPORT_LEN) { - (void) strcpy(address_port, argv[optind]); - } else { - (void) fprintf(stderr, gettext( - "argument too long -- %s\n"), - argv[optind]); - return (FAILURE); - } - } else if (pcnt == 2) { - if ((len = strlen(argv[optind])) + - (strlen(argv[optind + 1])) < MAX_ADRPORT_LEN) { - (void) strcpy(address_port, argv[optind]); - address_port[len] = ' '; - (void) strcpy(address_port + len + 1, argv[optind + 1]); - } else { - (void) fprintf(stderr, gettext( - "arguments too long -- %s %s\n"), - argv[optind], argv[optind + 1]); - return (FAILURE); - } - } else { - goto err; - } - - instance_name = create_instance_name(address_port, NULL, B_FALSE); - if (instance_name == NULL) { - return (FAILURE); - } - - KSSL_DEBUG("instance_name=%s\n", instance_name); - status = delete_instance(instance_name); - free(instance_name); - - return (status); - -err: - usage_delete(B_TRUE); - return (ERROR_USAGE); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/socket-filter-kssl.xml b/usr/src/cmd/cmd-inet/usr.sbin/socket-filter-kssl.xml deleted file mode 100644 index e821a9c964..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/socket-filter-kssl.xml +++ /dev/null @@ -1,90 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - - 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 - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. ---> - -<service_bundle type='manifest' name='SUNWcs:socket-filter-kssl'> - -<service - name='network/socket-filter' - type='service' - version='1'> - - <instance name='kssl' enabled='false'> - <dependency - name='kssl-filter-filesystem-root' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/filesystem/root' /> - </dependency> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-sockfilter start' - timeout_seconds='60' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-sockfilter stop' - timeout_seconds='60' /> - - <property_group name='startd' type='framework'> - <propval name='duration' type='astring' - value='transient' /> - </property_group> - - <property_group name='socket-filter' type='framework'> - <propval name='name' type='astring' value='ksslf' /> - <propval name='module_name' type='astring' - value='ksslf' /> - <propval name='attach_semantics' type='astring' - value='auto' /> - <propval name='socket_tuples' type='astring' - value='2:2:0,2:2:6,26:2:0,26:2:6' /> - </property_group> - - <template> - <common_name> - <loctext xml:lang='C'> - kernel SSL socket filter - </loctext> - </common_name> - <documentation> - <manpage title='ksslcfg' section='8' - manpath='/usr/share/man' /> - </documentation> - </template> - </instance> - - <stability value='Unstable' /> -</service> - -</service_bundle> diff --git a/usr/src/cmd/devfsadm/misc_link.c b/usr/src/cmd/devfsadm/misc_link.c index 93112628a4..7cc2c1812b 100644 --- a/usr/src/cmd/devfsadm/misc_link.c +++ b/usr/src/cmd/devfsadm/misc_link.c @@ -22,6 +22,7 @@ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright 2022 Garrett D'Amore <garrett@damore.org> */ #include <regex.h> @@ -106,7 +107,7 @@ static devfsadm_create_t misc_cbt[] = { "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|" "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|" "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|" - "(^sysevent$)|(^kssl$)|(^physmem$)", + "(^sysevent$)|(^physmem$)", TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name }, { "pseudo", "ddi_pseudo", diff --git a/usr/src/cmd/sgs/Makefile.sub b/usr/src/cmd/sgs/Makefile.sub index f127f18287..a56899c95d 100644 --- a/usr/src/cmd/sgs/Makefile.sub +++ b/usr/src/cmd/sgs/Makefile.sub @@ -27,7 +27,8 @@ include $(SRC)/Makefile.master -SUBDIRS = $(MACH) $(EXTRASUBDIRS) +SUBDIRS = $(EXTRASUBDIRS) +$(BUILD32)SUBDIRS += $(MACH) $(BUILD64)SUBDIRS += $(MACH64) all := TARGET= all diff --git a/usr/src/cmd/sgs/ld/Makefile b/usr/src/cmd/sgs/ld/Makefile index 75eeaf1889..35c78efe07 100644 --- a/usr/src/cmd/sgs/ld/Makefile +++ b/usr/src/cmd/sgs/ld/Makefile @@ -23,6 +23,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" + +BUILD32 = $(POUND_SIGN) include $(SRC)/cmd/sgs/Makefile.sub diff --git a/usr/src/cmd/sgs/ld/Makefile.com b/usr/src/cmd/sgs/ld/Makefile.com index 32d435cc67..12187dbd21 100644 --- a/usr/src/cmd/sgs/ld/Makefile.com +++ b/usr/src/cmd/sgs/ld/Makefile.com @@ -41,12 +41,11 @@ SRCDIR = $(SGSHOME)/ld MAPFILES = $(SRCDIR)/common/mapfile-intf $(MAPFILE.NGB) MAPOPTS = $(MAPFILES:%=-Wl,-M%) -RPATH = '-R$$ORIGIN/../../lib' -RPATH64 = '-R$$ORIGIN/../../../lib/$(MACH64)' +RPATH = '-R$$ORIGIN/../../lib/$(MACH64)' LDFLAGS += $(VERSREF) $(MAPOPTS) $(RPATH) -LDLIBS += -lumem $(LDLIBDIR) -lld $(ELFLIBDIR) -lelf \ - $(LDDBGLIBDIR) -llddbg $(CONVLIBDIR) -lconv +LDLIBS += -lumem $(LDLIBDIR64) -lld $(ELFLIBDIR64) -lelf \ + $(LDDBGLIBDIR64) -llddbg $(CONVLIBDIR64) -lconv CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-parentheses diff --git a/usr/src/cmd/sgs/ld/amd64/Makefile b/usr/src/cmd/sgs/ld/amd64/Makefile index 1315c657ff..2a4c3c5d37 100644 --- a/usr/src/cmd/sgs/ld/amd64/Makefile +++ b/usr/src/cmd/sgs/ld/amd64/Makefile @@ -27,14 +27,11 @@ include ../Makefile.com -LDLIBDIR = $(LDLIBDIR64) -ELFLIBDIR = $(ELFLIBDIR64) -LDDBGLIBDIR = $(LDDBGLIBDIR64) -CONVLIBDIR = $(CONVLIBDIR64) +install: all $(ROOTPROG) $(ROOTPROG64) \ + $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64) -RPATH = $(RPATH64) - -install: all $(ROOTPROG64) $(ROOTCCSBINLINK64) +$(ROOTBIN64)/ld: + $(RM) $@; $(SYMLINK) ../../bin/ld $@ .KEEP_STATE: diff --git a/usr/src/cmd/sgs/ld/common/ld.c b/usr/src/cmd/sgs/ld/common/ld.c index 794f5e5e09..90e14b46c3 100644 --- a/usr/src/cmd/sgs/ld/common/ld.c +++ b/usr/src/cmd/sgs/ld/common/ld.c @@ -226,12 +226,11 @@ archive(int fd, Elf *elf, uchar_t *class_ret, Half *mach_ret) /* * Determine: * - ELFCLASS of resulting object (class) - * - Whether user specified class of the linker (ldclass) * - ELF machine type of resulting object (m_mach) * * In order of priority, we determine this information as follows: * - * - Command line options (-32, -64, -z altexec64, -z target). + * - Command line options (-32, -64 -z target). * - From the first plain object seen on the command line. (This is * by far the most common case.) * - From the first object contained within the first archive @@ -241,17 +240,11 @@ archive(int fd, Elf *elf, uchar_t *class_ret, Half *mach_ret) * entry: * argc, argv - Command line argument vector * class_ret - Address of variable to receive ELFCLASS of output object - * ldclass_ret - Address of variable to receive ELFCLASS of - * linker to use. This will be ELFCLASS32/ELFCLASS64 if one - * is explicitly specified, and ELFCLASSNONE otherwise. - * ELFCLASSNONE therefore means that we should use the best - * link-editor that the system/kernel will allow. */ static int -process_args(int argc, char **argv, uchar_t *class_ret, uchar_t *ldclass_ret, - Half *mach) +process_args(int argc, char **argv, uchar_t *class_ret, Half *mach) { - uchar_t ldclass = ELFCLASSNONE, class = ELFCLASSNONE, ar_class; + uchar_t class = ELFCLASSNONE, ar_class; Half mach32 = EM_NONE, mach64 = EM_NONE, ar_mach; int c, ar_found = 0; @@ -278,10 +271,6 @@ process_args(int argc, char **argv, uchar_t *class_ret, uchar_t *ldclass_ret, * a mix of 32 and 64-bit objects, and the first object * in that archive is 32-bit. * - * -z altexec64 - * Use the 64-bit linker regardless of the class - * of the output object. - * * -z target=platform * Produce output object for the specified platform. * This option is needed when producing an object @@ -313,14 +302,6 @@ getmore: break; case 'z': -#if !defined(_LP64) - /* -z altexec64 */ - if (strncmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64), - MSG_ARG_ALTEXEC64_SIZE) == 0) { - ldclass = ELFCLASS64; - break; - } -#endif /* -z target=platform */ if (strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET), MSG_ARG_TARGET_SIZE) == 0) { @@ -459,9 +440,6 @@ getmore: class = ar_found ? ar_class : ELFCLASS32; *class_ret = class; - /* ELFCLASS of link-editor to use */ - *ldclass_ret = ldclass; - /* * Machine type of output object: If we did not establish a machine * type from the command line, or from the first plain object, then @@ -660,8 +638,7 @@ ld_altexec(char **argv, char **envp) int main(int argc, char **argv, char **envp) { - char **oargv = argv; - uchar_t class, ldclass, checkclass; + uchar_t class; Half mach; /* @@ -690,31 +667,9 @@ main(int argc, char **argv, char **envp) * - link-editor class * - target machine */ - if (process_args(argc, argv, &class, &ldclass, &mach)) + if (process_args(argc, argv, &class, &mach)) return (1); - /* - * Unless a 32-bit link-editor was explicitly requested, try - * to exec the 64-bit version. - */ - if (ldclass != ELFCLASS32) - checkclass = conv_check_native(oargv, envp); - - /* - * If an attempt to exec the 64-bit link-editor fails: - * - Bail if the 64-bit linker was explicitly requested - * - Continue quietly if the 64-bit linker was not requested. - * This is undoubtedly due to hardware/kernel limitations, - * and therefore represents the best we can do. Note that - * the 32-bit linker is capable of linking anything the - * 64-bit version is, subject to a 4GB limit on memory, and - * 2GB object size. - */ - if ((ldclass == ELFCLASS64) && (checkclass != ELFCLASS64)) { - eprintf(0, ERR_FATAL, MSG_INTL(MSG_SYS_64)); - return (1); - } - /* Call the libld entry point for the specified ELFCLASS */ if (class == ELFCLASS64) return (ld64_main(argc, argv, mach)); diff --git a/usr/src/cmd/sgs/ld/common/ld.msg b/usr/src/cmd/sgs/ld/common/ld.msg index cc3dcd56c4..3b31deb37f 100644 --- a/usr/src/cmd/sgs/ld/common/ld.msg +++ b/usr/src/cmd/sgs/ld/common/ld.msg @@ -35,7 +35,6 @@ @ MSG_SYS_EXEC "file %s: exec failed: %s" @ MSG_SYS_ALLOC "alloc failed: %s" -@ MSG_SYS_64 "unable to execute 64-bit version of ld" @ MSG_ERR_BADTARG "unknown target platform: %s" @@ -60,7 +59,6 @@ @ MSG_ARG_TWO "2" @ MSG_ARG_FOUR "4" -@ MSG_ARG_ALTEXEC64 "altexec64" @ MSG_ARG_TARGET "target=" @ MSG_LD_OPTIONS "LD_OPTIONS" diff --git a/usr/src/cmd/sgs/ld/i386/Makefile b/usr/src/cmd/sgs/ld/i386/Makefile deleted file mode 100644 index c9a167d407..0000000000 --- a/usr/src/cmd/sgs/ld/i386/Makefile +++ /dev/null @@ -1,31 +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 (c) 1996 by Sun Microsystems, Inc. -# All rights reserved. - -include ../Makefile.com - -.KEEP_STATE: - -install: all $(ROOTPROG) $(ROOTCCSBINLINK) - -include ../Makefile.targ diff --git a/usr/src/cmd/sgs/ld/sparc/Makefile b/usr/src/cmd/sgs/ld/sparc/Makefile deleted file mode 100644 index 999606887c..0000000000 --- a/usr/src/cmd/sgs/ld/sparc/Makefile +++ /dev/null @@ -1,31 +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 (c) 1996 by Sun Microsystems, Inc. -# All rights reserved. - -include ../Makefile.com - -.KEEP_STATE: - -install: all $(ROOTBIN) $(ROOTCCSBINLINK) - -include ../Makefile.targ diff --git a/usr/src/cmd/sgs/ld/sparcv9/Makefile b/usr/src/cmd/sgs/ld/sparcv9/Makefile index 8cc2aab477..6ad7730834 100644 --- a/usr/src/cmd/sgs/ld/sparcv9/Makefile +++ b/usr/src/cmd/sgs/ld/sparcv9/Makefile @@ -26,16 +26,13 @@ include ../Makefile.com -LDLIBDIR = $(LDLIBDIR64) -ELFLIBDIR = $(ELFLIBDIR64) -LDDBGLIBDIR = $(LDDBGLIBDIR64) -CONVLIBDIR = $(CONVLIBDIR64) +install: all $(ROOTPROG) $(ROOTPROG64) \ + $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64) -RPATH = $(RPATH64) +$(ROOTBIN64)/ld: + $(RM) $@; $(SYMLINK) ../../bin/ld $@ .KEEP_STATE: -install: all $(ROOTBIN64) $(ROOTCCSBINLINK64) - include ../Makefile.targ include $(SRC)/Makefile.master.64 diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c index 2dfa6e4ca3..0ad5299b0a 100644 --- a/usr/src/cmd/sgs/libld/common/args.c +++ b/usr/src/cmd/sgs/libld/common/args.c @@ -192,7 +192,6 @@ usage_mesg(Boolean detail) (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE)); - (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZADLIB)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDEF)); @@ -1580,8 +1579,9 @@ parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage) } /* * The following options just need validation as they - * are interpreted on the second pass through the - * command line arguments. + * are interpreted either on the second pass through + * the command line arguments, by ld(1) directly, or + * are merely accepted for compatibility. */ } else if ( strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY), diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index 93e9889c0f..c14d1a7ff4 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -140,7 +140,6 @@ allow extraction of\n\ \t\t\tarchive members to resolve weak references from \ \n\t\t\t\archive files\n" -@ MSG_ARG_DETAIL_ZAL "\t[-z altexec64]\texecute the 64-bit link-editor\n" @ MSG_ARG_DETAIL_ZADLIB "\t[-z assert-deflib]\n\ \t\t\tenables warnings for linking with libraries in \ the \n\t\t\tdefault search path\n\ diff --git a/usr/src/cmd/sgs/tools/SUNWonld-README b/usr/src/cmd/sgs/tools/SUNWonld-README index 83906f59c3..fdcbd59a76 100644 --- a/usr/src/cmd/sgs/tools/SUNWonld-README +++ b/usr/src/cmd/sgs/tools/SUNWonld-README @@ -1689,3 +1689,4 @@ Bugid Risk Synopsis 4795 /usr/bin/ld manpage and help should indicate '-soname' not '--soname' 14090 ld(1) could use a normal allocator 14722 ld should keep group members in separate output sections +14770 ld(1) should be 64bit only diff --git a/usr/src/cmd/svc/shell/mfsthistory b/usr/src/cmd/svc/shell/mfsthistory index 7a719d1c49..2a1bac3b74 100644 --- a/usr/src/cmd/svc/shell/mfsthistory +++ b/usr/src/cmd/svc/shell/mfsthistory @@ -311,7 +311,6 @@ svc:/network/routing/legacy-routing:ipv4 var/svc/manifest/network/routing/legacy svc:/network/routing/legacy-routing var/svc/manifest/network/routing/legacy-routing.xml svc:/network/shares/group:default var/svc/manifest/network/shares/group.xml svc:/network/shares/group var/svc/manifest/network/shares/group.xml -svc:/network/ssl/proxy var/svc/manifest/network/ssl/kssl-proxy.xml svc:/system/auditd:default var/svc/manifest/system/auditd.xml svc:/system/auditd var/svc/manifest/system/auditd.xml svc:/system/boot-archive-update:default var/svc/manifest/system/boot-archive-update.xml diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c index 1c15c31b5c..a8a4ab4dfa 100644 --- a/usr/src/cmd/truss/codes.c +++ b/usr/src/cmd/truss/codes.c @@ -26,6 +26,7 @@ * Copyright 2020 Joyent, Inc. * Copyright (c) 2014, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Garrett D'Amore <garrett@damore.org> */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -91,7 +92,6 @@ #include <net/simnet.h> #include <sys/vnic.h> #include <sys/fs/zfs.h> -#include <inet/kssl/kssl.h> #include <sys/dkio.h> #include <sys/fdio.h> #include <sys/cdio.h> @@ -1307,12 +1307,6 @@ const struct ioc { { (uint_t)ZFS_IOC_GET_BOOTENV, "ZFS_IOC_GET_BOOTENV", "zfs_cmd_t" }, - /* kssl ioctls */ - { (uint_t)KSSL_ADD_ENTRY, "KSSL_ADD_ENTRY", - "kssl_params_t"}, - { (uint_t)KSSL_DELETE_ENTRY, "KSSL_DELETE_ENTRY", - "sockaddr_in"}, - /* disk ioctls - (0x04 << 8) - dkio.h */ { (uint_t)DKIOCGGEOM, "DKIOCGGEOM", "struct dk_geom"}, diff --git a/usr/src/lib/brand/joyent-minimal/zone/manifests b/usr/src/lib/brand/joyent-minimal/zone/manifests index 955d46702e..ee102432e1 100644 --- a/usr/src/lib/brand/joyent-minimal/zone/manifests +++ b/usr/src/lib/brand/joyent-minimal/zone/manifests @@ -30,8 +30,6 @@ # application/x11/xvnc-inetd.xml # network/ldap/client.xml # network/rpc/keyserv.xml -# network/socket-filter-kssl.xml -# network/ssl/kssl-proxy.xml # network/nfs/rquota.xml # network/smb/server.xml # network/dns/server.xml diff --git a/usr/src/lib/brand/joyent/zone/manifests b/usr/src/lib/brand/joyent/zone/manifests index 684f4c9c4b..e465b8c7cc 100644 --- a/usr/src/lib/brand/joyent/zone/manifests +++ b/usr/src/lib/brand/joyent/zone/manifests @@ -29,8 +29,6 @@ # application/x11/xfs.xml # application/x11/xvnc-inetd.xml # network/rpc/keyserv.xml -# network/socket-filter-kssl.xml -# network/ssl/kssl-proxy.xml # network/dns/server.xml # network/ftp.xml # network/finger.xml diff --git a/usr/src/lib/libsecdb/exec_attr.txt b/usr/src/lib/libsecdb/exec_attr.txt index dc86dc9342..feb95dd8c4 100644 --- a/usr/src/lib/libsecdb/exec_attr.txt +++ b/usr/src/lib/libsecdb/exec_attr.txt @@ -20,6 +20,7 @@ # # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # # /etc/security/exec_attr # @@ -224,7 +225,6 @@ Network IPsec Management:suser:cmd:::/usr/sbin/ikecert:euid=0 Network IPsec Management:suser:cmd:::/usr/sbin/ipsecconf:euid=0 Network IPsec Management:suser:cmd:::/usr/sbin/ipseckey:uid=0 Network IPsec Management:suser:cmd:::/usr/sbin/ipsecalgs:euid=0 -Network Security:solaris:cmd:::/usr/sbin/ksslcfg:euid=0 Network Security:suser:cmd:::/usr/bin/ssh-keygen:uid=0;gid=sys Object Access Management:solaris:cmd:::/usr/bin/chgrp:privs=file_chown Object Access Management:solaris:cmd:::/usr/bin/chmod:privs=file_owner diff --git a/usr/src/man/man8/Makefile b/usr/src/man/man8/Makefile index 3f7e3dc598..bad2e9d2d7 100644 --- a/usr/src/man/man8/Makefile +++ b/usr/src/man/man8/Makefile @@ -19,6 +19,7 @@ # Copyright 2020 Joyent, Inc. # Copyright 2020 Peter Tribble # Copyright 2021 OmniOS Community Edition (OmniOSce) Association. +# Copryight 2022 Garrett D'Amore <garrett@damore.org> # include $(SRC)/Makefile.master @@ -249,7 +250,6 @@ _MANFILES= 6to4relay.8 \ kpropd.8 \ kproplog.8 \ krb5kdc.8 \ - ksslcfg.8 \ kstat.8 \ ktkt_warnd.8 \ labelit.8 \ diff --git a/usr/src/man/man8/ksslcfg.8 b/usr/src/man/man8/ksslcfg.8 deleted file mode 100644 index 74fbf79247..0000000000 --- a/usr/src/man/man8/ksslcfg.8 +++ /dev/null @@ -1,417 +0,0 @@ -'\" te -.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved -.\" 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] -.TH KSSLCFG 8 "November 22, 2021" -.SH NAME -ksslcfg \- enable and configure SMF instance of Kernel SSL -.SH SYNOPSIS -.nf -\fBksslcfg\fR create \fB-f\fR pkcs11 \fB-T\fR \fItoken_label\fR \fB-C\fR \fIcertificate_label\fR - [\fB-d\fR \fIsofttoken_directory\fR] - [\fB-p\fR \fIpassword_file\fR [\fB-u\fR \fIusername\fR]] - [\fB-h\fR \fIca_certchain_file\fR] [\fB-c\fR \fIciphersuites\fR] - [\fB-t\fR \fIssl_session_cache_timeout\fR] - [\fB-z\fR \fIssl_session_cache_size\fR] [\fB-v\fR] \fB-x\fR \fIproxy_port\fR [\fIhost\fR] \fIssl_port\fR -.fi - -.LP -.nf -\fBksslcfg\fR create \fB-f\fR pkcs12 \fB-i\fR \fIcert_and_key_pk12file\fR - [\fB-p\fR \fIpassword_file\fR [\fB-u\fR \fIusername\fR]] - [\fB-c\fR \fIciphersuites\fR] [\fB-t\fR \fIssl_session_cache_timeout\fR] - [\fB-z\fR \fIssl_session_cache_size\fR] [\fB-v\fR] \fB-x\fR \fIproxy_port\fR [\fIhost\fR] \fIssl_port\fR -.fi - -.LP -.nf -\fBksslcfg\fR create \fB-f\fR pem \fB-i\fR \fIcert_and_key_pemfile\fR - [\fB-p\fR \fIpassword_file\fR [\fB-u\fR \fIusername\fR]] - [\fB-c\fR \fIciphersuites\fR] [\fB-t\fR \fIssl_session_cache_timeout\fR] - [\fB-z\fR \fIssl_session_cache_size\fR] [\fB-v\fR] \fB-x\fR \fIproxy_port\fR [\fIhost\fR] \fIssl_port\fR -.fi - -.LP -.nf -\fBksslcfg\fR delete [\fB-v\fR] [\fIhost\fR] \fIssl_port\fR -.fi - -.LP -.nf -\fBksslcfg\fR \fB-V\fR -.fi - -.LP -.nf -\fBksslcfg\fR \fB-?\fR -.fi - -.SH DESCRIPTION -\fBksslcfg\fR manages \fBsmf\fR(7) instances for the Kernel SSL proxy module. -An SSL-enabled web server can use the services of its Kernel SSL proxy to -improve the performance of the HTTPS packets processing. It does so by creating -an instance of the Kernel SSL service, specifying the SSL proxy port and -parameters, and by listening on the proxy port. -.sp -.LP -The \fBcreate\fR subcommand creates an instance and enables the service for the -given address and SSL port. -.sp -.LP -The \fBdelete\fR subcommand disables the service for the given address and -port, if it is enabled, and deletes the instance from the SMF repository. -.sp -.LP -\fBksslcfg\fR can be run as root or by other users assigned to the Network -Security profile. See \fBrbac\fR(7) and \fBuser_attr\fR(5). You must run -\fBksslcfg\fR to configure your Kernel SSL proxy before you start your -application. -.sp -.LP -\fBksslcfg\fR allows you to specify an \fIssl_port\fR operand, described under -OPERANDS, and, with the \fB-x\fR option, a \fIproxy_port\fR value. When -specified for use with the Kernel SSL proxy, these values cannot also be -configured for the Solaris Network Cache and Acceleration (NCA) feature. See -\fBnca\fR(1) for a description of the NCA feature. -.sp -.LP -The Fault Managed Resource Identifier (FMRI) for the kernel SSL proxy instances -is \fBsvc://network/ssl/proxy\fR. \fBksslcfg\fR creates an instance of that -service unique to the combination of host and SSL port. Instance FMRIs for -particular proxy entries can be found with \fBsvcs\fR(1) and used for -dependencies of other services. -.SH OPTIONS -The following options are supported: -.sp -.ne 2 -.na -\fB\fB-c\fR \fIciphersuites\fR\fR -.ad -.sp .6 -.RS 4n -Set of ciphers a client is allowed to negotiate in a sorted order. The -supported SSL version3 and TLS ciphers are listed below. Note that the names -are case-insensitive. -.sp -.in +2 -.nf -rsa_rc4_128_sha -rsa_rc4_128_md5 -rsa_aes_256_cbc_sha -rsa_aes_128_cbc_sha -rsa_3des_ede_cbc_sha -rsa_des_cbc_sha -.fi -.in -2 - -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR \fIkey_format\fR\fR -.ad -.sp .6 -.RS 4n -Uses the certificate/key format specified in \fIkey_format\fR. The supported -options are \fBpkcs11\fR, \fBpkcs12\fR, and \fBpem\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-i\fR \fIkey_and_certificate_file\fR\fR -.ad -.sp .6 -.RS 4n -When \fBpkcs12\fR or \fBpem\fR is specified with the \fB-f\fR option, reads a -key and a certificate of the web server from \fIkey_and_certificate_file\fR. -This file can also contain any intermediate CA certificates that form the -certificate chain to the root CA for the server certificate. These certificates -must follow the server certificate in the file and the order must be bottom up: -lowest level CA certificate followed by the next higher level CA certificate, -and so on. -.RE - -.sp -.ne 2 -.na -\fB\fB-C\fR \fIcertificate_label\fR\fR -.ad -.sp .6 -.RS 4n -PKCS#11 can store multiple certificates in single token. This option enables -you to specify a single certificate, identified by \fIcertificate_label\fR. -This label must match the \fBCKA_LABEL\fR on the certificate object in the -token specified by \fB-T\fR. This option is to be used only with \fB-f\fR -\fBpkcs11\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-d\fR \fIsofttoken_directory\fR\fR -.ad -.sp .6 -.RS 4n -This option is applicable only with the \fBpkcs11\fR key format, when the token -label is the Sun Software PKCS#11 softtoken. Use this option to override the -default location of the PKCS#11 softtoken directory (\fB$HOME/.sunw\fR). See -\fBpkcs11_softtoken\fR(7). -.RE - -.sp -.ne 2 -.na -\fB\fB-h\fR \fIca_certchain_file\fR\fR -.ad -.sp .6 -.RS 4n -When \fBpkcs11\fR is specified with the \fB-f\fR option, reads a set of -intermediate CA certificates that form the certificate chain to the root CA for -the server certificate (specified with the \fB-C\fR option), from -\fIca_certchain_file\fR. The file must be in PEM format. -.RE - -.sp -.ne 2 -.na -\fB\fB-p\fR \fIpassword_file\fR\fR -.ad -.sp .6 -.RS 4n -Obtains the password used to encrypt the private key from \fIpassword_file\fR. -When using the \fBpkcs11\fR option (see \fB-f\fR, above), the password is used -to authenticate the user to the PKCS #11 token. -.RE - -.sp -.ne 2 -.na -\fB\fB-t\fR \fIssl_session_cache_timeout\fR\fR -.ad -.sp .6 -.RS 4n -The timeout value, in seconds, for an SSL session. It corresponds to -\fBSSL3SessionTimeout\fR of the Sun ONE web server configuration or -\fBSSLSessionCacheTimeout\fR of \fBmod_ssl\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-T\fR \fItoken_label\fR\fR -.ad -.sp .6 -.RS 4n -When \fBpkcs11\fR is specified with \fB-f\fR, uses the PKCS#11 token specified -in \fItoken_label\fR. Use \fBcryptoadm list\fR \fB-v\fR to display all PKCS#11 -tokens available. -.RE - -.sp -.ne 2 -.na -\fB\fB-u\fR \fIusername\fR\fR -.ad -.sp .6 -.RS 4n -The username of the user who owns the password file. If omitted, the system -will try to read the password file as root. -.RE - -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.sp .6 -.RS 4n -Verbose mode. -.RE - -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.sp .6 -.RS 4n -Displays the version. -.RE - -.sp -.ne 2 -.na -\fB\fB-x\fR \fIproxy_port\fR\fR -.ad -.sp .6 -.RS 4n -The SSL proxy port. The port number is designated exclusively for clear-text -HTTP communication between the web server and the kernel SSL proxy module. No -external HTTP packets are delivered to this port. -.RE - -.sp -.ne 2 -.na -\fB\fB-z\fR \fIssl_session_cache_size\fR\fR -.ad -.sp .6 -.RS 4n -The maximum number of SSL sessions that can be cached. It corresponds to -\fBSSLCacheEntries\fR of the Sun ONE web server configuration. When this option -is not specified, the default is 5000 entries. -.RE - -.sp -.ne 2 -.na -\fB\fB-?\fR \fI\fR\fR -.ad -.sp .6 -.RS 4n -Displays the usage of the command. -.RE - -.SH OPERANDS -.ne 2 -.na -\fB\fB[\fIhost\fR] [\fIssl_port\fR]\fR\fR -.ad -.RS 21n -The address and the port of the web server for which the kernel SSL entry is -created. If \fIhost\fR is omitted, the entry will be used for all requests that -arrived at the \fIssl_port\fR, regardless of the destination address. Both a -host name and an IP address are acceptable forms for \fIhost\fR. \fIssl_port\fR -is required. Typically, this has a value of 443. -.RE - -.SH EXAMPLES -\fBExample 1 \fRCreate and Enable a Kernel SSL Instance -.sp -.LP -The following command creates and enables a Kernel SSL instance using a -certificate and a key in PKCS#11 format. - -.sp -.in +2 -.nf -# \fBksslcfg create -f pkcs11 -T "Sun Software PKCS#11 softtoken" \e --C "Server-Cert" -p /some/directory/password -u webservd \e --x 8080 www.example.com 443\fR - -% \fBsvcs svc:/network/ssl/proxy\fR -STATE STIME FMRI -online Sep_27 svc:/network/ssl/proxy:kssl-www-example-com-443 -.fi -.in -2 -.sp - -.LP -\fBExample 2 \fRCreate and Enable a Default Instance for All Addresses -.sp -.LP -The following command creates and enables a default instance for all addresses -from a certificate and key in a \fBpkcs#12\fR file. - -.sp -.in +2 -.nf -# \fBksslcfg create -x 8888 -f pkcs12 -i /some/directory/keypair.p12 \e - -p /some/directory/password -u webservd 443\fR -.fi -.in -2 -.sp - -.LP -\fBExample 3 \fRCreate and Enable an Instance with Specific Cipher Suites -.sp -.LP -The following command creates and enables an instance with specific cipher -suites. - -.sp -.in +2 -.nf -# \fBksslcfg create -x 8080 -f pem \e --i /some/directory/keypair.pem -p /some/directory/password \e --c "rsa_rc4_128_md5,rsa_rc4_128_sha" \e -209.249.116.195 443\fR -.fi -.in -2 -.sp - -.LP -\fBExample 4 \fRDisable and Delete an Instance -.sp -.LP -The following command disables and deletes an instance. - -.sp -.in +2 -.nf -# \fBksslcfg delete www.example.com 443\fR -.fi -.in -2 -.sp - -.SH EXIT STATUS -.ne 2 -.na -\fB\fB0\fR\fR -.ad -.RS 6n -Successful completion. -.RE - -.sp -.ne 2 -.na -\fB\fB>0\fR\fR -.ad -.RS 6n -An error occurred. -.RE - -.SH ATTRIBUTES -See \fBattributes\fR(7) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability See below. -.TE - -.sp -.LP -Command line options are Evolving; command output is Unstable. The FMRI service -name (\fBsvc://network/ssl/proxy\fR) is Unstable, as is the FMRI instance's -name format. The utility name is Stable. -.SH SEE ALSO -.BR nca (1), -.BR svcprop (1), -.BR svcs (1), -.BR user_attr (5), -.BR attributes (7), -.BR pkcs11_softtoken (7), -.BR rbac (7), -.BR smf (7), -.BR cryptoadm (8), -.BR svcadm (8), -.BR svccfg (8) -.SH NOTES -\fBksslcfg\fR \fBcreate\fR without an host argument creates an \fBINADDR_ANY\fR -\fBsmf\fR instance. \fBksslcfg\fR \fBdelete\fR without an host argument deletes -only the \fBINADDR_ANY\fR instance. \fBksslcfg\fR \fBdelete\fR needs a host -argument to delete any non-\fBINADDR_ANY\fR instance. -.sp -.LP -On a system with \fBzones\fR(7) installed, the \fBksslcfg\fR command can be -used only in the global zone at this time. diff --git a/usr/src/man/man9e/Makefile b/usr/src/man/man9e/Makefile index a67785e520..33de233a1a 100644 --- a/usr/src/man/man9e/Makefile +++ b/usr/src/man/man9e/Makefile @@ -45,6 +45,8 @@ MANFILES= Intro.9e \ mac.9e \ mac_capab_transceiver.9e \ mac_capab_led.9e \ + mac_capab_rings.9e \ + mac_filter.9e \ mc_getcapab.9e \ mc_getprop.9e \ mc_getstat.9e \ @@ -57,6 +59,12 @@ MANFILES= Intro.9e \ mc_start.9e \ mc_tx.9e \ mc_unicst.9e \ + mgi_start.9e \ + mi_enable.9e \ + mr_gget.9e \ + mr_rget.9e \ + mri_poll.9e \ + mri_stat.9e \ mmap.9e \ open.9e \ power.9e \ @@ -121,6 +129,15 @@ MANLINKS= ddi_ufm_op_fill_image.9e \ mcl_set.9e \ mct_info.9e \ mct_read.9e \ + mgi_addmac.9e \ + mgi_addvlan.9e \ + mgi_remmac.9e \ + mgi_remvlan.9e \ + mgi_stop.9e \ + mi_disable.9e \ + mri_start.9e \ + mri_stop.9e \ + mri_tx.9e \ intro.9e \ tran_destroy_pkt.9e \ tran_pkt_constructor.9e \ @@ -159,6 +176,11 @@ gldm_set_promiscuous.9e := LINKSRC = gld.9e gldm_start.9e := LINKSRC = gld.9e gldm_stop.9e := LINKSRC = gld.9e +mgi_addmac.9e := LINKSRC = mac_filter.9e +mgi_remmac.9e := LINKSRC = mac_filter.9e +mgi_addvlan.9e := LINKSRC = mac_filter.9e +mgi_remvlan.9e := LINKSRC = mac_filter.9e + mc_close.9e := LINKSRC = mc_open.9e mc_stop.9e := LINKSRC = mc_start.9e @@ -167,6 +189,14 @@ mcl_set.9e := LINKSRC = mac_capab_led.9e mct_info.9e := LINKSRC = mac_capab_transceiver.9e mct_read.9e := LINKSRC = mac_capab_transceiver.9e +mgi_stop.9e := LINKSRC = mgi_start.9e +mri_start.9e := LINKSRC = mgi_start.9e +mri_stop.9e := LINKSRC = mgi_start.9e + +mi_disable.9e := LINKSRC = mi_enable.9e + +mri_tx.9e := LINKSRC = mc_tx.9e + tran_setcap.9e := LINKSRC = tran_getcap.9e tran_destroy_pkt.9e := LINKSRC = tran_init_pkt.9e diff --git a/usr/src/man/man9e/mac.9e b/usr/src/man/man9e/mac.9e index cc24da4b9b..a3a6f5c4ad 100644 --- a/usr/src/man/man9e/mac.9e +++ b/usr/src/man/man9e/mac.9e @@ -11,9 +11,9 @@ .\" .\" Copyright 2019 Joyent, Inc. .\" Copyright 2020 RackTop Systems, Inc. -.\" Copyright 2021 Oxide Computer Company +.\" Copyright 2022 Oxide Computer Company .\" -.Dd February 13, 2021 +.Dd July 2, 2022 .Dt MAC 9E .Os .Sh NAME @@ -70,8 +70,58 @@ routines. In addition, all of the work to interact with .Xr dlpi 4P is taken care of automatically and transparently. +.Ss High-Level Design +At a high-level, a device driver is chiefly concerned with three general +operations: +.Bl -enum -offset indent +.It +Sending frames +.It +Receiving frames +.It +Managing device configuration and metadata +.El +.Pp +When sending frames, the MAC framework always calls functions registered +in the +.Xr mac_callbacks 9S +structure to have the driver transmit frames on hardware. +When receiving frames, the driver will generally receive an interrupt which will +cause it to check for incoming data and deliver it to the MAC framework. +.Pp +Configuration of a device, such as whether auto-negotiation should be +enabled, the speeds that the device supports, the MTU (maximum +transmission unit), and the generation of pause frames are all driven by +properties. +The functions to get, set, and obtain information about properties are +defined through callback functions specified in the +.Xr mac_callbacks 9S +structure. +The full list of properties and a description of the relevant callbacks +can be found in the +.Sx PROPERTIES +section. +.Pp +The MAC framework is designed to take advantage of various modern +features provided by hardware, such as checksumming, segmentation +offload, and hardware filtering. +The MAC framework assumes none of these advanced features are present +and allows device drivers to negotiate them through a capability system. +Drivers can declare that they support various capabilities by +implementing the optional +.Xr mc_getcapab 9E +entry point. +Each capability has its associated entry points and structures to fill +out. +The capabilities are detailed in the +.Sx CAPABILITIES +section. +.Pp +The following sections describe the flow of a basic device driver. +For advanced device drivers, the flow is generally the same. +The primary distinction is in how frames are sent and received. .Ss Initializing MAC Support -For a device to be used in the framework, it must register with the +For a device to be used by the MAC framework, it must register with the framework and take specific actions during .Xr _init 9E , .Xr attach 9E , @@ -98,7 +148,7 @@ entry points. Normally, in a driver's .Xr _init 9E entry point, it passes its -.Sy modlinkage +.Xr modlinkage 9S structure directly to .Xr mod_install 9F . To properly register with MAC, the driver must call @@ -129,7 +179,7 @@ To register with MAC, a driver must allocate a structure, fill it in, and then call .Xr mac_register 9F . The -.Sy mac_register_t +.Vt mac_register_t structure contains information about the device and all of the required function pointers that will be used as callbacks by the framework. .Pp @@ -146,11 +196,11 @@ it will start receiving callbacks from the MAC framework. To allocate the registration structure, the driver should call .Xr mac_alloc 9F . Device drivers should generally always pass the symbol -.Sy MAC_VERSION +.Dv MAC_VERSION as the argument to .Xr mac_alloc 9F . Upon successful completion, the driver will receive a -.Sy mac_register_t +.Vt mac_register_t structure which it should fill in. The structure and its members are documented in .Xr mac_register 9S . @@ -177,7 +227,7 @@ should enable interrupts and finish any other initialization required. If the call to .Xr mac_register 9F failed, then it should unwind its initialization and should return -.Sy DDI_FAILURE +.Dv DDI_FAILURE from its .Xr attach 9E routine. @@ -250,13 +300,14 @@ or .Xr mac_rx 9F . Other routines in the DDI may be called while locks are held; however, device driver writers should be careful about calling blocking routines -while locks are held or in interrupt context, though it is generally -legal to do so. +while locks are held or in interrupt context, even when it is +legal to do so as this may cause all other callers that need a given +lock to back up behind such an operation. .Ss Receiving Data A device driver will often receive data through the means of an -interrupt. -When that interrupt occurs, the device driver will receive one or more frames -with optional metadata. +interrupt or by being asked to poll for frames. +When this occurs, zero or more frames, each with optional metadata, may +be ready for the device driver to consume. Often each frame has a corresponding descriptor which has information about whether or not there were errors or whether or not the device successfully checksummed the packet. @@ -267,11 +318,20 @@ See the section .Sx RECEIVE DESCRIPTOR LAYOUT for more information. .Pp -During a single interrupt, a device driver should process a fixed number -of frames. +During a single interrupt or poll request, a device driver should process +a fixed number of frames. For each frame the device driver should: .Bl -enum -offset indent .It +Ensure that all of the DMA memory for the descriptor ring is synchronized with +the +.Xr ddi_dma_sync 9F +function and check the handle for errors if the device driver has enabled DMA +error reporting as part of the Fault Management Architecture (FMA). +If the driver does not rely on DMA, then it may skip this step. +It is recommended that this is performed once per interrupt or poll for +the entire region and not on a per-packet basis. +.It First check whether or not the frame has errors. If errors were detected, then the frame should not be sent to the operating system. @@ -302,7 +362,7 @@ should set the corresponding checksumming information with a call to It should then append this new message block to the .Em end of the message block chain, linking it to the -.Sy b_next +.Fa b_next pointer. It is vitally important that all the frames be chained in the order that they were received. @@ -333,6 +393,37 @@ The rest of the networking stack will handle issues related to keeping up appropriately and ensure that kernel memory is not exhausted by packets that are not being processed. .Pp +If the device driver has negotiated the +.Dv MAC_CAPAB_RINGS +capability +.Pq discussed in Xr mac_capab_rings 9E +then it should call +.Xr mac_rx_ring 9F +and not +.Xr mac_rx 9F . +A given interrupt may correspond to more than one ring that needs to be +checked. +The set of rings is likely to span different groups that were registered +with MAC through the +.Xr mr_gget 9E +interface. +In those cases, the driver should follow the above procedure +independently for each ring. +That means it will call +.Xr mac_rx_ring 9F +once for each ring using the handle that it received from when MAC +called the driver's +.Xr mr_rget 9E +entry point. +When it is looking at the rings, the driver will need to make sure that +the ring has not had interrupts disabled +.Pq due to a pending change to polling mode . +This is discussed in greater detail in the +.Xr mac_capab_rings 9E +and +.Xr mri_poll 9E +manual pages. +.Pp Finally, the device driver should make sure that any other housekeeping activities required for the ring are taken care of such that more data can be received. @@ -371,6 +462,22 @@ device driver writers provide private properties for their device to control the interrupt coalescing rate. This will make it much easier to perform experiments and observe the impact of different interrupt rates on the rest of the system. +.Ss Polling +Even with interrupt coalescing, when there is a certain incoming packet rate it +can make more sense to just actively poll the device, asking for more packets +rather than constantly taking an interrupt. +When a device driver supports the +.Xr mac_capab_rings 9E +capability and therefore polling on receive rings, the MAC framework will ask +the driver to disable interrupts, with its +.Xr mi_disable 9E +entry point, and then subsequently call its polling entry point, +.Xr mri_poll 9E . +.Pp +As long as a device driver implements the needed entry points, then there is +nothing else that it needs to do to take advantage of polling. +A driver should not attempt to spin up its own threads, task queues, or +creatively use timeouts, to try to simulate polling for received packets. .Ss MAC Address Filter Management The MAC framework will attempt to use as many MAC address filters as a device has. @@ -382,6 +489,27 @@ and just return the appropriate error as documented in the corresponding manual pages for the entry points. The framework will ensure that the device is placed in promiscuous mode if it needs to. +.Pp +If the hardware supports more than one unicast filter then the device +driver should consider implementing the +.Dv MAC_CAPAB_RINGS +capability, which exposes a means for multiple unicast MAC address filters to be +used by the broader system. +It is still useful to implement this on hardware which only has a single ring. +See +.Xr mac_capab_rings 9E +for more information. +.Ss Receive Side Scaling +Receive side scaling is where a hardware device supports multiple, +independent queues of frames that can be received. +Each of these queues is generally associated with an independent +interrupt and the hardware usually performs some form of hash across the +queues. +Hardware which supports this should look at implementing the +.Dv MAC_CAPAB_RINGS +capability and see +.Xr mac_capab_rings 9E +for more information. .Ss Link Updates It is the responsibility of the device driver to keep track of the data link's state. @@ -505,18 +633,9 @@ fail the call to Administrators always interact with devices through the .Xr dladm 8 command line interface. -The state of devices such as whether the link is considered -.Sy up -or -.Sy down , -various link properties such as the -.Sy MTU , -.Sy auto-negotiation -state, -and -.Sy flow control -state, -are all exposed. +The state of devices such as whether the link is considered up or down , +various link properties such as the MTU, auto-negotiation state, and +flow control state, are all exposed. It is also the preferred way that these properties are set and configured. .Pp While device tunables may be presented in a @@ -543,7 +662,7 @@ Note, the set of capabilities changes over time and there are also private capabilities in the system. Several of the capabilities are used in the implementation of the MAC framework. Others, like -.Sy MAC_CAPAB_RINGS , +.Dv MAC_CAPAB_RINGS , represent feature that have not been stabilized and thus both API and binary compatibility for them is not guaranteed. It is important that the device driver handles unknown capabilities correctly. @@ -552,13 +671,13 @@ For more information, see .Pp The following capabilities are stable and defined in the system: -.Ss MAC_CAPAB_HCKSUM +.Ss Dv MAC_CAPAB_HCKSUM The -.Sy MAC_CAPAB_HCKSUM +.Dv MAC_CAPAB_HCKSUM capability indicates to the system that the device driver supports some amount of checksumming. The specific data for this capability is a pointer to a -.Sy uint32_t . +.Vt uint32_t . To indicate no support for any kind of checksumming, the driver should either set this value to zero or simply return that it doesn't support the capability. @@ -569,7 +688,7 @@ If the driver can only verify checksums when receiving data, then it should not indicate that it supports this capability. The following set of flags may be combined through a bitwise inclusive OR: .Bl -tag -width Ds -.It Sy HCKSUM_INET_PARTIAL +.It Dv HCKSUM_INET_PARTIAL This indicates that the hardware can calculate a partial checksum for both IPv4 and IPv6 UDP and TCP packets; however, it requires the pseudo-header checksum be calculated for it. @@ -578,22 +697,22 @@ The pseudo-header checksum will be available for the mblk_t when calling Note this does not imply that the hardware is capable of calculating the partial checksum for other L4 protocols or the IPv4 header checksum. That should be indicated with the -.Sy HCKSUM_IPHDRCKSUM flag. -.It Sy HCKSUM_INET_FULL_V4 +.Dv HCKSUM_IPHDRCKSUM flag. +.It Dv HCKSUM_INET_FULL_V4 This indicates that the hardware will fully calculate the L4 checksum for outgoing IPv4 UDP or TCP packets only, and does not require a pseudo-header checksum. Note this does not imply that the hardware is capable of calculating the checksum for other L4 protocols or the IPv4 header checksum. That should be indicated with the -.Sy HCKSUM_IPHDRCKSUM . -.It Sy HCKSUM_INET_FULL_V6 +.Dv HCKSUM_IPHDRCKSUM . +.It Dv HCKSUM_INET_FULL_V6 This indicates that the hardware will fully calculate the L4 checksum for outgoing IPv6 UDP or TCP packets only, and does not require a pseudo-header checksum. Note this does not imply that the hardware is capable of calculating the checksum for any other L4 protocols. -.It Sy HCKSUM_IPHDRCKSUM +.It Dv HCKSUM_IPHDRCKSUM This indicates that the hardware supports calculating the checksum for the IPv4 header itself. .El @@ -625,13 +744,13 @@ checksumming, then it should simply not call Note that the checksum flags should be set on the first mblk_t that makes up a given message. In other words, if multiple mblk_t structures are linked together by the -.Sy b_cont +.Fa b_cont member to describe a single frame, then it should only be called on the first mblk_t of that set. However, each distinct message should have the checksum bits set on it, if applicable. In other words, each mblk_t that is linked together by the -.Sy b_next +.Fa b_next pointer may have checksum flags set. .Pp It is recommended that device drivers provide a private property or @@ -645,9 +764,9 @@ The transmit property should be checked when determining how to reply to .Xr mc_getcapab 9E and the receive property should be checked in the context of the receive function. -.Ss MAC_CAPAB_LSO +.Ss Dv MAC_CAPAB_LSO The -.Sy MAC_CAPAB_LSO +.Dv MAC_CAPAB_LSO capability indicates that the driver supports various forms of large send offload (LSO). The private data is a pointer to a @@ -715,6 +834,88 @@ Like with checksumming, it is recommended that driver writers provide a means for disabling the support of LSO even if it is enabled by default. This deals with the case where issues that pop up for LSO may be worked around without requiring additional driver work. +.Sh EVOLVING CAPABILITIES +The following capabilities are still evolving in the operating system. +They are documented such that device driver writers may experiment with +them. +However, if such drivers are not present inside the core operating +system repository, they may be subject to API and ABI breakage. +.Ss Dv MAC_CAPAB_RINGS +The +.Dv MAC_CAPAB_RINGS +capability is very important for implementing a high-performing device +driver. +Networking hardware structures the queues of packets to be sent +and received into a ring. +Each entry in this ring has a descriptor, which describes the address +and options for a packet which is going to +be transmitted or received. +While simple networking devices only have a single ring, most high-speed +networking devices have support for many rings. +.Pp +Rings are used for two important purposes. +The first is receive side scaling (RSS), which is the ability to have +the hardware hash the contents of a packet based on some of the protocol +headers, and send it to one of several rings. +These different rings may each have their own interrupt associated with +them, allowing the card to receive traffic in parallel. +Similar logic can be performed when sending traffic, to leverage +multiple hardware resources, thus increasing capacity. +.Pp +The second use of rings is to group them together and apply filtering +rules. +For example, if a packet matches a specific VLAN or MAC address, +then it can be sent to a specific ring or a specific group of rings. +This is especially useful when there are multiple different virtual NICs +or zones in play as the operating system will be able to use the +hardware classificaiton features to already know where a given packet +needs to be delivered internally rather than having to determine that +for each packet. +.Pp +From the MAC framework's perspective, a driver can have one or more +groups. +A group consists of the following: +.Bl -bullet -offset -indent +.It +One or more hardware rings. +.It +One or more MAC address or VLAN filters. +.El +.Pp +The details around how a device driver changes when rings are employed, +the data structures that a driver must implement, and more are available +in +.Xr mac_capab_rings 9E . +.Ss Dv MAC_CAPAB_TRANSCEIVER +Many networking devices leverage external transceivers that adhere to +standards such as SFP, QSFP, QSFP-DD, etc., which often contain +standardized information in a EEPROM on the device. +The +.Dv MAC_CAPAB_TRANSCEIVER +capability provides a means of discovering the number of transceivers, +their types, and reading the data from a transceiver. +This allows administrators and users to determine if devices are +present, if the hardware can use them, and in many cases, detailed +information about the device ranging from its manufacturer and +serial numbers to specific information about its health. +Implementing this capability will lead to the operating system being +able to discover and display transceivers as part of its fault +management topology. +.Pp +See +.Xr mac_capab_transceiver 9E +for more details on the capability structure and the various function +entry points that come along with it. +.Ss Dv MAC_CAPAB_LED +The +.Dv MAC_CAPAB_LED +capability provides a means to access and control the LEDs on a network +interface card. +This is then made available to the broader operating system and consumed +by facilities such as the Fault Management Architecture. +See +.Xr mac_capab_led 9E +for more details on the structure and requirements of the capability. .Sh PROPERTIES Properties in the MAC framework represent aspects of a link. These include things like the link's current state and MTU. @@ -752,86 +953,86 @@ and .Xr mc_setprop 9E for more information on how to handle them. .Bl -hang -width Ds -.It Sy MAC_PROP_DUPLEX +.It Dv MAC_PROP_DUPLEX .Bd -filled -compact Type: -.Sy link_duplex_t | +.Vt link_duplex_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_DUPLEX +.Dv MAC_PROP_DUPLEX property is used to indicate whether or not the link is duplex. A duplex link may have traffic flowing in both directions at the same time. The -.Sy link_duplex_t +.Vt link_duplex_t is an enumeration which may be set to any of the following values: .Bl -tag -width Ds -.It Sy LINK_DUPLEX_UNKNOWN +.It Dv LINK_DUPLEX_UNKNOWN The current state of the link is unknown. This may be because the link has not negotiated to a specific speed or it is down. -.It Sy LINK_DUPLEX_HALF +.It Dv LINK_DUPLEX_HALF The link is running at half duplex. Communication may travel in only one direction on the link at a given time. -.It Sy LINK_DUPLEX_FULL +.It Dv LINK_DUPLEX_FULL The link is running at full duplex. Communication may travel in both directions on the link simultaneously. .El -.It Sy MAC_PROP_SPEED +.It Dv MAC_PROP_SPEED .Bd -filled -compact Type: -.Sy uint64_t | +.Vt uint64_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_SPEED +.Dv MAC_PROP_SPEED property stores the current link speed in bits per second. A link that is running at 100 MBit/s would store the value 100000000ULL. A link that is running at 40 Gbit/s would store the value 40000000000ULL. -.It Sy MAC_PROP_STATUS +.It Dv MAC_PROP_STATUS .Bd -filled -compact Type: -.Sy link_state_t | +.Vt link_state_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_STATUS +.Dv MAC_PROP_STATUS property is used to indicate the current state of the link. It indicates whether the link is up or down. The -.Sy link_state_t +.Vt link_state_t is an enumeration which may be set to any of the following values: .Bl -tag -width Ds -.It Sy LINK_STATE_UNKNOWN +.It Dv LINK_STATE_UNKNOWN The current state of the link is unknown. This may be because the driver's .Xr mc_start 9E endpoint has not been called so it has not attempted to start the link. -.It Sy LINK_STATE_DOWN +.It Dv LINK_STATE_DOWN The link is down. This may be because of a negotiation problem, a cable problem, or some other device specific issue. -.It Sy LINK_STATE_UP +.It Dv LINK_STATE_UP The link is up. If auto-negotiation is in use, it should have completed. Traffic should be able to flow over the link, barring other issues. .El -.It Sy MAC_PROP_AUTONEG +.It Dv MAC_PROP_AUTONEG .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_AUTONEG +.Dv MAC_PROP_AUTONEG property indicates whether or not the device is currently configured to perform auto-negotiation. A value of @@ -847,16 +1048,16 @@ state. When setting this property, if the device supports operating in the requested mode, then the device driver should reset the link to negotiate to the new speed after updating any internal registers. -.It Sy MAC_PROP_MTU +.It Dv MAC_PROP_MTU .Bd -filled -compact Type: -.Sy uint32_t | +.Vt uint32_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_MTU +.Dv MAC_PROP_MTU property determines the maximum transmission unit (MTU). This indicates the maximum size packet that the device can transmit, ignoring its own headers. @@ -881,35 +1082,35 @@ If the device does not support changing the MTU after the device's .Xr mc_start 9E entry point has been called, then driver writers should return .Er EBUSY . -.It Sy MAC_PROP_FLOWCTRL +.It Dv MAC_PROP_FLOWCTRL .Bd -filled -compact Type: -.Sy link_flowctrl_t | +.Vt link_flowctrl_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_FLOWCTRL +.Dv MAC_PROP_FLOWCTRL property manages the configuration of pause frames as part of Ethernet flow control. Note, this only describes what this device will advertise. What is actually enabled may be different and is subject to the rules of auto-negotiation. The -.Sy link_flowctrl_t +.Vt link_flowctrl_t is an enumeration that may be set to one of the following values: .Bl -tag -width Ds -.It Sy LINK_FLOWCTRL_NONE +.It Dv LINK_FLOWCTRL_NONE Flow control is disabled. No pause frames should be generated or honored. -.It Sy LINK_FLOWCTRL_RX +.It Dv LINK_FLOWCTRL_RX The device can receive pause frames; however, it should not generate them. -.It Sy LINK_FLOWCTRL_TX +.It Dv LINK_FLOWCTRL_TX The device can generate pause frames; however, it does not support receiving them. -.It Sy LINK_FLOWCTRL_BI +.It Dv LINK_FLOWCTRL_BI The device supports both sending and receiving pause frames. .El .Pp @@ -918,33 +1119,33 @@ it has configured the device, not what the device has actually negotiated. When setting the property, it should update the hardware and allow the link to potentially perform auto-negotiation again. -.It Sy MAC_PROP_EN_FEC_CAP +.It Dv MAC_PROP_EN_FEC_CAP .Bd -filled -compact Type: -.Sy link_fec_t | +.Vt link_fec_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_FEC_CAP +.Dv MAC_PROP_EN_FEC_CAP property indicates which Forward Error Correction (FEC) code is advertised by the device. .Pp The -.Sy link_fec_t +.Vt link_fec_t is an enumeration that may be a combination of the following bit values: .Bl -tag -width Ds -.It Sy LINK_FEC_NONE +.It Dv LINK_FEC_NONE No FEC over the link. -.It Sy LINK_FEC_AUTO +.It Dv LINK_FEC_AUTO The FEC coding to use is auto-negotiated, -.Sy LINK_FEC_AUTO +.Dv LINK_FEC_AUTO cannot be set along with any of the other values. This is the default setting the device driver should use. -.It Sy LINK_FEC_RS +.It Dv LINK_FEC_RS The link may use Reed-Solomon FEC coding. -.It Sy LINK_FEC_BASE_R +.It Dv LINK_FEC_BASE_R The link may use Base-R coding, also common referred to as FireCode. .El .Pp @@ -955,18 +1156,18 @@ the device driver should return .Er EINVAL . When retrieving this property, the device driver should return the current value of the property. -.It Sy MAC_PROP_ADV_FEC_CAP +.It Dv MAC_PROP_ADV_FEC_CAP .Bd -filled -compact Type: -.Sy link_fec_t | +.Vt link_fec_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_FEC_CAP +.Dv MAC_PROP_ADV_FEC_CAP has the same values as -.Sy MAC_PROP_EN_FEC_CAP . +.Dv MAC_PROP_EN_FEC_CAP . The property indicates which Forward Error Correction (FEC) code has been negotiated over the link. .El @@ -1003,119 +1204,119 @@ section for more information. .Pp The properties are ordered in increasing link speed: .Bl -hang -width Ds -.It Sy MAC_PROP_ADV_10HDX_CAP +.It Dv MAC_PROP_ADV_10HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_10HDX_CAP +.Dv MAC_PROP_ADV_10HDX_CAP property describes whether or not 10 Mbit/s half-duplex support is advertised. -.It Sy MAC_PROP_EN_10HDX_CAP +.It Dv MAC_PROP_EN_10HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_10HDX_CAP +.Dv MAC_PROP_EN_10HDX_CAP property describes whether or not 10 Mbit/s half-duplex support is enabled. -.It Sy MAC_PROP_ADV_10FDX_CAP +.It Dv MAC_PROP_ADV_10FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_10FDX_CAP +.Dv MAC_PROP_ADV_10FDX_CAP property describes whether or not 10 Mbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_10FDX_CAP +.It Dv MAC_PROP_EN_10FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_10FDX_CAP +.Dv MAC_PROP_EN_10FDX_CAP property describes whether or not 10 Mbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_100HDX_CAP +.It Dv MAC_PROP_ADV_100HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_100HDX_CAP +.Dv MAC_PROP_ADV_100HDX_CAP property describes whether or not 100 Mbit/s half-duplex support is advertised. -.It Sy MAC_PROP_EN_100HDX_CAP +.It Dv MAC_PROP_EN_100HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_100HDX_CAP +.Dv MAC_PROP_EN_100HDX_CAP property describes whether or not 100 Mbit/s half-duplex support is enabled. -.It Sy MAC_PROP_ADV_100FDX_CAP +.It Dv MAC_PROP_ADV_100FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_100FDX_CAP +.Dv MAC_PROP_ADV_100FDX_CAP property describes whether or not 100 Mbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_100FDX_CAP +.It Dv MAC_PROP_EN_100FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_100FDX_CAP +.Dv MAC_PROP_EN_100FDX_CAP property describes whether or not 100 Mbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_100T4_CAP +.It Dv MAC_PROP_ADV_100T4_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_100T4_CAP +.Dv MAC_PROP_ADV_100T4_CAP property describes whether or not 100 Mbit/s Ethernet using the 100BASE-T4 standard is advertised. -.It Sy MAC_PROP_EN_100T4_CAP +.It Dv MAC_PROP_EN_100T4_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed @@ -1128,169 +1329,169 @@ enabled. .It Sy MAC_PROP_ADV_1000HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_1000HDX_CAP +.Dv MAC_PROP_ADV_1000HDX_CAP property describes whether or not 1 Gbit/s half-duplex support is advertised. -.It Sy MAC_PROP_EN_1000HDX_CAP +.It Dv MAC_PROP_EN_1000HDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_1000HDX_CAP +.Dv MAC_PROP_EN_1000HDX_CAP property describes whether or not 1 Gbit/s half-duplex support is enabled. -.It Sy MAC_PROP_ADV_1000FDX_CAP +.It Dv MAC_PROP_ADV_1000FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_1000FDX_CAP +.Dv MAC_PROP_ADV_1000FDX_CAP property describes whether or not 1 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_1000FDX_CAP +.It Dv MAC_PROP_EN_1000FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_1000FDX_CAP +.Dv MAC_PROP_EN_1000FDX_CAP property describes whether or not 1 Gbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_2500FDX_CAP +.It Dv MAC_PROP_ADV_2500FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_2500FDX_CAP +.Dv MAC_PROP_ADV_2500FDX_CAP property describes whether or not 2.5 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_2500FDX_CAP +.It Dv MAC_PROP_EN_2500FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_2500FDX_CAP +.Dv MAC_PROP_EN_2500FDX_CAP property describes whether or not 2.5 Gbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_5000FDX_CAP +.It Dv MAC_PROP_ADV_5000FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_5000FDX_CAP +.Dv MAC_PROP_ADV_5000FDX_CAP property describes whether or not 5.0 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_5000FDX_CAP +.It Dv MAC_PROP_EN_5000FDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_5000FDX_CAP +.Dv MAC_PROP_EN_5000FDX_CAP property describes whether or not 5.0 Gbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_10GFDX_CAP +.It Dv MAC_PROP_ADV_10GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_10GFDX_CAP +.Dv MAC_PROP_ADV_10GFDX_CAP property describes whether or not 10 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_10GFDX_CAP +.It Dv MAC_PROP_EN_10GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_10GFDX_CAP +.Dv MAC_PROP_EN_10GFDX_CAP property describes whether or not 10 Gbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_40GFDX_CAP +.It Dv MAC_PROP_ADV_40GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_40GFDX_CAP +.Dv MAC_PROP_ADV_40GFDX_CAP property describes whether or not 40 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_40GFDX_CAP +.It Dv MAC_PROP_EN_40GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_40GFDX_CAP +.Dv MAC_PROP_EN_40GFDX_CAP property describes whether or not 40 Gbit/s full-duplex support is enabled. -.It Sy MAC_PROP_ADV_100GFDX_CAP +.It Dv MAC_PROP_ADV_100GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read-Only .Ed .Pp The -.Sy MAC_PROP_ADV_100GFDX_CAP +.Dv MAC_PROP_ADV_100GFDX_CAP property describes whether or not 100 Gbit/s full-duplex support is advertised. -.It Sy MAC_PROP_EN_100GFDX_CAP +.It Dv MAC_PROP_EN_100GFDX_CAP .Bd -filled -compact Type: -.Sy uint8_t | +.Vt uint8_t | Permissions: .Sy Read/Write .Ed .Pp The -.Sy MAC_PROP_EN_100GFDX_CAP +.Dv MAC_PROP_EN_100GFDX_CAP property describes whether or not 100 Gbit/s full-duplex support is enabled. .El @@ -1299,10 +1500,10 @@ In addition to the defined properties above, drivers are allowed to define private properties. These private properties are device-specific properties. All private properties share the same constant, -.Sy MAC_PROP_PRIVATE . +.Dv MAC_PROP_PRIVATE . Properties are distinguished by a name, which is a character string. The list of such private properties is defined when registering with mac in the -.Sy m_priv_props +.Fa m_priv_props member of the .Xr mac_register 9S structure. @@ -1316,7 +1517,7 @@ All such properties should start with a leading underscore character and then consist of alphanumeric ASCII characters and additional underscores or hyphens. .Pp Properties of type -.Sy MAC_PROP_PRIVATE +.Dv MAC_PROP_PRIVATE may show up in all three property related entry points: .Xr mc_propinfo 9E , .Xr mc_getprop 9E , @@ -1341,7 +1542,7 @@ proper stat. .Pp In general, if the device is not keeping track of these statistics, then it is recommended that the driver store these values as a -.Sy uint64_t +.Vt uint64_t to ensure that overflow does not occur. .Pp If a device does not support a specific statistic, then it is fine to @@ -1354,51 +1555,44 @@ for more information on the proper way to handle these. The following statistics are based on MIB-II statistics from both RFC 1213 and RFC 1573. .Bl -tag -width Ds -.It Sy MAC_STAT_IFSPEED +.It Dv MAC_STAT_IFSPEED The device's current speed in bits per second. -.It Sy MAC_STAT_MULTIRCV +.It Dv MAC_STAT_MULTIRCV The total number of received multicast packets. -.It Sy MAC_STAT_BRDCSTRCV +.It Dv MAC_STAT_BRDCSTRCV The total number of received broadcast packets. -.It Sy MAC_STAT_MULTIXMT +.It Dv MAC_STAT_MULTIXMT The total number of transmitted multicast packets. -.It Sy MAC_STAT_BRDCSTXMT +.It Dv MAC_STAT_BRDCSTXMT The total number of received broadcast packets. -.It Sy MAC_STAT_NORCVBUF +.It Dv MAC_STAT_NORCVBUF The total number of packets discarded by the hardware due to a lack of receive buffers. -.It Sy MAC_STAT_IERRORS +.It Dv MAC_STAT_IERRORS The total number of errors detected on input. -.It Sy MAC_STAT_UNKNOWNS +.It Dv MAC_STAT_UNKNOWNS The total number of received packets that were discarded because they were of an unknown protocol. -.It Sy MAC_STAT_NOXMTBUF +.It Dv MAC_STAT_NOXMTBUF The total number of outgoing packets dropped due to a lack of transmit buffers. -.It Sy MAC_STAT_OERRORS +.It Dv MAC_STAT_OERRORS The total number of outgoing packets that resulted in errors. -.It Sy MAC_STAT_COLLISIONS +.It Dv MAC_STAT_COLLISIONS Total number of collisions encountered by the transmitter. -.It Sy MAC_STAT_RBYTES -The total number of -.Sy bytes -received by the device, regardless of packet type. -.It Sy MAC_STAT_IPACKETS -The total number of -.Sy packets -received by the device, regardless of packet type. -.It Sy MAC_STAT_OBYTES -The total number of -.Sy bytes -transmitted by the device, regardless of packet type. -.It Sy MAC_STAT_OPACKETS -The total number of -.Sy packets -sent by the device, regardless of packet type. -.It Sy MAC_STAT_UNDERFLOWS +.It Dv MAC_STAT_RBYTES +The total number of bytes received by the device, regardless of packet +type. +.It Dv MAC_STAT_IPACKETS +The total number of packets received by the device, regardless of packet type. +.It Dv MAC_STAT_OBYTES +The total number of bytes transmitted by the device, regardless of packet type. +.It Dv MAC_STAT_OPACKETS +The total number of packets sent by the device, regardless of packet type. +.It Dv MAC_STAT_UNDERFLOWS The total number of packets that were smaller than the minimum sized packet for the device and were therefore dropped. -.It Sy MAC_STAT_OVERFLOWS +.It Dv MAC_STAT_OVERFLOWS The total number of packets that were larger than the maximum sized packet for the device and were therefore dropped. .El @@ -1407,203 +1601,203 @@ The following statistics are specific to Ethernet devices. They refer to values from RFC 1643 and include various MII/GMII specific stats. Many of these are also defined in IEEE 802.3. .Bl -tag -width Ds -.It Sy ETHER_STAT_ADV_CAP_1000FDX +.It Dv ETHER_STAT_ADV_CAP_1000FDX Indicates that the device is advertising support for 1 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_1000HDX +.It Dv ETHER_STAT_ADV_CAP_1000HDX Indicates that the device is advertising support for 1 Gbit/s half-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_100FDX +.It Dv ETHER_STAT_ADV_CAP_100FDX Indicates that the device is advertising support for 100 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_100GFDX +.It Dv ETHER_STAT_ADV_CAP_100GFDX Indicates that the device is advertising support for 100 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_100HDX +.It Dv ETHER_STAT_ADV_CAP_100HDX Indicates that the device is advertising support for 100 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_100T4 +.It Dv ETHER_STAT_ADV_CAP_100T4 Indicates that the device is advertising support for 100 Mbit/s 100BASE-T4 operation. -.It Sy ETHER_STAT_ADV_CAP_10FDX +.It Dv ETHER_STAT_ADV_CAP_10FDX Indicates that the device is advertising support for 10 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_10GFDX +.It Dv ETHER_STAT_ADV_CAP_10GFDX Indicates that the device is advertising support for 10 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_10HDX +.It Dv ETHER_STAT_ADV_CAP_10HDX Indicates that the device is advertising support for 10 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_2500FDX +.It Dv ETHER_STAT_ADV_CAP_2500FDX Indicates that the device is advertising support for 2.5 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_40GFDX +.It Dv ETHER_STAT_ADV_CAP_40GFDX Indicates that the device is advertising support for 40 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_5000FDX +.It Dv ETHER_STAT_ADV_CAP_5000FDX Indicates that the device is advertising support for 5.0 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_ADV_CAP_ASMPAUSE +.It Dv ETHER_STAT_ADV_CAP_ASMPAUSE Indicates that the device is advertising support for receiving pause frames. -.It Sy ETHER_STAT_ADV_CAP_AUTONEG +.It Dv ETHER_STAT_ADV_CAP_AUTONEG Indicates that the device is advertising support for auto-negotiation. -.It Sy ETHER_STAT_ADV_CAP_PAUSE +.It Dv ETHER_STAT_ADV_CAP_PAUSE Indicates that the device is advertising support for generating pause frames. -.It Sy ETHER_STAT_ADV_REMFAULT +.It Dv ETHER_STAT_ADV_REMFAULT Indicates that the device is advertising support for detecting faults in the remote link peer. -.It Sy ETHER_STAT_ALIGN_ERRORS +.It Dv ETHER_STAT_ALIGN_ERRORS Indicates the number of times an alignment error was generated by the Ethernet device. This is a count of packets that were not an integral number of octets and failed the FCS check. -.It Sy ETHER_STAT_CAP_1000FDX +.It Dv ETHER_STAT_CAP_1000FDX Indicates the device supports 1 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_1000HDX +.It Dv ETHER_STAT_CAP_1000HDX Indicates the device supports 1 Gbit/s half-duplex operation. -.It Sy ETHER_STAT_CAP_100FDX +.It Dv ETHER_STAT_CAP_100FDX Indicates the device supports 100 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_100GFDX +.It Dv ETHER_STAT_CAP_100GFDX Indicates the device supports 100 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_100HDX +.It Dv ETHER_STAT_CAP_100HDX Indicates the device supports 100 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_CAP_100T4 +.It Dv ETHER_STAT_CAP_100T4 Indicates the device supports 100 Mbit/s 100BASE-T4 operation. -.It Sy ETHER_STAT_CAP_10FDX +.It Dv ETHER_STAT_CAP_10FDX Indicates the device supports 10 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_10GFDX +.It Dv ETHER_STAT_CAP_10GFDX Indicates the device supports 10 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_10HDX +.It Dv ETHER_STAT_CAP_10HDX Indicates the device supports 10 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_CAP_2500FDX +.It Dv ETHER_STAT_CAP_2500FDX Indicates the device supports 2.5 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_40GFDX +.It Dv ETHER_STAT_CAP_40GFDX Indicates the device supports 40 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_5000FDX +.It Dv ETHER_STAT_CAP_5000FDX Indicates the device supports 5.0 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_CAP_ASMPAUSE +.It Dv ETHER_STAT_CAP_ASMPAUSE Indicates that the device supports the ability to receive pause frames. -.It Sy ETHER_STAT_CAP_AUTONEG +.It Dv ETHER_STAT_CAP_AUTONEG Indicates that the device supports the ability to perform link auto-negotiation. -.It Sy ETHER_STAT_CAP_PAUSE +.It Dv ETHER_STAT_CAP_PAUSE Indicates that the device supports the ability to transmit pause frames. -.It Sy ETHER_STAT_CAP_REMFAULT +.It Dv ETHER_STAT_CAP_REMFAULT Indicates that the device supports the ability of detecting a remote fault in a link peer. -.It Sy ETHER_STAT_CARRIER_ERRORS +.It Dv ETHER_STAT_CARRIER_ERRORS Indicates the number of times that the Ethernet carrier sense condition was lost or not asserted. -.It Sy ETHER_STAT_DEFER_XMTS +.It Dv ETHER_STAT_DEFER_XMTS Indicates the number of frames for which the device was unable to transmit the frame due to being busy and had to try again. -.It Sy ETHER_STAT_EX_COLLISIONS +.It Dv ETHER_STAT_EX_COLLISIONS Indicates the number of frames that failed to send due to an excessive number of collisions. -.It Sy ETHER_STAT_FCS_ERRORS +.It Dv ETHER_STAT_FCS_ERRORS Indicates the number of times that a frame check sequence failed. -.It Sy ETHER_STAT_FIRST_COLLISIONS +.It Dv ETHER_STAT_FIRST_COLLISIONS Indicates the number of times that a frame was eventually transmitted successfully, but only after a single collision. -.It Sy ETHER_STAT_JABBER_ERRORS +.It Dv ETHER_STAT_JABBER_ERRORS Indicates the number of frames that were received that were both larger than the maximum packet size and failed the frame check sequence. -.It Sy ETHER_STAT_LINK_ASMPAUSE +.It Dv ETHER_STAT_LINK_ASMPAUSE Indicates whether the link is currently configured to accept pause frames. -.It Sy ETHER_STAT_LINK_AUTONEG +.It Dv ETHER_STAT_LINK_AUTONEG Indicates whether the current link state is a result of auto-negotiation. -.It Sy ETHER_STAT_LINK_DUPLEX +.It Dv ETHER_STAT_LINK_DUPLEX Indicates the current duplex state of the link. The values used here should be the same as documented for -.Sy MAC_PROP_DUPLEX . -.It Sy ETHER_STAT_LINK_PAUSE +.Dv MAC_PROP_DUPLEX . +.It Dv ETHER_STAT_LINK_PAUSE Indicates whether the link is currently configured to generate pause frames. -.It Sy ETHER_STAT_LP_CAP_1000FDX +.It Dv ETHER_STAT_LP_CAP_1000FDX Indicates the remote device supports 1 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_1000HDX +.It Dv ETHER_STAT_LP_CAP_1000HDX Indicates the remote device supports 1 Gbit/s half-duplex operation. -.It Sy ETHER_STAT_LP_CAP_100FDX +.It Dv ETHER_STAT_LP_CAP_100FDX Indicates the remote device supports 100 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_100GFDX +.It Dv ETHER_STAT_LP_CAP_100GFDX Indicates the remote device supports 100 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_100HDX +.It Dv ETHER_STAT_LP_CAP_100HDX Indicates the remote device supports 100 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_LP_CAP_100T4 +.It Dv ETHER_STAT_LP_CAP_100T4 Indicates the remote device supports 100 Mbit/s 100BASE-T4 operation. -.It Sy ETHER_STAT_LP_CAP_10FDX +.It Dv ETHER_STAT_LP_CAP_10FDX Indicates the remote device supports 10 Mbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_10GFDX +.It Dv ETHER_STAT_LP_CAP_10GFDX Indicates the remote device supports 10 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_10HDX +.It Dv ETHER_STAT_LP_CAP_10HDX Indicates the remote device supports 10 Mbit/s half-duplex operation. -.It Sy ETHER_STAT_LP_CAP_2500FDX +.It Dv ETHER_STAT_LP_CAP_2500FDX Indicates the remote device supports 2.5 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_40GFDX +.It Dv ETHER_STAT_LP_CAP_40GFDX Indicates the remote device supports 40 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_5000FDX +.It Dv ETHER_STAT_LP_CAP_5000FDX Indicates the remote device supports 5.0 Gbit/s full-duplex operation. -.It Sy ETHER_STAT_LP_CAP_ASMPAUSE +.It Dv ETHER_STAT_LP_CAP_ASMPAUSE Indicates that the remote device supports the ability to receive pause frames. -.It Sy ETHER_STAT_LP_CAP_AUTONEG +.It Dv ETHER_STAT_LP_CAP_AUTONEG Indicates that the remote device supports the ability to perform link auto-negotiation. -.It Sy ETHER_STAT_LP_CAP_PAUSE +.It Dv ETHER_STAT_LP_CAP_PAUSE Indicates that the remote device supports the ability to transmit pause frames. -.It Sy ETHER_STAT_LP_CAP_REMFAULT +.It Dv ETHER_STAT_LP_CAP_REMFAULT Indicates that the remote device supports the ability of detecting a remote fault in a link peer. -.It Sy ETHER_STAT_MACRCV_ERRORS +.It Dv ETHER_STAT_MACRCV_ERRORS Indicates the number of times that the internal MAC layer encountered an error when attempting to receive and process a frame. -.It Sy ETHER_STAT_MACXMT_ERRORS +.It Dv ETHER_STAT_MACXMT_ERRORS Indicates the number of times that the internal MAC layer encountered an error when attempting to process and transmit a frame. -.It Sy ETHER_STAT_MULTI_COLLISIONS +.It Dv ETHER_STAT_MULTI_COLLISIONS Indicates the number of times that a frame was eventually transmitted successfully, but only after more than one collision. -.It Sy ETHER_STAT_SQE_ERRORS +.It Dv ETHER_STAT_SQE_ERRORS Indicates the number of times that an SQE error occurred. The specific conditions for this error are documented in IEEE 802.3. -.It Sy ETHER_STAT_TOOLONG_ERRORS +.It Dv ETHER_STAT_TOOLONG_ERRORS Indicates the number of frames that were received that were longer than the maximum frame size supported by the device. -.It Sy ETHER_STAT_TOOSHORT_ERRORS +.It Dv ETHER_STAT_TOOSHORT_ERRORS Indicates the number of frames that were received that were shorter than the minimum frame size supported by the device. -.It Sy ETHER_STAT_TX_LATE_COLLISIONS +.It Dv ETHER_STAT_TX_LATE_COLLISIONS Indicates the number of times a collision was detected late on the device. -.It Sy ETHER_STAT_XCVR_ADDR +.It Dv ETHER_STAT_XCVR_ADDR Indicates the address of the MII/GMII receiver address. -.It Sy ETHER_STAT_XCVR_ID +.It Dv ETHER_STAT_XCVR_ID Indicates the id of the MII/GMII receiver address. -.It Sy ETHER_STAT_XCVR_INUSE +.It Dv ETHER_STAT_XCVR_INUSE Indicates what kind of receiver is in use. The following values may be used: .Bl -tag -width Ds -.It Sy XCVR_UNDEFINED +.It Dv XCVR_UNDEFINED The receiver type is undefined by the hardware. -.It Sy XCVR_NONE +.It Dv XCVR_NONE There is no receiver in use by the hardware. -.It Sy XCVR_10 +.It Dv XCVR_10 The receiver supports 10BASE-T operation. -.It Sy XCVR_100T4 +.It Dv XCVR_100T4 The receiver supports 100BASE-T4 operation. -.It Sy XCVR_100X +.It Dv XCVR_100X The receiver supports 100BASE-TX operation. -.It Sy XCVR_100T2 +.It Dv XCVR_100T2 The receiver supports 100BASE-T2 operation. -.It Sy XCVR_1000X +.It Dv XCVR_1000X The receiver supports 1000BASE-X operation. This is used for all fiber receivers. -.It Sy XCVR_1000T +.It Dv XCVR_1000T The receiver supports 1000BASE-T operation. This is used for all copper receivers. .El @@ -1714,7 +1908,7 @@ While a device driver does not need to indicate that it is capable of all such capabilities described in .Xr ddi_fm_init 9F , we suggest that device drivers at least register the -.Sy DDI_FM_EREPORT_CAPABLE +.Dv DDI_FM_EREPORT_CAPABLE so as to allow the driver to report issues that it detects. .Pp If the driver registers with the fault management framework during its @@ -1815,7 +2009,7 @@ The device driver should indicate that the device's service was lost with a call to .Xr ddi_fm_service_impact 9F using the symbol -.Sy DDI_SERVICE_LOST . +.Dv DDI_SERVICE_LOST . .It At this point the device driver should issue a device reset through some device-specific means. @@ -1828,14 +2022,14 @@ MAC address filters, and more. Finally, when service has been restored, the device driver should call .Xr ddi_fm_service_impact 9F using the symbol -.Sy DDI_SERVICE_RESTORED . +.Dv DDI_SERVICE_RESTORED . .El .Pp When a non-fatal error occurs, then the device driver should submit an ereport and should optionally mark the device degraded using .Xr ddi_fm_service_impact 9F with the -.Sy DDI_SERVICE_DEGRADED +.Dv DDI_SERVICE_DEGRADED value depending on the nature of the problem that has occurred. .Pp Device drivers should never make the decision to remove a device from @@ -1876,11 +2070,11 @@ The networking stack manages framed data through the use of the structure. The mblk allows for a single message to be made up of individual blocks. Each part is linked together through its -.Sy b_cont +.Fa b_cont member. However, it also allows for multiple messages to be chained together through the use of the -.Sy b_next +.Fa b_next member. While the networking stack works with these structures, device drivers generally work with DMA regions. @@ -1903,7 +2097,7 @@ When receiving memory, it will allocate a mblk_t through the routine, copy the memory across with .Xr bcopy 9F , and then increment the mblk_t's -.Sy w_ptr +.Fa b_wptr structure. .Pp If, when receiving, memory is not available for a new message block, @@ -1986,6 +2180,9 @@ a given platform. .Xr attach 9E , .Xr close 9E , .Xr detach 9E , +.Xr mac_capab_led 9E , +.Xr mac_capab_rings 9E , +.Xr mac_capab_transceiver 9E , .Xr mc_close 9E , .Xr mc_getcapab 9E , .Xr mc_getprop 9E , diff --git a/usr/src/man/man9e/mac_capab_rings.9e b/usr/src/man/man9e/mac_capab_rings.9e new file mode 100644 index 0000000000..29d4521a6a --- /dev/null +++ b/usr/src/man/man9e/mac_capab_rings.9e @@ -0,0 +1,475 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MAC_CAPAB_RINGS 9E +.Os +.Sh NAME +.Nm mac_capab_rings +.Nd MAC ring capability +.Sh SYNOPSIS +.In sys/mac_provider.h +.Vt typedef struct mac_capab_rings_s mac_capab_rings_t; +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh DESCRIPTION +The +.Sy MAC_CAPAB_RINGS +capability provides a means for device drivers to take advantage of +the additional resources offered by hardware beyond the basic operations +to transmit and receive. +There are two primary concepts that this MAC capability relies on: rings +and groups. +.Pp +The +.Em ring +is a abstract concept which must be mapped to some hardware construct by +the driver. +It typically takes the form of a DMA memory region which is divided +into many smaller units, called descriptors or entries. +Each entry in the ring describes a location in memory of a packet, which the +hardware is to read from +.Pq to transmit it +or write to +.Pq upon reception . +Entries also typically contain metadata and attributes about the packet. +These entries are typically arranged in a fixed-size circular buffer +.Po hence the +.Dq ring +name +.Pc +which is shared between the operating system and the +hardware via the DMA-backed memory. +Most NICs, regardless of their support for this capability, use something +resembling a descriptor ring under the hood. +Some vendors may also refer to rings as +.Em queues . +The ring concept is intentionally general, so that more unusual underlying +hardware constructs can also be used to implement it. +.Pp +A collection of one or more rings is called a +.Em group . +Each group usually has a collection of filters that can be associated +with them. +These filters are usually defined in terms of matching something like a +MAC address, VLAN, or Ethertype, though more complex filters may exist +in hardware. +When a packet matches a filter, it will then be directed to the group +and eventually delivered to one of the rings in the group. +.Pp +In the MAC framework, rings and groups are separated into categories +based on their purpose: transmitting and receiving. +While the MAC framework thinks of transmit and receive rings as +different physical constructs, they may map to the same underlying +resources in the hardware. +The device driver may implement the +.Dv MAC_CAPAB_RINGS +capability for one of transmitting, receiving, or both. +.Ss Mapping Hardware to Rings and Groups +There are many different ways that hardware resources may map to this +capability. +Consider the following examples: +.Bl -enum +.It +Hardware may support a feature commonly known as receive side scaling +.Pq RSS . +With RSS, the hardware has multiple rings and uses a hash function +calculated over packet headers to choose which ring receives a +particular packet. +Rings are associated with different interrupts, allowing multiple rings +to be processed in parallel. +Supporting RSS in isolation would result in a device which has a single +group, and multiple rings within that group. +.It +Some hardware may have a single ring, but still support multiple receive +filters. +This is commonly seen with some 1 GbE devices. +While the hardware only has one ring, it has support for multiple +independent MAC address filters, each of which can be programmed to +receive traffic for a single MAC address. +The driver should map this situation to a single group with a single +ring. +However, it would implement the ability to program several filters. +While this may not seem useful at first, when virtual NICs are created +on top of a physical NIC, the additional hardware filters will be used +to avoid putting the device in promiscuous mode. +.It +Finally, some hardware has many rings, which can be placed in many +different groups. +Each group has its own filtering capabilities. +For such hardware, the device driver would declare support for multiple +groups, each of which has its own independent set of rings. +.El +.Pp +When choosing hardware constructs to implement rings and groups, it is +also important to consider interrupts. +In order to support polling, each receive ring must be able to +independently toggle whether that ring will generate an interrupt on +packet reception, even when many rings share the same hardware level +interrupt +.Pq e.g. the same MSI or MSI-X interrupt number and handler . +.Ss Filters +The +.Xr mac_group_info 9S +structure is used to define several different kinds of filters that the +group might implement. +There are three different classes of filters that exist: +.Bl -tag -width Ds +.It Sy MAC Address +A given frame matches a MAC Address filter if the receive address in +the Ethernet Header matches the specified MAC address. +.It Sy VLAN +A given frame matches a VLAN filter if it both has an 802.1Q VLAN tag +and that tag matches the VALN number specified in the filter. +If the frame's outer ethertype is not 0x8100, then the filter will not +match. +.It Sy MAC Address and VLAN +A given frame matches a MAC Address and VLAN filter if it matches both +the specified MAC address and the specified VLAN. +This is constructed as a logical AND of the previous two filters. +If only one of the two matches, then the frame does not match this +filter. +.Pp +Note: this filter type is still under development and has not been +plumbed through our APIs yet. +.El +.Pp +Devices may support many different filter types. +If the hardware resources required for a combined filter type +.Pq e.g. MAC Address and VLAN +are similar to the resources required for each in isolation, drivers +should prefer to implement just the combined type and should not +implement the individual types. +.Pp +The MAC framework assumes that the following rules hold regarding +filters: +.Bl -enum +.It +When there are multiple filters of the same kind with different +addresses, then the hardware will accept a frame if it matches +.Em ANY +of the specified filters. +In other words, if there are two VLAN filters defined, one for VLAN 23 +and one for VLAN 42, then if a frame has either VLAN 23 or VLAN 42, +it will be accepted for the group. +.It +If multiple different classes of filters are defined, then the hardware +should only accept a frame if it passes +.Em ALL +of the filter classes. +For example, if there is a MAC address filter and a separate VLAN +filter, the hardware will only accept the frame if it passes both sets +of filters. +.It +If there are multiple different classes of filters and there are +multiple filters present in each class, then the driver will accept a +packet as long as it matches +.Em ALL +filter classes. +However, within a given filter class, it may match +.Em ANY +of the filters. +See the following boolean logic as an alternative way to phrase this +case: +.Bd -literal -offset indent +match = MAC && VLAN +MAC = 00:11:22:33:44:55 OR 00:66:77:88:99:aa OR ... +VLAN = 11 OR 12 OR ... +.Ed +.El +.Pp +The following psuedocode summarizes the behavior for a device that +supports independent MAC and VLAN filters. +If the hardware only supports a single family of filters, then simply +treat that in the psuedocode as though it is always true: +.Bd -literal -offset indent +for each packet p: + for each MAC filter m: + if m matches p's mac: + for each VLAN filter v: + if v matches p's vlan: + accept p for group + proceed to next packet + reject packet p + proceed to next packet +.Ed +.Pp +The following psuedocode summarizes the behavior for a device that +supports a combined MAC address and VLAN filter: +.Bd -literal -offset indent +for each packet p: + for each filter f: + if f.mac matches p's mac and f.vlan matches p's vlan: + accept p for group + proceed to next packet + reject packet p + proceed to next packet +.Ed +.Ss MAC Capability Structure +When the device driver's +.Xr mc_getcapab 9E +function entry point is called with the capability requested set to +.Dv MAC_CAPAB_RINGS , +then the value of the capability structure is a pointer to a +.Vt mac_capab_rings_t +structure with the following members: +.Bd -literal -offset indent +mac_ring_type_t mr_type; +mac_groupt_type_t mr_group_type; +uint_t mr_rnum; +uint_t mr_gnum; +mac_get_ring_t mr_rget; +mac_get_group_t mr_gget; +.Ed +.Pp +If the driver supports the +.Dv MAC_CAPAB_RINGS +capability, then it should first check the +.Fa mr_type +member of the structure. +This member has the following possible values: +.Bl -tag -width Dv +.It Dv MAC_RING_TYPE_RX +Indicates that this group is for receive rings. +.It Dv MAC_RING_TYPE_TX +Indicates that this group is for transmit rings. +.El +.Pp +The driver will be asked to fill in this capability structure separately +for receive and transmit groups and rings. +This allows a driver to have different entry points for each type. +If neither of these values is specified, then the device driver must +return +.Dv B_FALSE +from its +.Xr mc_getcapab 9E +entry point. +Once it has identified the type, it should fill in the capability +structure based on the following rules: +.Bl -tag -width Fa +.It Fa mr_type +The +.Fa mr_type +member is used to indicate whether this group is for transmit or receive +rings. +The +.Fa mr_type +member should not be modified by the device driver. +It is set by the MAC framework when the driver's +.Xr mc_getcapab 9E +entry point is called. +As indicated above, the driver must check the value to determine which +group this +.Xr mc_getcapab 9E +call is referring to. +.It Fa mr_group_type +This member is used to indicate the group type. +This should be set to +.Dv MAC_GROUP_TYPE_STATIC , +which indicates that the assignment of rings to groups is fixed, and +each ring can only ever belong to one specific group. +The number of rings per group may vary on the group and can be set by +the driver. +.It Fa mr_rnum +This indicates the total number of rings that are available. +The number exposed may be less than the number supported in hardware. +This is often due to receiving fewer resources such as interrupts. +.It Fa mr_gnum +This indicates the total number of groups that are available from +hardware. +The number exposed may be less than the number supported in hardware. +This is often due to receiving fewer resources such as interrupts. +.Pp +When working with transmit rings, this value may be zero. +In this case, each ring is treated independently and separate groups for +each transmit ring are not required. +.It Fa mr_rget +This member is a function pointer that will be called to provide +information about a ring inside of a specific group. +See +.Xr mr_rget 9E +for information on the function, its signature, and responsibilities. +.It Fa mr_gget +This member is a function pointer that will be called to provide +information about a group. +See +.Xr mr_gget 9E +for information on the function, its signature, and responsibilities. +.El +.Sh DRIVER IMPLICATIONS +.Ss MAC Callback Entry Points +When a driver implements the +.Dv MAC_CAPAB_RINGS +capability, then it must not implement some of the traditional MAC +callbacks. +If the driver supports +.Dv MAC_CAPAB_RINGS +for receiving, then it must not implement the +.Xr mc_unicst 9E +entry point. +This is instead handled through the filters that were described earlier. +The filter entry points are defined as part of the +.Xr mac_group_info 9S +structure. +.Pp +If the driver supports +.Dv MAC_CAPAB_RINGS +for transmitting, then it should not implement the +.Xr mc_tx 9E +entry point, it will not be used. +The MAC framework will instead use the +.Xr mri_tx 9E +entry point that is provided by the driver in the +.Xr mac_ring_info 9S +structure. +.Ss Locking and Concurrency +One of the main points of the +.Dv MAC_CAPAB_RINGS +capability is to increase the parallelism and concurrency that is +actively going on in the driver. +This means that a driver may be asked to transmit, poll, or receiver +interrupts on all of its rings in parallel. +This usually calls for fine-grained locking in a driver's own data +structures to ensure that the various rings can be populated and used +without having to block on one another. +In general, most drivers have their own independent set of locks for +each transmit and receive ring. +They also usually have separate locks for each group. +.Pp +Just because one driver performs locking in one way, does not mean that +one has to mimic it. +The design of a driver and its locking is often tightly coupled to how +the underlying hardware works and its complexity. +.Ss Polling on rings +When the +.Dv MAC_CAPAB_RINGS +capability is implemented, then additional functionality for receiving +becomes available. +A receive ring has the ability to be polled. +When the operating system desires to begin polling the ring, it will +make a function call into the driver, asking it to receive packets from +this ring. +When receiving packets while polling, the process is generally identical +to that described in the +.Sy Receiving Data +section of +.Xr mac 9E . +For more details, see +.Xr mri_poll 9E . +.Pp +When the MAC framework wants to enable polling, it will first turn off +interrupts through the +.Xr mi_disable 9E +entry point on the driver. +The driver must ensure that there is proper serialization between the +interrupt enablement, interrupt disablement, the interrupt handler for +that ring, and the +.Xr mri_poll 9E +entry point. +For more information on the locking requirements related to polling, see +the discussions in +.Xr mri_poll 9E +and +.Xr mi_disable 9E . +.Ss Updated callback functions +When using rings, two of the primary functions that were used change. +First, the +.Xr mac_rx 9F +function should be replaced with the +.Xr mac_ring_rx 9F +function. +Secondly, +the +.Xr mac_tx_update 9F +function should be replaced with the +.Xr mac_tx_ring_update 9F +function. +.Ss Interrupt and Ring Mapping +Drivers often vary the number of rings that they expose based on the +number of interrupts that exist. +When a driver only supports a single group, there is often no reason to +have more rings than interrupts. +However, most hardware supports a means of having multiple rings tie to +the same interrupt. +Drivers then tie the rings in different groups to the same interrupts +and therefore when an interrupt is triggered, iterate over all of the +rings. +.Pp +Tying multiple rings together into a single interrupt should only be done +if hardware has the ability to control whether or not each ring +contributes to the interrupt. +For the +.Xr mi_disable 9E +entry point to work, each ring must be able to independently control +whether or not receipt of a packet generates the shared interrupt. +.Ss Filter Management +As part of general operation, the device driver will be asked to add +various filters to groups. +The MAC framework does not keep track of the assigned filters in such a +way that after a device reset that they'll be given to the driver again. +Therefore, it is recommended that the driver keep track of all filters +it has assigned such that they can be reinstated after a driver or +system initiated device reset of some kind. +There is no need to persist anything across a call to +.Xr detach 9E +or similar. +.Pp +For more information, see the +.Sy TX STALL DETECTION, DEVICE RESETS, AND FAULT MANAGEMENT +section of +.Xr mac 9E . +.Ss Broadcast, Multicast, and Promiscuous Mode +Rings and groups are currently designed to emphasize and enhance the +receipt of filtered, unicast frames. +This means that special handling is required when working with broadcast +traffic, multicast traffic, and enabling promiscuous mode. +This only applies to receive groups and rings. +.Pp +By default, only the first group with index zero, sometimes called the +default group, should ever be +programmed to receive broadcast traffic. +This group should always be programmed to receive broadcast traffic, the +same way that the broader device is programmed to always receive +broadcast traffic when the +.Dv MAC_CAPAB_RINGS +capability has not been negotiated. +.Pp +When multicast addresses are assigned to the device through the +.Xr mc_multicst 9E +entry point, those should also be assigned to the first group. +.Pp +Similarly, when enabling promiscuous mode, the driver should only enable +promiscuous traffic to be received by the first group. +.Pp +No other groups or rings should ever receive broadcast, multicast, or +promiscuous mode traffic. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mc_getcapab 9E , +.Xr mc_multicst 9E , +.Xr mc_tx 9E , +.Xr mc_unicst 9E , +.Xr mi_disable 9E , +.Xr mr_gaddring 9E , +.Xr mr_gget 9E , +.Xr mr_gremring 9E , +.Xr mr_rget 9E , +.Xr mri_poll 9E , +.Xr mac_ring_rx 9F , +.Xr mac_rx 9F , +.Xr mac_tx_ring_update 9F , +.Xr mac_tx_update 9F , +.Xr mac_group_info 9S diff --git a/usr/src/man/man9e/mac_filter.9e b/usr/src/man/man9e/mac_filter.9e new file mode 100644 index 0000000000..bd4283efe0 --- /dev/null +++ b/usr/src/man/man9e/mac_filter.9e @@ -0,0 +1,172 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MAC_FILTER 9E +.Os +.Sh NAME +.Nm mac_filter , +.Nm mgi_addmac , +.Nm mgi_remmac , +.Nm mgi_addvlan , +.Nm mgi_remvlan +.Nd add and remove filters from MAC groups +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft int +.Fo prefix_ring_add_mac +.Fa "mac_group_driver_t driver" +.Fa "const uint8_t *mac" +.Fc +.Ft int +.Fo prefix_ring_rem_mac +.Fa "mac_group_driver_t driver" +.Fa "const uint8_t *mac" +.Fc +.Ft int +.Fo prefix_ring_add_vlan +.Fa "mac_group_driver_t driver" +.Fa "uint16_t vlan" +.Fc +.Ft int +.Fo prefix_ring_rem_vlan +.Fa "mac_group_driver_t driver" +.Fa "uint16_t vlan" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the ring's private data that was passed in via the +.Vt mgi_driver +member of the +.Xr mac_group_info 9S +structure as part of the +.Xr mr_gget 9E +entry point. +.It Fa mac +A pointer to an array of bytes that contains the unicast address to add +or remove from a filter. +It is guaranteed to be at least as long, in bytes, as the MAC plugin's +address length. +For Ethernet devices that length is six bytes, +.Dv ETHERADDRL . +.It Fa vlan +The numeric value of the VLAN that should be added or removed from a +filter. +.El +.Sh DESCRIPTION +The +.Fn mac_filter +family of entry points are used to add and remove various classes of +filters from a device. +For more information on the filters, see the +.Sy Filters +section of +.Xr mac_capab_rings 9S +and the discussion around setting these members in +.Xr mac_group_info 9S . +.Pp +The +.Fa driver +argument indicates which group the request to add or remove a filter is +being requested on. +.Pp +The filter addition operations, +.Fn mgi_addmac , +.Fn mgi_addvlan , +and +.Fn mgi_addmvf , +all instruct the system to add a filter to the specified group. +The filter should not target any specific ring in the group. +If multiple rings are present, then the driver should ensure that the +hardware balances incoming traffic amongst all of the rings through a +consistent hashing mechanism such as receive side scaling. +.Pp +The +.Fn mgi_addmac +entry point instructs the driver to add the MAC address specified in +.Fa mac +to the filter list for the group. +The MAC address should always be a unicast MAC address; however, the +driver is encouraged to verify that before adding it. +.Pp +The +.Fn mgi_remmac +should remove the MAC address specified in +.Fa mac +from the filter list for the group. +.Pp +The +.Fn mgi_addvlan +entry point instructs the driver to add the VLAN specified in +.Fa vlan +to the filter list for the group. +The +.Fn mgi_remvlan +entry point instructs the driver to remove the VLAN specified in +.Fa vlan +from the filter list for the group. +.Ss Stacking Filters +Multiple filters of the same class should always be treated as a +logical-OR. +The frame may match any of the filters in a given class to be accepted. +Filters of different classes should always be treated as a logical-AND. +The frame must match a filter in all programmed classes to be accepted. +For more information, see the +.Sy Filters +section of +.Xr mac_capab_rings 9S . +.Sh RETURN VALUES +Upon successful completion, the driver should ensure that the filter has +been added or removed and return +.Sy 0 . +Otherwise, it should return the appropriate error number. +.Sh ERRORS +The device driver may return one of the following errors. +While this list is not intended to be exhaustive, it is recommended to use one +of these if possible. +.Bl -tag -width Er +.It Er EEXIST +The requested filter has already been programmed into the device. +.It Er EINVAL +The address +.Fa mac +is not a valid unicast address. +The VLAN +.Fa vlan +is not a valid VLAN identifier. +.It Er EIO +The driver encountered a device or transport error while trying to +update the device's state. +.It Er ENOENT +The driver was asked to remove a filter which was not currently +programmed. +.It Er ENOTSUP +The driver does not support this specific function. +This should only be used on specific hardware +.Pq generally devices from cloud providers +where neither promiscuous mode nor filters will allow +the filter to operate. +.It Er ENOSPC +The driver has run out of available hardware filters. +.El +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mr_gget 9E , +.Xr mac_group_info 9S diff --git a/usr/src/man/man9e/mc_tx.9e b/usr/src/man/man9e/mc_tx.9e index 48efd44661..dc214ba104 100644 --- a/usr/src/man/man9e/mc_tx.9e +++ b/usr/src/man/man9e/mc_tx.9e @@ -9,13 +9,15 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2016 Joyent, Inc. +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company .\" -.Dd Nov 26, 2017 +.Dd July 2, 2022 .Dt MC_TX 9E .Os .Sh NAME -.Nm mc_tx +.Nm mc_tx , +.Nm mri_tx .Nd transmit a message block chain .Sh SYNOPSIS .In sys/mac_provider.h @@ -24,24 +26,45 @@ .Fa "void *driver" .Fa "mblk_t *mp_chain" .Fc +.Ft "mblk_t *" +.Fo prefix_ring_tx +.Fa "void *driver_rh" +.Fa "mblk_t *mp_chain" +.Fc .Sh INTERFACE LEVEL illumos DDI specific +.Pp +The +.Fn mri_tx +entry point is +.Sy Uncommitted - +API and ABI stability is not guaranteed. .Sh PARAMETERS .Bl -tag -width Fa .It Fa driver A pointer to the driver's private data that was passed in via the -.Sy m_pdata +.Fa m_pdata member of the .Xr mac_register 9S structure to the .Xr mac_register 9F function. +.It Fa driver_rh +A pointer to the driver's private data for the ring that was passed in +via the +.Fa mri_driver +member of the +.Xr mac_ring_info 9S +structure. +This is initialized by the driver when its +.Xr mr_rget 9E +is called by MAC. .It Fa mp_chain A series of .Xr mblk 9S structures that may have multiple independent packets linked together on their -.Sy b_next +.Fa b_next member. .El .Sh DESCRIPTION @@ -56,10 +79,10 @@ argument represents the first frame. The frame may be spread out across one or more .Xr mblk 9S structures that are linked together by the -.Sy b_cont +.Fa b_cont member. There may be multiple frames, linked together by the -.Sy b_next +.Fa b_next pointer of the .Xr mblk 9S . .Pp @@ -73,9 +96,9 @@ section of .Pp As it processes each frame in the chain, if the device driver has advertised either of the -.Sy MAC_CAPAB_HCKSUM +.Dv MAC_CAPAB_HCKSUM or -.Sy MAC_CAPAB_LSO +.Dv MAC_CAPAB_LSO flags, it must check whether either apply for the given frame using the .Xr mac_hcksum_get 9F and @@ -99,8 +122,8 @@ Return the frames to indicate that resources are not available. .Pp The device driver is in charge of the memory associated with .Fa mp_chain . -If the device driver does not return the message blocks to the GLDv3, -then it must call +If the device driver does not return the message blocks to the MAC +framework, then it must call .Xr freemsg 9F on the frames. If it does not, the memory associated with them will be leaked. @@ -133,9 +156,9 @@ Once a device driver has returned unprocessed frames from its entry point, then the device driver will not receive any additional calls to its .Fn mc_tx -entry point until it calls +entry point until it calls the .Xr mac_tx_update 9F -to indicate that resources are available again. +function to indicate that resources are available again. Note that because it is the device driver that is calling this function to indicate resources are available, it is very important that it only return frames in cases where the device driver itself will be notified that resources @@ -153,6 +176,32 @@ related data structures. Note that the device driver should expect that it may have its transmit endpoints called into from other threads while it's servicing device interrupts related to them. +.Pp +The +.Fn mri_tx +entry point is similar to the +.Fn mc_tx +entry point, except that it is used by device drivers that have +negotiated the +.Dv MAC_CAPAB_RINGS +capability with transmit rings. +The driver should follow all of the same rules described earlier, except +that it will access a ring-specific data structure through +.Fa driver_rh +and when it needs to update that there is additional space available, it +must use +.Xr mac_tx_update_ring 9F +and not +.Xr mac_tx_update 9F . +.Pp +When the +.Fn mri_tx +entry point is called, the ring that should be used has been specified. +The driver must not attempt to use any other ring than the one specified +by +.Fa driver_rh +for any reason, including a lack of resources or an attempt to perform +its own hashing. .Sh CONTEXT The .Fn mc_tx @@ -165,14 +214,21 @@ context. Upon successful completion, the device driver should return .Dv NULL . Otherwise, it should return all unprocessed message blocks and ensure -that it calls +that it calls either .Xr mac_tx_update 9F +or +.Xr mac_tx_ring_update 9F some time in the future. .Sh SEE ALSO .Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mr_rget 9E , .Xr freemsg 9F , +.Xr mac_hcksum_get 9F , .Xr mac_lso_get 9F , .Xr mac_register 9F , +.Xr mac_tx_ring_update 9F , .Xr mac_tx_update 9F , .Xr mac_register 9S , +.Xr mac_ring_info 9S , .Xr mblk 9S diff --git a/usr/src/man/man9e/mc_unicst.9e b/usr/src/man/man9e/mc_unicst.9e index 9886dc22af..193a542423 100644 --- a/usr/src/man/man9e/mc_unicst.9e +++ b/usr/src/man/man9e/mc_unicst.9e @@ -9,9 +9,10 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2016 Joyent, Inc. +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company .\" -.Dd May 31, 2016 +.Dd July 2, 2022 .Dt MC_UNICST 9E .Os .Sh NAME @@ -30,7 +31,7 @@ illumos DDI specific .Bl -tag -width Fa .It Fa driver A pointer to the driver's private data that was passed in via the -.Sy m_pdata +.Fa m_pdata member of the .Xr mac_register 9S structure to the @@ -42,12 +43,12 @@ the device. It is guaranteed to be at least a number of bytes long equal to the length of the MAC plugin's address length. For Ethernet devices that length is six bytes, -.Sy ETHERADDRL . +.Dv ETHERADDRL . .El .Sh DESCRIPTION The .Fn mc_unicst -entry point is used by the GLDv3 to indicate that the device driver +entry point is used by the MAC framework to indicate that the device driver should update the primary MAC address of the device. In the basic mode of operation, this entry point is required and the device has a single primary MAC address. @@ -56,8 +57,14 @@ promiscuous mode. This call should overwrite the existing MAC address that is programmed into the device. .Pp +Device drivers that implement the +.Dv MAC_CAPAB_RINGS +capability +.Em must not +implement this interface. +.Pp As noted in the -.Sx PARAMETERS +.Sy PARAMETERS section, the .Fa mac array is guaranteed to be at least as many bytes as is required to @@ -83,8 +90,13 @@ The entry point only supports a single MAC address. In this case, devices should only use a single MAC address and replace that MAC address. -Support for using more than a single MAC address filter will be provided -by future interfaces. +To enable the operating system to take advantage of multiple unicast MAC +address filters, the driver should implement the +.Dv MAC_CAPAB_RINGS +capability. +See +.Xr mac_capab_rings 9E +for more information. .Sh RETURN VALUES Upon successful completion, the device driver should have updated its unicast filter and return @@ -106,5 +118,6 @@ update the device's state. .El .Sh SEE ALSO .Xr mac 9E , +.Xr mac_capab_rings 9E , .Xr mac_register 9F , .Xr mac_register 9S diff --git a/usr/src/man/man9e/mgi_start.9e b/usr/src/man/man9e/mgi_start.9e new file mode 100644 index 0000000000..adae22a3bf --- /dev/null +++ b/usr/src/man/man9e/mgi_start.9e @@ -0,0 +1,152 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide computer Company +.\" +.Dd July 2, 2022 +.Dt MGI_START 9E +.Os +.Sh NAME +.Nm mgi_start , +.Nm mgi_stop , +.Nm mri_start , +.Nm mri_stop +.Nd MAC group and ring start and stop entry points +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft int +.Fo prefix_group_start +.Fa "mac_group_driver_t gh" +.Fc +.Ft void +.Fo prefix_group_stop +.Fa "mac_group_driver_t gh" +.Fc +.Ft int +.Fo prefix_ring_start +.Fa "mac_ring_driver_t rh" +.Fa "uint64_t mr_gen" +.Fc +.Ft void +.Fo prefix_ring_stop +.Fa "mac_ring_driver_t rh" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the ring's private data that was passed in via the +.Vt mgi_driver +member of the +.Xr mac_group_info 9S +structure as part of the +.Xr mr_gget 9E +entry point. +.It Fa rh +A pointer to the ring's private data that was passed in via the +.Vt mri_driver +member of the +.Xr mac_ring_info 9S +structure as part of the +.Xr mr_rget 9E +entry point. +.It Fa mr_gen +A 64-bit generation number. +.El +.Sh DESCRIPTION +The +.Fn mgi_start , +.Fn mgi_stop , +.Fn mri_start , +and +.Fn mri_stop +entry points are used to start and stop MAC rings and groups. +The group entry points are optional, while the ring entry points are +required. +The group start entry point will be called before any rings and +similarly, the ring stop entry point will be called for all rings before +the group stop entry point. +In the group case, the group is identified by +.Fa gh , +while the ring entry points use +.Fa rh +to identify the specific ring. +These are opaque pointers to data that was set in the +.Xr mac_group_info 9S +and +.Xr mac_ring_info 9S +structures during the +.Xr mr_gget 9E +and +.Xr mr_rget 9E +entry points respectively. +.Pp +These entry points give the driver a chance to take action prior to +actually transmitting or receiving any data. +The amount of work that is required will vary based on the driver and +its design. +At a minimum, during the +.Fn mri_start +entry point, a driver is required to save the value of +.Fa mr_gen +for later use, in particular when calling +.Xr mac_rx_ring 9E . +This is used by the system to discriminate between generations of the +device's configuration and its operation. +The operating system will check that all received packets are called +with the value of +.Fa mr_gen +that it expects. +If they do not match, then they received packets will be dropped. +.Pp +In general, it is recommended that descriptor rings are allocated during +the driver's initial +.Xr attach 9E . +In contrast, allocating and freeing the actual memory associated with +the descriptor entries during ring start and stop can be a reasonable +way to try and reduce memory overhead of the driver. +For example, a receive ring generally needs to allocate one DMA buffer +for each entry in its receive ring that covers the maximum frame size +that the device can receive. +This is something that could be deferred to the +.Fn mri_start +entry point and then freed in the +.Fn mri_stop +entry point. +.Pp +It's worth noting that the +.Fn mrg_stop +and +.Fn mrg_stop +entry points purposefully return +.Ft void . +In particular, this means that the driver must be careful about doing +things which might fail, such as asynchronous communication to a device. +If that is necessary and such communication fails, the device should be +marked as faulted and attempt to recover via a reset or similar +mechanism in another context. +.Sh RETURN VALUES +Upon successful completion, the +.Fn mgi_start +and +.Fn mri_start +entry points should return +.Sy 0 . +Otherwise, they should return the appropriate error number. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mr_gget 9E , +.Xr mac_group_info 9S diff --git a/usr/src/man/man9e/mi_enable.9e b/usr/src/man/man9e/mi_enable.9e new file mode 100644 index 0000000000..c5958db42d --- /dev/null +++ b/usr/src/man/man9e/mi_enable.9e @@ -0,0 +1,107 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MI_ENABLE 9E +.Os +.Sh NAME +.Nm mi_enable , +.Nm mi_disable +.Nd MAC interrupt enable and disable entry points +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft int +.Fo prefix_intr_enable +.Fa "mac_intr_handle_t driver" +.Fc +.Ft int +.Fo prefix_intr_disable +.Fa "mac_intr_handle_t driver" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the mac interrupt's private data that was passed in via the +.Vt mi_handle +member of the +.Xr mac_intr 9S +structure. +.El +.Sh DESCRIPTION +The +.Fn mi_enable +and +.Fn mi_disable +entry points are used by the MAC framework when it wishes to disable the +generation of interrupts for the ring and poll on the it through the +.Xr mri_poll 9E +entry point. +.Pp +These entry points should enable and disable the generation of the +interrupt for the ring that is represented by +.Fa driver . +The +.Fa driver +argument corresponds to what the driver set in the +.Fa mri_intr +member while filling out the +.Xr mac_ring_info 9S +structure and generally is used to point to a specific ring. +.Pp +Importantly, this entry point is not asking to enable and disable the +underlying device-level interrupt such as a PCIe MSI or MSI-X, which may +be being used by multiple rings. +Drivers must not implement this in terms of the DDI interrupt functions +such as +.Xr ddi_intr_enable 9F +and +.Xr ddi_intr_disable 9F . +.Pp +Instead this should be implemented through device specific means such as +writing to registers or sending control messages to enable or disable +the generation of interrupts for the specified ring. +.Pp +When manipulating the device's control of interrupts, the driver should +be careful to serialize these changes with the ongoing processing of +interrupts through the interrupt handler and the +.Xr mri_poll 9E +entry point. +These should all be protected by the same mutex which is scoped to the +ring itself when the ability to turn on and off interrupt generation may +be manipulated on a per-ring basis. +Failure to properly synchronize this may lead to the driver mistakenly +delivering the same packet twice through both its interrupt handler and +its +.Xr mri_poll 9E +entry point. +.Sh RETURN VALUES +Upon successful completion, the +.Fn mi_enable +and +.Fn mi_disable +entry points should return +.Sy 0 . +Otherwise the appropriate error number should be returned. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mri_poll 9E , +.Xr ddi_intr_disable 9F , +.Xr ddi_intr_enable 9F , +.Xr mac_intr 9S , +.Xr mac_ring_info 9S diff --git a/usr/src/man/man9e/mr_gget.9e b/usr/src/man/man9e/mr_gget.9e new file mode 100644 index 0000000000..991c518c97 --- /dev/null +++ b/usr/src/man/man9e/mr_gget.9e @@ -0,0 +1,132 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MR_GGET 9E +.Os +.Sh NAME +.Nm mr_gget +.Nd fill MAC group information +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft void +.Fo prefix_fill_group_info +.Fa "void *driver" +.Fa "mac_ring_type_t rtype" +.Fa "const int group_index" +.Fa "mac_group_info_t *infop" +.Fa "mac_group_handle_t gh" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the driver's private data that was passed in via the +.Fa m_pdata +member of the +.Xr mac_register 9S +structure to the +.Xr mac_register 9F +function. +.It Fa rtype +A value indicating the type of ring that makes up the groups. +Valid values include: +.Bl -tag -width Dv +.It Dv MAC_RING_TYPE_RX +The group is intended for use with receive rings. +.It Dv MAC_RING_TYPE_TX +The group is intended for use with transmit rings. +.El +.It Fa group_index +An integer value that uniquely identifying the group. +Groups are numbered starting from zero. +.It Fa infop +A pointer to an instance of a +.Xr mac_group_info 9S +structure. +.It Fa gh +An opaque pointer to a group handle that can be used to identify this +group. +.El +.Sh DESCRIPTION +The +.Fn mr_gget +entry point provides a means for the device driver to fill in +information about a group. +The driver returns information about the group to the MAC framework via +the +.Fa infop +argument. +For the list of fields and an explanation of how to fill them in, please +see +.Xr mac_group_info 9S . +.Pp +The +.Fa rtype +argument describes whether this is a group of receive rings or a group +of transmit rings. +This is identified by the value in +.Fa rtype +which will be +.Dv MAC_RING_TYPE_RX +for a receive group +and +.Dv MAC_RING_TYPE_TX +for a transmit group. +It is recommended that a driver doule check that the +.Fa rtype +matches what it expects if it uses separate entry points for receive and +transmit groups. +The group information that is filled in varies between transmit and +receive groups. +If separate entry points were not specified in the +.Xr mac_capab_rings 9E +structure, then the driver must ensure that it checks this value and +acts appropriately. +.Pp +The +.Fa group_index +argument is used to uniquely identify a group. +Groups are numbered starting at zero and end at one less then the number +of groups specified in +.Fa mr_gnum +member of the +.Vt mac_capbab_rings_t +structure which is described in +.Xr mac_capab_rings 9E . +Group IDs can be represented as the mathematical range [0, mr_gnum). +.Pp +After filling in the group information in +.Fa infop , +the driver should make sure to store the group handle +.Fa gh +for future use, mapping it to the index +.Fa group_index . +.Sh CONTEXT +The +.Fn mr_gget +entry point will be called in response to a driver calling the +.Xr mac_register 9F +function and the driver has acknowledged that it supports the +.Dv MAC_CAPAB_RINGS +capability. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mac_register 9F , +.Xr mac_group_info 9S , +.Xr mac_register 9S diff --git a/usr/src/man/man9e/mr_rget.9e b/usr/src/man/man9e/mr_rget.9e new file mode 100644 index 0000000000..31a79edba8 --- /dev/null +++ b/usr/src/man/man9e/mr_rget.9e @@ -0,0 +1,151 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Compuer Company +.\" +.Dd July 2, 2022 +.Dt MR_RGET 9E +.Os +.Sh NAME +.Nm mr_rget +.Nd fill in ring information +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft void +.Fo prefix_fill_ring_info +.Fa "void *driver" +.Fa "mac_ring_type_t rtype" +.Fa "const int group_index" +.Fa "const int ring_index" +.Fa "mac_ring_info_t *infop" +.Fa "mac_ring_handle_t rh" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the driver's private data that was passed in via the +.Fa m_pdata +member of the +.Xr mac_register 9S +structure to the +.Xr mac_register 9F +function. +.It Fa group_index +An integer value indicating the group that this ring belongs to. +Groups are numbered starting from zero. +.It Fa rtype +A value indicating the type of ring. +Valid values include: +.Bl -tag -width Dv +.It Dv MAC_RING_TYPE_RX +The ring is a receive ring. +.It Dv MAC_RING_TYPE_TX +The ring is a transmit ring. +.El +.It Fa ring_index +An integer indicating the index of the ring inside of the group. +Ring indexes are numbered starting from zero. +Each group has its own set of ring indexes. +.It Fa infop +A pointer to an instance of a +.Xr mac_ring_info 9S +structure. +.It Fa rh +An opaque pointer to a ring handle that can be used to identify this +ring. +.El +.Sh DESCRIPTION +The +.Fn mr_rget +entry point provides a means for the device driver to fill in +information about a ring. +The driver must fill in information into the +.Fa infop +argument. +For the list of fields and an explanation of how to fill them in, please +see +.Xr mac_ring_info 9S . +.Pp +The +.Fa rtype +argument describes whether this is a receive ring or transmit ring +identified by a value of +.Dv MAC_RING_TYPE_RX +or +.Dv MAC_RING_TYPE_TX +respectively. +The ring information that is filled in varies between transmit and +receive rings. +If separate entry points were not specified in the +.Xr mac_capab_rings 9E +structure, then the driver +must ensure that it checks this value. +.Pp +The +.Fa group_index +and +.Fa ring_index +arguments are used to uniquely identify a ring. +The number of groups that a driver supports is based on the values +present in the +.Fa mr_gnum +member of the +.Vt mac_capbab_rings_t +structure which is described in +.Xr mac_capab_rings 9E . +The group index ranges from zero to the specified number of groups minus +one. +The number of rings in the group is determined based on the values +specified in +.Xr mac_group_info 9S +structure that is filled in during the +.Xr mr_gget 9E +entry point. +The ring numbering for each group is independent and always starts at +zero. +Based on the combination of group and ring index, the driver should be +able to map that to a unique ring. +.Pp +After filling out the ring structure in +.Fa infop , +the driver should make sure to store the ring handle in +.Fa rh +for future use. +This is required for callbacks such as +.Xr mac_rx_ring 9F +or +.Xr mac_tx_ring_update 9F . +.Sh CONTEXT +The +.Fn mr_rget +entry point will be called in response to a driver calling the +.Xr mac_register 9F +function and the driver has acknowledged that it supports the +.Dv MAC_CAPAB_RINGS +capability. +This will be called after a call to the driver's +.Xr mr_gget 9E +entry point. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mr_gget 9E , +.Xr mac_register 9F , +.Xr mac_rx_ring 9F , +.Xr mac_tx_ring_update 9F , +.Xr mac_group_info 9S , +.Xr mac_register 9S , +.Xr mac_ring_info 9S diff --git a/usr/src/man/man9e/mri_poll.9e b/usr/src/man/man9e/mri_poll.9e new file mode 100644 index 0000000000..779ecae3b6 --- /dev/null +++ b/usr/src/man/man9e/mri_poll.9e @@ -0,0 +1,117 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MRI_POLL 9E +.Os +.Sh NAME +.Nm mri_poll +.Nd Poll a ring for received network data +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft mblk_t * +.Fo prefix_ring_poll +.Fa "void *driver" +.Fa "int poll_bytes" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa driver +A pointer to the ring's private data that was passed in via the +.Fa mri_driver +member of the +.Xr mac_ring_info 9S +structure as part of the +.Xr mr_rget 9E +entry point. +.It Fa poll_bytes +The maximum number of bytes that the driver should poll in a given call. +.El +.Sh DESCRIPTION +The +.Fn mri_poll +entry point is called by the MAC framework when it wishes to have the +driver check the ring specified by +.Fa driver +for available data. +.Pp +The device driver should perform the same logic that it would when it's +procesing an interrupt and as described in the +.Sx Receiving Data +section of +.Xr mac 9E . +The main difference is that instead of calling +.Xr mac_ring_rx 9E , +it should instead return that data as a +.Vt mblk_t +chain. +Also, while an interrupt may map to more than one ring in some drivers, +the driver should only process the ring indicated by +.Fa driver . +The MAC framework can be polling some rings that are receiving a lot of +traffic while still relying on interrupts for others. +.Pp +Drivers should exercise caution with the locking between the polling, +interrupt disabling routines, and the interrupt handler. +This mutex is generally scoped to a receive ring and is used to +synchronize the act of transitioning between polling and handling +interrupts. +That means that in addition to the +.Fn mri_poll +entry point, the +.Xr mi_enable 9E +and +.Xr mi_disable 9E +entry points should synchronize on the same mutex when transitioning the +device. +This is the same mutex that would be used when processing this ring +during an interrupt handler, though that mutex should only be used while +processing a specific ring and not held for the duration of the entire +interrupt handler. +.Pp +The driver should limit the number of frames it collects based on the +size value present in the +.Fa poll_bytes +argument. +The driver should sum up the total size of each processed frame and +compare that running total to +.Fa poll_bytes . +If there are fewer frames than, +.Fa poll_bytes , +the driver should not wait and can instead return right away. +Similarly, if the driver has iterated around its entire descriptor ring +and still does not have enough enough, it is OK to return early. +Importantly, the framework is +.Em not +asking the driver to block until it has +.Fa poll_bytes +available . +.Sh RETURN VALUES +Upon successful completion, the device driver should return a message +block chain of collected frames. +If no frames are available or it encountered an error while procesing +data, then it should return +.Dv NULL . +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mac_ring_rx 9E , +.Xr mi_disable 9E , +.Xr mi_enable 9E , +.Xr mr_rget 9E , +.Xr mac_ring_info 9S diff --git a/usr/src/man/man9e/mri_stat.9e b/usr/src/man/man9e/mri_stat.9e new file mode 100644 index 0000000000..cfd4b3595b --- /dev/null +++ b/usr/src/man/man9e/mri_stat.9e @@ -0,0 +1,165 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MRI_STAT 9E +.Os +.Sh NAME +.Nm mri_stat +.Nd xtatistics collection entry point for rings +.Sh SYNOPSIS +.In sys/mac_provider.h +.Ft int +.Fo prefix_ring_stat +.Fa "mac_ring_driver_t rh" +.Fa "uint_t stat" +.Fa "uint64_t *val" +.Fc +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa rh +A pointer to the ring's private data that was passed in via the +.Vt mri_driver +member of the +.Xr mac_ring_info 9S +structure as part of the +.Xr mr_rget 9E +entry point. +.It Fa stat +The numeric identifier of a statistic. +.It Fa val +A pointer to a 64-bit unsigned value into which the device driver should +place statistic. +.El +.Sh DESCRIPTION +The +.Fn mri_stat +entry point is called by the MAC framework to get statistics that have +been scoped to the ring, indicated by +.Fa rh . +.Pp +The set of statistics that the driver should check depends on the kind +of ring that is in use. +If the driver encounters an unknown statistic it should return +.Er ENOTSUP . +All the statistics should be values that are scoped to the ring itself. +This is in contrast to the normal +.Xr mc_getstat 9E +entry point, which has statistics for the entire device. +Other than the scoping, the statistics listed below have the same +meaning as they do in the +.Sx STATISTICS +section of +.Xr mac 9E . +See +.Xr mac 9E +for more details of those statistics. +.Pp +Receive rings should support the following statistics: +.Bl -bullet +.It +.Dv MAC_STAT_IPACKETS +.It +.Dv MAC_STAT_RBYTES +.El +.Pp +Transmit rings should support the following statitics: +.Bl -bullet +.It +.Dv MAC_STAT_OBYTES +.It +.Dv MAC_STAT_OPACKETS +.El +.Sh EXAMPLES +The following example shows how a driver might structure its +.Fn mri_stat +entry point. +.Bd -literal +#include <sys/mac_provider.h> + +/* + * Note, this example merely shows the structure of the function. For + * the purpose of this example, we assume that we have a per-ring + * structure which has members that indicate its stats and that it has a + * lock which is used to serialize access to this data. + */ + +static int +example_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) +{ + example_tx_ring_t *etrp = arg; + + mutex_enter(&etrp->etrp_lock); + switch (stat) { + case MAC_STAT_OBYTES: + *val = etrp->etrp_stats.eps_obytes; + break; + case MAC_STAT_OPACKETS: + *val = etrp->etrp_stats.eps_opackets; + break; + default: + mutex_exit(&etrp->etrp_lock); + return (ENOTSUP); + } + mutex_exit(&etrp->etrp_lock); + + return (0); +} + +static int +example_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) +{ + example_rx_ring_t *errp = arg; + + mutex_enter(&errp->errp_lock); + switch (stat) { + case MAC_STAT_RBYTES: + *val = errp->errp_stats.eps_ibytes; + break; + case MAC_STAT_IPACKETS: + *val = errp->errp_stats.eps_ipackets; + break; + default: + mutex_exit(&errp->errp_lock); + return (ENOTSUP); + } + mutex_exit(&errp->errp_lock); + + return (0); +} +.Ed +.Sh ERRORS +The device driver may return one of the following errors. +While this list is not intended to be exhaustive, it is recommend to use +one of these if possible. +.Bl -tag -width Er +.It Er ENOTSUP +The specified statistic is unknown, unsupported, or unimplemented. +.It Er EIO +A transport or DMA FM related error occurred while trying to sync data +from the device. +.It Er ECANCELLED +The device is not currently in a state where it can currently service +the request. +.El +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mc_getstat 9E , +.Xr mr_rget 9E , +.Xr mac_ring_info 9S diff --git a/usr/src/man/man9f/Makefile b/usr/src/man/man9f/Makefile index f928da60fe..bcefcfe990 100644 --- a/usr/src/man/man9f/Makefile +++ b/usr/src/man/man9f/Makefile @@ -986,8 +986,10 @@ MANLINKS= AVL_NEXT.9f \ mac_prop_info_set_default_uint8.9f \ mac_prop_info_set_perm.9f \ mac_prop_info_set_range_uint32.9f \ + mac_ring_rx.9f \ mac_transceiver_info_set_present.9f \ mac_transceiver_info_set_usable.9f \ + mac_tx_ring_update.9f \ mac_unregister.9f \ makecom_g0.9f \ makecom_g0_s.9f \ @@ -1806,9 +1808,13 @@ mac_prop_info_set_default_uint64.9f := LINKSRC = mac_prop_info.9f mac_prop_info_set_perm.9f := LINKSRC = mac_prop_info.9f mac_prop_info_set_range_uint32.9f := LINKSRC = mac_prop_info.9f +mac_ring_rx.9f := LINKSRC = mac_rx.9f + mac_transceiver_info_set_present.9f := LINKSRC = mac_transceiver_info.9f mac_transceiver_info_set_usable.9f := LINKSRC = mac_transceiver_info.9f +mac_tx_ring_update.9f := LINKSRC = mac_tx_update.9f + mac_unregister.9f := LINKSRC = mac_register.9f makecom_g0.9f := LINKSRC = makecom.9f diff --git a/usr/src/man/man9f/mac_rx.9f b/usr/src/man/man9f/mac_rx.9f index 19067c1838..efd7b2c0b9 100644 --- a/usr/src/man/man9f/mac_rx.9f +++ b/usr/src/man/man9f/mac_rx.9f @@ -9,13 +9,15 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2016 Joyent, Inc. +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Compuer Company .\" -.Dd June 02, 2016 +.Dd July 2, 2022 .Dt MAC_RX 9F .Os .Sh NAME -.Nm mac_rx +.Nm mac_rx , +.Nm mac_ring_rx .Nd deliver frames from a driver to the system .Sh SYNOPSIS .In sys/mac_provider.h @@ -25,8 +27,21 @@ .Fa "mac_resource_handle_t mrh" .Fa "mblk_t *mp_chain" .Fc +.Ft void +.Fo mac_rx_ring +.Fa "mac_handle_t mh" +.Fa "mac_ring_handle_t mring" +.Fa "mblk_t *mp_chain" +.Fa "uint64_t mr_gen" +.Fc .Sh INTERFACE LEVEL illumos DDI specific +.Pp +The +.Fn mac_rx_ring +function point is +.Sy Uncommitted - +API and ABI stability is not guaranteed. .Sh PARAMETERS .Bl -tag -width Fa .It Fa mh @@ -35,12 +50,21 @@ The MAC handle obtained from a call to .It Fa mrh A reserved parameter that should be passed as .Dv NULL . +.It Fa mring +A pointer to the ring handle that was passed to the driver in the +.Xr mr_rget 9E +entry point. .It Fa mp_chain A series of one or more .Xr mblk 9S structures chained together by their .Sy b_next member. +.It Fa mr_gen +The generation number for the current ring. +The generation comes from the +.Xr mri_start 9E +entry point. .El .Sh DESCRIPTION The @@ -66,7 +90,48 @@ Device drivers should not call the .Fn mac_rx function after each individual mblk_t is assembled. Rather, the device driver should batch up as many frames as it is willing to -process in a given interrupt or otherwise. +process in a given interrupt or are available. +.Pp +The +.Fn mac_rx_ring +function is similar to the +.Fa mac_rx +function; however, it should be called by device drivers that have +negotiated the +.Dv MAC_CAPAB_RINGS +capability and indicated that it supports receive groups. +Device drivers that have negotiated this capability must not call the +.Fn mac_rx +function, but use the +.Fn mac_rx_ring +function instead. +The driver should pass the ring handle in +.Fa mring +for the ring in question that it processed. +If more than one ring was processed during an interrupt, then the driver +must call +.Fn mac_ring_rx +once for each ring and ensure that the +.Fa mr_gen +argument matches what was passed to the driver during the +.Xr mri_start 9E +entry point for each ring. +If the value of +.Fa mr_gen +does not match what the operating system expects, all of the packets +will be dropped. +This is used to make sure that the system is receiving what it considers +valid data from the device driver. +.Pp +When a driver supporting the +.Dv MAC_CAPAB_RINGS +capability is asked to poll via their +.Xr mri_poll 9E +entry point, then the driver should not call the +.Fn mac_ring_rx +function to deliver packets and instead returns them during the +.Xr mri_poll 9E +call. .Sh CONTEXT The .Fn mac_rx @@ -78,5 +143,9 @@ or context. .Sh SEE ALSO .Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mr_rget 9E , +.Xr mri_poll 9E , +.Xr mri_start 9E , .Xr mac_register 9F , .Xr mblk 9S diff --git a/usr/src/man/man9f/mac_tx_update.9f b/usr/src/man/man9f/mac_tx_update.9f index 95e1a79271..36badcb688 100644 --- a/usr/src/man/man9f/mac_tx_update.9f +++ b/usr/src/man/man9f/mac_tx_update.9f @@ -9,13 +9,15 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2016 Joyent, Inc. +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company .\" -.Dd June 02, 2016 +.Dd July 2, 2022 .Dt MAC_TX_UPDATE 9F .Os .Sh NAME -.Nm mac_tx_update +.Nm mac_tx_update , +.Nm mac_tx_ring_update .Nd indicate that a device can transmit again .Sh SYNOPSIS .In sys/mac_provider.h @@ -23,13 +25,28 @@ .Fo mac_tx_update .Fa "mac_handle_t mh" .Fc +.Ft void +.Fo mac_tx_ring_update +.Fa "mac_handle_t mh" +.Fa "mac_ring_handle_t mrh" +.Fc .Sh INTERFACE LEVEL illumos DDI specific +.Pp +The +.Fn mac_tx_ring_update +function point is +.Sy Uncommitted - +API and ABI stability is not guaranteed. .Sh PARAMETERS .Bl -tag -width Fa .It Fa mh The MAC handle obtained from a call to .Xr mac_register 9F . +.It Fa mrh +The MAC ring handle obtained when the driver's ring entry point +.Xr mr_rget 9E +was called. .El .Sh DESCRIPTION The @@ -55,6 +72,28 @@ See the section of .Xr mac 9E for more information. +.Pp +When a driver has negotiated the +.Dv MAC_CAPAB_RINGS +capability and indicated that it supports transmit groups, it must not +use the +.Fn mac_tx_update +function and should instead call the +.Fn mac_tx_ring_update +function targeting a specific ring instead. +The ring that is being updated is specified by the ring handle passed in +the +.Fa mrh +argument. +The ring should have previously returned frames from its +.Xr mri_tx 9E +entry point to indicate that it was blocked. +.Pp +In all other respects, the +.Fn mac_tx_ring_update +function is similar to the +.Fn mac_tx_update +function. .Sh CONTEXT The .Fn mac_tx_update @@ -66,5 +105,8 @@ or context. .Sh SEE ALSO .Xr mac 9E , +.Xr mac_capab_rings 9E , .Xr mc_tx 9E , +.Xr mr_rget 9E , +.Xr mri_tx 9E , .Xr mac_register 9F diff --git a/usr/src/man/man9s/Makefile b/usr/src/man/man9s/Makefile index d70a69691b..9cb917a5ff 100644 --- a/usr/src/man/man9s/Makefile +++ b/usr/src/man/man9s/Makefile @@ -50,7 +50,10 @@ MANFILES= Intro.9s \ kstat_named.9s \ linkblk.9s \ mac_callbacks.9s \ + mac_group_info.9s \ + mac_intr.9s \ mac_register.9s \ + mac_ring_info.9s \ modldrv.9s \ modlinkage.9s \ modlmisc.9s \ @@ -102,7 +105,10 @@ MANFILES= Intro.9s \ MANLINKS= dblk.9s \ intro.9s \ mac_callbacks_t.9s \ + mac_group_info_t.9s \ + mac_intr_t.9s \ mac_register_t.9s \ + mac_ring_info_t.9s \ mblk.9s \ usb_ep_ss_comp_descr_t.9s \ usb_ep_xdescr_t.9s \ @@ -125,7 +131,10 @@ intro.9s := LINKSRC = Intro.9s dblk.9s := LINKSRC = datab.9s mac_callbacks_t.9s := LINKSRC = mac_callbacks.9s +mac_group_info_t.9s := LINKSRC = mac_group_info.9s +mac_intr_t.9s := LINKSRC = mac_intr.9s mac_register_t.9s := LINKSRC = mac_register.9s +mac_ring_info_t.9s := LINKSRC = mac_ring_info.9s mblk.9s := LINKSRC = msgb.9s diff --git a/usr/src/man/man9s/mac_callbacks.9s b/usr/src/man/man9s/mac_callbacks.9s index ba2d27f309..9dd4c4e547 100644 --- a/usr/src/man/man9s/mac_callbacks.9s +++ b/usr/src/man/man9s/mac_callbacks.9s @@ -9,9 +9,10 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2016 Joyent, Inc. +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company .\" -.Dd May 12, 2016 +.Dd July 2, 2022 .Dt MAC_CALLBACKS 9S .Os .Sh NAME @@ -25,20 +26,21 @@ illumos DDI specific .Sh DESCRIPTION The .Sy mac_callbacks -structure is used by GLDv3 networking device drivers implementing the +structure is used by GLDv3 networking device drivers implementing and +using the .Xr mac 9E -interface. +framework and interfaces. .Pp The structure is normally allocated statically by drivers as a single global entry. A pointer to it is passed as the -.Sy m_callbacks +.Fa m_callbacks member of the -.Sy mac_register_t +.Vt mac_register_t structure. .Sh TYPES The following types define the function pointers in use in the -.Sy mac_register_t . +.Vt mac_register_t . .Bd -literal -offset indent typedef int (*mac_getstat_t)(void *, uint_t, uint64_t *); typedef int (*mac_start_t)(void *); @@ -80,59 +82,59 @@ mac_prop_info_t mc_propinfo; /* Get property information */ .Ed .Pp The -.Sy mc_callbacks +.Fa mc_callbacks member is used to denote which of a series of optional callbacks are present. This method allows additional members to be added to the -.Sy mac_callbacks_t +.Vt mac_callbacks_t structure while maintaining ABI compatibility with existing modules. If a member is not mentioned below, then it is a part of the base version of the structure and device drivers do not need to set anything to indicate that it is present. The -.Sy mc_callbacks +.Fa mc_callbacks member should be set to the bitwise inclusive OR of the following pre-processor values: .Bl -tag -width Dv -offset indent -.It Sy MC_IOCTL +.It Dv MC_IOCTL Indicates that the -.Sy mc_ioctl +.Fa mc_ioctl structure member has been set. -.It Sy MC_GETCAPAB +.It Dv MC_GETCAPAB Indicates that the -.Sy mc_getcapab +.Fa mc_getcapab structure member has been set. -.It Sy MC_OPEN +.It Dv MC_OPEN Indicates that the -.Sy mc_open +.Fa mc_open structure member has been set. -.It Sy MC_CLOSE +.It Dv MC_CLOSE Indicates that the -.Sy mc_close +.Fa mc_close structure member has been set. -.It Sy MC_SETPROP +.It Dv MC_SETPROP Indicates that the -.Sy mc_setprop +.Fa mc_setprop structure member has been set. -.It Sy MC_GETPROP +.It Dv MC_GETPROP Indicates that the -.Sy mc_getprop +.Fa mc_getprop structure member has been set. -.It Sy MC_PROPINFO +.It Dv MC_PROPINFO Indicates that the -.Sy mc_propinfo +.Fa mc_propinfo structure member has been set. -.It Sy MC_PROPERTIES +.It Dv MC_PROPERTIES Indicates that the -.Sy mc_getprop , -.Sy mc_propinfo , +.Fa mc_getprop , +.Fa mc_propinfo , and -.Sy mc_setprop +.Fa mc_setprop structure members have been set. .El .Pp The -.Sy mc_getstat +.Fa mc_getstat function defines an entry point used to receive statistics about the device. A list of statistics that it is required to support is available in @@ -141,76 +143,76 @@ For more information on the requirements of the function, see .Xr mc_getstat 9E . .Pp The -.Sy mc_start +.Fa mc_start member defines an entry point that is used to start the device. For more information on the requirements of the function, see .Xr mc_start 9E . .Pp The -.Sy mc_stop +.Fa mc_stop member defines an entry point that is used to stop the device. It is the opposite of the -.Sy mc_start +.Fa mc_start member. For more information on the requirements of the function, see .Xr mc_stop 9E . .Pp The -.Sy mc_setpromisc +.Fa mc_setpromisc member is used to enable and disable promiscuous mode on the device. For more information on the requirements of the function, see .Xr mc_setpromisc 9E . .Pp The -.Sy mc_multicst +.Fa mc_multicst member is used to enable or disable multicast addresses in the device's filters. For more information on the requirements of the function, see .Xr mc_multicst 9E . .Pp The -.Sy mc_unicst +.Fa mc_unicst member is used to set the primary unicast MAC address of the device. For more information on the requirements of the function, see .Xr mc_unicst 9E . .Pp The -.Sy mc_tx +.Fa mc_tx member is used to transmit a single message on the wire. For more information on the requirements of the function, see .Xr mc_tx 9E . .Pp The -.Sy mc_ioctl +.Fa mc_ioctl member is used to process device specific ioctls. -The GLDv3 does not define any ioctls that devices should handle; however, there -may be private ioctls for this device. +The MAC framework does not define any ioctls that devices should handle; +however, there may be private ioctls for this device. This entry point is optional. For it to be considered, the -.Sy MC_IOCTL +.Dv MC_IOCTL value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_ioctl 9E . .Pp The -.Sy mc_getcapab +.Fa mc_getcapab member is used to determine device capabilities. Each capability has its own data and semantics associated with it. A list of capabilities is provided in .Xr mac 9E . This entry point is optional. For it to be used, the -.Sy MC_GETCAPAB +.Dv MC_GETCAPAB value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_getcapab 9E . .Pp The -.Sy mc_open +.Fa mc_open member is used to provide specific actions to take when the device is opened. Note that most device drivers will not have a need to implement this. @@ -219,15 +221,15 @@ used with .Xr dlpi 4P . This entry point is optional. For it to be used, the -.Sy MC_OPEN +.Dv MC_OPEN value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_open 9E . .Pp The -.Sy mc_close +.Fa mc_close member is used to provide specific actions to take when the device is closed. Note that most device drivers will not have a need to implement this. @@ -236,52 +238,52 @@ used with .Xr dlpi 4P . This entry point is optional. For it to be used, the -.Sy MC_CLOSE +.Dv MC_CLOSE value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_close 9E . .Pp The -.Sy mc_getprop +.Fa mc_getprop member is used to get the current value of a property from the device. A list of properties, their sizes, and their interpretation is available in .Xr mac 9E . This entry point is optional. For it to be used, the -.Sy MC_GETPROP +.Dv MC_GETPROP value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_getprop 9E . .Pp The -.Sy mc_setprop +.Fa mc_setprop member is used to set the value of a device property. A list of properties, their sizes, and their interpretation is available in .Xr mac 9E . This entry point is optional. For it to be used, the -.Sy MC_SETPROP +.Dv MC_SETPROP value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_setprop 9E . .Pp The -.Sy mc_propinfo +.Fa mc_propinfo member is used to obtain metadata about a property such as its default value, whether or not it is writable, and more. A list of properties, their sizes, and their interpretation is available in .Xr mac 9E . This entry point is optional. For it to be used, the -.Sy MC_PROPINFO +.Dv MC_PROPINFO value must be present in the -.Sy mc_callbacks +.Fa mc_callbacks member. For more information on the requirements of the function, see .Xr mc_propinfo 9E . @@ -292,34 +294,39 @@ members must be set or a call to will fail. .Bl -bullet -offset indent .It -.Sy mc_getstat +.Fa mc_getstat .It -.Sy mc_start +.Fa mc_start .It -.Sy mc_stop +.Fa mc_stop .It -.Sy mc_setpromisc +.Fa mc_setpromisc .It -.Sy mc_multicst +.Fa mc_multicst .It -.Sy mc_tx +.Fa mc_tx .It -.Sy mc_unicst +.Fa mc_unicst .El .Pp -Note, that devices which implement the GLDv3 ring capabilities must not -implement the -.Sy mc_unicst -and -.Sy mc_tx -functions. -However, the ring capabilities are still private and evolving at this time. +Devices which implement the +.Dv MAC_CAPAB_RINGS +capability for receive rings must not implement the +.Fa mc_unicst +entry point. +Devices which implement the +.Dv MAC_CAPAB_RINGS +capability for transmit rings must not implement the +.Fa mc_tx +entry points. +For more information about the capability, please see +.Xr mac_capab_rings 9E . .Pp Generally, a device that implements one of -.Sy mc_getprop , -.Sy mc_setprop , +.Fa mc_getprop , +.Fa mc_setprop , or -.Sy mc_propinfo +.Fa mc_propinfo will want to implement all three endpoints to ensure that the property is fully integrated into user land utilities such as .Xr dladm 8 . @@ -327,6 +334,7 @@ is fully integrated into user land utilities such as .Xr dlpi 4P , .Xr dladm 8 , .Xr mac 9E , +.Xr mac_capab_rings 9E , .Xr mc_close 9E , .Xr mc_getcapab 9E , .Xr mc_getprop 9E , @@ -341,4 +349,5 @@ is fully integrated into user land utilities such as .Xr mc_stop 9E , .Xr mc_tx 9E , .Xr mc_unicst 9E , +.Xr mac_register 9F , .Xr mac_register 9S diff --git a/usr/src/man/man9s/mac_group_info.9s b/usr/src/man/man9s/mac_group_info.9s new file mode 100644 index 0000000000..85c2f37aee --- /dev/null +++ b/usr/src/man/man9s/mac_group_info.9s @@ -0,0 +1,182 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MAC_GROUP_INFO 9S +.Os +.Sh NAME +.Nm mac_group_info , +.Nm mac_group_info_t +.Nd MAC group information structure +.Sh SYNOPSIS +.In sys/mac_provider.h +.Sh INTERFACE LEVEL +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh DESCRIPTION +The +.Vt mac_group_info_t +structure is used by the MAC framework as part of the +.Dv MAC_CAPAB_RINGS +capability. +For background on the MAC framework, please see +.Xr mac 9E +and for an introduction to the +.Dv MAC_CAPAB_RINGS +capability, +.Xr mac_capab_rings 9E . +.Pp +When a device driver declares that it supports the +.Dv MAC_CAPAB_RINGS +capability and fills out the capability structure as described in +.Xr mac_capab_rings 9E , +it indicates that it supports a number of transmit and receive groups. +For each group that it indicates, its +.Xr mr_gget 9E +entry point will be called, during which it will have to fill out the +.Vt mac_group_info_t +structure described here. +.Sh TYPES +The following types define the function pointers in use in the +.Vt mac_group_info_t +structure. +.Bd -literal -offset indent +typedef int (*mac_group_start_t)(mac_group_driver_t); +typedef void (*mac_group_stop_t)(mac_group_driver_t); +typedef int (*mac_add_mac_addr_t)(mac_group_driver_t, const uint8_t *mac, + uint_t flags) +typedef int (*mac_rem_mac_addr_t)(mac_group_driver_t, const uint8_t *mac, + uint_t flags) +typedef int (*mac_add_vlan_t)(mac_group_driver_t, uint16_t vlan, uint_t flags) +typedef int (*mac_rem_vlan_t)(mac_group_driver_t, uint16_t vlan, uint_t flags) +.Ed +.Sh STRUCTURE MEMBERS +.Bd -literal -offset indent +mac_group_driver_t mgi_driver; +mac_group_start_t mgi_start; +mac_group_start_t mgi_stop; +uint_t mgi_count; +mac_add_mac_addr_t mgi_addmac; +mac_rem_mac_addr_t mgi_remmac; +mac_add_vlan_t mgi_addvlan; +mac_rem_vlan_t mgi_remvlan; +.Ed +.Pp +The +.Fa mgi_driver +member should be set by the driver to a driver-specific value that +represents the data structure that corresponds to this group. +The driver will receive this value in all of the callback functions that +are defined in this structure and listed below. +.Pp +The +.Fa mgi_start +member is an optional entry point. +If the driver needs to take a specific action before it the group is +used, then it should set this to a function. +For more information, see +.Xr mgi_start 9E . +.Pp +The +.Fa mgi_stop +member is an optional entry point. +If the driver needs to take a specific action when the group is being +stopped, then it should set this to a function. +For more information, see +.Xr mgi_stop 9E . +.Pp +The +.Fa mgi_count +member should be set to a count of the number of rings that are present +in this group. +When the group type is +.Dv MAC_GROUP_TYPE_STATIC , +then the value in +.Fa mgi_count +represents the fixed number of rings available to the group. +.Pp +The +.Fa mgi_addmac +member is an optional entry point and should be set to a function that +can add a MAC address filter to the group in hardware. +For more information, see +.Xr mgi_addmac 9E . +This member only has meaning for a receive group, transmit groups should +set this to +.Dv NULL . +.Pp +The +.Fa mgi_remmac +member is an optional entry point and should be set to a function that +can remove a MAC address filter from a group in hardware. +If the +.Fa mgi_addmac +member is a valid pointer, then this entry point must be as well. +For more information, see +.Xr mgi_remmac 9E . +This member only has meaning for a receive group, transmit groups should +set this to +.Dv NULL . +.Pp +The +.Fa mgi_addvlan +member is an optional entry point and should be set to a function that +can add a VLAN filter to the group in hardware. +For more information, see +.Xr mgi_addvlan 9E . +This member only has meaning for a receive group, transmit groups should +set this to +.Dv NULL . +.Pp +The +.Fa mgi_remvlan +member is an optional entry point and should be set to a function that +can remove a VLAN filter from a group in hardware. +If the +.Fa mgi_addvlan +member is a valid pointer, then this entry point must be as well. +For more information, see +.Xr mgi_remvlan 9E . +This member only has meaning for a receive group, transmit groups should +set this to +.Dv NULL . +.Ss Required Members +All of the non-function pointers described in this manual are required +members for both transmit and receive groups. +The +.Fa mgi_start +and +.Fa mgi_stop +members are optional for both transmit and receive groups. +.Pp +For transmit groups, all of the filter entry points must be set to +.Dv NULL . +.Pp +Receive groups must have some way to set a MAC address filter. +This means that one of the MAC address related functions must be set. +Currently, the driver must implement either +.Fa mgi_addmac +and +.Fa mgi_remmac . +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mgi_addmac 9E , +.Xr mgi_addvlan 9E , +.Xr mgi_remmac 9E , +.Xr mgi_remvlan 9E , +.Xr mgi_start 9E , +.Xr mgi_stop 9E , +.Xr mr_gget 9E diff --git a/usr/src/man/man9s/mac_intr.9s b/usr/src/man/man9s/mac_intr.9s new file mode 100644 index 0000000000..29fb93d803 --- /dev/null +++ b/usr/src/man/man9s/mac_intr.9s @@ -0,0 +1,114 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Compuer Company +.\" +.Dd July 2, 2022 +.Dt MAC_INTR 9S +.Os +.Sh NAME +.Nm mac_intr , +.Nm mac_intr_t +.Nd MAC interrupt information +.Sh SYNOPSIS +.In sys/mac_provider.h +.Sh INTERFACE STABILITY +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh DESCRIPTION +The +.Vt mac_intr_t +structure is used by the MAC framework as part of the +.Dv MAC_CAPAB_RINGS +capability. +For more background on the MAC framework, please see +.Xr mac 9E +and for more information on the +.Dv MAC_CAPAB_RINGS +capability, +.Xr mac_capab_rings 9E . +.Pp +The +.Vt mac_intr_t +structure is used to describe an interrupt and additional capabilities +around it. +The structure is usually used as part of another +.Xr mac 9E +related structure such as the +.Fa mri_intr +member of the +.Xr mac_ring_info 9S +structure. +The MAC framework uses the functions described here to enable and +disable interrupt generation for a specific ring, which is used as part +of switching between polling and interrupt-driven receiving. +.Pp +While the structure does embed a +.Vt ddi_intr_handle_t +that corresponds to the ring's unerlying MSI-X, MSI, INTx, or other +interrupt type, the +.Vt mac_intr_t +still represents and is scoped to a single ring itself. +.Sh TYPES +Tye following types define the function pointers in use in the +.Vt mac_intr_t +structure. +.Bd -literal -offset indent +typedef int (*mac_intr_enable_t)(mac_intr_handle_t); +typedef int (*mac_intr_disable_t)(mac_intr_handle_t); +.Ed +.Sh STRUCTURE MEMBERS +.Bd -literal -offset indent +mac_intr_handle_t mi_handle; +mac_intr_enable_t mi_enable; +mac_intr_disable_t mi_disable; +ddi_intr_handle_t mi_ddi_handle; +.Ed +.Pp +The +.Fa mi_handle +member should be set to a driver-specific value that will be passed back +to the driver in the various callback functions that are setin the +structure and described below. +.Pp +The +.Fa mi_enable +member is a required entry point for receive rings and optional for +transmit rings. +It should be set to a function which enables interrupts for the ring. +For more information, see +.Xr mi_enable 9E . +.Pp +The +.Fa mi_disable +member is a required entry point for receive rings and an optional entry +point for transmit rings. +It should be set to a function which disables interrupts for the ring. +For more information, see +.Xr mi_disable 9E . +.Pp +The +.Fa mi_ddi_handle +member should be set to the interrupt handle that corresponds to the +ring. +the interrupt handle will have come from +.Xr ddi_intr_alloc 9F . +This member should only be set if the interrupt is a MSI or MSI-X +interrupt. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mi_disable 9E , +.Xr mi_enable 9E , +.Xr ddi_intr_alloc 9F , +.Xr mac_ring_inf 9S diff --git a/usr/src/man/man9s/mac_ring_info.9s b/usr/src/man/man9s/mac_ring_info.9s new file mode 100644 index 0000000000..7432faea69 --- /dev/null +++ b/usr/src/man/man9s/mac_ring_info.9s @@ -0,0 +1,154 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2017, Joyent, Inc. +.\" Copyright 2022 Oxide Computer Company +.\" +.Dd July 2, 2022 +.Dt MAC_RING_INFO 9S +.Os +.Sh NAME +.Nm mac_ring_info , +.Nm mac_ring_info_t +.Nd MAC ring information structure +.Sh SYNOPSIS +.In sys/mac_provider.h +.Sh INTERFACE STABILITY +.Sy Uncommitted - +This interface is still evolving. +API and ABI stability is not guaranteed. +.Sh DESCRIPTION +The +.Vt mac_ring_info_t +structure is used by the MAC framework as part of the +.Dv MAC_CAPAB_RINGS +capability. +For more background on the MAC framework, please see +.Xr mac 9E +and for an introduction to the +.Dv MAC_CAPAB_RINGS +capability, +.Xr mac_capab_rings 9E . +.Pp +When a device driver declares that it supports the +.Dv MAC_CAPAB_RINGS +capability and fills out the structure as described in +.Xr mac_capab_rings 9E , +it indicates that it supports a number of rings for transmitting and +receiving. +For each ring that it supports, the driver's +.Xr mr_rget 9E +entry point will be called, during which it will have to fill out the +.Vt mac_ring_info_t +structure defined here. +.Sh TYPES +The following types define the function pointers in use in the +.Vt mac_ring_info_t +structure. +.Bd -literal -offset indent +typedef int (*mac_ring_start_t)(mac_ring_driver_t, uint64_t); +typedef void (*mac_ring_stop_t)(mac_ring_driver_t); + +typedef mblk_t *(*mac_ring_send_t)(mac_ring_driver_t, mblk_t *); +typedef mblk_t *(*mac_ring_poll_t)(mac_ring_driver_t, int); + +typedef int (*mac_ring_stat_t)(mac_ring_driver_t, uint_t, uint64_t *); +.Ed +.Sh STRUCTURE MEMBERS +.Bd -literal -offset indent +mac_ring_driver_t mri_driver; +mac_ring_start_t mri_start; +mac_ring_stop_t mri_stop; +mac_intr_t mri_intr; +mac_ring_send_t mri_tx; +mac_ring_poll_t mri_poll; +mac_ring_stat_t mri_stat; +.Ed +.Pp +The +.Fa mri_driver +member should be set to a driver-specific value that represents the data +structure that corresponds to the ring. +The driver will receive this value in all of the callback functions that +are defined in this structure and discussed below. +.Pp +The +.Fa mri_start +member is a required entry point that is used to start the ring. +While the device driver may not need to do any work with hardware to +start the use of the ring, it must record the ring's generation number. +For more information, see +.Xr mri_start 9E . +.Pp +The +.Fa mri_stop +member is an optional entry point that will be called when the ring is +being stopped. +For more information, see +.Xr mri_stop 9E . +.Pp +The +.Fa mri_intr +member contains information about the interrupt associated with the +ring. +For more information on filling it out, see +.Xr mac_intr 9S . +.Pp +The +.Fa mri_tx +member should only be set on transmit rings. +It must not be set on receive rings. +The +.Fa mri_tx +member should be set to a function that will transmit a given frame on +the specified ring. +For more information, see +.Xr mri_tx 9E . +.Pp +The +.Fa mri_poll +member should only be set on receive rings. +It must not be set on transmit rings. +The +.Fa mri_poll +member should be set to a function which will poll the specified ring. +For more information, see +.Xr mri_poll 9E . +.Pp +The +.Fa mri_stat +member should be set to a function which will retrieve statistics about +the specified ring. +For more information, see +.Xr mri_stat 9E . +.Ss Required Members +All non-function members are required. +The +.Fa mri_intr +member must be a properly filled out as per +.Xr mac_intr 9S . +.Pp +For transmit rings, the +.Fa mri_tx +member is required. +.Pp +For receive rings, the +.Fa mri_poll +member is required. +.Sh SEE ALSO +.Xr mac 9E , +.Xr mac_capab_rings 9E , +.Xr mri_poll 9E , +.Xr mri_start 9E , +.Xr mri_stat 9E , +.Xr mri_stop 9E , +.Xr mri_tx 9E , +.Xr mac_intr 9S diff --git a/usr/src/pkg/manifests/SUNWcs.man8.inc b/usr/src/pkg/manifests/SUNWcs.man8.inc index dd528d1b5c..e01e313a47 100644 --- a/usr/src/pkg/manifests/SUNWcs.man8.inc +++ b/usr/src/pkg/manifests/SUNWcs.man8.inc @@ -143,7 +143,6 @@ file path=usr/share/man/man8/ipsecconf.8 file path=usr/share/man/man8/ipseckey.8 file path=usr/share/man/man8/keyserv.8 file path=usr/share/man/man8/killall.8 -file path=usr/share/man/man8/ksslcfg.8 file path=usr/share/man/man8/labelit.8 file path=usr/share/man/man8/labelit_hsfs.8 file path=usr/share/man/man8/labelit_ufs.8 diff --git a/usr/src/pkg/manifests/SUNWcs.p5m b/usr/src/pkg/manifests/SUNWcs.p5m index 76e7943d1e..70a794b487 100644 --- a/usr/src/pkg/manifests/SUNWcs.p5m +++ b/usr/src/pkg/manifests/SUNWcs.p5m @@ -22,7 +22,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2013 Gary Mills -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2017 Nexenta Systems, Inc. # Copyright 2017 Toomas Soome <tsoome@me.com> # Copyright 2019 Peter Tribble. @@ -369,9 +369,6 @@ file path=lib/svc/manifest/network/rpc/keyserv.xml group=sys mode=0444 dir path=lib/svc/manifest/network/shares group=sys file path=lib/svc/manifest/network/shares/group.xml group=sys mode=0444 file path=lib/svc/manifest/network/shares/reparsed.xml group=sys mode=0444 -file path=lib/svc/manifest/network/socket-filter-kssl.xml group=sys mode=0444 -dir path=lib/svc/manifest/network/ssl group=sys -file path=lib/svc/manifest/network/ssl/kssl-proxy.xml group=sys mode=0444 dir path=lib/svc/manifest/platform group=sys $(sparc_ONLY)dir path=lib/svc/manifest/platform/sun4u group=sys dir path=lib/svc/manifest/site group=sys @@ -1184,7 +1181,6 @@ hardlink path=usr/lib/inet/in.iked target=../../../usr/lib/isaexec file path=usr/lib/inet/inetd mode=0555 file path=usr/lib/intrd mode=0555 file path=usr/lib/isaexec mode=0555 -file path=usr/lib/kssladm mode=0555 $(sparc_ONLY)file path=usr/lib/ld.so link path=usr/lib/ld.so.1 target=../../lib/ld.so.1 file path=usr/lib/libshare.so.1 @@ -1405,7 +1401,6 @@ file path=usr/sbin/ipsecconf mode=0555 file path=usr/sbin/ipseckey mode=0555 file path=usr/sbin/keyserv group=sys mode=0555 file path=usr/sbin/killall mode=0555 -file path=usr/sbin/ksslcfg mode=0555 link path=usr/sbin/labelit target=./clri file path=usr/sbin/link mode=0555 hardlink path=usr/sbin/list_devices target=../../usr/sbin/allocate @@ -1614,7 +1609,6 @@ dir path=var/svc/manifest/network/routing group=sys dir path=var/svc/manifest/network/rpc group=sys dir path=var/svc/manifest/network/security group=sys dir path=var/svc/manifest/network/shares group=sys -dir path=var/svc/manifest/network/ssl group=sys dir path=var/svc/manifest/platform group=sys $(sparc_ONLY)dir path=var/svc/manifest/platform/sun4u group=sys $(sparc_ONLY)dir path=var/svc/manifest/platform/sun4v group=sys diff --git a/usr/src/pkg/manifests/developer-linker.p5m b/usr/src/pkg/manifests/developer-linker.p5m index 795a5dabf0..d1ba314819 100644 --- a/usr/src/pkg/manifests/developer-linker.p5m +++ b/usr/src/pkg/manifests/developer-linker.p5m @@ -40,7 +40,7 @@ file path=usr/bin/$(ARCH32)/truss mode=0555 dir path=usr/bin/$(ARCH64) file path=usr/bin/$(ARCH64)/elfwrap mode=0555 file path=usr/bin/$(ARCH64)/gcore mode=0555 -file path=usr/bin/$(ARCH64)/ld mode=0755 +link path=usr/bin/$(ARCH64)/ld target=../../bin/ld file path=usr/bin/$(ARCH64)/ldd mode=0555 file path=usr/bin/$(ARCH64)/plimit mode=0555 file path=usr/bin/$(ARCH64)/pvs mode=0555 diff --git a/usr/src/pkg/manifests/system-header.p5m b/usr/src/pkg/manifests/system-header.p5m index 00d1f468d4..62ae910ece 100644 --- a/usr/src/pkg/manifests/system-header.p5m +++ b/usr/src/pkg/manifests/system-header.p5m @@ -23,7 +23,7 @@ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2013 Saso Kiselkov. All rights reserved. -# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# Copyright 2022 Garrett D'Amore <garrett@damore.org> # Copyright 2018 Nexenta Systems, Inc. # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> # Copyright 2020 Joyent, Inc. @@ -295,8 +295,6 @@ file path=usr/include/inet/ipclassifier.h file path=usr/include/inet/ipdrop.h file path=usr/include/inet/ipnet.h file path=usr/include/inet/ipp_common.h -dir path=usr/include/inet/kssl -file path=usr/include/inet/kssl/ksslapi.h file path=usr/include/inet/led.h file path=usr/include/inet/mi.h file path=usr/include/inet/mib2.h diff --git a/usr/src/pkg/manifests/system-kernel.man9e.inc b/usr/src/pkg/manifests/system-kernel.man9e.inc index f4169b140d..e787e8fad6 100644 --- a/usr/src/pkg/manifests/system-kernel.man9e.inc +++ b/usr/src/pkg/manifests/system-kernel.man9e.inc @@ -60,7 +60,9 @@ file path=usr/share/man/man9e/ks_snapshot.9e file path=usr/share/man/man9e/ks_update.9e file path=usr/share/man/man9e/mac.9e file path=usr/share/man/man9e/mac_capab_led.9e +file path=usr/share/man/man9e/mac_capab_rings.9e file path=usr/share/man/man9e/mac_capab_transceiver.9e +file path=usr/share/man/man9e/mac_filter.9e link path=usr/share/man/man9e/mc_close.9e target=mc_open.9e file path=usr/share/man/man9e/mc_getcapab.9e file path=usr/share/man/man9e/mc_getprop.9e @@ -78,7 +80,22 @@ file path=usr/share/man/man9e/mc_unicst.9e link path=usr/share/man/man9e/mcl_set.9e target=mac_capab_led.9e link path=usr/share/man/man9e/mct_info.9e target=mac_capab_transceiver.9e link path=usr/share/man/man9e/mct_read.9e target=mac_capab_transceiver.9e +link path=usr/share/man/man9e/mgi_addmac.9e target=mac_filter.9e +link path=usr/share/man/man9e/mgi_addvlan.9e target=mac_filter.9e +link path=usr/share/man/man9e/mgi_remmac.9e target=mac_filter.9e +link path=usr/share/man/man9e/mgi_remvlan.9e target=mac_filter.9e +file path=usr/share/man/man9e/mgi_start.9e +link path=usr/share/man/man9e/mgi_stop.9e target=mgi_start.9e +link path=usr/share/man/man9e/mi_disable.9e target=mi_enable.9e +file path=usr/share/man/man9e/mi_enable.9e file path=usr/share/man/man9e/mmap.9e +file path=usr/share/man/man9e/mr_gget.9e +file path=usr/share/man/man9e/mr_rget.9e +file path=usr/share/man/man9e/mri_poll.9e +link path=usr/share/man/man9e/mri_start.9e target=mgi_start.9e +file path=usr/share/man/man9e/mri_stat.9e +link path=usr/share/man/man9e/mri_stop.9e target=mgi_start.9e +link path=usr/share/man/man9e/mri_tx.9e target=mc_tx.9e file path=usr/share/man/man9e/open.9e file path=usr/share/man/man9e/power.9e file path=usr/share/man/man9e/print.9e diff --git a/usr/src/pkg/manifests/system-kernel.man9f.inc b/usr/src/pkg/manifests/system-kernel.man9f.inc index 43d195f6ca..ff65a720ad 100644 --- a/usr/src/pkg/manifests/system-kernel.man9f.inc +++ b/usr/src/pkg/manifests/system-kernel.man9f.inc @@ -810,12 +810,14 @@ link path=usr/share/man/man9f/mac_prop_info_set_perm.9f target=mac_prop_info.9f link path=usr/share/man/man9f/mac_prop_info_set_range_uint32.9f \ target=mac_prop_info.9f file path=usr/share/man/man9f/mac_register.9f +link path=usr/share/man/man9f/mac_ring_rx.9f target=mac_rx.9f file path=usr/share/man/man9f/mac_rx.9f file path=usr/share/man/man9f/mac_transceiver_info.9f link path=usr/share/man/man9f/mac_transceiver_info_set_present.9f \ target=mac_transceiver_info.9f link path=usr/share/man/man9f/mac_transceiver_info_set_usable.9f \ target=mac_transceiver_info.9f +link path=usr/share/man/man9f/mac_tx_ring_update.9f target=mac_tx_update.9f file path=usr/share/man/man9f/mac_tx_update.9f link path=usr/share/man/man9f/mac_unregister.9f target=mac_register.9f file path=usr/share/man/man9f/makecom.9f diff --git a/usr/src/pkg/manifests/system-kernel.man9s.inc b/usr/src/pkg/manifests/system-kernel.man9s.inc index baedb1f80c..0a00ec9e21 100644 --- a/usr/src/pkg/manifests/system-kernel.man9s.inc +++ b/usr/src/pkg/manifests/system-kernel.man9s.inc @@ -76,3 +76,9 @@ file path=usr/share/man/man9s/streamtab.9s file path=usr/share/man/man9s/stroptions.9s file path=usr/share/man/man9s/tuple.9s file path=usr/share/man/man9s/uio.9s +file path=usr/share/man/man9s/mac_group_info.9s +link path=usr/share/man/man9s/mac_group_info_t.9s target=mac_group_info.9s +file path=usr/share/man/man9s/mac_intr.9s +link path=usr/share/man/man9s/mac_intr_t.9s target=mac_intr.9s +file path=usr/share/man/man9s/mac_ring_info.9s +link path=usr/share/man/man9s/mac_ring_info_t.9s target=mac_ring_info.9s diff --git a/usr/src/pkg/manifests/system-kernel.p5m b/usr/src/pkg/manifests/system-kernel.p5m index 62e8a909c5..208bd86844 100644 --- a/usr/src/pkg/manifests/system-kernel.p5m +++ b/usr/src/pkg/manifests/system-kernel.p5m @@ -147,7 +147,6 @@ file path=kernel/drv/$(ARCH64)/iwscn group=sys file path=kernel/drv/$(ARCH64)/kb8042 group=sys file path=kernel/drv/$(ARCH64)/keysock group=sys file path=kernel/drv/$(ARCH64)/kmdb group=sys -file path=kernel/drv/$(ARCH64)/kssl group=sys file path=kernel/drv/$(ARCH64)/llc1 group=sys file path=kernel/drv/$(ARCH64)/lofi group=sys file path=kernel/drv/$(ARCH64)/log group=sys @@ -225,7 +224,6 @@ file path=kernel/drv/iptun.conf group=sys file path=kernel/drv/iwscn.conf group=sys file path=kernel/drv/keysock.conf group=sys file path=kernel/drv/kmdb.conf group=sys -file path=kernel/drv/kssl.conf group=sys file path=kernel/drv/llc1.conf group=sys file path=kernel/drv/lofi.conf group=sys file path=kernel/drv/log.conf group=sys \ @@ -397,7 +395,6 @@ dir path=kernel/socketmod group=sys dir path=kernel/socketmod/$(ARCH64) group=sys hardlink path=kernel/socketmod/$(ARCH64)/icmp \ target=../../../kernel/drv/$(ARCH64)/icmp -file path=kernel/socketmod/$(ARCH64)/ksslf group=sys mode=0755 hardlink path=kernel/socketmod/$(ARCH64)/rts \ target=../../../kernel/drv/$(ARCH64)/rts file path=kernel/socketmod/$(ARCH64)/socksctp group=sys mode=0755 @@ -546,7 +543,6 @@ driver name=kb8042 alias=pnpPNP,303 driver name=keysock perms="keysock 0666 root sys" \ policy="read_priv_set=sys_ip_config write_priv_set=sys_ip_config" driver name=kmdb -driver name=kssl perms="* 0666 root sys" driver name=llc1 clone_perms="llc1 0666 root sys" driver name=lofi perms="* 0600 root sys" perms="ctl 0644 root sys" driver name=log perms="conslog 0666 root sys" perms="log 0640 root sys" 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 800bf9fbde..9f0a12ff88 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 2021 Joyent, Inc. # Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> @@ -1663,13 +1663,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 b047275e06..265ec59b39 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 2021 Joyent, Inc. # Copyright 2018 Nexenta Systems, Inc. @@ -506,10 +506,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/common/io/sata/adapters/ahci/ahci.c b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c index 7f2100ba41..d3ae7fb6c7 100644 --- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c +++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c @@ -24,6 +24,7 @@ * Copyright 2018 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2021 RackTop Systems, Inc. */ /* @@ -780,6 +781,10 @@ ahci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities extended = 0x%x", cap2_status); + + if (cap2_status & AHCI_HBA_CAP2_SDS) { + ahci_ctlp->ahcictl_cap |= AHCI_CAP_SDS; + } } if (cap_status & AHCI_HBA_CAP_EMS) { @@ -5934,7 +5939,7 @@ ahci_find_dev_signature(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, * According to the spec, to reliably detect hot plug removals, software * must disable interface power management. Software should perform the * following initialization on a port after a device is attached: - * Set PxSCTL.IPM to 3h to disable interface state transitions + * Set PxSCTL.IPM to 3h or 7h to disable interface state transitions * Set PxCMD.ALPE to '0' to disable aggressive power management * Disable device initiated interface power management by SET FEATURE * @@ -5944,10 +5949,16 @@ static void ahci_disable_interface_pm(ahci_ctl_t *ahci_ctlp, uint8_t port) { uint32_t port_scontrol, port_cmd_status; + uint32_t ipm; port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port)); - SCONTROL_SET_IPM(port_scontrol, SCONTROL_IPM_DISABLE_BOTH); + if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SDS) { + ipm = SCONTROL_IPM_DISABLE_ALL; + } else { + ipm = SCONTROL_IPM_DISABLE_BOTH; + } + SCONTROL_SET_IPM(port_scontrol, ipm); ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol); diff --git a/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h b/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h index e738783dfe..1f7c8f71ef 100644 --- a/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h +++ b/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h @@ -25,6 +25,7 @@ */ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2021 RackTop Systems, Inc. */ #ifndef _AHCIREG_H @@ -68,7 +69,6 @@ extern "C" { #define AHCI_HBA_CAP_FBSS (0x1 << 16) /* FIS-based switching */ #define AHCI_HBA_CAP_SPM (0x1 << 17) /* port multiplier */ #define AHCI_HBA_CAP_SAM (0x1 << 18) /* AHCI mode only */ -#define AHCI_HBA_CAP_SNZO (0x1 << 19) /* non-zero DMA offsets */ #define AHCI_HBA_CAP_ISS (0xf << 20) /* interface speed support */ #define AHCI_HBA_CAP_SCLO (0x1 << 24) /* command list override */ #define AHCI_HBA_CAP_SAL (0x1 << 25) /* activity LED */ @@ -114,6 +114,12 @@ extern "C" { #define AHCI_HBA_EM_CTL_ATTR_ALHD (0x1 << 26) /* Activity LED HW Driven */ #define AHCI_HBA_EM_CTL_ATTR_PM (0x1 << 27) /* PM Support */ +#define AHCI_HBA_CAP2_BOH (0x1 << 0) /* BIOS/OS Handoff */ +#define AHCI_HBA_CAP2_NVMP (0x1 << 1) /* NVMHCI present */ +#define AHCI_HBA_CAP2_APST (0x1 << 2) /* Auto Partial to Slumber */ +#define AHCI_HBA_CAP2_SDS (0x1 << 3) /* Device Sleep */ +#define AHCI_HBA_CAP2_SADM (0x1 << 4) /* Aggressive Dev Sleep Mgmt */ +#define AHCI_HBA_CAP2_DESO (0x1 << 5) /* DevSleep from Slumber Only */ /* global HBA registers definitions */ #define AHCI_GLOBAL_OFFSET(ahci_ctlp) (ahci_ctlp->ahcictl_ahci_addr) @@ -313,7 +319,7 @@ typedef struct ahci_fis_h2d_register { (fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff)) #define SET_FIS_PMP(fis, pmp) \ - (fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= \ + (fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= \ ((pmp & 0xf) << 8)) #define SET_FIS_CDMDEVCTL(fis, cmddevctl) \ @@ -396,7 +402,7 @@ typedef struct ahci_fis_h2d_register { (fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl & 0xff) #define SET_FIS_SECTOR_COUNT(fis, sector_count) \ - (fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= \ + (fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= \ ((sector_count & 0xff))) #define GET_FIS_SECTOR_COUNT_EXP(fis) \ @@ -407,7 +413,7 @@ typedef struct ahci_fis_h2d_register { ((sector_count_exp & 0xff) << 8)) #define SET_FIS_DEVCTL(fis, devctl) \ - (fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= \ + (fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= \ ((devctl & 0xff) << 24)) /* offset 0x10 */ diff --git a/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h b/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h index 8195242dd3..34bcacc576 100644 --- a/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h +++ b/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h @@ -23,6 +23,7 @@ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2021 RackTop Systems, Inc. */ @@ -517,6 +518,8 @@ _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, #define AHCI_CAP_SRST_NO_HOSTPORT 0x800 /* Enclosure Management Services available */ #define AHCI_CAP_EMS 0x1000 +/* DevSleep Supported */ +#define AHCI_CAP_SDS 0x2000 /* Flags controlling the restart port behavior */ #define AHCI_PORT_RESET 0x0001 /* Reset the port */ diff --git a/usr/src/uts/common/sys/sata/sata_defs.h b/usr/src/uts/common/sys/sata/sata_defs.h index f3a3a1d481..de7667b770 100644 --- a/usr/src/uts/common/sys/sata/sata_defs.h +++ b/usr/src/uts/common/sys/sata/sata_defs.h @@ -23,6 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright 2021 RackTop Systems, Inc. */ #ifndef _SATA_DEFS_H @@ -827,10 +828,13 @@ struct mode_acoustic_management { (x = (x & ~SCONTROL_IPM) | \ ((new_val << SCONTROL_IPM_SHIFT) & SCONTROL_IPM)) +/* NB: IPM disable value is a bit-field (though not described) */ #define SCONTROL_IPM_NORESTRICT 0 /* No PM limit */ #define SCONTROL_IPM_DISABLE_PARTIAL 1 /* Disable partial */ #define SCONTROL_IPM_DISABLE_SLUMBER 2 /* Disable slumber */ #define SCONTROL_IPM_DISABLE_BOTH 3 /* Disable both */ +#define SCONTROL_IPM_DISABLE_DEVSLEEP 4 /* Disable devsleep */ +#define SCONTROL_IPM_DISABLE_ALL 7 /* Disable all PM */ #define SCONTROL_SPM_NORESTRICT 0 /* No PM limits */ #define SCONTROL_SPM_DO_PARTIAL 1 /* Go to partial */ diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index 2cb43d8beb..375eeb92d7 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 2021 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. @@ -267,7 +267,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 @@ -722,7 +721,6 @@ SOCKET_KMODS += sockpfp SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds -SOCKET_KMODS += ksslf SOCKET_KMODS += datafilt # 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 262bd70f6b..2d99df874d 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> @@ -860,7 +861,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/intel/os/minor_perm b/usr/src/uts/intel/os/minor_perm index 52aa933f0a..3b4971e69b 100644 --- a/usr/src/uts/intel/os/minor_perm +++ b/usr/src/uts/intel/os/minor_perm @@ -161,7 +161,6 @@ ipnet:lo0 0666 root sys ipsecah:ipsecah 0666 root sys ipsecesp:ipsecesp 0666 root sys keysock:keysock 0666 root sys -kssl:* 0666 root sys clone:llc1 0666 root sys lofi:* 0600 root sys lofi:ctl 0644 root sys diff --git a/usr/src/uts/intel/os/name_to_major b/usr/src/uts/intel/os/name_to_major index 6fb1517e5c..46a61f4e82 100644 --- a/usr/src/uts/intel/os/name_to_major +++ b/usr/src/uts/intel/os/name_to_major @@ -36,7 +36,6 @@ iwscn 30 kb8042 31 keysock 32 kmdb 33 -kssl 34 llc1 35 lofi 36 log 37 diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc index 94fc47b31b..ec7b4441a8 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 @@ -498,7 +499,6 @@ SOCKET_KMODS += sockpfp SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds -SOCKET_KMODS += ksslf SOCKET_KMODS += datafilt # 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); |