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