xref: /titanic_51/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.c (revision 32e0ab73531b6e6e8957e9ecdbbd42603865f2d0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5b8bf75cbSkrishna  * Common Development and Distribution License (the "License").
6b8bf75cbSkrishna  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*32e0ab73SMisaki Miyashita  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <fcntl.h>
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <locale.h>
327c478bd9Sstevel@tonic-gate #include <libgen.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <zone.h>
357c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
367c478bd9Sstevel@tonic-gate #include <cryptoutil.h>
377c478bd9Sstevel@tonic-gate #include "cryptoadm.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #define	REQ_ARG_CNT	2
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /* subcommand index */
427c478bd9Sstevel@tonic-gate enum subcommand_index {
437c478bd9Sstevel@tonic-gate 	CRYPTO_LIST,
447c478bd9Sstevel@tonic-gate 	CRYPTO_DISABLE,
457c478bd9Sstevel@tonic-gate 	CRYPTO_ENABLE,
467c478bd9Sstevel@tonic-gate 	CRYPTO_INSTALL,
477c478bd9Sstevel@tonic-gate 	CRYPTO_UNINSTALL,
487c478bd9Sstevel@tonic-gate 	CRYPTO_UNLOAD,
497c478bd9Sstevel@tonic-gate 	CRYPTO_REFRESH,
507c478bd9Sstevel@tonic-gate 	CRYPTO_START,
517c478bd9Sstevel@tonic-gate 	CRYPTO_STOP,
527c478bd9Sstevel@tonic-gate 	CRYPTO_HELP };
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
550a85b835SDaniel Anderson  * TRANSLATION_NOTE
567c478bd9Sstevel@tonic-gate  * Command keywords are not to be translated.
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate static char *cmd_table[] = {
597c478bd9Sstevel@tonic-gate 	"list",
607c478bd9Sstevel@tonic-gate 	"disable",
617c478bd9Sstevel@tonic-gate 	"enable",
627c478bd9Sstevel@tonic-gate 	"install",
637c478bd9Sstevel@tonic-gate 	"uninstall",
647c478bd9Sstevel@tonic-gate 	"unload",
657c478bd9Sstevel@tonic-gate 	"refresh",
667c478bd9Sstevel@tonic-gate 	"start",
677c478bd9Sstevel@tonic-gate 	"stop",
687c478bd9Sstevel@tonic-gate 	"--help" };
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /* provider type */
717c478bd9Sstevel@tonic-gate enum provider_type_index {
727c478bd9Sstevel@tonic-gate 	PROV_UEF_LIB,
737c478bd9Sstevel@tonic-gate 	PROV_KEF_SOFT,
747c478bd9Sstevel@tonic-gate 	PROV_KEF_HARD,
757c478bd9Sstevel@tonic-gate 	METASLOT,
767c478bd9Sstevel@tonic-gate 	PROV_BADNAME };
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate typedef struct {
797c478bd9Sstevel@tonic-gate 	char cp_name[MAXPATHLEN];
807c478bd9Sstevel@tonic-gate 	enum provider_type_index cp_type;
817c478bd9Sstevel@tonic-gate } cryptoadm_provider_t;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate /*
840a85b835SDaniel Anderson  * TRANSLATION_NOTE
857c478bd9Sstevel@tonic-gate  * Operand keywords are not to be translated.
867c478bd9Sstevel@tonic-gate  */
877c478bd9Sstevel@tonic-gate static const char *KN_PROVIDER = "provider=";
887c478bd9Sstevel@tonic-gate static const char *KN_MECH = "mechanism=";
897c478bd9Sstevel@tonic-gate static const char *KN_ALL = "all";
907c478bd9Sstevel@tonic-gate static const char *KN_TOKEN = "token=";
917c478bd9Sstevel@tonic-gate static const char *KN_SLOT = "slot=";
927c478bd9Sstevel@tonic-gate static const char *KN_DEFAULT_KS = "default-keystore";
937c478bd9Sstevel@tonic-gate static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate";
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate /* static variables */
967c478bd9Sstevel@tonic-gate static boolean_t	allflag = B_FALSE;
977c478bd9Sstevel@tonic-gate static boolean_t	rndflag = B_FALSE;
987c478bd9Sstevel@tonic-gate static mechlist_t	*mecharglist = NULL;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /* static functions */
1017c478bd9Sstevel@tonic-gate static void usage(void);
1027c478bd9Sstevel@tonic-gate static int get_provider_type(char *);
1037c478bd9Sstevel@tonic-gate static int process_mech_operands(int, char **, boolean_t);
1047c478bd9Sstevel@tonic-gate static int do_list(int, char **);
1057c478bd9Sstevel@tonic-gate static int do_disable(int, char **);
1067c478bd9Sstevel@tonic-gate static int do_enable(int, char **);
1077c478bd9Sstevel@tonic-gate static int do_install(int, char **);
1087c478bd9Sstevel@tonic-gate static int do_uninstall(int, char **);
1097c478bd9Sstevel@tonic-gate static int do_unload(int, char **);
1107c478bd9Sstevel@tonic-gate static int do_refresh(int);
1117c478bd9Sstevel@tonic-gate static int do_start(int);
1127c478bd9Sstevel@tonic-gate static int do_stop(int);
1137c478bd9Sstevel@tonic-gate static int list_simple_for_all(boolean_t);
1147c478bd9Sstevel@tonic-gate static int list_mechlist_for_all(boolean_t);
1157c478bd9Sstevel@tonic-gate static int list_policy_for_all(void);
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate int
1187c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1197c478bd9Sstevel@tonic-gate {
1207c478bd9Sstevel@tonic-gate 	char	*subcmd;
1217c478bd9Sstevel@tonic-gate 	int	cmdnum;
1227c478bd9Sstevel@tonic-gate 	int	cmd_index = 0;
1237c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1287c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
1297c478bd9Sstevel@tonic-gate #endif
1307c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	cryptodebug_init(basename(argv[0]));
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if (argc < REQ_ARG_CNT) {
1357c478bd9Sstevel@tonic-gate 		usage();
1367c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1377c478bd9Sstevel@tonic-gate 	}
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	/* get the subcommand index */
1407c478bd9Sstevel@tonic-gate 	cmd_index = 0;
1417c478bd9Sstevel@tonic-gate 	subcmd = argv[1];
1427c478bd9Sstevel@tonic-gate 	cmdnum = sizeof (cmd_table)/sizeof (cmd_table[0]);
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	while ((cmd_index < cmdnum) &&
1457c478bd9Sstevel@tonic-gate 	    (strcmp(subcmd, cmd_table[cmd_index]) != 0)) {
1467c478bd9Sstevel@tonic-gate 		cmd_index++;
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate 	if (cmd_index >= cmdnum) {
1497c478bd9Sstevel@tonic-gate 		usage();
1507c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1517c478bd9Sstevel@tonic-gate 	}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	/* do the subcommand */
1547c478bd9Sstevel@tonic-gate 	switch (cmd_index) {
1557c478bd9Sstevel@tonic-gate 	case CRYPTO_LIST:
1567c478bd9Sstevel@tonic-gate 		rc = do_list(argc, argv);
1577c478bd9Sstevel@tonic-gate 		break;
1587c478bd9Sstevel@tonic-gate 	case CRYPTO_DISABLE:
1597c478bd9Sstevel@tonic-gate 		rc = do_disable(argc, argv);
1607c478bd9Sstevel@tonic-gate 		break;
1617c478bd9Sstevel@tonic-gate 	case CRYPTO_ENABLE:
1627c478bd9Sstevel@tonic-gate 		rc = do_enable(argc, argv);
1637c478bd9Sstevel@tonic-gate 		break;
1647c478bd9Sstevel@tonic-gate 	case CRYPTO_INSTALL:
1657c478bd9Sstevel@tonic-gate 		rc = do_install(argc, argv);
1667c478bd9Sstevel@tonic-gate 		break;
1677c478bd9Sstevel@tonic-gate 	case CRYPTO_UNINSTALL:
1687c478bd9Sstevel@tonic-gate 		rc = do_uninstall(argc, argv);
1697c478bd9Sstevel@tonic-gate 		break;
1707c478bd9Sstevel@tonic-gate 	case CRYPTO_UNLOAD:
1717c478bd9Sstevel@tonic-gate 		rc = do_unload(argc, argv);
1727c478bd9Sstevel@tonic-gate 		break;
1737c478bd9Sstevel@tonic-gate 	case CRYPTO_REFRESH:
1747c478bd9Sstevel@tonic-gate 		rc = do_refresh(argc);
1757c478bd9Sstevel@tonic-gate 		break;
1767c478bd9Sstevel@tonic-gate 	case CRYPTO_START:
1777c478bd9Sstevel@tonic-gate 		rc = do_start(argc);
1787c478bd9Sstevel@tonic-gate 		break;
1797c478bd9Sstevel@tonic-gate 	case CRYPTO_STOP:
1807c478bd9Sstevel@tonic-gate 		rc = do_stop(argc);
1817c478bd9Sstevel@tonic-gate 		break;
1827c478bd9Sstevel@tonic-gate 	case CRYPTO_HELP:
1837c478bd9Sstevel@tonic-gate 		usage();
1847c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
1857c478bd9Sstevel@tonic-gate 		break;
1867c478bd9Sstevel@tonic-gate 	default: /* should not come here */
1877c478bd9Sstevel@tonic-gate 		usage();
1887c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
1897c478bd9Sstevel@tonic-gate 		break;
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate 	return (rc);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate static void
1967c478bd9Sstevel@tonic-gate usage(void)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	/*
1990a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
2007c478bd9Sstevel@tonic-gate 	 * Command usage is not to be translated.  Only the word "Usage:"
2017c478bd9Sstevel@tonic-gate 	 * along with localized expressions indicating what kind of value
2027c478bd9Sstevel@tonic-gate 	 * is expected for arguments.
2037c478bd9Sstevel@tonic-gate 	 */
2047c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("Usage:\n"));
2057c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2067c478bd9Sstevel@tonic-gate 	    "  cryptoadm list [-mpv] [provider=<%s> | metaslot]"
2077c478bd9Sstevel@tonic-gate 	    " [mechanism=<%s>]\n",
2087c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
2097c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
210b5a2d845SHai-May Chao 	    "  cryptoadm list fips-140\n");
211b5a2d845SHai-May Chao 	(void) fprintf(stderr,
2127c478bd9Sstevel@tonic-gate 	    "  cryptoadm disable provider=<%s>"
2137c478bd9Sstevel@tonic-gate 	    " mechanism=<%s> | random | all\n",
2147c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
2157c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2167c478bd9Sstevel@tonic-gate 	    "  cryptoadm disable metaslot"
2177c478bd9Sstevel@tonic-gate 	    " [auto-key-migrate] [mechanism=<%s>]\n",
2187c478bd9Sstevel@tonic-gate 	    gettext("mechanism-list"));
2197c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
220b5a2d845SHai-May Chao 	    "  cryptoadm disable fips-140\n");
221b5a2d845SHai-May Chao 	(void) fprintf(stderr,
2227c478bd9Sstevel@tonic-gate 	    "  cryptoadm enable provider=<%s>"
2237c478bd9Sstevel@tonic-gate 	    " mechanism=<%s> | random | all\n",
2247c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
2257c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2267c478bd9Sstevel@tonic-gate 	    "  cryptoadm enable metaslot [mechanism=<%s>]"
2277c478bd9Sstevel@tonic-gate 	    " [[token=<%s>] [slot=<%s>]"
2287c478bd9Sstevel@tonic-gate 	    " | [default-keystore]] | [auto-key-migrate]\n",
2297c478bd9Sstevel@tonic-gate 	    gettext("mechanism-list"), gettext("token-label"),
2307c478bd9Sstevel@tonic-gate 	    gettext("slot-description"));
2317c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
232b5a2d845SHai-May Chao 	    "  cryptoadm enable fips-140\n");
233b5a2d845SHai-May Chao 	(void) fprintf(stderr,
2347c478bd9Sstevel@tonic-gate 	    "  cryptoadm install provider=<%s>\n",
2357c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
2367c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2377c478bd9Sstevel@tonic-gate 	    "  cryptoadm install provider=<%s> [mechanism=<%s>]\n",
2387c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
2397c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2407c478bd9Sstevel@tonic-gate 	    "  cryptoadm uninstall provider=<%s>\n",
2417c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
2427c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2437c478bd9Sstevel@tonic-gate 	    "  cryptoadm unload provider=<%s>\n",
2447c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
2457c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2467c478bd9Sstevel@tonic-gate 	    "  cryptoadm refresh\n"
2477c478bd9Sstevel@tonic-gate 	    "  cryptoadm start\n"
2487c478bd9Sstevel@tonic-gate 	    "  cryptoadm stop\n"
2497c478bd9Sstevel@tonic-gate 	    "  cryptoadm --help\n");
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate /*
2547c478bd9Sstevel@tonic-gate  * Get the provider type.  This function returns
2557c478bd9Sstevel@tonic-gate  * - PROV_UEF_LIB if provname contains an absolute path name
2561b22764fSDaniel OpenSolaris Anderson  * - PROV_KEF_SOFT if provname is a base name only (e.g., "aes").
2577c478bd9Sstevel@tonic-gate  * - PROV_KEF_HARD if provname contains one slash only and the slash is not
2581b22764fSDaniel OpenSolaris Anderson  *	the 1st character (e.g., "mca/0").
2590a85b835SDaniel Anderson  * - PROV_BADNAME otherwise.
2607c478bd9Sstevel@tonic-gate  */
2617c478bd9Sstevel@tonic-gate static int
2627c478bd9Sstevel@tonic-gate get_provider_type(char *provname)
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate 	char *pslash1;
2657c478bd9Sstevel@tonic-gate 	char *pslash2;
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	if (provname == NULL) {
2687c478bd9Sstevel@tonic-gate 		return (FAILURE);
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	if (provname[0] == '/') {
2727c478bd9Sstevel@tonic-gate 		return (PROV_UEF_LIB);
2737c478bd9Sstevel@tonic-gate 	} else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
2747c478bd9Sstevel@tonic-gate 		/* no slash */
2757c478bd9Sstevel@tonic-gate 		return (PROV_KEF_SOFT);
2767c478bd9Sstevel@tonic-gate 	} else {
2777c478bd9Sstevel@tonic-gate 		pslash2 = strrchr(provname, SEP_SLASH);
2787c478bd9Sstevel@tonic-gate 		if (pslash1 == pslash2) {
2797c478bd9Sstevel@tonic-gate 			return (PROV_KEF_HARD);
2807c478bd9Sstevel@tonic-gate 		} else {
2817c478bd9Sstevel@tonic-gate 			return (PROV_BADNAME);
2827c478bd9Sstevel@tonic-gate 		}
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate /*
2877c478bd9Sstevel@tonic-gate  * Get the provider structure.  This function returns NULL if no valid
2887c478bd9Sstevel@tonic-gate  * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned.
2897c478bd9Sstevel@tonic-gate  * If provider= is found but has no argument, then a cryptoadm_provider_t
2907c478bd9Sstevel@tonic-gate  * with cp_type = PROV_BADNAME is returned.
2917c478bd9Sstevel@tonic-gate  */
2927c478bd9Sstevel@tonic-gate static cryptoadm_provider_t *
2937c478bd9Sstevel@tonic-gate get_provider(int argc, char **argv)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	int			c = 0;
2967c478bd9Sstevel@tonic-gate 	boolean_t		found = B_FALSE;
2977c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*provider = NULL;
2987c478bd9Sstevel@tonic-gate 	char			*provstr = NULL, *savstr;
2997c478bd9Sstevel@tonic-gate 	boolean_t		is_metaslot = B_FALSE;
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	while (!found && ++c < argc) {
3027c478bd9Sstevel@tonic-gate 		if (strncmp(argv[c], METASLOT_KEYWORD,
3037c478bd9Sstevel@tonic-gate 		    strlen(METASLOT_KEYWORD)) == 0) {
3047c478bd9Sstevel@tonic-gate 			is_metaslot = B_TRUE;
3057c478bd9Sstevel@tonic-gate 			found = B_TRUE;
3067c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_PROVIDER,
3077c478bd9Sstevel@tonic-gate 		    strlen(KN_PROVIDER)) == 0 &&
3087c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_PROVIDER)) {
3097c478bd9Sstevel@tonic-gate 			if ((provstr = strdup(argv[c])) == NULL) {
3107c478bd9Sstevel@tonic-gate 				int err = errno;
3117c478bd9Sstevel@tonic-gate 				/*
3120a85b835SDaniel Anderson 				 * TRANSLATION_NOTE
3137c478bd9Sstevel@tonic-gate 				 * "get_provider" is a function name and should
3147c478bd9Sstevel@tonic-gate 				 * not be translated.
3157c478bd9Sstevel@tonic-gate 				 */
3167c478bd9Sstevel@tonic-gate 				cryptoerror(LOG_STDERR, "get_provider: %s.",
3177c478bd9Sstevel@tonic-gate 				    strerror(err));
3187c478bd9Sstevel@tonic-gate 				return (NULL);
3197c478bd9Sstevel@tonic-gate 			}
3207c478bd9Sstevel@tonic-gate 			found = B_TRUE;
3217c478bd9Sstevel@tonic-gate 		}
3227c478bd9Sstevel@tonic-gate 	}
3237c478bd9Sstevel@tonic-gate 	if (!found)
3247c478bd9Sstevel@tonic-gate 		return (NULL);
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	provider = malloc(sizeof (cryptoadm_provider_t));
3277c478bd9Sstevel@tonic-gate 	if (provider == NULL) {
3287c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("out of memory."));
3297c478bd9Sstevel@tonic-gate 		if (provstr) {
3307c478bd9Sstevel@tonic-gate 			free(provstr);
3317c478bd9Sstevel@tonic-gate 		}
3327c478bd9Sstevel@tonic-gate 		return (NULL);
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	if (is_metaslot) {
3367c478bd9Sstevel@tonic-gate 		(void) strlcpy(provider->cp_name, METASLOT_KEYWORD,
3377c478bd9Sstevel@tonic-gate 		    strlen(METASLOT_KEYWORD));
3387c478bd9Sstevel@tonic-gate 		provider->cp_type = METASLOT;
3397c478bd9Sstevel@tonic-gate 	} else {
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 		savstr = provstr;
3427c478bd9Sstevel@tonic-gate 		(void) strtok(provstr, "=");
3437c478bd9Sstevel@tonic-gate 		provstr = strtok(NULL, "=");
3447c478bd9Sstevel@tonic-gate 		if (provstr == NULL) {
3457c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("bad provider name."));
3467c478bd9Sstevel@tonic-gate 			provider->cp_type = PROV_BADNAME;
3477c478bd9Sstevel@tonic-gate 			free(savstr);
3487c478bd9Sstevel@tonic-gate 			return (provider);
3497c478bd9Sstevel@tonic-gate 		}
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 		(void) strlcpy(provider->cp_name, provstr,
3527c478bd9Sstevel@tonic-gate 		    sizeof (provider->cp_name));
3537c478bd9Sstevel@tonic-gate 		provider->cp_type = get_provider_type(provider->cp_name);
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 		free(savstr);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 	return (provider);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate /*
3617c478bd9Sstevel@tonic-gate  * Process the "feature" operands.
3627c478bd9Sstevel@tonic-gate  *
3637c478bd9Sstevel@tonic-gate  * "argc" and "argv" contain values specified on the command line.
3647c478bd9Sstevel@tonic-gate  * All other arguments are used for returning parsing results.
3657c478bd9Sstevel@tonic-gate  * If any of these arguments are NULL, that keyword is not expected,
3667c478bd9Sstevel@tonic-gate  * and FAILURE will be returned.
3677c478bd9Sstevel@tonic-gate  */
3687c478bd9Sstevel@tonic-gate static int
3697c478bd9Sstevel@tonic-gate process_metaslot_operands(int argc, char **argv, char **meta_ks_token,
3707c478bd9Sstevel@tonic-gate     char **meta_ks_slot, boolean_t *use_default,
3717c478bd9Sstevel@tonic-gate     boolean_t *auto_key_migrate_flag)
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	int c = 2;
3747c478bd9Sstevel@tonic-gate 	int rc = SUCCESS;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	while (++c < argc) {
3777c478bd9Sstevel@tonic-gate 		if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
3787c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_MECH)) {
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 			/* process mechanism operands */
3817c478bd9Sstevel@tonic-gate 			if ((rc = process_mech_operands(argc, argv, B_TRUE))
3827c478bd9Sstevel@tonic-gate 			    != SUCCESS) {
3837c478bd9Sstevel@tonic-gate 				goto finish;
3847c478bd9Sstevel@tonic-gate 			}
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 		} else if ((strncmp(argv[c], KN_TOKEN,
3877c478bd9Sstevel@tonic-gate 		    strlen(KN_TOKEN)) == 0) &&
3887c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_TOKEN)) {
3897c478bd9Sstevel@tonic-gate 			if ((meta_ks_token) && (strtok(argv[c], "=") != NULL)) {
3907c478bd9Sstevel@tonic-gate 				char *tmp;
3917c478bd9Sstevel@tonic-gate 				if ((tmp = strtok(NULL, "=")) != NULL) {
3927c478bd9Sstevel@tonic-gate 					*meta_ks_token = strdup(tmp);
3937c478bd9Sstevel@tonic-gate 				} else {
3947c478bd9Sstevel@tonic-gate 					return (FAILURE);
3957c478bd9Sstevel@tonic-gate 				}
3967c478bd9Sstevel@tonic-gate 			} else {
3977c478bd9Sstevel@tonic-gate 				return (FAILURE);
3987c478bd9Sstevel@tonic-gate 			}
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 		} else if ((strncmp(argv[c], KN_SLOT,
4017c478bd9Sstevel@tonic-gate 		    strlen(KN_SLOT)) == 0) &&
4027c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_SLOT)) {
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 			if ((meta_ks_slot) && (strtok(argv[c], "=") != NULL)) {
4057c478bd9Sstevel@tonic-gate 				char *tmp;
4067c478bd9Sstevel@tonic-gate 				if ((tmp = strtok(NULL, "=")) != NULL) {
4077c478bd9Sstevel@tonic-gate 					*meta_ks_slot = strdup(tmp);
4087c478bd9Sstevel@tonic-gate 				} else {
4097c478bd9Sstevel@tonic-gate 					return (FAILURE);
4107c478bd9Sstevel@tonic-gate 				}
4117c478bd9Sstevel@tonic-gate 			} else {
4127c478bd9Sstevel@tonic-gate 				return (FAILURE);
4137c478bd9Sstevel@tonic-gate 			}
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_DEFAULT_KS,
4167c478bd9Sstevel@tonic-gate 		    strlen(KN_DEFAULT_KS)) == 0) {
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 			if (use_default) {
4197c478bd9Sstevel@tonic-gate 				*use_default = B_TRUE;
4207c478bd9Sstevel@tonic-gate 			} else {
4217c478bd9Sstevel@tonic-gate 				return (FAILURE);
4227c478bd9Sstevel@tonic-gate 			}
4237c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_AUTO_KEY_MIGRATE,
4247c478bd9Sstevel@tonic-gate 		    strlen(KN_AUTO_KEY_MIGRATE)) == 0) {
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 			if (auto_key_migrate_flag) {
4277c478bd9Sstevel@tonic-gate 				*auto_key_migrate_flag = B_TRUE;
4287c478bd9Sstevel@tonic-gate 			} else {
4297c478bd9Sstevel@tonic-gate 				return (FAILURE);
4307c478bd9Sstevel@tonic-gate 			}
4317c478bd9Sstevel@tonic-gate 		} else {
4327c478bd9Sstevel@tonic-gate 			return (FAILURE);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate finish:
4367c478bd9Sstevel@tonic-gate 	return (rc);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate /*
4407c478bd9Sstevel@tonic-gate  * Process the "feature" operands.
4417c478bd9Sstevel@tonic-gate  */
4427c478bd9Sstevel@tonic-gate static int
4437c478bd9Sstevel@tonic-gate process_feature_operands(int argc, char **argv)
4447c478bd9Sstevel@tonic-gate {
4457c478bd9Sstevel@tonic-gate 	int c = 2;
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	while (++c < argc) {
4487c478bd9Sstevel@tonic-gate 		if (strcmp(argv[c], KN_ALL) == 0) {
4497c478bd9Sstevel@tonic-gate 			allflag = B_TRUE;
4507c478bd9Sstevel@tonic-gate 			rndflag = B_TRUE; /* all includes random also. */
4517c478bd9Sstevel@tonic-gate 		} else if (strcmp(argv[c], RANDOM) == 0) {
4527c478bd9Sstevel@tonic-gate 			rndflag = B_TRUE;
4537c478bd9Sstevel@tonic-gate 		}
4547c478bd9Sstevel@tonic-gate 	}
4557c478bd9Sstevel@tonic-gate 	return (SUCCESS);
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate /*
4597c478bd9Sstevel@tonic-gate  * Process the mechanism operands for the disable, enable and install
4607c478bd9Sstevel@tonic-gate  * subcommands.  This function sets the static variable allflag to be B_TRUE
4617c478bd9Sstevel@tonic-gate  * if the keyword "all" is specified, otherwise builds a link list of the
4627c478bd9Sstevel@tonic-gate  * mechanism operands and save it in the static variable mecharglist.
4637c478bd9Sstevel@tonic-gate  *
4647c478bd9Sstevel@tonic-gate  * This function returns
4657c478bd9Sstevel@tonic-gate  *	ERROR_USAGE: mechanism operand is missing.
4667c478bd9Sstevel@tonic-gate  *	FAILURE: out of memory.
4677c478bd9Sstevel@tonic-gate  *	SUCCESS: otherwise.
4687c478bd9Sstevel@tonic-gate  */
4697c478bd9Sstevel@tonic-gate static int
4707c478bd9Sstevel@tonic-gate process_mech_operands(int argc, char **argv, boolean_t quiet)
4717c478bd9Sstevel@tonic-gate {
4727c478bd9Sstevel@tonic-gate 	mechlist_t	*pmech;
4737c478bd9Sstevel@tonic-gate 	mechlist_t	*pcur = NULL;
4747c478bd9Sstevel@tonic-gate 	mechlist_t	*phead = NULL;
4757c478bd9Sstevel@tonic-gate 	boolean_t	found = B_FALSE;
4767c478bd9Sstevel@tonic-gate 	char		*mechliststr = NULL;
4777c478bd9Sstevel@tonic-gate 	char		*curmech = NULL;
4787c478bd9Sstevel@tonic-gate 	int		c = -1;
4797c478bd9Sstevel@tonic-gate 	int		rc = SUCCESS;
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 	while (!found && ++c < argc) {
4827c478bd9Sstevel@tonic-gate 		if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
4837c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_MECH)) {
4847c478bd9Sstevel@tonic-gate 			found = B_TRUE;
4857c478bd9Sstevel@tonic-gate 		}
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 	if (!found) {
4887c478bd9Sstevel@tonic-gate 		if (!quiet)
4897c478bd9Sstevel@tonic-gate 			/*
4900a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
4917c478bd9Sstevel@tonic-gate 			 * "mechanism" could be either a literal keyword
4927c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a descriptive
4937c478bd9Sstevel@tonic-gate 			 * word and translatable.  A choice was made to
4947c478bd9Sstevel@tonic-gate 			 * view it as a literal keyword.
4957c478bd9Sstevel@tonic-gate 			 */
4967c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR,
4977c478bd9Sstevel@tonic-gate 			    gettext("the %s operand is missing.\n"),
4987c478bd9Sstevel@tonic-gate 			    "mechanism");
4997c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
5007c478bd9Sstevel@tonic-gate 	}
5017c478bd9Sstevel@tonic-gate 	(void) strtok(argv[c], "=");
5027c478bd9Sstevel@tonic-gate 	mechliststr = strtok(NULL, "=");
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 	if (strcmp(mechliststr, "all") == 0) {
5057c478bd9Sstevel@tonic-gate 		allflag = B_TRUE;
5067c478bd9Sstevel@tonic-gate 		mecharglist = NULL;
5077c478bd9Sstevel@tonic-gate 		return (SUCCESS);
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	curmech = strtok(mechliststr, ",");
5117c478bd9Sstevel@tonic-gate 	do {
5127c478bd9Sstevel@tonic-gate 		if ((pmech = create_mech(curmech)) == NULL) {
5137c478bd9Sstevel@tonic-gate 			rc = FAILURE;
5147c478bd9Sstevel@tonic-gate 			break;
5157c478bd9Sstevel@tonic-gate 		} else {
5167c478bd9Sstevel@tonic-gate 			if (phead == NULL) {
5177c478bd9Sstevel@tonic-gate 				phead = pcur = pmech;
5187c478bd9Sstevel@tonic-gate 			} else {
5197c478bd9Sstevel@tonic-gate 				pcur->next = pmech;
5207c478bd9Sstevel@tonic-gate 				pcur = pmech;
5217c478bd9Sstevel@tonic-gate 			}
5227c478bd9Sstevel@tonic-gate 		}
5237c478bd9Sstevel@tonic-gate 	} while ((curmech = strtok(NULL, ",")) != NULL);
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
5267c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("out of memory."));
5277c478bd9Sstevel@tonic-gate 		free_mechlist(phead);
5287c478bd9Sstevel@tonic-gate 	} else {
5297c478bd9Sstevel@tonic-gate 		mecharglist = phead;
5307c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
5317c478bd9Sstevel@tonic-gate 	}
5327c478bd9Sstevel@tonic-gate 	return (rc);
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate /*
5381b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm list" subcommand and options.
5397c478bd9Sstevel@tonic-gate  */
5407c478bd9Sstevel@tonic-gate static int
5417c478bd9Sstevel@tonic-gate do_list(int argc, char **argv)
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate 	boolean_t		mflag = B_FALSE;
5447c478bd9Sstevel@tonic-gate 	boolean_t		pflag = B_FALSE;
5457c478bd9Sstevel@tonic-gate 	boolean_t		vflag = B_FALSE;
5467c478bd9Sstevel@tonic-gate 	char			ch;
5477c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
5487c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
5497c478bd9Sstevel@tonic-gate 
550b5a2d845SHai-May Chao 	if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD,
551b5a2d845SHai-May Chao 	    strlen(FIPS_KEYWORD))) == 0) {
552*32e0ab73SMisaki Miyashita 		int	success_count = 0;
553b5a2d845SHai-May Chao 		/*
554b5a2d845SHai-May Chao 		 * cryptoadm list fips-140
555b5a2d845SHai-May Chao 		 */
556b5a2d845SHai-May Chao 		rc = do_fips_actions(FIPS140_STATUS, NOT_REFRESH);
557*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
558*32e0ab73SMisaki Miyashita 			success_count++;
559*32e0ab73SMisaki Miyashita 		(void) printf(gettext("\nKernel hardware providers:\n"));
560*32e0ab73SMisaki Miyashita 		(void) printf(gettext("=========================:\n"));
561*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_STATUS, HW_PROVIDER_NCP);
562*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
563*32e0ab73SMisaki Miyashita 			success_count++;
564*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_STATUS, HW_PROVIDER_N2CP);
565*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
566*32e0ab73SMisaki Miyashita 			success_count++;
567*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_STATUS, HW_PROVIDER_N2RNG);
568*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
569*32e0ab73SMisaki Miyashita 			success_count++;
570*32e0ab73SMisaki Miyashita 		/* succeed to get status from config file? */
571*32e0ab73SMisaki Miyashita 		return ((success_count > 0) ? SUCCESS: FAILURE);
572b5a2d845SHai-May Chao 	}
573b5a2d845SHai-May Chao 
5747c478bd9Sstevel@tonic-gate 	argc -= 1;
5757c478bd9Sstevel@tonic-gate 	argv += 1;
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	if (argc == 1) {
5787c478bd9Sstevel@tonic-gate 		rc = list_simple_for_all(B_FALSE);
5797c478bd9Sstevel@tonic-gate 		goto out;
5807c478bd9Sstevel@tonic-gate 	}
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	/*
5831b22764fSDaniel OpenSolaris Anderson 	 * cryptoadm list [-v] [-m] [-p] [provider=<>] [mechanism=<>]
5847c478bd9Sstevel@tonic-gate 	 */
5857c478bd9Sstevel@tonic-gate 	if (argc > 5) {
5867c478bd9Sstevel@tonic-gate 		usage();
5877c478bd9Sstevel@tonic-gate 		return (rc);
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	while ((ch = getopt(argc, argv, "mpv")) != EOF) {
5917c478bd9Sstevel@tonic-gate 		switch (ch) {
5927c478bd9Sstevel@tonic-gate 		case 'm':
5937c478bd9Sstevel@tonic-gate 			mflag = B_TRUE;
5947c478bd9Sstevel@tonic-gate 			if (pflag) {
5957c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
5967c478bd9Sstevel@tonic-gate 			}
5977c478bd9Sstevel@tonic-gate 			break;
5987c478bd9Sstevel@tonic-gate 		case 'p':
5997c478bd9Sstevel@tonic-gate 			pflag = B_TRUE;
6007c478bd9Sstevel@tonic-gate 			if (mflag || vflag) {
6017c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
6027c478bd9Sstevel@tonic-gate 			}
6037c478bd9Sstevel@tonic-gate 			break;
6047c478bd9Sstevel@tonic-gate 		case 'v':
6057c478bd9Sstevel@tonic-gate 			vflag = B_TRUE;
6067c478bd9Sstevel@tonic-gate 			if (pflag)
6077c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
6087c478bd9Sstevel@tonic-gate 			break;
6097c478bd9Sstevel@tonic-gate 		default:
6107c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
6117c478bd9Sstevel@tonic-gate 			break;
6127c478bd9Sstevel@tonic-gate 		}
6137c478bd9Sstevel@tonic-gate 	}
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	if (rc == ERROR_USAGE) {
6167c478bd9Sstevel@tonic-gate 		usage();
6177c478bd9Sstevel@tonic-gate 		return (rc);
6187c478bd9Sstevel@tonic-gate 	}
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 	if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
6217c478bd9Sstevel@tonic-gate 		goto out;
6227c478bd9Sstevel@tonic-gate 	}
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 	if (mflag || vflag) {
6277c478bd9Sstevel@tonic-gate 		if (argc > 0) {
6287c478bd9Sstevel@tonic-gate 			rc = process_mech_operands(argc, argv, B_TRUE);
6297c478bd9Sstevel@tonic-gate 			if (rc == FAILURE)
6307c478bd9Sstevel@tonic-gate 				goto out;
6317c478bd9Sstevel@tonic-gate 			/* "-m" is implied when a mechanism list is given */
6327c478bd9Sstevel@tonic-gate 			if (mecharglist != NULL || allflag)
6337c478bd9Sstevel@tonic-gate 				mflag = B_TRUE;
6347c478bd9Sstevel@tonic-gate 		}
6357c478bd9Sstevel@tonic-gate 	}
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
6387c478bd9Sstevel@tonic-gate 		if (mflag) {
6397c478bd9Sstevel@tonic-gate 			rc = list_mechlist_for_all(vflag);
6407c478bd9Sstevel@tonic-gate 		} else if (pflag) {
6417c478bd9Sstevel@tonic-gate 			rc = list_policy_for_all();
6427c478bd9Sstevel@tonic-gate 		} else if (vflag) {
6437c478bd9Sstevel@tonic-gate 			rc = list_simple_for_all(vflag);
6447c478bd9Sstevel@tonic-gate 		}
6457c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == METASLOT) {
6467c478bd9Sstevel@tonic-gate 		if ((!mflag) && (!vflag) && (!pflag)) {
6477c478bd9Sstevel@tonic-gate 			/* no flag is specified, just list metaslot status */
6487c478bd9Sstevel@tonic-gate 			rc = list_metaslot_info(mflag, vflag, mecharglist);
6497c478bd9Sstevel@tonic-gate 		} else if (mflag || vflag) {
6507c478bd9Sstevel@tonic-gate 			rc = list_metaslot_info(mflag, vflag, mecharglist);
6517c478bd9Sstevel@tonic-gate 		} else if (pflag) {
6527c478bd9Sstevel@tonic-gate 			rc = list_metaslot_policy();
6537c478bd9Sstevel@tonic-gate 		} else {
6547c478bd9Sstevel@tonic-gate 			/* error message */
6557c478bd9Sstevel@tonic-gate 			usage();
6567c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
6577c478bd9Sstevel@tonic-gate 		}
6587c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == PROV_BADNAME) {
6597c478bd9Sstevel@tonic-gate 		usage();
6607c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
6617c478bd9Sstevel@tonic-gate 		goto out;
6627c478bd9Sstevel@tonic-gate 	} else { /* do the listing for a provider only */
6631b22764fSDaniel OpenSolaris Anderson 		char	*provname = prov->cp_name;
6641b22764fSDaniel OpenSolaris Anderson 
6657c478bd9Sstevel@tonic-gate 		if (mflag || vflag) {
6667c478bd9Sstevel@tonic-gate 			if (vflag)
6677c478bd9Sstevel@tonic-gate 				(void) printf(gettext("Provider: %s\n"),
6681b22764fSDaniel OpenSolaris Anderson 				    provname);
6697c478bd9Sstevel@tonic-gate 			switch (prov->cp_type) {
6707c478bd9Sstevel@tonic-gate 			case PROV_UEF_LIB:
6711b22764fSDaniel OpenSolaris Anderson 				rc = list_mechlist_for_lib(provname,
6721b22764fSDaniel OpenSolaris Anderson 				    mecharglist, NULL, B_FALSE, vflag, mflag);
6737c478bd9Sstevel@tonic-gate 				break;
6747c478bd9Sstevel@tonic-gate 			case PROV_KEF_SOFT:
6751b22764fSDaniel OpenSolaris Anderson 				rc = list_mechlist_for_soft(provname,
676d616ad8eSHai-May Chao 				    NULL, NULL);
6777c478bd9Sstevel@tonic-gate 				break;
6787c478bd9Sstevel@tonic-gate 			case PROV_KEF_HARD:
6791b22764fSDaniel OpenSolaris Anderson 				rc = list_mechlist_for_hard(provname);
6807c478bd9Sstevel@tonic-gate 				break;
6817c478bd9Sstevel@tonic-gate 			default: /* should not come here */
6827c478bd9Sstevel@tonic-gate 				rc = FAILURE;
6837c478bd9Sstevel@tonic-gate 				break;
6847c478bd9Sstevel@tonic-gate 			}
6857c478bd9Sstevel@tonic-gate 		} else if (pflag) {
6867c478bd9Sstevel@tonic-gate 			switch (prov->cp_type) {
6877c478bd9Sstevel@tonic-gate 			case PROV_UEF_LIB:
6881b22764fSDaniel OpenSolaris Anderson 				rc = list_policy_for_lib(provname);
6897c478bd9Sstevel@tonic-gate 				break;
6907c478bd9Sstevel@tonic-gate 			case PROV_KEF_SOFT:
6917c478bd9Sstevel@tonic-gate 				if (getzoneid() == GLOBAL_ZONEID) {
6921b22764fSDaniel OpenSolaris Anderson 					rc = list_policy_for_soft(provname,
693d616ad8eSHai-May Chao 					    NULL, NULL);
6947c478bd9Sstevel@tonic-gate 				} else {
6957c478bd9Sstevel@tonic-gate 					/*
6960a85b835SDaniel Anderson 					 * TRANSLATION_NOTE
6977c478bd9Sstevel@tonic-gate 					 * "global" is keyword and not to
6987c478bd9Sstevel@tonic-gate 					 * be translated.
6997c478bd9Sstevel@tonic-gate 					 */
7007c478bd9Sstevel@tonic-gate 					cryptoerror(LOG_STDERR, gettext(
7017c478bd9Sstevel@tonic-gate 					    "policy information for kernel "
7027c478bd9Sstevel@tonic-gate 					    "providers is available "
7037c478bd9Sstevel@tonic-gate 					    "in the %s zone only"), "global");
7047c478bd9Sstevel@tonic-gate 					rc = FAILURE;
7057c478bd9Sstevel@tonic-gate 				}
7067c478bd9Sstevel@tonic-gate 				break;
7077c478bd9Sstevel@tonic-gate 			case PROV_KEF_HARD:
7087c478bd9Sstevel@tonic-gate 				if (getzoneid() == GLOBAL_ZONEID) {
7097c478bd9Sstevel@tonic-gate 					rc = list_policy_for_hard(
710d616ad8eSHai-May Chao 					    provname, NULL, NULL, NULL);
7117c478bd9Sstevel@tonic-gate 				} else {
7127c478bd9Sstevel@tonic-gate 					/*
7130a85b835SDaniel Anderson 					 * TRANSLATION_NOTE
7147c478bd9Sstevel@tonic-gate 					 * "global" is keyword and not to
7157c478bd9Sstevel@tonic-gate 					 * be translated.
7167c478bd9Sstevel@tonic-gate 					 */
7177c478bd9Sstevel@tonic-gate 					cryptoerror(LOG_STDERR, gettext(
7187c478bd9Sstevel@tonic-gate 					    "policy information for kernel "
7197c478bd9Sstevel@tonic-gate 					    "providers is available "
7207c478bd9Sstevel@tonic-gate 					    "in the %s zone only"), "global");
7217c478bd9Sstevel@tonic-gate 					rc = FAILURE;
7227c478bd9Sstevel@tonic-gate 				}
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 				break;
7257c478bd9Sstevel@tonic-gate 			default: /* should not come here */
7267c478bd9Sstevel@tonic-gate 				rc = FAILURE;
7277c478bd9Sstevel@tonic-gate 				break;
7287c478bd9Sstevel@tonic-gate 			}
7297c478bd9Sstevel@tonic-gate 		} else {
7307c478bd9Sstevel@tonic-gate 			/* error message */
7317c478bd9Sstevel@tonic-gate 			usage();
7327c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
7337c478bd9Sstevel@tonic-gate 		}
7347c478bd9Sstevel@tonic-gate 	}
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate out:
7377c478bd9Sstevel@tonic-gate 	if (prov != NULL)
7387c478bd9Sstevel@tonic-gate 		free(prov);
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL)
7417c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
7427c478bd9Sstevel@tonic-gate 	return (rc);
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate /*
7471b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm disable" subcommand.
7487c478bd9Sstevel@tonic-gate  */
7497c478bd9Sstevel@tonic-gate static int
7507c478bd9Sstevel@tonic-gate do_disable(int argc, char **argv)
7517c478bd9Sstevel@tonic-gate {
7527c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
7537c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
7547c478bd9Sstevel@tonic-gate 	boolean_t		auto_key_migrate_flag = B_FALSE;
7557c478bd9Sstevel@tonic-gate 
756b5a2d845SHai-May Chao 	if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD,
757b5a2d845SHai-May Chao 	    strlen(FIPS_KEYWORD))) == 0) {
758*32e0ab73SMisaki Miyashita 		int	success_count = 0;
759b5a2d845SHai-May Chao 		/*
760b5a2d845SHai-May Chao 		 * cryptoadm disable fips-140
761b5a2d845SHai-May Chao 		 */
762b5a2d845SHai-May Chao 		rc = do_fips_actions(FIPS140_DISABLE, NOT_REFRESH);
763*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
764*32e0ab73SMisaki Miyashita 			success_count++;
765*32e0ab73SMisaki Miyashita 		(void) printf(gettext("\nKernel hardware providers:\n"));
766*32e0ab73SMisaki Miyashita 		(void) printf(gettext("=========================:\n"));
767*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_DISABLE, HW_PROVIDER_NCP);
768*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
769*32e0ab73SMisaki Miyashita 			success_count++;
770*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_DISABLE, HW_PROVIDER_N2CP);
771*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
772*32e0ab73SMisaki Miyashita 			success_count++;
773*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_DISABLE, HW_PROVIDER_N2RNG);
774*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
775*32e0ab73SMisaki Miyashita 			success_count++;
776*32e0ab73SMisaki Miyashita 
777*32e0ab73SMisaki Miyashita 		if (success_count > 0) {
778*32e0ab73SMisaki Miyashita 			(void) printf(gettext(
779*32e0ab73SMisaki Miyashita 			    "\nThe FIPS-140 mode has changed.\n"));
780*32e0ab73SMisaki Miyashita 			(void) printf(gettext(
781*32e0ab73SMisaki Miyashita 			    "The system will require a reboot.\n"));
782*32e0ab73SMisaki Miyashita 			return (SUCCESS);
783*32e0ab73SMisaki Miyashita 		} else {
784*32e0ab73SMisaki Miyashita 			return (FAILURE);
785*32e0ab73SMisaki Miyashita 		}
786b5a2d845SHai-May Chao 	}
787b5a2d845SHai-May Chao 
7887c478bd9Sstevel@tonic-gate 	if ((argc < 3) || (argc > 5)) {
7897c478bd9Sstevel@tonic-gate 		usage();
7907c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
7917c478bd9Sstevel@tonic-gate 	}
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
7947c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
7957c478bd9Sstevel@tonic-gate 		usage();
7967c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
7977c478bd9Sstevel@tonic-gate 	}
7987c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_BADNAME) {
7997c478bd9Sstevel@tonic-gate 		return (FAILURE);
8007c478bd9Sstevel@tonic-gate 	}
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate 	if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
8037c478bd9Sstevel@tonic-gate 		goto out;
8047c478bd9Sstevel@tonic-gate 	}
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	/*
8077c478bd9Sstevel@tonic-gate 	 * If allflag or rndflag has already been set there is no reason to
8087c478bd9Sstevel@tonic-gate 	 * process mech=
8097c478bd9Sstevel@tonic-gate 	 */
8107c478bd9Sstevel@tonic-gate 	if (prov->cp_type == METASLOT) {
8117c478bd9Sstevel@tonic-gate 		if ((argc > 3) &&
8127c478bd9Sstevel@tonic-gate 		    (rc = process_metaslot_operands(argc, argv,
8137c478bd9Sstevel@tonic-gate 		    NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) {
8147c478bd9Sstevel@tonic-gate 			usage();
8157c478bd9Sstevel@tonic-gate 			return (rc);
8167c478bd9Sstevel@tonic-gate 		}
8177c478bd9Sstevel@tonic-gate 	} else if (!allflag && !rndflag &&
8187c478bd9Sstevel@tonic-gate 	    (rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
8197c478bd9Sstevel@tonic-gate 			return (rc);
8207c478bd9Sstevel@tonic-gate 	}
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate 	switch (prov->cp_type) {
8237c478bd9Sstevel@tonic-gate 	case METASLOT:
8247c478bd9Sstevel@tonic-gate 		rc = disable_metaslot(mecharglist, allflag,
8257c478bd9Sstevel@tonic-gate 		    auto_key_migrate_flag);
8267c478bd9Sstevel@tonic-gate 		break;
8277c478bd9Sstevel@tonic-gate 	case PROV_UEF_LIB:
8287c478bd9Sstevel@tonic-gate 		rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
8297c478bd9Sstevel@tonic-gate 		    mecharglist);
8307c478bd9Sstevel@tonic-gate 		break;
8317c478bd9Sstevel@tonic-gate 	case PROV_KEF_SOFT:
8327c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
8337c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
8347c478bd9Sstevel@tonic-gate 				rc = FAILURE;
8357c478bd9Sstevel@tonic-gate 				break;
8367c478bd9Sstevel@tonic-gate 			}
8377c478bd9Sstevel@tonic-gate 		}
8387c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
8397c478bd9Sstevel@tonic-gate 			rc = disable_kef_software(prov->cp_name, rndflag,
8407c478bd9Sstevel@tonic-gate 			    allflag, mecharglist);
8417c478bd9Sstevel@tonic-gate 		} else {
8427c478bd9Sstevel@tonic-gate 			/*
8430a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
8447c478bd9Sstevel@tonic-gate 			 * "disable" could be either a literal keyword
8457c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
8467c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
8477c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
8487c478bd9Sstevel@tonic-gate 			 * to be translated.
8497c478bd9Sstevel@tonic-gate 			 */
8507c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
8517c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
8527c478bd9Sstevel@tonic-gate 			    "disable", "global");
8537c478bd9Sstevel@tonic-gate 			rc = FAILURE;
8547c478bd9Sstevel@tonic-gate 		}
8557c478bd9Sstevel@tonic-gate 		break;
8567c478bd9Sstevel@tonic-gate 	case PROV_KEF_HARD:
8577c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
8587c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
8597c478bd9Sstevel@tonic-gate 				rc = FAILURE;
8607c478bd9Sstevel@tonic-gate 				break;
8617c478bd9Sstevel@tonic-gate 			}
8627c478bd9Sstevel@tonic-gate 		}
8637c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
8647c478bd9Sstevel@tonic-gate 			rc = disable_kef_hardware(prov->cp_name, rndflag,
8657c478bd9Sstevel@tonic-gate 			    allflag, mecharglist);
8667c478bd9Sstevel@tonic-gate 		} else {
8677c478bd9Sstevel@tonic-gate 			/*
8680a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
8697c478bd9Sstevel@tonic-gate 			 * "disable" could be either a literal keyword
8707c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
8717c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
8727c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
8737c478bd9Sstevel@tonic-gate 			 * to be translated.
8747c478bd9Sstevel@tonic-gate 			 */
8757c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
8767c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
8777c478bd9Sstevel@tonic-gate 			    "disable", "global");
8787c478bd9Sstevel@tonic-gate 			rc = FAILURE;
8797c478bd9Sstevel@tonic-gate 		}
8807c478bd9Sstevel@tonic-gate 		break;
8817c478bd9Sstevel@tonic-gate 	default: /* should not come here */
8827c478bd9Sstevel@tonic-gate 		rc = FAILURE;
8837c478bd9Sstevel@tonic-gate 		break;
8847c478bd9Sstevel@tonic-gate 	}
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate out:
8877c478bd9Sstevel@tonic-gate 	free(prov);
8887c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL) {
8897c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
8907c478bd9Sstevel@tonic-gate 	}
8917c478bd9Sstevel@tonic-gate 	return (rc);
8927c478bd9Sstevel@tonic-gate }
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate /*
8961b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm enable" subcommand.
8977c478bd9Sstevel@tonic-gate  */
8987c478bd9Sstevel@tonic-gate static int
8997c478bd9Sstevel@tonic-gate do_enable(int argc, char **argv)
9007c478bd9Sstevel@tonic-gate {
9017c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
9027c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
9037c478bd9Sstevel@tonic-gate 	char 			*alt_token = NULL, *alt_slot = NULL;
9041b22764fSDaniel OpenSolaris Anderson 	boolean_t		use_default = B_FALSE;
9051b22764fSDaniel OpenSolaris Anderson 	boolean_t		auto_key_migrate_flag = B_FALSE;
9067c478bd9Sstevel@tonic-gate 
907b5a2d845SHai-May Chao 	if ((argc == 3) && (strncmp(argv[2], FIPS_KEYWORD,
908b5a2d845SHai-May Chao 	    strlen(FIPS_KEYWORD))) == 0) {
909*32e0ab73SMisaki Miyashita 		int	success_count = 0;
910b5a2d845SHai-May Chao 		/*
911b5a2d845SHai-May Chao 		 * cryptoadm enable fips-140
912b5a2d845SHai-May Chao 		 */
913b5a2d845SHai-May Chao 		rc = do_fips_actions(FIPS140_ENABLE, NOT_REFRESH);
914*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
915*32e0ab73SMisaki Miyashita 			success_count++;
916*32e0ab73SMisaki Miyashita 		(void) printf(gettext("\nKernel hardware providers:\n"));
917*32e0ab73SMisaki Miyashita 		(void) printf(gettext("=========================:\n"));
918*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_ENABLE, HW_PROVIDER_NCP);
919*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
920*32e0ab73SMisaki Miyashita 			success_count++;
921*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_ENABLE, HW_PROVIDER_N2CP);
922*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
923*32e0ab73SMisaki Miyashita 			success_count++;
924*32e0ab73SMisaki Miyashita 		rc = do_fips_hw_actions(FIPS140_ENABLE, HW_PROVIDER_N2RNG);
925*32e0ab73SMisaki Miyashita 		if (rc == SUCCESS)
926*32e0ab73SMisaki Miyashita 			success_count++;
927*32e0ab73SMisaki Miyashita 
928*32e0ab73SMisaki Miyashita 		if (success_count > 0) {
929*32e0ab73SMisaki Miyashita 			(void) printf(gettext(
930*32e0ab73SMisaki Miyashita 			    "\nThe FIPS-140 mode has changed.\n"));
931*32e0ab73SMisaki Miyashita 			(void) printf(gettext(
932*32e0ab73SMisaki Miyashita 			    "The system will require a reboot.\n"));
933*32e0ab73SMisaki Miyashita 			return (SUCCESS);
934*32e0ab73SMisaki Miyashita 		} else {
935*32e0ab73SMisaki Miyashita 			return (FAILURE);
936*32e0ab73SMisaki Miyashita 		}
937b5a2d845SHai-May Chao 	}
938b5a2d845SHai-May Chao 
9397c478bd9Sstevel@tonic-gate 	if ((argc < 3) || (argc > 6)) {
9407c478bd9Sstevel@tonic-gate 		usage();
9417c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
9427c478bd9Sstevel@tonic-gate 	}
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
9457c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
9467c478bd9Sstevel@tonic-gate 		usage();
9477c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
9487c478bd9Sstevel@tonic-gate 	}
9497c478bd9Sstevel@tonic-gate 	if ((prov->cp_type != METASLOT) && (argc != 4)) {
9507c478bd9Sstevel@tonic-gate 		usage();
9517c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
9527c478bd9Sstevel@tonic-gate 	}
9537c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_BADNAME) {
9547c478bd9Sstevel@tonic-gate 		rc = FAILURE;
9557c478bd9Sstevel@tonic-gate 		goto out;
9567c478bd9Sstevel@tonic-gate 	}
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 	if (prov->cp_type == METASLOT) {
9607c478bd9Sstevel@tonic-gate 		if ((rc = process_metaslot_operands(argc, argv, &alt_token,
9617c478bd9Sstevel@tonic-gate 		    &alt_slot, &use_default, &auto_key_migrate_flag))
9627c478bd9Sstevel@tonic-gate 		    != SUCCESS) {
9637c478bd9Sstevel@tonic-gate 			usage();
9647c478bd9Sstevel@tonic-gate 			goto out;
9657c478bd9Sstevel@tonic-gate 		}
9667c478bd9Sstevel@tonic-gate 		if ((alt_slot || alt_token) && use_default) {
9677c478bd9Sstevel@tonic-gate 			usage();
9687c478bd9Sstevel@tonic-gate 			rc = FAILURE;
9697c478bd9Sstevel@tonic-gate 			goto out;
9707c478bd9Sstevel@tonic-gate 		}
9717c478bd9Sstevel@tonic-gate 	} else {
9727c478bd9Sstevel@tonic-gate 		if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
9737c478bd9Sstevel@tonic-gate 			goto out;
9747c478bd9Sstevel@tonic-gate 		}
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 		/*
9777c478bd9Sstevel@tonic-gate 		 * If allflag or rndflag has already been set there is
9787c478bd9Sstevel@tonic-gate 		 * no reason to process mech=
9797c478bd9Sstevel@tonic-gate 		 */
9807c478bd9Sstevel@tonic-gate 		if (!allflag && !rndflag &&
9817c478bd9Sstevel@tonic-gate 		    (rc = process_mech_operands(argc, argv, B_FALSE))
9827c478bd9Sstevel@tonic-gate 		    != SUCCESS) {
9837c478bd9Sstevel@tonic-gate 			goto out;
9847c478bd9Sstevel@tonic-gate 		}
9857c478bd9Sstevel@tonic-gate 	}
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate 	switch (prov->cp_type) {
9887c478bd9Sstevel@tonic-gate 	case METASLOT:
9897c478bd9Sstevel@tonic-gate 		rc = enable_metaslot(alt_token, alt_slot, use_default,
9907c478bd9Sstevel@tonic-gate 		    mecharglist, allflag, auto_key_migrate_flag);
9917c478bd9Sstevel@tonic-gate 		break;
9927c478bd9Sstevel@tonic-gate 	case PROV_UEF_LIB:
9937c478bd9Sstevel@tonic-gate 		rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
9947c478bd9Sstevel@tonic-gate 		    mecharglist);
9957c478bd9Sstevel@tonic-gate 		break;
9967c478bd9Sstevel@tonic-gate 	case PROV_KEF_SOFT:
9977c478bd9Sstevel@tonic-gate 	case PROV_KEF_HARD:
9987c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
9997c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
10007c478bd9Sstevel@tonic-gate 				rc = FAILURE;
10017c478bd9Sstevel@tonic-gate 				break;
10027c478bd9Sstevel@tonic-gate 			}
10037c478bd9Sstevel@tonic-gate 		}
10047c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
10057c478bd9Sstevel@tonic-gate 			rc = enable_kef(prov->cp_name, rndflag, allflag,
10067c478bd9Sstevel@tonic-gate 			    mecharglist);
10077c478bd9Sstevel@tonic-gate 		} else {
10087c478bd9Sstevel@tonic-gate 			/*
10090a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
10107c478bd9Sstevel@tonic-gate 			 * "enable" could be either a literal keyword
10117c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
10127c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
10137c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
10147c478bd9Sstevel@tonic-gate 			 * to be translated.
10157c478bd9Sstevel@tonic-gate 			 */
10167c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
10177c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
10187c478bd9Sstevel@tonic-gate 			    "enable", "global");
10197c478bd9Sstevel@tonic-gate 			rc = FAILURE;
10207c478bd9Sstevel@tonic-gate 		}
10217c478bd9Sstevel@tonic-gate 		break;
10227c478bd9Sstevel@tonic-gate 	default: /* should not come here */
10237c478bd9Sstevel@tonic-gate 		rc = FAILURE;
10247c478bd9Sstevel@tonic-gate 		break;
10257c478bd9Sstevel@tonic-gate 	}
10267c478bd9Sstevel@tonic-gate out:
10277c478bd9Sstevel@tonic-gate 	free(prov);
10287c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL) {
10297c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
10307c478bd9Sstevel@tonic-gate 	}
10317c478bd9Sstevel@tonic-gate 	if (alt_token != NULL) {
10327c478bd9Sstevel@tonic-gate 		free(alt_token);
10337c478bd9Sstevel@tonic-gate 	}
10347c478bd9Sstevel@tonic-gate 	if (alt_slot != NULL) {
10357c478bd9Sstevel@tonic-gate 		free(alt_slot);
10367c478bd9Sstevel@tonic-gate 	}
10377c478bd9Sstevel@tonic-gate 	return (rc);
10387c478bd9Sstevel@tonic-gate }
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate /*
10431b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm install" subcommand.
10447c478bd9Sstevel@tonic-gate  */
10457c478bd9Sstevel@tonic-gate static int
10467c478bd9Sstevel@tonic-gate do_install(int argc, char **argv)
10477c478bd9Sstevel@tonic-gate {
10487c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
10497c478bd9Sstevel@tonic-gate 	int	rc;
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 	if (argc < 3) {
10527c478bd9Sstevel@tonic-gate 		usage();
10537c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
10547c478bd9Sstevel@tonic-gate 	}
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
10577c478bd9Sstevel@tonic-gate 	if (prov == NULL ||
10587c478bd9Sstevel@tonic-gate 	    prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
10597c478bd9Sstevel@tonic-gate 		/*
10600a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
10617c478bd9Sstevel@tonic-gate 		 * "install" could be either a literal keyword and hence
10627c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
10637c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
10647c478bd9Sstevel@tonic-gate 		 */
10657c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
10667c478bd9Sstevel@tonic-gate 		    gettext("bad provider name for %s."), "install");
10677c478bd9Sstevel@tonic-gate 		rc = FAILURE;
10687c478bd9Sstevel@tonic-gate 		goto out;
10697c478bd9Sstevel@tonic-gate 	}
10707c478bd9Sstevel@tonic-gate 
10717c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_UEF_LIB) {
10727c478bd9Sstevel@tonic-gate 		rc = install_uef_lib(prov->cp_name);
10737c478bd9Sstevel@tonic-gate 		goto out;
10747c478bd9Sstevel@tonic-gate 	}
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 	/* It is the PROV_KEF_SOFT type now  */
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	/* check if there are mechanism operands */
10797c478bd9Sstevel@tonic-gate 	if (argc < 4) {
10807c478bd9Sstevel@tonic-gate 		/*
10810a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
10827c478bd9Sstevel@tonic-gate 		 * "mechanism" could be either a literal keyword and hence
10837c478bd9Sstevel@tonic-gate 		 * not to be translated, or a descriptive word and
10847c478bd9Sstevel@tonic-gate 		 * translatable.  A choice was made to view it as a literal
10857c478bd9Sstevel@tonic-gate 		 * keyword.
10867c478bd9Sstevel@tonic-gate 		 */
10877c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
10887c478bd9Sstevel@tonic-gate 		    gettext("need %s operands for installing a"
10897c478bd9Sstevel@tonic-gate 		    " kernel software provider."), "mechanism");
10907c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
10917c478bd9Sstevel@tonic-gate 		goto out;
10927c478bd9Sstevel@tonic-gate 	}
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 	if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
10957c478bd9Sstevel@tonic-gate 		goto out;
10967c478bd9Sstevel@tonic-gate 	}
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 	if (allflag == B_TRUE) {
10997c478bd9Sstevel@tonic-gate 		/*
11000a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
11017c478bd9Sstevel@tonic-gate 		 * "all", "mechanism", and "install" are all keywords and
11027c478bd9Sstevel@tonic-gate 		 * not to be translated.
11037c478bd9Sstevel@tonic-gate 		 */
11047c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
11057c478bd9Sstevel@tonic-gate 		    gettext("can not use the %1$s keyword for %2$s "
11067c478bd9Sstevel@tonic-gate 		    "in the %3$s subcommand."), "all", "mechanism", "install");
11077c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
11087c478bd9Sstevel@tonic-gate 		goto out;
11097c478bd9Sstevel@tonic-gate 	}
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
11127c478bd9Sstevel@tonic-gate 		rc = install_kef(prov->cp_name, mecharglist);
11137c478bd9Sstevel@tonic-gate 	} else {
11147c478bd9Sstevel@tonic-gate 		/*
11150a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
11167c478bd9Sstevel@tonic-gate 		 * "install" could be either a literal keyword and hence
11177c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
11187c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
11197c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
11207c478bd9Sstevel@tonic-gate 		 */
11217c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
11227c478bd9Sstevel@tonic-gate 		    "is supported in the %2$s zone only"), "install", "global");
11237c478bd9Sstevel@tonic-gate 		rc = FAILURE;
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate out:
11267c478bd9Sstevel@tonic-gate 	free(prov);
11277c478bd9Sstevel@tonic-gate 	return (rc);
11287c478bd9Sstevel@tonic-gate }
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate /*
11331b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm uninstall" subcommand.
11347c478bd9Sstevel@tonic-gate  */
11357c478bd9Sstevel@tonic-gate static int
11367c478bd9Sstevel@tonic-gate do_uninstall(int argc, char **argv)
11377c478bd9Sstevel@tonic-gate {
11387c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
11397c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	if (argc != 3) {
11427c478bd9Sstevel@tonic-gate 		usage();
11437c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
11447c478bd9Sstevel@tonic-gate 	}
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
11477c478bd9Sstevel@tonic-gate 	if (prov == NULL ||
11487c478bd9Sstevel@tonic-gate 	    prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
11497c478bd9Sstevel@tonic-gate 		/*
11500a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
11517c478bd9Sstevel@tonic-gate 		 * "uninstall" could be either a literal keyword and hence
11527c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
11537c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
11547c478bd9Sstevel@tonic-gate 		 */
11557c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
11567c478bd9Sstevel@tonic-gate 		    gettext("bad provider name for %s."), "uninstall");
11577c478bd9Sstevel@tonic-gate 		free(prov);
11587c478bd9Sstevel@tonic-gate 		return (FAILURE);
11597c478bd9Sstevel@tonic-gate 	}
11607c478bd9Sstevel@tonic-gate 
11617c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_UEF_LIB) {
11627c478bd9Sstevel@tonic-gate 		rc = uninstall_uef_lib(prov->cp_name);
11631b22764fSDaniel OpenSolaris Anderson 
11647c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == PROV_KEF_SOFT) {
11657c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
11661b22764fSDaniel OpenSolaris Anderson 			/* unload and remove from kcf.conf */
11677c478bd9Sstevel@tonic-gate 			rc = uninstall_kef(prov->cp_name);
11687c478bd9Sstevel@tonic-gate 		} else {
11697c478bd9Sstevel@tonic-gate 			/*
11700a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
11717c478bd9Sstevel@tonic-gate 			 * "uninstall" could be either a literal keyword and
11727c478bd9Sstevel@tonic-gate 			 * hence not to be translated, or a verb and
11737c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as a
11747c478bd9Sstevel@tonic-gate 			 * literal keyword.  "global" is keyword and not to
11757c478bd9Sstevel@tonic-gate 			 * be translated.
11767c478bd9Sstevel@tonic-gate 			 */
11777c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
11787c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
11797c478bd9Sstevel@tonic-gate 			    "uninstall", "global");
11807c478bd9Sstevel@tonic-gate 			rc = FAILURE;
11817c478bd9Sstevel@tonic-gate 		}
11827c478bd9Sstevel@tonic-gate 	}
11837c478bd9Sstevel@tonic-gate 
11847c478bd9Sstevel@tonic-gate 	free(prov);
11857c478bd9Sstevel@tonic-gate 	return (rc);
11867c478bd9Sstevel@tonic-gate }
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate /*
11901b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm unload" subcommand.
11917c478bd9Sstevel@tonic-gate  */
11927c478bd9Sstevel@tonic-gate static int
11937c478bd9Sstevel@tonic-gate do_unload(int argc, char **argv)
11947c478bd9Sstevel@tonic-gate {
11957c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
11961b22764fSDaniel OpenSolaris Anderson 	entry_t			*pent = NULL;
11971b22764fSDaniel OpenSolaris Anderson 	boolean_t		in_kernel = B_FALSE;
11987c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
11991b22764fSDaniel OpenSolaris Anderson 	char			*provname = NULL;
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate 	if (argc != 3) {
12027c478bd9Sstevel@tonic-gate 		usage();
12037c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
12047c478bd9Sstevel@tonic-gate 	}
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	/* check if it is a kernel software provider */
12077c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
12087c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
12097c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12107c478bd9Sstevel@tonic-gate 		    gettext("unable to determine provider name."));
12117c478bd9Sstevel@tonic-gate 		goto out;
12127c478bd9Sstevel@tonic-gate 	}
12131b22764fSDaniel OpenSolaris Anderson 	provname = prov->cp_name;
12147c478bd9Sstevel@tonic-gate 	if (prov->cp_type != PROV_KEF_SOFT) {
12157c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12167c478bd9Sstevel@tonic-gate 		    gettext("%s is not a valid kernel software provider."),
12171b22764fSDaniel OpenSolaris Anderson 		    provname);
12187c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12197c478bd9Sstevel@tonic-gate 		goto out;
12207c478bd9Sstevel@tonic-gate 	}
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
12237c478bd9Sstevel@tonic-gate 		/*
12240a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
12257c478bd9Sstevel@tonic-gate 		 * "unload" could be either a literal keyword and hence
12267c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.
12277c478bd9Sstevel@tonic-gate 		 * A choice was made to view it as a literal keyword.
12287c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
12297c478bd9Sstevel@tonic-gate 		 */
12307c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
12317c478bd9Sstevel@tonic-gate 		    "is supported in the %2$s zone only"), "unload", "global");
12327c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12337c478bd9Sstevel@tonic-gate 		goto out;
12347c478bd9Sstevel@tonic-gate 	}
12357c478bd9Sstevel@tonic-gate 
12361b22764fSDaniel OpenSolaris Anderson 	if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) {
12371b22764fSDaniel OpenSolaris Anderson 		cryptodebug("internal error");
12381b22764fSDaniel OpenSolaris Anderson 		rc = FAILURE;
12391b22764fSDaniel OpenSolaris Anderson 		goto out;
12401b22764fSDaniel OpenSolaris Anderson 	} else if (in_kernel == B_FALSE) {
12417c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12421b22764fSDaniel OpenSolaris Anderson 		    gettext("provider %s is not loaded or does not exist."),
12431b22764fSDaniel OpenSolaris Anderson 		    provname);
12447c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12457c478bd9Sstevel@tonic-gate 		goto out;
12467c478bd9Sstevel@tonic-gate 	}
12471b22764fSDaniel OpenSolaris Anderson 
12481b22764fSDaniel OpenSolaris Anderson 	/* Get kcf.conf entry.  If none, build a new entry */
1249d616ad8eSHai-May Chao 	if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
12501b22764fSDaniel OpenSolaris Anderson 		if ((pent = create_entry(provname)) == NULL) {
12511b22764fSDaniel OpenSolaris Anderson 			cryptoerror(LOG_STDERR, gettext("out of memory."));
12521b22764fSDaniel OpenSolaris Anderson 			rc = FAILURE;
12531b22764fSDaniel OpenSolaris Anderson 			goto out;
12541b22764fSDaniel OpenSolaris Anderson 		}
12551b22764fSDaniel OpenSolaris Anderson 	}
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate 	/* If it is unloaded already, return  */
12581b22764fSDaniel OpenSolaris Anderson 	if (!pent->load) { /* unloaded already */
12597c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12601b22764fSDaniel OpenSolaris Anderson 		    gettext("failed to unload %s."), provname);
12617c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12627c478bd9Sstevel@tonic-gate 		goto out;
12631b22764fSDaniel OpenSolaris Anderson 	} else if (unload_kef_soft(provname) != FAILURE) {
12641b22764fSDaniel OpenSolaris Anderson 		/* Mark as unloaded in kcf.conf */
12651b22764fSDaniel OpenSolaris Anderson 		pent->load = B_FALSE;
12661b22764fSDaniel OpenSolaris Anderson 		rc = update_kcfconf(pent, MODIFY_MODE);
12677c478bd9Sstevel@tonic-gate 	} else {
12681b22764fSDaniel OpenSolaris Anderson 		cryptoerror(LOG_STDERR,
12691b22764fSDaniel OpenSolaris Anderson 		    gettext("failed to unload %s."), provname);
12701b22764fSDaniel OpenSolaris Anderson 		rc = FAILURE;
12717c478bd9Sstevel@tonic-gate 	}
12727c478bd9Sstevel@tonic-gate out:
12737c478bd9Sstevel@tonic-gate 	free(prov);
12741b22764fSDaniel OpenSolaris Anderson 	free_entry(pent);
12757c478bd9Sstevel@tonic-gate 	return (rc);
12767c478bd9Sstevel@tonic-gate }
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate /*
12811b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm refresh" subcommand.
12827c478bd9Sstevel@tonic-gate  */
12837c478bd9Sstevel@tonic-gate static int
12847c478bd9Sstevel@tonic-gate do_refresh(int argc)
12857c478bd9Sstevel@tonic-gate {
12867c478bd9Sstevel@tonic-gate 	if (argc != 2) {
12877c478bd9Sstevel@tonic-gate 		usage();
12887c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
12897c478bd9Sstevel@tonic-gate 	}
12907c478bd9Sstevel@tonic-gate 
12911b22764fSDaniel OpenSolaris Anderson 	if (getzoneid() == GLOBAL_ZONEID) {
12921b22764fSDaniel OpenSolaris Anderson 		return (refresh());
12931b22764fSDaniel OpenSolaris Anderson 	} else { /* non-global zone */
12947c478bd9Sstevel@tonic-gate 		/*
12957c478bd9Sstevel@tonic-gate 		 * Note:  in non-global zone, this must silently return SUCCESS
12967c478bd9Sstevel@tonic-gate 		 * due to integration with SMF, for "svcadm refresh cryptosvc"
12977c478bd9Sstevel@tonic-gate 		 */
12987c478bd9Sstevel@tonic-gate 		return (SUCCESS);
12991b22764fSDaniel OpenSolaris Anderson 	}
13007c478bd9Sstevel@tonic-gate }
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate /*
13041b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm start" subcommand.
13057c478bd9Sstevel@tonic-gate  */
13067c478bd9Sstevel@tonic-gate static int
13077c478bd9Sstevel@tonic-gate do_start(int argc)
13087c478bd9Sstevel@tonic-gate {
13097c478bd9Sstevel@tonic-gate 	int ret;
13107c478bd9Sstevel@tonic-gate 
13117c478bd9Sstevel@tonic-gate 	if (argc != 2) {
13127c478bd9Sstevel@tonic-gate 		usage();
13137c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
13147c478bd9Sstevel@tonic-gate 	}
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 	ret = do_refresh(argc);
13177c478bd9Sstevel@tonic-gate 	if (ret != SUCCESS)
13187c478bd9Sstevel@tonic-gate 		return (ret);
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	return (start_daemon());
13217c478bd9Sstevel@tonic-gate }
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate /*
13241b22764fSDaniel OpenSolaris Anderson  * The top level function for the "cryptoadm stop" subcommand.
13257c478bd9Sstevel@tonic-gate  */
13267c478bd9Sstevel@tonic-gate static int
13277c478bd9Sstevel@tonic-gate do_stop(int argc)
13287c478bd9Sstevel@tonic-gate {
13297c478bd9Sstevel@tonic-gate 	if (argc != 2) {
13307c478bd9Sstevel@tonic-gate 		usage();
13317c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
13327c478bd9Sstevel@tonic-gate 	}
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 	return (stop_daemon());
13357c478bd9Sstevel@tonic-gate }
13367c478bd9Sstevel@tonic-gate 
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate /*
13401b22764fSDaniel OpenSolaris Anderson  * Print a list all the the providers.
13411b22764fSDaniel OpenSolaris Anderson  * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
13427c478bd9Sstevel@tonic-gate  */
13437c478bd9Sstevel@tonic-gate static int
13447c478bd9Sstevel@tonic-gate list_simple_for_all(boolean_t verbose)
13457c478bd9Sstevel@tonic-gate {
13461b22764fSDaniel OpenSolaris Anderson 	uentrylist_t		*pliblist = NULL;
13471b22764fSDaniel OpenSolaris Anderson 	uentrylist_t		*plibptr = NULL;
13481b22764fSDaniel OpenSolaris Anderson 	entry_t			*pent = NULL;
13497c478bd9Sstevel@tonic-gate 	crypto_get_dev_list_t	*pdevlist_kernel = NULL;
13501b22764fSDaniel OpenSolaris Anderson 	int			rc = SUCCESS;
13517c478bd9Sstevel@tonic-gate 	int			i;
13527c478bd9Sstevel@tonic-gate 
13537c478bd9Sstevel@tonic-gate 	/* get user-level providers */
13547c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
13557c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
13567c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
13577c478bd9Sstevel@tonic-gate 		    "failed to retrieve the list of user-level providers."));
13581b22764fSDaniel OpenSolaris Anderson 		rc = FAILURE;
13597c478bd9Sstevel@tonic-gate 	}
13601b22764fSDaniel OpenSolaris Anderson 
13611b22764fSDaniel OpenSolaris Anderson 	for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) {
1362d616ad8eSHai-May Chao 		/* skip metaslot and fips-140 entry */
1363d616ad8eSHai-May Chao 		if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1364d616ad8eSHai-May Chao 		    (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
13657c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Provider: %s\n"),
13667c478bd9Sstevel@tonic-gate 			    plibptr->puent->name);
13677c478bd9Sstevel@tonic-gate 			if (verbose) {
13687c478bd9Sstevel@tonic-gate 				(void) list_mechlist_for_lib(
13697c478bd9Sstevel@tonic-gate 				    plibptr->puent->name, mecharglist, NULL,
13707c478bd9Sstevel@tonic-gate 				    B_FALSE, verbose, B_FALSE);
13717c478bd9Sstevel@tonic-gate 				(void) printf("\n");
13727c478bd9Sstevel@tonic-gate 			}
13737c478bd9Sstevel@tonic-gate 		}
13747c478bd9Sstevel@tonic-gate 	}
13757c478bd9Sstevel@tonic-gate 	free_uentrylist(pliblist);
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate 	/* get kernel software providers */
13787c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
13797c478bd9Sstevel@tonic-gate 
13807c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
13811b22764fSDaniel OpenSolaris Anderson 		/* get kernel software providers from kernel ioctl */
13821b22764fSDaniel OpenSolaris Anderson 		crypto_get_soft_list_t		*psoftlist_kernel = NULL;
13831b22764fSDaniel OpenSolaris Anderson 		uint_t				sl_soft_count;
13841b22764fSDaniel OpenSolaris Anderson 		char				*psoftname;
13851b22764fSDaniel OpenSolaris Anderson 		entrylist_t			*pdevlist_conf = NULL;
13861b22764fSDaniel OpenSolaris Anderson 		entrylist_t			*psoftlist_conf = NULL;
13877c478bd9Sstevel@tonic-gate 
13881b22764fSDaniel OpenSolaris Anderson 		if (get_soft_list(&psoftlist_kernel) == FAILURE) {
13891b22764fSDaniel OpenSolaris Anderson 			cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
13901b22764fSDaniel OpenSolaris Anderson 			    "software provider list from kernel."));
13911b22764fSDaniel OpenSolaris Anderson 			rc = FAILURE;
13927c478bd9Sstevel@tonic-gate 		} else {
13931b22764fSDaniel OpenSolaris Anderson 			sl_soft_count = psoftlist_kernel->sl_soft_count;
13947c478bd9Sstevel@tonic-gate 
1395d616ad8eSHai-May Chao 			if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1396d616ad8eSHai-May Chao 			    == FAILURE) {
13971b22764fSDaniel OpenSolaris Anderson 				cryptoerror(LOG_ERR,
13981b22764fSDaniel OpenSolaris Anderson 				    "failed to retrieve the providers' "
13991b22764fSDaniel OpenSolaris Anderson 				    "information from file kcf.conf - %s.",
14001b22764fSDaniel OpenSolaris Anderson 				    _PATH_KCF_CONF);
14011b22764fSDaniel OpenSolaris Anderson 				free(psoftlist_kernel);
14021b22764fSDaniel OpenSolaris Anderson 				rc = FAILURE;
14031b22764fSDaniel OpenSolaris Anderson 			} else {
14041b22764fSDaniel OpenSolaris Anderson 
14051b22764fSDaniel OpenSolaris Anderson 				for (i = 0,
14061b22764fSDaniel OpenSolaris Anderson 				    psoftname = psoftlist_kernel->sl_soft_names;
14071b22764fSDaniel OpenSolaris Anderson 				    i < sl_soft_count;
14081b22764fSDaniel OpenSolaris Anderson 				    ++i, psoftname += strlen(psoftname) + 1) {
14091b22764fSDaniel OpenSolaris Anderson 					pent = getent_kef(psoftname,
1410d616ad8eSHai-May Chao 					    pdevlist_conf, psoftlist_conf);
14111b22764fSDaniel OpenSolaris Anderson 					(void) printf("\t%s%s\n", psoftname,
14121b22764fSDaniel OpenSolaris Anderson 					    (pent == NULL) || (pent->load) ?
14131b22764fSDaniel OpenSolaris Anderson 					    "" : gettext(" (inactive)"));
14141b22764fSDaniel OpenSolaris Anderson 				}
14157c478bd9Sstevel@tonic-gate 				free_entrylist(pdevlist_conf);
14167c478bd9Sstevel@tonic-gate 				free_entrylist(psoftlist_conf);
14171b22764fSDaniel OpenSolaris Anderson 			}
14181b22764fSDaniel OpenSolaris Anderson 			free(psoftlist_kernel);
14191b22764fSDaniel OpenSolaris Anderson 		}
14201b22764fSDaniel OpenSolaris Anderson 
14217c478bd9Sstevel@tonic-gate 	} else {
14227c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, use /dev/cryptoadm */
14231b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*pdevlist_zone = NULL;
14241b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*psoftlist_zone = NULL;
14251b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*ptr;
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 		if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
14287c478bd9Sstevel@tonic-gate 		    SUCCESS) {
14297c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR,
14307c478bd9Sstevel@tonic-gate 			    gettext("failed to retrieve the "
14317c478bd9Sstevel@tonic-gate 			    "list of kernel software providers.\n"));
14321b22764fSDaniel OpenSolaris Anderson 			rc = FAILURE;
14337c478bd9Sstevel@tonic-gate 		}
14347c478bd9Sstevel@tonic-gate 
14357c478bd9Sstevel@tonic-gate 		ptr = psoftlist_zone;
14367c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
14377c478bd9Sstevel@tonic-gate 			(void) printf("\t%s\n", ptr->pent->name);
14387c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
14397c478bd9Sstevel@tonic-gate 		}
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_zone);
14427c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_zone);
14437c478bd9Sstevel@tonic-gate 	}
14447c478bd9Sstevel@tonic-gate 
14457c478bd9Sstevel@tonic-gate 	/* get kernel hardware providers */
14467c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
14477c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) == FAILURE) {
14487c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
14497c478bd9Sstevel@tonic-gate 		    "the list of kernel hardware providers.\n"));
14501b22764fSDaniel OpenSolaris Anderson 		rc = FAILURE;
14517c478bd9Sstevel@tonic-gate 	} else {
14527c478bd9Sstevel@tonic-gate 		for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
14537c478bd9Sstevel@tonic-gate 			(void) printf("\t%s/%d\n",
14547c478bd9Sstevel@tonic-gate 			    pdevlist_kernel->dl_devs[i].le_dev_name,
14557c478bd9Sstevel@tonic-gate 			    pdevlist_kernel->dl_devs[i].le_dev_instance);
14567c478bd9Sstevel@tonic-gate 		}
14577c478bd9Sstevel@tonic-gate 	}
14587c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
14597c478bd9Sstevel@tonic-gate 
14601b22764fSDaniel OpenSolaris Anderson 	return (rc);
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate 
14657c478bd9Sstevel@tonic-gate /*
14667c478bd9Sstevel@tonic-gate  * List all the providers. And for each provider, list the mechanism list.
14671b22764fSDaniel OpenSolaris Anderson  * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
14687c478bd9Sstevel@tonic-gate  */
14697c478bd9Sstevel@tonic-gate static int
14707c478bd9Sstevel@tonic-gate list_mechlist_for_all(boolean_t verbose)
14717c478bd9Sstevel@tonic-gate {
14721b22764fSDaniel OpenSolaris Anderson 	crypto_get_dev_list_t	*pdevlist_kernel = NULL;
14731b22764fSDaniel OpenSolaris Anderson 	uentrylist_t		*pliblist = NULL;
14741b22764fSDaniel OpenSolaris Anderson 	uentrylist_t		*plibptr = NULL;
14751b22764fSDaniel OpenSolaris Anderson 	entry_t			*pent = NULL;
14761b22764fSDaniel OpenSolaris Anderson 	mechlist_t		*pmechlist = NULL;
14777c478bd9Sstevel@tonic-gate 	char			provname[MAXNAMELEN];
14787c478bd9Sstevel@tonic-gate 	char			devname[MAXNAMELEN];
14797c478bd9Sstevel@tonic-gate 	int			inst_num;
14807c478bd9Sstevel@tonic-gate 	int			count;
14817c478bd9Sstevel@tonic-gate 	int			i;
14827c478bd9Sstevel@tonic-gate 	int			rv;
14837c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	/* get user-level providers */
14867c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
14877c478bd9Sstevel@tonic-gate 	/*
14880a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
14897c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
14907c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
14917c478bd9Sstevel@tonic-gate 	 */
14927c478bd9Sstevel@tonic-gate 	(void) printf(gettext("=====================\n"));
14937c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
14947c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
14957c478bd9Sstevel@tonic-gate 		    "the list of user-level providers.\n"));
14967c478bd9Sstevel@tonic-gate 		rc = FAILURE;
14977c478bd9Sstevel@tonic-gate 	}
14987c478bd9Sstevel@tonic-gate 
14997c478bd9Sstevel@tonic-gate 	plibptr = pliblist;
15007c478bd9Sstevel@tonic-gate 	while (plibptr != NULL) {
1501d616ad8eSHai-May Chao 		/* skip metaslot and fips-140 entry */
1502d616ad8eSHai-May Chao 		if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1503d616ad8eSHai-May Chao 		    (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
15047c478bd9Sstevel@tonic-gate 			(void) printf(gettext("\nProvider: %s\n"),
15057c478bd9Sstevel@tonic-gate 			    plibptr->puent->name);
15067c478bd9Sstevel@tonic-gate 			rv = list_mechlist_for_lib(plibptr->puent->name,
15077c478bd9Sstevel@tonic-gate 			    mecharglist, NULL, B_FALSE, verbose, B_TRUE);
15087c478bd9Sstevel@tonic-gate 			if (rv == FAILURE) {
15097c478bd9Sstevel@tonic-gate 				rc = FAILURE;
15107c478bd9Sstevel@tonic-gate 			}
15117c478bd9Sstevel@tonic-gate 		}
15127c478bd9Sstevel@tonic-gate 		plibptr = plibptr->next;
15137c478bd9Sstevel@tonic-gate 	}
15147c478bd9Sstevel@tonic-gate 	free_uentrylist(pliblist);
15157c478bd9Sstevel@tonic-gate 
15167c478bd9Sstevel@tonic-gate 	/* get kernel software providers */
15177c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
15181b22764fSDaniel OpenSolaris Anderson 
15197c478bd9Sstevel@tonic-gate 	/*
15200a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
15217c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
15227c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
15237c478bd9Sstevel@tonic-gate 	 */
15247c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
15257c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
15261b22764fSDaniel OpenSolaris Anderson 		/* get kernel software providers from kernel ioctl */
15271b22764fSDaniel OpenSolaris Anderson 		crypto_get_soft_list_t		*psoftlist_kernel = NULL;
15281b22764fSDaniel OpenSolaris Anderson 		uint_t				sl_soft_count;
15291b22764fSDaniel OpenSolaris Anderson 		char				*psoftname;
15301b22764fSDaniel OpenSolaris Anderson 		int				i;
15311b22764fSDaniel OpenSolaris Anderson 		entrylist_t			*pdevlist_conf = NULL;
15321b22764fSDaniel OpenSolaris Anderson 		entrylist_t			*psoftlist_conf = NULL;
15337c478bd9Sstevel@tonic-gate 
15341b22764fSDaniel OpenSolaris Anderson 		if (get_soft_list(&psoftlist_kernel) == FAILURE) {
15351b22764fSDaniel OpenSolaris Anderson 			cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
15361b22764fSDaniel OpenSolaris Anderson 			    "software provider list from kernel."));
15371b22764fSDaniel OpenSolaris Anderson 			return (FAILURE);
15381b22764fSDaniel OpenSolaris Anderson 		}
15391b22764fSDaniel OpenSolaris Anderson 		sl_soft_count = psoftlist_kernel->sl_soft_count;
15401b22764fSDaniel OpenSolaris Anderson 
1541d616ad8eSHai-May Chao 		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1542d616ad8eSHai-May Chao 		    == FAILURE) {
15431b22764fSDaniel OpenSolaris Anderson 			cryptoerror(LOG_ERR,
15441b22764fSDaniel OpenSolaris Anderson 			    "failed to retrieve the providers' "
15451b22764fSDaniel OpenSolaris Anderson 			    "information from file kcf.conf - %s.",
15461b22764fSDaniel OpenSolaris Anderson 			    _PATH_KCF_CONF);
15471b22764fSDaniel OpenSolaris Anderson 			free(psoftlist_kernel);
15481b22764fSDaniel OpenSolaris Anderson 			return (FAILURE);
15497c478bd9Sstevel@tonic-gate 		}
15507c478bd9Sstevel@tonic-gate 
15511b22764fSDaniel OpenSolaris Anderson 		for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
15521b22764fSDaniel OpenSolaris Anderson 		    i < sl_soft_count;
15531b22764fSDaniel OpenSolaris Anderson 		    ++i, psoftname += strlen(psoftname) + 1) {
15541b22764fSDaniel OpenSolaris Anderson 			pent = getent_kef(psoftname, pdevlist_conf,
1555d616ad8eSHai-May Chao 			    psoftlist_conf);
15561b22764fSDaniel OpenSolaris Anderson 			if ((pent == NULL) || (pent->load)) {
15571b22764fSDaniel OpenSolaris Anderson 				rv = list_mechlist_for_soft(psoftname,
1558d616ad8eSHai-May Chao 				    NULL, NULL);
15597c478bd9Sstevel@tonic-gate 				if (rv == FAILURE) {
15607c478bd9Sstevel@tonic-gate 					rc = FAILURE;
15617c478bd9Sstevel@tonic-gate 				}
15627c478bd9Sstevel@tonic-gate 			} else {
15631b22764fSDaniel OpenSolaris Anderson 				(void) printf(gettext("%s: (inactive)\n"),
15641b22764fSDaniel OpenSolaris Anderson 				    psoftname);
15657c478bd9Sstevel@tonic-gate 			}
15667c478bd9Sstevel@tonic-gate 		}
15677c478bd9Sstevel@tonic-gate 
15681b22764fSDaniel OpenSolaris Anderson 		free(psoftlist_kernel);
15697c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_conf);
15707c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_conf);
15711b22764fSDaniel OpenSolaris Anderson 
15727c478bd9Sstevel@tonic-gate 	} else {
15737c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, use /dev/cryptoadm */
15741b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*pdevlist_zone = NULL;
15751b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*psoftlist_zone = NULL;
15761b22764fSDaniel OpenSolaris Anderson 		entrylist_t	*ptr;
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate 		if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
15797c478bd9Sstevel@tonic-gate 		    SUCCESS) {
15807c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("failed to retrieve "
15817c478bd9Sstevel@tonic-gate 			    "the list of kernel software providers.\n"));
15827c478bd9Sstevel@tonic-gate 			rc = FAILURE;
15837c478bd9Sstevel@tonic-gate 		}
15847c478bd9Sstevel@tonic-gate 
15851b22764fSDaniel OpenSolaris Anderson 		for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) {
15861b22764fSDaniel OpenSolaris Anderson 			rv = list_mechlist_for_soft(ptr->pent->name,
1587d616ad8eSHai-May Chao 			    pdevlist_zone, psoftlist_zone);
15887c478bd9Sstevel@tonic-gate 			if (rv == FAILURE) {
15897c478bd9Sstevel@tonic-gate 				(void) printf(gettext(
15907c478bd9Sstevel@tonic-gate 				    "%s: failed to get the mechanism list.\n"),
15917c478bd9Sstevel@tonic-gate 				    ptr->pent->name);
15927c478bd9Sstevel@tonic-gate 				rc = FAILURE;
15937c478bd9Sstevel@tonic-gate 			}
15947c478bd9Sstevel@tonic-gate 		}
15957c478bd9Sstevel@tonic-gate 
15967c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_zone);
15977c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_zone);
15987c478bd9Sstevel@tonic-gate 	}
15997c478bd9Sstevel@tonic-gate 
16007c478bd9Sstevel@tonic-gate 	/* Get kernel hardware providers and their mechanism lists */
16017c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
16027c478bd9Sstevel@tonic-gate 	/*
16030a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
16047c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
16057c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
16067c478bd9Sstevel@tonic-gate 	 */
16077c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
16087c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
16097c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
16107c478bd9Sstevel@tonic-gate 		    "the list of hardware providers.\n"));
16117c478bd9Sstevel@tonic-gate 		return (FAILURE);
16127c478bd9Sstevel@tonic-gate 	}
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 	for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
16157c478bd9Sstevel@tonic-gate 		(void) strlcpy(devname,
16167c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
16177c478bd9Sstevel@tonic-gate 		inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
16187c478bd9Sstevel@tonic-gate 		count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
16197c478bd9Sstevel@tonic-gate 		(void) snprintf(provname, sizeof (provname), "%s/%d", devname,
16207c478bd9Sstevel@tonic-gate 		    inst_num);
16217c478bd9Sstevel@tonic-gate 		if (get_dev_info(devname, inst_num, count, &pmechlist) ==
16227c478bd9Sstevel@tonic-gate 		    SUCCESS) {
16237c478bd9Sstevel@tonic-gate 			(void) filter_mechlist(&pmechlist, RANDOM);
16247c478bd9Sstevel@tonic-gate 			print_mechlist(provname, pmechlist);
16257c478bd9Sstevel@tonic-gate 			free_mechlist(pmechlist);
16267c478bd9Sstevel@tonic-gate 		} else {
16277c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s: failed to get the mechanism"
16287c478bd9Sstevel@tonic-gate 			    " list.\n"), provname);
16297c478bd9Sstevel@tonic-gate 			rc = FAILURE;
16307c478bd9Sstevel@tonic-gate 		}
16317c478bd9Sstevel@tonic-gate 	}
16327c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
16337c478bd9Sstevel@tonic-gate 	return (rc);
16347c478bd9Sstevel@tonic-gate }
16357c478bd9Sstevel@tonic-gate 
16367c478bd9Sstevel@tonic-gate 
16377c478bd9Sstevel@tonic-gate /*
16387c478bd9Sstevel@tonic-gate  * List all the providers. And for each provider, list the policy information.
16391b22764fSDaniel OpenSolaris Anderson  * Called for "cryptoadm list -p".
16407c478bd9Sstevel@tonic-gate  */
16417c478bd9Sstevel@tonic-gate static int
16427c478bd9Sstevel@tonic-gate list_policy_for_all(void)
16437c478bd9Sstevel@tonic-gate {
16441b22764fSDaniel OpenSolaris Anderson 	crypto_get_dev_list_t	*pdevlist_kernel = NULL;
16451b22764fSDaniel OpenSolaris Anderson 	uentrylist_t		*pliblist = NULL;
16461b22764fSDaniel OpenSolaris Anderson 	entrylist_t		*pdevlist_conf = NULL;
16471b22764fSDaniel OpenSolaris Anderson 	entrylist_t		*psoftlist_conf = NULL;
16481b22764fSDaniel OpenSolaris Anderson 	entrylist_t		*ptr = NULL;
16491b22764fSDaniel OpenSolaris Anderson 	entrylist_t		*phead = NULL;
16501b22764fSDaniel OpenSolaris Anderson 	boolean_t		found = B_FALSE;
16517c478bd9Sstevel@tonic-gate 	char			provname[MAXNAMELEN];
16527c478bd9Sstevel@tonic-gate 	int			i;
16537c478bd9Sstevel@tonic-gate 	int			rc = SUCCESS;
16547c478bd9Sstevel@tonic-gate 
16557c478bd9Sstevel@tonic-gate 	/* Get user-level providers */
16567c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
16577c478bd9Sstevel@tonic-gate 	/*
16580a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
16597c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
16607c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
16617c478bd9Sstevel@tonic-gate 	 */
16627c478bd9Sstevel@tonic-gate 	(void) printf(gettext("=====================\n"));
16637c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) == FAILURE) {
16647c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
16657c478bd9Sstevel@tonic-gate 		    "the list of user-level providers.\n"));
16661b22764fSDaniel OpenSolaris Anderson 		rc = FAILURE;
16677c478bd9Sstevel@tonic-gate 	} else {
16681b22764fSDaniel OpenSolaris Anderson 		uentrylist_t	*plibptr = pliblist;
16691b22764fSDaniel OpenSolaris Anderson 
16707c478bd9Sstevel@tonic-gate 		while (plibptr != NULL) {
1671d616ad8eSHai-May Chao 			/* skip metaslot and fips-140 entry */
1672d616ad8eSHai-May Chao 			if ((strcmp(plibptr->puent->name,
1673d616ad8eSHai-May Chao 			    METASLOT_KEYWORD) != 0) &&
1674d616ad8eSHai-May Chao 			    (strcmp(plibptr->puent->name,
1675d616ad8eSHai-May Chao 			    FIPS_KEYWORD) != 0)) {
16767c478bd9Sstevel@tonic-gate 				if (print_uef_policy(plibptr->puent)
16777c478bd9Sstevel@tonic-gate 				    == FAILURE) {
16787c478bd9Sstevel@tonic-gate 					rc = FAILURE;
16797c478bd9Sstevel@tonic-gate 				}
16807c478bd9Sstevel@tonic-gate 			}
16817c478bd9Sstevel@tonic-gate 			plibptr = plibptr->next;
16827c478bd9Sstevel@tonic-gate 		}
16837c478bd9Sstevel@tonic-gate 		free_uentrylist(pliblist);
16847c478bd9Sstevel@tonic-gate 	}
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 	/* kernel software providers */
16877c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
16887c478bd9Sstevel@tonic-gate 	/*
16890a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
16907c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
16917c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
16927c478bd9Sstevel@tonic-gate 	 */
16937c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
16947c478bd9Sstevel@tonic-gate 
16951b22764fSDaniel OpenSolaris Anderson 	/* Get all entries from the kernel */
16967c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
16971b22764fSDaniel OpenSolaris Anderson 		/* get kernel software providers from kernel ioctl */
16981b22764fSDaniel OpenSolaris Anderson 		crypto_get_soft_list_t		*psoftlist_kernel = NULL;
16991b22764fSDaniel OpenSolaris Anderson 		uint_t				sl_soft_count;
17001b22764fSDaniel OpenSolaris Anderson 		char				*psoftname;
17011b22764fSDaniel OpenSolaris Anderson 		int				i;
17027c478bd9Sstevel@tonic-gate 
17031b22764fSDaniel OpenSolaris Anderson 		if (get_soft_list(&psoftlist_kernel) == FAILURE) {
17041b22764fSDaniel OpenSolaris Anderson 			cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
17051b22764fSDaniel OpenSolaris Anderson 			    "software provider list from kernel."));
17061b22764fSDaniel OpenSolaris Anderson 			rc = FAILURE;
17071b22764fSDaniel OpenSolaris Anderson 		} else {
17081b22764fSDaniel OpenSolaris Anderson 			sl_soft_count = psoftlist_kernel->sl_soft_count;
17091b22764fSDaniel OpenSolaris Anderson 
17101b22764fSDaniel OpenSolaris Anderson 			for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
17111b22764fSDaniel OpenSolaris Anderson 			    i < sl_soft_count;
17121b22764fSDaniel OpenSolaris Anderson 			    ++i, psoftname += strlen(psoftname) + 1) {
17131b22764fSDaniel OpenSolaris Anderson 				(void) list_policy_for_soft(psoftname,
1714d616ad8eSHai-May Chao 				    pdevlist_conf, psoftlist_conf);
17151b22764fSDaniel OpenSolaris Anderson 			}
17161b22764fSDaniel OpenSolaris Anderson 			free(psoftlist_kernel);
17177c478bd9Sstevel@tonic-gate 		}
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 	} else {
17207c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, no policy info */
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate 		/*
17230a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
17247c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
17257c478bd9Sstevel@tonic-gate 		 */
17267c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
17277c478bd9Sstevel@tonic-gate 		    "policy information for kernel software providers is "
17287c478bd9Sstevel@tonic-gate 		    "available in the %s zone only"), "global");
17297c478bd9Sstevel@tonic-gate 	}
17307c478bd9Sstevel@tonic-gate 
17317c478bd9Sstevel@tonic-gate 	/* Kernel hardware providers */
17327c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
17337c478bd9Sstevel@tonic-gate 	/*
17340a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
17357c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
17367c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
17377c478bd9Sstevel@tonic-gate 	 */
17387c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
17417c478bd9Sstevel@tonic-gate 		/*
17420a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
17437c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
17447c478bd9Sstevel@tonic-gate 		 */
17457c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
17467c478bd9Sstevel@tonic-gate 		    "policy information for kernel hardware providers is "
17477c478bd9Sstevel@tonic-gate 		    "available in the %s zone only"), "global");
17487c478bd9Sstevel@tonic-gate 		return (FAILURE);
17497c478bd9Sstevel@tonic-gate 	}
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate 	/* Get the hardware provider list from kernel */
17527c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
17537c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
17547c478bd9Sstevel@tonic-gate 		    "failed to retrieve the list of hardware providers.\n"));
17557c478bd9Sstevel@tonic-gate 		return (FAILURE);
17567c478bd9Sstevel@tonic-gate 	}
17577c478bd9Sstevel@tonic-gate 
1758d616ad8eSHai-May Chao 	if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) {
17591b22764fSDaniel OpenSolaris Anderson 		cryptoerror(LOG_ERR, "failed to retrieve the providers' "
17601b22764fSDaniel OpenSolaris Anderson 		    "information from file kcf.conf - %s.",
17611b22764fSDaniel OpenSolaris Anderson 		    _PATH_KCF_CONF);
17621b22764fSDaniel OpenSolaris Anderson 		return (FAILURE);
17631b22764fSDaniel OpenSolaris Anderson 	}
17641b22764fSDaniel OpenSolaris Anderson 
17651b22764fSDaniel OpenSolaris Anderson 
17667c478bd9Sstevel@tonic-gate 	/*
17677c478bd9Sstevel@tonic-gate 	 * For each hardware provider from kernel, check if it has an entry
17687c478bd9Sstevel@tonic-gate 	 * in the config file.  If it has an entry, print out the policy from
17697c478bd9Sstevel@tonic-gate 	 * config file and remove the entry from the hardware provider list
17707c478bd9Sstevel@tonic-gate 	 * of the config file.  If it does not have an entry in the config
17717c478bd9Sstevel@tonic-gate 	 * file, no mechanisms of it have been disabled. But, we still call
17727c478bd9Sstevel@tonic-gate 	 * list_policy_for_hard() to account for the "random" feature.
17737c478bd9Sstevel@tonic-gate 	 */
17747c478bd9Sstevel@tonic-gate 	for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
17757c478bd9Sstevel@tonic-gate 		(void) snprintf(provname, sizeof (provname), "%s/%d",
17767c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_name,
17777c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_instance);
17781b22764fSDaniel OpenSolaris Anderson 
17797c478bd9Sstevel@tonic-gate 		found = B_FALSE;
17807c478bd9Sstevel@tonic-gate 		phead = ptr = pdevlist_conf;
17817c478bd9Sstevel@tonic-gate 		while (!found && ptr) {
17827c478bd9Sstevel@tonic-gate 			if (strcmp(ptr->pent->name, provname) == 0) {
17837c478bd9Sstevel@tonic-gate 				found = B_TRUE;
17847c478bd9Sstevel@tonic-gate 			} else {
17857c478bd9Sstevel@tonic-gate 				phead = ptr;
17867c478bd9Sstevel@tonic-gate 				ptr = ptr->next;
17877c478bd9Sstevel@tonic-gate 			}
17887c478bd9Sstevel@tonic-gate 		}
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate 		if (found) {
17911b22764fSDaniel OpenSolaris Anderson 			(void) list_policy_for_hard(ptr->pent->name,
1792d616ad8eSHai-May Chao 			    pdevlist_conf, psoftlist_conf, pdevlist_kernel);
17937c478bd9Sstevel@tonic-gate 			if (phead == ptr) {
17947c478bd9Sstevel@tonic-gate 				pdevlist_conf = pdevlist_conf->next;
17957c478bd9Sstevel@tonic-gate 			} else {
17967c478bd9Sstevel@tonic-gate 				phead->next = ptr->next;
17977c478bd9Sstevel@tonic-gate 			}
17987c478bd9Sstevel@tonic-gate 			free_entry(ptr->pent);
17997c478bd9Sstevel@tonic-gate 			free(ptr);
18007c478bd9Sstevel@tonic-gate 		} else {
18011b22764fSDaniel OpenSolaris Anderson 			(void) list_policy_for_hard(provname, pdevlist_conf,
1802d616ad8eSHai-May Chao 			    psoftlist_conf, pdevlist_kernel);
18037c478bd9Sstevel@tonic-gate 		}
18047c478bd9Sstevel@tonic-gate 	}
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate 	/*
18077c478bd9Sstevel@tonic-gate 	 * If there are still entries left in the pdevlist_conf list from
18087c478bd9Sstevel@tonic-gate 	 * the config file, these providers must have been detached.
18097c478bd9Sstevel@tonic-gate 	 * Should print out their policy information also.
18107c478bd9Sstevel@tonic-gate 	 */
18111b22764fSDaniel OpenSolaris Anderson 	for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) {
18121b22764fSDaniel OpenSolaris Anderson 		print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE);
18137c478bd9Sstevel@tonic-gate 	}
18147c478bd9Sstevel@tonic-gate 
18157c478bd9Sstevel@tonic-gate 	free_entrylist(pdevlist_conf);
18161b22764fSDaniel OpenSolaris Anderson 	free_entrylist(psoftlist_conf);
18177c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
18187c478bd9Sstevel@tonic-gate 
18197c478bd9Sstevel@tonic-gate 	return (rc);
18207c478bd9Sstevel@tonic-gate }
1821