pkcs11SUNWExtensions.c revision 17e2ff97562e18c6231f411e74f504236650a9a1
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Solaris specific functions to reduce the initialization
* overhead of using PKCS #11
*/
#include <stdlib.h>
#include <security/cryptoki.h>
#include <assert.h>
#include <cryptoutil.h>
#include <pkcs11Global.h>
#define NUM_SECRETKEY_ATTRS 12
typedef struct _ATTRTYPE_MECHINFO_MAPPING {
/* possible attribute types for creating key */
{CKA_VERIFY, CKF_VERIFY},
};
/*
* List of mechanisms that only supports asymmetric key operations
* in PKCS #11 V2.11
*/
};
typedef struct _KEY_TYPE_SIZE_MAPPING {
/*
* List of secret key types that have fixed sizes and their sizes.
* These key types do not allow CKA_VALUE_LEN for key generation.
* The sizes are in bytes.
*
* Discrete-sized keys, such as AES and Twofish, and variable sized
* keys, such as Blowfish, are not in this list.
*/
};
/*
* match_mech is an example of many possible criteria functions.
* It matches the given mech type (in args) with the slot's mech info.
* If no match is found, pkcs11_GetCriteriaSession is asked to return
* CKR_MECHANISM_INVALID.
*/
{
}
/*
* pkcs11_GetCriteriaSession will initialize the framework and do all
* the necessary work of calling C_GetSlotList(), C_GetMechanismInfo()
* C_OpenSession() to create a session that meets all the criteria in
* the given function pointer.
*
* The criteria function must return a boolean value of true or false.
* The arguments to the function are the current slot id, an opaque
* args value that is passed through to the function, and the error
* value pkcs11_GetCriteriaSession should return if no slot id meets the
* criteria.
*
* If the function is called multiple times, it will return a new session
* without reinitializing the framework.
*/
{
CK_ULONG i;
return (CKR_ARGUMENTS_BAD);
}
/* initialize PKCS #11 */
if (!pkcs11_initialized) {
(rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
return (rv);
}
}
/* get slot count */
return (rv);
}
if (slotcount == 0) {
return (CKR_FUNCTION_FAILED);
}
/* allocate memory for slot list */
return (CKR_HOST_MEMORY);
}
return (rv);
}
/* find slot with matching criteria */
for (i = 0; i < slotcount; i++) {
break;
}
}
if (i == slotcount) {
/* no matching slot found */
return (rv); /* this rv is from the criteria function */
}
return (rv);
}
/*
* SUNW_C_GetMechSession will initialize the framework and do all
* of the neccessary work of calling C_GetSlotList(), C_GetMechanismInfo()
* C_OpenSession() to create a session capable of providing the requested
* mechanism.
*
* If the function is called multiple times, it will return a new session
* without reinitializing the framework.
*/
{
/*
* All the code in this function can be replaced with one line:
*
* return (pkcs11_GetCriteriaSession(match_mech, (void *)mech,
* hSession));
*
*/
CK_ULONG i;
return (CKR_ARGUMENTS_BAD);
}
/* initialize PKCS #11 */
if (!pkcs11_initialized) {
(rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
return (rv);
}
}
/* get slot count */
return (rv);
}
if (slotcount == 0) {
return (CKR_FUNCTION_FAILED);
}
/* allocate memory for slot list */
return (CKR_HOST_MEMORY);
}
return (rv);
}
/* find slot with matching mechanism */
for (i = 0; i < slotcount; i++) {
/* found mechanism */
break;
}
}
if (i == slotcount) {
/* no matching mechanism found */
return (CKR_MECHANISM_INVALID);
}
return (rv);
}
/*
* SUNW_C_KeyToObject creates a secret key object for the given
* mechanism from the rawkey data.
*/
{
CK_ULONG i, j;
/* template for creating generic secret key object */
return (CKR_ARGUMENTS_BAD);
}
/*
* Check to make sure mechanism type is not for asymmetric key
* only operations. This function is only applicable to
* generating secret key.
*/
for (i = 0; i < num_asym_mechs; i++) {
if (mech == asymmetric_mechs[i]) {
return (CKR_MECHANISM_INVALID);
}
}
return (rv);
}
i = 0;
i++;
/* get the key type for this mechanism */
return (rv);
}
assert(i < NUM_SECRETKEY_ATTRS);
i++;
return (rv);
}
/* set the attribute type flag on object based on mechanism */
for (j = 0; j < num_mapping; j++) {
assert(i < NUM_SECRETKEY_ATTRS);
} else {
}
i++;
}
assert(i < NUM_SECRETKEY_ATTRS);
i++;
assert(i < NUM_SECRETKEY_ATTRS);
i++;
return (rv);
}
/*
* pkcs11_PasswdToPBKD2Object will create a secret key from the given string
* (e.g. passphrase) using PKCS#5 Password-Based Key Derivation Function 2
* (PBKD2).
*
* Session must be open. Salt and iterations use defaults.
*/
{
iterations == 0UL) {
return (CKR_ARGUMENTS_BAD);
}
/*
* Check to make sure key type is not asymmetric. This function
* is only applicable to generating secret key.
*/
for (i = 0; i < num_asym_mechs; i++) {
if (key_type == asym_key_type) {
return (CKR_KEY_TYPE_INCONSISTENT);
}
}
/*
* Key length must either be 0 or the correct size for PBKD of
* fixed-size secret keys. However, underlying key generation
* cannot have CKA_VALUE_LEN set for the key length attribute.
*/
sizeof (fixed_size_secrets) / sizeof (KEY_TYPE_SIZE_MAPPING);
for (i = 0; i < num_fixed_secs; i++) {
key_len = 0;
}
if (key_len == 0) {
break;
}
return (CKR_KEY_SIZE_RANGE);
}
}
params.saltSource = 0;
} else {
}
params.ulPrfDataLen = 0;
/*
* PKCS#11 spec error, ulPasswordLen should have been pulPasswordLen,
* or its type should have been CK_ULONG instead of CK_ULONG_PTR,
* but it's legacy now
*/
i = 0;
i++;
assert(i < NUM_SECRETKEY_ATTRS);
i++;
assert(i < NUM_SECRETKEY_ATTRS);
i++;
if (key_len != 0) {
assert(i < NUM_SECRETKEY_ATTRS);
i++;
}
/*
* C_GenerateKey may not implicitly set capability attributes,
* e.g. CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, ...
*/
for (j = 0; j < num_mapping; j++) {
assert(i < NUM_SECRETKEY_ATTRS);
&truevalue : &falsevalue;
i++;
}
return (rv);
}
/*
* pkcs11_ObjectToKey gets the rawkey data from a secret key object.
* The caller is responsible to free the allocated rawkey data.
*
* Optionally the object can be destroyed after the value is retrieved.
* As an example, after using pkcs11_PasswdToPBKD2Object() to create a
* secret key object from a passphrase, an app may call pkcs11_ObjectToKey
* to get the rawkey data. The intermediate object may no longer be needed
* and should be destroyed.
*/
{
*rawkey_len == 0) {
return (CKR_ARGUMENTS_BAD);
}
template.ulValueLen = 0;
/* First get the size of the rawkey */
return (rv);
}
return (CKR_HOST_MEMORY);
}
/* Then get the rawkey data */
return (rv);
}
if (destroy_obj) {
/*
* Could have asserted rv == CKR_OK, making threaded
* apps that share objects see stars. Here mercy is ok.
*/
}
return (CKR_OK);
}
/*
* pkcs11_PasswdToKey will create PKCS#5 PBKD2 rawkey data from the
* given passphrase. The caller is responsible to free the allocated
* rawkey data.
*/
{
&obj);
return (rv);
return (rv);
}