summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com>2018-03-27 09:24:56 -0700
committerPramod <pramod.raghavendra.jayathirth@intel.com>2018-03-30 02:17:20 +0000
commit4ba28823277dd1d154e4a26f7eae440c40b1f9fd (patch)
tree6acf40941e2cb98670374be20279e18cc96b5c64
parent8a5b33a9ba846d785d244e29bc29a46f7be34928 (diff)
Adds the HardwareInfra layer in SoftHSM
This enables the support of multiple HSMs Issue-ID: AAF-200 Change-Id: I825a72a0bf46827ff3be0c0311085cf970b970a6 Signed-off-by: Pramod <pramod.raghavendra.jayathirth@intel.com>
-rw-r--r--SoftHSMv2/configure.ac1
-rw-r--r--SoftHSMv2/src/lib/HwInfra/HwInfra.c719
-rw-r--r--SoftHSMv2/src/lib/HwInfra/HwInfra.h87
-rw-r--r--SoftHSMv2/src/lib/HwInfra/Makefile.am16
-rwxr-xr-xSoftHSMv2/src/lib/HwInfra/README24
-rwxr-xr-xSoftHSMv2/src/lib/HwInfra/hwpluginif.h223
-rw-r--r--SoftHSMv2/src/lib/Makefile.am7
-rw-r--r--SoftHSMv2/src/lib/SoftHSM.cpp174
-rw-r--r--SoftHSMv2/src/lib/SoftHSM.h1
-rw-r--r--SoftHSMv2/src/lib/session_mgr/Session.cpp19
-rw-r--r--SoftHSMv2/src/lib/session_mgr/Session.h6
11 files changed, 1260 insertions, 17 deletions
diff --git a/SoftHSMv2/configure.ac b/SoftHSMv2/configure.ac
index 216dd46..eb95bdd 100644
--- a/SoftHSMv2/configure.ac
+++ b/SoftHSMv2/configure.ac
@@ -211,6 +211,7 @@ AC_CONFIG_FILES([
src/lib/slot_mgr/test/Makefile
src/lib/handle_mgr/Makefile
src/lib/handle_mgr/test/Makefile
+ src/lib/HwInfra/Makefile
src/lib/test/Makefile
src/lib/test/softhsm2.conf
src/lib/test/softhsm2-alt.conf
diff --git a/SoftHSMv2/src/lib/HwInfra/HwInfra.c b/SoftHSMv2/src/lib/HwInfra/HwInfra.c
new file mode 100644
index 0000000..528097d
--- /dev/null
+++ b/SoftHSMv2/src/lib/HwInfra/HwInfra.c
@@ -0,0 +1,719 @@
+/* Copyright 2018 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "HwInfra.h"
+#include "hwpluginif.h"
+
+#include "cryptoki.h"
+
+char hw_plugins_parent_dir[MAX_PARENT_PATH_NAME+1] = "";
+char *default_hw_plugin_parent_dir = "/tmp/hwparent/";
+void *g_dl_handle;
+SSHSM_HW_FUNCTIONS_t g_pluginfuncs;
+
+
+/**
+ Function name : prepareHWPlugin
+ Description: This function is expected to be called by C_Initialize
+ of softHSM. This function does following
+ -- Reads the parent directory entries
+ -- If the subdirectory entry starts with 'S', then it calls loadHWPlugin
+ -- if the loadHWPlugin returns failure, then it finds the next subdirectory
+ that start with 'S' and calls loadHWPlugin.
+**/
+
+int prepareHWPlugin()
+{
+ DIR *dirhandle;
+ struct dirent *entry;
+ int len;
+ char *env;
+ int ret_val = 0;
+
+ LOG("%s() called \n", __func__);
+ /** check if there is any envrionment variable defined to represent
+ ** hw plugin parent directory.
+ **/
+ env = getenv("SSHSM_HW_PLUGINS_PARENT_DIR");
+ if (env != NULL)
+ {
+ len = strlen(env);
+ if (len > MAX_PARENT_PATH_NAME)
+ {
+ LOG("SSHSM_HW_PLUGINS_PARENT_DIR environment is too long %d \n", len);
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + ENVIRONMENT_TOO_LONG);
+ }
+ strcpy(hw_plugins_parent_dir, env);
+ }
+ else
+ {
+ strcpy(hw_plugins_parent_dir, default_hw_plugin_parent_dir);
+ }
+
+ /**Read parent directory entries **/
+ ret_val = -1;
+ dirhandle = opendir (hw_plugins_parent_dir);
+ if (dirhandle != NULL)
+ {
+ int count = 0;
+ while (NULL != (entry = readdir (dirhandle)) )
+ {
+ count++;
+ /**Check if it is directory **/
+ if (entry->d_type == DT_DIR)
+ {
+ /** See if it starts with 'S' **/
+ if ((entry->d_name[0] == 'S') ||
+ (entry->d_name[0] == 's') )
+ {
+ /** Load plugin.so file if it exists in the subdirectory
+ load it and check whether the HW is present by calling
+ init function **/
+ ret_val = loadHWPlugin( hw_plugins_parent_dir,
+ entry->d_name);
+ if(ret_val == 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ LOG ("Couldn't open the directory \n");
+ return ret_val;
+ }
+
+ closedir(dirhandle);
+ return ret_val;
+}
+
+/**
+ Function name : loadHWPlugin
+ Description: It first checks whether there is plugin.so file, activate
+ directory and at least one key directory. if any of them not present, then
+ it returns error. If all three are present, then it calls
+ of softHSM. It calls HwPlugin_Initiate_Activate_and_load_key() function.
+**/
+
+int loadHWPlugin(char *parent_dir, char *pluginsubdir)
+{
+ char fullpath[256+1];
+ DIR *dirhandle;
+ struct dirent *entry;
+ char so_present, activate_dir_present, key_dir_present;
+ hwpluginentries_t *entries;
+ int ret_val = -1;
+
+ if (strlen(parent_dir) + strlen(pluginsubdir) > 256 )
+ {
+ LOG("hwpluing path is too long \n");
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ }
+
+ strcpy(fullpath, parent_dir);
+ strcat(fullpath, pluginsubdir);
+
+ dirhandle = opendir(fullpath);
+
+ entries = malloc(sizeof(hwpluginentries_t));
+ if (entries == NULL )
+ {
+ LOG("Could not allocate entries \n");
+ closedir(dirhandle);
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
+ }
+ memset(entries, 0, sizeof(hwpluginentries_t));
+
+ if (dirhandle != NULL)
+ {
+ so_present = 0;
+ activate_dir_present = 0;
+ key_dir_present = 0;
+ while (NULL != (entry = readdir (dirhandle)) )
+ {
+ /** Ensure that the directory has plugin.so file, activate directory,
+ ** at least one key directory
+ **/
+
+ if ((entry->d_type == DT_REG) &&
+ (strcmp(entry->d_name, "plugin.so") == 0))
+ {
+ so_present = 1;
+ if (strlen(fullpath) + strlen("/")+ strlen(entry->d_name) > 256)
+ {
+ LOG("plugin so path is too long \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ break;
+ }
+ strcpy(entries->so_full_path, fullpath);
+ strcat(entries->so_full_path, "/");
+ strcat(entries->so_full_path, entry->d_name);
+ }
+
+ if ((entry->d_type == DT_DIR) &&
+ (strcmp(entry->d_name, "activate") == 0 ))
+ {
+ activate_dir_present = 1;
+ if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
+ {
+ LOG("activate path is too long \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ break;
+ }
+ strcpy(entries->activate_dir_full_path, fullpath);
+ strcat(entries->activate_dir_full_path, "/");
+ strcat(entries->activate_dir_full_path, entry->d_name);
+ strcat(entries->activate_dir_full_path, "/");
+ }
+
+ if ((entry->d_type == DT_DIR) &&
+ (strncmp(entry->d_name, "key", 3) == 0 ))
+ {
+ key_dir_present = 1;
+ if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
+ {
+ LOG("activate path is too long \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ break;
+ }
+ strcpy(entries->key_dir_full_path[entries->num_key_dirs],
+ fullpath);
+ strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
+ strcat(entries->key_dir_full_path[entries->num_key_dirs],
+ entry->d_name);
+ strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
+ entries->num_key_dirs++;
+ }
+
+ if (so_present && activate_dir_present && key_dir_present)
+ {
+ printf("so dir path: %s \n", entries->so_full_path);
+ printf("activate dir path: %s \n", entries->activate_dir_full_path);
+ ret_val = HwPlugin_Initiate_Activate_and_load_keys(entries);
+ break;
+ }
+ }
+
+ if (!so_present || !activate_dir_present || !key_dir_present)
+ {
+ LOG("Minimum set of entries not present hwplugin dir plugindir %s so_present %d activate present %d key present %d \n", fullpath, so_present, activate_dir_present, key_dir_present);
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + INCOMPLETE_PLUGIN_DIR);
+ }
+ }
+ else
+ {
+ LOG("Could not open hwplugin directory %s \n", fullpath);
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
+ }
+ free(entries);
+ closedir(dirhandle);
+ return(ret_val);
+}
+
+
+/**
+** Function name: HWPlugin_Initiate_Activate_and_load_keys
+** Description: This function loads plugin, gets the function pointers,
+** activates the plugin and then finally loads the keys
+**/
+int HwPlugin_Initiate_Activate_and_load_keys(hwpluginentries_t *entries)
+{
+ int ret_val;
+
+ ret_val = load_hw_plugin_and_get_function_pointers(entries->so_full_path,
+ &g_pluginfuncs);
+ if(ret_val != 0)
+ return(ret_val);
+
+ ret_val = init_hw_plugin(&g_pluginfuncs);
+ if(ret_val != 0 )
+ return(ret_val);
+
+ ret_val = activate_hw_plugin(entries, &g_pluginfuncs);
+ if (ret_val != 0 )
+ return(ret_val);
+
+ ret_val = load_keys_in_hw_plugin(entries, &g_pluginfuncs);
+ if (ret_val != 0 )
+ return(ret_val);
+
+ return(0);
+}
+
+
+/**
+ Function name : load_hw_plugin_and_get_function_pointers
+**/
+
+int load_hw_plugin_and_get_function_pointers(char *so_path,
+ SSHSM_HW_FUNCTIONS_t *funcs)
+{
+ int (*functogetpluginfuncs)(SSHSM_HW_FUNCTIONS_t *fs);
+ int ret_val;
+
+ g_dl_handle = dlopen(so_path, RTLD_NOW);
+ if(g_dl_handle == NULL )
+ {
+ LOG("dlopen on %s failed: %s \n", so_path, dlerror());
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_OPEN_ERROR);
+ }
+
+ functogetpluginfuncs = NULL;
+ functogetpluginfuncs = dlsym(g_dl_handle,
+ "sshsm_hw_plugin_get_plugin_functions");
+
+ if (functogetpluginfuncs == NULL)
+ {
+ LOG("dlsym of sshsm_hw_plugin_get_plugin_functions : %s \n", dlerror() );
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_SYM_ERROR);
+ }
+
+ ret_val = functogetpluginfuncs(funcs);
+
+ return ret_val;
+}
+
+int init_hw_plugin(SSHSM_HW_FUNCTIONS_t *funcs)
+{
+ int ret_val;
+
+ ret_val = (funcs->xxx_init)();
+
+ if(ret_val != 0 )
+ {
+ LOG("HWPlugin init failed \n" );
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
+ }
+ return(ret_val);
+}
+
+
+int activate_hw_plugin(hwpluginentries_t *entries, SSHSM_HW_FUNCTIONS_t *funcs)
+{
+ int ret_val;
+
+ if( (entries == NULL) || (funcs == NULL) )
+ {
+ ret_val = -1;
+ LOG("activate_hw_plugin: Input values are NULL \n");
+ return ret_val;
+ }
+ /** Read all files starting with 'A' and pass the information to
+ ** plugin
+ **/
+
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
+
+ memset(&comp_buffers, 0, sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
+
+ ret_val = get_all_file_contents(entries->activate_dir_full_path, 'A',
+ &comp_buffers);
+
+ if (ret_val == 0 )
+ {
+ ret_val = (funcs->xxx_activate)(&comp_buffers);
+ //free_buffers(&comp_buffers);
+ }
+
+ return(ret_val);
+}
+
+
+int load_keys_in_hw_plugin(hwpluginentries_t *entries,
+ SSHSM_HW_FUNCTIONS_t *funcs)
+{
+
+ int ret_val;
+ void *key_handle;
+ int ii;
+ //unsigned long hwkeyhandle=987654321;
+ //key_handle = (void *) &hwkeyhandle;
+
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
+
+ /**
+ Travese through all key directories and load the key in plugin
+ **/
+
+ ret_val = -1;
+ for(ii = 0; ii < entries->num_key_dirs; ii++)
+ {
+ memset(&comp_buffers, 0,
+ sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
+
+ ret_val = get_all_file_contents(entries->key_dir_full_path[ii], 'K',
+ &comp_buffers);
+
+ if(ret_val == 0)
+ {
+ ret_val = (funcs->xxx_load_key)(&comp_buffers, &key_handle);
+ //free_buffers(&comp_buffers);
+ if(ret_val == 0)
+ {
+ /** Get PKCS11 information **/
+ /** Call SoftHSM functions to create private key object */
+ ret_val = program_pkcs11_info(entries->key_dir_full_path[ii], &key_handle);
+ }
+ }
+
+ }
+
+ return(0);
+}
+
+int get_all_file_contents(char *dirpath, char starting_char,
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
+{
+ DIR *dirhandle;
+ struct dirent *entry;
+
+ buffer_info_t *buffer;
+ char *token;
+
+ struct stat st;
+ int fd;
+
+ int ret_val = 0;
+
+
+ char fullpath[256+1];
+
+ dirhandle = opendir(dirpath);
+ if (dirhandle != NULL)
+ {
+ while (NULL != (entry = readdir (dirhandle)))
+ {
+ if ((entry->d_type == DT_REG) &&
+ (entry->d_name[0] == starting_char))
+ {
+ buffer = malloc(sizeof(buffer_info_t));
+ if (buffer == NULL )
+ {
+ LOG("Could not allocate entries \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
+ break;
+ }
+ token = strchr(entry->d_name, '.');
+ strcpy(buffer->id, token+1);
+
+ /** get full path of the file **/
+ if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
+ {
+ LOG("file path is too long \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ free(buffer);
+ break;
+ }
+ strcpy(fullpath,dirpath);
+ strcat(fullpath, entry->d_name);
+ stat(fullpath, &st);
+ buffer->buffer = malloc(st.st_size);
+ if(buffer->buffer == NULL)
+ {
+ LOG("Could not allocate entries \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
+ free(buffer);
+ break;
+ }
+ buffer->length_of_buffer = st.st_size;
+ fd = open(fullpath, O_RDONLY);
+ if (fd == -1 )
+ {
+ LOG("Could not open file %s \n", fullpath);
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
+ free(buffer->buffer);
+ free(buffer);
+ break;
+ }
+
+ if(read(fd, buffer->buffer, st.st_size) < 0)
+ {
+ LOG("Reading from file %s failed \n", fullpath);
+ continue;
+ }
+
+ close(fd);
+
+ /** Now write this buffer in c_buffers **/
+ c_buffers->buffer_info[c_buffers->num_buffers] = buffer;
+ c_buffers->num_buffers++;
+
+ }
+ }
+ }
+ else
+ {
+ LOG("Could not open hwplugin directory %s \n", dirpath);
+ return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
+ }
+
+ closedir(dirhandle);
+ //if (ret_val != 0 )
+ //free_buffers(c_buffers);
+
+ return(ret_val);
+}
+
+void free_buffers ( SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
+{
+ int ii;
+
+ for(ii = 0; ii < c_buffers->num_buffers; ii++)
+ {
+ free(c_buffers->buffer_info[ii]->buffer);
+ free(c_buffers->buffer_info[ii]);
+ }
+}
+
+int program_pkcs11_info (char *dirpath, void *key_handle)
+{
+ DIR *dirhandle;
+ struct dirent *entry;
+
+ char fullpath[256+1];
+ int ret_val = 0;
+
+ FILE *fp;
+ char buffer[80+1];
+
+ unsigned int slot_id = 0;
+ unsigned char upin[64+1];
+ int upin_len = 0;
+ unsigned char keyid[64+1];
+ int key_id_len = 0;
+ unsigned char key_label[64+1] = "";
+ char *valuep;
+ char *endvalue;
+
+
+ dirhandle = opendir(dirpath);
+ if (dirhandle != NULL)
+ {
+ while (NULL != (entry = readdir (dirhandle)))
+ {
+ if (strcmp(entry->d_name, "pkcs11.cfg") == 0 )
+ {
+ /** get full path of the file **/
+ if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
+ {
+ LOG("file path is too long \n");
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ break;
+ }
+ strcpy(fullpath,dirpath);
+ strcat(fullpath, entry->d_name);
+
+ fp = fopen(fullpath, "r");
+ if(fp == NULL )
+ {
+ ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
+ break;
+ }
+ while (fgets(buffer, 80, fp) != NULL)
+ {
+ valuep = strchr(buffer, ':');
+ if(valuep == NULL)
+ continue;
+ valuep[0] = '\0';
+
+ /** Looks like \n is part of buffer that is read via fgets
+ ** Replacce tha with 0 **/
+ endvalue = strchr(valuep+1, '\n');
+ if(endvalue != NULL)
+ endvalue[0] = '\0';
+ if (strcmp(buffer, "slot") == 0)
+ {
+ slot_id = strtoul(valuep+1, NULL, 10);
+ continue;
+ }
+ if(strcmp(buffer, "key_id") == 0 )
+ {
+ strcpy((char*)keyid, valuep+1);
+ key_id_len = strlen((char*)keyid);
+ continue;
+ }
+ if(strcmp(buffer, "key_label") == 0 )
+ {
+ strcpy((char*)key_label, valuep+1);
+ continue;
+ }
+ if(strcmp(buffer, "upin") == 0 )
+ {
+ strcpy((char*) upin, valuep+1);
+ upin_len = strlen((char *) upin);
+ continue;
+ }
+ }
+ fclose(fp);
+
+ /** Program key in SoftHSM **/
+ ret_val = PrepareKeyInSoftHSM(slot_id, upin, upin_len, keyid,
+ key_id_len, key_label, key_handle);
+
+ break;
+ }
+
+ }
+ }
+
+ return ret_val;
+}
+
+
+/*** PrepareKeyInSoftHSM
+** Description: It creates the object in softhsm with given key id and
+** key label and also stores the keyhandle that was returned by hardware plugin
+** Inputs:
+** - Slot ID
+** - Key ID
+** - Key Label
+** - upin
+** - pluginkeyHandle
+** Output:
+** - None
+** Renturs
+** - SUCCESS or FAILURE
+*****/
+int PrepareKeyInSoftHSM(unsigned int slot_id,
+ unsigned char *upin, int upin_len,
+ unsigned char *key_id, int key_id_len,
+ unsigned char *key_label, void *key_handle)
+{
+ CK_SESSION_HANDLE hSession;
+ CK_RV ret_val;
+ int ii;
+ CK_OBJECT_HANDLE hKey;
+ unsigned char key_handle_str[32] = {0};
+
+ printf ("slot %ul upin %s key_id %s key_label %s \n", slot_id, upin, key_id,
+ key_label);
+
+ if(!key_handle)
+ {
+ //ultoa((CK_ULONG)key_handle, key_handle_str, 16); // Linking error seen
+ printf("Key_handle to be stored: %lx \n", *((CK_ULONG *)key_handle) );
+ sprintf((char *) key_handle_str, "%lx", *((CK_ULONG *)key_handle));
+ }
+ else
+ {
+ printf("Input Key handle is NULL ! \n");
+ }
+
+ /** For creating the key object, first the session needs to be opened
+ C_OpenSession is used to open the session
+ **/
+ ret_val = C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION,
+ NULL_PTR, NULL_PTR, &hSession);
+
+ if (ret_val != CKR_OK)
+ {
+ printf("OpenSession failed for slot %x \n", slot_id);
+ return(ret_val);
+ }
+
+ /** Next step is login
+ ** C_Login is used to login to the session
+ **/
+ ret_val = C_Login(hSession, CKU_USER, upin, upin_len);
+ if (ret_val != CKR_OK)
+ {
+ printf("Login failed: 0x%lx | for slot %x upin below \n", ret_val, slot_id);
+ for (ii = 0; ii < upin_len; ii++ )
+ printf("%2x %c \n", upin[ii], upin[ii]);
+ return(ret_val);
+ }
+
+ CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
+ CK_KEY_TYPE keyType = CKK_RSA;
+ CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE ;
+
+ CK_ATTRIBUTE keyTemplate[] = {
+ { CKA_CLASS, &privClass, sizeof(privClass) },
+ { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
+ { CKA_LABEL, key_label, strlen((char *) key_label) },
+ { CKA_ID, key_id, (CK_ULONG)key_id_len },
+ { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
+ { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) },
+ { CKA_UNWRAP, &ckFalse, sizeof(ckFalse) },
+ { CKA_TOKEN, &ckTrue, sizeof(ckTrue) },
+ { CKA_PRIVATE, &ckTrue, sizeof(ckTrue) },
+ { CKA_EXTRACTABLE, &ckTrue, sizeof(ckTrue) },
+ { CKA_PUBLIC_EXPONENT, 0, 0},
+ { CKA_MODULUS, 0, 0},
+ { CKA_PRIVATE_EXPONENT, 0, 0},
+ { CKA_PRIME_2, 0, 0},
+ { CKA_EXPONENT_1, 0, 0},
+ { CKA_EXPONENT_2, 0, 0},
+ { CKA_COEFFICIENT, 0, 0},
+ { CKA_PRIME_1, key_handle_str, strlen((char *)key_handle_str) }
+ /** For now keep the key handle returned by Plugin in CK_PRIME_1.
+ ** TBD - Define new attribute to store this in future
+ ***/
+ };
+
+ ret_val = C_CreateObject(hSession, keyTemplate,
+ sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE),&hKey);
+ if (ret_val != CKR_OK)
+ {
+ printf("CreateObject failed: 0x%lx | for slot %x | keylabel %s | keyid below \n",
+ ret_val, slot_id, key_label);
+ for (ii = 0; ii < key_id_len; ii++ )
+ printf("%2x %c \n", key_id[ii], key_id[ii]);
+ //return(ret_val);
+ }
+
+ ret_val = C_Logout(hSession);
+ if (ret_val != CKR_OK)
+ {
+ printf("Logout failed 0x%lx | for slot %x \n", ret_val, slot_id);
+ return(ret_val);
+ }
+
+ ret_val = C_CloseSession(hSession);
+ if (ret_val != CKR_OK)
+ {
+ printf("C_CloseSession failed for slot %x \n", slot_id);
+ return(ret_val);
+ }
+
+ return ret_val;
+}
+
+int HwInfraSignInit(void *keyHandle, unsigned long mechanism,
+ void* param, int paramLen)
+{
+ return ( g_pluginfuncs.xxx_rsa_sign_init(keyHandle, mechanism, param, paramLen) );
+}
+
+int HwInfraSign( void *keyHandle, unsigned long mechanism,
+ unsigned char *msg, int msg_len,
+ unsigned char *outsig, int *outsiglen)
+{
+ return ( g_pluginfuncs.xxx_rsa_sign(keyHandle, mechanism, msg, msg_len,
+ outsig, outsiglen) );
+}
+
diff --git a/SoftHSMv2/src/lib/HwInfra/HwInfra.h b/SoftHSMv2/src/lib/HwInfra/HwInfra.h
new file mode 100644
index 0000000..a62bd7d
--- /dev/null
+++ b/SoftHSMv2/src/lib/HwInfra/HwInfra.h
@@ -0,0 +1,87 @@
+/* Copyright 2018 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "hwpluginif.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef __SSHSM_HW_INFRA_UTIL_H__
+#define __SSHSM_HW_INFRA_UTIL_H__
+
+#define MAX_KEY_DIRS_SUPPORTED 64
+
+typedef struct hwpluginentries_s {
+ char so_full_path[256+1];
+ char activate_dir_full_path[256+1];
+ int num_key_dirs;
+ char key_dir_full_path[MAX_KEY_DIRS_SUPPORTED][256+1];
+}hwpluginentries_t;
+
+int prepareHWPlugin();
+int loadHWPlugin(char *parent_dir, char *pluginsubdir);
+int HwPlugin_Initiate_Activate_and_load_keys( hwpluginentries_t *);
+int load_hw_plugin_and_get_function_pointers(char *,
+ SSHSM_HW_FUNCTIONS_t *funcs);
+int init_hw_plugin(SSHSM_HW_FUNCTIONS_t *funcs);
+int activate_hw_plugin(hwpluginentries_t *entries, SSHSM_HW_FUNCTIONS_t *funcs);
+int load_keys_in_hw_plugin(hwpluginentries_t *entries,
+ SSHSM_HW_FUNCTIONS_t *funcs);
+int get_all_file_contents(char *dirpath, char starting_char,
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers );
+
+void free_buffers ( SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers );
+int program_pkcs11_info (char *dirpath, void *key_handle);
+int PrepareKeyInSoftHSM(unsigned int slot_id,
+ unsigned char *upin, int upin_len,
+ unsigned char *key_id, int key_id_len,
+ unsigned char *key_label, void *key_handle);
+
+int HwInfraSignInit(void *keyHandle, unsigned long mechanism,
+ void* param, int paramLen);
+
+int HwInfraSign( void *keyHandle, unsigned long mechanism,
+ unsigned char *msg, int msg_len,
+ unsigned char *outsig, int *outsiglen);
+
+#define MAX_PARENT_PATH_NAME 256
+
+#define LOG printf
+#define SSHSM_HW_PLUGIN_ERROR_BASE (10000)
+
+#define ENVIRONMENT_TOO_LONG (01)
+#define PLUGIN_PATH_TOO_LONG (02)
+#define PLUGIN_PATH_OPEN_ERROR (03)
+#define INCOMPLETE_PLUGIN_DIR (04)
+#define ALLOCATION_ERROR (05)
+#define PLUGIN_DL_OPEN_ERROR (06)
+#define PLUGIN_DL_SYM_ERROR (07)
+#define PLUGIN_INIT_ERROR (10)
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* __SSHSM_HW_INFRA_UTIL_H__ */
+
+
diff --git a/SoftHSMv2/src/lib/HwInfra/Makefile.am b/SoftHSMv2/src/lib/HwInfra/Makefile.am
new file mode 100644
index 0000000..b327b15
--- /dev/null
+++ b/SoftHSMv2/src/lib/HwInfra/Makefile.am
@@ -0,0 +1,16 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(srcdir)/.. \
+ -I$(srcdir)/../common \
+ -I$(srcdir)/../crypto \
+ -I$(srcdir)/../data_mgr \
+ -I$(srcdir)/../object_store \
+ -I$(srcdir)/../pkcs11 \
+ -I$(srcdir)/../session_mgr
+
+noinst_LTLIBRARIES = libsofthsm_hwinfra.la
+libsofthsm_hwinfra_la_SOURCES = HwInfra.c
+
+SUBDIRS =
+
+EXTRA_DIST = $(srcdir)/*.h
diff --git a/SoftHSMv2/src/lib/HwInfra/README b/SoftHSMv2/src/lib/HwInfra/README
new file mode 100755
index 0000000..ea301af
--- /dev/null
+++ b/SoftHSMv2/src/lib/HwInfra/README
@@ -0,0 +1,24 @@
+/* Copyright 2018 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#Commands to build stub plugin
+gcc -fPIC -c tpmplugin_stub.c
+ld -shared -o plugin.so tpmplugin_stub.o
+
+#Commands to build hwinfra
+gcc -o hwinfrautil hwinfrautil.c -ldl
+
+
diff --git a/SoftHSMv2/src/lib/HwInfra/hwpluginif.h b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h
new file mode 100755
index 0000000..b078be3
--- /dev/null
+++ b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h
@@ -0,0 +1,223 @@
+/* Copyright 2018 Intel Corporation, Inc
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __SSHSM_HW_PLUGIN_IF_H__
+#define __SSHSM_HW_PLUGIN_IF_H__
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define MAX_ID_LENGTH (32)
+
+typedef struct buffer_info_s{
+ char id[MAX_ID_LENGTH+1];
+ int length_of_buffer;
+ unsigned char *buffer;
+ }buffer_info_t;
+
+/***
+ * Init Callback
+ * Description:
+ * This function is called by HWPluginInfra as part of C_Initialize to figure
+ * out whether there is any correspnding HW is present to use this plugin.
+ * In case of TPM2.0 Plugin,
+ * it is expected that this function checks
+ * whether the TPM2.0 is present or not, by checking the capabilities
+ * using Tss2_Sys_GetCapability with TPM_CAP_TPM_PROPERTIES and
+ * TPM_PT_MANUFACTURER property. If this function returns SUCCESS,
+ * TPM plguin can assume that TPM2.0 is presenta nd return success
+ * In case of SGX Plugin: <To be filled>
+ * Parameters:
+ * Inputs: None
+ * OUtputs; None
+ * Returns : SUCCESS (if HW is present), FAILURE if HW is not present
+ *
+ ***/
+typedef int (*sshsm_hw_plugin_init)();
+
+/***
+ * UnInit Callback
+ * Description: This function is called by HWPluginInfra during C_Finalize().
+ * This functin is gives chance for any cleanup by plugins.
+ ***/
+typedef int (*sshsm_hw_plugin_uninit)();
+
+
+/***
+ * Activate Callback
+ * Description: This callback function is called by HWPluginInfra
+ * (as part of C_Intialize) to activate the
+ * HW via HW plugin. SofHSM HWPluginInfra reads set of files required for
+ * activation (from
+ * activation directory) and passes them as buffers.
+ * HWPluginInfra reads the file in 'activate directory'
+ * as part of C_Initialize and passes the file content as is
+ * to the activate callback function.
+ * If there are two files, then num_buffers in in_info would be 2.
+ * 'id' is name of the file (May not be used by TPM plugin)
+ * 'length_of_buffer' is the valid length of the buffer.
+ * 'buffer' contains the file content.
+ * HWPluginInfra in SoftHSM allocates memory for this structure and internal
+ * buffers and it frees them up after this function returns. Hence,
+ * the plugin should not expect that these buffers are valid after the call
+ * is returned.
+ *
+ * In case of TPM Plugin:
+ * It is expected that activate directory has a file with SRK Handle
+ * saved in it. Note that SRK is saved in TPM memory (persistence)
+ * Actiate function of TPM plugin is called with SRK handle.
+ *
+ ***/
+#define MAX_BUFFER_SEGMENTS 8
+typedef struct sshsm_hw_plugin_activate_in_info_s {
+ int num_buffers;
+ buffer_info_t *buffer_info[MAX_BUFFER_SEGMENTS];
+}SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t;
+
+
+typedef int (*sshsm_hw_plugin_activate)(
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info
+ );
+
+
+
+/***
+ * Load Key Callback
+ * Description: This callback function is called by SoftHSM HWPluginInfra
+ * to load private keys into the HW using HW plugin.
+ * Each HW plugin expects the keys to be specific to its HW.
+ * Since SoftHSM HWPluginInfra is expected to be generic, the design
+ * chosen is that HWPluginInfra reads key content from files and pass
+ * that information to HW Plugins via this function pointer.
+ * Yet times, Key information for HW Plugins is exposed as multiple files.
+ * Hence, HWPluginInfra reads multiple files for each key. Since, there
+ * could be multiple keys, each set of files that correspond to one key
+ * is expected to have same file name, but with different extensions. Since
+ * the directory holding these file may also need to have other files
+ * related to key, but for PKCS11, it is expected that all HWPlugin related
+ * files should have its name start with HW.
+ *
+ * HWPluginInfra calls this callback function as many timne as number of
+ * distinct keys. For each distinct key, it reads the HW tagged files, loads
+ * them into the buffer pointers and calls the HW Plugin -loadkey- function.
+ * HWPluginInfra also stores the any returned buffers into the SoftHSM key
+ * object.
+ *
+ * In case of TPM Plugin, it does following:
+ *
+ * -- Gets the buffers in in_info structure.
+ * --- Typically, there are two buffers in TPM understandable way
+ * - public & private key portion
+ * --- From global variables, it knows SRKHandle, SAPI context.
+ * --- Using Tss2_Sys_Load(), it loads the key.
+ *
+ * -- In both cases, it also expected to return KeyHandle, which is
+ * keyObjectHandle in case of TPM.
+ *
+ *
+ ***/
+
+/***
+typedef struct sshsm_hw_plugin_load_key_in_info_s {
+ int num_buffers;
+ buffer_info_t buffer_info[];
+}SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t;
+***/
+
+
+typedef int (*sshsm_hw_plugin_load_key)(
+ SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
+ void **keyHandle
+ );
+
+typedef int (*sshsm_hw_plugin_unload_key)(
+ void **keyHandle
+ );
+
+
+
+/***
+ * Callback: RSA Sign Init
+ * Description: This is called by HWPluginInfra as part of C_SignInit function
+ * for RSA keys
+ */
+
+typedef int (*sshsm_hw_plugin_rsa_sign_init)(
+ void *keyHandle,
+ unsigned long mechanism,
+ void *param,
+ int len
+ );
+
+
+
+/***
+ * Callback: RSA Sign Init
+ * Description: This is called by HWPluginInfra as part of C_Sign function
+ * for RSA keys. HWPluginInfra get the keyHandle from the key object.
+ *
+ * In case of TPM plugin, it does following:
+ * -- TSS2_Sys_Sing function is called.
+ *
+ *
+ */
+
+typedef int (*sshsm_hw_plugin_rsa_sign)(
+ void *keyHandle,
+ unsigned long mechanism,
+ unsigned char *msg,
+ int msg_len,
+ unsigned char *outsig,
+ int *outsiglen
+ );
+
+/***
+ * Function Name: sshsm_hw_plugin_get_plugin_functions
+ * Descrpiton: Every HW plugin is expected to define this function.
+ * This function is expected to return its function as pointers to the
+ * caller.
+ * SoftHSM calls this function after loading the hw plugin .SO file.
+ * SoftHSM calls this function as part of C_initialize.
+ * Arugments:
+ * Outputs: funcs
+ * Inputs: None
+ * Return value: SUCCESS or FAILURE
+ *
+ ***/
+
+typedef struct sshsm_hw_functions_s
+{
+ sshsm_hw_plugin_init xxx_init;
+ sshsm_hw_plugin_uninit xxx_uninit;
+ sshsm_hw_plugin_activate xxx_activate;
+ sshsm_hw_plugin_load_key xxx_load_key;
+ sshsm_hw_plugin_unload_key xxx_unload_key;
+ sshsm_hw_plugin_rsa_sign_init xxx_rsa_sign_init;
+ sshsm_hw_plugin_rsa_sign xxx_rsa_sign;
+
+}SSHSM_HW_FUNCTIONS_t;
+
+
+int sshsm_hw_plugin_get_plugin_functions(SSHSM_HW_FUNCTIONS_t *funcs);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/SoftHSMv2/src/lib/Makefile.am b/SoftHSMv2/src/lib/Makefile.am
index c579d62..eac1704 100644
--- a/SoftHSMv2/src/lib/Makefile.am
+++ b/SoftHSMv2/src/lib/Makefile.am
@@ -8,6 +8,7 @@ AM_CPPFLAGS = -I$(srcdir)/common \
-I$(srcdir)/pkcs11 \
-I$(srcdir)/session_mgr \
-I$(srcdir)/slot_mgr \
+ -I$(srcdir)/HwInfra \
@CRYPTO_INCLUDES@
lib_LTLIBRARIES = libsofthsm2.la
@@ -23,7 +24,8 @@ libsofthsm2_la_LIBADD = common/libsofthsm_common.la \
handle_mgr/libsofthsm_handlemgr.la \
object_store/libsofthsm_objectstore.la \
session_mgr/libsofthsm_sessionmgr.la \
- slot_mgr/libsofthsm_slotmgr.la
+ slot_mgr/libsofthsm_slotmgr.la \
+ HwInfra/libsofthsm_hwinfra.la
libsofthsm2_la_LDFLAGS = -version-info @VERSION_INFO@ \
-avoid-version -module
@@ -42,8 +44,9 @@ SUBDIRS = common \
object_store \
session_mgr \
slot_mgr \
+ HwInfra \
handle_mgr \
test
EXTRA_DIST = $(srcdir)/*.h \
- $(srcdir)/pkcs11/*.h
+ $(srcdir)/pkcs11/*.h
diff --git a/SoftHSMv2/src/lib/SoftHSM.cpp b/SoftHSMv2/src/lib/SoftHSM.cpp
index 7a23a8a..214178f 100644
--- a/SoftHSMv2/src/lib/SoftHSM.cpp
+++ b/SoftHSMv2/src/lib/SoftHSM.cpp
@@ -67,6 +67,8 @@
#include "P11Objects.h"
#include "odd.h"
+#include "HwInfra.h"
+
#if defined(WITH_OPENSSL)
#include "OSSLCryptoFactory.h"
#else
@@ -101,6 +103,39 @@ std::auto_ptr<SoftHSM> SoftHSM::instance(NULL);
#endif
+static CK_RV Extract_key_handle(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, void *hwKeyHandle)
+{
+ CK_RV rv=CK_TRUE;
+
+ // get value of the hw key handle
+ CK_ATTRIBUTE valAttrib[] = {
+ {CKA_PRIME_1, NULL_PTR, 0}
+ };
+
+ // Get the length of the attribute first
+ rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE));
+ if(rv != CKR_OK)
+ {
+ printf("Getting length of keyHandle with C_GetAttributeValue() API failed ! \n");
+ return rv;
+ }
+
+ valAttrib[0].pValue = (CK_VOID_PTR) malloc(valAttrib[0].ulValueLen);
+
+ rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE));
+
+ // Convert the keyHandle from string to CK_ULONG
+ sscanf((char*) valAttrib[0].pValue, "%lx", (CK_ULONG *) hwKeyHandle);
+ printf("Extract_key_handle:: hwKeyHandle: %lu \n", (CK_ULONG) hwKeyHandle);
+
+ if(!(valAttrib[0].pValue))
+ {
+ free(valAttrib[0].pValue);
+ }
+
+ return rv;
+}
+
static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERTIFICATE_TYPE certType, P11Object **p11object)
{
switch(objClass) {
@@ -342,6 +377,7 @@ SoftHSM::SoftHSM()
slotManager = NULL;
sessionManager = NULL;
handleManager = NULL;
+ isHWavailable = false;
}
// Destructor
@@ -518,6 +554,17 @@ CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs)
// Set the state to initialised
isInitialised = true;
+ if(prepareHWPlugin())
+ {
+ printf("HW plugin NOT available to use ! \n");
+ isHWavailable = false;
+ }
+ else
+ {
+ printf("HW plugin available and initialized ! \n");
+ isHWavailable = true;
+ }
+
return CKR_OK;
}
@@ -4168,20 +4215,33 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
#endif
}
- // Initialize signing
- if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen))
- {
- asymCrypto->recyclePrivateKey(privateKey);
- CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
- return CKR_MECHANISM_INVALID;
- }
-
- // Check if re-authentication is required
- if (key->getBooleanValue(CKA_ALWAYS_AUTHENTICATE, false))
- {
- session->setReAuthentication(true);
- }
+ // Initialize signing
+ if(isHWavailable)
+ {
+ // Extract HW key handle
+ CK_ULONG hwKeyHandle = 0;
+ if(!Extract_key_handle (hSession, hKey, &hwKeyHandle))
+ {
+ LOG("ERROR in extracting key handle \n");
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+ LOG("Extracted key handle value: %lu \n", hwKeyHandle);
+ if(! HwInfraSignInit(&hwKeyHandle, mechanism, param, paramLen))
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+ }
+ else
+ {
+ if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen))
+ {
+ asymCrypto->recyclePrivateKey(privateKey);
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
+ return CKR_MECHANISM_INVALID;
+ }
+ }
session->setOpType(SESSION_OP_SIGN);
session->setAsymmetricCryptoOp(asymCrypto);
session->setMechanism(mechanism);
@@ -4189,6 +4249,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
session->setAllowMultiPartOp(bAllowMultiPartOp);
session->setAllowSinglePartOp(true);
session->setPrivateKey(privateKey);
+ session->setKeyHandle(hKey);
return CKR_OK;
}
@@ -4336,6 +4397,79 @@ static CK_RV AsymSign(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, C
return CKR_OK;
}
+// AsymmetricAlgorithm version of C_Sign
+static CK_RV AsymSignHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
+ AsymMech::Type mechanism = session->getMechanism();
+ PrivateKey* privateKey = session->getPrivateKey();
+ CK_ULONG hwKeyHandle = 0;
+ if (asymCrypto == NULL || !session->getAllowSinglePartOp() || privateKey == NULL)
+ {
+ session->resetOp();
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
+
+ // Size of the signature
+ CK_ULONG size = privateKey->getOutputLength();
+ if (pSignature == NULL_PTR)
+ {
+ *pulSignatureLen = size;
+ return CKR_OK;
+ }
+
+ // Check buffer sizeq
+ if (*pulSignatureLen < size)
+ {
+ *pulSignatureLen = size;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ // Get the data
+ ByteString data;
+
+ // We must allow input length <= k and therfore need to prepend the data with zeroes.
+ if (mechanism == AsymMech::RSA) {
+ data.wipe(size-ulDataLen);
+ }
+
+ data += ByteString(pData, ulDataLen);
+ ByteString signature;
+
+ // Extract HW key handle
+ CK_OBJECT_HANDLE hKey = session->getKeyHandle();
+ if(!Extract_key_handle (hSession, hKey, &hwKeyHandle))
+ {
+ LOG("ERROR in extracting key handle \n");
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+ LOG("Extracted key handle value: %lu \n", hwKeyHandle);
+
+ // Sign the data
+ if(!HwInfraSign((void *)&hwKeyHandle, mechanism,
+ pData, ulDataLen,
+ pSignature, (int *) pulSignatureLen))
+ {
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+
+ // Check size
+ if (*pulSignatureLen != size)
+ {
+ ERROR_MSG("The size of the signature differs from the size of the mechanism");
+ session->resetOp();
+ return CKR_GENERAL_ERROR;
+ }
+
+
+ session->resetOp();
+ return CKR_OK;
+}
+
+
+
// Sign the data in a single pass operation
CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
{
@@ -4356,8 +4490,18 @@ CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ul
return MacSign(session, pData, ulDataLen,
pSignature, pulSignatureLen);
else
- return AsymSign(session, pData, ulDataLen,
- pSignature, pulSignatureLen);
+ {
+ if(isHWavailable)
+ {
+ return AsymSignHW(hSession, session, pData, ulDataLen,
+ pSignature, pulSignatureLen);
+ }
+ else
+ {
+ return AsymSign(session, pData, ulDataLen,
+ pSignature, pulSignatureLen);
+ }
+ }
}
// MacAlgorithm version of C_SignUpdate
diff --git a/SoftHSMv2/src/lib/SoftHSM.h b/SoftHSMv2/src/lib/SoftHSM.h
index 70d497a..323f3a5 100644
--- a/SoftHSMv2/src/lib/SoftHSM.h
+++ b/SoftHSMv2/src/lib/SoftHSM.h
@@ -184,6 +184,7 @@ private:
// Is the SoftHSM PKCS #11 library initialised?
bool isInitialised;
bool isRemovable;
+ bool isHWavailable;
SessionObjectStore* sessionObjectStore;
ObjectStore* objectStore;
diff --git a/SoftHSMv2/src/lib/session_mgr/Session.cpp b/SoftHSMv2/src/lib/session_mgr/Session.cpp
index 5db36fd..54c0ff7 100644
--- a/SoftHSMv2/src/lib/session_mgr/Session.cpp
+++ b/SoftHSMv2/src/lib/session_mgr/Session.cpp
@@ -58,6 +58,9 @@ Session::Session(Slot* inSlot, bool inIsReadWrite, CK_VOID_PTR inPApplication, C
symmetricKey = NULL;
param = NULL;
paramLen = 0;
+
+ // Storing Key handle in session
+ hKey = CK_INVALID_HANDLE;
}
// Constructor
@@ -85,6 +88,9 @@ Session::Session()
symmetricKey = NULL;
param = NULL;
paramLen = 0;
+
+ // Storing Key handle in session
+ hKey = CK_INVALID_HANDLE;
}
// Destructor
@@ -93,6 +99,19 @@ Session::~Session()
resetOp();
}
+void Session::setKeyHandle(CK_OBJECT_HANDLE inHKey)
+{
+ //store the key hanldle for subsequent use
+ hKey = inHKey;
+}
+
+
+CK_OBJECT_HANDLE Session::getKeyHandle()
+{
+ //return the Key handle for subsequent use
+ return hKey;
+}
+
// Get session info
CK_RV Session::getInfo(CK_SESSION_INFO_PTR pInfo)
{
diff --git a/SoftHSMv2/src/lib/session_mgr/Session.h b/SoftHSMv2/src/lib/session_mgr/Session.h
index 142aaa5..128fb2b 100644
--- a/SoftHSMv2/src/lib/session_mgr/Session.h
+++ b/SoftHSMv2/src/lib/session_mgr/Session.h
@@ -124,6 +124,9 @@ public:
void setSymmetricKey(SymmetricKey* inSymmetricKey);
SymmetricKey* getSymmetricKey();
+ void setKeyHandle(CK_OBJECT_HANDLE inHKey);
+ CK_OBJECT_HANDLE getKeyHandle();
+
private:
// Constructor
Session();
@@ -170,6 +173,9 @@ private:
// Symmetric Crypto
SymmetricKey* symmetricKey;
+
+ // Storing Key handle in session
+ CK_OBJECT_HANDLE hKey;
};
#endif // !_SOFTHSM_V2_SESSION_H