17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5b8bf75cbSkrishna * Common Development and Distribution License (the "License"). 6b8bf75cbSkrishna * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22b5a2d845SHai-May Chao * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <fcntl.h> 277c478bd9Sstevel@tonic-gate #include <stdio.h> 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <strings.h> 307c478bd9Sstevel@tonic-gate #include <unistd.h> 317c478bd9Sstevel@tonic-gate #include <locale.h> 327c478bd9Sstevel@tonic-gate #include <libgen.h> 337c478bd9Sstevel@tonic-gate #include <sys/types.h> 347c478bd9Sstevel@tonic-gate #include <sys/stat.h> 357c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h> 367c478bd9Sstevel@tonic-gate #include <signal.h> 377c478bd9Sstevel@tonic-gate #include <sys/crypto/elfsign.h> 387c478bd9Sstevel@tonic-gate #include "cryptoadm.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate static int check_hardware_provider(char *, char *, int *, int *); 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * Display the mechanism list for a kernel software provider. 441b22764fSDaniel OpenSolaris Anderson * This implements part of the "cryptoadm list -m" command. 451b22764fSDaniel OpenSolaris Anderson * 46*d616ad8eSHai-May Chao * Parameters phardlist and psoftlist are supplied by 47b5a2d845SHai-May Chao * get_soft_info(). 48b5a2d845SHai-May Chao * If NULL, this function obtains it by calling getent_kef() and 49b5a2d845SHai-May Chao * then get_kcfconf_info() via get_soft_info() internally. 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate int 521b22764fSDaniel OpenSolaris Anderson list_mechlist_for_soft(char *provname, 53*d616ad8eSHai-May Chao entrylist_t *phardlist, entrylist_t *psoftlist) 547c478bd9Sstevel@tonic-gate { 551b22764fSDaniel OpenSolaris Anderson mechlist_t *pmechlist = NULL; 567c478bd9Sstevel@tonic-gate int rc; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate if (provname == NULL) { 597c478bd9Sstevel@tonic-gate return (FAILURE); 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 62*d616ad8eSHai-May Chao rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist); 637c478bd9Sstevel@tonic-gate if (rc == SUCCESS) { 647c478bd9Sstevel@tonic-gate (void) filter_mechlist(&pmechlist, RANDOM); 657c478bd9Sstevel@tonic-gate print_mechlist(provname, pmechlist); 667c478bd9Sstevel@tonic-gate free_mechlist(pmechlist); 677c478bd9Sstevel@tonic-gate } else { 687c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 697c478bd9Sstevel@tonic-gate "failed to retrieve the mechanism list for %s."), 707c478bd9Sstevel@tonic-gate provname); 717c478bd9Sstevel@tonic-gate } 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate return (rc); 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate /* 777c478bd9Sstevel@tonic-gate * Display the mechanism list for a kernel hardware provider. 781b22764fSDaniel OpenSolaris Anderson * This implements part of the "cryptoadm list -m" command. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate int 817c478bd9Sstevel@tonic-gate list_mechlist_for_hard(char *provname) 827c478bd9Sstevel@tonic-gate { 831b22764fSDaniel OpenSolaris Anderson mechlist_t *pmechlist = NULL; 847c478bd9Sstevel@tonic-gate char devname[MAXNAMELEN]; 857c478bd9Sstevel@tonic-gate int inst_num; 867c478bd9Sstevel@tonic-gate int count; 877c478bd9Sstevel@tonic-gate int rc = SUCCESS; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate if (provname == NULL) { 907c478bd9Sstevel@tonic-gate return (FAILURE); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate /* 947c478bd9Sstevel@tonic-gate * Check if the provider is valid. If it is valid, get the number of 957c478bd9Sstevel@tonic-gate * mechanisms also. 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate if (check_hardware_provider(provname, devname, &inst_num, &count) == 987c478bd9Sstevel@tonic-gate FAILURE) { 997c478bd9Sstevel@tonic-gate return (FAILURE); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* Get the mechanism list for the kernel hardware provider */ 1037c478bd9Sstevel@tonic-gate if ((rc = get_dev_info(devname, inst_num, count, &pmechlist)) == 1047c478bd9Sstevel@tonic-gate SUCCESS) { 1057c478bd9Sstevel@tonic-gate (void) filter_mechlist(&pmechlist, RANDOM); 1067c478bd9Sstevel@tonic-gate print_mechlist(provname, pmechlist); 1077c478bd9Sstevel@tonic-gate free_mechlist(pmechlist); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate return (rc); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* 1157c478bd9Sstevel@tonic-gate * Display the policy information for a kernel software provider. 1161b22764fSDaniel OpenSolaris Anderson * This implements part of the "cryptoadm list -p" command. 1171b22764fSDaniel OpenSolaris Anderson * 118*d616ad8eSHai-May Chao * Parameters phardlist and psoftlist are supplied by 119b5a2d845SHai-May Chao * getent_kef(). 120b5a2d845SHai-May Chao * If NULL, this function obtains it by calling get_kcfconf_info() 121b5a2d845SHai-May Chao * via getent_kef() internally. 1227c478bd9Sstevel@tonic-gate */ 1237c478bd9Sstevel@tonic-gate int 1241b22764fSDaniel OpenSolaris Anderson list_policy_for_soft(char *provname, 125*d616ad8eSHai-May Chao entrylist_t *phardlist, entrylist_t *psoftlist) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate int rc; 1287c478bd9Sstevel@tonic-gate entry_t *pent = NULL; 1291b22764fSDaniel OpenSolaris Anderson mechlist_t *pmechlist = NULL; 1307c478bd9Sstevel@tonic-gate boolean_t has_random = B_FALSE; 1317c478bd9Sstevel@tonic-gate boolean_t has_mechs = B_FALSE; 1321b22764fSDaniel OpenSolaris Anderson boolean_t in_kernel = B_FALSE; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate if (provname == NULL) { 1357c478bd9Sstevel@tonic-gate return (FAILURE); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1381b22764fSDaniel OpenSolaris Anderson if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) { 1391b22764fSDaniel OpenSolaris Anderson return (FAILURE); 1401b22764fSDaniel OpenSolaris Anderson } else if (in_kernel == B_FALSE) { 1417c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("%s does not exist."), 1427c478bd9Sstevel@tonic-gate provname); 1437c478bd9Sstevel@tonic-gate return (FAILURE); 1447c478bd9Sstevel@tonic-gate } 145*d616ad8eSHai-May Chao pent = getent_kef(provname, phardlist, psoftlist); 1467c478bd9Sstevel@tonic-gate 147*d616ad8eSHai-May Chao rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist); 1487c478bd9Sstevel@tonic-gate if (rc == SUCCESS) { 1497c478bd9Sstevel@tonic-gate has_random = filter_mechlist(&pmechlist, RANDOM); 1507c478bd9Sstevel@tonic-gate if (pmechlist != NULL) { 1517c478bd9Sstevel@tonic-gate has_mechs = B_TRUE; 1527c478bd9Sstevel@tonic-gate free_mechlist(pmechlist); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate } else { 1557c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 1567c478bd9Sstevel@tonic-gate "failed to retrieve the mechanism list for %s."), 1577c478bd9Sstevel@tonic-gate provname); 1587c478bd9Sstevel@tonic-gate return (rc); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1611b22764fSDaniel OpenSolaris Anderson print_kef_policy(provname, pent, has_random, has_mechs); 1627c478bd9Sstevel@tonic-gate free_entry(pent); 1637c478bd9Sstevel@tonic-gate return (SUCCESS); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate /* 1697c478bd9Sstevel@tonic-gate * Display the policy information for a kernel hardware provider. 1701b22764fSDaniel OpenSolaris Anderson * This implements part of the "cryptoadm list -p" command. 1711b22764fSDaniel OpenSolaris Anderson * 172*d616ad8eSHai-May Chao * Parameters phardlist and psoftlist are supplied by getent_kef(). 173b5a2d845SHai-May Chao * If NULL, this function obtains it by calling get_kcfconf_info() via 174b5a2d845SHai-May Chao * getent_kef() internally. 175b5a2d845SHai-May Chao * Parameter pdevlist is supplied by check_kernel_for_hard(). 176b5a2d845SHai-May Chao * If NULL, this function obtains it by calling get_dev_list() via 177b5a2d845SHai-May Chao * check_kernel_for_hard() internally. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate int 1801b22764fSDaniel OpenSolaris Anderson list_policy_for_hard(char *provname, 1811b22764fSDaniel OpenSolaris Anderson entrylist_t *phardlist, entrylist_t *psoftlist, 182*d616ad8eSHai-May Chao crypto_get_dev_list_t *pdevlist) 1837c478bd9Sstevel@tonic-gate { 1841b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 1851b22764fSDaniel OpenSolaris Anderson boolean_t in_kernel; 1861b22764fSDaniel OpenSolaris Anderson mechlist_t *pmechlist = NULL; 1877c478bd9Sstevel@tonic-gate char devname[MAXNAMELEN]; 1887c478bd9Sstevel@tonic-gate int inst_num; 1897c478bd9Sstevel@tonic-gate int count; 1907c478bd9Sstevel@tonic-gate int rc = SUCCESS; 1917c478bd9Sstevel@tonic-gate boolean_t has_random = B_FALSE; 1927c478bd9Sstevel@tonic-gate boolean_t has_mechs = B_FALSE; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if (provname == NULL) { 1957c478bd9Sstevel@tonic-gate return (FAILURE); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * Check if the provider is valid. If it is valid, get the number of 2007c478bd9Sstevel@tonic-gate * mechanisms also. 2017c478bd9Sstevel@tonic-gate */ 2027c478bd9Sstevel@tonic-gate if (check_hardware_provider(provname, devname, &inst_num, &count) == 2037c478bd9Sstevel@tonic-gate FAILURE) { 2047c478bd9Sstevel@tonic-gate return (FAILURE); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* Get the mechanism list for the kernel hardware provider */ 2087c478bd9Sstevel@tonic-gate if ((rc = get_dev_info(devname, inst_num, count, &pmechlist)) == 2097c478bd9Sstevel@tonic-gate SUCCESS) { 2107c478bd9Sstevel@tonic-gate has_random = filter_mechlist(&pmechlist, RANDOM); 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate if (pmechlist != NULL) { 2137c478bd9Sstevel@tonic-gate has_mechs = B_TRUE; 2147c478bd9Sstevel@tonic-gate free_mechlist(pmechlist); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate } else { 2177c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 2187c478bd9Sstevel@tonic-gate "failed to retrieve the mechanism list for %s."), 2197c478bd9Sstevel@tonic-gate devname); 2207c478bd9Sstevel@tonic-gate return (rc); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * If the hardware provider has an entry in the kcf.conf file, 2257c478bd9Sstevel@tonic-gate * some of its mechanisms must have been disabled. Print out 2267c478bd9Sstevel@tonic-gate * the disabled list from the config file entry. Otherwise, 2277c478bd9Sstevel@tonic-gate * if it is active, then all the mechanisms for it are enabled. 2287c478bd9Sstevel@tonic-gate */ 229*d616ad8eSHai-May Chao if ((pent = getent_kef(provname, phardlist, psoftlist)) != NULL) { 2301b22764fSDaniel OpenSolaris Anderson print_kef_policy(provname, pent, has_random, has_mechs); 2317c478bd9Sstevel@tonic-gate free_entry(pent); 2327c478bd9Sstevel@tonic-gate return (SUCCESS); 2337c478bd9Sstevel@tonic-gate } else { 2341b22764fSDaniel OpenSolaris Anderson if (check_kernel_for_hard(provname, pdevlist, 2351b22764fSDaniel OpenSolaris Anderson &in_kernel) == FAILURE) { 2367c478bd9Sstevel@tonic-gate return (FAILURE); 2371b22764fSDaniel OpenSolaris Anderson } else if (in_kernel == B_TRUE) { 2387c478bd9Sstevel@tonic-gate (void) printf(gettext( 2397c478bd9Sstevel@tonic-gate "%s: all mechanisms are enabled."), provname); 2407c478bd9Sstevel@tonic-gate if (has_random) 2417c478bd9Sstevel@tonic-gate /* 2420a85b835SDaniel Anderson * TRANSLATION_NOTE 2437c478bd9Sstevel@tonic-gate * "random" is a keyword and not to be 2447c478bd9Sstevel@tonic-gate * translated. 2457c478bd9Sstevel@tonic-gate */ 2467c478bd9Sstevel@tonic-gate (void) printf(gettext(" %s is enabled.\n"), 2477c478bd9Sstevel@tonic-gate "random"); 2487c478bd9Sstevel@tonic-gate else 2497c478bd9Sstevel@tonic-gate (void) printf("\n"); 2507c478bd9Sstevel@tonic-gate return (SUCCESS); 2517c478bd9Sstevel@tonic-gate } else { 2527c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 2537c478bd9Sstevel@tonic-gate gettext("%s does not exist."), provname); 2547c478bd9Sstevel@tonic-gate return (FAILURE); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate 2601b22764fSDaniel OpenSolaris Anderson /* 2611b22764fSDaniel OpenSolaris Anderson * Disable a kernel hardware provider. 2621b22764fSDaniel OpenSolaris Anderson * This implements the "cryptoadm disable" command for 2631b22764fSDaniel OpenSolaris Anderson * kernel hardware providers. 2641b22764fSDaniel OpenSolaris Anderson */ 2657c478bd9Sstevel@tonic-gate int 2667c478bd9Sstevel@tonic-gate disable_kef_hardware(char *provname, boolean_t rndflag, boolean_t allflag, 2677c478bd9Sstevel@tonic-gate mechlist_t *dislist) 2687c478bd9Sstevel@tonic-gate { 2691b22764fSDaniel OpenSolaris Anderson crypto_load_dev_disabled_t *pload_dev_dis = NULL; 2701b22764fSDaniel OpenSolaris Anderson mechlist_t *infolist = NULL; 2711b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 2727c478bd9Sstevel@tonic-gate boolean_t new_dev_entry = B_FALSE; 2737c478bd9Sstevel@tonic-gate char devname[MAXNAMELEN]; 2747c478bd9Sstevel@tonic-gate int inst_num; 2757c478bd9Sstevel@tonic-gate int count; 2761b22764fSDaniel OpenSolaris Anderson int fd = -1; 2777c478bd9Sstevel@tonic-gate int rc = SUCCESS; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate if (provname == NULL) { 2807c478bd9Sstevel@tonic-gate return (FAILURE); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * Check if the provider is valid. If it is valid, get the number of 2857c478bd9Sstevel@tonic-gate * mechanisms also. 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate if (check_hardware_provider(provname, devname, &inst_num, &count) 2887c478bd9Sstevel@tonic-gate == FAILURE) { 2897c478bd9Sstevel@tonic-gate return (FAILURE); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate /* Get the mechanism list for the kernel hardware provider */ 2937c478bd9Sstevel@tonic-gate if (get_dev_info(devname, inst_num, count, &infolist) == FAILURE) { 2947c478bd9Sstevel@tonic-gate return (FAILURE); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * Get the entry of this hardware provider from the config file. 2997c478bd9Sstevel@tonic-gate * If there is no entry yet, create one for it. 3007c478bd9Sstevel@tonic-gate */ 301*d616ad8eSHai-May Chao if ((pent = getent_kef(provname, NULL, NULL)) == NULL) { 3021b22764fSDaniel OpenSolaris Anderson if ((pent = create_entry(provname)) == NULL) { 3037c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("out of memory.")); 3047c478bd9Sstevel@tonic-gate free_mechlist(infolist); 3057c478bd9Sstevel@tonic-gate return (FAILURE); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate new_dev_entry = B_TRUE; 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * kCF treats random as an internal mechanism. So, we need to 3127c478bd9Sstevel@tonic-gate * filter it from the mechanism list here, if we are NOT disabling 3137c478bd9Sstevel@tonic-gate * or enabling the random feature. Note that we map random feature at 3147c478bd9Sstevel@tonic-gate * cryptoadm(1M) level to the "random" mechanism in kCF. 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate if (!rndflag) { 317407eb7ccSmcpowers (void) filter_mechlist(&dislist, RANDOM); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* Calculate the new disabled list */ 3217c478bd9Sstevel@tonic-gate if (disable_mechs(&pent, infolist, allflag, dislist) == FAILURE) { 322407eb7ccSmcpowers free_mechlist(infolist); 3237c478bd9Sstevel@tonic-gate free_entry(pent); 3247c478bd9Sstevel@tonic-gate return (FAILURE); 3257c478bd9Sstevel@tonic-gate } 326407eb7ccSmcpowers free_mechlist(infolist); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* If no mechanisms are to be disabled, return */ 3297c478bd9Sstevel@tonic-gate if (pent->dis_count == 0) { 3307c478bd9Sstevel@tonic-gate free_entry(pent); 3317c478bd9Sstevel@tonic-gate return (SUCCESS); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate /* Update the config file with the new entry or the updated entry */ 3357c478bd9Sstevel@tonic-gate if (new_dev_entry) { 3367c478bd9Sstevel@tonic-gate rc = update_kcfconf(pent, ADD_MODE); 3377c478bd9Sstevel@tonic-gate } else { 3387c478bd9Sstevel@tonic-gate rc = update_kcfconf(pent, MODIFY_MODE); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate if (rc == FAILURE) { 3427c478bd9Sstevel@tonic-gate free_entry(pent); 3437c478bd9Sstevel@tonic-gate return (FAILURE); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate /* Inform kernel about the new disabled mechanism list */ 3477c478bd9Sstevel@tonic-gate if ((pload_dev_dis = setup_dev_dis(pent)) == NULL) { 3487c478bd9Sstevel@tonic-gate free_entry(pent); 3497c478bd9Sstevel@tonic-gate return (FAILURE); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate free_entry(pent); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 3547c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 3557c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno)); 3567c478bd9Sstevel@tonic-gate free(pload_dev_dis); 3577c478bd9Sstevel@tonic-gate return (FAILURE); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis) == -1) { 3617c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl failed: %s", 3627c478bd9Sstevel@tonic-gate strerror(errno)); 3637c478bd9Sstevel@tonic-gate free(pload_dev_dis); 3647c478bd9Sstevel@tonic-gate (void) close(fd); 3657c478bd9Sstevel@tonic-gate return (FAILURE); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) { 3697c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl return_value = " 3707c478bd9Sstevel@tonic-gate "%d", pload_dev_dis->dd_return_value); 3717c478bd9Sstevel@tonic-gate free(pload_dev_dis); 3727c478bd9Sstevel@tonic-gate (void) close(fd); 3737c478bd9Sstevel@tonic-gate return (FAILURE); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate free(pload_dev_dis); 3777c478bd9Sstevel@tonic-gate (void) close(fd); 3787c478bd9Sstevel@tonic-gate return (SUCCESS); 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate 3821b22764fSDaniel OpenSolaris Anderson /* 3831b22764fSDaniel OpenSolaris Anderson * Disable a kernel software provider. 3841b22764fSDaniel OpenSolaris Anderson * This implements the "cryptoadm disable" command for 3851b22764fSDaniel OpenSolaris Anderson * kernel software providers. 3861b22764fSDaniel OpenSolaris Anderson */ 3877c478bd9Sstevel@tonic-gate int 3887c478bd9Sstevel@tonic-gate disable_kef_software(char *provname, boolean_t rndflag, boolean_t allflag, 3897c478bd9Sstevel@tonic-gate mechlist_t *dislist) 3907c478bd9Sstevel@tonic-gate { 3917c478bd9Sstevel@tonic-gate crypto_load_soft_disabled_t *pload_soft_dis = NULL; 3921b22764fSDaniel OpenSolaris Anderson mechlist_t *infolist = NULL; 3931b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 3941b22764fSDaniel OpenSolaris Anderson entrylist_t *phardlist = NULL; 3951b22764fSDaniel OpenSolaris Anderson entrylist_t *psoftlist = NULL; 3961b22764fSDaniel OpenSolaris Anderson boolean_t in_kernel = B_FALSE; 3971b22764fSDaniel OpenSolaris Anderson int fd = -1; 3981b22764fSDaniel OpenSolaris Anderson int rc = SUCCESS; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate if (provname == NULL) { 4017c478bd9Sstevel@tonic-gate return (FAILURE); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * Check if the kernel software provider is currently unloaded. 4067c478bd9Sstevel@tonic-gate * If it is unloaded, return FAILURE, because the disable subcommand 4077c478bd9Sstevel@tonic-gate * can not perform on inactive (unloaded) providers. 4087c478bd9Sstevel@tonic-gate */ 409*d616ad8eSHai-May Chao if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) { 4107c478bd9Sstevel@tonic-gate return (FAILURE); 4111b22764fSDaniel OpenSolaris Anderson } else if (in_kernel == B_FALSE) { 4127c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 4131b22764fSDaniel OpenSolaris Anderson gettext("%s is not loaded or does not exist."), 4141b22764fSDaniel OpenSolaris Anderson provname); 4157c478bd9Sstevel@tonic-gate return (FAILURE); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 418*d616ad8eSHai-May Chao if (get_kcfconf_info(&phardlist, &psoftlist) == FAILURE) { 4191b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_ERR, 4201b22764fSDaniel OpenSolaris Anderson "failed to retrieve the providers' " 4211b22764fSDaniel OpenSolaris Anderson "information from the configuration file - %s.", 4221b22764fSDaniel OpenSolaris Anderson _PATH_KCF_CONF); 4237c478bd9Sstevel@tonic-gate return (FAILURE); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4261b22764fSDaniel OpenSolaris Anderson /* 4271b22764fSDaniel OpenSolaris Anderson * Get the entry of this provider from the kcf.conf file, if any. 4281b22764fSDaniel OpenSolaris Anderson * Otherwise, create a new kcf.conf entry for writing back to the file. 4291b22764fSDaniel OpenSolaris Anderson */ 430*d616ad8eSHai-May Chao pent = getent_kef(provname, phardlist, psoftlist); 4311b22764fSDaniel OpenSolaris Anderson if (pent == NULL) { /* create a new entry */ 4321b22764fSDaniel OpenSolaris Anderson pent = create_entry(provname); 4331b22764fSDaniel OpenSolaris Anderson if (pent == NULL) { 4341b22764fSDaniel OpenSolaris Anderson cryptodebug("out of memory."); 4351b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4361b22764fSDaniel OpenSolaris Anderson goto out; 4371b22764fSDaniel OpenSolaris Anderson } 4381b22764fSDaniel OpenSolaris Anderson } 4391b22764fSDaniel OpenSolaris Anderson 4401b22764fSDaniel OpenSolaris Anderson /* Get the mechanism list for the software provider from the kernel */ 441*d616ad8eSHai-May Chao if (get_soft_info(provname, &infolist, phardlist, psoftlist) == 442*d616ad8eSHai-May Chao FAILURE) { 4431b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4441b22764fSDaniel OpenSolaris Anderson goto out; 4451b22764fSDaniel OpenSolaris Anderson } 4461b22764fSDaniel OpenSolaris Anderson 4471b22764fSDaniel OpenSolaris Anderson if ((infolist != NULL) && (infolist->name[0] != '\0')) { 4481b22764fSDaniel OpenSolaris Anderson /* 4491b22764fSDaniel OpenSolaris Anderson * Replace the supportedlist from kcf.conf with possibly 4501b22764fSDaniel OpenSolaris Anderson * more-up-to-date list from the kernel. This is the case 4511b22764fSDaniel OpenSolaris Anderson * for default software providers that had more mechanisms 4521b22764fSDaniel OpenSolaris Anderson * added in the current version of the kernel. 4531b22764fSDaniel OpenSolaris Anderson */ 4541b22764fSDaniel OpenSolaris Anderson free_mechlist(pent->suplist); 4551b22764fSDaniel OpenSolaris Anderson pent->suplist = infolist; 4561b22764fSDaniel OpenSolaris Anderson } 4571b22764fSDaniel OpenSolaris Anderson 4581b22764fSDaniel OpenSolaris Anderson /* 4591b22764fSDaniel OpenSolaris Anderson * kCF treats random as an internal mechanism. So, we need to 4601b22764fSDaniel OpenSolaris Anderson * filter it from the mechanism list here, if we are NOT disabling 4611b22764fSDaniel OpenSolaris Anderson * or enabling the random feature. Note that we map random feature at 4621b22764fSDaniel OpenSolaris Anderson * cryptoadm(1M) level to the "random" mechanism in kCF. 4631b22764fSDaniel OpenSolaris Anderson */ 4647c478bd9Sstevel@tonic-gate if (!rndflag) { 4657c478bd9Sstevel@tonic-gate (void) filter_mechlist(&infolist, RANDOM); 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* Calculate the new disabled list */ 4697c478bd9Sstevel@tonic-gate if (disable_mechs(&pent, infolist, allflag, dislist) == FAILURE) { 4701b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4711b22764fSDaniel OpenSolaris Anderson goto out; 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* Update the kcf.conf file with the updated entry */ 4757c478bd9Sstevel@tonic-gate if (update_kcfconf(pent, MODIFY_MODE) == FAILURE) { 4761b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4771b22764fSDaniel OpenSolaris Anderson goto out; 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4801b22764fSDaniel OpenSolaris Anderson /* Setup argument to inform kernel about the new disabled list. */ 4817c478bd9Sstevel@tonic-gate if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) { 4821b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4831b22764fSDaniel OpenSolaris Anderson goto out; 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 4877c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 4887c478bd9Sstevel@tonic-gate gettext("failed to open %s for RW: %s"), 4897c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno)); 4901b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4911b22764fSDaniel OpenSolaris Anderson goto out; 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4941b22764fSDaniel OpenSolaris Anderson /* Inform kernel about the new disabled list. */ 4957c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis) == -1) { 4967c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: %s", 4977c478bd9Sstevel@tonic-gate strerror(errno)); 4981b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 4991b22764fSDaniel OpenSolaris Anderson goto out; 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) { 5037c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl return_value = " 5047c478bd9Sstevel@tonic-gate "%d", pload_soft_dis->sd_return_value); 5051b22764fSDaniel OpenSolaris Anderson rc = FAILURE; 5061b22764fSDaniel OpenSolaris Anderson goto out; 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5091b22764fSDaniel OpenSolaris Anderson out: 5101b22764fSDaniel OpenSolaris Anderson free_entrylist(phardlist); 5111b22764fSDaniel OpenSolaris Anderson free_entrylist(psoftlist); 5121b22764fSDaniel OpenSolaris Anderson free_mechlist(infolist); 5131b22764fSDaniel OpenSolaris Anderson free_entry(pent); 5147c478bd9Sstevel@tonic-gate free(pload_soft_dis); 5151b22764fSDaniel OpenSolaris Anderson if (fd != -1) 5167c478bd9Sstevel@tonic-gate (void) close(fd); 5171b22764fSDaniel OpenSolaris Anderson return (rc); 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate 5211b22764fSDaniel OpenSolaris Anderson /* 5221b22764fSDaniel OpenSolaris Anderson * Enable a kernel software or hardware provider. 5231b22764fSDaniel OpenSolaris Anderson * This implements the "cryptoadm enable" command for kernel providers. 5241b22764fSDaniel OpenSolaris Anderson */ 5257c478bd9Sstevel@tonic-gate int 5267c478bd9Sstevel@tonic-gate enable_kef(char *provname, boolean_t rndflag, boolean_t allflag, 5277c478bd9Sstevel@tonic-gate mechlist_t *mlist) 5287c478bd9Sstevel@tonic-gate { 5297c478bd9Sstevel@tonic-gate crypto_load_soft_disabled_t *pload_soft_dis = NULL; 5307c478bd9Sstevel@tonic-gate crypto_load_dev_disabled_t *pload_dev_dis = NULL; 5311b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 5327c478bd9Sstevel@tonic-gate boolean_t redo_flag = B_FALSE; 5331b22764fSDaniel OpenSolaris Anderson boolean_t in_kernel = B_FALSE; 5341b22764fSDaniel OpenSolaris Anderson int fd = -1; 5357c478bd9Sstevel@tonic-gate int rc = SUCCESS; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate 5381b22764fSDaniel OpenSolaris Anderson /* Get the entry of this provider from the kcf.conf file, if any. */ 539*d616ad8eSHai-May Chao pent = getent_kef(provname, NULL, NULL); 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (is_device(provname)) { 5427c478bd9Sstevel@tonic-gate if (pent == NULL) { 5437c478bd9Sstevel@tonic-gate /* 5447c478bd9Sstevel@tonic-gate * This device doesn't have an entry in the config 5457c478bd9Sstevel@tonic-gate * file, therefore nothing is disabled. 5467c478bd9Sstevel@tonic-gate */ 5477c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 5487c478bd9Sstevel@tonic-gate "all mechanisms are enabled already for %s."), 5497c478bd9Sstevel@tonic-gate provname); 5501b22764fSDaniel OpenSolaris Anderson free_entry(pent); 5517c478bd9Sstevel@tonic-gate return (SUCCESS); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate } else { /* a software module */ 5541b22764fSDaniel OpenSolaris Anderson if (check_kernel_for_soft(provname, NULL, &in_kernel) == 5551b22764fSDaniel OpenSolaris Anderson FAILURE) { 5561b22764fSDaniel OpenSolaris Anderson free_entry(pent); 5577c478bd9Sstevel@tonic-gate return (FAILURE); 5581b22764fSDaniel OpenSolaris Anderson } else if (in_kernel == B_FALSE) { 5591b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_STDERR, gettext("%s does not exist."), 5601b22764fSDaniel OpenSolaris Anderson provname); 5611b22764fSDaniel OpenSolaris Anderson free_entry(pent); 5621b22764fSDaniel OpenSolaris Anderson return (FAILURE); 5631b22764fSDaniel OpenSolaris Anderson } else if ((pent == NULL) || (pent->dis_count == 0)) { 5647c478bd9Sstevel@tonic-gate /* nothing to be enabled. */ 5657c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 5667c478bd9Sstevel@tonic-gate "all mechanisms are enabled already for %s."), 5677c478bd9Sstevel@tonic-gate provname); 5687c478bd9Sstevel@tonic-gate free_entry(pent); 5697c478bd9Sstevel@tonic-gate return (SUCCESS); 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5731b22764fSDaniel OpenSolaris Anderson /* 5741b22764fSDaniel OpenSolaris Anderson * kCF treats random as an internal mechanism. So, we need to 5751b22764fSDaniel OpenSolaris Anderson * filter it from the mechanism list here, if we are NOT disabling 5761b22764fSDaniel OpenSolaris Anderson * or enabling the random feature. Note that we map random feature at 5771b22764fSDaniel OpenSolaris Anderson * cryptoadm(1M) level to the "random" mechanism in kCF. 5781b22764fSDaniel OpenSolaris Anderson */ 5797c478bd9Sstevel@tonic-gate if (!rndflag) { 5807c478bd9Sstevel@tonic-gate redo_flag = filter_mechlist(&pent->dislist, RANDOM); 5817c478bd9Sstevel@tonic-gate if (redo_flag) 5827c478bd9Sstevel@tonic-gate pent->dis_count--; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate /* Update the entry by enabling mechanisms for this provider */ 5867c478bd9Sstevel@tonic-gate if ((rc = enable_mechs(&pent, allflag, mlist)) != SUCCESS) { 5877c478bd9Sstevel@tonic-gate free_entry(pent); 5887c478bd9Sstevel@tonic-gate return (rc); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate if (redo_flag) { 5927c478bd9Sstevel@tonic-gate mechlist_t *tmp; 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate if ((tmp = create_mech(RANDOM)) == NULL) { 5957c478bd9Sstevel@tonic-gate free_entry(pent); 5967c478bd9Sstevel@tonic-gate return (FAILURE); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate tmp->next = pent->dislist; 5997c478bd9Sstevel@tonic-gate pent->dislist = tmp; 6007c478bd9Sstevel@tonic-gate pent->dis_count++; 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * Update the kcf.conf file with the updated entry. 6057c478bd9Sstevel@tonic-gate * For a hardware provider, if there is no more disabled mechanism, 6061b22764fSDaniel OpenSolaris Anderson * remove the entire kcf.conf entry. 6077c478bd9Sstevel@tonic-gate */ 6087c478bd9Sstevel@tonic-gate if (is_device(pent->name) && (pent->dis_count == 0)) { 6097c478bd9Sstevel@tonic-gate rc = update_kcfconf(pent, DELETE_MODE); 6107c478bd9Sstevel@tonic-gate } else { 6117c478bd9Sstevel@tonic-gate rc = update_kcfconf(pent, MODIFY_MODE); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate if (rc == FAILURE) { 6157c478bd9Sstevel@tonic-gate free_entry(pent); 6167c478bd9Sstevel@tonic-gate return (FAILURE); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate /* Inform Kernel about the policy change */ 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 6237c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 6247c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno)); 6251b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6267c478bd9Sstevel@tonic-gate return (FAILURE); 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate if (is_device(provname)) { 6307c478bd9Sstevel@tonic-gate /* LOAD_DEV_DISABLED */ 6317c478bd9Sstevel@tonic-gate if ((pload_dev_dis = setup_dev_dis(pent)) == NULL) { 6321b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6337c478bd9Sstevel@tonic-gate return (FAILURE); 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis) == -1) { 6377c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl failed: " 6387c478bd9Sstevel@tonic-gate "%s", strerror(errno)); 6391b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6407c478bd9Sstevel@tonic-gate free(pload_dev_dis); 6417c478bd9Sstevel@tonic-gate (void) close(fd); 6427c478bd9Sstevel@tonic-gate return (FAILURE); 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) { 6467c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl " 6477c478bd9Sstevel@tonic-gate "return_value = %d", 6487c478bd9Sstevel@tonic-gate pload_dev_dis->dd_return_value); 6491b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6507c478bd9Sstevel@tonic-gate free(pload_dev_dis); 6517c478bd9Sstevel@tonic-gate (void) close(fd); 6527c478bd9Sstevel@tonic-gate return (FAILURE); 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6551b22764fSDaniel OpenSolaris Anderson } else { /* a software module */ 6567c478bd9Sstevel@tonic-gate /* LOAD_SOFT_DISABLED */ 6577c478bd9Sstevel@tonic-gate if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) { 6581b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6597c478bd9Sstevel@tonic-gate return (FAILURE); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis) 6637c478bd9Sstevel@tonic-gate == -1) { 6647c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: " 6657c478bd9Sstevel@tonic-gate "%s", strerror(errno)); 6661b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6677c478bd9Sstevel@tonic-gate free(pload_soft_dis); 6687c478bd9Sstevel@tonic-gate (void) close(fd); 6697c478bd9Sstevel@tonic-gate return (FAILURE); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) { 6737c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl " 6747c478bd9Sstevel@tonic-gate "return_value = %d", 6757c478bd9Sstevel@tonic-gate pload_soft_dis->sd_return_value); 6761b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6777c478bd9Sstevel@tonic-gate free(pload_soft_dis); 6787c478bd9Sstevel@tonic-gate (void) close(fd); 6797c478bd9Sstevel@tonic-gate return (FAILURE); 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate 6831b22764fSDaniel OpenSolaris Anderson free_entry(pent); 6841b22764fSDaniel OpenSolaris Anderson free(pload_soft_dis); 6857c478bd9Sstevel@tonic-gate (void) close(fd); 6867c478bd9Sstevel@tonic-gate return (SUCCESS); 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate /* 6917c478bd9Sstevel@tonic-gate * Install a software module with the specified mechanism list into the system. 6927c478bd9Sstevel@tonic-gate * This routine adds an entry into the config file for this software module 6937c478bd9Sstevel@tonic-gate * first, then makes a CRYPTO_LOAD_SOFT_CONFIG ioctl call to inform kernel 6947c478bd9Sstevel@tonic-gate * about the new addition. 6957c478bd9Sstevel@tonic-gate */ 6967c478bd9Sstevel@tonic-gate int 6977c478bd9Sstevel@tonic-gate install_kef(char *provname, mechlist_t *mlist) 6987c478bd9Sstevel@tonic-gate { 6997c478bd9Sstevel@tonic-gate crypto_load_soft_config_t *pload_soft_conf = NULL; 7007c478bd9Sstevel@tonic-gate boolean_t found; 7011b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 7021b22764fSDaniel OpenSolaris Anderson FILE *pfile = NULL; 7031b22764fSDaniel OpenSolaris Anderson FILE *pfile_tmp = NULL; 7047c478bd9Sstevel@tonic-gate char tmpfile_name[MAXPATHLEN]; 7057c478bd9Sstevel@tonic-gate char *ptr; 7067c478bd9Sstevel@tonic-gate char *str; 7077c478bd9Sstevel@tonic-gate char *name; 7087c478bd9Sstevel@tonic-gate char buffer[BUFSIZ]; 7097c478bd9Sstevel@tonic-gate char buffer2[BUFSIZ]; 7107c478bd9Sstevel@tonic-gate int found_count; 7111b22764fSDaniel OpenSolaris Anderson int fd = -1; 7127c478bd9Sstevel@tonic-gate int rc = SUCCESS; 7131b22764fSDaniel OpenSolaris Anderson int err; 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate if ((provname == NULL) || (mlist == NULL)) { 7167c478bd9Sstevel@tonic-gate return (FAILURE); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate /* Check if the provider already exists */ 720*d616ad8eSHai-May Chao if ((pent = getent_kef(provname, NULL, NULL)) != NULL) { 7217c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("%s exists already."), 7227c478bd9Sstevel@tonic-gate provname); 7237c478bd9Sstevel@tonic-gate free_entry(pent); 7247c478bd9Sstevel@tonic-gate return (FAILURE); 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate /* Create an entry with provname and mlist. */ 7281b22764fSDaniel OpenSolaris Anderson if ((pent = create_entry(provname)) == NULL) { 7297c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("out of memory.")); 7307c478bd9Sstevel@tonic-gate return (FAILURE); 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate pent->sup_count = get_mech_count(mlist); 7337c478bd9Sstevel@tonic-gate pent->suplist = mlist; 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate /* Append an entry for this software module to the kcf.conf file. */ 7367c478bd9Sstevel@tonic-gate if ((str = ent2str(pent)) == NULL) { 7377c478bd9Sstevel@tonic-gate free_entry(pent); 7387c478bd9Sstevel@tonic-gate return (FAILURE); 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) { 7427c478bd9Sstevel@tonic-gate err = errno; 7437c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 7447c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 7457c478bd9Sstevel@tonic-gate strerror(err)); 7467c478bd9Sstevel@tonic-gate cryptodebug("failed to open %s for write.", _PATH_KCF_CONF); 7477c478bd9Sstevel@tonic-gate free_entry(pent); 7487c478bd9Sstevel@tonic-gate return (FAILURE); 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 7527c478bd9Sstevel@tonic-gate err = errno; 7537c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 7547c478bd9Sstevel@tonic-gate gettext("failed to lock the configuration - %s"), 7557c478bd9Sstevel@tonic-gate strerror(err)); 7567c478bd9Sstevel@tonic-gate free_entry(pent); 7577c478bd9Sstevel@tonic-gate (void) fclose(pfile); 7587c478bd9Sstevel@tonic-gate return (FAILURE); 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate /* 7627c478bd9Sstevel@tonic-gate * Create a temporary file in the /etc/crypto directory. 7637c478bd9Sstevel@tonic-gate */ 7647c478bd9Sstevel@tonic-gate (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name)); 7657c478bd9Sstevel@tonic-gate if (mkstemp(tmpfile_name) == -1) { 7667c478bd9Sstevel@tonic-gate err = errno; 7677c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 7687c478bd9Sstevel@tonic-gate gettext("failed to create a temporary file - %s"), 7697c478bd9Sstevel@tonic-gate strerror(err)); 7707c478bd9Sstevel@tonic-gate free_entry(pent); 7717c478bd9Sstevel@tonic-gate (void) fclose(pfile); 7727c478bd9Sstevel@tonic-gate return (FAILURE); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 7767c478bd9Sstevel@tonic-gate err = errno; 7777c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"), 7787c478bd9Sstevel@tonic-gate tmpfile_name, strerror(err)); 7797c478bd9Sstevel@tonic-gate free_entry(pent); 7807c478bd9Sstevel@tonic-gate (void) fclose(pfile); 7817c478bd9Sstevel@tonic-gate return (FAILURE); 7827c478bd9Sstevel@tonic-gate } 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate /* 7867c478bd9Sstevel@tonic-gate * Loop thru the config file. If the provider was reserved within a 7877c478bd9Sstevel@tonic-gate * package bracket, just uncomment it. Otherwise, append it at 7887c478bd9Sstevel@tonic-gate * the end. The resulting file will be saved in the temp file first. 7897c478bd9Sstevel@tonic-gate */ 7907c478bd9Sstevel@tonic-gate found_count = 0; 7917c478bd9Sstevel@tonic-gate rc = SUCCESS; 7927c478bd9Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 7937c478bd9Sstevel@tonic-gate found = B_FALSE; 7947c478bd9Sstevel@tonic-gate if (buffer[0] == '#') { 7957c478bd9Sstevel@tonic-gate (void) strlcpy(buffer2, buffer, BUFSIZ); 7967c478bd9Sstevel@tonic-gate ptr = buffer2; 7977c478bd9Sstevel@tonic-gate ptr++; 7987c478bd9Sstevel@tonic-gate if ((name = strtok(ptr, SEP_COLON)) == NULL) { 7997c478bd9Sstevel@tonic-gate rc = FAILURE; 8007c478bd9Sstevel@tonic-gate break; 8017c478bd9Sstevel@tonic-gate } else if (strcmp(provname, name) == 0) { 8027c478bd9Sstevel@tonic-gate found = B_TRUE; 8037c478bd9Sstevel@tonic-gate found_count++; 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate } 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate if (found == B_FALSE) { 8087c478bd9Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) { 8097c478bd9Sstevel@tonic-gate rc = FAILURE; 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate } else { 8127c478bd9Sstevel@tonic-gate if (found_count == 1) { 8137c478bd9Sstevel@tonic-gate if (fputs(str, pfile_tmp) == EOF) { 8147c478bd9Sstevel@tonic-gate rc = FAILURE; 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate } else { 8177c478bd9Sstevel@tonic-gate /* 8187c478bd9Sstevel@tonic-gate * Found a second entry with #libname. 8191b22764fSDaniel OpenSolaris Anderson * Should not happen. The kcf.conf file 8207c478bd9Sstevel@tonic-gate * is corrupted. Give a warning and skip 8217c478bd9Sstevel@tonic-gate * this entry. 8227c478bd9Sstevel@tonic-gate */ 8237c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 8247c478bd9Sstevel@tonic-gate "(Warning) Found an additional reserved " 8257c478bd9Sstevel@tonic-gate "entry for %s."), provname); 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate if (rc == FAILURE) { 8307c478bd9Sstevel@tonic-gate break; 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate (void) fclose(pfile); 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if (rc == FAILURE) { 8367c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("write error.")); 8377c478bd9Sstevel@tonic-gate (void) fclose(pfile_tmp); 8387c478bd9Sstevel@tonic-gate if (unlink(tmpfile_name) != 0) { 8397c478bd9Sstevel@tonic-gate err = errno; 8407c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 8417c478bd9Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), tmpfile_name, 8427c478bd9Sstevel@tonic-gate strerror(err)); 8437c478bd9Sstevel@tonic-gate } 8447c478bd9Sstevel@tonic-gate free_entry(pent); 8457c478bd9Sstevel@tonic-gate return (FAILURE); 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate if (found_count == 0) { 8497c478bd9Sstevel@tonic-gate /* 8507c478bd9Sstevel@tonic-gate * This libname was not in package before, append it to the 8517c478bd9Sstevel@tonic-gate * end of the temp file. 8527c478bd9Sstevel@tonic-gate */ 8537c478bd9Sstevel@tonic-gate if (fputs(str, pfile_tmp) == EOF) { 8547c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 8557c478bd9Sstevel@tonic-gate "failed to write to %s: %s"), tmpfile_name, 8567c478bd9Sstevel@tonic-gate strerror(errno)); 8577c478bd9Sstevel@tonic-gate (void) fclose(pfile_tmp); 8587c478bd9Sstevel@tonic-gate if (unlink(tmpfile_name) != 0) { 8597c478bd9Sstevel@tonic-gate err = errno; 8607c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 8617c478bd9Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 8627c478bd9Sstevel@tonic-gate tmpfile_name, strerror(err)); 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate free_entry(pent); 8657c478bd9Sstevel@tonic-gate return (FAILURE); 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate } 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate if (fclose(pfile_tmp) != 0) { 8707c478bd9Sstevel@tonic-gate err = errno; 8717c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8727c478bd9Sstevel@tonic-gate gettext("failed to close %s: %s"), tmpfile_name, 8737c478bd9Sstevel@tonic-gate strerror(err)); 8741b22764fSDaniel OpenSolaris Anderson free_entry(pent); 8757c478bd9Sstevel@tonic-gate return (FAILURE); 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) { 8797c478bd9Sstevel@tonic-gate err = errno; 8807c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8817c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 8827c478bd9Sstevel@tonic-gate strerror(err)); 8837c478bd9Sstevel@tonic-gate cryptodebug("failed to rename %s to %s: %s", tmpfile_name, 8847c478bd9Sstevel@tonic-gate _PATH_KCF_CONF, strerror(err)); 8857c478bd9Sstevel@tonic-gate rc = FAILURE; 8867c478bd9Sstevel@tonic-gate } else if (chmod(_PATH_KCF_CONF, 8877c478bd9Sstevel@tonic-gate S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 8887c478bd9Sstevel@tonic-gate err = errno; 8897c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8907c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 8917c478bd9Sstevel@tonic-gate strerror(err)); 8927c478bd9Sstevel@tonic-gate cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF, 8937c478bd9Sstevel@tonic-gate strerror(err)); 8947c478bd9Sstevel@tonic-gate rc = FAILURE; 8957c478bd9Sstevel@tonic-gate } else { 8967c478bd9Sstevel@tonic-gate rc = SUCCESS; 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate if (rc == FAILURE) { 9007c478bd9Sstevel@tonic-gate if (unlink(tmpfile_name) != 0) { 9017c478bd9Sstevel@tonic-gate err = errno; 9027c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 9037c478bd9Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 9047c478bd9Sstevel@tonic-gate tmpfile_name, strerror(err)); 9057c478bd9Sstevel@tonic-gate } 9061b22764fSDaniel OpenSolaris Anderson free_entry(pent); 9077c478bd9Sstevel@tonic-gate return (FAILURE); 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate /* Inform kernel of this new software module. */ 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate if ((pload_soft_conf = setup_soft_conf(pent)) == NULL) { 9147c478bd9Sstevel@tonic-gate free_entry(pent); 9157c478bd9Sstevel@tonic-gate return (FAILURE); 9167c478bd9Sstevel@tonic-gate } 9177c478bd9Sstevel@tonic-gate 9187c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 9197c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 9207c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(errno)); 9217c478bd9Sstevel@tonic-gate free_entry(pent); 9227c478bd9Sstevel@tonic-gate free(pload_soft_conf); 9237c478bd9Sstevel@tonic-gate return (FAILURE); 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, pload_soft_conf) == -1) { 9277c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s", 9287c478bd9Sstevel@tonic-gate strerror(errno)); 9297c478bd9Sstevel@tonic-gate free_entry(pent); 9307c478bd9Sstevel@tonic-gate free(pload_soft_conf); 9317c478bd9Sstevel@tonic-gate (void) close(fd); 9327c478bd9Sstevel@tonic-gate return (FAILURE); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) { 9367c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed, " 9377c478bd9Sstevel@tonic-gate "return_value = %d", pload_soft_conf->sc_return_value); 9387c478bd9Sstevel@tonic-gate free_entry(pent); 9397c478bd9Sstevel@tonic-gate free(pload_soft_conf); 9407c478bd9Sstevel@tonic-gate (void) close(fd); 9417c478bd9Sstevel@tonic-gate return (FAILURE); 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate free_entry(pent); 9457c478bd9Sstevel@tonic-gate free(pload_soft_conf); 9467c478bd9Sstevel@tonic-gate (void) close(fd); 9477c478bd9Sstevel@tonic-gate return (SUCCESS); 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate /* 9517c478bd9Sstevel@tonic-gate * Uninstall the software module. This routine first unloads the software 9527c478bd9Sstevel@tonic-gate * module with 3 ioctl calls, then deletes its entry from the config file. 9537c478bd9Sstevel@tonic-gate * Removing an entry from the config file needs to be done last to ensure 9547c478bd9Sstevel@tonic-gate * that there is still an entry if the earlier unload failed for any reason. 9557c478bd9Sstevel@tonic-gate */ 9567c478bd9Sstevel@tonic-gate int 9577c478bd9Sstevel@tonic-gate uninstall_kef(char *provname) 9587c478bd9Sstevel@tonic-gate { 9591b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL; 9607c478bd9Sstevel@tonic-gate int rc = SUCCESS; 9611b22764fSDaniel OpenSolaris Anderson boolean_t in_kernel = B_FALSE; 9621b22764fSDaniel OpenSolaris Anderson boolean_t in_kcfconf = B_FALSE; 9631b22764fSDaniel OpenSolaris Anderson int fd = -1; 9641b22764fSDaniel OpenSolaris Anderson crypto_load_soft_config_t *pload_soft_conf = NULL; 9657c478bd9Sstevel@tonic-gate 9661b22764fSDaniel OpenSolaris Anderson /* Check to see if the provider exists first. */ 9671b22764fSDaniel OpenSolaris Anderson if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) { 9681b22764fSDaniel OpenSolaris Anderson return (FAILURE); 9691b22764fSDaniel OpenSolaris Anderson } else if (in_kernel == B_FALSE) { 9701b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_STDERR, gettext("%s does not exist."), 9711b22764fSDaniel OpenSolaris Anderson provname); 9727c478bd9Sstevel@tonic-gate return (FAILURE); 9737c478bd9Sstevel@tonic-gate } 9747c478bd9Sstevel@tonic-gate 9751b22764fSDaniel OpenSolaris Anderson /* 9761b22764fSDaniel OpenSolaris Anderson * If it is loaded, unload it first. This does 2 ioctl calls: 9771b22764fSDaniel OpenSolaris Anderson * CRYPTO_UNLOAD_SOFT_MODULE and CRYPTO_LOAD_SOFT_DISABLED. 9781b22764fSDaniel OpenSolaris Anderson */ 9791b22764fSDaniel OpenSolaris Anderson if (unload_kef_soft(provname) == FAILURE) { 9801b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_STDERR, 9811b22764fSDaniel OpenSolaris Anderson gettext("failed to unload %s during uninstall.\n"), 9821b22764fSDaniel OpenSolaris Anderson provname); 9831b22764fSDaniel OpenSolaris Anderson return (FAILURE); 9841b22764fSDaniel OpenSolaris Anderson } 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate /* 9871b22764fSDaniel OpenSolaris Anderson * Inform kernel to remove the configuration of this software module. 9887c478bd9Sstevel@tonic-gate */ 9891b22764fSDaniel OpenSolaris Anderson 9901b22764fSDaniel OpenSolaris Anderson /* Setup ioctl() parameter */ 991*d616ad8eSHai-May Chao pent = getent_kef(provname, NULL, NULL); 9921b22764fSDaniel OpenSolaris Anderson if (pent != NULL) { /* in kcf.conf */ 9931b22764fSDaniel OpenSolaris Anderson in_kcfconf = B_TRUE; 9941b22764fSDaniel OpenSolaris Anderson free_mechlist(pent->suplist); 9951b22764fSDaniel OpenSolaris Anderson pent->suplist = NULL; 9961b22764fSDaniel OpenSolaris Anderson pent->sup_count = 0; 9971b22764fSDaniel OpenSolaris Anderson } else if ((pent = create_entry(provname)) == NULL) { 9981b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_STDERR, gettext("out of memory.")); 9991b22764fSDaniel OpenSolaris Anderson return (FAILURE); 10001b22764fSDaniel OpenSolaris Anderson } 10011b22764fSDaniel OpenSolaris Anderson if ((pload_soft_conf = setup_soft_conf(pent)) == NULL) { 10027c478bd9Sstevel@tonic-gate free_entry(pent); 10037c478bd9Sstevel@tonic-gate return (FAILURE); 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate 10061b22764fSDaniel OpenSolaris Anderson /* Open the /dev/cryptoadm device */ 10071b22764fSDaniel OpenSolaris Anderson if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 10081b22764fSDaniel OpenSolaris Anderson int err = errno; 10091b22764fSDaniel OpenSolaris Anderson cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 10101b22764fSDaniel OpenSolaris Anderson ADMIN_IOCTL_DEVICE, strerror(err)); 10111b22764fSDaniel OpenSolaris Anderson free_entry(pent); 10121b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 10137c478bd9Sstevel@tonic-gate return (FAILURE); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10161b22764fSDaniel OpenSolaris Anderson if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, 10171b22764fSDaniel OpenSolaris Anderson pload_soft_conf) == -1) { 10181b22764fSDaniel OpenSolaris Anderson cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s", 10191b22764fSDaniel OpenSolaris Anderson strerror(errno)); 10201b22764fSDaniel OpenSolaris Anderson free_entry(pent); 10211b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 10221b22764fSDaniel OpenSolaris Anderson (void) close(fd); 10237c478bd9Sstevel@tonic-gate return (FAILURE); 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate 10261b22764fSDaniel OpenSolaris Anderson if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) { 10271b22764fSDaniel OpenSolaris Anderson cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl = return_value = %d", 10281b22764fSDaniel OpenSolaris Anderson pload_soft_conf->sc_return_value); 10291b22764fSDaniel OpenSolaris Anderson free_entry(pent); 10301b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 10311b22764fSDaniel OpenSolaris Anderson (void) close(fd); 10327c478bd9Sstevel@tonic-gate return (FAILURE); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate 10351b22764fSDaniel OpenSolaris Anderson /* ioctl cleanup */ 10361b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 10371b22764fSDaniel OpenSolaris Anderson (void) close(fd); 10381b22764fSDaniel OpenSolaris Anderson 10391b22764fSDaniel OpenSolaris Anderson 10401b22764fSDaniel OpenSolaris Anderson /* Finally, remove entry from kcf.conf, if present */ 10411b22764fSDaniel OpenSolaris Anderson if (in_kcfconf && (pent != NULL)) { 10421b22764fSDaniel OpenSolaris Anderson rc = update_kcfconf(pent, DELETE_MODE); 10437c478bd9Sstevel@tonic-gate } 10447c478bd9Sstevel@tonic-gate 10451b22764fSDaniel OpenSolaris Anderson free_entry(pent); 10467c478bd9Sstevel@tonic-gate return (rc); 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate 10501b22764fSDaniel OpenSolaris Anderson /* 10511b22764fSDaniel OpenSolaris Anderson * Implement the "cryptoadm refresh" command for global zones. 10521b22764fSDaniel OpenSolaris Anderson * That is, send the current contents of kcf.conf to the kernel via ioctl(). 10531b22764fSDaniel OpenSolaris Anderson */ 10547c478bd9Sstevel@tonic-gate int 10557c478bd9Sstevel@tonic-gate refresh(void) 10567c478bd9Sstevel@tonic-gate { 10577c478bd9Sstevel@tonic-gate crypto_load_soft_config_t *pload_soft_conf = NULL; 10587c478bd9Sstevel@tonic-gate crypto_load_soft_disabled_t *pload_soft_dis = NULL; 10597c478bd9Sstevel@tonic-gate crypto_load_dev_disabled_t *pload_dev_dis = NULL; 10607c478bd9Sstevel@tonic-gate entrylist_t *pdevlist = NULL; 10617c478bd9Sstevel@tonic-gate entrylist_t *psoftlist = NULL; 10627c478bd9Sstevel@tonic-gate entrylist_t *ptr; 10631b22764fSDaniel OpenSolaris Anderson int fd = -1; 10647c478bd9Sstevel@tonic-gate int rc = SUCCESS; 10651b22764fSDaniel OpenSolaris Anderson int err; 10667c478bd9Sstevel@tonic-gate 1067*d616ad8eSHai-May Chao if (get_kcfconf_info(&pdevlist, &psoftlist) == FAILURE) { 10687c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to retrieve the providers' " 10697c478bd9Sstevel@tonic-gate "information from the configuration file - %s.", 10707c478bd9Sstevel@tonic-gate _PATH_KCF_CONF); 10717c478bd9Sstevel@tonic-gate return (FAILURE); 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate 10747c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 10757c478bd9Sstevel@tonic-gate err = errno; 10767c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 10777c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(err)); 10787c478bd9Sstevel@tonic-gate free(psoftlist); 10797c478bd9Sstevel@tonic-gate free(pdevlist); 10807c478bd9Sstevel@tonic-gate return (FAILURE); 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate /* 10841b22764fSDaniel OpenSolaris Anderson * For each software provider module, pass two sets of information to 10851b22764fSDaniel OpenSolaris Anderson * the kernel: the supported list and the disabled list. 10867c478bd9Sstevel@tonic-gate */ 10871b22764fSDaniel OpenSolaris Anderson for (ptr = psoftlist; ptr != NULL; ptr = ptr->next) { 10881b22764fSDaniel OpenSolaris Anderson entry_t *pent = ptr->pent; 10891b22764fSDaniel OpenSolaris Anderson 10907c478bd9Sstevel@tonic-gate /* load the supported list */ 10911b22764fSDaniel OpenSolaris Anderson if ((pload_soft_conf = setup_soft_conf(pent)) == NULL) { 10921b22764fSDaniel OpenSolaris Anderson cryptodebug("setup_soft_conf() failed"); 10937c478bd9Sstevel@tonic-gate rc = FAILURE; 10947c478bd9Sstevel@tonic-gate break; 10957c478bd9Sstevel@tonic-gate } 10967c478bd9Sstevel@tonic-gate 10971b22764fSDaniel OpenSolaris Anderson if (!pent->load) { /* unloaded--mark as loaded */ 10981b22764fSDaniel OpenSolaris Anderson pent->load = B_TRUE; 10991b22764fSDaniel OpenSolaris Anderson rc = update_kcfconf(pent, MODIFY_MODE); 11001b22764fSDaniel OpenSolaris Anderson if (rc != SUCCESS) { 11011b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 11021b22764fSDaniel OpenSolaris Anderson break; 11031b22764fSDaniel OpenSolaris Anderson } 11041b22764fSDaniel OpenSolaris Anderson } 11051b22764fSDaniel OpenSolaris Anderson 11067c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, pload_soft_conf) 11077c478bd9Sstevel@tonic-gate == -1) { 11087c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s", 11097c478bd9Sstevel@tonic-gate strerror(errno)); 11107c478bd9Sstevel@tonic-gate free(pload_soft_conf); 11117c478bd9Sstevel@tonic-gate rc = FAILURE; 11127c478bd9Sstevel@tonic-gate break; 11137c478bd9Sstevel@tonic-gate } 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) { 11167c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl " 11177c478bd9Sstevel@tonic-gate "return_value = %d", 11187c478bd9Sstevel@tonic-gate pload_soft_conf->sc_return_value); 11197c478bd9Sstevel@tonic-gate free(pload_soft_conf); 11207c478bd9Sstevel@tonic-gate rc = FAILURE; 11217c478bd9Sstevel@tonic-gate break; 11227c478bd9Sstevel@tonic-gate } 11237c478bd9Sstevel@tonic-gate 11241b22764fSDaniel OpenSolaris Anderson free(pload_soft_conf); 11251b22764fSDaniel OpenSolaris Anderson 11267c478bd9Sstevel@tonic-gate /* load the disabled list */ 11277c478bd9Sstevel@tonic-gate if (ptr->pent->dis_count != 0) { 11287c478bd9Sstevel@tonic-gate pload_soft_dis = setup_soft_dis(ptr->pent); 11297c478bd9Sstevel@tonic-gate if (pload_soft_dis == NULL) { 11301b22764fSDaniel OpenSolaris Anderson cryptodebug("setup_soft_dis() failed"); 11311b22764fSDaniel OpenSolaris Anderson free(pload_soft_dis); 11327c478bd9Sstevel@tonic-gate rc = FAILURE; 11337c478bd9Sstevel@tonic-gate break; 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, 11377c478bd9Sstevel@tonic-gate pload_soft_dis) == -1) { 11387c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl " 11397c478bd9Sstevel@tonic-gate "failed: %s", strerror(errno)); 11407c478bd9Sstevel@tonic-gate free(pload_soft_dis); 11417c478bd9Sstevel@tonic-gate rc = FAILURE; 11427c478bd9Sstevel@tonic-gate break; 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate 11457c478bd9Sstevel@tonic-gate if (pload_soft_dis->sd_return_value != 11467c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) { 11477c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl " 11487c478bd9Sstevel@tonic-gate "return_value = %d", 11497c478bd9Sstevel@tonic-gate pload_soft_dis->sd_return_value); 11507c478bd9Sstevel@tonic-gate free(pload_soft_dis); 11517c478bd9Sstevel@tonic-gate rc = FAILURE; 11527c478bd9Sstevel@tonic-gate break; 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate free(pload_soft_dis); 11557c478bd9Sstevel@tonic-gate } 11567c478bd9Sstevel@tonic-gate } 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate if (rc != SUCCESS) { 11597c478bd9Sstevel@tonic-gate (void) close(fd); 11607c478bd9Sstevel@tonic-gate return (rc); 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate 11637c478bd9Sstevel@tonic-gate 11641b22764fSDaniel OpenSolaris Anderson /* 11651b22764fSDaniel OpenSolaris Anderson * For each hardware provider module, pass the disabled list 11661b22764fSDaniel OpenSolaris Anderson * information to the kernel. 11671b22764fSDaniel OpenSolaris Anderson */ 11681b22764fSDaniel OpenSolaris Anderson for (ptr = pdevlist; ptr != NULL; ptr = ptr->next) { 11697c478bd9Sstevel@tonic-gate /* load the disabled list */ 11707c478bd9Sstevel@tonic-gate if (ptr->pent->dis_count != 0) { 11717c478bd9Sstevel@tonic-gate pload_dev_dis = setup_dev_dis(ptr->pent); 11727c478bd9Sstevel@tonic-gate if (pload_dev_dis == NULL) { 11737c478bd9Sstevel@tonic-gate rc = FAILURE; 11747c478bd9Sstevel@tonic-gate break; 11757c478bd9Sstevel@tonic-gate } 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis) 11787c478bd9Sstevel@tonic-gate == -1) { 11797c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl " 11807c478bd9Sstevel@tonic-gate "failed: %s", strerror(errno)); 11817c478bd9Sstevel@tonic-gate free(pload_dev_dis); 11827c478bd9Sstevel@tonic-gate rc = FAILURE; 11837c478bd9Sstevel@tonic-gate break; 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) { 11877c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl " 11887c478bd9Sstevel@tonic-gate "return_value = %d", 11897c478bd9Sstevel@tonic-gate pload_dev_dis->dd_return_value); 11907c478bd9Sstevel@tonic-gate free(pload_dev_dis); 11917c478bd9Sstevel@tonic-gate rc = FAILURE; 11927c478bd9Sstevel@tonic-gate break; 11937c478bd9Sstevel@tonic-gate } 11947c478bd9Sstevel@tonic-gate free(pload_dev_dis); 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate (void) close(fd); 11997c478bd9Sstevel@tonic-gate return (rc); 12007c478bd9Sstevel@tonic-gate } 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate /* 12037c478bd9Sstevel@tonic-gate * Unload the kernel software provider. Before calling this function, the 12041b22764fSDaniel OpenSolaris Anderson * caller should check to see if the provider is in the kernel. 12051b22764fSDaniel OpenSolaris Anderson * 12061b22764fSDaniel OpenSolaris Anderson * This routine makes 2 ioctl calls to remove it completely from the kernel: 12071b22764fSDaniel OpenSolaris Anderson * CRYPTO_UNLOAD_SOFT_MODULE - does a modunload of the KCF module 12081b22764fSDaniel OpenSolaris Anderson * CRYPTO_LOAD_SOFT_DISABLED - updates kernel disabled mechanism list 12091b22764fSDaniel OpenSolaris Anderson * 12101b22764fSDaniel OpenSolaris Anderson * This implements part of "cryptoadm unload" and "cryptoadm uninstall". 12117c478bd9Sstevel@tonic-gate */ 12127c478bd9Sstevel@tonic-gate int 12131b22764fSDaniel OpenSolaris Anderson unload_kef_soft(char *provname) 12147c478bd9Sstevel@tonic-gate { 12157c478bd9Sstevel@tonic-gate crypto_unload_soft_module_t *punload_soft = NULL; 12167c478bd9Sstevel@tonic-gate crypto_load_soft_disabled_t *pload_soft_dis = NULL; 12177c478bd9Sstevel@tonic-gate entry_t *pent = NULL; 12181b22764fSDaniel OpenSolaris Anderson int fd = -1; 12191b22764fSDaniel OpenSolaris Anderson int err; 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate if (provname == NULL) { 12227c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 12237c478bd9Sstevel@tonic-gate return (FAILURE); 12247c478bd9Sstevel@tonic-gate } 12257c478bd9Sstevel@tonic-gate 1226*d616ad8eSHai-May Chao pent = getent_kef(provname, NULL, NULL); 12271b22764fSDaniel OpenSolaris Anderson if (pent == NULL) { /* not in kcf.conf */ 1228b8bf75cbSkrishna /* Construct an entry using the provname */ 12291b22764fSDaniel OpenSolaris Anderson pent = create_entry(provname); 1230b8bf75cbSkrishna if (pent == NULL) { 1231b8bf75cbSkrishna cryptoerror(LOG_STDERR, gettext("out of memory.")); 1232b8bf75cbSkrishna return (FAILURE); 1233b8bf75cbSkrishna } 12347c478bd9Sstevel@tonic-gate } 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gate /* Open the admin_ioctl_device */ 12377c478bd9Sstevel@tonic-gate if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) { 12387c478bd9Sstevel@tonic-gate err = errno; 12397c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"), 12407c478bd9Sstevel@tonic-gate ADMIN_IOCTL_DEVICE, strerror(err)); 12411b22764fSDaniel OpenSolaris Anderson free_entry(pent); 12427c478bd9Sstevel@tonic-gate return (FAILURE); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate /* Inform kernel to unload this software module */ 12467c478bd9Sstevel@tonic-gate if ((punload_soft = setup_unload_soft(pent)) == NULL) { 12471b22764fSDaniel OpenSolaris Anderson free_entry(pent); 12487c478bd9Sstevel@tonic-gate (void) close(fd); 12497c478bd9Sstevel@tonic-gate return (FAILURE); 12507c478bd9Sstevel@tonic-gate } 12517c478bd9Sstevel@tonic-gate 12527c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_UNLOAD_SOFT_MODULE, punload_soft) == -1) { 12537c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_UNLOAD_SOFT_MODULE ioctl failed: %s", 12547c478bd9Sstevel@tonic-gate strerror(errno)); 12557c478bd9Sstevel@tonic-gate free_entry(pent); 12567c478bd9Sstevel@tonic-gate free(punload_soft); 12577c478bd9Sstevel@tonic-gate (void) close(fd); 12587c478bd9Sstevel@tonic-gate return (FAILURE); 12597c478bd9Sstevel@tonic-gate } 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate if (punload_soft->sm_return_value != CRYPTO_SUCCESS) { 12627c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_UNLOAD_SOFT_MODULE ioctl return_value = " 12637c478bd9Sstevel@tonic-gate "%d", punload_soft->sm_return_value); 12647c478bd9Sstevel@tonic-gate /* 12650a85b835SDaniel Anderson * If the return value is CRYPTO_UNKNOWN_PROVIDER, it means 12667c478bd9Sstevel@tonic-gate * that the provider is not registered yet. Should just 12677c478bd9Sstevel@tonic-gate * continue. 12687c478bd9Sstevel@tonic-gate */ 12697c478bd9Sstevel@tonic-gate if (punload_soft->sm_return_value != CRYPTO_UNKNOWN_PROVIDER) { 12707c478bd9Sstevel@tonic-gate free_entry(pent); 12717c478bd9Sstevel@tonic-gate free(punload_soft); 12727c478bd9Sstevel@tonic-gate (void) close(fd); 12737c478bd9Sstevel@tonic-gate return (FAILURE); 12747c478bd9Sstevel@tonic-gate } 12757c478bd9Sstevel@tonic-gate } 12767c478bd9Sstevel@tonic-gate 12777c478bd9Sstevel@tonic-gate free(punload_soft); 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate /* Inform kernel to remove the disabled entries if any */ 12807c478bd9Sstevel@tonic-gate if (pent->dis_count == 0) { 12817c478bd9Sstevel@tonic-gate free_entry(pent); 12827c478bd9Sstevel@tonic-gate (void) close(fd); 12837c478bd9Sstevel@tonic-gate return (SUCCESS); 12847c478bd9Sstevel@tonic-gate } else { 12857c478bd9Sstevel@tonic-gate free_mechlist(pent->dislist); 12867c478bd9Sstevel@tonic-gate pent->dislist = NULL; 12877c478bd9Sstevel@tonic-gate pent->dis_count = 0; 12887c478bd9Sstevel@tonic-gate } 12897c478bd9Sstevel@tonic-gate 12907c478bd9Sstevel@tonic-gate if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) { 12917c478bd9Sstevel@tonic-gate free_entry(pent); 12927c478bd9Sstevel@tonic-gate (void) close(fd); 12937c478bd9Sstevel@tonic-gate return (FAILURE); 12947c478bd9Sstevel@tonic-gate } 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate /* pent is no longer needed; free it */ 12977c478bd9Sstevel@tonic-gate free_entry(pent); 12987c478bd9Sstevel@tonic-gate 12997c478bd9Sstevel@tonic-gate if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis) == -1) { 13007c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: %s", 13017c478bd9Sstevel@tonic-gate strerror(errno)); 13027c478bd9Sstevel@tonic-gate free(pload_soft_dis); 13037c478bd9Sstevel@tonic-gate (void) close(fd); 13047c478bd9Sstevel@tonic-gate return (FAILURE); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) { 13087c478bd9Sstevel@tonic-gate cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl return_value = " 13097c478bd9Sstevel@tonic-gate "%d", pload_soft_dis->sd_return_value); 13107c478bd9Sstevel@tonic-gate free(pload_soft_dis); 13117c478bd9Sstevel@tonic-gate (void) close(fd); 13127c478bd9Sstevel@tonic-gate return (FAILURE); 13137c478bd9Sstevel@tonic-gate } 13147c478bd9Sstevel@tonic-gate 13157c478bd9Sstevel@tonic-gate free(pload_soft_dis); 13167c478bd9Sstevel@tonic-gate (void) close(fd); 13177c478bd9Sstevel@tonic-gate return (SUCCESS); 13187c478bd9Sstevel@tonic-gate } 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate /* 13227c478bd9Sstevel@tonic-gate * Check if a hardware provider is valid. If it is valid, returns its device 13237c478bd9Sstevel@tonic-gate * name, instance number and the number of mechanisms it supports. 13247c478bd9Sstevel@tonic-gate */ 13257c478bd9Sstevel@tonic-gate static int 13267c478bd9Sstevel@tonic-gate check_hardware_provider(char *provname, char *pname, int *pnum, int *pcount) 13277c478bd9Sstevel@tonic-gate { 13287c478bd9Sstevel@tonic-gate crypto_get_dev_list_t *dev_list = NULL; 13297c478bd9Sstevel@tonic-gate int i; 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate if (provname == NULL) { 13327c478bd9Sstevel@tonic-gate return (FAILURE); 13337c478bd9Sstevel@tonic-gate } 13347c478bd9Sstevel@tonic-gate 13357c478bd9Sstevel@tonic-gate /* First, get the device name and the instance number from provname */ 13367c478bd9Sstevel@tonic-gate if (split_hw_provname(provname, pname, pnum) == FAILURE) { 13377c478bd9Sstevel@tonic-gate return (FAILURE); 13387c478bd9Sstevel@tonic-gate } 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate /* 13417c478bd9Sstevel@tonic-gate * Get the complete device list from kernel and check if this provider 13427c478bd9Sstevel@tonic-gate * is in the list. 13437c478bd9Sstevel@tonic-gate */ 13447c478bd9Sstevel@tonic-gate if (get_dev_list(&dev_list) == FAILURE) { 13457c478bd9Sstevel@tonic-gate return (FAILURE); 13467c478bd9Sstevel@tonic-gate } 13477c478bd9Sstevel@tonic-gate 13487c478bd9Sstevel@tonic-gate for (i = 0; i < dev_list->dl_dev_count; i++) { 13497c478bd9Sstevel@tonic-gate if ((strcmp(dev_list->dl_devs[i].le_dev_name, pname) == 0) && 13507c478bd9Sstevel@tonic-gate (dev_list->dl_devs[i].le_dev_instance == *pnum)) { 13517c478bd9Sstevel@tonic-gate break; 13527c478bd9Sstevel@tonic-gate } 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate if (i == dev_list->dl_dev_count) { 13567c478bd9Sstevel@tonic-gate /* didn't find this provider in the kernel device list */ 13577c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("%s does not exist."), 13587c478bd9Sstevel@tonic-gate provname); 13597c478bd9Sstevel@tonic-gate free(dev_list); 13607c478bd9Sstevel@tonic-gate return (FAILURE); 13617c478bd9Sstevel@tonic-gate } 13627c478bd9Sstevel@tonic-gate 13637c478bd9Sstevel@tonic-gate /* This provider is valid. Get its mechanism count */ 13647c478bd9Sstevel@tonic-gate *pcount = dev_list->dl_devs[i].le_mechanism_count; 13657c478bd9Sstevel@tonic-gate 13667c478bd9Sstevel@tonic-gate free(dev_list); 13677c478bd9Sstevel@tonic-gate return (SUCCESS); 13687c478bd9Sstevel@tonic-gate } 1369