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