static int cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, int *rval) { int error; #define ARG ((caddr_t)arg) switch (cmd) { case CRYPTO_LOAD_DEV_DISABLED: case CRYPTO_LOAD_SOFT_DISABLED: case CRYPTO_LOAD_SOFT_CONFIG: case CRYPTO_UNLOAD_SOFT_MODULE: case CRYPTO_POOL_CREATE: case CRYPTO_POOL_WAIT: case CRYPTO_POOL_RUN: case CRYPTO_LOAD_DOOR: case CRYPTO_FIPS140_SET: if ((error = drv_priv(c)) != 0) return (error); default: break; } switch (cmd) { case CRYPTO_GET_DEV_LIST: return (get_dev_list(dev, ARG, mode, rval)); case CRYPTO_GET_DEV_INFO: return (get_dev_info(dev, ARG, mode, rval)); case CRYPTO_GET_SOFT_LIST: return (get_soft_list(dev, ARG, mode, rval)); case CRYPTO_GET_SOFT_INFO: return (get_soft_info(dev, ARG, mode, rval)); case CRYPTO_LOAD_DEV_DISABLED: return (load_dev_disabled(dev, ARG, mode, rval)); case CRYPTO_LOAD_SOFT_DISABLED: return (load_soft_disabled(dev, ARG, mode, rval)); case CRYPTO_LOAD_SOFT_CONFIG: return (load_soft_config(dev, ARG, mode, rval)); case CRYPTO_UNLOAD_SOFT_MODULE: return (unload_soft_module(dev, ARG, mode, rval)); case CRYPTO_POOL_CREATE: /* * The framework allocates and initializes the pool. * So, this is a no op. We are keeping this ioctl around * to be used for any future threadpool related work. */ if (audit_active) audit_cryptoadm(CRYPTO_POOL_CREATE, NULL, NULL, 0, 0, 0, 0); return (0); case CRYPTO_POOL_WAIT: { int nthrs = 0, err; if ((err = kcf_svc_wait(&nthrs)) == 0) { if (copyout((caddr_t)&nthrs, ARG, sizeof (int)) == -1) err = EFAULT; } if (audit_active) audit_cryptoadm(CRYPTO_POOL_WAIT, NULL, NULL, 0, 0, 0, err); return (err); } case CRYPTO_POOL_RUN: { int err; err = kcf_svc_do_run(); if (audit_active) audit_cryptoadm(CRYPTO_POOL_RUN, NULL, NULL, 0, 0, 0, err); return (err); } case CRYPTO_LOAD_DOOR: return (load_door(dev, ARG, mode, rval)); case CRYPTO_FIPS140_STATUS: return (fips140_actions(dev, ARG, mode, rval, cmd)); case CRYPTO_FIPS140_SET: { int err; err = fips140_actions(dev, ARG, mode, rval, cmd); if (audit_active) audit_cryptoadm(CRYPTO_FIPS140_SET, NULL, NULL, 0, 0, 0, err); return (err); } } return (EINVAL); }
/* * List all the providers. And for each provider, list the mechanism list. * Called for "cryptoadm list -m" or "cryptoadm list -mv" . */ static int list_mechlist_for_all(boolean_t verbose) { crypto_get_dev_list_t *pdevlist_kernel = NULL; uentrylist_t *pliblist = NULL; uentrylist_t *plibptr = NULL; entry_t *pent = NULL; mechlist_t *pmechlist = NULL; char provname[MAXNAMELEN]; char devname[MAXNAMELEN]; int inst_num; int count; int i; int rv; int rc = SUCCESS; /* get user-level providers */ (void) printf(gettext("\nUser-level providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("=====================\n")); if (get_pkcs11conf_info(&pliblist) != SUCCESS) { cryptoerror(LOG_STDERR, gettext("failed to retrieve " "the list of user-level providers.\n")); rc = FAILURE; } plibptr = pliblist; while (plibptr != NULL) { /* skip metaslot and fips-140 entry */ if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) && (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) { (void) printf(gettext("\nProvider: %s\n"), plibptr->puent->name); rv = list_mechlist_for_lib(plibptr->puent->name, mecharglist, NULL, B_FALSE, verbose, B_TRUE); if (rv == FAILURE) { rc = FAILURE; } } plibptr = plibptr->next; } free_uentrylist(pliblist); /* get kernel software providers */ (void) printf(gettext("\nKernel software providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("==========================\n")); if (getzoneid() == GLOBAL_ZONEID) { /* get kernel software providers from kernel ioctl */ crypto_get_soft_list_t *psoftlist_kernel = NULL; uint_t sl_soft_count; char *psoftname; int i; entrylist_t *pdevlist_conf = NULL; entrylist_t *psoftlist_conf = NULL; if (get_soft_list(&psoftlist_kernel) == FAILURE) { cryptoerror(LOG_ERR, gettext("Failed to retrieve the " "software provider list from kernel.")); return (FAILURE); } sl_soft_count = psoftlist_kernel->sl_soft_count; if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) { cryptoerror(LOG_ERR, "failed to retrieve the providers' " "information from file kcf.conf - %s.", _PATH_KCF_CONF); free(psoftlist_kernel); return (FAILURE); } for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; i < sl_soft_count; ++i, psoftname += strlen(psoftname) + 1) { pent = getent_kef(psoftname, pdevlist_conf, psoftlist_conf); if ((pent == NULL) || (pent->load)) { rv = list_mechlist_for_soft(psoftname, NULL, NULL); if (rv == FAILURE) { rc = FAILURE; } } else { (void) printf(gettext("%s: (inactive)\n"), psoftname); } } free(psoftlist_kernel); free_entrylist(pdevlist_conf); free_entrylist(psoftlist_conf); } else { /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ entrylist_t *pdevlist_zone = NULL; entrylist_t *psoftlist_zone = NULL; entrylist_t *ptr; if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != SUCCESS) { cryptoerror(LOG_STDERR, gettext("failed to retrieve " "the list of kernel software providers.\n")); rc = FAILURE; } for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) { rv = list_mechlist_for_soft(ptr->pent->name, pdevlist_zone, psoftlist_zone); if (rv == FAILURE) { (void) printf(gettext( "%s: failed to get the mechanism list.\n"), ptr->pent->name); rc = FAILURE; } } free_entrylist(pdevlist_zone); free_entrylist(psoftlist_zone); } /* Get kernel hardware providers and their mechanism lists */ (void) printf(gettext("\nKernel hardware providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("==========================\n")); if (get_dev_list(&pdevlist_kernel) != SUCCESS) { cryptoerror(LOG_STDERR, gettext("failed to retrieve " "the list of hardware providers.\n")); return (FAILURE); } for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { (void) strlcpy(devname, pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN); inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; count = pdevlist_kernel->dl_devs[i].le_mechanism_count; (void) snprintf(provname, sizeof (provname), "%s/%d", devname, inst_num); if (get_dev_info(devname, inst_num, count, &pmechlist) == SUCCESS) { (void) filter_mechlist(&pmechlist, RANDOM); print_mechlist(provname, pmechlist); free_mechlist(pmechlist); } else { (void) printf(gettext("%s: failed to get the mechanism" " list.\n"), provname); rc = FAILURE; } } free(pdevlist_kernel); return (rc); }
/* * List all the providers. And for each provider, list the policy information. * Called for "cryptoadm list -p". */ static int list_policy_for_all(void) { crypto_get_dev_list_t *pdevlist_kernel = NULL; uentrylist_t *pliblist = NULL; entrylist_t *pdevlist_conf = NULL; entrylist_t *psoftlist_conf = NULL; entrylist_t *ptr = NULL; entrylist_t *phead = NULL; boolean_t found = B_FALSE; char provname[MAXNAMELEN]; int i; int rc = SUCCESS; /* Get user-level providers */ (void) printf(gettext("\nUser-level providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("=====================\n")); if (get_pkcs11conf_info(&pliblist) == FAILURE) { cryptoerror(LOG_STDERR, gettext("failed to retrieve " "the list of user-level providers.\n")); rc = FAILURE; } else { uentrylist_t *plibptr = pliblist; while (plibptr != NULL) { /* skip metaslot and fips-140 entry */ if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) && (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) { if (print_uef_policy(plibptr->puent) == FAILURE) { rc = FAILURE; } } plibptr = plibptr->next; } free_uentrylist(pliblist); } /* kernel software providers */ (void) printf(gettext("\nKernel software providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("==========================\n")); /* Get all entries from the kernel */ if (getzoneid() == GLOBAL_ZONEID) { /* get kernel software providers from kernel ioctl */ crypto_get_soft_list_t *psoftlist_kernel = NULL; uint_t sl_soft_count; char *psoftname; int i; if (get_soft_list(&psoftlist_kernel) == FAILURE) { cryptoerror(LOG_ERR, gettext("Failed to retrieve the " "software provider list from kernel.")); rc = FAILURE; } else { sl_soft_count = psoftlist_kernel->sl_soft_count; for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; i < sl_soft_count; ++i, psoftname += strlen(psoftname) + 1) { (void) list_policy_for_soft(psoftname, pdevlist_conf, psoftlist_conf); } free(psoftlist_kernel); } } else { /* kcf.conf not there in non-global zone, no policy info */ /* * TRANSLATION_NOTE * "global" is keyword and not to be translated. */ cryptoerror(LOG_STDERR, gettext( "policy information for kernel software providers is " "available in the %s zone only"), "global"); } /* Kernel hardware providers */ (void) printf(gettext("\nKernel hardware providers:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("==========================\n")); if (getzoneid() != GLOBAL_ZONEID) { /* * TRANSLATION_NOTE * "global" is keyword and not to be translated. */ cryptoerror(LOG_STDERR, gettext( "policy information for kernel hardware providers is " "available in the %s zone only"), "global"); return (FAILURE); } /* Get the hardware provider list from kernel */ if (get_dev_list(&pdevlist_kernel) != SUCCESS) { cryptoerror(LOG_STDERR, gettext( "failed to retrieve the list of hardware providers.\n")); return (FAILURE); } if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) { cryptoerror(LOG_ERR, "failed to retrieve the providers' " "information from file kcf.conf - %s.", _PATH_KCF_CONF); return (FAILURE); } /* * For each hardware provider from kernel, check if it has an entry * in the config file. If it has an entry, print out the policy from * config file and remove the entry from the hardware provider list * of the config file. If it does not have an entry in the config * file, no mechanisms of it have been disabled. But, we still call * list_policy_for_hard() to account for the "random" feature. */ for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { (void) snprintf(provname, sizeof (provname), "%s/%d", pdevlist_kernel->dl_devs[i].le_dev_name, pdevlist_kernel->dl_devs[i].le_dev_instance); found = B_FALSE; phead = ptr = pdevlist_conf; while (!found && ptr) { if (strcmp(ptr->pent->name, provname) == 0) { found = B_TRUE; } else { phead = ptr; ptr = ptr->next; } } if (found) { (void) list_policy_for_hard(ptr->pent->name, pdevlist_conf, psoftlist_conf, pdevlist_kernel); if (phead == ptr) { pdevlist_conf = pdevlist_conf->next; } else { phead->next = ptr->next; } free_entry(ptr->pent); free(ptr); } else { (void) list_policy_for_hard(provname, pdevlist_conf, psoftlist_conf, pdevlist_kernel); } } /* * If there are still entries left in the pdevlist_conf list from * the config file, these providers must have been detached. * Should print out their policy information also. */ for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) { print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE); } free_entrylist(pdevlist_conf); free_entrylist(psoftlist_conf); free(pdevlist_kernel); return (rc); }
/* * Print a list all the the providers. * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p). */ static int list_simple_for_all(boolean_t verbose) { uentrylist_t *pliblist = NULL; uentrylist_t *plibptr = NULL; entry_t *pent = NULL; crypto_get_dev_list_t *pdevlist_kernel = NULL; int rc = SUCCESS; int i; /* get user-level providers */ (void) printf(gettext("\nUser-level providers:\n")); if (get_pkcs11conf_info(&pliblist) != SUCCESS) { cryptoerror(LOG_STDERR, gettext( "failed to retrieve the list of user-level providers.")); rc = FAILURE; } for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) { /* skip metaslot and fips-140 entry */ if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) && (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) { (void) printf(gettext("Provider: %s\n"), plibptr->puent->name); if (verbose) { (void) list_mechlist_for_lib( plibptr->puent->name, mecharglist, NULL, B_FALSE, verbose, B_FALSE); (void) printf("\n"); } } } free_uentrylist(pliblist); /* get kernel software providers */ (void) printf(gettext("\nKernel software providers:\n")); if (getzoneid() == GLOBAL_ZONEID) { /* get kernel software providers from kernel ioctl */ crypto_get_soft_list_t *psoftlist_kernel = NULL; uint_t sl_soft_count; char *psoftname; entrylist_t *pdevlist_conf = NULL; entrylist_t *psoftlist_conf = NULL; if (get_soft_list(&psoftlist_kernel) == FAILURE) { cryptoerror(LOG_ERR, gettext("Failed to retrieve the " "software provider list from kernel.")); rc = FAILURE; } else { sl_soft_count = psoftlist_kernel->sl_soft_count; if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) { cryptoerror(LOG_ERR, "failed to retrieve the providers' " "information from file kcf.conf - %s.", _PATH_KCF_CONF); free(psoftlist_kernel); rc = FAILURE; } else { for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; i < sl_soft_count; ++i, psoftname += strlen(psoftname) + 1) { pent = getent_kef(psoftname, pdevlist_conf, psoftlist_conf); (void) printf("\t%s%s\n", psoftname, (pent == NULL) || (pent->load) ? "" : gettext(" (inactive)")); } free_entrylist(pdevlist_conf); free_entrylist(psoftlist_conf); } free(psoftlist_kernel); } } else { /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ entrylist_t *pdevlist_zone = NULL; entrylist_t *psoftlist_zone = NULL; entrylist_t *ptr; if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != SUCCESS) { cryptoerror(LOG_STDERR, gettext("failed to retrieve the " "list of kernel software providers.\n")); rc = FAILURE; } ptr = psoftlist_zone; while (ptr != NULL) { (void) printf("\t%s\n", ptr->pent->name); ptr = ptr->next; } free_entrylist(pdevlist_zone); free_entrylist(psoftlist_zone); } /* get kernel hardware providers */ (void) printf(gettext("\nKernel hardware providers:\n")); if (get_dev_list(&pdevlist_kernel) == FAILURE) { cryptoerror(LOG_STDERR, gettext("failed to retrieve " "the list of kernel hardware providers.\n")); rc = FAILURE; } else { for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { (void) printf("\t%s/%d\n", pdevlist_kernel->dl_devs[i].le_dev_name, pdevlist_kernel->dl_devs[i].le_dev_instance); } } free(pdevlist_kernel); return (rc); }