changeset 10979:00cad6413daf

6897371 cryptoadm needs changes in order to support fips-140 mode in local zones 6897374 Memory leaking in kernel algorithm modules and softtoken dsa with fips enabled
author Hai-May Chao <Hai-May.Chao@Sun.COM>
date Thu, 05 Nov 2009 21:57:36 -0800
parents 5a4580d4e2b9
children 53f23d6d46a3
files usr/src/cmd/cmd-crypto/cryptoadm/adm_kef.c usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c usr/src/cmd/cmd-crypto/cryptoadm/adm_util.c usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.c usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.h usr/src/common/crypto/fips/fips_des_util.c usr/src/common/crypto/fips/fips_ecc_util.c usr/src/common/crypto/fips/fips_rsa_util.c usr/src/common/crypto/fips/fips_sha1_util.c usr/src/common/crypto/fips/fips_sha2_util.c usr/src/lib/libcryptoutil/common/config_parsing.c usr/src/lib/libcryptoutil/common/cryptoutil.h usr/src/lib/pkcs11/libpkcs11/common/pkcs11Conf.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c
diffstat 16 files changed, 317 insertions(+), 264 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef.c	Thu Nov 05 21:57:36 2009 -0800
@@ -43,15 +43,14 @@
  * Display the mechanism list for a kernel software provider.
  * This implements part of the "cryptoadm list -m" command.
  *
- * Parameters phardlist, psoftlist and pfipslist are supplied by
+ * Parameters phardlist and psoftlist are supplied by
  * get_soft_info().
  * If NULL, this function obtains it by calling getent_kef() and
  * then get_kcfconf_info() via get_soft_info() internally.
  */
 int
 list_mechlist_for_soft(char *provname,
-    entrylist_t *phardlist, entrylist_t *psoftlist,
-    entrylist_t *pfipslist)
+    entrylist_t *phardlist, entrylist_t *psoftlist)
 {
 	mechlist_t	*pmechlist = NULL;
 	int		rc;
@@ -60,8 +59,7 @@
 		return (FAILURE);
 	}
 
-	rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist,
-	    pfipslist);
+	rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist);
 	if (rc == SUCCESS) {
 		(void) filter_mechlist(&pmechlist, RANDOM);
 		print_mechlist(provname, pmechlist);
@@ -117,15 +115,14 @@
  * Display the policy information for a kernel software provider.
  * This implements part of the "cryptoadm list -p" command.
  *
- * Parameters phardlist, psoftlist and pfipslist are supplied by
+ * Parameters phardlist and psoftlist are supplied by
  * getent_kef().
  * If NULL, this function obtains it by calling get_kcfconf_info()
  * via getent_kef() internally.
  */
 int
 list_policy_for_soft(char *provname,
-    entrylist_t *phardlist, entrylist_t *psoftlist,
-    entrylist_t *pfipslist)
+    entrylist_t *phardlist, entrylist_t *psoftlist)
 {
 	int		rc;
 	entry_t		*pent = NULL;
@@ -145,11 +142,9 @@
 		    provname);
 		return (FAILURE);
 	}
-	pent = getent_kef(provname, phardlist, psoftlist,
-	    pfipslist);
+	pent = getent_kef(provname, phardlist, psoftlist);
 
