4947627 improve libcrypto string/mechanism conversion functions in edge cases
authorda73024
Wed, 02 Jul 2008 16:29:05 -0700
changeset 7011 536e17662ef1
parent 7010 827c1f26c430
child 7012 932cd76b5633
4947627 improve libcrypto string/mechanism conversion functions in edge cases 5031131 perf: pkcs11_kernel can benefit from a more efficient pkcs11_mech2str()
usr/src/cmd/cmd-crypto/cryptoadm/adm_metaslot.c
usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c
usr/src/lib/libcryptoutil/common/cryptoutil.h
usr/src/lib/libcryptoutil/common/mechstr.c
usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_metaslot.c	Wed Jul 02 13:50:00 2008 -0700
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_metaslot.c	Wed Jul 02 16:29:05 2008 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -169,7 +168,7 @@
 	/*
 	 * We know for sure that metaslot is slot 0 in the framework,
 	 * so, we will do a C_GetSlotInfo() trying to see if it works.
-	 * If it failes with CKR_SLOT_ID_INVALID, we know that metaslot
+	 * If it fails with CKR_SLOT_ID_INVALID, we know that metaslot
 	 * is not really enabled.
 	 */
 	rv = funcs->C_GetSlotInfo(METASLOT_ID, &slot_info);
@@ -284,11 +283,18 @@
 	}
 
 	for (i = 0; i < mech_count; i++) {
-		(void) printf("%-29s", pkcs11_mech2str(pmech_list[i]));
+		CK_MECHANISM_TYPE	mech = pmech_list[i];
+
+		if (mech > CKM_VENDOR_DEFINED) {
+			(void) printf("%#lx", mech);
+		} else {
+			(void) printf("%-29s", pkcs11_mech2str(mech));
+		}
+
 		if (verbose) {
 			CK_MECHANISM_INFO mech_info;
 			rv = funcs->C_GetMechanismInfo(METASLOT_ID,
-			    pmech_list[i], &mech_info);
+			    mech, &mech_info);
 			if (rv != CKR_OK) {
 				cryptodebug("C_GetMechanismInfo failed with "
 				    "error code 0x%x\n", rv);
--- a/usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c	Wed Jul 02 13:50:00 2008 -0700
+++ b/usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c	Wed Jul 02 16:29:05 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -115,31 +115,31 @@
 display_mech_info(CK_MECHANISM_INFO *mechInfo)
 {
 	CK_FLAGS ec_flags = CKF_EC_F_P | CKF_EC_F_2M | CKF_EC_ECPARAMETERS |
-		CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS | CKF_EC_COMPRESS;
+	    CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS | CKF_EC_COMPRESS;
 
 	(void) printf("%-4ld %-4ld ", mechInfo->ulMinKeySize,
-		mechInfo->ulMaxKeySize);
+	    mechInfo->ulMaxKeySize);
 	(void) printf("%s  %s  %s  %s  %s  %s  %s  %s  %s  %s  %s  %s  "
-		"%s  %s",
-		(mechInfo->flags & CKF_HW) ? "X" : ".",
-		(mechInfo->flags & CKF_ENCRYPT) ? "X" : ".",
-		(mechInfo->flags & CKF_DECRYPT) ? "X" : ".",
-		(mechInfo->flags & CKF_DIGEST) ? "X" : ".",
-		(mechInfo->flags & CKF_SIGN) ? "X" : ".",
-		(mechInfo->flags & CKF_SIGN_RECOVER) ? "X" : ".",
-		(mechInfo->flags & CKF_VERIFY) ? "X" : ".",
-		(mechInfo->flags & CKF_VERIFY_RECOVER) ? "X" : ".",
-		(mechInfo->flags & CKF_GENERATE) ? "X" : ".",
-		(mechInfo->flags & CKF_GENERATE_KEY_PAIR) ? "X" : ".",
-		(mechInfo->flags & CKF_WRAP) ? "X" : ".",
-		(mechInfo->flags & CKF_UNWRAP) ? "X" : ".",
-		(mechInfo->flags & CKF_DERIVE) ? "X" : ".",
-		(mechInfo->flags & ec_flags) ? "X" : ".");
+	    "%s  %s",
+	    (mechInfo->flags & CKF_HW) ? "X" : ".",
+	    (mechInfo->flags & CKF_ENCRYPT) ? "X" : ".",
+	    (mechInfo->flags & CKF_DECRYPT) ? "X" : ".",
+	    (mechInfo->flags & CKF_DIGEST) ? "X" : ".",
+	    (mechInfo->flags & CKF_SIGN) ? "X" : ".",
+	    (mechInfo->flags & CKF_SIGN_RECOVER) ? "X" : ".",
+	    (mechInfo->flags & CKF_VERIFY) ? "X" : ".",
+	    (mechInfo->flags & CKF_VERIFY_RECOVER) ? "X" : ".",
+	    (mechInfo->flags & CKF_GENERATE) ? "X" : ".",
+	    (mechInfo->flags & CKF_GENERATE_KEY_PAIR) ? "X" : ".",
+	    (mechInfo->flags & CKF_WRAP) ? "X" : ".",
+	    (mechInfo->flags & CKF_UNWRAP) ? "X" : ".",
+	    (mechInfo->flags & CKF_DERIVE) ? "X" : ".",
+	    (mechInfo->flags & ec_flags) ? "X" : ".");
 }
 
 /*
  * Converts the provided list of mechanism names in their string format to
- * their corrsponding PKCS#11 mechanism IDs.
+ * their corresponding PKCS#11 mechanism IDs.
  *
  * The list of mechanism names to be converted is provided in the
  * "mlist" argument.  The list of converted mechanism IDs is returned
@@ -194,15 +194,15 @@
 	CK_ULONG	slot_count;
 	CK_ULONG	mech_count;
 	uentry_t	*puent = NULL;
-	boolean_t lib_initialized = B_FALSE;
-	void	*dldesc = NULL;
-	char	*dl_error;
-	char 	*mech_name;
-	char	*isa;
-	char	libpath[MAXPATHLEN];
-	char	buf[MAXPATHLEN];
-	int	i, j;
-	int	rc = SUCCESS;
+	boolean_t	lib_initialized = B_FALSE;
+	void		*dldesc = NULL;
+	char		*dl_error;
+	const char 	*mech_name;
+	char		*isa;
+	char		libpath[MAXPATHLEN];
+	char		buf[MAXPATHLEN];
+	int		i, j;
+	int		rc = SUCCESS;
 
 	if (libname == NULL) {
 		/* should not happen */
