4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
33 #include <sys/types.h>
35 #include <sys/crypto/ioctladmin.h>
36 #include <cryptoutil.h>
37 #include "cryptoadm.h"
41 /* subcommand index */
42 enum subcommand_index
{
56 * Command keywords are not to be translated.
58 static char *cmd_table
[] = {
71 enum provider_type_index
{
79 char cp_name
[MAXPATHLEN
];
80 enum provider_type_index cp_type
;
81 } cryptoadm_provider_t
;
85 * Operand keywords are not to be translated.
87 static const char *KN_PROVIDER
= "provider=";
88 static const char *KN_MECH
= "mechanism=";
89 static const char *KN_ALL
= "all";
90 static const char *KN_TOKEN
= "token=";
91 static const char *KN_SLOT
= "slot=";
92 static const char *KN_DEFAULT_KS
= "default-keystore";
93 static const char *KN_AUTO_KEY_MIGRATE
= "auto-key-migrate";
95 /* static variables */
96 static boolean_t allflag
= B_FALSE
;
97 static boolean_t rndflag
= B_FALSE
;
98 static mechlist_t
*mecharglist
= NULL
;
100 /* static functions */
101 static void usage(void);
102 static int get_provider_type(char *);
103 static int process_mech_operands(int, char **, boolean_t
);
104 static int do_list(int, char **);
105 static int do_disable(int, char **);
106 static int do_enable(int, char **);
107 static int do_install(int, char **);
108 static int do_uninstall(int, char **);
109 static int do_unload(int, char **);
110 static int do_refresh(int);
111 static int do_start(int);
112 static int do_stop(int);
113 static int list_simple_for_all(boolean_t
);
114 static int list_mechlist_for_all(boolean_t
);
115 static int list_policy_for_all(void);
118 main(int argc
, char *argv
[])
125 (void) setlocale(LC_ALL
, "");
127 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
128 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
130 (void) textdomain(TEXT_DOMAIN
);
132 cryptodebug_init(basename(argv
[0]));
134 if (argc
< REQ_ARG_CNT
) {
136 return (ERROR_USAGE
);
139 /* get the subcommand index */
142 cmdnum
= sizeof (cmd_table
)/sizeof (cmd_table
[0]);
144 while ((cmd_index
< cmdnum
) &&
145 (strcmp(subcmd
, cmd_table
[cmd_index
]) != 0)) {
148 if (cmd_index
>= cmdnum
) {
150 return (ERROR_USAGE
);
153 /* do the subcommand */
156 rc
= do_list(argc
, argv
);
159 rc
= do_disable(argc
, argv
);
162 rc
= do_enable(argc
, argv
);
165 rc
= do_install(argc
, argv
);
167 case CRYPTO_UNINSTALL
:
168 rc
= do_uninstall(argc
, argv
);
171 rc
= do_unload(argc
, argv
);
174 rc
= do_refresh(argc
);
186 default: /* should not come here */
200 * Command usage is not to be translated. Only the word "Usage:"
201 * along with localized expressions indicating what kind of value
202 * is expected for arguments.
204 (void) fprintf(stderr
, gettext("Usage:\n"));
205 (void) fprintf(stderr
,
206 " cryptoadm list [-mpv] [provider=<%s> | metaslot]"
207 " [mechanism=<%s>]\n",
208 gettext("provider-name"), gettext("mechanism-list"));
209 (void) fprintf(stderr
,
210 " cryptoadm disable provider=<%s>"
211 " mechanism=<%s> | random | all\n",
212 gettext("provider-name"), gettext("mechanism-list"));
213 (void) fprintf(stderr
,
214 " cryptoadm disable metaslot"
215 " [auto-key-migrate] [mechanism=<%s>]\n",
216 gettext("mechanism-list"));
217 (void) fprintf(stderr
,
218 " cryptoadm enable provider=<%s>"
219 " mechanism=<%s> | random | all\n",
220 gettext("provider-name"), gettext("mechanism-list"));
221 (void) fprintf(stderr
,
222 " cryptoadm enable metaslot [mechanism=<%s>]"
223 " [[token=<%s>] [slot=<%s>]"
224 " | [default-keystore]] | [auto-key-migrate]\n",
225 gettext("mechanism-list"), gettext("token-label"),
226 gettext("slot-description"));
227 (void) fprintf(stderr
,
228 " cryptoadm install provider=<%s>\n",
229 gettext("provider-name"));
230 (void) fprintf(stderr
,
231 " cryptoadm install provider=<%s> [mechanism=<%s>]\n",
232 gettext("provider-name"), gettext("mechanism-list"));
233 (void) fprintf(stderr
,
234 " cryptoadm uninstall provider=<%s>\n",
235 gettext("provider-name"));
236 (void) fprintf(stderr
,
237 " cryptoadm unload provider=<%s>\n",
238 gettext("provider-name"));
239 (void) fprintf(stderr
,
240 " cryptoadm refresh\n"
243 " cryptoadm --help\n");
248 * Get the provider type. This function returns
249 * - PROV_UEF_LIB if provname contains an absolute path name
250 * - PROV_KEF_SOFT if provname is a base name only (e.g., "aes").
251 * - PROV_KEF_HARD if provname contains one slash only and the slash is not
252 * the 1st character (e.g., "mca/0").
253 * - PROV_BADNAME otherwise.
256 get_provider_type(char *provname
)
261 if (provname
== NULL
) {
265 if (provname
[0] == '/') {
266 return (PROV_UEF_LIB
);
267 } else if ((pslash1
= strchr(provname
, SEP_SLASH
)) == NULL
) {
269 return (PROV_KEF_SOFT
);
271 pslash2
= strrchr(provname
, SEP_SLASH
);
272 if (pslash1
== pslash2
) {
273 return (PROV_KEF_HARD
);
275 return (PROV_BADNAME
);
281 * Get the provider structure. This function returns NULL if no valid
282 * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned.
283 * If provider= is found but has no argument, then a cryptoadm_provider_t
284 * with cp_type = PROV_BADNAME is returned.
286 static cryptoadm_provider_t
*
287 get_provider(int argc
, char **argv
)
290 boolean_t found
= B_FALSE
;
291 cryptoadm_provider_t
*provider
= NULL
;
292 char *provstr
= NULL
, *savstr
;
293 boolean_t is_metaslot
= B_FALSE
;
295 while (!found
&& ++c
< argc
) {
296 if (strncmp(argv
[c
], METASLOT_KEYWORD
,
297 strlen(METASLOT_KEYWORD
)) == 0) {
298 is_metaslot
= B_TRUE
;
300 } else if (strncmp(argv
[c
], KN_PROVIDER
,
301 strlen(KN_PROVIDER
)) == 0 &&
302 strlen(argv
[c
]) > strlen(KN_PROVIDER
)) {
303 if ((provstr
= strdup(argv
[c
])) == NULL
) {
307 * "get_provider" is a function name and should
310 cryptoerror(LOG_STDERR
, "get_provider: %s.",
320 provider
= malloc(sizeof (cryptoadm_provider_t
));
321 if (provider
== NULL
) {
322 cryptoerror(LOG_STDERR
, gettext("out of memory."));
330 (void) strlcpy(provider
->cp_name
, METASLOT_KEYWORD
,
331 strlen(METASLOT_KEYWORD
));
332 provider
->cp_type
= METASLOT
;
336 (void) strtok(provstr
, "=");
337 provstr
= strtok(NULL
, "=");
338 if (provstr
== NULL
) {
339 cryptoerror(LOG_STDERR
, gettext("bad provider name."));
340 provider
->cp_type
= PROV_BADNAME
;
345 (void) strlcpy(provider
->cp_name
, provstr
,
346 sizeof (provider
->cp_name
));
347 provider
->cp_type
= get_provider_type(provider
->cp_name
);
355 * Process the "feature" operands.
357 * "argc" and "argv" contain values specified on the command line.
358 * All other arguments are used for returning parsing results.
359 * If any of these arguments are NULL, that keyword is not expected,
360 * and FAILURE will be returned.
363 process_metaslot_operands(int argc
, char **argv
, char **meta_ks_token
,
364 char **meta_ks_slot
, boolean_t
*use_default
,
365 boolean_t
*auto_key_migrate_flag
)
371 if ((strncmp(argv
[c
], KN_MECH
, strlen(KN_MECH
)) == 0) &&
372 strlen(argv
[c
]) > strlen(KN_MECH
)) {
374 /* process mechanism operands */
375 if ((rc
= process_mech_operands(argc
, argv
, B_TRUE
))
380 } else if ((strncmp(argv
[c
], KN_TOKEN
,
381 strlen(KN_TOKEN
)) == 0) &&
382 strlen(argv
[c
]) > strlen(KN_TOKEN
)) {
383 if ((meta_ks_token
) && (strtok(argv
[c
], "=") != NULL
)) {
385 if ((tmp
= strtok(NULL
, "=")) != NULL
) {
386 *meta_ks_token
= strdup(tmp
);
394 } else if ((strncmp(argv
[c
], KN_SLOT
,
395 strlen(KN_SLOT
)) == 0) &&
396 strlen(argv
[c
]) > strlen(KN_SLOT
)) {
398 if ((meta_ks_slot
) && (strtok(argv
[c
], "=") != NULL
)) {
400 if ((tmp
= strtok(NULL
, "=")) != NULL
) {
401 *meta_ks_slot
= strdup(tmp
);
409 } else if (strncmp(argv
[c
], KN_DEFAULT_KS
,
410 strlen(KN_DEFAULT_KS
)) == 0) {
413 *use_default
= B_TRUE
;
417 } else if (strncmp(argv
[c
], KN_AUTO_KEY_MIGRATE
,
418 strlen(KN_AUTO_KEY_MIGRATE
)) == 0) {
420 if (auto_key_migrate_flag
) {
421 *auto_key_migrate_flag
= B_TRUE
;
434 * Process the "feature" operands.
437 process_feature_operands(int argc
, char **argv
)
442 if (strcmp(argv
[c
], KN_ALL
) == 0) {
444 rndflag
= B_TRUE
; /* all includes random also. */
445 } else if (strcmp(argv
[c
], RANDOM
) == 0) {
453 * Process the mechanism operands for the disable, enable and install
454 * subcommands. This function sets the static variable allflag to be B_TRUE
455 * if the keyword "all" is specified, otherwise builds a link list of the
456 * mechanism operands and save it in the static variable mecharglist.
458 * This function returns
459 * ERROR_USAGE: mechanism operand is missing.
460 * FAILURE: out of memory.
461 * SUCCESS: otherwise.
464 process_mech_operands(int argc
, char **argv
, boolean_t quiet
)
467 mechlist_t
*pcur
= NULL
;
468 mechlist_t
*phead
= NULL
;
469 boolean_t found
= B_FALSE
;
470 char *mechliststr
= NULL
;
471 char *curmech
= NULL
;
475 while (!found
&& ++c
< argc
) {
476 if ((strncmp(argv
[c
], KN_MECH
, strlen(KN_MECH
)) == 0) &&
477 strlen(argv
[c
]) > strlen(KN_MECH
)) {
485 * "mechanism" could be either a literal keyword
486 * and hence not to be translated, or a descriptive
487 * word and translatable. A choice was made to
488 * view it as a literal keyword.
490 cryptoerror(LOG_STDERR
,
491 gettext("the %s operand is missing.\n"),
493 return (ERROR_USAGE
);
495 (void) strtok(argv
[c
], "=");
496 mechliststr
= strtok(NULL
, "=");
498 if (strcmp(mechliststr
, "all") == 0) {
504 curmech
= strtok(mechliststr
, ",");
506 if ((pmech
= create_mech(curmech
)) == NULL
) {
511 phead
= pcur
= pmech
;
517 } while ((curmech
= strtok(NULL
, ",")) != NULL
);
520 cryptoerror(LOG_STDERR
, gettext("out of memory."));
521 free_mechlist(phead
);
532 * The top level function for the "cryptoadm list" subcommand and options.
535 do_list(int argc
, char **argv
)
537 boolean_t mflag
= B_FALSE
;
538 boolean_t pflag
= B_FALSE
;
539 boolean_t vflag
= B_FALSE
;
541 cryptoadm_provider_t
*prov
= NULL
;
548 rc
= list_simple_for_all(B_FALSE
);
553 * cryptoadm list [-v] [-m] [-p] [provider=<>] [mechanism=<>]
560 while ((ch
= getopt(argc
, argv
, "mpv")) != EOF
) {
570 if (mflag
|| vflag
) {
585 if (rc
== ERROR_USAGE
) {
590 if ((rc
= process_feature_operands(argc
, argv
)) != SUCCESS
) {
594 prov
= get_provider(argc
, argv
);
596 if (mflag
|| vflag
) {
598 rc
= process_mech_operands(argc
, argv
, B_TRUE
);
601 /* "-m" is implied when a mechanism list is given */
602 if (mecharglist
!= NULL
|| allflag
)
609 rc
= list_mechlist_for_all(vflag
);
611 rc
= list_policy_for_all();
613 rc
= list_simple_for_all(vflag
);
615 } else if (prov
->cp_type
== METASLOT
) {
616 if ((!mflag
) && (!vflag
) && (!pflag
)) {
617 /* no flag is specified, just list metaslot status */
618 rc
= list_metaslot_info(mflag
, vflag
, mecharglist
);
619 } else if (mflag
|| vflag
) {
620 rc
= list_metaslot_info(mflag
, vflag
, mecharglist
);
622 rc
= list_metaslot_policy();
628 } else if (prov
->cp_type
== PROV_BADNAME
) {
632 } else { /* do the listing for a provider only */
633 char *provname
= prov
->cp_name
;
635 if (mflag
|| vflag
) {
637 (void) printf(gettext("Provider: %s\n"),
639 switch (prov
->cp_type
) {
641 rc
= list_mechlist_for_lib(provname
,
642 mecharglist
, NULL
, B_FALSE
, vflag
, mflag
);
645 rc
= list_mechlist_for_soft(provname
,
649 rc
= list_mechlist_for_hard(provname
);
651 default: /* should not come here */
656 switch (prov
->cp_type
) {
658 rc
= list_policy_for_lib(provname
);
661 if (getzoneid() == GLOBAL_ZONEID
) {
662 rc
= list_policy_for_soft(provname
,
667 * "global" is keyword and not to
670 cryptoerror(LOG_STDERR
, gettext(
671 "policy information for kernel "
672 "providers is available "
673 "in the %s zone only"), "global");
678 if (getzoneid() == GLOBAL_ZONEID
) {
679 rc
= list_policy_for_hard(
680 provname
, NULL
, NULL
, NULL
);
684 * "global" is keyword and not to
687 cryptoerror(LOG_STDERR
, gettext(
688 "policy information for kernel "
689 "providers is available "
690 "in the %s zone only"), "global");
695 default: /* should not come here */
709 if (mecharglist
!= NULL
)
710 free_mechlist(mecharglist
);
716 * The top level function for the "cryptoadm disable" subcommand.
719 do_disable(int argc
, char **argv
)
721 cryptoadm_provider_t
*prov
= NULL
;
723 boolean_t auto_key_migrate_flag
= B_FALSE
;
725 if ((argc
< 3) || (argc
> 5)) {
727 return (ERROR_USAGE
);
730 prov
= get_provider(argc
, argv
);
733 return (ERROR_USAGE
);
735 if (prov
->cp_type
== PROV_BADNAME
) {
739 if ((rc
= process_feature_operands(argc
, argv
)) != SUCCESS
) {
744 * If allflag or rndflag has already been set there is no reason to
747 if (prov
->cp_type
== METASLOT
) {
749 (rc
= process_metaslot_operands(argc
, argv
,
750 NULL
, NULL
, NULL
, &auto_key_migrate_flag
)) != SUCCESS
) {
754 } else if (!allflag
&& !rndflag
&&
755 (rc
= process_mech_operands(argc
, argv
, B_FALSE
)) != SUCCESS
) {
759 switch (prov
->cp_type
) {
761 rc
= disable_metaslot(mecharglist
, allflag
,
762 auto_key_migrate_flag
);
765 rc
= disable_uef_lib(prov
->cp_name
, rndflag
, allflag
,
769 if (rndflag
&& !allflag
) {
770 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
775 if (getzoneid() == GLOBAL_ZONEID
) {
776 rc
= disable_kef_software(prov
->cp_name
, rndflag
,
777 allflag
, mecharglist
);
781 * "disable" could be either a literal keyword
782 * and hence not to be translated, or a verb and
783 * translatable. A choice was made to view it as
784 * a literal keyword. "global" is keyword and not
787 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
788 "providers is supported in the %2$s zone only"),
789 "disable", "global");
794 if (rndflag
&& !allflag
) {
795 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
800 if (getzoneid() == GLOBAL_ZONEID
) {
801 rc
= disable_kef_hardware(prov
->cp_name
, rndflag
,
802 allflag
, mecharglist
);
806 * "disable" could be either a literal keyword
807 * and hence not to be translated, or a verb and
808 * translatable. A choice was made to view it as
809 * a literal keyword. "global" is keyword and not
812 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
813 "providers is supported in the %2$s zone only"),
814 "disable", "global");
818 default: /* should not come here */
825 if (mecharglist
!= NULL
) {
826 free_mechlist(mecharglist
);
833 * The top level function for the "cryptoadm enable" subcommand.
836 do_enable(int argc
, char **argv
)
838 cryptoadm_provider_t
*prov
= NULL
;
840 char *alt_token
= NULL
, *alt_slot
= NULL
;
841 boolean_t use_default
= B_FALSE
;
842 boolean_t auto_key_migrate_flag
= B_FALSE
;
844 if ((argc
< 3) || (argc
> 6)) {
846 return (ERROR_USAGE
);
849 prov
= get_provider(argc
, argv
);
852 return (ERROR_USAGE
);
854 if ((prov
->cp_type
!= METASLOT
) && (argc
!= 4)) {
856 return (ERROR_USAGE
);
858 if (prov
->cp_type
== PROV_BADNAME
) {
864 if (prov
->cp_type
== METASLOT
) {
865 if ((rc
= process_metaslot_operands(argc
, argv
, &alt_token
,
866 &alt_slot
, &use_default
, &auto_key_migrate_flag
))
871 if ((alt_slot
|| alt_token
) && use_default
) {
877 if ((rc
= process_feature_operands(argc
, argv
)) != SUCCESS
) {
882 * If allflag or rndflag has already been set there is
883 * no reason to process mech=
885 if (!allflag
&& !rndflag
&&
886 (rc
= process_mech_operands(argc
, argv
, B_FALSE
))
892 switch (prov
->cp_type
) {
894 rc
= enable_metaslot(alt_token
, alt_slot
, use_default
,
895 mecharglist
, allflag
, auto_key_migrate_flag
);
898 rc
= enable_uef_lib(prov
->cp_name
, rndflag
, allflag
,
903 if (rndflag
&& !allflag
) {
904 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
909 if (getzoneid() == GLOBAL_ZONEID
) {
910 rc
= enable_kef(prov
->cp_name
, rndflag
, allflag
,
915 * "enable" could be either a literal keyword
916 * and hence not to be translated, or a verb and
917 * translatable. A choice was made to view it as
918 * a literal keyword. "global" is keyword and not
921 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
922 "providers is supported in the %2$s zone only"),
927 default: /* should not come here */
933 if (mecharglist
!= NULL
) {
934 free_mechlist(mecharglist
);
936 if (alt_token
!= NULL
) {
939 if (alt_slot
!= NULL
) {
948 * The top level function for the "cryptoadm install" subcommand.
951 do_install(int argc
, char **argv
)
953 cryptoadm_provider_t
*prov
= NULL
;
958 return (ERROR_USAGE
);
961 prov
= get_provider(argc
, argv
);
963 prov
->cp_type
== PROV_BADNAME
|| prov
->cp_type
== PROV_KEF_HARD
) {
966 * "install" could be either a literal keyword and hence
967 * not to be translated, or a verb and translatable. A
968 * choice was made to view it as a literal keyword.
970 cryptoerror(LOG_STDERR
,
971 gettext("bad provider name for %s."), "install");
976 if (prov
->cp_type
== PROV_UEF_LIB
) {
977 rc
= install_uef_lib(prov
->cp_name
);
981 /* It is the PROV_KEF_SOFT type now */
983 /* check if there are mechanism operands */
987 * "mechanism" could be either a literal keyword and hence
988 * not to be translated, or a descriptive word and
989 * translatable. A choice was made to view it as a literal
992 cryptoerror(LOG_STDERR
,
993 gettext("need %s operands for installing a"
994 " kernel software provider."), "mechanism");
999 if ((rc
= process_mech_operands(argc
, argv
, B_FALSE
)) != SUCCESS
) {
1003 if (allflag
== B_TRUE
) {
1006 * "all", "mechanism", and "install" are all keywords and
1007 * not to be translated.
1009 cryptoerror(LOG_STDERR
,
1010 gettext("can not use the %1$s keyword for %2$s "
1011 "in the %3$s subcommand."), "all", "mechanism", "install");
1016 if (getzoneid() == GLOBAL_ZONEID
) {
1017 rc
= install_kef(prov
->cp_name
, mecharglist
);
1021 * "install" could be either a literal keyword and hence
1022 * not to be translated, or a verb and translatable. A
1023 * choice was made to view it as a literal keyword.
1024 * "global" is keyword and not to be translated.
1026 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel providers "
1027 "is supported in the %2$s zone only"), "install", "global");
1038 * The top level function for the "cryptoadm uninstall" subcommand.
1041 do_uninstall(int argc
, char **argv
)
1043 cryptoadm_provider_t
*prov
= NULL
;
1048 return (ERROR_USAGE
);
1051 prov
= get_provider(argc
, argv
);
1053 prov
->cp_type
== PROV_BADNAME
|| prov
->cp_type
== PROV_KEF_HARD
) {
1056 * "uninstall" could be either a literal keyword and hence
1057 * not to be translated, or a verb and translatable. A
1058 * choice was made to view it as a literal keyword.
1060 cryptoerror(LOG_STDERR
,
1061 gettext("bad provider name for %s."), "uninstall");
1066 if (prov
->cp_type
== PROV_UEF_LIB
) {
1067 rc
= uninstall_uef_lib(prov
->cp_name
);
1069 } else if (prov
->cp_type
== PROV_KEF_SOFT
) {
1070 if (getzoneid() == GLOBAL_ZONEID
) {
1071 /* unload and remove from kcf.conf */
1072 rc
= uninstall_kef(prov
->cp_name
);
1076 * "uninstall" could be either a literal keyword and
1077 * hence not to be translated, or a verb and
1078 * translatable. A choice was made to view it as a
1079 * literal keyword. "global" is keyword and not to
1082 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
1083 "providers is supported in the %2$s zone only"),
1084 "uninstall", "global");
1095 * The top level function for the "cryptoadm unload" subcommand.
1098 do_unload(int argc
, char **argv
)
1100 cryptoadm_provider_t
*prov
= NULL
;
1101 entry_t
*pent
= NULL
;
1102 boolean_t in_kernel
= B_FALSE
;
1104 char *provname
= NULL
;
1108 return (ERROR_USAGE
);
1111 /* check if it is a kernel software provider */
1112 prov
= get_provider(argc
, argv
);
1114 cryptoerror(LOG_STDERR
,
1115 gettext("unable to determine provider name."));
1118 provname
= prov
->cp_name
;
1119 if (prov
->cp_type
!= PROV_KEF_SOFT
) {
1120 cryptoerror(LOG_STDERR
,
1121 gettext("%s is not a valid kernel software provider."),
1127 if (getzoneid() != GLOBAL_ZONEID
) {
1130 * "unload" could be either a literal keyword and hence
1131 * not to be translated, or a verb and translatable.
1132 * A choice was made to view it as a literal keyword.
1133 * "global" is keyword and not to be translated.
1135 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel providers "
1136 "is supported in the %2$s zone only"), "unload", "global");
1141 if (check_kernel_for_soft(provname
, NULL
, &in_kernel
) == FAILURE
) {
1142 cryptodebug("internal error");
1145 } else if (in_kernel
== B_FALSE
) {
1146 cryptoerror(LOG_STDERR
,
1147 gettext("provider %s is not loaded or does not exist."),
1153 /* Get kcf.conf entry. If none, build a new entry */
1154 if ((pent
= getent_kef(provname
, NULL
, NULL
)) == NULL
) {
1155 if ((pent
= create_entry(provname
)) == NULL
) {
1156 cryptoerror(LOG_STDERR
, gettext("out of memory."));
1162 /* If it is unloaded already, return */
1163 if (!pent
->load
) { /* unloaded already */
1164 cryptoerror(LOG_STDERR
,
1165 gettext("failed to unload %s."), provname
);
1168 } else if (unload_kef_soft(provname
) != FAILURE
) {
1169 /* Mark as unloaded in kcf.conf */
1170 pent
->load
= B_FALSE
;
1171 rc
= update_kcfconf(pent
, MODIFY_MODE
);
1173 cryptoerror(LOG_STDERR
,
1174 gettext("failed to unload %s."), provname
);
1186 * The top level function for the "cryptoadm refresh" subcommand.
1189 do_refresh(int argc
)
1193 return (ERROR_USAGE
);
1196 if (getzoneid() == GLOBAL_ZONEID
) {
1198 } else { /* non-global zone */
1200 * Note: in non-global zone, this must silently return SUCCESS
1201 * due to integration with SMF, for "svcadm refresh cryptosvc"
1209 * The top level function for the "cryptoadm start" subcommand.
1210 * This used to start up kcfd, but now all it does is load up the
1211 * initial providers.
1218 return (ERROR_USAGE
);
1221 return (do_refresh(argc
));
1225 * The top level function for the "cryptoadm stop" subcommand.
1226 * This no longer does anything useful, but we leave it here
1227 * for compatibility.
1234 return (ERROR_USAGE
);
1243 * Print a list all the the providers.
1244 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
1247 list_simple_for_all(boolean_t verbose
)
1249 uentrylist_t
*pliblist
= NULL
;
1250 uentrylist_t
*plibptr
= NULL
;
1251 entry_t
*pent
= NULL
;
1252 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1256 /* get user-level providers */
1257 (void) printf(gettext("\nUser-level providers:\n"));
1258 if (get_pkcs11conf_info(&pliblist
) != SUCCESS
) {
1259 cryptoerror(LOG_STDERR
, gettext(
1260 "failed to retrieve the list of user-level providers."));
1264 for (plibptr
= pliblist
; plibptr
!= NULL
; plibptr
= plibptr
->next
) {
1265 /* skip metaslot and fips-140 entry */
1266 if ((strcmp(plibptr
->puent
->name
, METASLOT_KEYWORD
) != 0) &&
1267 (strcmp(plibptr
->puent
->name
, FIPS_KEYWORD
) != 0)) {
1268 (void) printf(gettext("Provider: %s\n"),
1269 plibptr
->puent
->name
);
1271 (void) list_mechlist_for_lib(
1272 plibptr
->puent
->name
, mecharglist
, NULL
,
1273 B_FALSE
, verbose
, B_FALSE
);
1274 (void) printf("\n");
1278 free_uentrylist(pliblist
);
1280 /* get kernel software providers */
1281 (void) printf(gettext("\nKernel software providers:\n"));
1283 if (getzoneid() == GLOBAL_ZONEID
) {
1284 /* get kernel software providers from kernel ioctl */
1285 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1286 uint_t sl_soft_count
;
1288 entrylist_t
*pdevlist_conf
= NULL
;
1289 entrylist_t
*psoftlist_conf
= NULL
;
1291 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1292 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1293 "software provider list from kernel."));
1296 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1298 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
)
1300 cryptoerror(LOG_ERR
,
1301 "failed to retrieve the providers' "
1302 "information from file kcf.conf - %s.",
1304 free(psoftlist_kernel
);
1309 psoftname
= psoftlist_kernel
->sl_soft_names
;
1311 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1312 pent
= getent_kef(psoftname
,
1313 pdevlist_conf
, psoftlist_conf
);
1314 (void) printf("\t%s%s\n", psoftname
,
1315 (pent
== NULL
) || (pent
->load
) ?
1316 "" : gettext(" (inactive)"));
1318 free_entrylist(pdevlist_conf
);
1319 free_entrylist(psoftlist_conf
);
1321 free(psoftlist_kernel
);
1325 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1326 entrylist_t
*pdevlist_zone
= NULL
;
1327 entrylist_t
*psoftlist_zone
= NULL
;
1330 if (get_admindev_info(&pdevlist_zone
, &psoftlist_zone
) !=
1332 cryptoerror(LOG_STDERR
,
1333 gettext("failed to retrieve the "
1334 "list of kernel software providers.\n"));
1338 ptr
= psoftlist_zone
;
1339 while (ptr
!= NULL
) {
1340 (void) printf("\t%s\n", ptr
->pent
->name
);
1344 free_entrylist(pdevlist_zone
);
1345 free_entrylist(psoftlist_zone
);
1348 /* get kernel hardware providers */
1349 (void) printf(gettext("\nKernel hardware providers:\n"));
1350 if (get_dev_list(&pdevlist_kernel
) == FAILURE
) {
1351 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1352 "the list of kernel hardware providers.\n"));
1355 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1356 (void) printf("\t%s/%d\n",
1357 pdevlist_kernel
->dl_devs
[i
].le_dev_name
,
1358 pdevlist_kernel
->dl_devs
[i
].le_dev_instance
);
1361 free(pdevlist_kernel
);
1369 * List all the providers. And for each provider, list the mechanism list.
1370 * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
1373 list_mechlist_for_all(boolean_t verbose
)
1375 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1376 uentrylist_t
*pliblist
= NULL
;
1377 uentrylist_t
*plibptr
= NULL
;
1378 entry_t
*pent
= NULL
;
1379 mechlist_t
*pmechlist
= NULL
;
1380 char provname
[MAXNAMELEN
];
1381 char devname
[MAXNAMELEN
];
1388 /* get user-level providers */
1389 (void) printf(gettext("\nUser-level providers:\n"));
1392 * Strictly for appearance's sake, this line should be as long as
1393 * the length of the translated text above.
1395 (void) printf(gettext("=====================\n"));
1396 if (get_pkcs11conf_info(&pliblist
) != SUCCESS
) {
1397 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1398 "the list of user-level providers.\n"));
1403 while (plibptr
!= NULL
) {
1404 /* skip metaslot and fips-140 entry */
1405 if ((strcmp(plibptr
->puent
->name
, METASLOT_KEYWORD
) != 0) &&
1406 (strcmp(plibptr
->puent
->name
, FIPS_KEYWORD
) != 0)) {
1407 (void) printf(gettext("\nProvider: %s\n"),
1408 plibptr
->puent
->name
);
1409 rv
= list_mechlist_for_lib(plibptr
->puent
->name
,
1410 mecharglist
, NULL
, B_FALSE
, verbose
, B_TRUE
);
1411 if (rv
== FAILURE
) {
1415 plibptr
= plibptr
->next
;
1417 free_uentrylist(pliblist
);
1419 /* get kernel software providers */
1420 (void) printf(gettext("\nKernel software providers:\n"));
1424 * Strictly for appearance's sake, this line should be as long as
1425 * the length of the translated text above.
1427 (void) printf(gettext("==========================\n"));
1428 if (getzoneid() == GLOBAL_ZONEID
) {
1429 /* get kernel software providers from kernel ioctl */
1430 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1431 uint_t sl_soft_count
;
1434 entrylist_t
*pdevlist_conf
= NULL
;
1435 entrylist_t
*psoftlist_conf
= NULL
;
1437 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1438 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1439 "software provider list from kernel."));
1442 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1444 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
)
1446 cryptoerror(LOG_ERR
,
1447 "failed to retrieve the providers' "
1448 "information from file kcf.conf - %s.",
1450 free(psoftlist_kernel
);
1454 for (i
= 0, psoftname
= psoftlist_kernel
->sl_soft_names
;
1456 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1457 pent
= getent_kef(psoftname
, pdevlist_conf
,
1459 if ((pent
== NULL
) || (pent
->load
)) {
1460 rv
= list_mechlist_for_soft(psoftname
,
1462 if (rv
== FAILURE
) {
1466 (void) printf(gettext("%s: (inactive)\n"),
1471 free(psoftlist_kernel
);
1472 free_entrylist(pdevlist_conf
);
1473 free_entrylist(psoftlist_conf
);
1476 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1477 entrylist_t
*pdevlist_zone
= NULL
;
1478 entrylist_t
*psoftlist_zone
= NULL
;
1481 if (get_admindev_info(&pdevlist_zone
, &psoftlist_zone
) !=
1483 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1484 "the list of kernel software providers.\n"));
1488 for (ptr
= psoftlist_zone
; ptr
!= NULL
; ptr
= ptr
->next
) {
1489 rv
= list_mechlist_for_soft(ptr
->pent
->name
,
1490 pdevlist_zone
, psoftlist_zone
);
1491 if (rv
== FAILURE
) {
1492 (void) printf(gettext(
1493 "%s: failed to get the mechanism list.\n"),
1499 free_entrylist(pdevlist_zone
);
1500 free_entrylist(psoftlist_zone
);
1503 /* Get kernel hardware providers and their mechanism lists */
1504 (void) printf(gettext("\nKernel hardware providers:\n"));
1507 * Strictly for appearance's sake, this line should be as long as
1508 * the length of the translated text above.
1510 (void) printf(gettext("==========================\n"));
1511 if (get_dev_list(&pdevlist_kernel
) != SUCCESS
) {
1512 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1513 "the list of hardware providers.\n"));
1517 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1518 (void) strlcpy(devname
,
1519 pdevlist_kernel
->dl_devs
[i
].le_dev_name
, MAXNAMELEN
);
1520 inst_num
= pdevlist_kernel
->dl_devs
[i
].le_dev_instance
;
1521 count
= pdevlist_kernel
->dl_devs
[i
].le_mechanism_count
;
1522 (void) snprintf(provname
, sizeof (provname
), "%s/%d", devname
,
1524 if (get_dev_info(devname
, inst_num
, count
, &pmechlist
) ==
1526 (void) filter_mechlist(&pmechlist
, RANDOM
);
1527 print_mechlist(provname
, pmechlist
);
1528 free_mechlist(pmechlist
);
1530 (void) printf(gettext("%s: failed to get the mechanism"
1531 " list.\n"), provname
);
1535 free(pdevlist_kernel
);
1541 * List all the providers. And for each provider, list the policy information.
1542 * Called for "cryptoadm list -p".
1545 list_policy_for_all(void)
1547 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1548 uentrylist_t
*pliblist
= NULL
;
1549 entrylist_t
*pdevlist_conf
= NULL
;
1550 entrylist_t
*psoftlist_conf
= NULL
;
1551 entrylist_t
*ptr
= NULL
;
1552 entrylist_t
*phead
= NULL
;
1553 boolean_t found
= B_FALSE
;
1554 char provname
[MAXNAMELEN
];
1558 /* Get user-level providers */
1559 (void) printf(gettext("\nUser-level providers:\n"));
1562 * Strictly for appearance's sake, this line should be as long as
1563 * the length of the translated text above.
1565 (void) printf(gettext("=====================\n"));
1566 if (get_pkcs11conf_info(&pliblist
) == FAILURE
) {
1567 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1568 "the list of user-level providers.\n"));
1571 uentrylist_t
*plibptr
= pliblist
;
1573 while (plibptr
!= NULL
) {
1574 /* skip metaslot and fips-140 entry */
1575 if ((strcmp(plibptr
->puent
->name
,
1576 METASLOT_KEYWORD
) != 0) &&
1577 (strcmp(plibptr
->puent
->name
,
1578 FIPS_KEYWORD
) != 0)) {
1579 if (print_uef_policy(plibptr
->puent
)
1584 plibptr
= plibptr
->next
;
1586 free_uentrylist(pliblist
);
1589 /* kernel software providers */
1590 (void) printf(gettext("\nKernel software providers:\n"));
1593 * Strictly for appearance's sake, this line should be as long as
1594 * the length of the translated text above.
1596 (void) printf(gettext("==========================\n"));
1598 /* Get all entries from the kernel */
1599 if (getzoneid() == GLOBAL_ZONEID
) {
1600 /* get kernel software providers from kernel ioctl */
1601 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1602 uint_t sl_soft_count
;
1606 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1607 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1608 "software provider list from kernel."));
1611 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1613 for (i
= 0, psoftname
= psoftlist_kernel
->sl_soft_names
;
1615 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1616 (void) list_policy_for_soft(psoftname
,
1617 pdevlist_conf
, psoftlist_conf
);
1619 free(psoftlist_kernel
);
1623 /* kcf.conf not there in non-global zone, no policy info */
1627 * "global" is keyword and not to be translated.
1629 cryptoerror(LOG_STDERR
, gettext(
1630 "policy information for kernel software providers is "
1631 "available in the %s zone only"), "global");
1634 /* Kernel hardware providers */
1635 (void) printf(gettext("\nKernel hardware providers:\n"));
1638 * Strictly for appearance's sake, this line should be as long as
1639 * the length of the translated text above.
1641 (void) printf(gettext("==========================\n"));
1643 if (getzoneid() != GLOBAL_ZONEID
) {
1646 * "global" is keyword and not to be translated.
1648 cryptoerror(LOG_STDERR
, gettext(
1649 "policy information for kernel hardware providers is "
1650 "available in the %s zone only"), "global");
1654 /* Get the hardware provider list from kernel */
1655 if (get_dev_list(&pdevlist_kernel
) != SUCCESS
) {
1656 cryptoerror(LOG_STDERR
, gettext(
1657 "failed to retrieve the list of hardware providers.\n"));
1661 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
) == FAILURE
) {
1662 cryptoerror(LOG_ERR
, "failed to retrieve the providers' "
1663 "information from file kcf.conf - %s.",
1670 * For each hardware provider from kernel, check if it has an entry
1671 * in the config file. If it has an entry, print out the policy from
1672 * config file and remove the entry from the hardware provider list
1673 * of the config file. If it does not have an entry in the config
1674 * file, no mechanisms of it have been disabled. But, we still call
1675 * list_policy_for_hard() to account for the "random" feature.
1677 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1678 (void) snprintf(provname
, sizeof (provname
), "%s/%d",
1679 pdevlist_kernel
->dl_devs
[i
].le_dev_name
,
1680 pdevlist_kernel
->dl_devs
[i
].le_dev_instance
);
1683 phead
= ptr
= pdevlist_conf
;
1684 while (!found
&& ptr
) {
1685 if (strcmp(ptr
->pent
->name
, provname
) == 0) {
1694 (void) list_policy_for_hard(ptr
->pent
->name
,
1695 pdevlist_conf
, psoftlist_conf
, pdevlist_kernel
);
1697 pdevlist_conf
= pdevlist_conf
->next
;
1699 phead
->next
= ptr
->next
;
1701 free_entry(ptr
->pent
);
1704 (void) list_policy_for_hard(provname
, pdevlist_conf
,
1705 psoftlist_conf
, pdevlist_kernel
);
1710 * If there are still entries left in the pdevlist_conf list from
1711 * the config file, these providers must have been detached.
1712 * Should print out their policy information also.
1714 for (ptr
= pdevlist_conf
; ptr
!= NULL
; ptr
= ptr
->next
) {
1715 print_kef_policy(ptr
->pent
->name
, ptr
->pent
, B_FALSE
, B_TRUE
);
1718 free_entrylist(pdevlist_conf
);
1719 free_entrylist(psoftlist_conf
);
1720 free(pdevlist_kernel
);