adm_kef_ioctl.c revision 1b22764f59e3a183ca5db98b6bfd27fdf2b20e02
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER START
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * The contents of this file are subject to the terms of the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Common Development and Distribution License (the "License").
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You may not use this file except in compliance with the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * or http://www.opensolaris.org/os/licensing.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * See the License for the specific language governing permissions
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * and limitations under the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * When distributing Covered Code, include this CDDL HEADER in each
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If applicable, add the following below this CDDL HEADER, with the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * fields enclosed by brackets "[]" replaced with your own identifying
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * information: Portions Copyright [yyyy] [name of copyright owner]
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER END
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Use is subject to license terms.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <fcntl.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <stdio.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <stdlib.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <strings.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <unistd.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <locale.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <libgen.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <sys/types.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <zone.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/crypto/ioctladmin.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include "cryptoadm.h"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define DEFAULT_DEV_NUM 5
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define DEFAULT_SOFT_NUM 10
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic crypto_get_soft_info_t *setup_get_soft_info(char *, int);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Prepare the argument for the LOAD_SOFT_CONFIG ioctl call for the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * provider pointed by pent. Return NULL if out of memory.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicrypto_load_soft_config_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindisetup_soft_conf(entry_t *pent)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi crypto_load_soft_config_t *pload_soft_conf;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mechlist_t *plist;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t sup_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi size_t extra_mech_size = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (pent == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi sup_count = pent->sup_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (sup_count > 1) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size = sizeof (crypto_mech_name_t) *
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (sup_count - 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi pload_soft_conf = malloc(sizeof (crypto_load_soft_config_t) +
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (pload_soft_conf == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cryptodebug("out of memory.");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) strlcpy(pload_soft_conf->sc_name, pent->name, MAXNAMELEN);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi pload_soft_conf->sc_count = sup_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi i = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi plist = pent->suplist;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi while (i < sup_count) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) strlcpy(pload_soft_conf->sc_list[i++],
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi plist->name, CRYPTO_MAX_MECH_NAME);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi plist = plist->next;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (pload_soft_conf);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi/*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * Prepare the argument for the LOAD_SOFT_DISABLED ioctl call for the
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * provider pointed by pent. Return NULL if out of memory.
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindicrypto_load_soft_disabled_t *
0eb822a1c0c2bea495647510b75f77f0e57633ebcindisetup_soft_dis(entry_t *pent)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi crypto_load_soft_disabled_t *pload_soft_dis = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mechlist_t *plist = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi size_t extra_mech_size = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t dis_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (pent == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi dis_count = pent->dis_count;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (dis_count > 1) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi extra_mech_size = sizeof (crypto_mech_name_t) *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (dis_count - 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi pload_soft_dis = malloc(sizeof (crypto_load_soft_disabled_t) +
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (pload_soft_dis == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cryptodebug("out of memory.");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) strlcpy(pload_soft_dis->sd_name, pent->name, MAXNAMELEN);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi pload_soft_dis->sd_count = dis_count;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi i = 0;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi plist = pent->dislist;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while (i < dis_count) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) strlcpy(pload_soft_dis->sd_list[i++],
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi plist->name, CRYPTO_MAX_MECH_NAME);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi plist = plist->next;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (pload_soft_dis);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Prepare the argument for the LOAD_DEV_DISABLED ioctl call for the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * provider pointed by pent. Return NULL if out of memory.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicrypto_load_dev_disabled_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindisetup_dev_dis(entry_t *pent)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi crypto_load_dev_disabled_t *pload_dev_dis = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mechlist_t *plist = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi size_t extra_mech_size = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t dis_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char pname[MAXNAMELEN];
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int inst_num;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (pent == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* get the device name and the instance number */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (split_hw_provname(pent->name, pname, &inst_num) == FAILURE) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* allocate space for pload_dev_des */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi dis_count = pent->dis_count;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (dis_count > 1) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size = sizeof (crypto_mech_name_t) *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (dis_count - 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi pload_dev_dis = malloc(sizeof (crypto_load_dev_disabled_t) +
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (pload_dev_dis == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi cryptodebug("out of memory.");
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi /* set the values for pload_dev_dis */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) strlcpy(pload_dev_dis->dd_dev_name, pname, MAXNAMELEN);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi pload_dev_dis->dd_dev_instance = inst_num;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi pload_dev_dis->dd_count = dis_count;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi i = 0;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi plist = pent->dislist;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while (i < dis_count) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) strlcpy(pload_dev_dis->dd_list[i++],
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi plist->name, CRYPTO_MAX_MECH_NAME);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi plist = plist->next;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (pload_dev_dis);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Prepare the calling argument of the UNLOAD_SOFT_MODULE ioctl call for the
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * provider pointed by pent. Return NULL if out of memory.
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindicrypto_unload_soft_module_t *
0eb822a1c0c2bea495647510b75f77f0e57633ebcindisetup_unload_soft(entry_t *pent)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi crypto_unload_soft_module_t *punload_soft;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (pent == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi punload_soft = malloc(sizeof (crypto_unload_soft_module_t));
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (punload_soft == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cryptodebug("out of memory.");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) strlcpy(punload_soft->sm_name, pent->name, MAXNAMELEN);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (punload_soft);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Prepare the calling argument for the GET_SOFT_INFO call for the provider
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * with the number of mechanisms specified in the second argument.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Called by get_soft_info().
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic crypto_get_soft_info_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindisetup_get_soft_info(char *provname, int count)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi crypto_get_soft_info_t *psoft_info;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi size_t extra_mech_size = 0;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (provname == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (count > 1) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi extra_mech_size = sizeof (crypto_mech_name_t) * (count - 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi psoft_info = malloc(sizeof (crypto_get_soft_info_t) + extra_mech_size);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (psoft_info == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi cryptodebug("out of memory.");
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) strlcpy(psoft_info->si_name, provname, MAXNAMELEN);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi psoft_info->si_count = count;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (psoft_info);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi}
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi/*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * Get the device list from kernel.
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindiint
0eb822a1c0c2bea495647510b75f77f0e57633ebcindiget_dev_list(crypto_get_dev_list_t **ppdevlist)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi crypto_get_dev_list_t *pdevlist;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int fd = -1;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int count = DEFAULT_DEV_NUM;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi sizeof (crypto_dev_list_entry_t) * (count - 1));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (pdevlist == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cryptodebug("out of memory.");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (FAILURE);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ADMIN_IOCTL_DEVICE, strerror(errno));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (FAILURE);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
pdevlist->dl_dev_count = count;
if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
strerror(errno));
free(pdevlist);
(void) close(fd);
return (FAILURE);
}
/* BUFFER is too small, get the number of devices and retry it. */
if (pdevlist->dl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
count = pdevlist->dl_dev_count;
free(pdevlist);
pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
sizeof (crypto_dev_list_entry_t) * (count - 1));
if (pdevlist == NULL) {
cryptodebug("out of memory.");
(void) close(fd);
return (FAILURE);
}
if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
strerror(errno));
free(pdevlist);
(void) close(fd);
return (FAILURE);
}
}
if (pdevlist->dl_return_value != CRYPTO_SUCCESS) {
cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed, "
"return_value = %d", pdevlist->dl_return_value);
free(pdevlist);
(void) close(fd);
return (FAILURE);
}
*ppdevlist = pdevlist;
(void) close(fd);
return (SUCCESS);
}
/*
* Get all the mechanisms supported by the hardware provider.
* The result will be stored in the second argument.
*/
int
get_dev_info(char *devname, int inst_num, int count, mechlist_t **ppmechlist)
{
crypto_get_dev_info_t *dev_info;
mechlist_t *phead;
mechlist_t *pcur;
mechlist_t *pmech;
int fd = -1;
int i;
int rc;
if (devname == NULL || count < 1) {
cryptodebug("get_dev_info(): devname is NULL or bogus count");
return (FAILURE);
}
/* Set up the argument for the CRYPTO_GET_DEV_INFO ioctl call */
dev_info = malloc(sizeof (crypto_get_dev_info_t) +
sizeof (crypto_mech_name_t) * (count - 1));
if (dev_info == NULL) {
cryptodebug("out of memory.");
return (FAILURE);
}
(void) strlcpy(dev_info->di_dev_name, devname, MAXNAMELEN);
dev_info->di_dev_instance = inst_num;
dev_info->di_count = count;
/* Open the ioctl device */
if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
ADMIN_IOCTL_DEVICE, strerror(errno));
free(dev_info);
return (FAILURE);
}
if (ioctl(fd, CRYPTO_GET_DEV_INFO, dev_info) == -1) {
cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed: %s",
strerror(errno));
free(dev_info);
(void) close(fd);
return (FAILURE);
}
if (dev_info->di_return_value != CRYPTO_SUCCESS) {
cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed, "
"return_value = %d", dev_info->di_return_value);
free(dev_info);
(void) close(fd);
return (FAILURE);
}
phead = pcur = NULL;
rc = SUCCESS;
for (i = 0; i < dev_info->di_count; i++) {
pmech = create_mech(&dev_info->di_list[i][0]);
if (pmech == NULL) {
rc = FAILURE;
break;
} else {
if (phead == NULL) {
phead = pcur = pmech;
} else {
pcur->next = pmech;
pcur = pmech;
}
}
}
if (rc == SUCCESS) {
*ppmechlist = phead;
} else {
free_mechlist(phead);
}
free(dev_info);
(void) close(fd);
return (rc);
}
/*
* Get the supported mechanism list of the software provider from kernel.
*
* Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
* If NULL, this function calls get_kcfconf_info() internally.
*/
int
get_soft_info(char *provname, mechlist_t **ppmechlist,
entrylist_t *phardlist, entrylist_t *psoftlist)
{
boolean_t in_kernel = B_FALSE;
crypto_get_soft_info_t *psoft_info;
mechlist_t *phead;
mechlist_t *pmech;
mechlist_t *pcur;
entry_t *pent = NULL;
int count;
int fd = -1;
int rc;
int i;
if (provname == NULL) {
return (FAILURE);
}
if (getzoneid() == GLOBAL_ZONEID) {
/* use kcf.conf for kernel software providers in global zone */
if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
NULL) {
/* No kcf.conf entry for this provider */
if (check_kernel_for_soft(provname, NULL, &in_kernel)
== FAILURE) {
return (FAILURE);
} else if (in_kernel == B_FALSE) {
cryptoerror(LOG_STDERR,
gettext("%s does not exist."), provname);
return (FAILURE);
}
/*
* Set mech count to 1. It will be reset to the
* correct value later if the setup buffer is too small.
*/
count = 1;
} else {
count = pent->sup_count;
free_entry(pent);
}
} else {
/*
* kcf.conf not there in non-global zone: set mech count to 1.
* It will be reset to the correct value later if the setup
* buffer is too small.
*/
count = 1;
}
if ((psoft_info = setup_get_soft_info(provname, count)) == NULL) {
return (FAILURE);
}
if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
ADMIN_IOCTL_DEVICE, strerror(errno));
free(psoft_info);
return (FAILURE);
}
/* make GET_SOFT_INFO ioctl call */
if ((rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info)) == -1) {
cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed: %s",
strerror(errno));
(void) close(fd);
free(psoft_info);
return (FAILURE);
}
/* BUFFER is too small, get the number of mechanisms and retry it. */
if (psoft_info->si_return_value == CRYPTO_BUFFER_TOO_SMALL) {
count = psoft_info->si_count;
free(psoft_info);
if ((psoft_info = setup_get_soft_info(provname, count))
== NULL) {
(void) close(fd);
return (FAILURE);
} else {
rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info);
if (rc == -1) {
cryptodebug("CRYPTO_GET_SOFT_INFO ioctl "
"failed: %s", strerror(errno));
(void) close(fd);
free(psoft_info);
return (FAILURE);
}
}
}
(void) close(fd);
if (psoft_info->si_return_value != CRYPTO_SUCCESS) {
cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed, "
"return_value = %d", psoft_info->si_return_value);
free(psoft_info);
return (FAILURE);
}
/* Build the mechanism linked list and return it */
rc = SUCCESS;
phead = pcur = NULL;
for (i = 0; i < psoft_info->si_count; i++) {
pmech = create_mech(&psoft_info->si_list[i][0]);
if (pmech == NULL) {
rc = FAILURE;
break;
} else {
if (phead == NULL) {
phead = pcur = pmech;
} else {
pcur->next = pmech;
pcur = pmech;
}
}
}
if (rc == FAILURE) {
free_mechlist(phead);
} else {
*ppmechlist = phead;
}
free(psoft_info);
return (rc);
}
/*
* Get the kernel software provider list from kernel.
*/
int
get_soft_list(crypto_get_soft_list_t **ppsoftlist)
{
crypto_get_soft_list_t *psoftlist = NULL;
int count = DEFAULT_SOFT_NUM;
int len;
int fd = -1;
if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
ADMIN_IOCTL_DEVICE, strerror(errno));
return (FAILURE);
}
len = MAXNAMELEN * count;
psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
if (psoftlist == NULL) {
cryptodebug("out of memory.");
(void) close(fd);
return (FAILURE);
}
psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
psoftlist->sl_soft_count = count;
psoftlist->sl_soft_len = len;
if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed: %s",
strerror(errno));
free(psoftlist);
(void) close(fd);
return (FAILURE);
}
/*
* if BUFFER is too small, get the number of software providers and
* the minimum length needed for names and length and retry it.
*/
if (psoftlist->sl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
count = psoftlist->sl_soft_count;
len = psoftlist->sl_soft_len;
free(psoftlist);
psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
if (psoftlist == NULL) {
cryptodebug("out of memory.");
(void) close(fd);
return (FAILURE);
}
psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
psoftlist->sl_soft_count = count;
psoftlist->sl_soft_len = len;
if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed:"
"%s", strerror(errno));
free(psoftlist);
(void) close(fd);
return (FAILURE);
}
}
if (psoftlist->sl_return_value != CRYPTO_SUCCESS) {
cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed, "
"return_value = %d", psoftlist->sl_return_value);
free(psoftlist);
(void) close(fd);
return (FAILURE);
}
*ppsoftlist = psoftlist;
(void) close(fd);
return (SUCCESS);
}