@@ -285,7 +285,7 @@
 	} else if (slot_count == 0) {
 		if (!no_warn)
 			(void) printf(gettext("%s: no slots presented.\n"),
-				libname);
+			    libname);
 		rc = SUCCESS;
 		goto clean_exit;
 	}
@@ -341,65 +341,65 @@
 			CK_TOKEN_INFO tokeninfo;
 
 			(void) printf(gettext("Description: %.64s\n"
-				"Manufacturer: %.32s\n"
-				"PKCS#11 Version: %d.%d\n"),
-				slotinfo.slotDescription,
-				slotinfo.manufacturerID,
-				prov_funcs->version.major,
-				prov_funcs->version.minor);
+			    "Manufacturer: %.32s\n"
+			    "PKCS#11 Version: %d.%d\n"),
+			    slotinfo.slotDescription,
+			    slotinfo.manufacturerID,
+			    prov_funcs->version.major,
+			    prov_funcs->version.minor);
 
 			(void) printf(gettext("Hardware Version: %d.%d\n"
-				"Firmware Version: %d.%d\n"),
-				slotinfo.hardwareVersion.major,
-				slotinfo.hardwareVersion.minor,
-				slotinfo.firmwareVersion.major,
-				slotinfo.firmwareVersion.minor);
+			    "Firmware Version: %d.%d\n"),
+			    slotinfo.hardwareVersion.major,
+			    slotinfo.hardwareVersion.minor,
+			    slotinfo.firmwareVersion.major,
+			    slotinfo.firmwareVersion.minor);
 
 			(void) printf(gettext("Token Present: %s\n"),
-				(slotinfo.flags & CKF_TOKEN_PRESENT ?
-				gettext("True") : gettext("False")));
+			    (slotinfo.flags & CKF_TOKEN_PRESENT ?
+			    gettext("True") : gettext("False")));
 
 			display_slot_flags(slotinfo.flags);
 
 			rv = prov_funcs->C_GetTokenInfo(prov_slots[i],
-				&tokeninfo);
+			    &tokeninfo);
 			if (rv != CKR_OK) {
 				cryptodebug("Failed to get "
-					"token info from %s", libname);
+				    "token info from %s", libname);
 				rc = FAILURE;
 				break;
 			}
 
 			(void) printf(gettext("Token Label: %.32s\n"
-				"Manufacturer ID: %.32s\n"
-				"Model: %.16s\n"
-				"Serial Number: %.16s\n"
-				"Hardware Version: %d.%d\n"
-				"Firmware Version: %d.%d\n"
-				"UTC Time: %.16s\n"
-				"PIN Length: %d-%d\n"),
-				tokeninfo.label,
-				tokeninfo.manufacturerID,
-				tokeninfo.model,
-				tokeninfo.serialNumber,
-				tokeninfo.hardwareVersion.major,
-				tokeninfo.hardwareVersion.minor,
-				tokeninfo.firmwareVersion.major,
-				tokeninfo.firmwareVersion.minor,
-				tokeninfo.utcTime,
-				tokeninfo.ulMinPinLen,
-				tokeninfo.ulMaxPinLen);
+			    "Manufacturer ID: %.32s\n"
+			    "Model: %.16s\n"
+			    "Serial Number: %.16s\n"
+			    "Hardware Version: %d.%d\n"
+			    "Firmware Version: %d.%d\n"
+			    "UTC Time: %.16s\n"
+			    "PIN Length: %d-%d\n"),
+			    tokeninfo.label,
+			    tokeninfo.manufacturerID,
+			    tokeninfo.model,
+			    tokeninfo.serialNumber,
+			    tokeninfo.hardwareVersion.major,
+			    tokeninfo.hardwareVersion.minor,
+			    tokeninfo.firmwareVersion.major,
+			    tokeninfo.firmwareVersion.minor,
+			    tokeninfo.utcTime,
+			    tokeninfo.ulMinPinLen,
+			    tokeninfo.ulMaxPinLen);
 
 			display_token_flags(tokeninfo.flags);
 		}
 
 		if (mlist == NULL) {
 			rv = prov_funcs->C_GetMechanismList(prov_slots[i],
-				NULL_PTR, &mech_count);
+			    NULL_PTR, &mech_count);
 			if (rv != CKR_OK) {
 				cryptodebug(
-					"failed to call C_GetMechanismList() "
-					"from %s.", libname);
+				    "failed to call C_GetMechanismList() "
+				    "from %s.", libname);
 				rc = FAILURE;
 				break;
 			}