-	rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist,
-	    pfipslist);
+	rc = get_soft_info(provname, &pmechlist, phardlist, psoftlist);
 	if (rc == SUCCESS) {
 		has_random = filter_mechlist(&pmechlist, RANDOM);
 		if (pmechlist != NULL) {
@@ -174,7 +169,7 @@
  * Display the policy information for a kernel hardware provider.
  * This implements part of the "cryptoadm list -p" command.
  *
- * Parameters phardlist, psoftlist and pfipslist are supplied by getent_kef().
+ * Parameters phardlist and psoftlist are supplied by getent_kef().
  * If NULL, this function obtains it by calling get_kcfconf_info() via
  * getent_kef() internally.
  * Parameter pdevlist is supplied by check_kernel_for_hard().
@@ -184,7 +179,7 @@
 int
 list_policy_for_hard(char *provname,
 	entrylist_t *phardlist, entrylist_t *psoftlist,
-	entrylist_t *pfipslist, crypto_get_dev_list_t *pdevlist)
+	crypto_get_dev_list_t *pdevlist)
 {
 	entry_t		*pent = NULL;
 	boolean_t	in_kernel;
@@ -231,8 +226,7 @@
 	 * the disabled list from the config file entry.  Otherwise,
 	 * if it is active, then all the mechanisms for it are enabled.
 	 */
-	if ((pent = getent_kef(provname, phardlist, psoftlist,
-	    pfipslist)) != NULL) {
+	if ((pent = getent_kef(provname, phardlist, psoftlist)) != NULL) {
 		print_kef_policy(provname, pent, has_random, has_mechs);
 		free_entry(pent);
 		return (SUCCESS);
@@ -304,7 +298,7 @@
 	 * Get the entry of this hardware provider from the config file.
 	 * If there is no entry yet, create one for it.
 	 */
-	if ((pent = getent_kef(provname, NULL, NULL, NULL)) == NULL) {
+	if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
 		if ((pent = create_entry(provname)) == NULL) {
 			cryptoerror(LOG_STDERR, gettext("out of memory."));
 			free_mechlist(infolist);
@@ -399,7 +393,6 @@
 	entry_t				*pent = NULL;
 	entrylist_t			*phardlist = NULL;
 	entrylist_t			*psoftlist = NULL;
-	entrylist_t			*pfipslist = NULL;
 	boolean_t			in_kernel = B_FALSE;
 	int				fd = -1;
 	int				rc = SUCCESS;
@@ -413,8 +406,7 @@
 	 * If it is unloaded, return FAILURE, because the disable subcommand
 	 * can not perform on inactive (unloaded) providers.
 	 */
-	if (check_kernel_for_soft(provname, NULL, &in_kernel) ==
-	    FAILURE) {
+	if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) {
 		return (FAILURE);
 	} else if (in_kernel == B_FALSE) {
 		cryptoerror(LOG_STDERR,
@@ -423,8 +415,7 @@
 		return (FAILURE);
 	}
 
-	if (get_kcfconf_info(&phardlist, &psoftlist, &pfipslist) ==
-	    FAILURE) {
+	if (get_kcfconf_info(&phardlist, &psoftlist) == FAILURE) {
 		cryptoerror(LOG_ERR,
 		    "failed to retrieve the providers' "
 		    "information from the configuration file - %s.",
@@ -436,7 +427,7 @@
 	 * Get the entry of this provider from the kcf.conf file, if any.
 	 * Otherwise, create a new kcf.conf entry for writing back to the file.
 	 */
-	pent = getent_kef(provname, phardlist, psoftlist, pfipslist);
+	pent = getent_kef(provname, phardlist, psoftlist);
 	if (pent == NULL) { /* create a new entry */
 		pent = create_entry(provname);
 		if (pent == NULL) {
@@ -447,8 +438,8 @@
 	}
 
 	/* Get the mechanism list for the software provider from the kernel */
-	if (get_soft_info(provname, &infolist, phardlist, psoftlist,
-	    pfipslist) == FAILURE) {
+	if (get_soft_info(provname, &infolist, phardlist, psoftlist) ==
+	    FAILURE) {
 		rc = FAILURE;
 		goto out;
 	}
@@ -545,7 +536,7 @@
 
 
 	/* Get the entry of this provider from the kcf.conf file, if any. */
-	pent = getent_kef(provname, NULL, NULL, NULL);
+	pent = getent_kef(provname, NULL, NULL);
 
 	if (is_device(provname)) {
 		if (pent == NULL) {
@@ -726,7 +717,7 @@
 	}
 
 	/* Check if the provider already exists */
-	if ((pent = getent_kef(provname, NULL, NULL, NULL)) != NULL) {
+	if ((pent = getent_kef(provname, NULL, NULL)) != NULL) {
 		cryptoerror(LOG_STDERR, gettext("%s exists already."),
 		    provname);
 		free_entry(pent);
@@ -997,7 +988,7 @@
 	 */
 
 	/* Setup ioctl() parameter */
-	pent = getent_kef(provname, NULL, NULL, NULL);
+	pent = getent_kef(provname, NULL, NULL);
 	if (pent != NULL) { /* in kcf.conf */
 		in_kcfconf = B_TRUE;
 		free_mechlist(pent->suplist);
@@ -1068,14 +1059,12 @@
 	crypto_load_dev_disabled_t	*pload_dev_dis = NULL;
 	entrylist_t			*pdevlist = NULL;
 	entrylist_t			*psoftlist = NULL;
-	entrylist_t			*pfipslist = NULL;
 	entrylist_t			*ptr;
 	int				fd = -1;
 	int				rc = SUCCESS;
 	int				err;
 
-	if (get_kcfconf_info(&pdevlist, &psoftlist, &pfipslist) ==
-	    FAILURE) {
+	if (get_kcfconf_info(&pdevlist, &psoftlist) == FAILURE) {
 		cryptoerror(LOG_ERR, "failed to retrieve the providers' "
 		    "information from the configuration file - %s.",
 		    _PATH_KCF_CONF);
@@ -1209,11 +1198,16 @@
 	/*
 	 * handle fips_status=enabled|disabled
 	 */
-	ptr = pfipslist;
-	if (ptr != NULL && ptr->pent->flag_fips_enabled) {
-		rc = do_fips_actions(FIPS140_ENABLE, REFRESH);
-	} else {
-		rc = do_fips_actions(FIPS140_DISABLE, REFRESH);
+	{
+		int	pkcs11_fips_mode = 0;
+
+		/* Get FIPS-140 status from pkcs11.conf */
+		fips_status_pkcs11conf(&pkcs11_fips_mode);
+		if (pkcs11_fips_mode == CRYPTO_FIPS_MODE_ENABLED) {
+			rc = do_fips_actions(FIPS140_ENABLE, REFRESH);
+		} else {
+			rc = do_fips_actions(FIPS140_DISABLE, REFRESH);
+		}
 	}
 
 	(void) close(fd);
@@ -1244,7 +1238,7 @@
 		return (FAILURE);
 	}
 
-	pent = getent_kef(provname, NULL, NULL, NULL);
+	pent = getent_kef(provname, NULL, NULL);
 	if (pent == NULL) { /* not in kcf.conf */
 		/* Construct an entry using the provname */
 		pent = create_entry(provname);
@@ -1387,43 +1381,3 @@
 	free(dev_list);
 	return (SUCCESS);
 }
-
-int
-fips_update_kcfconf(int action)
-{
-
-	char	*str;
-
-	if (action == FIPS140_ENABLE)
-		str = "fips-140:fips_status=enabled\n";
-	else
-		str = "fips-140:fips_status=disabled\n";
-
-	if (update_conf(_PATH_KCF_CONF, str) != SUCCESS)
-		return (FAILURE);
-
-	return (SUCCESS);
-}
-
-void
-fips_status_kcfconf(int *status)
-{
-
-	entry_t *pent = NULL;
-
-	if ((pent = getent_kef(FIPS_KEYWORD, NULL, NULL, NULL)) == NULL) {
-		/*
-		 * By default (no FIPS entry), we assume FIPS is disabled.
-		 */
-		*status = CRYPTO_FIPS_MODE_DISABLED;
-		return;
-	}
-
-	if (pent->flag_fips_enabled)
-		*status = CRYPTO_FIPS_MODE_ENABLED;
-	else
-		*status = CRYPTO_FIPS_MODE_DISABLED;
-
-	return;
-
-}
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c	Thu Nov 05 21:57:36 2009 -0800
@@ -402,8 +402,7 @@
  */
 int
 get_soft_info(char *provname, mechlist_t **ppmechlist,
-	entrylist_t *phardlist, entrylist_t *psoftlist,
-	entrylist_t *pfipslist)
+	entrylist_t *phardlist, entrylist_t *psoftlist)
 {
 	boolean_t		in_kernel = B_FALSE;
 	crypto_get_soft_info_t	*psoft_info;
@@ -422,8 +421,8 @@
 
 	if (getzoneid() == GLOBAL_ZONEID) {
 		/* use kcf.conf for kernel software providers in global zone */
-		if ((pent = getent_kef(provname, phardlist, psoftlist,
-		    pfipslist)) == NULL) {
+		if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
+		    NULL) {
 
 			/* No kcf.conf entry for this provider */
 			if (check_kernel_for_soft(provname, NULL, &in_kernel)
@@ -617,13 +616,13 @@
 	crypto_fips140_t	fips_info;
 	int	fd;
 	int	rc = SUCCESS;
-	int	kcf_fips_mode = 0;
+	int	pkcs11_fips_mode = 0;
 
-	/* Get FIPS-140 status from kcf.conf */
-	fips_status_kcfconf(&kcf_fips_mode);
+	/* Get FIPS-140 status from pkcs11.conf */
+	fips_status_pkcs11conf(&pkcs11_fips_mode);
 
 	if (action == FIPS140_STATUS) {
-		if (kcf_fips_mode == CRYPTO_FIPS_MODE_ENABLED)
+		if (pkcs11_fips_mode == CRYPTO_FIPS_MODE_ENABLED)
 			(void) printf(gettext(
 			    "\tFIPS-140 mode is enabled.\n"));
 		else
@@ -635,7 +634,7 @@
 	if (caller == NOT_REFRESH) {
 		/* Is it a duplicate operation? */
 		if ((action == FIPS140_ENABLE) &&
-		    (kcf_fips_mode == CRYPTO_FIPS_MODE_ENABLED)) {
+		    (pkcs11_fips_mode == CRYPTO_FIPS_MODE_ENABLED)) {
 			cryptoerror(LOG_STDERR,
 			    gettext("FIPS-140 mode has already "
 			    "been enabled.\n"));
@@ -643,7 +642,7 @@
 		}
 
 		if ((action == FIPS140_DISABLE) &&
-		    (kcf_fips_mode == CRYPTO_FIPS_MODE_DISABLED)) {
+		    (pkcs11_fips_mode == CRYPTO_FIPS_MODE_DISABLED)) {
 			cryptoerror(LOG_STDERR,
 			    gettext("FIPS-140 mode has already "
 			    "been disabled.\n"));
@@ -651,8 +650,8 @@
 		}
 
 		if ((action == FIPS140_ENABLE) || (action == FIPS140_DISABLE)) {
-			/* Update kcf.conf */
-			if ((rc = fips_update_kcfconf(action)) != SUCCESS)
+			/* Update pkcs11.conf */
+			if ((rc = fips_update_pkcs11conf(action)) != SUCCESS)
 				return (rc);
 		}
 
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -35,7 +35,6 @@
 #include <zone.h>
 #include <sys/stat.h>
 #include "cryptoadm.h"
-#include <cryptoutil.h>
 
 static int err; /* To store errno which may be overwritten by gettext() */
 static int build_entrylist(entry_t *, entrylist_t **);
@@ -145,7 +144,6 @@
 		return (NULL);
 	}
 
-	pent2->flag_fips_enabled = pent1->flag_fips_enabled;
 	pent2->sup_count = pent1->sup_count;
 	pent2->dis_count = pent1->dis_count;
 	pent2->load = pent1->load;
@@ -248,35 +246,6 @@
 	return (rc);
 }
 
-static int
-parse_fips(char *buf, entry_t *pent)
-{
-	char *value;
-
-	if (strncmp(buf, EF_FIPS_STATUS, sizeof (EF_FIPS_STATUS) - 1) == 0) {
-		if (value = strpbrk(buf, SEP_EQUAL)) {
-			value++; /* get rid of = */
-			if (strcmp(value, DISABLED_KEYWORD) == 0) {
-				pent->flag_fips_enabled = B_FALSE;
-			} else if (strcmp(value, ENABLED_KEYWORD) == 0) {
-				pent->flag_fips_enabled = B_TRUE;
-			} else {
-				cryptoerror(LOG_ERR, gettext(
-				    "Failed to parse kcf.conf file.\n"));
-				return (FAILURE);
-			}
-			return (SUCCESS);
-		} else {
-			return (FAILURE);
-		}
-	} else {
-		/* should not come here */
-		cryptoerror(LOG_ERR, gettext(
-		    "Failed to parse kcf.conf file.\n"));
-		return (FAILURE);
-	}
-
-}
 
 /*
  * Convert a char string containing a line about a provider
@@ -305,15 +274,6 @@
 		return (FAILURE);
 	}
 
-	if (is_fips(token1)) {
-		if ((rc = parse_fips(buf + strlen(token1) + 1,
-		    pent)) != SUCCESS) {
-			free_entry(pent);
-		}
-		*ppent = pent;
-		return (rc);
-	}
-
 	if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
 		/* The entry contains a provider name only */
 		free_entry(pent);
@@ -666,16 +626,6 @@
 	}
 }
 
-boolean_t
-is_fips(char *name)
-{
-	if (strcmp(name, FIPS_KEYWORD) == 0) {
-		return (B_TRUE);
-	} else {
-		return (B_FALSE);
-	}
-}
-
 /*
  * Split a hardware provider name with the "name/inst_num" format into
  * a name and a number (e.g., split "mca/0" into "mca" instance 0).
@@ -717,8 +667,7 @@
  * The kcf.conf file is available only in the global zone.
  */
 int
-get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist,
-    entrylist_t **ppfipslist)
+get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
 {
 	FILE	*pfile = NULL;
 	char	buffer[BUFSIZ];
@@ -733,8 +682,6 @@
 
 	*ppdevlist = NULL;
 	*ppsoftlist = NULL;
-	*ppfipslist = NULL;
-
 	while (fgets(buffer, BUFSIZ, pfile) != NULL) {
 		if (buffer[0] == '#' || buffer[0] == ' ' ||
 		    buffer[0] == '\n'|| buffer[0] == '\t') {
@@ -748,15 +695,7 @@
 		buffer[len] = '\0';
 
 		if ((rc = interpret(buffer,  &pent)) == SUCCESS) {
-			if (is_fips(pent->name)) {
-				if (*ppfipslist != NULL) {
-					cryptoerror(LOG_STDERR, gettext(
-					"multiple fips entries."));
-					rc = FAILURE;
-				} else {
-					rc = build_entrylist(pent, ppfipslist);
-				}
-			} else if (is_device(pent->name)) {
+			if (is_device(pent->name)) {
 				rc = build_entrylist(pent, ppdevlist);
 			} else {
 				rc = build_entrylist(pent, ppsoftlist);
@@ -764,13 +703,11 @@
 		} else {
 			cryptoerror(LOG_STDERR, gettext(
 			    "failed to parse configuration."));
-			rc = FAILURE;
 		}
 
 		if (rc != SUCCESS) {
 			free_entrylist(*ppdevlist);
 			free_entrylist(*ppsoftlist);
-			free_entrylist(*ppfipslist);
 			free_entry(pent);
 			break;
 		}
@@ -800,7 +737,6 @@
 	entrylist_t		*tmp_pdev = NULL;
 	entrylist_t		*tmp_psoft = NULL;
 	entrylist_t		*phardlist = NULL, *psoftlist = NULL;
-	entrylist_t		*pfipslist = NULL;
 
 	/*
 	 * Get hardware providers
@@ -844,8 +780,7 @@
 	 * Get software providers
 	 */
 	if (getzoneid() == GLOBAL_ZONEID) {
-		if (get_kcfconf_info(&phardlist, &psoftlist, &pfipslist) !=
-		    SUCCESS) {
+		if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
 			goto fail_out;
 		}
 	}
@@ -859,8 +794,8 @@
 	    i < psoftlist_kernel->sl_soft_count;
 	    i++, psoftname = psoftname + strlen(psoftname) + 1) {
 		pmech = NULL;
-		if (get_soft_info(psoftname, &pmech, phardlist, psoftlist,
-		    pfipslist) != SUCCESS) {
+		if (get_soft_info(psoftname, &pmech, phardlist, psoftlist) !=
+		    SUCCESS) {
 			cryptodebug(
 			    "failed to retrieve the mechanism list for %s.",
 			    psoftname);
@@ -914,15 +849,13 @@
  * If NULL, this function calls get_kcfconf_info() internally.
  */
 entry_t *
-getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist,
-    entrylist_t *pfipslist)
+getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist)
 {
 	entry_t		*pent = NULL;
 	boolean_t	memory_allocated = B_FALSE;
 
-	if ((phardlist == NULL) || (psoftlist == NULL) || (pfipslist == NULL)) {
-		if (get_kcfconf_info(&phardlist, &psoftlist, &pfipslist) !=
-		    SUCCESS) {
+	if ((phardlist == NULL) || (psoftlist == NULL)) {
+		if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
 			return (NULL);
 		}
 		memory_allocated = B_TRUE;
@@ -930,8 +863,6 @@
 
 	if (is_device(provname)) {
 		pent = getent(provname, phardlist);
-	} else if (is_fips(provname)) {
-		pent = getent(provname, pfipslist);
 	} else {
 		pent = getent(provname, psoftlist);
 	}
@@ -939,7 +870,6 @@
 	if (memory_allocated) {
 		free_entrylist(phardlist);
 		free_entrylist(psoftlist);
-		free_entrylist(pfipslist);
 	}
 
 	return (pent);
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c	Thu Nov 05 21:57:36 2009 -0800
@@ -1655,3 +1655,44 @@
 	    "-  -  -  -  -  -  -  -  -  -  -  -  -  -\n",
 	    gettext("----------------------------"));
 }
+
+int
+fips_update_pkcs11conf(int action)
+{
+
+	char	*str;
+
+	if (action == FIPS140_ENABLE)
+		str = "fips-140:fips_status=enabled\n";
+	else
+		str = "fips-140:fips_status=disabled\n";
+
+	if (update_conf(_PATH_PKCS11_CONF, str) != SUCCESS)
+		return (FAILURE);
+
+	return (SUCCESS);
+}
+
+void
+fips_status_pkcs11conf(int *status)
+{
+
+	uentry_t *puent = NULL;
+
+	if ((puent = getent_uef(FIPS_KEYWORD)) == NULL) {
+		/*
+		 * By default (no fips-140 entry), we assume fips-140
+		 * mode is disabled.
+		 */
+		*status = CRYPTO_FIPS_MODE_DISABLED;
+		return;
+	}
+
+	if (puent->flag_fips_enabled)
+		*status = CRYPTO_FIPS_MODE_ENABLED;
+	else
+		*status = CRYPTO_FIPS_MODE_DISABLED;
+
+	return;
+
+}
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -110,6 +110,7 @@
 {
 
 	boolean_t	found;
+	boolean_t	fips_entry = B_FALSE;
 	FILE	*pfile;
 	FILE	*pfile_tmp;
 	char	tmpfile_name[MAXPATHLEN];
@@ -179,6 +180,17 @@
 					found = B_TRUE;
 					found_count++;
 				}
+			} else {
+				(void) strlcpy(buffer2, buffer, BUFSIZ);
+				ptr = buffer2;
+				if ((name = strtok(ptr, SEP_COLON)) == NULL) {
+					rc = FAILURE;
+					break;
+				} else if (strcmp(FIPS_KEYWORD, name) == 0) {
+					found = B_TRUE;
+					found_count++;
+					fips_entry = B_TRUE;
+				}
 			}
 		} else { /* _PATH_KCF_CONF */
 			if (buffer[0] == '#') {
@@ -188,9 +200,6 @@
 				if ((name = strtok(ptr, SEP_COLON)) == NULL) {
 					rc = FAILURE;
 					break;
-				} else if (strcmp(FIPS_KEYWORD, name) == 0) {
-					found = B_TRUE;
-					found_count++;
 				}
 			} else {
 				(void) strlcpy(buffer2, buffer, BUFSIZ);
@@ -198,9 +207,6 @@
 				if ((name = strtok(ptr, SEP_COLON)) == NULL) {
 					rc = FAILURE;
 					break;
-				} else if (strcmp(FIPS_KEYWORD, name) == 0) {
-					found = B_TRUE;
-					found_count++;
 				}
 			}
 		}
@@ -212,8 +218,17 @@
 		} else {
 			if (found_count == 1) {
 				if (strcmp(conf_file, _PATH_PKCS11_CONF) == 0) {
-					if (fputs(ptr, pfile_tmp) == EOF) {
-						rc = FAILURE;
+					if (fips_entry == B_TRUE) {
+						if (fputs(entry, pfile_tmp) ==
+						    EOF) {
+							rc = FAILURE;
+						}
+						fips_entry = B_FALSE;
+					} else {
+						if (fputs(ptr, pfile_tmp) ==
+						    EOF) {
+							rc = FAILURE;
+						}
 					}
 				} else {
 					if (fputs(entry, pfile_tmp) == EOF) {
--- a/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.c	Thu Nov 05 21:57:36 2009 -0800
@@ -659,7 +659,7 @@
 				break;
 			case PROV_KEF_SOFT:
 				rc = list_mechlist_for_soft(provname,
-				    NULL, NULL, NULL);
+				    NULL, NULL);
 				break;
 			case PROV_KEF_HARD:
 				rc = list_mechlist_for_hard(provname);
@@ -676,7 +676,7 @@
 			case PROV_KEF_SOFT:
 				if (getzoneid() == GLOBAL_ZONEID) {
 					rc = list_policy_for_soft(provname,
-					    NULL, NULL, NULL);
+					    NULL, NULL);
 				} else {
 					/*
 					 * TRANSLATION_NOTE
@@ -693,7 +693,7 @@
 			case PROV_KEF_HARD:
 				if (getzoneid() == GLOBAL_ZONEID) {
 					rc = list_policy_for_hard(
-					    provname, NULL, NULL, NULL, NULL);
+					    provname, NULL, NULL, NULL);
 				} else {
 					/*
 					 * TRANSLATION_NOTE
@@ -1186,7 +1186,7 @@
 	}
 
 	/* Get kcf.conf entry.  If none, build a new entry */
-	if ((pent = getent_kef(provname, NULL, NULL, NULL)) == NULL) {
+	if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
 		if ((pent = create_entry(provname)) == NULL) {
 			cryptoerror(LOG_STDERR, gettext("out of memory."));
 			rc = FAILURE;
@@ -1299,7 +1299,9 @@
 	}
 
 	for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) {
-		if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
+		/* skip metaslot and fips-140 entry */
+		if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
+		    (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
 			(void) printf(gettext("Provider: %s\n"),
 			    plibptr->puent->name);
 			if (verbose) {
@@ -1322,7 +1324,6 @@
 		char				*psoftname;
 		entrylist_t			*pdevlist_conf = NULL;
 		entrylist_t			*psoftlist_conf = NULL;
-		entrylist_t			*pfipslist_conf = NULL;
 
 		if (get_soft_list(&psoftlist_kernel) == FAILURE) {
 			cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
@@ -1331,8 +1332,8 @@
 		} else {
 			sl_soft_count = psoftlist_kernel->sl_soft_count;
 
-			if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf,
-			    &pfipslist_conf) == FAILURE) {
+			if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
+			    == FAILURE) {
 				cryptoerror(LOG_ERR,
 				    "failed to retrieve the providers' "
 				    "information from file kcf.conf - %s.",
@@ -1346,15 +1347,13 @@
 				    i < sl_soft_count;
 				    ++i, psoftname += strlen(psoftname) + 1) {
 					pent = getent_kef(psoftname,
-					    pdevlist_conf, psoftlist_conf,
-					    pfipslist_conf);
+					    pdevlist_conf, psoftlist_conf);
 					(void) printf("\t%s%s\n", psoftname,
 					    (pent == NULL) || (pent->load) ?
 					    "" : gettext(" (inactive)"));
 				}
 				free_entrylist(pdevlist_conf);
 				free_entrylist(psoftlist_conf);
-				free_entrylist(pfipslist_conf);
 			}
 			free(psoftlist_kernel);
 		}
@@ -1439,8 +1438,9 @@
 
 	plibptr = pliblist;
 	while (plibptr != NULL) {
-		/* skip metaslot entry */
-		if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
+		/* skip metaslot and fips-140 entry */
+		if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
+		    (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
 			(void) printf(gettext("\nProvider: %s\n"),
 			    plibptr->puent->name);
 			rv = list_mechlist_for_lib(plibptr->puent->name,
@@ -1470,7 +1470,6 @@
 		int				i;
 		entrylist_t			*pdevlist_conf = NULL;
 		entrylist_t			*psoftlist_conf = NULL;
-		entrylist_t			*pfipslist_conf = NULL;
 
 		if (get_soft_list(&psoftlist_kernel) == FAILURE) {
 			cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
@@ -1479,8 +1478,8 @@
 		}
 		sl_soft_count = psoftlist_kernel->sl_soft_count;
 
-		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf,
-		    &pfipslist_conf) == FAILURE) {
+		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
+		    == FAILURE) {
 			cryptoerror(LOG_ERR,
 			    "failed to retrieve the providers' "
 			    "information from file kcf.conf - %s.",
@@ -1493,10 +1492,10 @@
 		    i < sl_soft_count;
 		    ++i, psoftname += strlen(psoftname) + 1) {
 			pent = getent_kef(psoftname, pdevlist_conf,
-			    psoftlist_conf, pfipslist_conf);
+			    psoftlist_conf);
 			if ((pent == NULL) || (pent->load)) {
 				rv = list_mechlist_for_soft(psoftname,
-				    NULL, NULL, NULL);
+				    NULL, NULL);
 				if (rv == FAILURE) {
 					rc = FAILURE;
 				}
@@ -1509,13 +1508,11 @@
 		free(psoftlist_kernel);
 		free_entrylist(pdevlist_conf);
 		free_entrylist(psoftlist_conf);
-		free_entrylist(pfipslist_conf);
 
 	} else {
 		/* kcf.conf not there in non-global zone, use /dev/cryptoadm */
 		entrylist_t	*pdevlist_zone = NULL;
 		entrylist_t	*psoftlist_zone = NULL;
-		entrylist_t	*pfipslist_zone = NULL;
 		entrylist_t	*ptr;
 
 		if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
@@ -1527,7 +1524,7 @@
 
 		for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) {
 			rv = list_mechlist_for_soft(ptr->pent->name,
-			    pdevlist_zone, psoftlist_zone, pfipslist_zone);
+			    pdevlist_zone, psoftlist_zone);
 			if (rv == FAILURE) {
 				(void) printf(gettext(
 				    "%s: failed to get the mechanism list.\n"),
@@ -1588,7 +1585,6 @@
 	uentrylist_t		*pliblist = NULL;
 	entrylist_t		*pdevlist_conf = NULL;
 	entrylist_t		*psoftlist_conf = NULL;
-	entrylist_t		*pfipslist_conf = NULL;
 	entrylist_t		*ptr = NULL;
 	entrylist_t		*phead = NULL;
 	boolean_t		found = B_FALSE;
@@ -1612,9 +1608,11 @@
 		uentrylist_t	*plibptr = pliblist;
 
 		while (plibptr != NULL) {
-			/* skip metaslot entry */
-			if (strcmp(plibptr->puent->name,
-			    METASLOT_KEYWORD) != 0) {
+			/* skip metaslot and fips-140 entry */
+			if ((strcmp(plibptr->puent->name,
+			    METASLOT_KEYWORD) != 0) &&
+			    (strcmp(plibptr->puent->name,
+			    FIPS_KEYWORD) != 0)) {
 				if (print_uef_policy(plibptr->puent)
 				    == FAILURE) {
 					rc = FAILURE;
@@ -1653,8 +1651,7 @@
 			    i < sl_soft_count;
 			    ++i, psoftname += strlen(psoftname) + 1) {
 				(void) list_policy_for_soft(psoftname,
-				    pdevlist_conf, psoftlist_conf,
-				    pfipslist_conf);
+				    pdevlist_conf, psoftlist_conf);
 			}
 			free(psoftlist_kernel);
 		}
@@ -1698,8 +1695,7 @@
 		return (FAILURE);
 	}
 
-	if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf,
-	    &pfipslist_conf) == FAILURE) {
+	if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) {
 		cryptoerror(LOG_ERR, "failed to retrieve the providers' "
 		    "information from file kcf.conf - %s.",
 		    _PATH_KCF_CONF);
@@ -1733,8 +1729,7 @@
 
 		if (found) {
 			(void) list_policy_for_hard(ptr->pent->name,
-			    pdevlist_conf, psoftlist_conf, pfipslist_conf,
-			    pdevlist_kernel);
+			    pdevlist_conf, psoftlist_conf, pdevlist_kernel);
 			if (phead == ptr) {
 				pdevlist_conf = pdevlist_conf->next;
 			} else {
@@ -1744,7 +1739,7 @@
 			free(ptr);
 		} else {
 			(void) list_policy_for_hard(provname, pdevlist_conf,
-			    psoftlist_conf, pfipslist_conf, pdevlist_kernel);
+			    psoftlist_conf, pdevlist_kernel);
 		}
 	}
 
@@ -1759,7 +1754,6 @@
 
 	free_entrylist(pdevlist_conf);
 	free_entrylist(psoftlist_conf);
-	free_entrylist(pfipslist_conf);
 	free(pdevlist_kernel);
 
 	return (rc);
--- a/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.h	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.h	Thu Nov 05 21:57:36 2009 -0800
@@ -74,7 +74,6 @@
 	mechlist_t	*dislist; /* disabled list */
 	uint_t		dis_count;
 	boolean_t	load; /* B_FALSE after cryptoadm unload */
-	boolean_t	flag_fips_enabled;
 } entry_t;
 
 
@@ -97,20 +96,18 @@
 
 /* adm_kef_util */
 extern boolean_t is_device(char *);
-extern boolean_t is_fips(char *);
-extern int fips_update_kcfconf(int);
-extern void fips_status_kcfconf(int *);
+extern int fips_update_pkcs11conf(int);
+extern void fips_status_pkcs11conf(int *);
 extern char *ent2str(entry_t *);
 extern entry_t *getent_kef(char *provname,
-		entrylist_t *pdevlist, entrylist_t *psoftlist,
-		entrylist_t *pfipslist);
+		entrylist_t *pdevlist, entrylist_t *psoftlist);
 extern int check_kernel_for_soft(char *provname,
 		crypto_get_soft_list_t *psoftlist, boolean_t *in_kernel);
 extern int check_kernel_for_hard(char *provname,
 		crypto_get_dev_list_t *pdevlist, boolean_t *in_kernel);
 extern int disable_mechs(entry_t **, mechlist_t *, boolean_t, mechlist_t *);
 extern int enable_mechs(entry_t **, boolean_t, mechlist_t *);
-extern int get_kcfconf_info(entrylist_t **, entrylist_t **, entrylist_t **);
+extern int get_kcfconf_info(entrylist_t **, entrylist_t **);
 extern int get_admindev_info(entrylist_t **, entrylist_t **);
 extern int get_mech_count(mechlist_t *);
 extern entry_t *create_entry(char *provname);
@@ -145,15 +142,12 @@
 
 /* adm_kef */
 extern int list_mechlist_for_soft(char *provname,
-		entrylist_t *phardlist, entrylist_t *psoftlist,
-		entrylist_t *pfipslist);
+		entrylist_t *phardlist, entrylist_t *psoftlist);
 extern int list_mechlist_for_hard(char *);
 extern int list_policy_for_soft(char *provname,
-		entrylist_t *phardlist, entrylist_t *psoftlist,
-		entrylist_t *pfipslist);
+		entrylist_t *phardlist, entrylist_t *psoftlist);
 extern int list_policy_for_hard(char *provname,
 		entrylist_t *phardlist, entrylist_t *psoftlist,
-		entrylist_t *pfipslist,
 		crypto_get_dev_list_t *pdevlist);
 extern int disable_kef_software(char *, boolean_t, boolean_t, mechlist_t *);
 extern int disable_kef_hardware(char *, boolean_t, boolean_t, mechlist_t *);
@@ -173,8 +167,7 @@
 extern int get_dev_info(char *, int, int, mechlist_t **);
 extern int get_dev_list(crypto_get_dev_list_t **);
 extern int get_soft_info(char *provname, mechlist_t **ppmechlist,
-		entrylist_t *phardlist, entrylist_t *psoftlist,
-		entrylist_t *pfipslist);
+		entrylist_t *phardlist, entrylist_t *psoftlist);
 extern int get_soft_list(crypto_get_soft_list_t **);
 extern int do_fips_actions(int, int);
 
--- a/usr/src/common/crypto/fips/fips_des_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/common/crypto/fips/fips_des_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -238,6 +238,8 @@
 			kmem_free(des_ctx->dc_keysched,
 			    des_ctx->dc_keysched_len);
 		}
+		bzero(des_ctx, sizeof (des_ctx_t));
+		kmem_free(des_ctx, sizeof (des_ctx_t));
 	}
 }
 #endif
--- a/usr/src/common/crypto/fips/fips_ecc_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/common/crypto/fips/fips_ecc_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -50,6 +50,10 @@
 #define	MAX_ECKEY_LEN		72
 #define	SHA1_DIGEST_SIZE	20
 
+static void free_ecparams(ECParams *, boolean_t);
+static void free_ecprivkey(ECPrivateKey *);
+static void free_ecpubkey(ECPublicKey *);
+
 static int
 fips_ecdsa_sign_verify(uint8_t *encodedParams,
 	unsigned int encodedParamsLen,
@@ -77,7 +81,9 @@
 	ECPublicKey ecdsa_public_key;
 	SECStatus ecdsaStatus = SECSuccess;
 	SHA1_CTX *sha1_context = NULL;
+	int rv = CKR_DEVICE_ERROR;
 
+	(void) memset(&ecdsa_public_key, 0, sizeof (ECPublicKey));
 	/* construct the ECDSA private/public key pair */
 	encodedparams.type = siBuffer;
 	encodedparams.data = (unsigned char *) encodedParams;
@@ -98,7 +104,7 @@
 	    ecdsa_Known_Seed, sizeof (ecdsa_Known_Seed), 0);
 
 	if (ecdsaStatus != SECSuccess) {
-		return (CKR_DEVICE_ERROR);
+		goto loser;
 	}
 
 	/* construct public key from private key. */
@@ -132,11 +138,14 @@
 	 */
 #ifdef _KERNEL
 	if ((sha1_context = kmem_zalloc(sizeof (SHA1_CTX),
-	    KM_SLEEP)) == NULL)
+	    KM_SLEEP)) == NULL) {
 #else
-	if ((sha1_context = malloc(sizeof (SHA1_CTX))) == NULL)
+	if ((sha1_context = malloc(sizeof (SHA1_CTX))) == NULL) {
 #endif
-		return (CKR_HOST_MEMORY);
+		ecdsaStatus = SECFailure;
+		rv = CKR_HOST_MEMORY;
+		goto loser;
+	}
 
 	SHA1Init(sha1_context);
 
@@ -177,8 +186,21 @@
 	    &digest, 0);
 
 loser:
+	if (ecdsa_public_key.publicValue.data != NULL)
+		free_ecpubkey(&ecdsa_public_key);
+	if (ecdsa_private_key != NULL)
+		free_ecprivkey(ecdsa_private_key);
+	free_ecparams(ecparams, B_TRUE);
+
+	if (sha1_context != NULL)
+#ifdef _KERNEL
+		kmem_free(sha1_context, sizeof (SHA1_CTX));
+#else
+		free(sha1_context);
+#endif
+
 	if (ecdsaStatus != SECSuccess) {
-		return (CKR_DEVICE_ERROR);
+		return (rv);
 	}
 
 	return (CKR_OK);
@@ -218,3 +240,43 @@
 
 	return (CKR_OK);
 }
+
+static void
+free_ecparams(ECParams *params, boolean_t freeit)
+{
+	SECITEM_FreeItem(&params->fieldID.u.prime, B_FALSE);
+	SECITEM_FreeItem(&params->curve.a, B_FALSE);
+	SECITEM_FreeItem(&params->curve.b, B_FALSE);
+	SECITEM_FreeItem(&params->curve.seed, B_FALSE);
+	SECITEM_FreeItem(&params->base, B_FALSE);
+	SECITEM_FreeItem(&params->order, B_FALSE);
+	SECITEM_FreeItem(&params->DEREncoding, B_FALSE);
+	SECITEM_FreeItem(&params->curveOID, B_FALSE);
+	if (freeit)
+#ifdef _KERNEL
+		kmem_free(params, sizeof (ECParams));
+#else
+		free(params);
+#endif
+}
+
+static void
+free_ecprivkey(ECPrivateKey *key)
+{
+	free_ecparams(&key->ecParams, B_FALSE);
+	SECITEM_FreeItem(&key->publicValue, B_FALSE);
+	bzero(key->privateValue.data, key->privateValue.len);
+	SECITEM_FreeItem(&key->privateValue, B_FALSE);
+	SECITEM_FreeItem(&key->version, B_FALSE);
+#ifdef _KERNEL
+	kmem_free(key, sizeof (ECPrivateKey));
+#else
+	free(key);
+#endif
+}
+
+static void
+free_ecpubkey(ECPublicKey *key)
+{
+	free_ecparams(&key->ecParams, B_FALSE);
+}
--- a/usr/src/common/crypto/fips/fips_rsa_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/common/crypto/fips/fips_rsa_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -399,6 +399,11 @@
 		(void) memcpy(der_data, der_prefix, der_len);
 		(void) memcpy(der_data + der_len, hash, hash_len);
 		der_data_len = der_len + hash_len;
+#ifdef _KERNEL
+		kmem_free(sha1_context, sizeof (SHA1_CTX));
+#else
+		free(sha1_context);
+#endif
 		break;
 	}
 
--- a/usr/src/common/crypto/fips/fips_sha1_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/common/crypto/fips/fips_sha1_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -86,6 +86,8 @@
 fips_sha1_hash(SHA1_CTX *sha1_context, uchar_t *in, ulong_t inlen, uchar_t *out)
 {
 
+	int rv;
+
 	if (in != NULL) {
 #ifdef	__sparcv9
 		SHA1Update((SHA1_CTX *)sha1_context, in, (uint_t)inlen);
@@ -93,10 +95,17 @@
 		SHA1Update((SHA1_CTX *)sha1_context, in, inlen);
 #endif	/* __sparcv9 */
 		SHA1Final(out, (SHA1_CTX *)sha1_context);
-		return (CKR_OK);
+		rv = CKR_OK;
 	} else
-		return (CKR_ARGUMENTS_BAD);
+		rv = CKR_ARGUMENTS_BAD;
 
+	if (sha1_context)
+#ifdef _KERNEL
+		kmem_free(sha1_context, sizeof (SHA1_CTX));
+#else
+		free(sha1_context);
+#endif
+	return (rv);
 }
 
 
@@ -246,6 +255,7 @@
 	 */
 	SHA1Final(hmac_computed, &((sha1_hmac_ctx)->hc_ocontext));
 
+	kmem_free(sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
 }
 
 #endif
--- a/usr/src/common/crypto/fips/fips_sha2_util.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/common/crypto/fips/fips_sha2_util.c	Thu Nov 05 21:57:36 2009 -0800
@@ -121,13 +121,24 @@
 	ulong_t inlen, uchar_t *out)
 {
 
+	int rv;
+
 	if (in != NULL) {
 		SHA2Update((SHA2_CTX *)sha2_context, in, inlen);
 		SHA2Final(out, (SHA2_CTX *)sha2_context);
-		return (CKR_OK);
+		rv = CKR_OK;
 	} else {
-		return (CKR_ARGUMENTS_BAD);
+		rv = CKR_ARGUMENTS_BAD;
 	}
+
+	if (sha2_context)
+#ifdef _KERNEL
+		kmem_free(sha2_context, sizeof (SHA2_CTX));
+#else
+		free(sha2_context);
+#endif
+	return (rv);
+
 }
 
 #ifndef _KERNEL
@@ -376,6 +387,8 @@
 	}
 
 	SHA2Final(hmac_computed, &((sha2_hmac_ctx)->hc_ocontext));
+
+	kmem_free(sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
 }
 
 #endif
--- a/usr/src/lib/libcryptoutil/common/config_parsing.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/lib/libcryptoutil/common/config_parsing.c	Thu Nov 05 21:57:36 2009 -0800
@@ -33,6 +33,7 @@
 
 static int uef_interpret(char *, uentry_t **);
 static int parse_policylist(char *, uentry_t *);
+static boolean_t is_fips(char *);
 
 /*
  * Retrieve the user-level provider info from the pkcs11.conf file.
@@ -103,6 +104,35 @@
 	return (rc);
 }
 
+static int
+parse_fips_mode(char *buf, boolean_t *mode)
+{
+	char *value;
+
+	if (strncmp(buf, EF_FIPS_STATUS, sizeof (EF_FIPS_STATUS) - 1) == 0) {
+		if (value = strpbrk(buf, SEP_EQUAL)) {
+			value++; /* get rid of = */
+			if (strcmp(value, DISABLED_KEYWORD) == 0) {
+				*mode = B_FALSE;
+			} else if (strcmp(value, ENABLED_KEYWORD) == 0) {
+				*mode = B_TRUE;
+			} else {
+				cryptoerror(LOG_ERR, gettext(
+				    "Failed to parse pkcs11.conf file.\n"));
+				return (CKR_FUNCTION_FAILED);
+			}
+			return (CKR_OK);
+		} else {
+			return (CKR_FUNCTION_FAILED);
+		}
+	} else {
+		/* should not come here */
+		cryptoerror(LOG_ERR, gettext(
+		    "Failed to parse pkcs11.conf file.\n"));
+		return (CKR_FUNCTION_FAILED);
+	}
+
+}
 
 /*
  * This routine converts a char string into a uentry_t structure
@@ -147,6 +177,18 @@
 		return (FAILURE);
 	}
 	(void) strlcpy(pent->name, token1, sizeof (pent->name));
+
+	if (is_fips(token1)) {
+		if ((rc = parse_fips_mode(buf + strlen(token1) + 1,
+		    &pent->flag_fips_enabled)) != SUCCESS) {
+			free_uentry(pent);
+			return (rc);
+		}
+
+		*ppent = pent;
+		return (SUCCESS);
+	}
+
 	/*
 	 * in case metaslot_auto_key_migrate is not specified, it should
 	 * be default to true
@@ -444,6 +486,7 @@
 		(void) memcpy(puent2->metaslot_ks_token,
 		    puent1->metaslot_ks_token, TOKEN_LABEL_SIZE);
 		puent2->count = puent1->count;
+		puent2->flag_fips_enabled = puent1->flag_fips_enabled;
 		return (puent2);
 	}
 }
@@ -547,35 +590,6 @@
 	return (rc);
 }
 
-static CK_RV
-parse_fips_mode(char *buf, int *mode)
-{
-
-	char *value;
-
-	if (strncmp(buf, EF_FIPS_STATUS, sizeof (EF_FIPS_STATUS) - 1) == 0) {
-		if (value = strpbrk(buf, SEP_EQUAL)) {
-			value++; /* get rid of = */
-			if (strcmp(value, DISABLED_KEYWORD) == 0) {
-				*mode = CRYPTO_FIPS_MODE_DISABLED;
-			} else if (strcmp(value, ENABLED_KEYWORD) == 0) {
-				*mode = CRYPTO_FIPS_MODE_ENABLED;
-			} else {
-				cryptoerror(LOG_ERR,
-				    "failed to parse kcf.conf file.\n");
-				return (CKR_FUNCTION_FAILED);
-			}
-			return (CKR_OK);
-		} else {
-			return (CKR_FUNCTION_FAILED);
-		}
-	} else {
-		/* should not come here */
-		return (CKR_FUNCTION_FAILED);
-	}
-
-}
-
 static boolean_t
 is_fips(char *name)
 {
@@ -595,10 +609,11 @@
 	CK_RV	rc = CKR_OK;
 	int found = 0;
 	char *token1;
+	boolean_t fips_mode = B_FALSE;
 
-	if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) {
+	if ((pfile = fopen(_PATH_PKCS11_CONF, "r")) == NULL) {
 		cryptoerror(LOG_DEBUG,
-		    "failed to open the kcf.conf file for read only.");
+		    "failed to open the pkcs11.conf file for read only.");
 		*mode = CRYPTO_FIPS_MODE_DISABLED;
 		return (CKR_OK);
 	}
@@ -623,10 +638,14 @@
 
 		if (is_fips(token1)) {
 			if ((rc = parse_fips_mode(buffer + strlen(token1) + 1,
-			    mode)) != CKR_OK) {
+			    &fips_mode)) != CKR_OK) {
 				goto out;
 			} else {
 				found++;
+				if (fips_mode == B_TRUE)
+					*mode = CRYPTO_FIPS_MODE_ENABLED;
+				else
+					*mode = CRYPTO_FIPS_MODE_DISABLED;
 				break;
 			}
 		} else {
--- a/usr/src/lib/libcryptoutil/common/cryptoutil.h	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/lib/libcryptoutil/common/cryptoutil.h	Thu Nov 05 21:57:36 2009 -0800
@@ -106,6 +106,7 @@
 	CK_UTF8CHAR	metaslot_ks_slot[SLOT_DESCRIPTION_SIZE + 1];
 	CK_UTF8CHAR	metaslot_ks_token[TOKEN_LABEL_SIZE + 1];
 	int 		count;
+	boolean_t	flag_fips_enabled;
 } uentry_t;
 
 typedef struct uentrylist {
--- a/usr/src/lib/pkcs11/libpkcs11/common/pkcs11Conf.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/lib/pkcs11/libpkcs11/common/pkcs11Conf.c	Thu Nov 05 21:57:36 2009 -0800
@@ -492,6 +492,15 @@
 			goto contparse;
 		}
 
+		if (!strcasecmp(phead->puent->name, FIPS_KEYWORD)) {
+			/*
+			 * Skip standard processing for fips-140
+			 * entry since it is not an actual library
+			 * that can be dlopened.
+			 */
+			goto contparse;
+		}
+
 		/* Check for Instruction Set Architecture indicator */
 		if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) {
 			/* Substitute the architecture dependent path */
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c	Fri Nov 06 13:10:19 2009 +0800
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c	Thu Nov 05 21:57:36 2009 -0800
@@ -259,6 +259,7 @@
 	else
 		rv = CKR_FUNCTION_FAILED;
 clean1:
+	free(sha1_context);
 	return (rv);
 }
 
@@ -366,6 +367,7 @@
 clean6:
 	DSA_key_finish(&dsakey);
 clean1:
+	free(sha1_context);
 	return (rv);
 }
 
@@ -484,7 +486,7 @@
 	if ((rv != CKR_OK) ||
 	    (memcmp(dsa_computed_signature, dsa_known_signature,
 	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
-		return (rv);
+		goto clean;
 	}
 
 	/*
@@ -495,6 +497,10 @@
 	rv = fips_dsa_verify(&dsa_params, &dsa_public_key,
 	    dsa_known_digest, dsa_computed_signature);
 
+clean:
+	free(dsa_private_key.key);
+	free(dsa_public_key.key);
+
 	if (rv != CKR_OK)
 		return (CKR_DEVICE_ERROR);
 	else