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 #include <fcntl.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <strings.h> 31 #include <unistd.h> 32 #include <locale.h> 33 #include <libgen.h> 34 #include <sys/types.h> 35 #include <zone.h> 36 #include <sys/crypto/ioctladmin.h> 37 #include <cryptoutil.h> 38 #include "cryptoadm.h" 39 40 #define REQ_ARG_CNT 2 41 42 /* subcommand index */ 43 enum subcommand_index { 44 CRYPTO_LIST, 45 CRYPTO_DISABLE, 46 CRYPTO_ENABLE, 47 CRYPTO_INSTALL, 48 CRYPTO_UNINSTALL, 49 CRYPTO_UNLOAD, 50 CRYPTO_REFRESH, 51 CRYPTO_START, 52 CRYPTO_STOP, 53 CRYPTO_HELP }; 54 55 /* 56 * TRANSLATION_NOTE 57 * Command keywords are not to be translated. 58 */ 59 static char *cmd_table[] = { 60 "list", 61 "disable", 62 "enable", 63 "install", 64 "uninstall", 65 "unload", 66 "refresh", 67 "start", 68 "stop", 69 "--help" }; 70 71 /* provider type */ 72 enum provider_type_index { 73 PROV_UEF_LIB, 74 PROV_KEF_SOFT, 75 PROV_KEF_HARD, 76 METASLOT, 77 PROV_BADNAME }; 78 79 typedef struct { 80 char cp_name[MAXPATHLEN]; 81 enum provider_type_index cp_type; 82 } cryptoadm_provider_t; 83 84 /* 85 * TRANSLATION_NOTE 86 * Operand keywords are not to be translated. 87 */ 88 static const char *KN_PROVIDER = "provider="; 89 static const char *KN_MECH = "mechanism="; 90 static const char *KN_ALL = "all"; 91 static const char *KN_TOKEN = "token="; 92 static const char *KN_SLOT = "slot="; 93 static const char *KN_DEFAULT_KS = "default-keystore"; 94 static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate"; 95 96 /* static variables */ 97 static boolean_t allflag = B_FALSE; 98 static boolean_t rndflag = B_FALSE; 99 static mechlist_t *mecharglist = NULL; 100 101 /* static functions */ 102 static void usage(void); 103 static int get_provider_type(char *); 104 static int process_mech_operands(int, char **, boolean_t); 105 static int do_list(int, char **); 106 static int do_disable(int, char **); 107 static int do_enable(int, char **); 108 static int do_install(int, char **); 109 static int do_uninstall(int, char **); 110 static int do_unload(int, char **); 111 static int do_refresh(int); 112 static int do_start(int); 113 static int do_stop(int); 114 static int list_simple_for_all(boolean_t); 115 static int list_mechlist_for_all(boolean_t); 116 static int list_policy_for_all(void); 117 118 int 119 main(int argc, char *argv[]) 120 { 121 char *subcmd; 122 int cmdnum; 123 int cmd_index = 0; 124 int rc = SUCCESS; 125 126 (void) setlocale(LC_ALL, ""); 127 128 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 129 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 130 #endif 131 (void) textdomain(TEXT_DOMAIN); 132 133 cryptodebug_init(basename(argv[0])); 134 135 if (argc < REQ_ARG_CNT) { 136 usage(); 137 return (ERROR_USAGE); 138 } 139 140 /* get the subcommand index */ 141 cmd_index = 0; 142 subcmd = argv[1]; 143 cmdnum = sizeof (cmd_table)/sizeof (cmd_table[0]); 144 145 while ((cmd_index < cmdnum) && 146 (strcmp(subcmd, cmd_table[cmd_index]) != 0)) { 147 cmd_index++; 148 } 149 if (cmd_index >= cmdnum) { 150 usage(); 151 return (ERROR_USAGE); 152 } 153 154 /* do the subcommand */ 155 switch (cmd_index) { 156 case CRYPTO_LIST: 157 rc = do_list(argc, argv); 158 break; 159 case CRYPTO_DISABLE: 160 rc = do_disable(argc, argv); 161 break; 162 case CRYPTO_ENABLE: 163 rc = do_enable(argc, argv); 164 break; 165 case CRYPTO_INSTALL: 166 rc = do_install(argc, argv); 167 break; 168 case CRYPTO_UNINSTALL: 169 rc = do_uninstall(argc, argv); 170 break; 171 case CRYPTO_UNLOAD: 172 rc = do_unload(argc, argv); 173 break; 174 case CRYPTO_REFRESH: 175 rc = do_refresh(argc); 176 break; 177 case CRYPTO_START: 178 rc = do_start(argc); 179 break; 180 case CRYPTO_STOP: 181 rc = do_stop(argc); 182 break; 183 case CRYPTO_HELP: 184 usage(); 185 rc = SUCCESS; 186 break; 187 default: /* should not come here */ 188 usage(); 189 rc = ERROR_USAGE; 190 break; 191 } 192 return (rc); 193 } 194 195 196 static void 197 usage(void) 198 { 199 /* 200 * TRANSLATION_NOTE 201 * Command usage is not to be translated. Only the word "Usage:" 202 * along with localized expressions indicating what kind of value 203 * is expected for arguments. 204 */ 205 (void) fprintf(stderr, gettext("Usage:\n")); 206 (void) fprintf(stderr, 207 " cryptoadm list [-mpv] [provider=<%s> | metaslot]" 208 " [mechanism=<%s>]\n", 209 gettext("provider-name"), gettext("mechanism-list")); 210 (void) fprintf(stderr, 211 " cryptoadm list fips-140\n"); 212 (void) fprintf(stderr, 213 " cryptoadm disable provider=<%s>" 214 " mechanism=<%s> | random | all\n", 215 gettext("provider-name"), gettext("mechanism-list")); 216 (void) fprintf(stderr, 217 " cryptoadm disable metaslot" 218 " [auto-key-migrate] [mechanism=<%s>]\n", 219 gettext("mechanism-list")); 220 (void) fprintf(stderr, 221 " cryptoadm disable fips-140\n"); 222 (void) fprintf(stderr, 223 " cryptoadm enable provider=<%s>" 224 " mechanism=<%s> | random | all\n", 225 gettext("provider-name"), gettext("mechanism-list")); 226 (void) fprintf(stderr, 227 " cryptoadm enable metaslot [mechanism=<%s>]" 228 " [[token=<%s>] [slot=<%s>]" 229 " | [default-keystore]] | [auto-key-migrate]\n", 230 gettext("mechanism-list"), gettext("token-label"), 231 gettext("slot-description")); 232 (void) fprintf(stderr, 233 " cryptoadm enable fips-140\n"); 234 (void) fprintf(stderr, 235 " cryptoadm install provider=<%s>\n", 236 gettext("provider-name")); 237 (void) fprintf(stderr, 238 " cryptoadm install provider=<%s> [mechanism=<%s>]\n", 239 gettext("provider-name"), gettext("mechanism-list")); 240 (void) fprintf(stderr, 241 " cryptoadm uninstall provider=<%s>\n", 242 gettext("provider-name")); 243 (void) fprintf(stderr, 244 " cryptoadm unload provider=<%s>\n", 245 gettext("provider-name")); 246 (void) fprintf(stderr, 247 " cryptoadm refresh\n" 248 " cryptoadm start\n" 249 " cryptoadm stop\n" 250 " cryptoadm --help\n"); 251 } 252 253 254 /* 255 * Get the provider type. This function returns 256 * - PROV_UEF_LIB if provname contains an absolute path name 257 * - PROV_KEF_SOFT if provname is a base name only (e.g., "aes"). 258 * - PROV_KEF_HARD if provname contains one slash only and the slash is not 259 * the 1st character (e.g., "mca/0"). 260 * - PROV_BADNAME otherwise. 261 */ 262 static int 263 get_provider_type(char *provname) 264 { 265 char *pslash1; 266 char *pslash2; 267 268 if (provname == NULL) { 269 return (FAILURE); 270 } 271 272 if (provname[0] == '/') { 273 return (PROV_UEF_LIB); 274 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) { 275 /* no slash */ 276 return (PROV_KEF_SOFT); 277 } else { 278 pslash2 = strrchr(provname, SEP_SLASH); 279 if (pslash1 == pslash2) { 280 return (PROV_KEF_HARD); 281 } else { 282 return (PROV_BADNAME); 283 } 284 } 285 } 286 287 /* 288 * Get the provider structure. This function returns NULL if no valid 289 * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned. 290 * If provider= is found but has no argument, then a cryptoadm_provider_t 291 * with cp_type = PROV_BADNAME is returned. 292 */ 293 static cryptoadm_provider_t * 294 get_provider(int argc, char **argv) 295 { 296 int c = 0; 297 boolean_t found = B_FALSE; 298 cryptoadm_provider_t *provider = NULL; 299 char *provstr = NULL, *savstr; 300 boolean_t is_metaslot = B_FALSE; 301 302 while (!found && ++c < argc) { 303 if (strncmp(argv[c], METASLOT_KEYWORD, 304 strlen(METASLOT_KEYWORD)) == 0) { 305 is_metaslot = B_TRUE; 306 found = B_TRUE; 307 } else if (strncmp(argv[c], KN_PROVIDER, 308 strlen(KN_PROVIDER)) == 0 && 309 strlen(argv[c]) > strlen(KN_PROVIDER)) { 310 if ((provstr = strdup(argv[c])) == NULL) { 311 int err = errno; 312 /* 313 * TRANSLATION_NOTE 314 * "get_provider" is a function name and should 315 * not be translated. 316 */ 317 cryptoerror(LOG_STDERR, "get_provider: %s.", 318 strerror(err)); 319 return (NULL); 320 } 321 found = B_TRUE; 322 } 323 } 324 if (!found) 325 return (NULL); 326 327 provider = malloc(sizeof (cryptoadm_provider_t)); 328 if (provider == NULL) { 329 cryptoerror(LOG_STDERR, gettext("out of memory.")); 330 if (provstr) { 331 free(provstr); 332 } 333 return (NULL); 334 } 335 336 if (is_metaslot) { 337 (void) strlcpy(provider->cp_name, METASLOT_KEYWORD, 338 strlen(METASLOT_KEYWORD)); 339 provider->cp_type = METASLOT; 340 } else { 341 342 savstr = provstr; 343 (void) strtok(provstr, "="); 344 provstr = strtok(NULL, "="); 345 if (provstr == NULL) { 346 cryptoerror(LOG_STDERR, gettext("bad provider name.")); 347 provider->cp_type = PROV_BADNAME; 348 free(savstr); 349 return (provider); 350 } 351 352 (void) strlcpy(provider->cp_name, provstr, 353 sizeof (provider->cp_name)); 354 provider->cp_type = get_provider_type(provider->cp_name); 355 356 free(savstr); 357 } 358 return (provider); 359 } 360 361 /* 362 * Process the "feature" operands. 363 * 364 * "argc" and "argv" contain values specified on the command line. 365 * All other arguments are used for returning parsing results. 366 * If any of these arguments are NULL, that keyword is not expected, 367 * and FAILURE will be returned. 368 */ 369 static int 370 process_metaslot_operands(int argc, char **argv, char **meta_ks_token, 371 char **meta_ks_slot, boolean_t *use_default, 372 boolean_t *auto_key_migrate_flag) 373 { 374 int c = 2; 375 int rc = SUCCESS; 376 377 while (++c < argc) { 378 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) && 379 strlen(argv[c]) > strlen(KN_MECH)) { 380 381 /* process mechanism operands */ 382 if ((rc = process_mech_operands(argc, argv, B_TRUE)) 383 != SUCCESS) { 384 goto finish; 385 } 386 387 } else if ((strncmp(argv[c], KN_TOKEN, 388 strlen(KN_TOKEN)) == 0) && 389 strlen(argv[c]) > strlen(KN_TOKEN)) { 390 if ((meta_ks_token) && (strtok(argv[c], "=") != NULL)) { 391 char *tmp; 392 if ((tmp = strtok(NULL, "=")) != NULL) { 393 *meta_ks_token = strdup(tmp); 394 } else { 395 return (FAILURE); 396 } 397 } else { 398 return (FAILURE); 399 } 400 401 } else if ((strncmp(argv[c], KN_SLOT, 402 strlen(KN_SLOT)) == 0) && 403 strlen(argv[c]) > strlen(KN_SLOT)) { 404 405 if ((meta_ks_slot) && (strtok(argv[c], "=") != NULL)) { 406 char *tmp; 407 if ((tmp = strtok(NULL, "=")) != NULL) { 408 *meta_ks_slot = strdup(tmp); 409 } else { 410 return (FAILURE); 411 } 412 } else { 413 return (FAILURE); 414 } 415 416 } else if (strncmp(argv[c], KN_DEFAULT_KS, 417 strlen(KN_DEFAULT_KS)) == 0) { 418 419 if (use_default) { 420 *use_default = B_TRUE; 421 } else { 422 return (FAILURE); 423 } 424 } else if (strncmp(argv[c], KN_AUTO_KEY_MIGRATE, 425 strlen(KN_AUTO_KEY_MIGRATE)) == 0) { 426 427 if (auto_key_migrate_flag) { 428 *auto_key_migrate_flag = B_TRUE; 429 } else { 430 return (FAILURE); 431 } 432 } else { 433 return (FAILURE); 434 } 435 } 436 finish: 437 return (rc); 438 } 439 440 /* 441 * Process the "feature" operands. 442 */ 443 static int 444 process_feature_operands(int argc, char **argv) 445 { 446 int c = 2; 447 448 while (++c < argc) { 449 if (strcmp(argv[c], KN_ALL) == 0) { 450 allflag = B_TRUE; 451 rndflag = B_TRUE; /* all includes random also. */ 452 } else if (strcmp(argv[c], RANDOM) == 0) { 453 rndflag = B_TRUE; 454 } 455 } 456 return (SUCCESS); 457 } 458 459 /* 460 * Process the mechanism operands for the disable, enable and install 461 * subcommands. This function sets the static variable allflag to be B_TRUE 462 * if the keyword "all" is specified, otherwise builds a link list of the 463 * mechanism operands and save it in the static variable mecharglist. 464 * 465 * This function returns 466 * ERROR_USAGE: mechanism operand is missing. 467 * FAILURE: out of memory. 468 * SUCCESS: otherwise. 469 */ 470 static int 471 process_mech_operands(int argc, char **argv, boolean_t quiet) 472 { 473 mechlist_t *pmech; 474 mechlist_t *pcur = NULL; 475 mechlist_t *phead = NULL; 476 boolean_t found = B_FALSE; 477 char *mechliststr = NULL; 478 char *curmech = NULL; 479 int c = -1; 480 int rc = SUCCESS; 481 482 while (!found && ++c < argc) { 483 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) && 484 strlen(argv[c]) > strlen(KN_MECH)) { 485 found = B_TRUE; 486 } 487 } 488 if (!found) { 489 if (!quiet) 490 /* 491 * TRANSLATION_NOTE 492 * "mechanism" could be either a literal keyword 493 * and hence not to be translated, or a descriptive 494 * word and translatable. A choice was made to 495 * view it as a literal keyword. 496 */ 497 cryptoerror(LOG_STDERR, 498 gettext("the %s operand is missing.\n"), 499 "mechanism"); 500 return (ERROR_USAGE); 501 } 502 (void) strtok(argv[c], "="); 503 mechliststr = strtok(NULL, "="); 504 505 if (strcmp(mechliststr, "all") == 0) { 506 allflag = B_TRUE; 507 mecharglist = NULL; 508 return (SUCCESS); 509 } 510 511 curmech = strtok(mechliststr, ","); 512 do { 513 if ((pmech = create_mech(curmech)) == NULL) { 514 rc = FAILURE; 515 break; 516 } else { 517 if (phead == NULL) { 518 phead = pcur = pmech; 519 } else { 520 pcur->next = pmech; 521 pcur = pmech; 522 } 523 } 524 } while ((curmech = strtok(NULL, ",")) != NULL); 525 526 if (rc == FAILURE) { 527 cryptoerror(LOG_STDERR, gettext("out of memory.")); 528 free_mechlist(phead); 529 } else { 530 mecharglist = phead; 531 rc = SUCCESS; 532 } 533 return (rc); 534 } 535 536 537 538 /* 539 * The top level function for the "cryptoadm list" subcommand and options. 540 */ 541 static int 542 do_list(int argc, char **argv) 543 { 544 boolean_t mflag = B_FALSE; 545 boolean_t pflag = B_FALSE; 546 boolean_t vflag = B_FALSE; 547 char ch; 548 cryptoadm_provider_t *prov = NULL; 549 int rc = SUCCESS; 550 551 if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD, 552 strlen(FIPS_KEYWORD))) == 0) { 553 /* 554 * cryptoadm list fips-140 555 */ 556 rc = do_fips_actions(FIPS140_STATUS, NOT_REFRESH); 557 return (rc); 558 } 559 560 argc -= 1; 561 argv += 1; 562 563 if (argc == 1) { 564 rc = list_simple_for_all(B_FALSE); 565 goto out; 566 } 567 568 /* 569 * cryptoadm list [-v] [-m] [-p] [provider=<>] [mechanism=<>] 570 */ 571 if (argc > 5) { 572 usage(); 573 return (rc); 574 } 575 576 while ((ch = getopt(argc, argv, "mpv")) != EOF) { 577 switch (ch) { 578 case 'm': 579 mflag = B_TRUE; 580 if (pflag) { 581 rc = ERROR_USAGE; 582 } 583 break; 584 case 'p': 585 pflag = B_TRUE; 586 if (mflag || vflag) { 587 rc = ERROR_USAGE; 588 } 589 break; 590 case 'v': 591 vflag = B_TRUE; 592 if (pflag) 593 rc = ERROR_USAGE; 594 break; 595 default: 596 rc = ERROR_USAGE; 597 break; 598 } 599 } 600 601 if (rc == ERROR_USAGE) { 602 usage(); 603 return (rc); 604 } 605 606 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 607 goto out; 608 } 609 610 prov = get_provider(argc, argv); 611 612 if (mflag || vflag) { 613 if (argc > 0) { 614 rc = process_mech_operands(argc, argv, B_TRUE); 615 if (rc == FAILURE) 616 goto out; 617 /* "-m" is implied when a mechanism list is given */ 618 if (mecharglist != NULL || allflag) 619 mflag = B_TRUE; 620 } 621 } 622 623 if (prov == NULL) { 624 if (mflag) { 625 rc = list_mechlist_for_all(vflag); 626 } else if (pflag) { 627 rc = list_policy_for_all(); 628 } else if (vflag) { 629 rc = list_simple_for_all(vflag); 630 } 631 } else if (prov->cp_type == METASLOT) { 632 if ((!mflag) && (!vflag) && (!pflag)) { 633 /* no flag is specified, just list metaslot status */ 634 rc = list_metaslot_info(mflag, vflag, mecharglist); 635 } else if (mflag || vflag) { 636 rc = list_metaslot_info(mflag, vflag, mecharglist); 637 } else if (pflag) { 638 rc = list_metaslot_policy(); 639 } else { 640 /* error message */ 641 usage(); 642 rc = ERROR_USAGE; 643 } 644 } else if (prov->cp_type == PROV_BADNAME) { 645 usage(); 646 rc = ERROR_USAGE; 647 goto out; 648 } else { /* do the listing for a provider only */ 649 char *provname = prov->cp_name; 650 651 if (mflag || vflag) { 652 if (vflag) 653 (void) printf(gettext("Provider: %s\n"), 654 provname); 655 switch (prov->cp_type) { 656 case PROV_UEF_LIB: 657 rc = list_mechlist_for_lib(provname, 658 mecharglist, NULL, B_FALSE, vflag, mflag); 659 break; 660 case PROV_KEF_SOFT: 661 rc = list_mechlist_for_soft(provname, 662 NULL, NULL); 663 break; 664 case PROV_KEF_HARD: 665 rc = list_mechlist_for_hard(provname); 666 break; 667 default: /* should not come here */ 668 rc = FAILURE; 669 break; 670 } 671 } else if (pflag) { 672 switch (prov->cp_type) { 673 case PROV_UEF_LIB: 674 rc = list_policy_for_lib(provname); 675 break; 676 case PROV_KEF_SOFT: 677 if (getzoneid() == GLOBAL_ZONEID) { 678 rc = list_policy_for_soft(provname, 679 NULL, NULL); 680 } else { 681 /* 682 * TRANSLATION_NOTE 683 * "global" is keyword and not to 684 * be translated. 685 */ 686 cryptoerror(LOG_STDERR, gettext( 687 "policy information for kernel " 688 "providers is available " 689 "in the %s zone only"), "global"); 690 rc = FAILURE; 691 } 692 break; 693 case PROV_KEF_HARD: 694 if (getzoneid() == GLOBAL_ZONEID) { 695 rc = list_policy_for_hard( 696 provname, NULL, NULL, NULL); 697 } else { 698 /* 699 * TRANSLATION_NOTE 700 * "global" is keyword and not to 701 * be translated. 702 */ 703 cryptoerror(LOG_STDERR, gettext( 704 "policy information for kernel " 705 "providers is available " 706 "in the %s zone only"), "global"); 707 rc = FAILURE; 708 } 709 710 break; 711 default: /* should not come here */ 712 rc = FAILURE; 713 break; 714 } 715 } else { 716 /* error message */ 717 usage(); 718 rc = ERROR_USAGE; 719 } 720 } 721 722 out: 723 if (prov != NULL) 724 free(prov); 725 726 if (mecharglist != NULL) 727 free_mechlist(mecharglist); 728 return (rc); 729 } 730 731 732 /* 733 * The top level function for the "cryptoadm disable" subcommand. 734 */ 735 static int 736 do_disable(int argc, char **argv) 737 { 738 cryptoadm_provider_t *prov = NULL; 739 int rc = SUCCESS; 740 boolean_t auto_key_migrate_flag = B_FALSE; 741 742 if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD, 743 strlen(FIPS_KEYWORD))) == 0) { 744 /* 745 * cryptoadm disable fips-140 746 */ 747 rc = do_fips_actions(FIPS140_DISABLE, NOT_REFRESH); 748 return (rc); 749 } 750 751 if ((argc < 3) || (argc > 5)) { 752 usage(); 753 return (ERROR_USAGE); 754 } 755 756 prov = get_provider(argc, argv); 757 if (prov == NULL) { 758 usage(); 759 return (ERROR_USAGE); 760 } 761 if (prov->cp_type == PROV_BADNAME) { 762 return (FAILURE); 763 } 764 765 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 766 goto out; 767 } 768 769 /* 770 * If allflag or rndflag has already been set there is no reason to 771 * process mech= 772 */ 773 if (prov->cp_type == METASLOT) { 774 if ((argc > 3) && 775 (rc = process_metaslot_operands(argc, argv, 776 NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) { 777 usage(); 778 return (rc); 779 } 780 } else if (!allflag && !rndflag && 781 (rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) { 782 return (rc); 783 } 784 785 switch (prov->cp_type) { 786 case METASLOT: 787 rc = disable_metaslot(mecharglist, allflag, 788 auto_key_migrate_flag); 789 break; 790 case PROV_UEF_LIB: 791 rc = disable_uef_lib(prov->cp_name, rndflag, allflag, 792 mecharglist); 793 break; 794 case PROV_KEF_SOFT: 795 if (rndflag && !allflag) { 796 if ((mecharglist = create_mech(RANDOM)) == NULL) { 797 rc = FAILURE; 798 break; 799 } 800 } 801 if (getzoneid() == GLOBAL_ZONEID) { 802 rc = disable_kef_software(prov->cp_name, rndflag, 803 allflag, mecharglist); 804 } else { 805 /* 806 * TRANSLATION_NOTE 807 * "disable" could be either a literal keyword 808 * and hence not to be translated, or a verb and 809 * translatable. A choice was made to view it as 810 * a literal keyword. "global" is keyword and not 811 * to be translated. 812 */ 813 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 814 "providers is supported in the %2$s zone only"), 815 "disable", "global"); 816 rc = FAILURE; 817 } 818 break; 819 case PROV_KEF_HARD: 820 if (rndflag && !allflag) { 821 if ((mecharglist = create_mech(RANDOM)) == NULL) { 822 rc = FAILURE; 823 break; 824 } 825 } 826 if (getzoneid() == GLOBAL_ZONEID) { 827 rc = disable_kef_hardware(prov->cp_name, rndflag, 828 allflag, mecharglist); 829 } else { 830 /* 831 * TRANSLATION_NOTE 832 * "disable" could be either a literal keyword 833 * and hence not to be translated, or a verb and 834 * translatable. A choice was made to view it as 835 * a literal keyword. "global" is keyword and not 836 * to be translated. 837 */ 838 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 839 "providers is supported in the %2$s zone only"), 840 "disable", "global"); 841 rc = FAILURE; 842 } 843 break; 844 default: /* should not come here */ 845 rc = FAILURE; 846 break; 847 } 848 849 out: 850 free(prov); 851 if (mecharglist != NULL) { 852 free_mechlist(mecharglist); 853 } 854 return (rc); 855 } 856 857 858 /* 859 * The top level function for the "cryptoadm enable" subcommand. 860 */ 861 static int 862 do_enable(int argc, char **argv) 863 { 864 cryptoadm_provider_t *prov = NULL; 865 int rc = SUCCESS; 866 char *alt_token = NULL, *alt_slot = NULL; 867 boolean_t use_default = B_FALSE; 868 boolean_t auto_key_migrate_flag = B_FALSE; 869 870 if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD, 871 strlen(FIPS_KEYWORD))) == 0) { 872 /* 873 * cryptoadm enable fips-140 874 */ 875 rc = do_fips_actions(FIPS140_ENABLE, NOT_REFRESH); 876 return (rc); 877 } 878 879 if ((argc < 3) || (argc > 6)) { 880 usage(); 881 return (ERROR_USAGE); 882 } 883 884 prov = get_provider(argc, argv); 885 if (prov == NULL) { 886 usage(); 887 return (ERROR_USAGE); 888 } 889 if ((prov->cp_type != METASLOT) && (argc != 4)) { 890 usage(); 891 return (ERROR_USAGE); 892 } 893 if (prov->cp_type == PROV_BADNAME) { 894 rc = FAILURE; 895 goto out; 896 } 897 898 899 if (prov->cp_type == METASLOT) { 900 if ((rc = process_metaslot_operands(argc, argv, &alt_token, 901 &alt_slot, &use_default, &auto_key_migrate_flag)) 902 != SUCCESS) { 903 usage(); 904 goto out; 905 } 906 if ((alt_slot || alt_token) && use_default) { 907 usage(); 908 rc = FAILURE; 909 goto out; 910 } 911 } else { 912 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 913 goto out; 914 } 915 916 /* 917 * If allflag or rndflag has already been set there is 918 * no reason to process mech= 919 */ 920 if (!allflag && !rndflag && 921 (rc = process_mech_operands(argc, argv, B_FALSE)) 922 != SUCCESS) { 923 goto out; 924 } 925 } 926 927 switch (prov->cp_type) { 928 case METASLOT: 929 rc = enable_metaslot(alt_token, alt_slot, use_default, 930 mecharglist, allflag, auto_key_migrate_flag); 931 break; 932 case PROV_UEF_LIB: 933 rc = enable_uef_lib(prov->cp_name, rndflag, allflag, 934 mecharglist); 935 break; 936 case PROV_KEF_SOFT: 937 case PROV_KEF_HARD: 938 if (rndflag && !allflag) { 939 if ((mecharglist = create_mech(RANDOM)) == NULL) { 940 rc = FAILURE; 941 break; 942 } 943 } 944 if (getzoneid() == GLOBAL_ZONEID) { 945 rc = enable_kef(prov->cp_name, rndflag, allflag, 946 mecharglist); 947 } else { 948 /* 949 * TRANSLATION_NOTE 950 * "enable" could be either a literal keyword 951 * and hence not to be translated, or a verb and 952 * translatable. A choice was made to view it as 953 * a literal keyword. "global" is keyword and not 954 * to be translated. 955 */ 956 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 957 "providers is supported in the %2$s zone only"), 958 "enable", "global"); 959 rc = FAILURE; 960 } 961 break; 962 default: /* should not come here */ 963 rc = FAILURE; 964 break; 965 } 966 out: 967 free(prov); 968 if (mecharglist != NULL) { 969 free_mechlist(mecharglist); 970 } 971 if (alt_token != NULL) { 972 free(alt_token); 973 } 974 if (alt_slot != NULL) { 975 free(alt_slot); 976 } 977 return (rc); 978 } 979 980 981 982 /* 983 * The top level function for the "cryptoadm install" subcommand. 984 */ 985 static int 986 do_install(int argc, char **argv) 987 { 988 cryptoadm_provider_t *prov = NULL; 989 int rc; 990 991 if (argc < 3) { 992 usage(); 993 return (ERROR_USAGE); 994 } 995 996 prov = get_provider(argc, argv); 997 if (prov == NULL || 998 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 999 /* 1000 * TRANSLATION_NOTE 1001 * "install" could be either a literal keyword and hence 1002 * not to be translated, or a verb and translatable. A 1003 * choice was made to view it as a literal keyword. 1004 */ 1005 cryptoerror(LOG_STDERR, 1006 gettext("bad provider name for %s."), "install"); 1007 rc = FAILURE; 1008 goto out; 1009 } 1010 1011 if (prov->cp_type == PROV_UEF_LIB) { 1012 rc = install_uef_lib(prov->cp_name); 1013 goto out; 1014 } 1015 1016 /* It is the PROV_KEF_SOFT type now */ 1017 1018 /* check if there are mechanism operands */ 1019 if (argc < 4) { 1020 /* 1021 * TRANSLATION_NOTE 1022 * "mechanism" could be either a literal keyword and hence 1023 * not to be translated, or a descriptive word and 1024 * translatable. A choice was made to view it as a literal 1025 * keyword. 1026 */ 1027 cryptoerror(LOG_STDERR, 1028 gettext("need %s operands for installing a" 1029 " kernel software provider."), "mechanism"); 1030 rc = ERROR_USAGE; 1031 goto out; 1032 } 1033 1034 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) { 1035 goto out; 1036 } 1037 1038 if (allflag == B_TRUE) { 1039 /* 1040 * TRANSLATION_NOTE 1041 * "all", "mechanism", and "install" are all keywords and 1042 * not to be translated. 1043 */ 1044 cryptoerror(LOG_STDERR, 1045 gettext("can not use the %1$s keyword for %2$s " 1046 "in the %3$s subcommand."), "all", "mechanism", "install"); 1047 rc = ERROR_USAGE; 1048 goto out; 1049 } 1050 1051 if (getzoneid() == GLOBAL_ZONEID) { 1052 rc = install_kef(prov->cp_name, mecharglist); 1053 } else { 1054 /* 1055 * TRANSLATION_NOTE 1056 * "install" could be either a literal keyword and hence 1057 * not to be translated, or a verb and translatable. A 1058 * choice was made to view it as a literal keyword. 1059 * "global" is keyword and not to be translated. 1060 */ 1061 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1062 "is supported in the %2$s zone only"), "install", "global"); 1063 rc = FAILURE; 1064 } 1065 out: 1066 free(prov); 1067 return (rc); 1068 } 1069 1070 1071 1072 /* 1073 * The top level function for the "cryptoadm uninstall" subcommand. 1074 */ 1075 static int 1076 do_uninstall(int argc, char **argv) 1077 { 1078 cryptoadm_provider_t *prov = NULL; 1079 int rc = SUCCESS; 1080 1081 if (argc != 3) { 1082 usage(); 1083 return (ERROR_USAGE); 1084 } 1085 1086 prov = get_provider(argc, argv); 1087 if (prov == NULL || 1088 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 1089 /* 1090 * TRANSLATION_NOTE 1091 * "uninstall" could be either a literal keyword and hence 1092 * not to be translated, or a verb and translatable. A 1093 * choice was made to view it as a literal keyword. 1094 */ 1095 cryptoerror(LOG_STDERR, 1096 gettext("bad provider name for %s."), "uninstall"); 1097 free(prov); 1098 return (FAILURE); 1099 } 1100 1101 if (prov->cp_type == PROV_UEF_LIB) { 1102 rc = uninstall_uef_lib(prov->cp_name); 1103 1104 } else if (prov->cp_type == PROV_KEF_SOFT) { 1105 if (getzoneid() == GLOBAL_ZONEID) { 1106 /* unload and remove from kcf.conf */ 1107 rc = uninstall_kef(prov->cp_name); 1108 } else { 1109 /* 1110 * TRANSLATION_NOTE 1111 * "uninstall" could be either a literal keyword and 1112 * hence not to be translated, or a verb and 1113 * translatable. A choice was made to view it as a 1114 * literal keyword. "global" is keyword and not to 1115 * be translated. 1116 */ 1117 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 1118 "providers is supported in the %2$s zone only"), 1119 "uninstall", "global"); 1120 rc = FAILURE; 1121 } 1122 } 1123 1124 free(prov); 1125 return (rc); 1126 } 1127 1128 1129 /* 1130 * The top level function for the "cryptoadm unload" subcommand. 1131 */ 1132 static int 1133 do_unload(int argc, char **argv) 1134 { 1135 cryptoadm_provider_t *prov = NULL; 1136 entry_t *pent = NULL; 1137 boolean_t in_kernel = B_FALSE; 1138 int rc = SUCCESS; 1139 char *provname = NULL; 1140 1141 if (argc != 3) { 1142 usage(); 1143 return (ERROR_USAGE); 1144 } 1145 1146 /* check if it is a kernel software provider */ 1147 prov = get_provider(argc, argv); 1148 if (prov == NULL) { 1149 cryptoerror(LOG_STDERR, 1150 gettext("unable to determine provider name.")); 1151 goto out; 1152 } 1153 provname = prov->cp_name; 1154 if (prov->cp_type != PROV_KEF_SOFT) { 1155 cryptoerror(LOG_STDERR, 1156 gettext("%s is not a valid kernel software provider."), 1157 provname); 1158 rc = FAILURE; 1159 goto out; 1160 } 1161 1162 if (getzoneid() != GLOBAL_ZONEID) { 1163 /* 1164 * TRANSLATION_NOTE 1165 * "unload" could be either a literal keyword and hence 1166 * not to be translated, or a verb and translatable. 1167 * A choice was made to view it as a literal keyword. 1168 * "global" is keyword and not to be translated. 1169 */ 1170 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1171 "is supported in the %2$s zone only"), "unload", "global"); 1172 rc = FAILURE; 1173 goto out; 1174 } 1175 1176 if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) { 1177 cryptodebug("internal error"); 1178 rc = FAILURE; 1179 goto out; 1180 } else if (in_kernel == B_FALSE) { 1181 cryptoerror(LOG_STDERR, 1182 gettext("provider %s is not loaded or does not exist."), 1183 provname); 1184 rc = FAILURE; 1185 goto out; 1186 } 1187 1188 /* Get kcf.conf entry. If none, build a new entry */ 1189 if ((pent = getent_kef(provname, NULL, NULL)) == NULL) { 1190 if ((pent = create_entry(provname)) == NULL) { 1191 cryptoerror(LOG_STDERR, gettext("out of memory.")); 1192 rc = FAILURE; 1193 goto out; 1194 } 1195 } 1196 1197 /* If it is unloaded already, return */ 1198 if (!pent->load) { /* unloaded already */ 1199 cryptoerror(LOG_STDERR, 1200 gettext("failed to unload %s."), provname); 1201 rc = FAILURE; 1202 goto out; 1203 } else if (unload_kef_soft(provname) != FAILURE) { 1204 /* Mark as unloaded in kcf.conf */ 1205 pent->load = B_FALSE; 1206 rc = update_kcfconf(pent, MODIFY_MODE); 1207 } else { 1208 cryptoerror(LOG_STDERR, 1209 gettext("failed to unload %s."), provname); 1210 rc = FAILURE; 1211 } 1212 out: 1213 free(prov); 1214 free_entry(pent); 1215 return (rc); 1216 } 1217 1218 1219 1220 /* 1221 * The top level function for the "cryptoadm refresh" subcommand. 1222 */ 1223 static int 1224 do_refresh(int argc) 1225 { 1226 if (argc != 2) { 1227 usage(); 1228 return (ERROR_USAGE); 1229 } 1230 1231 if (getzoneid() == GLOBAL_ZONEID) { 1232 return (refresh()); 1233 } else { /* non-global zone */ 1234 /* 1235 * Note: in non-global zone, this must silently return SUCCESS 1236 * due to integration with SMF, for "svcadm refresh cryptosvc" 1237 */ 1238 return (SUCCESS); 1239 } 1240 } 1241 1242 1243 /* 1244 * The top level function for the "cryptoadm start" subcommand. 1245 */ 1246 static int 1247 do_start(int argc) 1248 { 1249 int ret; 1250 1251 if (argc != 2) { 1252 usage(); 1253 return (ERROR_USAGE); 1254 } 1255 1256 ret = do_refresh(argc); 1257 if (ret != SUCCESS) 1258 return (ret); 1259 1260 return (start_daemon()); 1261 } 1262 1263 /* 1264 * The top level function for the "cryptoadm stop" subcommand. 1265 */ 1266 static int 1267 do_stop(int argc) 1268 { 1269 if (argc != 2) { 1270 usage(); 1271 return (ERROR_USAGE); 1272 } 1273 1274 return (stop_daemon()); 1275 } 1276 1277 1278 1279 /* 1280 * Print a list all the the providers. 1281 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p). 1282 */ 1283 static int 1284 list_simple_for_all(boolean_t verbose) 1285 { 1286 uentrylist_t *pliblist = NULL; 1287 uentrylist_t *plibptr = NULL; 1288 entry_t *pent = NULL; 1289 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1290 int rc = SUCCESS; 1291 int i; 1292 1293 /* get user-level providers */ 1294 (void) printf(gettext("\nUser-level providers:\n")); 1295 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1296 cryptoerror(LOG_STDERR, gettext( 1297 "failed to retrieve the list of user-level providers.")); 1298 rc = FAILURE; 1299 } 1300 1301 for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) { 1302 /* skip metaslot and fips-140 entry */ 1303 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) && 1304 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) { 1305 (void) printf(gettext("Provider: %s\n"), 1306 plibptr->puent->name); 1307 if (verbose) { 1308 (void) list_mechlist_for_lib( 1309 plibptr->puent->name, mecharglist, NULL, 1310 B_FALSE, verbose, B_FALSE); 1311 (void) printf("\n"); 1312 } 1313 } 1314 } 1315 free_uentrylist(pliblist); 1316 1317 /* get kernel software providers */ 1318 (void) printf(gettext("\nKernel software providers:\n")); 1319 1320 if (getzoneid() == GLOBAL_ZONEID) { 1321 /* get kernel software providers from kernel ioctl */ 1322 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1323 uint_t sl_soft_count; 1324 char *psoftname; 1325 entrylist_t *pdevlist_conf = NULL; 1326 entrylist_t *psoftlist_conf = NULL; 1327 1328 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1329 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1330 "software provider list from kernel.")); 1331 rc = FAILURE; 1332 } else { 1333 sl_soft_count = psoftlist_kernel->sl_soft_count; 1334 1335 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) 1336 == FAILURE) { 1337 cryptoerror(LOG_ERR, 1338 "failed to retrieve the providers' " 1339 "information from file kcf.conf - %s.", 1340 _PATH_KCF_CONF); 1341 free(psoftlist_kernel); 1342 rc = FAILURE; 1343 } else { 1344 1345 for (i = 0, 1346 psoftname = psoftlist_kernel->sl_soft_names; 1347 i < sl_soft_count; 1348 ++i, psoftname += strlen(psoftname) + 1) { 1349 pent = getent_kef(psoftname, 1350 pdevlist_conf, psoftlist_conf); 1351 (void) printf("\t%s%s\n", psoftname, 1352 (pent == NULL) || (pent->load) ? 1353 "" : gettext(" (inactive)")); 1354 } 1355 free_entrylist(pdevlist_conf); 1356 free_entrylist(psoftlist_conf); 1357 } 1358 free(psoftlist_kernel); 1359 } 1360 1361 } else { 1362 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1363 entrylist_t *pdevlist_zone = NULL; 1364 entrylist_t *psoftlist_zone = NULL; 1365 entrylist_t *ptr; 1366 1367 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1368 SUCCESS) { 1369 cryptoerror(LOG_STDERR, 1370 gettext("failed to retrieve the " 1371 "list of kernel software providers.\n")); 1372 rc = FAILURE; 1373 } 1374 1375 ptr = psoftlist_zone; 1376 while (ptr != NULL) { 1377 (void) printf("\t%s\n", ptr->pent->name); 1378 ptr = ptr->next; 1379 } 1380 1381 free_entrylist(pdevlist_zone); 1382 free_entrylist(psoftlist_zone); 1383 } 1384 1385 /* get kernel hardware providers */ 1386 (void) printf(gettext("\nKernel hardware providers:\n")); 1387 if (get_dev_list(&pdevlist_kernel) == FAILURE) { 1388 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1389 "the list of kernel hardware providers.\n")); 1390 rc = FAILURE; 1391 } else { 1392 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1393 (void) printf("\t%s/%d\n", 1394 pdevlist_kernel->dl_devs[i].le_dev_name, 1395 pdevlist_kernel->dl_devs[i].le_dev_instance); 1396 } 1397 } 1398 free(pdevlist_kernel); 1399 1400 return (rc); 1401 } 1402 1403 1404 1405 /* 1406 * List all the providers. And for each provider, list the mechanism list. 1407 * Called for "cryptoadm list -m" or "cryptoadm list -mv" . 1408 */ 1409 static int 1410 list_mechlist_for_all(boolean_t verbose) 1411 { 1412 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1413 uentrylist_t *pliblist = NULL; 1414 uentrylist_t *plibptr = NULL; 1415 entry_t *pent = NULL; 1416 mechlist_t *pmechlist = NULL; 1417 char provname[MAXNAMELEN]; 1418 char devname[MAXNAMELEN]; 1419 int inst_num; 1420 int count; 1421 int i; 1422 int rv; 1423 int rc = SUCCESS; 1424 1425 /* get user-level providers */ 1426 (void) printf(gettext("\nUser-level providers:\n")); 1427 /* 1428 * TRANSLATION_NOTE 1429 * Strictly for appearance's sake, this line should be as long as 1430 * the length of the translated text above. 1431 */ 1432 (void) printf(gettext("=====================\n")); 1433 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1434 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1435 "the list of user-level providers.\n")); 1436 rc = FAILURE; 1437 } 1438 1439 plibptr = pliblist; 1440 while (plibptr != NULL) { 1441 /* skip metaslot and fips-140 entry */ 1442 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) && 1443 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) { 1444 (void) printf(gettext("\nProvider: %s\n"), 1445 plibptr->puent->name); 1446 rv = list_mechlist_for_lib(plibptr->puent->name, 1447 mecharglist, NULL, B_FALSE, verbose, B_TRUE); 1448 if (rv == FAILURE) { 1449 rc = FAILURE; 1450 } 1451 } 1452 plibptr = plibptr->next; 1453 } 1454 free_uentrylist(pliblist); 1455 1456 /* get kernel software providers */ 1457 (void) printf(gettext("\nKernel software providers:\n")); 1458 1459 /* 1460 * TRANSLATION_NOTE 1461 * Strictly for appearance's sake, this line should be as long as 1462 * the length of the translated text above. 1463 */ 1464 (void) printf(gettext("==========================\n")); 1465 if (getzoneid() == GLOBAL_ZONEID) { 1466 /* get kernel software providers from kernel ioctl */ 1467 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1468 uint_t sl_soft_count; 1469 char *psoftname; 1470 int i; 1471 entrylist_t *pdevlist_conf = NULL; 1472 entrylist_t *psoftlist_conf = NULL; 1473 1474 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1475 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1476 "software provider list from kernel.")); 1477 return (FAILURE); 1478 } 1479 sl_soft_count = psoftlist_kernel->sl_soft_count; 1480 1481 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) 1482 == FAILURE) { 1483 cryptoerror(LOG_ERR, 1484 "failed to retrieve the providers' " 1485 "information from file kcf.conf - %s.", 1486 _PATH_KCF_CONF); 1487 free(psoftlist_kernel); 1488 return (FAILURE); 1489 } 1490 1491 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 1492 i < sl_soft_count; 1493 ++i, psoftname += strlen(psoftname) + 1) { 1494 pent = getent_kef(psoftname, pdevlist_conf, 1495 psoftlist_conf); 1496 if ((pent == NULL) || (pent->load)) { 1497 rv = list_mechlist_for_soft(psoftname, 1498 NULL, NULL); 1499 if (rv == FAILURE) { 1500 rc = FAILURE; 1501 } 1502 } else { 1503 (void) printf(gettext("%s: (inactive)\n"), 1504 psoftname); 1505 } 1506 } 1507 1508 free(psoftlist_kernel); 1509 free_entrylist(pdevlist_conf); 1510 free_entrylist(psoftlist_conf); 1511 1512 } else { 1513 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1514 entrylist_t *pdevlist_zone = NULL; 1515 entrylist_t *psoftlist_zone = NULL; 1516 entrylist_t *ptr; 1517 1518 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1519 SUCCESS) { 1520 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1521 "the list of kernel software providers.\n")); 1522 rc = FAILURE; 1523 } 1524 1525 for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) { 1526 rv = list_mechlist_for_soft(ptr->pent->name, 1527 pdevlist_zone, psoftlist_zone); 1528 if (rv == FAILURE) { 1529 (void) printf(gettext( 1530 "%s: failed to get the mechanism list.\n"), 1531 ptr->pent->name); 1532 rc = FAILURE; 1533 } 1534 } 1535 1536 free_entrylist(pdevlist_zone); 1537 free_entrylist(psoftlist_zone); 1538 } 1539 1540 /* Get kernel hardware providers and their mechanism lists */ 1541 (void) printf(gettext("\nKernel hardware providers:\n")); 1542 /* 1543 * TRANSLATION_NOTE 1544 * Strictly for appearance's sake, this line should be as long as 1545 * the length of the translated text above. 1546 */ 1547 (void) printf(gettext("==========================\n")); 1548 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1549 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1550 "the list of hardware providers.\n")); 1551 return (FAILURE); 1552 } 1553 1554 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1555 (void) strlcpy(devname, 1556 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN); 1557 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; 1558 count = pdevlist_kernel->dl_devs[i].le_mechanism_count; 1559 (void) snprintf(provname, sizeof (provname), "%s/%d", devname, 1560 inst_num); 1561 if (get_dev_info(devname, inst_num, count, &pmechlist) == 1562 SUCCESS) { 1563 (void) filter_mechlist(&pmechlist, RANDOM); 1564 print_mechlist(provname, pmechlist); 1565 free_mechlist(pmechlist); 1566 } else { 1567 (void) printf(gettext("%s: failed to get the mechanism" 1568 " list.\n"), provname); 1569 rc = FAILURE; 1570 } 1571 } 1572 free(pdevlist_kernel); 1573 return (rc); 1574 } 1575 1576 1577 /* 1578 * List all the providers. And for each provider, list the policy information. 1579 * Called for "cryptoadm list -p". 1580 */ 1581 static int 1582 list_policy_for_all(void) 1583 { 1584 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1585 uentrylist_t *pliblist = NULL; 1586 entrylist_t *pdevlist_conf = NULL; 1587 entrylist_t *psoftlist_conf = NULL; 1588 entrylist_t *ptr = NULL; 1589 entrylist_t *phead = NULL; 1590 boolean_t found = B_FALSE; 1591 char provname[MAXNAMELEN]; 1592 int i; 1593 int rc = SUCCESS; 1594 1595 /* Get user-level providers */ 1596 (void) printf(gettext("\nUser-level providers:\n")); 1597 /* 1598 * TRANSLATION_NOTE 1599 * Strictly for appearance's sake, this line should be as long as 1600 * the length of the translated text above. 1601 */ 1602 (void) printf(gettext("=====================\n")); 1603 if (get_pkcs11conf_info(&pliblist) == FAILURE) { 1604 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1605 "the list of user-level providers.\n")); 1606 rc = FAILURE; 1607 } else { 1608 uentrylist_t *plibptr = pliblist; 1609 1610 while (plibptr != NULL) { 1611 /* skip metaslot and fips-140 entry */ 1612 if ((strcmp(plibptr->puent->name, 1613 METASLOT_KEYWORD) != 0) && 1614 (strcmp(plibptr->puent->name, 1615 FIPS_KEYWORD) != 0)) { 1616 if (print_uef_policy(plibptr->puent) 1617 == FAILURE) { 1618 rc = FAILURE; 1619 } 1620 } 1621 plibptr = plibptr->next; 1622 } 1623 free_uentrylist(pliblist); 1624 } 1625 1626 /* kernel software providers */ 1627 (void) printf(gettext("\nKernel software providers:\n")); 1628 /* 1629 * TRANSLATION_NOTE 1630 * Strictly for appearance's sake, this line should be as long as 1631 * the length of the translated text above. 1632 */ 1633 (void) printf(gettext("==========================\n")); 1634 1635 /* Get all entries from the kernel */ 1636 if (getzoneid() == GLOBAL_ZONEID) { 1637 /* get kernel software providers from kernel ioctl */ 1638 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1639 uint_t sl_soft_count; 1640 char *psoftname; 1641 int i; 1642 1643 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1644 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1645 "software provider list from kernel.")); 1646 rc = FAILURE; 1647 } else { 1648 sl_soft_count = psoftlist_kernel->sl_soft_count; 1649 1650 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 1651 i < sl_soft_count; 1652 ++i, psoftname += strlen(psoftname) + 1) { 1653 (void) list_policy_for_soft(psoftname, 1654 pdevlist_conf, psoftlist_conf); 1655 } 1656 free(psoftlist_kernel); 1657 } 1658 1659 } else { 1660 /* kcf.conf not there in non-global zone, no policy info */ 1661 1662 /* 1663 * TRANSLATION_NOTE 1664 * "global" is keyword and not to be translated. 1665 */ 1666 cryptoerror(LOG_STDERR, gettext( 1667 "policy information for kernel software providers is " 1668 "available in the %s zone only"), "global"); 1669 } 1670 1671 /* Kernel hardware providers */ 1672 (void) printf(gettext("\nKernel hardware providers:\n")); 1673 /* 1674 * TRANSLATION_NOTE 1675 * Strictly for appearance's sake, this line should be as long as 1676 * the length of the translated text above. 1677 */ 1678 (void) printf(gettext("==========================\n")); 1679 1680 if (getzoneid() != GLOBAL_ZONEID) { 1681 /* 1682 * TRANSLATION_NOTE 1683 * "global" is keyword and not to be translated. 1684 */ 1685 cryptoerror(LOG_STDERR, gettext( 1686 "policy information for kernel hardware providers is " 1687 "available in the %s zone only"), "global"); 1688 return (FAILURE); 1689 } 1690 1691 /* Get the hardware provider list from kernel */ 1692 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1693 cryptoerror(LOG_STDERR, gettext( 1694 "failed to retrieve the list of hardware providers.\n")); 1695 return (FAILURE); 1696 } 1697 1698 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) { 1699 cryptoerror(LOG_ERR, "failed to retrieve the providers' " 1700 "information from file kcf.conf - %s.", 1701 _PATH_KCF_CONF); 1702 return (FAILURE); 1703 } 1704 1705 1706 /* 1707 * For each hardware provider from kernel, check if it has an entry 1708 * in the config file. If it has an entry, print out the policy from 1709 * config file and remove the entry from the hardware provider list 1710 * of the config file. If it does not have an entry in the config 1711 * file, no mechanisms of it have been disabled. But, we still call 1712 * list_policy_for_hard() to account for the "random" feature. 1713 */ 1714 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1715 (void) snprintf(provname, sizeof (provname), "%s/%d", 1716 pdevlist_kernel->dl_devs[i].le_dev_name, 1717 pdevlist_kernel->dl_devs[i].le_dev_instance); 1718 1719 found = B_FALSE; 1720 phead = ptr = pdevlist_conf; 1721 while (!found && ptr) { 1722 if (strcmp(ptr->pent->name, provname) == 0) { 1723 found = B_TRUE; 1724 } else { 1725 phead = ptr; 1726 ptr = ptr->next; 1727 } 1728 } 1729 1730 if (found) { 1731 (void) list_policy_for_hard(ptr->pent->name, 1732 pdevlist_conf, psoftlist_conf, pdevlist_kernel); 1733 if (phead == ptr) { 1734 pdevlist_conf = pdevlist_conf->next; 1735 } else { 1736 phead->next = ptr->next; 1737 } 1738 free_entry(ptr->pent); 1739 free(ptr); 1740 } else { 1741 (void) list_policy_for_hard(provname, pdevlist_conf, 1742 psoftlist_conf, pdevlist_kernel); 1743 } 1744 } 1745 1746 /* 1747 * If there are still entries left in the pdevlist_conf list from 1748 * the config file, these providers must have been detached. 1749 * Should print out their policy information also. 1750 */ 1751 for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) { 1752 print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE); 1753 } 1754 1755 free_entrylist(pdevlist_conf); 1756 free_entrylist(psoftlist_conf); 1757 free(pdevlist_kernel); 1758 1759 return (rc); 1760 } 1761