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