528097dcb39da7c05efafc1b3ef465659600db3d
[aaf/sshsm.git] / SoftHSMv2 / src / lib / HwInfra / HwInfra.c
1 /* Copyright 2018 Intel Corporation, Inc
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *       http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <dirent.h>
20 #include <string.h>
21 #include <dlfcn.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include "HwInfra.h"
26 #include "hwpluginif.h"
27
28 #include "cryptoki.h"
29
30 char hw_plugins_parent_dir[MAX_PARENT_PATH_NAME+1] = "";
31 char *default_hw_plugin_parent_dir = "/tmp/hwparent/";
32 void *g_dl_handle;
33 SSHSM_HW_FUNCTIONS_t g_pluginfuncs;
34
35
36 /**
37   Function name : prepareHWPlugin
38   Description:  This function is expected to be called by C_Initialize
39   of softHSM.  This function does following
40   -- Reads the parent directory entries
41   -- If the subdirectory entry starts with 'S', then it calls loadHWPlugin
42   -- if the loadHWPlugin returns failure, then it finds the next subdirectory
43      that start with 'S' and calls loadHWPlugin.
44 **/
45
46 int prepareHWPlugin()
47 {
48   DIR *dirhandle;
49   struct dirent *entry;
50   int len;
51   char *env;
52   int ret_val = 0;
53
54   LOG("%s() called \n", __func__);
55   /** check if there is any envrionment variable defined to represent
56    ** hw plugin parent directory.
57    **/
58   env = getenv("SSHSM_HW_PLUGINS_PARENT_DIR");
59   if (env != NULL)
60   {
61      len = strlen(env);
62      if (len > MAX_PARENT_PATH_NAME)
63      {
64         LOG("SSHSM_HW_PLUGINS_PARENT_DIR environment is too long %d \n", len);
65         return(SSHSM_HW_PLUGIN_ERROR_BASE + ENVIRONMENT_TOO_LONG);
66      }
67      strcpy(hw_plugins_parent_dir, env);
68   }
69   else
70   {
71      strcpy(hw_plugins_parent_dir, default_hw_plugin_parent_dir);
72   }
73
74   /**Read parent directory entries **/
75   ret_val = -1;
76   dirhandle = opendir (hw_plugins_parent_dir);
77   if (dirhandle != NULL)
78     {
79       int count = 0;
80       while (NULL != (entry = readdir (dirhandle)) )
81       {
82          count++;
83          /**Check if it is directory **/
84          if (entry->d_type == DT_DIR)
85          {
86              /** See if it starts with 'S' **/
87              if ((entry->d_name[0] == 'S') ||
88                  (entry->d_name[0] == 's') )
89              {
90                 /** Load plugin.so file if it exists in the subdirectory
91                     load it and check whether the HW is present by calling
92                     init function  **/
93                 ret_val = loadHWPlugin( hw_plugins_parent_dir,
94                                 entry->d_name);
95                 if(ret_val == 0)
96                 {
97                   break;
98                 }
99              }
100          }
101       }
102     }
103   else
104   {
105     LOG ("Couldn't open the directory \n");
106     return ret_val;
107   }
108
109   closedir(dirhandle);
110   return ret_val;
111 }
112
113 /**
114   Function name : loadHWPlugin
115   Description:  It first checks whether there is plugin.so file, activate
116   directory and at least one key directory. if any of them not present, then
117   it returns error.  If all three are present, then it calls
118   of softHSM.  It calls HwPlugin_Initiate_Activate_and_load_key() function.
119 **/
120
121 int loadHWPlugin(char *parent_dir, char *pluginsubdir)
122 {
123    char fullpath[256+1];
124    DIR *dirhandle;
125    struct dirent *entry;
126    char so_present, activate_dir_present, key_dir_present;
127    hwpluginentries_t *entries;
128    int ret_val = -1;
129
130    if (strlen(parent_dir) + strlen(pluginsubdir) > 256 )
131    {
132      LOG("hwpluing path is too long  \n");
133      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
134    }
135
136    strcpy(fullpath, parent_dir);
137    strcat(fullpath, pluginsubdir);
138
139    dirhandle = opendir(fullpath);
140
141    entries = malloc(sizeof(hwpluginentries_t));
142    if (entries == NULL )
143    {
144      LOG("Could not allocate entries  \n");
145      closedir(dirhandle);
146      return(SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
147    }
148    memset(entries, 0, sizeof(hwpluginentries_t));
149
150    if (dirhandle != NULL)
151    {
152       so_present = 0;
153       activate_dir_present = 0;
154       key_dir_present = 0;
155       while (NULL != (entry = readdir (dirhandle)) )
156       {
157          /** Ensure that the directory has plugin.so file, activate directory,
158           ** at least one key directory
159           **/
160
161           if ((entry->d_type == DT_REG) &&
162               (strcmp(entry->d_name, "plugin.so") == 0))
163           {
164              so_present = 1;
165              if (strlen(fullpath) + strlen("/")+ strlen(entry->d_name) > 256)
166              {
167                 LOG("plugin so path is too long  \n");
168                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
169                 break;
170              }
171              strcpy(entries->so_full_path, fullpath);
172              strcat(entries->so_full_path, "/");
173              strcat(entries->so_full_path, entry->d_name);
174           }
175
176           if ((entry->d_type == DT_DIR) &&
177               (strcmp(entry->d_name, "activate") == 0 ))
178           {
179              activate_dir_present = 1;
180              if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
181              {
182                 LOG("activate path is too long  \n");
183                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
184                 break;
185              }
186              strcpy(entries->activate_dir_full_path, fullpath);
187              strcat(entries->activate_dir_full_path, "/");
188              strcat(entries->activate_dir_full_path, entry->d_name);
189              strcat(entries->activate_dir_full_path, "/");
190           }
191
192           if ((entry->d_type == DT_DIR) &&
193               (strncmp(entry->d_name, "key", 3) == 0 ))
194           {
195              key_dir_present = 1;
196              if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
197              {
198                 LOG("activate path is too long  \n");
199                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
200                 break;
201              }
202              strcpy(entries->key_dir_full_path[entries->num_key_dirs],
203                              fullpath);
204              strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
205              strcat(entries->key_dir_full_path[entries->num_key_dirs],
206                               entry->d_name);
207              strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
208              entries->num_key_dirs++;
209           }
210
211           if (so_present && activate_dir_present && key_dir_present)
212           {
213               printf("so dir path: %s \n", entries->so_full_path);
214               printf("activate dir path: %s \n", entries->activate_dir_full_path);
215               ret_val = HwPlugin_Initiate_Activate_and_load_keys(entries);
216               break;
217           }
218       }
219
220       if (!so_present || !activate_dir_present || !key_dir_present)
221       {
222           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);
223           return(SSHSM_HW_PLUGIN_ERROR_BASE + INCOMPLETE_PLUGIN_DIR);
224       }
225    }
226    else
227    {
228      LOG("Could not open hwplugin directory %s \n", fullpath);
229      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
230    }
231    free(entries);
232    closedir(dirhandle);
233    return(ret_val);
234 }
235
236
237 /**
238 ** Function name: HWPlugin_Initiate_Activate_and_load_keys
239 ** Description:  This function loads plugin, gets the function pointers,
240 ** activates the plugin and then finally loads the keys
241 **/
242 int HwPlugin_Initiate_Activate_and_load_keys(hwpluginentries_t *entries)
243 {
244      int ret_val;
245
246      ret_val = load_hw_plugin_and_get_function_pointers(entries->so_full_path,
247                    &g_pluginfuncs);
248      if(ret_val != 0)
249         return(ret_val);
250
251      ret_val = init_hw_plugin(&g_pluginfuncs);
252      if(ret_val != 0 )
253         return(ret_val);
254
255      ret_val = activate_hw_plugin(entries, &g_pluginfuncs);
256      if (ret_val != 0 )
257        return(ret_val);
258
259      ret_val = load_keys_in_hw_plugin(entries, &g_pluginfuncs);
260      if (ret_val != 0 )
261        return(ret_val);
262
263      return(0);
264 }
265
266
267 /**
268   Function name : load_hw_plugin_and_get_function_pointers
269 **/
270
271 int load_hw_plugin_and_get_function_pointers(char *so_path,
272               SSHSM_HW_FUNCTIONS_t *funcs)
273 {
274    int (*functogetpluginfuncs)(SSHSM_HW_FUNCTIONS_t *fs);
275    int ret_val;
276
277    g_dl_handle = dlopen(so_path, RTLD_NOW);
278    if(g_dl_handle == NULL )
279    {
280        LOG("dlopen on %s failed: %s \n", so_path, dlerror());
281        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_OPEN_ERROR);
282    }
283
284    functogetpluginfuncs = NULL;
285    functogetpluginfuncs = dlsym(g_dl_handle,
286              "sshsm_hw_plugin_get_plugin_functions");
287
288    if (functogetpluginfuncs == NULL)
289    {
290        LOG("dlsym of sshsm_hw_plugin_get_plugin_functions : %s \n", dlerror() );
291        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_SYM_ERROR);
292    }
293
294    ret_val = functogetpluginfuncs(funcs);
295
296     return ret_val;
297 }
298
299 int init_hw_plugin(SSHSM_HW_FUNCTIONS_t *funcs)
300 {
301     int ret_val;
302
303     ret_val = (funcs->xxx_init)();
304
305     if(ret_val != 0 )
306     {
307        LOG("HWPlugin init failed \n" );
308        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
309
310     }
311     return(ret_val);
312 }
313
314
315 int activate_hw_plugin(hwpluginentries_t *entries, SSHSM_HW_FUNCTIONS_t *funcs)
316 {
317    int ret_val;
318
319    if( (entries == NULL) || (funcs == NULL) )
320    {
321      ret_val = -1;
322      LOG("activate_hw_plugin: Input values are NULL \n");
323      return ret_val;
324    }
325    /** Read all files starting with 'A' and pass the information to
326     ** plugin
327     **/
328
329    SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
330
331    memset(&comp_buffers, 0, sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
332
333    ret_val = get_all_file_contents(entries->activate_dir_full_path, 'A',
334                        &comp_buffers);
335
336    if (ret_val == 0 )
337    {
338      ret_val = (funcs->xxx_activate)(&comp_buffers);
339      //free_buffers(&comp_buffers);
340    }
341
342    return(ret_val);
343 }
344
345
346 int load_keys_in_hw_plugin(hwpluginentries_t *entries,
347                    SSHSM_HW_FUNCTIONS_t *funcs)
348 {
349
350     int ret_val;
351     void *key_handle;
352     int ii;
353     //unsigned long hwkeyhandle=987654321;
354     //key_handle = (void *) &hwkeyhandle;
355
356     SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
357
358     /**
359      Travese through all key directories and load the key in plugin
360     **/
361
362     ret_val = -1;
363     for(ii = 0; ii < entries->num_key_dirs; ii++)
364     {
365        memset(&comp_buffers, 0,
366           sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
367
368        ret_val = get_all_file_contents(entries->key_dir_full_path[ii], 'K',
369                         &comp_buffers);
370
371        if(ret_val == 0)
372        {
373            ret_val = (funcs->xxx_load_key)(&comp_buffers, &key_handle);
374            //free_buffers(&comp_buffers);
375            if(ret_val == 0)
376            {
377                /** Get PKCS11 information **/
378                /** Call SoftHSM functions to create private key object */
379                ret_val = program_pkcs11_info(entries->key_dir_full_path[ii], &key_handle);
380            }
381        }
382
383     }
384
385     return(0);
386 }
387
388 int get_all_file_contents(char *dirpath, char starting_char,
389                   SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
390 {
391    DIR *dirhandle;
392    struct dirent *entry;
393
394    buffer_info_t *buffer;
395    char *token;
396
397    struct stat st;
398    int fd;
399
400    int ret_val = 0;
401
402
403    char fullpath[256+1];
404
405    dirhandle = opendir(dirpath);
406    if (dirhandle != NULL)
407    {
408       while (NULL != (entry = readdir (dirhandle)))
409       {
410          if ((entry->d_type == DT_REG) &&
411               (entry->d_name[0] == starting_char))
412          {
413              buffer = malloc(sizeof(buffer_info_t));
414              if (buffer == NULL )
415              {
416                LOG("Could not allocate entries  \n");
417                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
418                break;
419              }
420              token = strchr(entry->d_name, '.');
421              strcpy(buffer->id, token+1);
422
423              /** get full path of the file **/
424              if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
425              {
426                 LOG("file  path is too long  \n");
427                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
428                 free(buffer);
429                 break;
430              }
431              strcpy(fullpath,dirpath);
432              strcat(fullpath, entry->d_name);
433              stat(fullpath, &st);
434              buffer->buffer = malloc(st.st_size);
435              if(buffer->buffer == NULL)
436              {
437                LOG("Could not allocate entries  \n");
438                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
439                free(buffer);
440                break;
441              }
442              buffer->length_of_buffer = st.st_size;
443              fd = open(fullpath, O_RDONLY);
444              if (fd == -1 )
445              {
446                LOG("Could not open file %s  \n", fullpath);
447                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
448                free(buffer->buffer);
449                free(buffer);
450                break;
451              }
452
453              if(read(fd, buffer->buffer, st.st_size) < 0)
454              {
455                 LOG("Reading from file %s failed \n", fullpath);
456                 continue;
457              }
458
459              close(fd);
460
461              /** Now write this buffer in c_buffers **/
462              c_buffers->buffer_info[c_buffers->num_buffers] = buffer;
463              c_buffers->num_buffers++;
464
465          }
466       }
467    }
468    else
469    {
470      LOG("Could not open hwplugin directory %s \n", dirpath);
471      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
472    }
473
474    closedir(dirhandle);
475    //if (ret_val != 0 )
476      //free_buffers(c_buffers);
477
478    return(ret_val);
479 }
480
481 void free_buffers ( SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
482 {
483    int ii;
484
485    for(ii = 0; ii < c_buffers->num_buffers; ii++)
486    {
487       free(c_buffers->buffer_info[ii]->buffer);
488       free(c_buffers->buffer_info[ii]);
489    }
490 }
491
492 int program_pkcs11_info (char *dirpath, void *key_handle)
493 {
494    DIR *dirhandle;
495    struct dirent *entry;
496
497    char fullpath[256+1];
498    int ret_val = 0;
499
500    FILE *fp;
501    char buffer[80+1];
502
503    unsigned int  slot_id = 0;
504    unsigned char upin[64+1];
505    int upin_len = 0;
506    unsigned char keyid[64+1];
507    int key_id_len = 0;
508    unsigned char key_label[64+1] = "";
509    char *valuep;
510    char *endvalue;
511
512
513    dirhandle = opendir(dirpath);
514    if (dirhandle != NULL)
515    {
516       while (NULL != (entry = readdir (dirhandle)))
517       {
518            if (strcmp(entry->d_name, "pkcs11.cfg") == 0 )
519            {
520               /** get full path of the file **/
521                if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
522              {
523                 LOG("file  path is too long  \n");
524                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
525                 break;
526              }
527              strcpy(fullpath,dirpath);
528              strcat(fullpath, entry->d_name);
529
530              fp = fopen(fullpath, "r");
531              if(fp == NULL )
532              {
533                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
534                 break;
535              }
536              while (fgets(buffer, 80, fp) != NULL)
537              {
538                  valuep = strchr(buffer, ':');
539                  if(valuep == NULL)
540                     continue;
541                  valuep[0] = '\0';
542
543                  /** Looks like \n is part of buffer that is read via fgets
544                   ** Replacce tha with 0 **/
545                  endvalue = strchr(valuep+1, '\n');
546                  if(endvalue != NULL)
547                     endvalue[0] =  '\0';
548                  if (strcmp(buffer, "slot") == 0)
549                  {
550                     slot_id = strtoul(valuep+1, NULL, 10);
551                     continue;
552                  }
553                  if(strcmp(buffer, "key_id") == 0 )
554                  {
555                     strcpy((char*)keyid, valuep+1);
556                     key_id_len = strlen((char*)keyid);
557                     continue;
558                  }
559                  if(strcmp(buffer, "key_label") == 0 )
560                  {
561                     strcpy((char*)key_label, valuep+1);
562                     continue;
563                  }
564                  if(strcmp(buffer, "upin") == 0 )
565                  {
566                     strcpy((char*) upin, valuep+1);
567                     upin_len = strlen((char *) upin);
568                     continue;
569                  }
570              }
571              fclose(fp);
572
573              /** Program key in SoftHSM **/
574              ret_val = PrepareKeyInSoftHSM(slot_id, upin, upin_len, keyid,
575                            key_id_len, key_label, key_handle);
576
577               break;
578            }
579
580       }
581    }
582
583    return ret_val;
584 }
585
586
587 /*** PrepareKeyInSoftHSM
588 ** Description:  It creates the object in softhsm with given key id and
589 ** key label and also stores the keyhandle that was returned by hardware plugin
590 ** Inputs:
591 **   -  Slot ID
592 **   -  Key ID
593 **   -  Key Label
594 **   -  upin
595 **   -  pluginkeyHandle
596 ** Output:
597 **    - None
598 ** Renturs
599 **     - SUCCESS or FAILURE
600 *****/
601 int PrepareKeyInSoftHSM(unsigned int slot_id,
602                unsigned char *upin, int upin_len,
603                unsigned char *key_id, int key_id_len,
604                unsigned char *key_label, void *key_handle)
605 {
606     CK_SESSION_HANDLE hSession;
607     CK_RV ret_val;
608     int ii;
609     CK_OBJECT_HANDLE hKey;
610     unsigned char key_handle_str[32] = {0};
611
612     printf ("slot %ul upin %s key_id %s key_label %s \n", slot_id, upin, key_id,
613              key_label);
614
615     if(!key_handle)
616     {
617         //ultoa((CK_ULONG)key_handle,  key_handle_str,  16); // Linking error seen
618         printf("Key_handle to be stored: %lx \n", *((CK_ULONG *)key_handle) );
619         sprintf((char *) key_handle_str, "%lx", *((CK_ULONG *)key_handle));
620     }
621     else
622     {
623         printf("Input Key handle is NULL ! \n");
624     }
625
626     /** For creating the key object, first the session needs to be opened
627         C_OpenSession is used to open the session
628      **/
629     ret_val = C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION,
630                             NULL_PTR, NULL_PTR, &hSession);
631
632     if (ret_val != CKR_OK)
633     {
634         printf("OpenSession failed for slot %x \n", slot_id);
635         return(ret_val);
636     }
637
638     /** Next step is login
639      ** C_Login is used to login to the session
640      **/
641     ret_val = C_Login(hSession, CKU_USER,  upin, upin_len);
642     if (ret_val != CKR_OK)
643     {
644         printf("Login failed: 0x%lx | for slot %x upin below \n", ret_val, slot_id);
645         for (ii = 0; ii < upin_len; ii++ )
646            printf("%2x  %c \n",  upin[ii], upin[ii]);
647         return(ret_val);
648     }
649
650     CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
651     CK_KEY_TYPE keyType = CKK_RSA;
652     CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE ;
653
654     CK_ATTRIBUTE keyTemplate[] = {
655         { CKA_CLASS,            &privClass,         sizeof(privClass) },
656         { CKA_KEY_TYPE,         &keyType,           sizeof(keyType) },
657         { CKA_LABEL,            key_label,          strlen((char *) key_label) },
658         { CKA_ID,               key_id,             (CK_ULONG)key_id_len },
659         { CKA_SIGN,             &ckTrue,            sizeof(ckTrue) },
660         { CKA_DECRYPT,          &ckTrue,            sizeof(ckTrue) },
661         { CKA_UNWRAP,           &ckFalse,           sizeof(ckFalse) },
662         { CKA_TOKEN,            &ckTrue,            sizeof(ckTrue) },
663         { CKA_PRIVATE,          &ckTrue,            sizeof(ckTrue) },
664         { CKA_EXTRACTABLE,      &ckTrue,            sizeof(ckTrue) },
665         { CKA_PUBLIC_EXPONENT,  0,            0},
666         { CKA_MODULUS,          0,            0},
667         { CKA_PRIVATE_EXPONENT, 0,            0},
668         { CKA_PRIME_2,          0,            0},
669         { CKA_EXPONENT_1,       0,            0},
670         { CKA_EXPONENT_2,       0,            0},
671         { CKA_COEFFICIENT,      0,            0},
672         { CKA_PRIME_1,          key_handle_str,     strlen((char *)key_handle_str) }
673         /** For now keep the key handle returned by Plugin in CK_PRIME_1.
674         ** TBD - Define new attribute to store this in future
675         ***/
676     };
677
678     ret_val =  C_CreateObject(hSession, keyTemplate,
679                  sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE),&hKey);
680     if (ret_val != CKR_OK)
681     {
682         printf("CreateObject failed: 0x%lx | for slot %x | keylabel %s | keyid below \n",
683                 ret_val, slot_id, key_label);
684         for (ii = 0; ii < key_id_len; ii++ )
685            printf("%2x  %c \n",  key_id[ii], key_id[ii]);
686         //return(ret_val);
687     }
688
689     ret_val = C_Logout(hSession);
690     if (ret_val != CKR_OK)
691     {
692         printf("Logout failed 0x%lx | for slot %x \n", ret_val, slot_id);
693         return(ret_val);
694     }
695
696     ret_val = C_CloseSession(hSession);
697     if (ret_val != CKR_OK)
698     {
699         printf("C_CloseSession failed for slot %x \n", slot_id);
700         return(ret_val);
701     }
702
703     return ret_val;
704 }
705
706 int HwInfraSignInit(void *keyHandle,  unsigned long mechanism,
707                  void* param, int paramLen)
708 {
709     return ( g_pluginfuncs.xxx_rsa_sign_init(keyHandle, mechanism, param, paramLen) );
710 }
711
712 int HwInfraSign( void *keyHandle,  unsigned long mechanism,
713                  unsigned char *msg, int msg_len,
714                  unsigned char *outsig,  int *outsiglen)
715 {
716     return ( g_pluginfuncs.xxx_rsa_sign(keyHandle, mechanism, msg, msg_len,
717                 outsig, outsiglen) );
718 }
719