Blame misc/mech_list.c

Packit 8681c6
/*
Packit 8681c6
 * COPYRIGHT (c) International Business Machines Corp. 2005-2017
Packit 8681c6
 *
Packit 8681c6
 * This program is provided under the terms of the Common Public License,
Packit 8681c6
 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
Packit 8681c6
 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
Packit 8681c6
 * found in the file LICENSE file or at
Packit 8681c6
 * https://opensource.org/licenses/cpl1.0.php
Packit 8681c6
 */
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * This is an example of how you might convert your library's internal
Packit 8681c6
 * mechanism descriptors into PKCS#11-compatible descriptors while
Packit 8681c6
 * generating a mechanism list for openCryptoki.
Packit 8681c6
 */
Packit 8681c6
Packit 8681c6
#include "mech_types.h"
Packit 8681c6
Packit 8681c6
#ifndef NULL
Packit 8681c6
#define NULL 0
Packit 8681c6
#endif
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Bogus internal data descriptors for various mechanisms.
Packit 8681c6
 */
Packit 8681c6
#define CUSTOM_MECH_TDES 1
Packit 8681c6
#define CUSTOM_MECH_BLOWFISH 2
Packit 8681c6
#define CUSTOM_MECH_RIPEMD160 3
Packit 8681c6
#define CUSTOM_MECH_DSA 4
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * An example of a library's way of representing a mechanism.
Packit 8681c6
 */
Packit 8681c6
struct custom_mech_descriptor {
Packit 8681c6
	int mech_type;
Packit 8681c6
	int min_key_size;
Packit 8681c6
	int max_key_size;
Packit 8681c6
	int is_hw_accelerated;
Packit 8681c6
	int support_encrypt;
Packit 8681c6
	int support_decrypt;
Packit 8681c6
	int support_digest;
Packit 8681c6
	int support_wrap;
Packit 8681c6
	int support_unwrap;
Packit 8681c6
	int support_sign;
Packit 8681c6
	int support_verify;
Packit 8681c6
};
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Something like this should actually be filled in by querying the
Packit 8681c6
 * driver for what is available; if the library supports software
Packit 8681c6
 * fallback, then the CKF_HW flag should not be set so openCryptoki is
Packit 8681c6
 * aware of what really is hardware accelerated and what is not.
Packit 8681c6
 */