@@ -410,7 +410,7 @@
 			}
 
 			pmech_list = malloc(mech_count *
-					sizeof (CK_MECHANISM_TYPE));
+			    sizeof (CK_MECHANISM_TYPE));
 			if (pmech_list == NULL) {
 				cryptodebug("out of memory");
 				rc = FAILURE;
@@ -419,11 +419,11 @@
 
 			/* Get the actual mechanism list */
 			rv = prov_funcs->C_GetMechanismList(prov_slots[i],
-				pmech_list, &mech_count);
+			    pmech_list, &mech_count);
 			if (rv != CKR_OK) {
 				cryptodebug(
-					"failed to call C_GetMechanismList() "
-					"from %s.", libname);
+				    "failed to call C_GetMechanismList() "
+				    "from %s.", libname);
 				(void) free(pmech_list);
 				rc = FAILURE;
 				break;
@@ -446,12 +446,19 @@
 		 * mechanism list.
 		 */
 		for (j = 0; show_mechs && j < mech_count; j++) {
-			mech_name = pkcs11_mech2str(pmech_list[j]);
-			(void) printf("%-29s", mech_name);
+			CK_MECHANISM_TYPE	mech = pmech_list[j];
+
+			if (mech > CKM_VENDOR_DEFINED) {
+				(void) printf("%#lx", mech);
+			} else {
+				mech_name = pkcs11_mech2str(mech);
+				(void) printf("%-29s", mech_name);
+			}
+
 			if (verbose) {
 				CK_MECHANISM_INFO mech_info;
 				rv = prov_funcs->C_GetMechanismInfo(
-				    prov_slots[i], pmech_list[j], &mech_info);
+				    prov_slots[i], mech, &mech_info);
 				if (rv != CKR_OK) {
 					cryptodebug(
 					    "failed to call "
@@ -1114,9 +1121,9 @@
 int
 display_policy(uentry_t *puent)
 {
-	CK_MECHANISM_TYPE  mech_id;
-	char *mech_name;
-	umechlist_t *ptr;
+	CK_MECHANISM_TYPE	mech_id;
+	const char		*mech_name;
+	umechlist_t		*ptr;
 
 	if (puent == NULL) {
 		return (SUCCESS);
@@ -1136,12 +1143,16 @@
 					/* vendor defined mechanism */
 					(void) printf("%s", ptr->name);
 				} else {
-					mech_name = pkcs11_mech2str(mech_id);
-					if (mech_name == NULL) {
-						return (FAILURE);
+					if (mech_id > CKM_VENDOR_DEFINED) {
+						(void) printf("%#lx", mech_id);
+					} else {
+						mech_name = pkcs11_mech2str(
+						    mech_id);
+						if (mech_name == NULL) {
+							return (FAILURE);
+						}
+						(void) printf("%s", mech_name);
 					}
-					(void) printf("%s", mech_name);
-					free(mech_name);
 				}
 
 				ptr = ptr->next;
@@ -1171,7 +1182,6 @@
 						return (FAILURE);
 					}
 					(void) printf("%s", mech_name);
-					free(mech_name);
 				}
 				ptr = ptr->next;
 				if (ptr == NULL) {
@@ -1201,7 +1211,7 @@
 
 	rng_flag = NO_RNG;
 	if (list_mechlist_for_lib(puent->name, NULL, &rng_flag, B_TRUE,
-		B_FALSE, B_FALSE) != SUCCESS) {
+	    B_FALSE, B_FALSE) != SUCCESS) {
 		cryptoerror(LOG_STDERR,
 		    gettext("%s internal error."), puent->name);
 		return (FAILURE);
@@ -1298,7 +1308,7 @@
 		err = errno;
 		cryptoerror(LOG_STDERR,
 		    gettext("failed to update the configuration - %s"),
-			strerror(err));
+		    strerror(err));
 		(void) fclose(pfile);
 		return (FAILURE);
 	}
--- a/usr/src/lib/libcryptoutil/common/cryptoutil.h	Wed Jul 02 13:50:00 2008 -0700
+++ b/usr/src/lib/libcryptoutil/common/cryptoutil.h	Wed Jul 02 16:29:05 2008 -0700
@@ -114,7 +114,7 @@
 extern void cryptoerror(int priority, const char *fmt, ...);
 extern void cryptodebug_init(const char *prefix);
 
-extern char *pkcs11_mech2str(CK_MECHANISM_TYPE mech);
+extern const char *pkcs11_mech2str(CK_MECHANISM_TYPE mech);
 extern CK_RV pkcs11_str2mech(char *mech_str, CK_MECHANISM_TYPE_PTR mech);
 
 extern int get_pkcs11conf_info(uentrylist_t **);
--- a/usr/src/lib/libcryptoutil/common/mechstr.c	Wed Jul 02 13:50:00 2008 -0700
+++ b/usr/src/lib/libcryptoutil/common/mechstr.c	Wed Jul 02 16:29:05 2008 -0700
@@ -29,6 +29,7 @@
  * Convert Algorithm names as strings to PKCS#11 Mech numbers and vice versa.
  */
 
+#include <limits.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -41,10 +42,16 @@
  * This table is a one-to-one mapping between mechanism names and numbers.
  * As such, it should not contain deprecated mechanism names (aliases).
  */
-static const struct {
-	const char *str;
-	CK_MECHANISM_TYPE mech;
-} mapping[] = {
+typedef struct {
+	const char		*str;
+	CK_MECHANISM_TYPE	mech;
+} pkcs11_mapping_t;
+
+/*
+ * Note: elements in this table MUST be in numeric order,
+ * since bsearch(3C) is used to search this table.
+ */
+static const pkcs11_mapping_t mapping[] = {
 	{ "CKM_RSA_PKCS_KEY_PAIR_GEN", CKM_RSA_PKCS_KEY_PAIR_GEN },
 	{ "CKM_RSA_PKCS", CKM_RSA_PKCS },
 	{ "CKM_RSA_9796", CKM_RSA_9796 },
@@ -293,31 +300,52 @@
 	{ "CKM_DSA_PARAMETER_GEN", CKM_DSA_PARAMETER_GEN },
 	{ "CKM_DH_PKCS_PARAMETER_GEN", CKM_DH_PKCS_PARAMETER_GEN },
 	{ "CKM_X9_42_DH_PARAMETER_GEN", CKM_X9_42_DH_PARAMETER_GEN },
-	{ "CKM_VENDOR_DEFINED", CKM_VENDOR_DEFINED },
+	/*
+	 * Values above 0x8000000 (CKM_VENDOR_DEFINED) are represented
+	 * as strings with hexadecimal numbers (e.g., "0x8123456").
+	 */
 	{ NULL, 0 }
 };
 
+
+/*
+ * pkcs11_mech_comp - compare two pkcs11_mapping_t structures
+ *
+ * Return a strcmp-like result (positive, zero, or negative).
+ * For use with bsearch(3C) in pkcs11_mech2str().
+ */
+static int
+pkcs11_mech_comp(const void *mapping1, const void *mapping2) {
+	return (((pkcs11_mapping_t *)mapping1)->mech -
+		((pkcs11_mapping_t *)mapping2)->mech);
+}
+
+
 /*
  * pkcs11_mech2str - convert PKCS#11 mech to a string
  *
  * Anything below CKM_VENDOR_DEFINED that wasn't in the mapping table
  * at build time causes NULL to be returned.  Anything above it also
- * returns NULL since we have no way to know what its real name is.
+ * returns NULL since we have no way to know its real name.
  */
-char
+const char
 *pkcs11_mech2str(CK_MECHANISM_TYPE mech)
 {
-	int i;
-	char buf[11];	/* Num chars for representing ulong in ASCII */
+	pkcs11_mapping_t	target;
+	pkcs11_mapping_t	*result = NULL;
 
 	if (mech > CKM_VENDOR_DEFINED) {
-		(void) snprintf(buf, sizeof (buf), "%#lx", mech);
-		return (strdup(buf));
+		return (NULL);
 	}
 
-	for (i = 0; mapping[i].str; i++) {
-		if (mapping[i].mech == mech)
-			return (strdup(mapping[i].str));
+	/* Search for the mechanism number using bsearch(3C) */
+	target.mech = mech;
+	target.str = NULL;
+	result = (pkcs11_mapping_t *)bsearch((void *)&target, (void *)mapping,
+	    (sizeof (mapping) / sizeof (pkcs11_mapping_t)) - 1,
+	    sizeof (pkcs11_mapping_t), pkcs11_mech_comp);
+	if (result != NULL) {
+		return (result->str);
 	}
 
 	return (NULL);
@@ -326,46 +354,46 @@
 /*
  * pkcs11_str2mech - convert a string into a PKCS#11 mech number.
  *
- * Since there isn't reserved value for an invalid mech we return
+ * Since there isn't a reserved value for an invalid mech we return
  * CKR_MECHANISM_INVALID for anything we don't recognise.
  * The value in mech isn't meaningful in these cases.
  */
 CK_RV
 pkcs11_str2mech(char *mech_str, CK_MECHANISM_TYPE_PTR mech)
 {
-	int i;
-	char *tmech_str;
+	int	i;
+	int	compare_off = 0;
 
 	if (mech_str == NULL)
 		return (CKR_MECHANISM_INVALID);
 
-	if (strncasecmp(mech_str, "0x8", 3) == 0) {
+	if (strncasecmp(mech_str, "0x", 2) == 0) {
+		long long llnum;
 		cryptodebug("pkcs11_str2mech: hex string passed in: %s",
 		    mech_str);
-		*mech = strtoll(mech_str, NULL, 16);
-		return (CKR_OK);
+		llnum = strtoll(mech_str, NULL, 16);
+		if ((llnum >= CKM_VENDOR_DEFINED) && (llnum <= UINT_MAX)) {
+			*mech = llnum;
+			return (CKR_OK);
+		} else {
+			return (CKR_MECHANISM_INVALID);
+		}
 	}
 
+	/* If there's no CKM_ prefix, then ignore it in comparisons */
 	if (strncasecmp(mech_str, "CKM_", 4) != 0) {
-		size_t tmech_strlen = strlen(mech_str) + 4 + 1;
 		cryptodebug("pkcs11_str2mech: no CKM_ prefix: %s", mech_str);
-		tmech_str = malloc(tmech_strlen * sizeof (char));
-		(void) snprintf(tmech_str, tmech_strlen, "CKM_%s", mech_str);
-		cryptodebug("pkcs11_str2mech: with prefix: %s", tmech_str);
-	} else {
-		tmech_str = mech_str;
+		cryptodebug("pkcs11_str2mech: with prefix: CKM_%s", mech_str);
+		compare_off = 4;
 	}
 
+	/* Linear search for a matching string */
 	for (i = 0; mapping[i].str; i++) {
-		if (strcasecmp(mapping[i].str, tmech_str) == 0) {
+		if (strcasecmp(&mapping[i].str[compare_off], mech_str) == 0) {
 			*mech = mapping[i].mech;
-			if (tmech_str != mech_str)
-				free(tmech_str);
 			return (CKR_OK);
 		}
 	}
-	if (tmech_str != mech_str)
-		free(tmech_str);
 
 	return (CKR_MECHANISM_INVALID);
 }
--- a/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c	Wed Jul 02 13:50:00 2008 -0700
+++ b/usr/src/lib/pkcs11/pkcs11_kernel/common/kernelUtil.c	Wed Jul 02 16:29:05 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <stdio.h>
 #include <cryptoutil.h>
 #include <errno.h>
 #include <security/cryptoki.h>
@@ -192,11 +193,12 @@
 kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number)
 {
 	crypto_get_mechanism_number_t get_number;
-	char *string;
+	const char *string;
 	CK_RV rv;
 	int r;
 	kmh_elem_t *elem;
 	uint_t h;
+	char buf[11];   /* Num chars for representing ulong in ASCII */
 
 	/*
 	 * Search for an existing entry. No need to lock since we are
@@ -210,11 +212,17 @@
 		}
 	}
 
-	string = pkcs11_mech2str(type);
+	if (type > CKM_VENDOR_DEFINED) {
+		(void) snprintf(buf, sizeof (buf), "%#lx", type);
+		string = buf;
+	} else {
+		string = pkcs11_mech2str(type);
+	}
+
 	if (string == NULL)
 		return (CKR_MECHANISM_INVALID);
 
-	get_number.pn_mechanism_string = string;
+	get_number.pn_mechanism_string = (char *)string;
 	get_number.pn_mechanism_len = strlen(string) + 1;
 
 	while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER,
@@ -239,7 +247,6 @@
 		(void) kmech_hash_insert(type, *k_number);
 	}
 
-	free(string);
 	return (rv);
 }
 
@@ -1174,7 +1181,7 @@
  * Get the value of the CKA_PRIVATE attribute for the object just returned
  * from the HW provider.  This function will be called by any function
  * that creates a new object, because the CKA_PRIVATE value of an object is
- * token sepecific.  The CKA_PRIVATE attribute value of the new object will be
+ * token specific.  The CKA_PRIVATE attribute value of the new object will be
  * stored in the object structure in the library, which will be used later at
  * C_Logout to clean up all private objects.
  */
@@ -1221,12 +1228,20 @@
     CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags)
 {
 	crypto_get_provider_mechanism_info_t mechanism_info;
-	char *string;
+	const char *string;
 	CK_FLAGS flags, mi_flags;
 	CK_RV rv;
 	int r;
+	char buf[11];   /* Num chars for representing ulong in ASCII */
 
-	string = pkcs11_mech2str(type);
+	if (type > CKM_VENDOR_DEFINED) {
+		/* allocate/build a string containing the mechanism number */
+		(void) snprintf(buf, sizeof (buf), "%#lx", type);
+		string = buf;
+	} else {
+		string = pkcs11_mech2str(type);
+	}
+
 	if (string == NULL)
 		return (CKR_MECHANISM_INVALID);
 
@@ -1246,7 +1261,7 @@
 	}
 
 	if (rv != CKR_OK) {
-		goto out;
+		return (rv);
 	}
 
 	/*
@@ -1263,8 +1278,7 @@
 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC);
 
 	if (mi_flags == 0) {
-		rv = CKR_MECHANISM_INVALID;
-		goto out;
+		return (CKR_MECHANISM_INVALID);
 	}
 
 	if (rv == CKR_OK) {
@@ -1310,7 +1324,5 @@
 
 	}
 
-out:
-	free(string);
 	return (rv);
 }