10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57968Sopensolaris@drydog.com * Common Development and Distribution License (the "License").
67968Sopensolaris@drydog.com * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12929SMisaki.Miyashita@Oracle.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <fcntl.h>
260Sstevel@tonic-gate #include <stdio.h>
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <strings.h>
290Sstevel@tonic-gate #include <unistd.h>
300Sstevel@tonic-gate #include <locale.h>
310Sstevel@tonic-gate #include <libgen.h>
320Sstevel@tonic-gate #include <sys/types.h>
33*12929SMisaki.Miyashita@Oracle.COM #include <sys/varargs.h>
340Sstevel@tonic-gate #include <zone.h>
350Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
360Sstevel@tonic-gate #include "cryptoadm.h"
370Sstevel@tonic-gate
380Sstevel@tonic-gate #define DEFAULT_DEV_NUM 5
390Sstevel@tonic-gate #define DEFAULT_SOFT_NUM 10
400Sstevel@tonic-gate
41*12929SMisaki.Miyashita@Oracle.COM #define NUM_FIPS_SW_PROV \
42*12929SMisaki.Miyashita@Oracle.COM (sizeof (fips_sw_providers) / sizeof (char *))
43*12929SMisaki.Miyashita@Oracle.COM
44*12929SMisaki.Miyashita@Oracle.COM static char *fips_sw_providers[] = {
45*12929SMisaki.Miyashita@Oracle.COM "des",
46*12929SMisaki.Miyashita@Oracle.COM "aes",
47*12929SMisaki.Miyashita@Oracle.COM "ecc",
48*12929SMisaki.Miyashita@Oracle.COM "sha1",
49*12929SMisaki.Miyashita@Oracle.COM "sha2",
50*12929SMisaki.Miyashita@Oracle.COM "rsa",
51*12929SMisaki.Miyashita@Oracle.COM "swrand"
52*12929SMisaki.Miyashita@Oracle.COM };
53*12929SMisaki.Miyashita@Oracle.COM
540Sstevel@tonic-gate static crypto_get_soft_info_t *setup_get_soft_info(char *, int);
550Sstevel@tonic-gate
56*12929SMisaki.Miyashita@Oracle.COM static void
fips_sw_printf(const char * format,...)57*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(const char *format, ...)
58*12929SMisaki.Miyashita@Oracle.COM {
59*12929SMisaki.Miyashita@Oracle.COM va_list ap;
60*12929SMisaki.Miyashita@Oracle.COM char message[1024];
61*12929SMisaki.Miyashita@Oracle.COM int i;
62*12929SMisaki.Miyashita@Oracle.COM
63*12929SMisaki.Miyashita@Oracle.COM va_start(ap, format);
64*12929SMisaki.Miyashita@Oracle.COM (void) snprintf(message, sizeof (message), format, ap);
65*12929SMisaki.Miyashita@Oracle.COM va_end(ap);
66*12929SMisaki.Miyashita@Oracle.COM
67*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("\nUser-level providers:\n"));
68*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("=====================\n"));
69*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("/usr/lib/security/$ISA/pkcs11_softtoken: %s\n"),
70*12929SMisaki.Miyashita@Oracle.COM message);
71*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("\nKernel software providers:\n"));
72*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("==========================\n"));
73*12929SMisaki.Miyashita@Oracle.COM for (i = 0; i < NUM_FIPS_SW_PROV; i++) {
74*12929SMisaki.Miyashita@Oracle.COM (void) printf(gettext("%s: %s\n"),
75*12929SMisaki.Miyashita@Oracle.COM fips_sw_providers[i], message);
76*12929SMisaki.Miyashita@Oracle.COM }
77*12929SMisaki.Miyashita@Oracle.COM }
78*12929SMisaki.Miyashita@Oracle.COM
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate * Prepare the argument for the LOAD_SOFT_CONFIG ioctl call for the
810Sstevel@tonic-gate * provider pointed by pent. Return NULL if out of memory.
820Sstevel@tonic-gate */
830Sstevel@tonic-gate crypto_load_soft_config_t *
setup_soft_conf(entry_t * pent)840Sstevel@tonic-gate setup_soft_conf(entry_t *pent)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate crypto_load_soft_config_t *pload_soft_conf;
870Sstevel@tonic-gate mechlist_t *plist;
887968Sopensolaris@drydog.com uint_t sup_count;
897968Sopensolaris@drydog.com size_t extra_mech_size = 0;
907968Sopensolaris@drydog.com int i;
910Sstevel@tonic-gate
920Sstevel@tonic-gate if (pent == NULL) {
930Sstevel@tonic-gate return (NULL);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate
960Sstevel@tonic-gate sup_count = pent->sup_count;
970Sstevel@tonic-gate if (sup_count > 1) {
980Sstevel@tonic-gate extra_mech_size = sizeof (crypto_mech_name_t) *
990Sstevel@tonic-gate (sup_count - 1);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate pload_soft_conf = malloc(sizeof (crypto_load_soft_config_t) +
1030Sstevel@tonic-gate extra_mech_size);
1040Sstevel@tonic-gate if (pload_soft_conf == NULL) {
1050Sstevel@tonic-gate cryptodebug("out of memory.");
1060Sstevel@tonic-gate return (NULL);
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate (void) strlcpy(pload_soft_conf->sc_name, pent->name, MAXNAMELEN);
1100Sstevel@tonic-gate pload_soft_conf->sc_count = sup_count;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate i = 0;
1130Sstevel@tonic-gate plist = pent->suplist;
1140Sstevel@tonic-gate while (i < sup_count) {
1150Sstevel@tonic-gate (void) strlcpy(pload_soft_conf->sc_list[i++],
1160Sstevel@tonic-gate plist->name, CRYPTO_MAX_MECH_NAME);
1170Sstevel@tonic-gate plist = plist->next;
1180Sstevel@tonic-gate }
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate return (pload_soft_conf);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate /*
1250Sstevel@tonic-gate * Prepare the argument for the LOAD_SOFT_DISABLED ioctl call for the
1260Sstevel@tonic-gate * provider pointed by pent. Return NULL if out of memory.
1270Sstevel@tonic-gate */
1280Sstevel@tonic-gate crypto_load_soft_disabled_t *
setup_soft_dis(entry_t * pent)1290Sstevel@tonic-gate setup_soft_dis(entry_t *pent)
1300Sstevel@tonic-gate {
1317968Sopensolaris@drydog.com crypto_load_soft_disabled_t *pload_soft_dis = NULL;
1327968Sopensolaris@drydog.com mechlist_t *plist = NULL;
1337968Sopensolaris@drydog.com size_t extra_mech_size = 0;
1347968Sopensolaris@drydog.com uint_t dis_count;
1357968Sopensolaris@drydog.com int i;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate if (pent == NULL) {
1380Sstevel@tonic-gate return (NULL);
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate dis_count = pent->dis_count;
1420Sstevel@tonic-gate if (dis_count > 1) {
1430Sstevel@tonic-gate extra_mech_size = sizeof (crypto_mech_name_t) *
1440Sstevel@tonic-gate (dis_count - 1);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate pload_soft_dis = malloc(sizeof (crypto_load_soft_disabled_t) +
1480Sstevel@tonic-gate extra_mech_size);
1490Sstevel@tonic-gate if (pload_soft_dis == NULL) {
1500Sstevel@tonic-gate cryptodebug("out of memory.");
1510Sstevel@tonic-gate return (NULL);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate (void) strlcpy(pload_soft_dis->sd_name, pent->name, MAXNAMELEN);
1550Sstevel@tonic-gate pload_soft_dis->sd_count = dis_count;
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate i = 0;
1580Sstevel@tonic-gate plist = pent->dislist;
1590Sstevel@tonic-gate while (i < dis_count) {
1600Sstevel@tonic-gate (void) strlcpy(pload_soft_dis->sd_list[i++],
1610Sstevel@tonic-gate plist->name, CRYPTO_MAX_MECH_NAME);
1620Sstevel@tonic-gate plist = plist->next;
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate return (pload_soft_dis);
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate * Prepare the argument for the LOAD_DEV_DISABLED ioctl call for the
1710Sstevel@tonic-gate * provider pointed by pent. Return NULL if out of memory.
1720Sstevel@tonic-gate */
1730Sstevel@tonic-gate crypto_load_dev_disabled_t *
setup_dev_dis(entry_t * pent)1740Sstevel@tonic-gate setup_dev_dis(entry_t *pent)
1750Sstevel@tonic-gate {
1767968Sopensolaris@drydog.com crypto_load_dev_disabled_t *pload_dev_dis = NULL;
1777968Sopensolaris@drydog.com mechlist_t *plist = NULL;
1787968Sopensolaris@drydog.com size_t extra_mech_size = 0;
1797968Sopensolaris@drydog.com uint_t dis_count;
1807968Sopensolaris@drydog.com int i;
1817968Sopensolaris@drydog.com char pname[MAXNAMELEN];
1827968Sopensolaris@drydog.com int inst_num;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate if (pent == NULL) {
1850Sstevel@tonic-gate return (NULL);
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate /* get the device name and the instance number */
1890Sstevel@tonic-gate if (split_hw_provname(pent->name, pname, &inst_num) == FAILURE) {
1900Sstevel@tonic-gate return (NULL);
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate /* allocate space for pload_dev_des */
1940Sstevel@tonic-gate dis_count = pent->dis_count;
1950Sstevel@tonic-gate if (dis_count > 1) {
1960Sstevel@tonic-gate extra_mech_size = sizeof (crypto_mech_name_t) *
1970Sstevel@tonic-gate (dis_count - 1);
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate pload_dev_dis = malloc(sizeof (crypto_load_dev_disabled_t) +
2010Sstevel@tonic-gate extra_mech_size);
2020Sstevel@tonic-gate if (pload_dev_dis == NULL) {
2030Sstevel@tonic-gate cryptodebug("out of memory.");
2040Sstevel@tonic-gate return (NULL);
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate /* set the values for pload_dev_dis */
2080Sstevel@tonic-gate (void) strlcpy(pload_dev_dis->dd_dev_name, pname, MAXNAMELEN);
2090Sstevel@tonic-gate pload_dev_dis->dd_dev_instance = inst_num;
2100Sstevel@tonic-gate pload_dev_dis->dd_count = dis_count;
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate i = 0;
2130Sstevel@tonic-gate plist = pent->dislist;
2140Sstevel@tonic-gate while (i < dis_count) {
2150Sstevel@tonic-gate (void) strlcpy(pload_dev_dis->dd_list[i++],
2160Sstevel@tonic-gate plist->name, CRYPTO_MAX_MECH_NAME);
2170Sstevel@tonic-gate plist = plist->next;
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate return (pload_dev_dis);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate /*
2250Sstevel@tonic-gate * Prepare the calling argument of the UNLOAD_SOFT_MODULE ioctl call for the
2260Sstevel@tonic-gate * provider pointed by pent. Return NULL if out of memory.
2270Sstevel@tonic-gate */
2280Sstevel@tonic-gate crypto_unload_soft_module_t *
setup_unload_soft(entry_t * pent)2290Sstevel@tonic-gate setup_unload_soft(entry_t *pent)
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate crypto_unload_soft_module_t *punload_soft;
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate if (pent == NULL) {
2340Sstevel@tonic-gate return (NULL);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate punload_soft = malloc(sizeof (crypto_unload_soft_module_t));
2380Sstevel@tonic-gate if (punload_soft == NULL) {
2390Sstevel@tonic-gate cryptodebug("out of memory.");
2400Sstevel@tonic-gate return (NULL);
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate (void) strlcpy(punload_soft->sm_name, pent->name, MAXNAMELEN);
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate return (punload_soft);
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate /*
2500Sstevel@tonic-gate * Prepare the calling argument for the GET_SOFT_INFO call for the provider
2510Sstevel@tonic-gate * with the number of mechanisms specified in the second argument.
2527968Sopensolaris@drydog.com *
2537968Sopensolaris@drydog.com * Called by get_soft_info().
2540Sstevel@tonic-gate */
2550Sstevel@tonic-gate static crypto_get_soft_info_t *
setup_get_soft_info(char * provname,int count)2560Sstevel@tonic-gate setup_get_soft_info(char *provname, int count)
2570Sstevel@tonic-gate {
2587968Sopensolaris@drydog.com crypto_get_soft_info_t *psoft_info;
2597968Sopensolaris@drydog.com size_t extra_mech_size = 0;
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate if (provname == NULL) {
2620Sstevel@tonic-gate return (NULL);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate if (count > 1) {
2660Sstevel@tonic-gate extra_mech_size = sizeof (crypto_mech_name_t) * (count - 1);
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate psoft_info = malloc(sizeof (crypto_get_soft_info_t) + extra_mech_size);
2700Sstevel@tonic-gate if (psoft_info == NULL) {
2710Sstevel@tonic-gate cryptodebug("out of memory.");
2720Sstevel@tonic-gate return (NULL);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate (void) strlcpy(psoft_info->si_name, provname, MAXNAMELEN);
2760Sstevel@tonic-gate psoft_info->si_count = count;
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate return (psoft_info);
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /*
2830Sstevel@tonic-gate * Get the device list from kernel.
2840Sstevel@tonic-gate */
2850Sstevel@tonic-gate int
get_dev_list(crypto_get_dev_list_t ** ppdevlist)2860Sstevel@tonic-gate get_dev_list(crypto_get_dev_list_t **ppdevlist)
2870Sstevel@tonic-gate {
2887968Sopensolaris@drydog.com crypto_get_dev_list_t *pdevlist;
2897968Sopensolaris@drydog.com int fd = -1;
2907968Sopensolaris@drydog.com int count = DEFAULT_DEV_NUM;
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
2930Sstevel@tonic-gate sizeof (crypto_dev_list_entry_t) * (count - 1));
2940Sstevel@tonic-gate if (pdevlist == NULL) {
2950Sstevel@tonic-gate cryptodebug("out of memory.");
2960Sstevel@tonic-gate return (FAILURE);
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
3000Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
3010Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno));
3020Sstevel@tonic-gate return (FAILURE);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate pdevlist->dl_dev_count = count;
3060Sstevel@tonic-gate if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
3070Sstevel@tonic-gate cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
3080Sstevel@tonic-gate strerror(errno));
3090Sstevel@tonic-gate free(pdevlist);
3100Sstevel@tonic-gate (void) close(fd);
3110Sstevel@tonic-gate return (FAILURE);
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate /* BUFFER is too small, get the number of devices and retry it. */
3150Sstevel@tonic-gate if (pdevlist->dl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
3160Sstevel@tonic-gate count = pdevlist->dl_dev_count;
3170Sstevel@tonic-gate free(pdevlist);
3180Sstevel@tonic-gate pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
3190Sstevel@tonic-gate sizeof (crypto_dev_list_entry_t) * (count - 1));
3200Sstevel@tonic-gate if (pdevlist == NULL) {
3210Sstevel@tonic-gate cryptodebug("out of memory.");
3220Sstevel@tonic-gate (void) close(fd);
3230Sstevel@tonic-gate return (FAILURE);
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
3270Sstevel@tonic-gate cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
3280Sstevel@tonic-gate strerror(errno));
3290Sstevel@tonic-gate free(pdevlist);
3300Sstevel@tonic-gate (void) close(fd);
3310Sstevel@tonic-gate return (FAILURE);
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate if (pdevlist->dl_return_value != CRYPTO_SUCCESS) {
3360Sstevel@tonic-gate cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed, "
3370Sstevel@tonic-gate "return_value = %d", pdevlist->dl_return_value);
3380Sstevel@tonic-gate free(pdevlist);
3390Sstevel@tonic-gate (void) close(fd);
3400Sstevel@tonic-gate return (FAILURE);
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate *ppdevlist = pdevlist;
3440Sstevel@tonic-gate (void) close(fd);
3450Sstevel@tonic-gate return (SUCCESS);
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate /*
3500Sstevel@tonic-gate * Get all the mechanisms supported by the hardware provider.
3510Sstevel@tonic-gate * The result will be stored in the second argument.
3520Sstevel@tonic-gate */
3530Sstevel@tonic-gate int
get_dev_info(char * devname,int inst_num,int count,mechlist_t ** ppmechlist)3540Sstevel@tonic-gate get_dev_info(char *devname, int inst_num, int count, mechlist_t **ppmechlist)
3550Sstevel@tonic-gate {
3567968Sopensolaris@drydog.com crypto_get_dev_info_t *dev_info;
3577968Sopensolaris@drydog.com mechlist_t *phead;
3587968Sopensolaris@drydog.com mechlist_t *pcur;
3597968Sopensolaris@drydog.com mechlist_t *pmech;
3607968Sopensolaris@drydog.com int fd = -1;
3617968Sopensolaris@drydog.com int i;
3627968Sopensolaris@drydog.com int rc;
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate if (devname == NULL || count < 1) {
3650Sstevel@tonic-gate cryptodebug("get_dev_info(): devname is NULL or bogus count");
3660Sstevel@tonic-gate return (FAILURE);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate /* Set up the argument for the CRYPTO_GET_DEV_INFO ioctl call */
3700Sstevel@tonic-gate dev_info = malloc(sizeof (crypto_get_dev_info_t) +
3710Sstevel@tonic-gate sizeof (crypto_mech_name_t) * (count - 1));
3720Sstevel@tonic-gate if (dev_info == NULL) {
3730Sstevel@tonic-gate cryptodebug("out of memory.");
3740Sstevel@tonic-gate return (FAILURE);
3750Sstevel@tonic-gate }
3760Sstevel@tonic-gate (void) strlcpy(dev_info->di_dev_name, devname, MAXNAMELEN);
3770Sstevel@tonic-gate dev_info->di_dev_instance = inst_num;
3780Sstevel@tonic-gate dev_info->di_count = count;
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate /* Open the ioctl device */
3810Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
3820Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
3830Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno));
3840Sstevel@tonic-gate free(dev_info);
3850Sstevel@tonic-gate return (FAILURE);
3860Sstevel@tonic-gate }
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate if (ioctl(fd, CRYPTO_GET_DEV_INFO, dev_info) == -1) {
3890Sstevel@tonic-gate cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed: %s",
3900Sstevel@tonic-gate strerror(errno));
3910Sstevel@tonic-gate free(dev_info);
3920Sstevel@tonic-gate (void) close(fd);
3930Sstevel@tonic-gate return (FAILURE);
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate if (dev_info->di_return_value != CRYPTO_SUCCESS) {
3970Sstevel@tonic-gate cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed, "
3980Sstevel@tonic-gate "return_value = %d", dev_info->di_return_value);
3990Sstevel@tonic-gate free(dev_info);
4000Sstevel@tonic-gate (void) close(fd);
4010Sstevel@tonic-gate return (FAILURE);
4020Sstevel@tonic-gate }
4030Sstevel@tonic-gate
4040Sstevel@tonic-gate phead = pcur = NULL;
4050Sstevel@tonic-gate rc = SUCCESS;
4060Sstevel@tonic-gate for (i = 0; i < dev_info->di_count; i++) {
4070Sstevel@tonic-gate pmech = create_mech(&dev_info->di_list[i][0]);
4080Sstevel@tonic-gate if (pmech == NULL) {
4090Sstevel@tonic-gate rc = FAILURE;
4100Sstevel@tonic-gate break;
4110Sstevel@tonic-gate } else {
4120Sstevel@tonic-gate if (phead == NULL) {
4130Sstevel@tonic-gate phead = pcur = pmech;
4140Sstevel@tonic-gate } else {
4150Sstevel@tonic-gate pcur->next = pmech;
4160Sstevel@tonic-gate pcur = pmech;
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate if (rc == SUCCESS) {
4220Sstevel@tonic-gate *ppmechlist = phead;
4230Sstevel@tonic-gate } else {
4240Sstevel@tonic-gate free_mechlist(phead);
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate free(dev_info);
4280Sstevel@tonic-gate (void) close(fd);
4290Sstevel@tonic-gate return (rc);
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate /*
4340Sstevel@tonic-gate * Get the supported mechanism list of the software provider from kernel.
4357968Sopensolaris@drydog.com *
4367968Sopensolaris@drydog.com * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
4377968Sopensolaris@drydog.com * If NULL, this function calls get_kcfconf_info() internally.
4380Sstevel@tonic-gate */
4390Sstevel@tonic-gate int
get_soft_info(char * provname,mechlist_t ** ppmechlist,entrylist_t * phardlist,entrylist_t * psoftlist)4407968Sopensolaris@drydog.com get_soft_info(char *provname, mechlist_t **ppmechlist,
44110979SHai-May.Chao@Sun.COM entrylist_t *phardlist, entrylist_t *psoftlist)
4420Sstevel@tonic-gate {
4437968Sopensolaris@drydog.com boolean_t in_kernel = B_FALSE;
4440Sstevel@tonic-gate crypto_get_soft_info_t *psoft_info;
4457968Sopensolaris@drydog.com mechlist_t *phead;
4467968Sopensolaris@drydog.com mechlist_t *pmech;
4477968Sopensolaris@drydog.com mechlist_t *pcur;
4487968Sopensolaris@drydog.com entry_t *pent = NULL;
4497968Sopensolaris@drydog.com int count;
4507968Sopensolaris@drydog.com int fd = -1;
4517968Sopensolaris@drydog.com int rc;
4527968Sopensolaris@drydog.com int i;
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate if (provname == NULL) {
4550Sstevel@tonic-gate return (FAILURE);
4560Sstevel@tonic-gate }
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate if (getzoneid() == GLOBAL_ZONEID) {
4590Sstevel@tonic-gate /* use kcf.conf for kernel software providers in global zone */
46010979SHai-May.Chao@Sun.COM if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
46110979SHai-May.Chao@Sun.COM NULL) {
4627968Sopensolaris@drydog.com
4637968Sopensolaris@drydog.com /* No kcf.conf entry for this provider */
4647968Sopensolaris@drydog.com if (check_kernel_for_soft(provname, NULL, &in_kernel)
4657968Sopensolaris@drydog.com == FAILURE) {
4667968Sopensolaris@drydog.com return (FAILURE);
4677968Sopensolaris@drydog.com } else if (in_kernel == B_FALSE) {
4687968Sopensolaris@drydog.com cryptoerror(LOG_STDERR,
4697968Sopensolaris@drydog.com gettext("%s does not exist."), provname);
4707968Sopensolaris@drydog.com return (FAILURE);
4717968Sopensolaris@drydog.com }
4727968Sopensolaris@drydog.com
4737968Sopensolaris@drydog.com /*
4747968Sopensolaris@drydog.com * Set mech count to 1. It will be reset to the
4757968Sopensolaris@drydog.com * correct value later if the setup buffer is too small.
4767968Sopensolaris@drydog.com */
4777968Sopensolaris@drydog.com count = 1;
4787968Sopensolaris@drydog.com } else {
4797968Sopensolaris@drydog.com count = pent->sup_count;
4807968Sopensolaris@drydog.com free_entry(pent);
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate } else {
4830Sstevel@tonic-gate /*
4847968Sopensolaris@drydog.com * kcf.conf not there in non-global zone: set mech count to 1.
4857968Sopensolaris@drydog.com * It will be reset to the correct value later if the setup
4867968Sopensolaris@drydog.com * buffer is too small.
4870Sstevel@tonic-gate */
4880Sstevel@tonic-gate count = 1;
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate if ((psoft_info = setup_get_soft_info(provname, count)) == NULL) {
4920Sstevel@tonic-gate return (FAILURE);
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
4960Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
4970Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno));
4980Sstevel@tonic-gate free(psoft_info);
4990Sstevel@tonic-gate return (FAILURE);
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate /* make GET_SOFT_INFO ioctl call */
5030Sstevel@tonic-gate if ((rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info)) == -1) {
5040Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed: %s",
5050Sstevel@tonic-gate strerror(errno));
5060Sstevel@tonic-gate (void) close(fd);
5070Sstevel@tonic-gate free(psoft_info);
5080Sstevel@tonic-gate return (FAILURE);
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate /* BUFFER is too small, get the number of mechanisms and retry it. */
5120Sstevel@tonic-gate if (psoft_info->si_return_value == CRYPTO_BUFFER_TOO_SMALL) {
5130Sstevel@tonic-gate count = psoft_info->si_count;
5140Sstevel@tonic-gate free(psoft_info);
5150Sstevel@tonic-gate if ((psoft_info = setup_get_soft_info(provname, count))
5160Sstevel@tonic-gate == NULL) {
5170Sstevel@tonic-gate (void) close(fd);
5180Sstevel@tonic-gate return (FAILURE);
5190Sstevel@tonic-gate } else {
5200Sstevel@tonic-gate rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info);
5210Sstevel@tonic-gate if (rc == -1) {
5220Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_INFO ioctl "
5230Sstevel@tonic-gate "failed: %s", strerror(errno));
5240Sstevel@tonic-gate (void) close(fd);
5250Sstevel@tonic-gate free(psoft_info);
5260Sstevel@tonic-gate return (FAILURE);
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate }
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate (void) close(fd);
5320Sstevel@tonic-gate if (psoft_info->si_return_value != CRYPTO_SUCCESS) {
5330Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed, "
5340Sstevel@tonic-gate "return_value = %d", psoft_info->si_return_value);
5350Sstevel@tonic-gate free(psoft_info);
5360Sstevel@tonic-gate return (FAILURE);
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate
5407968Sopensolaris@drydog.com /* Build the mechanism linked list and return it */
5410Sstevel@tonic-gate rc = SUCCESS;
5420Sstevel@tonic-gate phead = pcur = NULL;
5430Sstevel@tonic-gate for (i = 0; i < psoft_info->si_count; i++) {
5440Sstevel@tonic-gate pmech = create_mech(&psoft_info->si_list[i][0]);
5450Sstevel@tonic-gate if (pmech == NULL) {
5460Sstevel@tonic-gate rc = FAILURE;
5470Sstevel@tonic-gate break;
5480Sstevel@tonic-gate } else {
5490Sstevel@tonic-gate if (phead == NULL) {
5500Sstevel@tonic-gate phead = pcur = pmech;
5510Sstevel@tonic-gate } else {
5520Sstevel@tonic-gate pcur->next = pmech;
5530Sstevel@tonic-gate pcur = pmech;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate if (rc == FAILURE) {
5590Sstevel@tonic-gate free_mechlist(phead);
5600Sstevel@tonic-gate } else {
5610Sstevel@tonic-gate *ppmechlist = phead;
5620Sstevel@tonic-gate }
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate free(psoft_info);
5650Sstevel@tonic-gate return (rc);
5660Sstevel@tonic-gate }
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate /*
5700Sstevel@tonic-gate * Get the kernel software provider list from kernel.
5710Sstevel@tonic-gate */
5720Sstevel@tonic-gate int
get_soft_list(crypto_get_soft_list_t ** ppsoftlist)5730Sstevel@tonic-gate get_soft_list(crypto_get_soft_list_t **ppsoftlist)
5740Sstevel@tonic-gate {
5750Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist = NULL;
5767968Sopensolaris@drydog.com int count = DEFAULT_SOFT_NUM;
5777968Sopensolaris@drydog.com int len;
5787968Sopensolaris@drydog.com int fd = -1;
5790Sstevel@tonic-gate
5800Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
5810Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
5820Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno));
5830Sstevel@tonic-gate return (FAILURE);
5840Sstevel@tonic-gate }
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate len = MAXNAMELEN * count;
5870Sstevel@tonic-gate psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
5880Sstevel@tonic-gate if (psoftlist == NULL) {
5890Sstevel@tonic-gate cryptodebug("out of memory.");
5900Sstevel@tonic-gate (void) close(fd);
5910Sstevel@tonic-gate return (FAILURE);
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
5940Sstevel@tonic-gate psoftlist->sl_soft_count = count;
5950Sstevel@tonic-gate psoftlist->sl_soft_len = len;
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
5980Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed: %s",
5990Sstevel@tonic-gate strerror(errno));
6000Sstevel@tonic-gate free(psoftlist);
6010Sstevel@tonic-gate (void) close(fd);
6020Sstevel@tonic-gate return (FAILURE);
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate /*
6060Sstevel@tonic-gate * if BUFFER is too small, get the number of software providers and
6070Sstevel@tonic-gate * the minimum length needed for names and length and retry it.
6080Sstevel@tonic-gate */
6090Sstevel@tonic-gate if (psoftlist->sl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
6100Sstevel@tonic-gate count = psoftlist->sl_soft_count;
6110Sstevel@tonic-gate len = psoftlist->sl_soft_len;
6120Sstevel@tonic-gate free(psoftlist);
6130Sstevel@tonic-gate psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
6140Sstevel@tonic-gate if (psoftlist == NULL) {
6150Sstevel@tonic-gate cryptodebug("out of memory.");
6160Sstevel@tonic-gate (void) close(fd);
6170Sstevel@tonic-gate return (FAILURE);
6180Sstevel@tonic-gate }
6190Sstevel@tonic-gate psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
6200Sstevel@tonic-gate psoftlist->sl_soft_count = count;
6210Sstevel@tonic-gate psoftlist->sl_soft_len = len;
6220Sstevel@tonic-gate
6230Sstevel@tonic-gate if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
6240Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed:"
6250Sstevel@tonic-gate "%s", strerror(errno));
6260Sstevel@tonic-gate free(psoftlist);
6270Sstevel@tonic-gate (void) close(fd);
6280Sstevel@tonic-gate return (FAILURE);
6290Sstevel@tonic-gate }
6300Sstevel@tonic-gate }
6310Sstevel@tonic-gate
6320Sstevel@tonic-gate if (psoftlist->sl_return_value != CRYPTO_SUCCESS) {
6330Sstevel@tonic-gate cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed, "
6340Sstevel@tonic-gate "return_value = %d", psoftlist->sl_return_value);
6350Sstevel@tonic-gate free(psoftlist);
6360Sstevel@tonic-gate (void) close(fd);
6370Sstevel@tonic-gate return (FAILURE);
6380Sstevel@tonic-gate }
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate *ppsoftlist = psoftlist;
6410Sstevel@tonic-gate (void) close(fd);
6420Sstevel@tonic-gate return (SUCCESS);
6430Sstevel@tonic-gate }
64410500SHai-May.Chao@Sun.COM
64510500SHai-May.Chao@Sun.COM /*
64610500SHai-May.Chao@Sun.COM * Perform the FIPS related actions
64710500SHai-May.Chao@Sun.COM */
64810500SHai-May.Chao@Sun.COM int
do_fips_actions(int action,int caller)64910500SHai-May.Chao@Sun.COM do_fips_actions(int action, int caller)
65010500SHai-May.Chao@Sun.COM {
65110500SHai-May.Chao@Sun.COM
65210500SHai-May.Chao@Sun.COM crypto_fips140_t fips_info;
65310500SHai-May.Chao@Sun.COM int fd;
65410500SHai-May.Chao@Sun.COM int rc = SUCCESS;
65510979SHai-May.Chao@Sun.COM int pkcs11_fips_mode = 0;
65610500SHai-May.Chao@Sun.COM
65710979SHai-May.Chao@Sun.COM /* Get FIPS-140 status from pkcs11.conf */
65810979SHai-May.Chao@Sun.COM fips_status_pkcs11conf(&pkcs11_fips_mode);
65910500SHai-May.Chao@Sun.COM
66010500SHai-May.Chao@Sun.COM if (action == FIPS140_STATUS) {
66110979SHai-May.Chao@Sun.COM if (pkcs11_fips_mode == CRYPTO_FIPS_MODE_ENABLED)
662*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode is enabled."));
66310500SHai-May.Chao@Sun.COM else
664*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode is disabled."));
66510500SHai-May.Chao@Sun.COM return (SUCCESS);
66610500SHai-May.Chao@Sun.COM }
66710500SHai-May.Chao@Sun.COM
66810500SHai-May.Chao@Sun.COM if (caller == NOT_REFRESH) {
66910500SHai-May.Chao@Sun.COM /* Is it a duplicate operation? */
67010500SHai-May.Chao@Sun.COM if ((action == FIPS140_ENABLE) &&
67110979SHai-May.Chao@Sun.COM (pkcs11_fips_mode == CRYPTO_FIPS_MODE_ENABLED)) {
672*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode has already "
673*12929SMisaki.Miyashita@Oracle.COM "been enabled."));
67410500SHai-May.Chao@Sun.COM return (FAILURE);
67510500SHai-May.Chao@Sun.COM }
67610500SHai-May.Chao@Sun.COM
67710500SHai-May.Chao@Sun.COM if ((action == FIPS140_DISABLE) &&
67810979SHai-May.Chao@Sun.COM (pkcs11_fips_mode == CRYPTO_FIPS_MODE_DISABLED)) {
679*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode has already "
680*12929SMisaki.Miyashita@Oracle.COM "been disabled."));
68110500SHai-May.Chao@Sun.COM return (FAILURE);
68210500SHai-May.Chao@Sun.COM }
68310500SHai-May.Chao@Sun.COM
68410500SHai-May.Chao@Sun.COM if ((action == FIPS140_ENABLE) || (action == FIPS140_DISABLE)) {
68510979SHai-May.Chao@Sun.COM /* Update pkcs11.conf */
68610979SHai-May.Chao@Sun.COM if ((rc = fips_update_pkcs11conf(action)) != SUCCESS)
68710500SHai-May.Chao@Sun.COM return (rc);
68810500SHai-May.Chao@Sun.COM }
68910500SHai-May.Chao@Sun.COM
69010500SHai-May.Chao@Sun.COM /* No need to inform kernel */
69110500SHai-May.Chao@Sun.COM if (action == FIPS140_ENABLE) {
692*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode was enabled "
693*12929SMisaki.Miyashita@Oracle.COM "successfully."));
69410500SHai-May.Chao@Sun.COM } else {
695*12929SMisaki.Miyashita@Oracle.COM fips_sw_printf(gettext("FIPS-140 mode was disabled "
696*12929SMisaki.Miyashita@Oracle.COM "successfully."));
69710500SHai-May.Chao@Sun.COM }
69810500SHai-May.Chao@Sun.COM
69910500SHai-May.Chao@Sun.COM return (SUCCESS);
70010500SHai-May.Chao@Sun.COM
70110500SHai-May.Chao@Sun.COM }
70210500SHai-May.Chao@Sun.COM
70310500SHai-May.Chao@Sun.COM /* This is refresh, need to inform kernel */
70410500SHai-May.Chao@Sun.COM (void) memset(&fips_info, 0, sizeof (crypto_fips140_t));
70510500SHai-May.Chao@Sun.COM
70610500SHai-May.Chao@Sun.COM if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
70710500SHai-May.Chao@Sun.COM cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
70810500SHai-May.Chao@Sun.COM ADMIN_IOCTL_DEVICE, strerror(errno));
70910500SHai-May.Chao@Sun.COM return (FAILURE);
71010500SHai-May.Chao@Sun.COM }
71110500SHai-May.Chao@Sun.COM
71210500SHai-May.Chao@Sun.COM switch (action) {
71310500SHai-May.Chao@Sun.COM case FIPS140_ENABLE:
71410500SHai-May.Chao@Sun.COM /* make CRYPTO_FIPS_SET ioctl call */
71510500SHai-May.Chao@Sun.COM fips_info.fips140_op = FIPS140_ENABLE;
71610500SHai-May.Chao@Sun.COM if ((rc = ioctl(fd, CRYPTO_FIPS140_SET, &fips_info)) == -1) {
71710500SHai-May.Chao@Sun.COM cryptodebug("CRYPTO_FIPS140_ENABLE ioctl failed: %s",
71810500SHai-May.Chao@Sun.COM strerror(errno));
71910500SHai-May.Chao@Sun.COM rc = FAILURE;
72010500SHai-May.Chao@Sun.COM goto out;
72110500SHai-May.Chao@Sun.COM }
72210500SHai-May.Chao@Sun.COM
72310500SHai-May.Chao@Sun.COM if (fips_info.fips140_return_value != CRYPTO_SUCCESS) {
72410500SHai-May.Chao@Sun.COM cryptodebug("CRYPTO_FIPS140_ENABLE ioctl failed, "
72510500SHai-May.Chao@Sun.COM "return_value = %d",
72610500SHai-May.Chao@Sun.COM fips_info.fips140_return_value);
72710500SHai-May.Chao@Sun.COM rc = FAILURE;
72810500SHai-May.Chao@Sun.COM }
72910500SHai-May.Chao@Sun.COM
73010500SHai-May.Chao@Sun.COM break;
73110500SHai-May.Chao@Sun.COM
73210500SHai-May.Chao@Sun.COM case FIPS140_DISABLE:
73310500SHai-May.Chao@Sun.COM /* make CRYPTO_FIPS140_SET ioctl call */
73410500SHai-May.Chao@Sun.COM fips_info.fips140_op = FIPS140_DISABLE;
73510500SHai-May.Chao@Sun.COM if ((rc = ioctl(fd, CRYPTO_FIPS140_SET, &fips_info)) == -1) {
73610500SHai-May.Chao@Sun.COM cryptodebug("CRYPTO_FIPS140_DISABLE ioctl failed: %s",
73710500SHai-May.Chao@Sun.COM strerror(errno));
73810500SHai-May.Chao@Sun.COM rc = FAILURE;
73910500SHai-May.Chao@Sun.COM goto out;
74010500SHai-May.Chao@Sun.COM }
74110500SHai-May.Chao@Sun.COM
74210500SHai-May.Chao@Sun.COM if (fips_info.fips140_return_value != CRYPTO_SUCCESS) {
74310500SHai-May.Chao@Sun.COM cryptodebug("CRYPTO_FIPS140_DISABLE ioctl failed, "
74410500SHai-May.Chao@Sun.COM "return_value = %d",
74510500SHai-May.Chao@Sun.COM fips_info.fips140_return_value);
74610500SHai-May.Chao@Sun.COM rc = FAILURE;
74710500SHai-May.Chao@Sun.COM }
74810500SHai-May.Chao@Sun.COM
74910500SHai-May.Chao@Sun.COM break;
75010500SHai-May.Chao@Sun.COM
75110500SHai-May.Chao@Sun.COM default:
75210500SHai-May.Chao@Sun.COM rc = FAILURE;
75310500SHai-May.Chao@Sun.COM break;
75410500SHai-May.Chao@Sun.COM };
75510500SHai-May.Chao@Sun.COM
75610500SHai-May.Chao@Sun.COM out:
75710500SHai-May.Chao@Sun.COM (void) close(fd);
75810500SHai-May.Chao@Sun.COM return (rc);
75910500SHai-May.Chao@Sun.COM }
760