Packit 8681c6
struct custom_mech_descriptor library_specific_mechs[] = {
Packit 8681c6
	{CUSTOM_MECH_TDES, 24, 24, 1, 1, 1, 0, 1, 1, 0, 0},
Packit 8681c6
	{CUSTOM_MECH_BLOWFISH, 16, 16, 1, 1, 1, 0, 1, 1, 0, 0},
Packit 8681c6
	{CUSTOM_MECH_RIPEMD160, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
Packit 8681c6
	{CUSTOM_MECH_DSA, 512, 4096, 1, 0, 0, 0, 0, 0, 1, 1}
Packit 8681c6
};
Packit 8681c6
#define CUSTOM_MECH_ARRAY_SIZE 4
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Here is an example of how you might map your driver's type
Packit 8681c6
 * descriptors to the PKCS#11 type descriptors
Packit 8681c6
 */
Packit 8681c6
struct mech_type_mapping {
Packit 8681c6
	int internal_mech_type;
Packit 8681c6
	CK_MECHANISM_TYPE pkcs11_mech_type;
Packit 8681c6
};
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * The mapping from the internal driver type to the PKCS#11 type.
Packit 8681c6
 */
Packit 8681c6
struct mech_type_mapping mech_type_map[] = {
Packit 8681c6
	{CUSTOM_MECH_TDES, CKM_DES3_CBC},
Packit 8681c6
	{CUSTOM_MECH_BLOWFISH, CKM_VENDOR_DEFINED},
Packit 8681c6
	{CUSTOM_MECH_RIPEMD160, CKM_RIPEMD160},
Packit 8681c6
	{CUSTOM_MECH_DSA, CKM_DSA}
Packit 8681c6
};
Packit 8681c6
#define MECH_TYPE_MAP_SIZE 4
Packit 8681c6
Packit 8681c6
static CK_MECHANISM_TYPE pkcs11_mech_type_for_internal_type(int internal_type)
Packit 8681c6
{
Packit 8681c6
	int i = 0;
Packit 8681c6
	CK_MECHANISM_TYPE pkcs11_type = CKM_VENDOR_DEFINED;
Packit 8681c6
	while (i < MECH_TYPE_MAP_SIZE) {
Packit 8681c6
		if (mech_type_map[i].internal_mech_type == internal_type) {
Packit 8681c6
			pkcs11_type = mech_type_map[i].pkcs11_mech_type;
Packit 8681c6
			break;
Packit 8681c6
		}
Packit 8681c6
		i++;
Packit 8681c6
	}
Packit 8681c6
	return pkcs11_type;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Example method that converts a library's internal mechanism
Packit 8681c6
 * descriptor into a PKCS#11 mechanism descriptor. Yours may look very
Packit 8681c6
 * different from this one...
Packit 8681c6
 */
Packit 8681c6
static void convert_internal_element_to_pkcs11_method_element(
Packit 8681c6
	MECH_LIST_ELEMENT *element,
Packit 8681c6
	struct custom_mech_descriptor *internal_mech)
Packit 8681c6
{
Packit 8681c6
	element->mech_type =
Packit 8681c6
		pkcs11_mech_type_for_internal_type(internal_mech->mech_type);
Packit 8681c6
	element->mech_info.ulMinKeySize = internal_mech->min_key_size;
Packit 8681c6
	element->mech_info.ulMaxKeySize = internal_mech->max_key_size;
Packit 8681c6
	element->mech_info.flags = 0;
Packit 8681c6
	/* Partial example list of flags that could be set */
Packit 8681c6
	if (internal_mech->is_hw_accelerated) {
Packit 8681c6
		element->mech_info.flags |= CKF_HW;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_encrypt) {
Packit 8681c6
		element->mech_info.flags |= CKF_ENCRYPT;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_decrypt) {
Packit 8681c6
		element->mech_info.flags |= CKF_DECRYPT;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_digest) {
Packit 8681c6
		element->mech_info.flags |= CKF_DIGEST;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_wrap) {
Packit 8681c6
		element->mech_info.flags |= CKF_WRAP;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_unwrap) {
Packit 8681c6
		element->mech_info.flags |= CKF_UNWRAP;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_sign) {
Packit 8681c6
		element->mech_info.flags |= CKF_SIGN;
Packit 8681c6
	}
Packit 8681c6
	if (internal_mech->support_verify) {
Packit 8681c6
		element->mech_info.flags |= CKF_VERIFY;
Packit 8681c6
	}
Packit 8681c6
	/* ... */
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Generates a list of supported mechanisms. This is the function that
Packit 8681c6
 * openCryptoki will be calling directly with a pointer to a
Packit 8681c6
 * placeholder mech_list struct.
Packit 8681c6
 *
Packit 8681c6
 * @param head Pointer to placeholder mech_list struct; this function
Packit 8681c6
 *             fills in the list by tagging on newly malloc'd
Packit 8681c6
 *             mech_list structs off of this struct.
Packit 8681c6
 */
Packit 8681c6
void generate_pkcs11_mech_list(struct mech_list *head)
Packit 8681c6
{
Packit 8681c6
	struct mech_list *item;
Packit 8681c6
	int i = 0;
Packit 8681c6
	item = head;
Packit 8681c6
	while (i < CUSTOM_MECH_ARRAY_SIZE) {
Packit 8681c6
		item->next = malloc(sizeof(struct mech_list));
Packit 8681c6
		item = item->next;
Packit 8681c6
		convert_internal_element_to_pkcs11_method_element(
Packit 8681c6
			&item->element, &library_specific_mechs[i]);
Packit 8681c6
		i++;
Packit 8681c6
	}
Packit 8681c6
	item->next = NULL;
Packit 8681c6
	return;
Packit 8681c6
}