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 */
710 if (mecharglist
!= NULL
)
711 free_mechlist(mecharglist
);
717 * The top level function for the "cryptoadm disable" subcommand.
720 do_disable(int argc
, char **argv
)
722 cryptoadm_provider_t
*prov
= NULL
;
724 boolean_t auto_key_migrate_flag
= B_FALSE
;
726 if ((argc
< 3) || (argc
> 5)) {
728 return (ERROR_USAGE
);
731 prov
= get_provider(argc
, argv
);
734 return (ERROR_USAGE
);
736 if (prov
->cp_type
== PROV_BADNAME
) {
740 if ((rc
= process_feature_operands(argc
, argv
)) != SUCCESS
) {
745 * If allflag or rndflag has already been set there is no reason to
748 if (prov
->cp_type
== METASLOT
) {
750 (rc
= process_metaslot_operands(argc
, argv
,
751 NULL
, NULL
, NULL
, &auto_key_migrate_flag
)) != SUCCESS
) {
755 } else if (!allflag
&& !rndflag
&&
756 (rc
= process_mech_operands(argc
, argv
, B_FALSE
)) != SUCCESS
) {
760 switch (prov
->cp_type
) {
762 rc
= disable_metaslot(mecharglist
, allflag
,
763 auto_key_migrate_flag
);
766 rc
= disable_uef_lib(prov
->cp_name
, rndflag
, allflag
,
770 if (rndflag
&& !allflag
) {
771 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
776 if (getzoneid() == GLOBAL_ZONEID
) {
777 rc
= disable_kef_software(prov
->cp_name
, rndflag
,
778 allflag
, mecharglist
);
782 * "disable" could be either a literal keyword
783 * and hence not to be translated, or a verb and
784 * translatable. A choice was made to view it as
785 * a literal keyword. "global" is keyword and not
788 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
789 "providers is supported in the %2$s zone only"),
790 "disable", "global");
795 if (rndflag
&& !allflag
) {
796 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
801 if (getzoneid() == GLOBAL_ZONEID
) {
802 rc
= disable_kef_hardware(prov
->cp_name
, rndflag
,
803 allflag
, mecharglist
);
807 * "disable" could be either a literal keyword
808 * and hence not to be translated, or a verb and
809 * translatable. A choice was made to view it as
810 * a literal keyword. "global" is keyword and not
813 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
814 "providers is supported in the %2$s zone only"),
815 "disable", "global");
819 default: /* should not come here */
826 if (mecharglist
!= NULL
) {
827 free_mechlist(mecharglist
);
834 * The top level function for the "cryptoadm enable" subcommand.
837 do_enable(int argc
, char **argv
)
839 cryptoadm_provider_t
*prov
= NULL
;
841 char *alt_token
= NULL
, *alt_slot
= NULL
;
842 boolean_t use_default
= B_FALSE
;
843 boolean_t auto_key_migrate_flag
= B_FALSE
;
845 if ((argc
< 3) || (argc
> 6)) {
847 return (ERROR_USAGE
);
850 prov
= get_provider(argc
, argv
);
853 return (ERROR_USAGE
);
855 if ((prov
->cp_type
!= METASLOT
) && (argc
!= 4)) {
857 return (ERROR_USAGE
);
859 if (prov
->cp_type
== PROV_BADNAME
) {
865 if (prov
->cp_type
== METASLOT
) {
866 if ((rc
= process_metaslot_operands(argc
, argv
, &alt_token
,
867 &alt_slot
, &use_default
, &auto_key_migrate_flag
))
872 if ((alt_slot
|| alt_token
) && use_default
) {
878 if ((rc
= process_feature_operands(argc
, argv
)) != SUCCESS
) {
883 * If allflag or rndflag has already been set there is
884 * no reason to process mech=
886 if (!allflag
&& !rndflag
&&
887 (rc
= process_mech_operands(argc
, argv
, B_FALSE
))
893 switch (prov
->cp_type
) {
895 rc
= enable_metaslot(alt_token
, alt_slot
, use_default
,
896 mecharglist
, allflag
, auto_key_migrate_flag
);
899 rc
= enable_uef_lib(prov
->cp_name
, rndflag
, allflag
,
904 if (rndflag
&& !allflag
) {
905 if ((mecharglist
= create_mech(RANDOM
)) == NULL
) {
910 if (getzoneid() == GLOBAL_ZONEID
) {
911 rc
= enable_kef(prov
->cp_name
, rndflag
, allflag
,
916 * "enable" could be either a literal keyword
917 * and hence not to be translated, or a verb and
918 * translatable. A choice was made to view it as
919 * a literal keyword. "global" is keyword and not
922 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
923 "providers is supported in the %2$s zone only"),
928 default: /* should not come here */
934 if (mecharglist
!= NULL
) {
935 free_mechlist(mecharglist
);
937 if (alt_token
!= NULL
) {
940 if (alt_slot
!= NULL
) {
949 * The top level function for the "cryptoadm install" subcommand.
952 do_install(int argc
, char **argv
)
954 cryptoadm_provider_t
*prov
= NULL
;
959 return (ERROR_USAGE
);
962 prov
= get_provider(argc
, argv
);
964 prov
->cp_type
== PROV_BADNAME
|| prov
->cp_type
== PROV_KEF_HARD
) {
967 * "install" could be either a literal keyword and hence
968 * not to be translated, or a verb and translatable. A
969 * choice was made to view it as a literal keyword.
971 cryptoerror(LOG_STDERR
,
972 gettext("bad provider name for %s."), "install");
977 if (prov
->cp_type
== PROV_UEF_LIB
) {
978 rc
= install_uef_lib(prov
->cp_name
);
982 /* It is the PROV_KEF_SOFT type now */
984 /* check if there are mechanism operands */
988 * "mechanism" could be either a literal keyword and hence
989 * not to be translated, or a descriptive word and
990 * translatable. A choice was made to view it as a literal
993 cryptoerror(LOG_STDERR
,
994 gettext("need %s operands for installing a"
995 " kernel software provider."), "mechanism");
1000 if ((rc
= process_mech_operands(argc
, argv
, B_FALSE
)) != SUCCESS
) {
1004 if (allflag
== B_TRUE
) {
1007 * "all", "mechanism", and "install" are all keywords and
1008 * not to be translated.
1010 cryptoerror(LOG_STDERR
,
1011 gettext("can not use the %1$s keyword for %2$s "
1012 "in the %3$s subcommand."), "all", "mechanism", "install");
1017 if (getzoneid() == GLOBAL_ZONEID
) {
1018 rc
= install_kef(prov
->cp_name
, mecharglist
);
1022 * "install" could be either a literal keyword and hence
1023 * not to be translated, or a verb and translatable. A
1024 * choice was made to view it as a literal keyword.
1025 * "global" is keyword and not to be translated.
1027 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel providers "
1028 "is supported in the %2$s zone only"), "install", "global");
1039 * The top level function for the "cryptoadm uninstall" subcommand.
1042 do_uninstall(int argc
, char **argv
)
1044 cryptoadm_provider_t
*prov
= NULL
;
1049 return (ERROR_USAGE
);
1052 prov
= get_provider(argc
, argv
);
1054 prov
->cp_type
== PROV_BADNAME
|| prov
->cp_type
== PROV_KEF_HARD
) {
1057 * "uninstall" could be either a literal keyword and hence
1058 * not to be translated, or a verb and translatable. A
1059 * choice was made to view it as a literal keyword.
1061 cryptoerror(LOG_STDERR
,
1062 gettext("bad provider name for %s."), "uninstall");
1067 if (prov
->cp_type
== PROV_UEF_LIB
) {
1068 rc
= uninstall_uef_lib(prov
->cp_name
);
1070 } else if (prov
->cp_type
== PROV_KEF_SOFT
) {
1071 if (getzoneid() == GLOBAL_ZONEID
) {
1072 /* unload and remove from kcf.conf */
1073 rc
= uninstall_kef(prov
->cp_name
);
1077 * "uninstall" could be either a literal keyword and
1078 * hence not to be translated, or a verb and
1079 * translatable. A choice was made to view it as a
1080 * literal keyword. "global" is keyword and not to
1083 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel "
1084 "providers is supported in the %2$s zone only"),
1085 "uninstall", "global");
1096 * The top level function for the "cryptoadm unload" subcommand.
1099 do_unload(int argc
, char **argv
)
1101 cryptoadm_provider_t
*prov
= NULL
;
1102 entry_t
*pent
= NULL
;
1103 boolean_t in_kernel
= B_FALSE
;
1105 char *provname
= NULL
;
1109 return (ERROR_USAGE
);
1112 /* check if it is a kernel software provider */
1113 prov
= get_provider(argc
, argv
);
1115 cryptoerror(LOG_STDERR
,
1116 gettext("unable to determine provider name."));
1119 provname
= prov
->cp_name
;
1120 if (prov
->cp_type
!= PROV_KEF_SOFT
) {
1121 cryptoerror(LOG_STDERR
,
1122 gettext("%s is not a valid kernel software provider."),
1128 if (getzoneid() != GLOBAL_ZONEID
) {
1131 * "unload" could be either a literal keyword and hence
1132 * not to be translated, or a verb and translatable.
1133 * A choice was made to view it as a literal keyword.
1134 * "global" is keyword and not to be translated.
1136 cryptoerror(LOG_STDERR
, gettext("%1$s for kernel providers "
1137 "is supported in the %2$s zone only"), "unload", "global");
1142 if (check_kernel_for_soft(provname
, NULL
, &in_kernel
) == FAILURE
) {
1143 cryptodebug("internal error");
1146 } else if (in_kernel
== B_FALSE
) {
1147 cryptoerror(LOG_STDERR
,
1148 gettext("provider %s is not loaded or does not exist."),
1154 /* Get kcf.conf entry. If none, build a new entry */
1155 if ((pent
= getent_kef(provname
, NULL
, NULL
)) == NULL
) {
1156 if ((pent
= create_entry(provname
)) == NULL
) {
1157 cryptoerror(LOG_STDERR
, gettext("out of memory."));
1163 /* If it is unloaded already, return */
1164 if (!pent
->load
) { /* unloaded already */
1165 cryptoerror(LOG_STDERR
,
1166 gettext("failed to unload %s."), provname
);
1169 } else if (unload_kef_soft(provname
) != FAILURE
) {
1170 /* Mark as unloaded in kcf.conf */
1171 pent
->load
= B_FALSE
;
1172 rc
= update_kcfconf(pent
, MODIFY_MODE
);
1174 cryptoerror(LOG_STDERR
,
1175 gettext("failed to unload %s."), provname
);
1187 * The top level function for the "cryptoadm refresh" subcommand.
1190 do_refresh(int argc
)
1194 return (ERROR_USAGE
);
1197 if (getzoneid() == GLOBAL_ZONEID
) {
1199 } else { /* non-global zone */
1201 * Note: in non-global zone, this must silently return SUCCESS
1202 * due to integration with SMF, for "svcadm refresh cryptosvc"
1210 * The top level function for the "cryptoadm start" subcommand.
1211 * This used to start up kcfd, but now all it does is load up the
1212 * initial providers.
1219 return (ERROR_USAGE
);
1222 return (do_refresh(argc
));
1226 * The top level function for the "cryptoadm stop" subcommand.
1227 * This no longer does anything useful, but we leave it here
1228 * for compatibility.
1235 return (ERROR_USAGE
);
1244 * Print a list all the the providers.
1245 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
1248 list_simple_for_all(boolean_t verbose
)
1250 uentrylist_t
*pliblist
= NULL
;
1251 uentrylist_t
*plibptr
= NULL
;
1252 entry_t
*pent
= NULL
;
1253 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1257 /* get user-level providers */
1258 (void) printf(gettext("\nUser-level providers:\n"));
1259 if (get_pkcs11conf_info(&pliblist
) != SUCCESS
) {
1260 cryptoerror(LOG_STDERR
, gettext(
1261 "failed to retrieve the list of user-level providers."));
1265 for (plibptr
= pliblist
; plibptr
!= NULL
; plibptr
= plibptr
->next
) {
1266 /* skip metaslot and fips-140 entry */
1267 if ((strcmp(plibptr
->puent
->name
, METASLOT_KEYWORD
) != 0) &&
1268 (strcmp(plibptr
->puent
->name
, FIPS_KEYWORD
) != 0)) {
1269 (void) printf(gettext("Provider: %s\n"),
1270 plibptr
->puent
->name
);
1272 (void) list_mechlist_for_lib(
1273 plibptr
->puent
->name
, mecharglist
, NULL
,
1274 B_FALSE
, verbose
, B_FALSE
);
1275 (void) printf("\n");
1279 free_uentrylist(pliblist
);
1281 /* get kernel software providers */
1282 (void) printf(gettext("\nKernel software providers:\n"));
1284 if (getzoneid() == GLOBAL_ZONEID
) {
1285 /* get kernel software providers from kernel ioctl */
1286 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1287 uint_t sl_soft_count
;
1289 entrylist_t
*pdevlist_conf
= NULL
;
1290 entrylist_t
*psoftlist_conf
= NULL
;
1292 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1293 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1294 "software provider list from kernel."));
1297 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1299 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
)
1301 cryptoerror(LOG_ERR
,
1302 "failed to retrieve the providers' "
1303 "information from file kcf.conf - %s.",
1305 free(psoftlist_kernel
);
1310 psoftname
= psoftlist_kernel
->sl_soft_names
;
1312 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1313 pent
= getent_kef(psoftname
,
1314 pdevlist_conf
, psoftlist_conf
);
1315 (void) printf("\t%s%s\n", psoftname
,
1316 (pent
== NULL
) || (pent
->load
) ?
1317 "" : gettext(" (inactive)"));
1319 free_entrylist(pdevlist_conf
);
1320 free_entrylist(psoftlist_conf
);
1322 free(psoftlist_kernel
);
1326 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1327 entrylist_t
*pdevlist_zone
= NULL
;
1328 entrylist_t
*psoftlist_zone
= NULL
;
1331 if (get_admindev_info(&pdevlist_zone
, &psoftlist_zone
) !=
1333 cryptoerror(LOG_STDERR
,
1334 gettext("failed to retrieve the "
1335 "list of kernel software providers.\n"));
1339 ptr
= psoftlist_zone
;
1340 while (ptr
!= NULL
) {
1341 (void) printf("\t%s\n", ptr
->pent
->name
);
1345 free_entrylist(pdevlist_zone
);
1346 free_entrylist(psoftlist_zone
);
1349 /* get kernel hardware providers */
1350 (void) printf(gettext("\nKernel hardware providers:\n"));
1351 if (get_dev_list(&pdevlist_kernel
) == FAILURE
) {
1352 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1353 "the list of kernel hardware providers.\n"));
1356 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1357 (void) printf("\t%s/%d\n",
1358 pdevlist_kernel
->dl_devs
[i
].le_dev_name
,
1359 pdevlist_kernel
->dl_devs
[i
].le_dev_instance
);
1362 free(pdevlist_kernel
);
1370 * List all the providers. And for each provider, list the mechanism list.
1371 * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
1374 list_mechlist_for_all(boolean_t verbose
)
1376 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1377 uentrylist_t
*pliblist
= NULL
;
1378 uentrylist_t
*plibptr
= NULL
;
1379 entry_t
*pent
= NULL
;
1380 mechlist_t
*pmechlist
= NULL
;
1381 char provname
[MAXNAMELEN
];
1382 char devname
[MAXNAMELEN
];
1389 /* get user-level providers */
1390 (void) printf(gettext("\nUser-level providers:\n"));
1393 * Strictly for appearance's sake, this line should be as long as
1394 * the length of the translated text above.
1396 (void) printf(gettext("=====================\n"));
1397 if (get_pkcs11conf_info(&pliblist
) != SUCCESS
) {
1398 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1399 "the list of user-level providers.\n"));
1404 while (plibptr
!= NULL
) {
1405 /* skip metaslot and fips-140 entry */
1406 if ((strcmp(plibptr
->puent
->name
, METASLOT_KEYWORD
) != 0) &&
1407 (strcmp(plibptr
->puent
->name
, FIPS_KEYWORD
) != 0)) {
1408 (void) printf(gettext("\nProvider: %s\n"),
1409 plibptr
->puent
->name
);
1410 rv
= list_mechlist_for_lib(plibptr
->puent
->name
,
1411 mecharglist
, NULL
, B_FALSE
, verbose
, B_TRUE
);
1412 if (rv
== FAILURE
) {
1416 plibptr
= plibptr
->next
;
1418 free_uentrylist(pliblist
);
1420 /* get kernel software providers */
1421 (void) printf(gettext("\nKernel software providers:\n"));
1425 * Strictly for appearance's sake, this line should be as long as
1426 * the length of the translated text above.
1428 (void) printf(gettext("==========================\n"));
1429 if (getzoneid() == GLOBAL_ZONEID
) {
1430 /* get kernel software providers from kernel ioctl */
1431 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1432 uint_t sl_soft_count
;
1435 entrylist_t
*pdevlist_conf
= NULL
;
1436 entrylist_t
*psoftlist_conf
= NULL
;
1438 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1439 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1440 "software provider list from kernel."));
1443 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1445 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
)
1447 cryptoerror(LOG_ERR
,
1448 "failed to retrieve the providers' "
1449 "information from file kcf.conf - %s.",
1451 free(psoftlist_kernel
);
1455 for (i
= 0, psoftname
= psoftlist_kernel
->sl_soft_names
;
1457 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1458 pent
= getent_kef(psoftname
, pdevlist_conf
,
1460 if ((pent
== NULL
) || (pent
->load
)) {
1461 rv
= list_mechlist_for_soft(psoftname
,
1463 if (rv
== FAILURE
) {
1467 (void) printf(gettext("%s: (inactive)\n"),
1472 free(psoftlist_kernel
);
1473 free_entrylist(pdevlist_conf
);
1474 free_entrylist(psoftlist_conf
);
1477 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1478 entrylist_t
*pdevlist_zone
= NULL
;
1479 entrylist_t
*psoftlist_zone
= NULL
;
1482 if (get_admindev_info(&pdevlist_zone
, &psoftlist_zone
) !=
1484 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1485 "the list of kernel software providers.\n"));
1489 for (ptr
= psoftlist_zone
; ptr
!= NULL
; ptr
= ptr
->next
) {
1490 rv
= list_mechlist_for_soft(ptr
->pent
->name
,
1491 pdevlist_zone
, psoftlist_zone
);
1492 if (rv
== FAILURE
) {
1493 (void) printf(gettext(
1494 "%s: failed to get the mechanism list.\n"),
1500 free_entrylist(pdevlist_zone
);
1501 free_entrylist(psoftlist_zone
);
1504 /* Get kernel hardware providers and their mechanism lists */
1505 (void) printf(gettext("\nKernel hardware providers:\n"));
1508 * Strictly for appearance's sake, this line should be as long as
1509 * the length of the translated text above.
1511 (void) printf(gettext("==========================\n"));
1512 if (get_dev_list(&pdevlist_kernel
) != SUCCESS
) {
1513 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1514 "the list of hardware providers.\n"));
1518 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1519 (void) strlcpy(devname
,
1520 pdevlist_kernel
->dl_devs
[i
].le_dev_name
, MAXNAMELEN
);
1521 inst_num
= pdevlist_kernel
->dl_devs
[i
].le_dev_instance
;
1522 count
= pdevlist_kernel
->dl_devs
[i
].le_mechanism_count
;
1523 (void) snprintf(provname
, sizeof (provname
), "%s/%d", devname
,
1525 if (get_dev_info(devname
, inst_num
, count
, &pmechlist
) ==
1527 (void) filter_mechlist(&pmechlist
, RANDOM
);
1528 print_mechlist(provname
, pmechlist
);
1529 free_mechlist(pmechlist
);
1531 (void) printf(gettext("%s: failed to get the mechanism"
1532 " list.\n"), provname
);
1536 free(pdevlist_kernel
);
1542 * List all the providers. And for each provider, list the policy information.
1543 * Called for "cryptoadm list -p".
1546 list_policy_for_all(void)
1548 crypto_get_dev_list_t
*pdevlist_kernel
= NULL
;
1549 uentrylist_t
*pliblist
= NULL
;
1550 entrylist_t
*pdevlist_conf
= NULL
;
1551 entrylist_t
*psoftlist_conf
= NULL
;
1552 entrylist_t
*ptr
= NULL
;
1553 entrylist_t
*phead
= NULL
;
1554 boolean_t found
= B_FALSE
;
1555 char provname
[MAXNAMELEN
];
1559 /* Get user-level providers */
1560 (void) printf(gettext("\nUser-level providers:\n"));
1563 * Strictly for appearance's sake, this line should be as long as
1564 * the length of the translated text above.
1566 (void) printf(gettext("=====================\n"));
1567 if (get_pkcs11conf_info(&pliblist
) == FAILURE
) {
1568 cryptoerror(LOG_STDERR
, gettext("failed to retrieve "
1569 "the list of user-level providers.\n"));
1572 uentrylist_t
*plibptr
= pliblist
;
1574 while (plibptr
!= NULL
) {
1575 /* skip metaslot and fips-140 entry */
1576 if ((strcmp(plibptr
->puent
->name
,
1577 METASLOT_KEYWORD
) != 0) &&
1578 (strcmp(plibptr
->puent
->name
,
1579 FIPS_KEYWORD
) != 0)) {
1580 if (print_uef_policy(plibptr
->puent
)
1585 plibptr
= plibptr
->next
;
1587 free_uentrylist(pliblist
);
1590 /* kernel software providers */
1591 (void) printf(gettext("\nKernel software providers:\n"));
1594 * Strictly for appearance's sake, this line should be as long as
1595 * the length of the translated text above.
1597 (void) printf(gettext("==========================\n"));
1599 /* Get all entries from the kernel */
1600 if (getzoneid() == GLOBAL_ZONEID
) {
1601 /* get kernel software providers from kernel ioctl */
1602 crypto_get_soft_list_t
*psoftlist_kernel
= NULL
;
1603 uint_t sl_soft_count
;
1607 if (get_soft_list(&psoftlist_kernel
) == FAILURE
) {
1608 cryptoerror(LOG_ERR
, gettext("Failed to retrieve the "
1609 "software provider list from kernel."));
1612 sl_soft_count
= psoftlist_kernel
->sl_soft_count
;
1614 for (i
= 0, psoftname
= psoftlist_kernel
->sl_soft_names
;
1616 ++i
, psoftname
+= strlen(psoftname
) + 1) {
1617 (void) list_policy_for_soft(psoftname
,
1618 pdevlist_conf
, psoftlist_conf
);
1620 free(psoftlist_kernel
);
1624 /* kcf.conf not there in non-global zone, no policy info */
1628 * "global" is keyword and not to be translated.
1630 cryptoerror(LOG_STDERR
, gettext(
1631 "policy information for kernel software providers is "
1632 "available in the %s zone only"), "global");
1635 /* Kernel hardware providers */
1636 (void) printf(gettext("\nKernel hardware providers:\n"));
1639 * Strictly for appearance's sake, this line should be as long as
1640 * the length of the translated text above.
1642 (void) printf(gettext("==========================\n"));
1644 if (getzoneid() != GLOBAL_ZONEID
) {
1647 * "global" is keyword and not to be translated.
1649 cryptoerror(LOG_STDERR
, gettext(
1650 "policy information for kernel hardware providers is "
1651 "available in the %s zone only"), "global");
1655 /* Get the hardware provider list from kernel */
1656 if (get_dev_list(&pdevlist_kernel
) != SUCCESS
) {
1657 cryptoerror(LOG_STDERR
, gettext(
1658 "failed to retrieve the list of hardware providers.\n"));
1662 if (get_kcfconf_info(&pdevlist_conf
, &psoftlist_conf
) == FAILURE
) {
1663 cryptoerror(LOG_ERR
, "failed to retrieve the providers' "
1664 "information from file kcf.conf - %s.",
1671 * For each hardware provider from kernel, check if it has an entry
1672 * in the config file. If it has an entry, print out the policy from
1673 * config file and remove the entry from the hardware provider list
1674 * of the config file. If it does not have an entry in the config
1675 * file, no mechanisms of it have been disabled. But, we still call
1676 * list_policy_for_hard() to account for the "random" feature.
1678 for (i
= 0; i
< pdevlist_kernel
->dl_dev_count
; i
++) {
1679 (void) snprintf(provname
, sizeof (provname
), "%s/%d",
1680 pdevlist_kernel
->dl_devs
[i
].le_dev_name
,
1681 pdevlist_kernel
->dl_devs
[i
].le_dev_instance
);
1684 phead
= ptr
= pdevlist_conf
;
1685 while (!found
&& ptr
) {
1686 if (strcmp(ptr
->pent
->name
, provname
) == 0) {
1695 (void) list_policy_for_hard(ptr
->pent
->name
,
1696 pdevlist_conf
, psoftlist_conf
, pdevlist_kernel
);
1698 pdevlist_conf
= pdevlist_conf
->next
;
1700 phead
->next
= ptr
->next
;
1702 free_entry(ptr
->pent
);
1705 (void) list_policy_for_hard(provname
, pdevlist_conf
,
1706 psoftlist_conf
, pdevlist_kernel
);
1711 * If there are still entries left in the pdevlist_conf list from
1712 * the config file, these providers must have been detached.
1713 * Should print out their policy information also.
1715 for (ptr
= pdevlist_conf
; ptr
!= NULL
; ptr
= ptr
->next
) {
1716 print_kef_policy(ptr
->pent
->name
, ptr
->pent
, B_FALSE
, B_TRUE
);
1719 free_entrylist(pdevlist_conf
);
1720 free_entrylist(psoftlist_conf
);
1721 free(pdevlist_kernel
);