4947627 improve libcrypto string/mechanism conversion functions in edge cases
5031131 perf: pkcs11_kernel can benefit from a more efficient pkcs11_mech2str()
--- 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);
}