1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * The ioctl interface for administrative commands. 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <sys/types.h> 34*0Sstevel@tonic-gate #include <sys/modctl.h> 35*0Sstevel@tonic-gate #include <sys/conf.h> 36*0Sstevel@tonic-gate #include <sys/stat.h> 37*0Sstevel@tonic-gate #include <sys/ddi.h> 38*0Sstevel@tonic-gate #include <sys/sunddi.h> 39*0Sstevel@tonic-gate #include <sys/kmem.h> 40*0Sstevel@tonic-gate #include <sys/errno.h> 41*0Sstevel@tonic-gate #include <sys/ksynch.h> 42*0Sstevel@tonic-gate #include <sys/file.h> 43*0Sstevel@tonic-gate #include <sys/open.h> 44*0Sstevel@tonic-gate #include <sys/cred.h> 45*0Sstevel@tonic-gate #include <sys/model.h> 46*0Sstevel@tonic-gate #include <sys/sysmacros.h> 47*0Sstevel@tonic-gate #include <sys/crypto/common.h> 48*0Sstevel@tonic-gate #include <sys/crypto/api.h> 49*0Sstevel@tonic-gate #include <sys/crypto/impl.h> 50*0Sstevel@tonic-gate #include <sys/crypto/sched_impl.h> 51*0Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h> 52*0Sstevel@tonic-gate #include <c2/audit.h> 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate /* 55*0Sstevel@tonic-gate * DDI entry points. 56*0Sstevel@tonic-gate */ 57*0Sstevel@tonic-gate static int cryptoadm_attach(dev_info_t *, ddi_attach_cmd_t); 58*0Sstevel@tonic-gate static int cryptoadm_detach(dev_info_t *, ddi_detach_cmd_t); 59*0Sstevel@tonic-gate static int cryptoadm_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 60*0Sstevel@tonic-gate static int cryptoadm_open(dev_t *, int, int, cred_t *); 61*0Sstevel@tonic-gate static int cryptoadm_close(dev_t, int, int, cred_t *); 62*0Sstevel@tonic-gate static int cryptoadm_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate extern void audit_cryptoadm(int, char *, crypto_mech_name_t *, uint_t, 65*0Sstevel@tonic-gate uint_t, uint32_t, int); 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * Module linkage. 68*0Sstevel@tonic-gate */ 69*0Sstevel@tonic-gate static struct cb_ops cbops = { 70*0Sstevel@tonic-gate cryptoadm_open, /* cb_open */ 71*0Sstevel@tonic-gate cryptoadm_close, /* cb_close */ 72*0Sstevel@tonic-gate nodev, /* cb_strategy */ 73*0Sstevel@tonic-gate nodev, /* cb_print */ 74*0Sstevel@tonic-gate nodev, /* cb_dump */ 75*0Sstevel@tonic-gate nodev, /* cb_read */ 76*0Sstevel@tonic-gate nodev, /* cb_write */ 77*0Sstevel@tonic-gate cryptoadm_ioctl, /* cb_ioctl */ 78*0Sstevel@tonic-gate nodev, /* cb_devmap */ 79*0Sstevel@tonic-gate nodev, /* cb_mmap */ 80*0Sstevel@tonic-gate nodev, /* cb_segmap */ 81*0Sstevel@tonic-gate nochpoll, /* cb_chpoll */ 82*0Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */ 83*0Sstevel@tonic-gate NULL, /* cb_streamtab */ 84*0Sstevel@tonic-gate D_MP, /* cb_flag */ 85*0Sstevel@tonic-gate CB_REV, /* cb_rev */ 86*0Sstevel@tonic-gate nodev, /* cb_aread */ 87*0Sstevel@tonic-gate nodev, /* cb_awrite */ 88*0Sstevel@tonic-gate }; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate static struct dev_ops devops = { 91*0Sstevel@tonic-gate DEVO_REV, /* devo_rev */ 92*0Sstevel@tonic-gate 0, /* devo_refcnt */ 93*0Sstevel@tonic-gate cryptoadm_getinfo, /* devo_getinfo */ 94*0Sstevel@tonic-gate nulldev, /* devo_identify */ 95*0Sstevel@tonic-gate nulldev, /* devo_probe */ 96*0Sstevel@tonic-gate cryptoadm_attach, /* devo_attach */ 97*0Sstevel@tonic-gate cryptoadm_detach, /* devo_detach */ 98*0Sstevel@tonic-gate nodev, /* devo_reset */ 99*0Sstevel@tonic-gate &cbops, /* devo_cb_ops */ 100*0Sstevel@tonic-gate NULL, /* devo_bus_ops */ 101*0Sstevel@tonic-gate NULL, /* devo_power */ 102*0Sstevel@tonic-gate }; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate static struct modldrv modldrv = { 105*0Sstevel@tonic-gate &mod_driverops, /* drv_modops */ 106*0Sstevel@tonic-gate "Cryptographic Administrative Interface v%I%", /* drv_linkinfo */ 107*0Sstevel@tonic-gate &devops, 108*0Sstevel@tonic-gate }; 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate static struct modlinkage modlinkage = { 111*0Sstevel@tonic-gate MODREV_1, /* ml_rev */ 112*0Sstevel@tonic-gate &modldrv, /* ml_linkage */ 113*0Sstevel@tonic-gate NULL 114*0Sstevel@tonic-gate }; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate static dev_info_t *cryptoadm_dip = NULL; 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* 119*0Sstevel@tonic-gate * DDI entry points. 120*0Sstevel@tonic-gate */ 121*0Sstevel@tonic-gate int 122*0Sstevel@tonic-gate _init(void) 123*0Sstevel@tonic-gate { 124*0Sstevel@tonic-gate return (mod_install(&modlinkage)); 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate int 128*0Sstevel@tonic-gate _fini(void) 129*0Sstevel@tonic-gate { 130*0Sstevel@tonic-gate return (mod_remove(&modlinkage)); 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate int 134*0Sstevel@tonic-gate _info(struct modinfo *modinfop) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate /* ARGSUSED */ 140*0Sstevel@tonic-gate static int 141*0Sstevel@tonic-gate cryptoadm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 142*0Sstevel@tonic-gate { 143*0Sstevel@tonic-gate switch (cmd) { 144*0Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO: 145*0Sstevel@tonic-gate *result = (void *)cryptoadm_dip; 146*0Sstevel@tonic-gate return (DDI_SUCCESS); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE: 149*0Sstevel@tonic-gate *result = (void *)0; 150*0Sstevel@tonic-gate return (DDI_SUCCESS); 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate return (DDI_FAILURE); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate static int 156*0Sstevel@tonic-gate cryptoadm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 157*0Sstevel@tonic-gate { 158*0Sstevel@tonic-gate if (cmd != DDI_ATTACH) { 159*0Sstevel@tonic-gate return (DDI_FAILURE); 160*0Sstevel@tonic-gate } 161*0Sstevel@tonic-gate if (ddi_get_instance(dip) != 0) { 162*0Sstevel@tonic-gate /* we only allow instance 0 to attach */ 163*0Sstevel@tonic-gate return (DDI_FAILURE); 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate /* create the minor node */ 167*0Sstevel@tonic-gate if (ddi_create_minor_node(dip, "cryptoadm", S_IFCHR, 0, 168*0Sstevel@tonic-gate DDI_PSEUDO, 0) != DDI_SUCCESS) { 169*0Sstevel@tonic-gate cmn_err(CE_WARN, "cryptoadm: failed creating minor node"); 170*0Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL); 171*0Sstevel@tonic-gate return (DDI_FAILURE); 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate cryptoadm_dip = dip; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate return (DDI_SUCCESS); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate static int 180*0Sstevel@tonic-gate cryptoadm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate if (cmd != DDI_DETACH) 183*0Sstevel@tonic-gate return (DDI_FAILURE); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate cryptoadm_dip = NULL; 186*0Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate return (DDI_SUCCESS); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate /* ARGSUSED */ 192*0Sstevel@tonic-gate static int 193*0Sstevel@tonic-gate cryptoadm_open(dev_t *devp, int flag, int otyp, cred_t *credp) 194*0Sstevel@tonic-gate { 195*0Sstevel@tonic-gate if (otyp != OTYP_CHR || cryptoadm_dip == NULL) 196*0Sstevel@tonic-gate return (ENXIO); 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate /* exclusive opens are not supported */ 199*0Sstevel@tonic-gate if (flag & FEXCL) 200*0Sstevel@tonic-gate return (ENOTSUP); 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate *devp = makedevice(getmajor(*devp), 0); 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate kcf_sched_start(); 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate return (0); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate /* ARGSUSED */ 210*0Sstevel@tonic-gate static int 211*0Sstevel@tonic-gate cryptoadm_close(dev_t dev, int flag, int otyp, cred_t *credp) 212*0Sstevel@tonic-gate { 213*0Sstevel@tonic-gate return (0); 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate /* 217*0Sstevel@tonic-gate * Returns TRUE if array of size MAXNAMELEN contains a '\0' 218*0Sstevel@tonic-gate * termination character, otherwise, it returns FALSE. 219*0Sstevel@tonic-gate */ 220*0Sstevel@tonic-gate static boolean_t 221*0Sstevel@tonic-gate null_terminated(char *array) 222*0Sstevel@tonic-gate { 223*0Sstevel@tonic-gate int i; 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate for (i = 0; i < MAXNAMELEN; i++) 226*0Sstevel@tonic-gate if (array[i] == '\0') 227*0Sstevel@tonic-gate return (B_TRUE); 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate return (B_FALSE); 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate /* 233*0Sstevel@tonic-gate * This ioctl returns an array of hardware providers. Each entry 234*0Sstevel@tonic-gate * contains a device name, device instance, and number of 235*0Sstevel@tonic-gate * supported mechanisms. 236*0Sstevel@tonic-gate */ 237*0Sstevel@tonic-gate /* ARGSUSED */ 238*0Sstevel@tonic-gate static int 239*0Sstevel@tonic-gate get_dev_list(dev_t dev, caddr_t arg, int mode, int *rval) 240*0Sstevel@tonic-gate { 241*0Sstevel@tonic-gate crypto_get_dev_list_t dev_list; 242*0Sstevel@tonic-gate crypto_dev_list_entry_t *entries; 243*0Sstevel@tonic-gate size_t copyout_size; 244*0Sstevel@tonic-gate uint_t count; 245*0Sstevel@tonic-gate ulong_t offset; 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate if (copyin(arg, &dev_list, sizeof (dev_list)) != 0) 248*0Sstevel@tonic-gate return (EFAULT); 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* get the list from the core module */ 251*0Sstevel@tonic-gate if (crypto_get_dev_list(&count, &entries) != 0) { 252*0Sstevel@tonic-gate dev_list.dl_return_value = CRYPTO_FAILED; 253*0Sstevel@tonic-gate if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) { 254*0Sstevel@tonic-gate return (EFAULT); 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate return (0); 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate /* check if buffer is too small */ 260*0Sstevel@tonic-gate if (count > dev_list.dl_dev_count) { 261*0Sstevel@tonic-gate dev_list.dl_dev_count = count; 262*0Sstevel@tonic-gate dev_list.dl_return_value = CRYPTO_BUFFER_TOO_SMALL; 263*0Sstevel@tonic-gate crypto_free_dev_list(entries, count); 264*0Sstevel@tonic-gate if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) { 265*0Sstevel@tonic-gate return (EFAULT); 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate return (0); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate dev_list.dl_dev_count = count; 271*0Sstevel@tonic-gate dev_list.dl_return_value = CRYPTO_SUCCESS; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate copyout_size = count * sizeof (crypto_dev_list_entry_t); 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate /* copyout the first stuff */ 276*0Sstevel@tonic-gate if (copyout(&dev_list, arg, sizeof (dev_list)) != 0) { 277*0Sstevel@tonic-gate crypto_free_dev_list(entries, count); 278*0Sstevel@tonic-gate return (EFAULT); 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate /* copyout entries */ 282*0Sstevel@tonic-gate offset = offsetof(crypto_get_dev_list_t, dl_devs); 283*0Sstevel@tonic-gate if (count > 0 && copyout(entries, arg + offset, copyout_size) != 0) { 284*0Sstevel@tonic-gate crypto_free_dev_list(entries, count); 285*0Sstevel@tonic-gate return (EFAULT); 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate crypto_free_dev_list(entries, count); 288*0Sstevel@tonic-gate return (0); 289*0Sstevel@tonic-gate } 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate /* 292*0Sstevel@tonic-gate * This ioctl returns a buffer containing the null terminated names 293*0Sstevel@tonic-gate * of software providers. 294*0Sstevel@tonic-gate */ 295*0Sstevel@tonic-gate /* ARGSUSED */ 296*0Sstevel@tonic-gate static int 297*0Sstevel@tonic-gate get_soft_list(dev_t dev, caddr_t arg, int mode, int *rval) 298*0Sstevel@tonic-gate { 299*0Sstevel@tonic-gate STRUCT_DECL(crypto_get_soft_list, soft_list); 300*0Sstevel@tonic-gate char *names; 301*0Sstevel@tonic-gate size_t len; 302*0Sstevel@tonic-gate uint_t count; 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate STRUCT_INIT(soft_list, mode); 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate if (copyin(arg, STRUCT_BUF(soft_list), STRUCT_SIZE(soft_list)) != 0) 307*0Sstevel@tonic-gate return (EFAULT); 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* get the list from the core module */ 310*0Sstevel@tonic-gate if (crypto_get_soft_list(&count, &names, &len) != 0) { 311*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_return_value, CRYPTO_FAILED); 312*0Sstevel@tonic-gate if (copyout(STRUCT_BUF(soft_list), arg, 313*0Sstevel@tonic-gate STRUCT_SIZE(soft_list)) != 0) { 314*0Sstevel@tonic-gate return (EFAULT); 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate return (0); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate /* check if buffer is too small */ 320*0Sstevel@tonic-gate if (len > STRUCT_FGET(soft_list, sl_soft_len)) { 321*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_soft_count, count); 322*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_soft_len, len); 323*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_return_value, 324*0Sstevel@tonic-gate CRYPTO_BUFFER_TOO_SMALL); 325*0Sstevel@tonic-gate kmem_free(names, len); 326*0Sstevel@tonic-gate if (copyout(STRUCT_BUF(soft_list), arg, 327*0Sstevel@tonic-gate STRUCT_SIZE(soft_list)) != 0) { 328*0Sstevel@tonic-gate return (EFAULT); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate return (0); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_soft_count, count); 334*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_soft_len, len); 335*0Sstevel@tonic-gate STRUCT_FSET(soft_list, sl_return_value, CRYPTO_SUCCESS); 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate if (count > 0 && copyout(names, 338*0Sstevel@tonic-gate STRUCT_FGETP(soft_list, sl_soft_names), len) != 0) { 339*0Sstevel@tonic-gate kmem_free(names, len); 340*0Sstevel@tonic-gate return (EFAULT); 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate kmem_free(names, len); 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate if (copyout(STRUCT_BUF(soft_list), arg, STRUCT_SIZE(soft_list)) != 0) { 345*0Sstevel@tonic-gate return (EFAULT); 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate return (0); 349*0Sstevel@tonic-gate } 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate /* 352*0Sstevel@tonic-gate * This ioctl returns an array of mechanisms supported by the 353*0Sstevel@tonic-gate * specified device. 354*0Sstevel@tonic-gate */ 355*0Sstevel@tonic-gate /* ARGSUSED */ 356*0Sstevel@tonic-gate static int 357*0Sstevel@tonic-gate get_dev_info(dev_t dev, caddr_t arg, int mode, int *rval) 358*0Sstevel@tonic-gate { 359*0Sstevel@tonic-gate crypto_get_dev_info_t dev_info; 360*0Sstevel@tonic-gate crypto_mech_name_t *entries; 361*0Sstevel@tonic-gate size_t copyout_size; 362*0Sstevel@tonic-gate uint_t count; 363*0Sstevel@tonic-gate ulong_t offset; 364*0Sstevel@tonic-gate char *dev_name; 365*0Sstevel@tonic-gate int rv; 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate if (copyin(arg, &dev_info, sizeof (dev_info)) != 0) 368*0Sstevel@tonic-gate return (EFAULT); 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate dev_name = dev_info.di_dev_name; 371*0Sstevel@tonic-gate /* make sure the device name is null terminated */ 372*0Sstevel@tonic-gate if (!null_terminated(dev_name)) { 373*0Sstevel@tonic-gate dev_info.di_return_value = CRYPTO_ARGUMENTS_BAD; 374*0Sstevel@tonic-gate if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) { 375*0Sstevel@tonic-gate return (EFAULT); 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate return (0); 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate /* get mechanism names from the core module */ 381*0Sstevel@tonic-gate if ((rv = crypto_get_dev_info(dev_name, dev_info.di_dev_instance, 382*0Sstevel@tonic-gate &count, &entries)) != CRYPTO_SUCCESS) { 383*0Sstevel@tonic-gate dev_info.di_return_value = rv; 384*0Sstevel@tonic-gate if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) { 385*0Sstevel@tonic-gate return (EFAULT); 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate return (0); 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate /* check if buffer is too small */ 391*0Sstevel@tonic-gate if (count > dev_info.di_count) { 392*0Sstevel@tonic-gate dev_info.di_count = count; 393*0Sstevel@tonic-gate dev_info.di_return_value = CRYPTO_BUFFER_TOO_SMALL; 394*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 395*0Sstevel@tonic-gate if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) { 396*0Sstevel@tonic-gate return (EFAULT); 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate return (0); 399*0Sstevel@tonic-gate } 400*0Sstevel@tonic-gate 401*0Sstevel@tonic-gate dev_info.di_count = count; 402*0Sstevel@tonic-gate dev_info.di_return_value = CRYPTO_SUCCESS; 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate copyout_size = count * sizeof (crypto_mech_name_t); 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate /* copyout the first stuff */ 407*0Sstevel@tonic-gate if (copyout(&dev_info, arg, sizeof (dev_info)) != 0) { 408*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 409*0Sstevel@tonic-gate return (EFAULT); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate /* copyout entries */ 413*0Sstevel@tonic-gate offset = offsetof(crypto_get_dev_info_t, di_list); 414*0Sstevel@tonic-gate if (copyout(entries, arg + offset, copyout_size) != 0) { 415*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 416*0Sstevel@tonic-gate return (EFAULT); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 419*0Sstevel@tonic-gate return (0); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate /* 423*0Sstevel@tonic-gate * This ioctl returns an array of mechanisms supported by the 424*0Sstevel@tonic-gate * specified cryptographic module. 425*0Sstevel@tonic-gate */ 426*0Sstevel@tonic-gate /* ARGSUSED */ 427*0Sstevel@tonic-gate static int 428*0Sstevel@tonic-gate get_soft_info(dev_t dev, caddr_t arg, int mode, int *rval) 429*0Sstevel@tonic-gate { 430*0Sstevel@tonic-gate crypto_get_soft_info_t soft_info; 431*0Sstevel@tonic-gate crypto_mech_name_t *entries; 432*0Sstevel@tonic-gate size_t copyout_size; 433*0Sstevel@tonic-gate uint_t count; 434*0Sstevel@tonic-gate ulong_t offset; 435*0Sstevel@tonic-gate char *name; 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate if (copyin(arg, &soft_info, sizeof (soft_info)) != 0) 438*0Sstevel@tonic-gate return (EFAULT); 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate name = soft_info.si_name; 441*0Sstevel@tonic-gate /* make sure the provider name is null terminated */ 442*0Sstevel@tonic-gate if (!null_terminated(name)) { 443*0Sstevel@tonic-gate soft_info.si_return_value = CRYPTO_ARGUMENTS_BAD; 444*0Sstevel@tonic-gate if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) { 445*0Sstevel@tonic-gate return (EFAULT); 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate return (0); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate /* get mechanism names from the core module */ 451*0Sstevel@tonic-gate if (crypto_get_soft_info(name, &count, &entries) != 0) { 452*0Sstevel@tonic-gate soft_info.si_return_value = CRYPTO_FAILED; 453*0Sstevel@tonic-gate if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) { 454*0Sstevel@tonic-gate return (EFAULT); 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate return (0); 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate /* check if buffer is too small */ 460*0Sstevel@tonic-gate if (count > soft_info.si_count) { 461*0Sstevel@tonic-gate soft_info.si_count = count; 462*0Sstevel@tonic-gate soft_info.si_return_value = CRYPTO_BUFFER_TOO_SMALL; 463*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 464*0Sstevel@tonic-gate if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) { 465*0Sstevel@tonic-gate return (EFAULT); 466*0Sstevel@tonic-gate } 467*0Sstevel@tonic-gate return (0); 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate soft_info.si_count = count; 471*0Sstevel@tonic-gate soft_info.si_return_value = CRYPTO_SUCCESS; 472*0Sstevel@tonic-gate copyout_size = count * sizeof (crypto_mech_name_t); 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate /* copyout the first stuff */ 475*0Sstevel@tonic-gate if (copyout(&soft_info, arg, sizeof (soft_info)) != 0) { 476*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 477*0Sstevel@tonic-gate return (EFAULT); 478*0Sstevel@tonic-gate } 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate /* copyout entries */ 481*0Sstevel@tonic-gate offset = offsetof(crypto_get_soft_info_t, si_list); 482*0Sstevel@tonic-gate if (copyout(entries, arg + offset, copyout_size) != 0) { 483*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 484*0Sstevel@tonic-gate return (EFAULT); 485*0Sstevel@tonic-gate } 486*0Sstevel@tonic-gate crypto_free_mech_list(entries, count); 487*0Sstevel@tonic-gate return (0); 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate /* 491*0Sstevel@tonic-gate * This ioctl disables mechanisms supported by the specified device. 492*0Sstevel@tonic-gate */ 493*0Sstevel@tonic-gate /* ARGSUSED */ 494*0Sstevel@tonic-gate static int 495*0Sstevel@tonic-gate load_dev_disabled(dev_t dev, caddr_t arg, int mode, int *rval) 496*0Sstevel@tonic-gate { 497*0Sstevel@tonic-gate crypto_load_dev_disabled_t dev_disabled; 498*0Sstevel@tonic-gate crypto_mech_name_t *entries; 499*0Sstevel@tonic-gate size_t size; 500*0Sstevel@tonic-gate ulong_t offset; 501*0Sstevel@tonic-gate uint_t count; 502*0Sstevel@tonic-gate uint_t instance; 503*0Sstevel@tonic-gate char *dev_name; 504*0Sstevel@tonic-gate uint32_t rv; 505*0Sstevel@tonic-gate int error = 0; 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate if (copyin(arg, &dev_disabled, sizeof (dev_disabled)) != 0) { 508*0Sstevel@tonic-gate error = EFAULT; 509*0Sstevel@tonic-gate goto out2; 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate dev_name = dev_disabled.dd_dev_name; 513*0Sstevel@tonic-gate /* make sure the device name is null terminated */ 514*0Sstevel@tonic-gate if (!null_terminated(dev_name)) { 515*0Sstevel@tonic-gate rv = CRYPTO_ARGUMENTS_BAD; 516*0Sstevel@tonic-gate goto out; 517*0Sstevel@tonic-gate } 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate count = dev_disabled.dd_count; 520*0Sstevel@tonic-gate instance = dev_disabled.dd_dev_instance; 521*0Sstevel@tonic-gate if (count == 0) { 522*0Sstevel@tonic-gate /* remove the entry */ 523*0Sstevel@tonic-gate if (crypto_load_dev_disabled(dev_name, instance, 0, NULL) != 0) 524*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 525*0Sstevel@tonic-gate else 526*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 527*0Sstevel@tonic-gate goto out; 528*0Sstevel@tonic-gate } 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate if (count > KCF_MAXMECHS) { 531*0Sstevel@tonic-gate rv = CRYPTO_ARGUMENTS_BAD; 532*0Sstevel@tonic-gate goto out; 533*0Sstevel@tonic-gate } 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate size = count * sizeof (crypto_mech_name_t); 536*0Sstevel@tonic-gate entries = kmem_alloc(size, KM_SLEEP); 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate offset = offsetof(crypto_load_dev_disabled_t, dd_list); 539*0Sstevel@tonic-gate if (copyin(arg + offset, entries, size) != 0) { 540*0Sstevel@tonic-gate kmem_free(entries, size); 541*0Sstevel@tonic-gate error = EFAULT; 542*0Sstevel@tonic-gate goto out2; 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate /* 'entries' consumed (but not freed) by crypto_load_dev_disabled() */ 546*0Sstevel@tonic-gate if (crypto_load_dev_disabled(dev_name, instance, count, entries) != 0) { 547*0Sstevel@tonic-gate kmem_free(entries, size); 548*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 549*0Sstevel@tonic-gate goto out; 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 552*0Sstevel@tonic-gate out: 553*0Sstevel@tonic-gate dev_disabled.dd_return_value = rv; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate if (copyout(&dev_disabled, arg, sizeof (dev_disabled)) != 0) { 556*0Sstevel@tonic-gate error = EFAULT; 557*0Sstevel@tonic-gate } 558*0Sstevel@tonic-gate out2: 559*0Sstevel@tonic-gate #ifdef C2_AUDIT 560*0Sstevel@tonic-gate if (audit_active) 561*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_LOAD_DEV_DISABLED, dev_name, entries, 562*0Sstevel@tonic-gate count, instance, rv, error); 563*0Sstevel@tonic-gate #endif 564*0Sstevel@tonic-gate return (error); 565*0Sstevel@tonic-gate } 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate /* 568*0Sstevel@tonic-gate * This ioctl disables mechanisms supported by the specified 569*0Sstevel@tonic-gate * cryptographic module. 570*0Sstevel@tonic-gate */ 571*0Sstevel@tonic-gate /* ARGSUSED */ 572*0Sstevel@tonic-gate static int 573*0Sstevel@tonic-gate load_soft_disabled(dev_t dev, caddr_t arg, int mode, int *rval) 574*0Sstevel@tonic-gate { 575*0Sstevel@tonic-gate crypto_load_soft_disabled_t soft_disabled; 576*0Sstevel@tonic-gate crypto_mech_name_t *entries; 577*0Sstevel@tonic-gate size_t size; 578*0Sstevel@tonic-gate uint_t count; 579*0Sstevel@tonic-gate ulong_t offset; 580*0Sstevel@tonic-gate char *name; 581*0Sstevel@tonic-gate uint32_t rv; 582*0Sstevel@tonic-gate int error = 0; 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate if (copyin(arg, &soft_disabled, sizeof (soft_disabled)) != 0) { 585*0Sstevel@tonic-gate error = EFAULT; 586*0Sstevel@tonic-gate goto out2; 587*0Sstevel@tonic-gate } 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate name = soft_disabled.sd_name; 590*0Sstevel@tonic-gate /* make sure the name is null terminated */ 591*0Sstevel@tonic-gate if (!null_terminated(name)) { 592*0Sstevel@tonic-gate soft_disabled.sd_return_value = CRYPTO_ARGUMENTS_BAD; 593*0Sstevel@tonic-gate if (copyout(&soft_disabled, arg, sizeof (soft_disabled)) != 0) { 594*0Sstevel@tonic-gate return (EFAULT); 595*0Sstevel@tonic-gate } 596*0Sstevel@tonic-gate return (0); 597*0Sstevel@tonic-gate } 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate count = soft_disabled.sd_count; 600*0Sstevel@tonic-gate if (count == 0) { 601*0Sstevel@tonic-gate /* remove the entry */ 602*0Sstevel@tonic-gate if (crypto_load_soft_disabled(name, 0, NULL) != 0) { 603*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 604*0Sstevel@tonic-gate } else { 605*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate goto out; 608*0Sstevel@tonic-gate } 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate if (count > KCF_MAXMECHS) { 611*0Sstevel@tonic-gate rv = CRYPTO_ARGUMENTS_BAD; 612*0Sstevel@tonic-gate goto out; 613*0Sstevel@tonic-gate } 614*0Sstevel@tonic-gate 615*0Sstevel@tonic-gate size = count * sizeof (crypto_mech_name_t); 616*0Sstevel@tonic-gate entries = kmem_alloc(size, KM_SLEEP); 617*0Sstevel@tonic-gate 618*0Sstevel@tonic-gate offset = offsetof(crypto_load_soft_disabled_t, sd_list); 619*0Sstevel@tonic-gate if (copyin(arg + offset, entries, size) != 0) { 620*0Sstevel@tonic-gate kmem_free(entries, size); 621*0Sstevel@tonic-gate error = EFAULT; 622*0Sstevel@tonic-gate goto out2; 623*0Sstevel@tonic-gate } 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate /* 'entries' is consumed by crypto_load_soft_disabled() */ 626*0Sstevel@tonic-gate if (crypto_load_soft_disabled(name, count, entries) != 0) { 627*0Sstevel@tonic-gate kmem_free(entries, size); 628*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 629*0Sstevel@tonic-gate goto out; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 632*0Sstevel@tonic-gate out: 633*0Sstevel@tonic-gate soft_disabled.sd_return_value = rv; 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate if (copyout(&soft_disabled, arg, sizeof (soft_disabled)) != 0) { 636*0Sstevel@tonic-gate error = EFAULT; 637*0Sstevel@tonic-gate } 638*0Sstevel@tonic-gate out2: 639*0Sstevel@tonic-gate #ifdef C2_AUDIT 640*0Sstevel@tonic-gate if (audit_active) 641*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_LOAD_SOFT_DISABLED, name, entries, 642*0Sstevel@tonic-gate count, 0, rv, error); 643*0Sstevel@tonic-gate #endif 644*0Sstevel@tonic-gate return (error); 645*0Sstevel@tonic-gate } 646*0Sstevel@tonic-gate 647*0Sstevel@tonic-gate /* 648*0Sstevel@tonic-gate * This ioctl loads the supported mechanisms of the specfied cryptographic 649*0Sstevel@tonic-gate * module. This is so, at boot time, all software providers do not 650*0Sstevel@tonic-gate * have to be opened in order to cause them to register their 651*0Sstevel@tonic-gate * supported mechanisms. 652*0Sstevel@tonic-gate */ 653*0Sstevel@tonic-gate /* ARGSUSED */ 654*0Sstevel@tonic-gate static int 655*0Sstevel@tonic-gate load_soft_config(dev_t dev, caddr_t arg, int mode, int *rval) 656*0Sstevel@tonic-gate { 657*0Sstevel@tonic-gate crypto_load_soft_config_t soft_config; 658*0Sstevel@tonic-gate crypto_mech_name_t *entries; 659*0Sstevel@tonic-gate size_t size; 660*0Sstevel@tonic-gate uint_t count; 661*0Sstevel@tonic-gate ulong_t offset; 662*0Sstevel@tonic-gate char *name; 663*0Sstevel@tonic-gate uint32_t rv; 664*0Sstevel@tonic-gate int error = 0; 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate if (copyin(arg, &soft_config, sizeof (soft_config)) != 0) { 667*0Sstevel@tonic-gate error = EFAULT; 668*0Sstevel@tonic-gate goto out2; 669*0Sstevel@tonic-gate } 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate name = soft_config.sc_name; 672*0Sstevel@tonic-gate /* make sure the name is null terminated */ 673*0Sstevel@tonic-gate if (!null_terminated(name)) { 674*0Sstevel@tonic-gate soft_config.sc_return_value = CRYPTO_ARGUMENTS_BAD; 675*0Sstevel@tonic-gate if (copyout(&soft_config, arg, sizeof (soft_config)) != 0) { 676*0Sstevel@tonic-gate return (EFAULT); 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate return (0); 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate count = soft_config.sc_count; 682*0Sstevel@tonic-gate if (count == 0) { 683*0Sstevel@tonic-gate if (crypto_load_soft_config(name, 0, NULL) != 0) { 684*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 685*0Sstevel@tonic-gate } else { 686*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 687*0Sstevel@tonic-gate } 688*0Sstevel@tonic-gate goto out; 689*0Sstevel@tonic-gate } 690*0Sstevel@tonic-gate 691*0Sstevel@tonic-gate if (count > KCF_MAXMECHS) { 692*0Sstevel@tonic-gate rv = CRYPTO_ARGUMENTS_BAD; 693*0Sstevel@tonic-gate goto out; 694*0Sstevel@tonic-gate } 695*0Sstevel@tonic-gate 696*0Sstevel@tonic-gate size = count * sizeof (crypto_mech_name_t); 697*0Sstevel@tonic-gate entries = kmem_alloc(size, KM_SLEEP); 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate offset = offsetof(crypto_load_soft_config_t, sc_list); 700*0Sstevel@tonic-gate if (copyin(arg + offset, entries, size) != 0) { 701*0Sstevel@tonic-gate kmem_free(entries, size); 702*0Sstevel@tonic-gate error = EFAULT; 703*0Sstevel@tonic-gate goto out2; 704*0Sstevel@tonic-gate } 705*0Sstevel@tonic-gate 706*0Sstevel@tonic-gate /* 707*0Sstevel@tonic-gate * 'entries' is consumed (but not freed) by 708*0Sstevel@tonic-gate * crypto_load_soft_config() 709*0Sstevel@tonic-gate */ 710*0Sstevel@tonic-gate if (crypto_load_soft_config(name, count, entries) != 0) { 711*0Sstevel@tonic-gate kmem_free(entries, size); 712*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 713*0Sstevel@tonic-gate goto out; 714*0Sstevel@tonic-gate } 715*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 716*0Sstevel@tonic-gate out: 717*0Sstevel@tonic-gate soft_config.sc_return_value = rv; 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate if (copyout(&soft_config, arg, sizeof (soft_config)) != 0) { 720*0Sstevel@tonic-gate error = EFAULT; 721*0Sstevel@tonic-gate } 722*0Sstevel@tonic-gate out2: 723*0Sstevel@tonic-gate #ifdef C2_AUDIT 724*0Sstevel@tonic-gate if (audit_active) 725*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_LOAD_SOFT_CONFIG, name, entries, count, 726*0Sstevel@tonic-gate 0, rv, error); 727*0Sstevel@tonic-gate #endif 728*0Sstevel@tonic-gate return (error); 729*0Sstevel@tonic-gate } 730*0Sstevel@tonic-gate 731*0Sstevel@tonic-gate /* 732*0Sstevel@tonic-gate * This ioctl unloads the specfied cryptographic module and removes 733*0Sstevel@tonic-gate * its table of supported mechanisms. 734*0Sstevel@tonic-gate */ 735*0Sstevel@tonic-gate /* ARGSUSED */ 736*0Sstevel@tonic-gate static int 737*0Sstevel@tonic-gate unload_soft_module(dev_t dev, caddr_t arg, int mode, int *rval) 738*0Sstevel@tonic-gate { 739*0Sstevel@tonic-gate crypto_unload_soft_module_t unload_soft_module; 740*0Sstevel@tonic-gate char *name; 741*0Sstevel@tonic-gate uint32_t rv; 742*0Sstevel@tonic-gate int error = 0; 743*0Sstevel@tonic-gate 744*0Sstevel@tonic-gate if (copyin(arg, &unload_soft_module, 745*0Sstevel@tonic-gate sizeof (unload_soft_module)) != 0) { 746*0Sstevel@tonic-gate error = EFAULT; 747*0Sstevel@tonic-gate goto out2; 748*0Sstevel@tonic-gate } 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate name = unload_soft_module.sm_name; 751*0Sstevel@tonic-gate /* make sure the name is null terminated */ 752*0Sstevel@tonic-gate if (!null_terminated(name)) { 753*0Sstevel@tonic-gate unload_soft_module.sm_return_value = CRYPTO_ARGUMENTS_BAD; 754*0Sstevel@tonic-gate if (copyout(&unload_soft_module, arg, 755*0Sstevel@tonic-gate sizeof (unload_soft_module)) != 0) { 756*0Sstevel@tonic-gate return (EFAULT); 757*0Sstevel@tonic-gate } 758*0Sstevel@tonic-gate return (0); 759*0Sstevel@tonic-gate } 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate rv = crypto_unload_soft_module(name); 762*0Sstevel@tonic-gate out: 763*0Sstevel@tonic-gate unload_soft_module.sm_return_value = rv; 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate if (copyout(&unload_soft_module, arg, 766*0Sstevel@tonic-gate sizeof (unload_soft_module)) != 0) { 767*0Sstevel@tonic-gate error = EFAULT; 768*0Sstevel@tonic-gate } 769*0Sstevel@tonic-gate out2: 770*0Sstevel@tonic-gate #ifdef C2_AUDIT 771*0Sstevel@tonic-gate if (audit_active) 772*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_UNLOAD_SOFT_MODULE, name, NULL, 0, 0, 773*0Sstevel@tonic-gate rv, error); 774*0Sstevel@tonic-gate #endif 775*0Sstevel@tonic-gate 776*0Sstevel@tonic-gate return (error); 777*0Sstevel@tonic-gate } 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate /* 780*0Sstevel@tonic-gate * This ioctl loads a door descriptor into the kernel. The descriptor 781*0Sstevel@tonic-gate * is used for module verification. 782*0Sstevel@tonic-gate */ 783*0Sstevel@tonic-gate /* ARGSUSED */ 784*0Sstevel@tonic-gate static int 785*0Sstevel@tonic-gate load_door(dev_t dev, caddr_t arg, int mode, int *rval) 786*0Sstevel@tonic-gate { 787*0Sstevel@tonic-gate crypto_load_door_t load_door; 788*0Sstevel@tonic-gate uint32_t rv; 789*0Sstevel@tonic-gate int error = 0; 790*0Sstevel@tonic-gate 791*0Sstevel@tonic-gate if (copyin(arg, &load_door, sizeof (crypto_load_door_t)) != 0) { 792*0Sstevel@tonic-gate error = EFAULT; 793*0Sstevel@tonic-gate goto out2; 794*0Sstevel@tonic-gate } 795*0Sstevel@tonic-gate 796*0Sstevel@tonic-gate if (crypto_load_door(load_door.ld_did) != 0) { 797*0Sstevel@tonic-gate rv = CRYPTO_FAILED; 798*0Sstevel@tonic-gate goto out; 799*0Sstevel@tonic-gate } 800*0Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 801*0Sstevel@tonic-gate out: 802*0Sstevel@tonic-gate load_door.ld_return_value = rv; 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate if (copyout(&load_door, arg, sizeof (crypto_load_door_t)) != 0) 805*0Sstevel@tonic-gate error = EFAULT; 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate out2: 808*0Sstevel@tonic-gate #ifdef C2_AUDIT 809*0Sstevel@tonic-gate if (audit_active) 810*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_LOAD_DOOR, NULL, NULL, 811*0Sstevel@tonic-gate 0, 0, rv, error); 812*0Sstevel@tonic-gate #endif 813*0Sstevel@tonic-gate return (error); 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate static int 817*0Sstevel@tonic-gate cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, 818*0Sstevel@tonic-gate int *rval) 819*0Sstevel@tonic-gate { 820*0Sstevel@tonic-gate int error; 821*0Sstevel@tonic-gate #define ARG ((caddr_t)arg) 822*0Sstevel@tonic-gate 823*0Sstevel@tonic-gate switch (cmd) { 824*0Sstevel@tonic-gate case CRYPTO_LOAD_DEV_DISABLED: 825*0Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_DISABLED: 826*0Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_CONFIG: 827*0Sstevel@tonic-gate case CRYPTO_UNLOAD_SOFT_MODULE: 828*0Sstevel@tonic-gate case CRYPTO_POOL_CREATE: 829*0Sstevel@tonic-gate case CRYPTO_POOL_WAIT: 830*0Sstevel@tonic-gate case CRYPTO_POOL_RUN: 831*0Sstevel@tonic-gate case CRYPTO_LOAD_DOOR: 832*0Sstevel@tonic-gate if ((error = drv_priv(c)) != 0) 833*0Sstevel@tonic-gate return (error); 834*0Sstevel@tonic-gate default: 835*0Sstevel@tonic-gate break; 836*0Sstevel@tonic-gate } 837*0Sstevel@tonic-gate 838*0Sstevel@tonic-gate switch (cmd) { 839*0Sstevel@tonic-gate case CRYPTO_GET_DEV_LIST: 840*0Sstevel@tonic-gate return (get_dev_list(dev, ARG, mode, rval)); 841*0Sstevel@tonic-gate 842*0Sstevel@tonic-gate case CRYPTO_GET_DEV_INFO: 843*0Sstevel@tonic-gate return (get_dev_info(dev, ARG, mode, rval)); 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate case CRYPTO_GET_SOFT_LIST: 846*0Sstevel@tonic-gate return (get_soft_list(dev, ARG, mode, rval)); 847*0Sstevel@tonic-gate 848*0Sstevel@tonic-gate case CRYPTO_GET_SOFT_INFO: 849*0Sstevel@tonic-gate return (get_soft_info(dev, ARG, mode, rval)); 850*0Sstevel@tonic-gate 851*0Sstevel@tonic-gate case CRYPTO_LOAD_DEV_DISABLED: 852*0Sstevel@tonic-gate return (load_dev_disabled(dev, ARG, mode, rval)); 853*0Sstevel@tonic-gate 854*0Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_DISABLED: 855*0Sstevel@tonic-gate return (load_soft_disabled(dev, ARG, mode, rval)); 856*0Sstevel@tonic-gate 857*0Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_CONFIG: 858*0Sstevel@tonic-gate return (load_soft_config(dev, ARG, mode, rval)); 859*0Sstevel@tonic-gate 860*0Sstevel@tonic-gate case CRYPTO_UNLOAD_SOFT_MODULE: 861*0Sstevel@tonic-gate return (unload_soft_module(dev, ARG, mode, rval)); 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate case CRYPTO_POOL_CREATE: 864*0Sstevel@tonic-gate /* 865*0Sstevel@tonic-gate * The framework allocates and initializes the pool. 866*0Sstevel@tonic-gate * So, this is a no op. We are keeping this ioctl around 867*0Sstevel@tonic-gate * to be used for any future threadpool related work. 868*0Sstevel@tonic-gate */ 869*0Sstevel@tonic-gate #ifdef C2_AUDIT 870*0Sstevel@tonic-gate if (audit_active) 871*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_POOL_CREATE, NULL, NULL, 872*0Sstevel@tonic-gate 0, 0, 0, 0); 873*0Sstevel@tonic-gate #endif 874*0Sstevel@tonic-gate return (0); 875*0Sstevel@tonic-gate 876*0Sstevel@tonic-gate case CRYPTO_POOL_WAIT: { 877*0Sstevel@tonic-gate int nthrs = 0, err; 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate if ((err = kcf_svc_wait(&nthrs)) == 0) { 880*0Sstevel@tonic-gate if (copyout((caddr_t)&nthrs, ARG, sizeof (int)) 881*0Sstevel@tonic-gate == -1) 882*0Sstevel@tonic-gate err = EFAULT; 883*0Sstevel@tonic-gate } 884*0Sstevel@tonic-gate #ifdef C2_AUDIT 885*0Sstevel@tonic-gate if (audit_active) 886*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_POOL_WAIT, NULL, NULL, 887*0Sstevel@tonic-gate 0, 0, 0, err); 888*0Sstevel@tonic-gate #endif 889*0Sstevel@tonic-gate return (err); 890*0Sstevel@tonic-gate } 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate case CRYPTO_POOL_RUN: { 893*0Sstevel@tonic-gate int err; 894*0Sstevel@tonic-gate 895*0Sstevel@tonic-gate err = kcf_svc_do_run(); 896*0Sstevel@tonic-gate #ifdef C2_AUDIT 897*0Sstevel@tonic-gate if (audit_active) 898*0Sstevel@tonic-gate audit_cryptoadm(CRYPTO_POOL_RUN, NULL, NULL, 899*0Sstevel@tonic-gate 0, 0, 0, err); 900*0Sstevel@tonic-gate #endif 901*0Sstevel@tonic-gate return (err); 902*0Sstevel@tonic-gate } 903*0Sstevel@tonic-gate 904*0Sstevel@tonic-gate case CRYPTO_LOAD_DOOR: 905*0Sstevel@tonic-gate return (load_door(dev, ARG, mode, rval)); 906*0Sstevel@tonic-gate } 907*0Sstevel@tonic-gate return (EINVAL); 908*0Sstevel@tonic-gate } 909