Added a new Attribute to store TPM key handle 31/44731/10
authorRitu Sood <ritu.sood@intel.com>
Thu, 26 Apr 2018 01:50:05 +0000 (01:50 +0000)
committerRitu Sood <ritu.sood@intel.com>
Thu, 24 May 2018 05:55:20 +0000 (05:55 +0000)
Includes changes to detect existing instances of key  and
also some bug fixes. Also added new functionality for
RSA_SignUpdate, RSA_SignFinal and RSA_Cleanup

Issue-ID: AAF-260
Change-Id: Ib064e86b8f112784ed6d352ab1557ab9a13c5978
Signed-off-by: Ritu Sood <ritu.sood@intel.com>
12 files changed:
SoftHSMv2/src/lib/HwInfra/HwInfra.cpp [moved from SoftHSMv2/src/lib/HwInfra/HwInfra.c with 77% similarity]
SoftHSMv2/src/lib/HwInfra/HwInfra.h
SoftHSMv2/src/lib/HwInfra/Makefile.am
SoftHSMv2/src/lib/HwInfra/hwpluginif.h
SoftHSMv2/src/lib/P11Attributes.cpp
SoftHSMv2/src/lib/P11Attributes.h
SoftHSMv2/src/lib/P11Objects.cpp
SoftHSMv2/src/lib/SoftHSM.cpp
SoftHSMv2/src/lib/object_store/DBObject.cpp
SoftHSMv2/src/lib/object_store/OSAttributes.h
SoftHSMv2/src/lib/session_mgr/Session.cpp
SoftHSMv2/src/lib/session_mgr/Session.h

similarity index 77%
rename from SoftHSMv2/src/lib/HwInfra/HwInfra.c
rename to SoftHSMv2/src/lib/HwInfra/HwInfra.cpp
index 528097d..557630b 100644 (file)
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include "HwInfra.h"
 #include "hwpluginif.h"
-
+#include "OSAttributes.h"
 #include "cryptoki.h"
 
 char hw_plugins_parent_dir[MAX_PARENT_PATH_NAME+1] = "";
@@ -32,7 +32,6 @@ 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
@@ -138,7 +137,7 @@ int loadHWPlugin(char *parent_dir, char *pluginsubdir)
 
    dirhandle = opendir(fullpath);
 
-   entries = malloc(sizeof(hwpluginentries_t));
+   entries = (hwpluginentries_t*)malloc(sizeof(hwpluginentries_t));
    if (entries == NULL )
    {
      LOG("Could not allocate entries  \n");
@@ -282,7 +281,7 @@ int load_hw_plugin_and_get_function_pointers(char *so_path,
    }
 
    functogetpluginfuncs = NULL;
-   functogetpluginfuncs = dlsym(g_dl_handle,
+   functogetpluginfuncs = (int (*)(SSHSM_HW_FUNCTIONS_t *)) dlsym(g_dl_handle,
              "sshsm_hw_plugin_get_plugin_functions");
 
    if (functogetpluginfuncs == NULL)
@@ -342,7 +341,6 @@ int activate_hw_plugin(hwpluginentries_t *entries, SSHSM_HW_FUNCTIONS_t *funcs)
    return(ret_val);
 }
 
-
 int load_keys_in_hw_plugin(hwpluginentries_t *entries,
                    SSHSM_HW_FUNCTIONS_t *funcs)
 {
@@ -354,6 +352,7 @@ int load_keys_in_hw_plugin(hwpluginentries_t *entries,
     //key_handle = (void *) &hwkeyhandle;
 
     SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
+    SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t import_public_key;
 
     /**
      Travese through all key directories and load the key in plugin
@@ -370,19 +369,27 @@ int load_keys_in_hw_plugin(hwpluginentries_t *entries,
 
        if(ret_val == 0)
        {
-           ret_val = (funcs->xxx_load_key)(&comp_buffers, &key_handle);
+           ret_val = (funcs->xxx_load_key)(&comp_buffers, &key_handle,
+                                                       &import_public_key);
            //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);
+               if (ret_val == 0) {
+                   ret_val = program_pkcs11_info(entries->key_dir_full_path[ii],
+                                             &key_handle,  &import_public_key);
+                   if (import_public_key.modulus != NULL)
+                      free(import_public_key.modulus);
+                   if (import_public_key.exponent != NULL)
+                      free(import_public_key.exponent);
+               }
            }
        }
 
     }
 
-    return(0);
+    return(ret_val);
 }
 
 int get_all_file_contents(char *dirpath, char starting_char,
@@ -410,7 +417,7 @@ int get_all_file_contents(char *dirpath, char starting_char,
          if ((entry->d_type == DT_REG) &&
               (entry->d_name[0] == starting_char))
          {
-             buffer = malloc(sizeof(buffer_info_t));
+             buffer = (buffer_info_t*) malloc(sizeof(buffer_info_t));
              if (buffer == NULL )
              {
                LOG("Could not allocate entries  \n");
@@ -431,7 +438,7 @@ int get_all_file_contents(char *dirpath, char starting_char,
              strcpy(fullpath,dirpath);
              strcat(fullpath, entry->d_name);
              stat(fullpath, &st);
-             buffer->buffer = malloc(st.st_size);
+             buffer->buffer = (unsigned char*) malloc(st.st_size);
              if(buffer->buffer == NULL)
              {
                LOG("Could not allocate entries  \n");
@@ -489,7 +496,8 @@ void free_buffers ( SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
    }
 }
 
-int program_pkcs11_info (char *dirpath, void *key_handle)
+int program_pkcs11_info (char *dirpath, void *key_handle,
+                         SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *import_public_key)
 {
    DIR *dirhandle;
    struct dirent *entry;
@@ -572,7 +580,7 @@ int program_pkcs11_info (char *dirpath, void *key_handle)
 
              /** Program key in SoftHSM **/
              ret_val = PrepareKeyInSoftHSM(slot_id, upin, upin_len, keyid,
-                           key_id_len, key_label, key_handle);
+                           key_id_len, key_label, key_handle, import_public_key);
 
               break;
            }
@@ -584,6 +592,28 @@ int program_pkcs11_info (char *dirpath, void *key_handle)
 }
 
 
+void long_to_byte_string(const unsigned long longValue, unsigned char *out, size_t *outlen)
+{
+        unsigned long setValue = longValue;
+        unsigned char byteStrIn[8];
+        size_t i;
+
+        for (i = 0; i < 8; i++)
+        {
+            byteStrIn[7-i] = (unsigned char) (setValue & 0xFF);
+            setValue >>= 8;
+        }
+        for (i = 0; i < 8; i++)
+        {
+            if (byteStrIn[i])
+               break;
+        }
+        memcpy(out, &byteStrIn[i], 8-i);
+        *outlen = 8-i;
+}
+
+
+
 /*** 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
@@ -601,7 +631,8 @@ 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)
+               unsigned char *key_label, void *key_handle,
+               SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *import_public_key)
 {
     CK_SESSION_HANDLE hSession;
     CK_RV ret_val;
@@ -611,16 +642,15 @@ int PrepareKeyInSoftHSM(unsigned int slot_id,
 
     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));
+        printf("Input Key handle is NULL ! \n");
+        return (SSHSM_HW_PLUGIN_ERROR_BASE + INVALID_KEY_ERROR);
     }
-    else
+    if (import_public_key->modulus == NULL ||
+                    import_public_key->exponent == NULL)
     {
-        printf("Input Key handle is NULL ! \n");
+         return (SSHSM_HW_PLUGIN_ERROR_BASE + INVALID_KEY_ERROR);
     }
 
     /** For creating the key object, first the session needs to be opened
@@ -651,39 +681,64 @@ int PrepareKeyInSoftHSM(unsigned int slot_id,
     CK_KEY_TYPE keyType = CKK_RSA;
     CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE ;
 
+    unsigned long int key_id_int = atol( (const char*) key_id );
+    unsigned char byte_str[8];
+    size_t outlen;
+    long_to_byte_string(key_id_int, byte_str, &outlen);
+
     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_ID,               byte_str,           outlen },
         { 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
-        ***/
+        { CKA_EXTRACTABLE,      &ckFalse,           sizeof(ckFalse) },
+        { CKA_SENSITIVE,        &ckFalse,           sizeof(ckFalse) },
+        { CKA_PUBLIC_EXPONENT,  import_public_key->exponent, import_public_key->exponent_size},
+        //{ CKA_MODULUS,          pN,                 sizeof(pN) },
+        { CKA_MODULUS,          import_public_key->modulus, import_public_key->modulus_size },
+        { 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_OS_PRIVATE_HANDLE,       (CK_VOID_PTR ) *((CK_ULONG*)key_handle),      sizeof(CK_ULONG) }
     };
 
-    ret_val =  C_CreateObject(hSession, keyTemplate,
+
+    CK_OBJECT_HANDLE hObject;
+    CK_ULONG ulObjectCount;
+    CK_RV rv;
+
+    rv = C_FindObjectsInit(hSession, keyTemplate, 0);
+    if(rv != CKR_OK) {
+        LOG ("C_FindObjectsInit rv %ld\n", rv);
+    }
+    rv = C_FindObjects(hSession, &hObject, 16, &ulObjectCount);
+    printf("PrepareKeyInSoftHSM: ulObjectCount %ld\n", ulObjectCount);
+    if(rv != CKR_OK || ulObjectCount == 0) {
+        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",
+        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]);
+            for (ii = 0; ii < key_id_len; ii++ )
+               printf("%2x  %c \n",  key_id[ii], key_id[ii]);
         //return(ret_val);
+        }
+    }
+    else {
+        printf("PrepareKeyInSoftHSM: Object already exists\n");
+    }
+
+    rv = C_FindObjectsFinal(hSession);
+    if(rv != CKR_OK) {
+        LOG ("C_FindObjectsFinal rv %ld\n", rv);
     }
 
     ret_val = C_Logout(hSession);
@@ -704,16 +759,56 @@ int PrepareKeyInSoftHSM(unsigned int slot_id,
 }
 
 int HwInfraSignInit(void *keyHandle,  unsigned long mechanism,
-                 void* param, int paramLen)
+                 void* param, int paramLen, void **hwCryptoOpaque)
 {
-    return ( g_pluginfuncs.xxx_rsa_sign_init(keyHandle, mechanism, param, paramLen) );
+    if (g_pluginfuncs.xxx_rsa_sign_init == NULL)
+        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
+    return (g_pluginfuncs.xxx_rsa_sign_init(keyHandle, mechanism, param,
+                                                 paramLen, hwCryptoOpaque)) ;
+
 }
 
-int HwInfraSign( void *keyHandle,  unsigned long mechanism,
-                 unsigned char *msg, int msg_len,
+int HwInfraSign(void *keyHandle,  unsigned long mechanism,
+                 unsigned char *msg, int msg_len, void *hwCryptoOpaque,
                  unsigned char *outsig,  int *outsiglen)
 {
+    if (g_pluginfuncs.xxx_rsa_sign == NULL)
+        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
     return ( g_pluginfuncs.xxx_rsa_sign(keyHandle, mechanism, msg, msg_len,
-                outsig, outsiglen) );
+                hwCryptoOpaque, outsig, outsiglen) );
+}
+
+int HwInfraSignUpdate(void *keyHandle, unsigned long mechanism,
+                      unsigned char *param, int paramLen, void *hwCryptoOpaque)
+{
+    if (g_pluginfuncs.xxx_rsa_sign_update == NULL)
+        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
+    int x =  ( g_pluginfuncs.xxx_rsa_sign_update(keyHandle, mechanism, param,
+                                               paramLen, hwCryptoOpaque) );
+    return 0;
+}
+
+int HwInfraSignFinal(void *keyHandle, unsigned long mechanism,
+                  void *hwCryptoOpaque,
+                 unsigned char *outsig,  int *outsiglen)
+{
+    if (g_pluginfuncs.xxx_rsa_sign_final == NULL)
+        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
+    return ( g_pluginfuncs.xxx_rsa_sign_final(keyHandle, mechanism,
+                                     hwCryptoOpaque, outsig, outsiglen) );
+}
+
+int HwInfraSignCleanup(void *keyHandle, unsigned long mechanism,
+                       void *hwCryptoOpaque)
+{
+    if (g_pluginfuncs.xxx_rsa_sign_cleanup == NULL)
+        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
+
+    return ( g_pluginfuncs.xxx_rsa_sign_cleanup(keyHandle, mechanism,
+                                                hwCryptoOpaque) );
 }
 
index a62bd7d..8cbbada 100644 (file)
@@ -50,18 +50,26 @@ 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 program_pkcs11_info (char *dirpath, void *key_handle, SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t* ik);
 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);
+               unsigned char *key_label, void *key_handle,
+               SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t* ik);
 
 int HwInfraSignInit(void *keyHandle,  unsigned long mechanism,
-                 void* param, int paramLen);
-
-int HwInfraSign( void *keyHandle,  unsigned long mechanism,
-                 unsigned char *msg, int msg_len,
+                 void* param, int paramLen, void **hwCryptoOpaque);
+int HwInfraSign(void *keyHandle,  unsigned long mechanism,
+                 unsigned char *msg, int msg_len, void *hwCryptoOpaque,
+                 unsigned char *outsig,  int *outsiglen);
+int HwInfraSignUpdate(void *keyHandle, unsigned long mechanism,
+                 unsigned char *msg, int msg_len, void *hwCryptoOpaque);
+int HwInfraSignFinal(void *keyHandle,  unsigned long mechanism,
+                 void *hwCryptoOpaque,
                  unsigned char *outsig,  int *outsiglen);
+int HwInfraSignCleanup(void *keyHandle,  unsigned long mechanism,
+                       void *hwCryptoOpaque);
+
 
 #define MAX_PARENT_PATH_NAME 256
 
@@ -76,6 +84,7 @@ int HwInfraSign( void *keyHandle,  unsigned long mechanism,
 #define PLUGIN_DL_OPEN_ERROR (06)
 #define PLUGIN_DL_SYM_ERROR (07)
 #define PLUGIN_INIT_ERROR (10)
+#define INVALID_KEY_ERROR (11)
 
 #if defined(__cplusplus)
 }
index b327b15..3ff3726 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS =                   -I$(srcdir)/.. \
                                -I$(srcdir)/../session_mgr
 
 noinst_LTLIBRARIES =           libsofthsm_hwinfra.la
-libsofthsm_hwinfra_la_SOURCES =        HwInfra.c
+libsofthsm_hwinfra_la_SOURCES =        HwInfra.cpp
 
 SUBDIRS =
 
index b078be3..a8ade2a 100755 (executable)
@@ -94,6 +94,20 @@ typedef int (*sshsm_hw_plugin_activate)(
         );
 
 
+/***
+ * Import Public Key
+ * Description: This is called by HWPluginInfra after load key to get the public
+ * key modulus and exponent.  Plugin to allocate memory for modulus and exponent
+ * based on size. HwInfra will release the buffers after using them.
+ */
+
+typedef struct sshsm_hw_plugin_import_public_key_info_s {
+    unsigned long modulus_size;
+    unsigned char *modulus;
+    unsigned long exponent_size;
+    unsigned char *exponent;
+}SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t;
+
 
 /***
  * Load Key  Callback
@@ -141,32 +155,30 @@ typedef struct sshsm_hw_plugin_load_key_in_info_s {
 
 typedef int (*sshsm_hw_plugin_load_key)(
            SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
-           void **keyHandle
+           void **keyHandle,
+           SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *import_public_key
         );
 
 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
+ * for RSA keys.  Plugin can allocate memory for any state and can add its reference to
+ * pluginOutDataRef. This pointer is passed to sign, signupdate and signfinal.
  */
 
 typedef int (*sshsm_hw_plugin_rsa_sign_init)(
          void *keyHandle,
          unsigned long mechanism,
          void *param,
-         int len
+         int len,
+         void **pluginOutDataRef
         );
 
-
-
 /***
- * Callback:  RSA Sign Init
+ * Callback:  RSA Sign
  * Description: This is called by HWPluginInfra as part of C_Sign function
  * for RSA keys. HWPluginInfra get the keyHandle from the key object.
  *
@@ -181,10 +193,37 @@ typedef int (*sshsm_hw_plugin_rsa_sign)(
          unsigned long mechanism,
          unsigned char *msg,
          int msg_len,
+         void *pluginDataRef,
          unsigned char *outsig,
          int *outsiglen
         );
 
+typedef int (*sshsm_hw_plugin_rsa_sign_update)(
+         void *keyHandle,
+         unsigned long mechanism,
+         unsigned char *msg,
+         int msg_len,
+         void *pluginDataRef
+        );
+
+typedef int (*sshsm_hw_plugin_rsa_sign_final)(
+         void *keyHandle,
+         unsigned long mechanism,
+         void *pluginDataRef,
+         unsigned char *outsig,
+         int *outsiglen
+        );
+
+/** This function is called by SSHSM only if there sign_final function is not called.
+If sign_final function is called, it is assumed that plugin would have cleaned this up.
+***/
+
+typedef int (*sshsm_hw_plugin_rsa_sign_cleanup)(
+         void *keyHandle,
+         unsigned long mechanism,
+         void *pluginDataRef
+        );
+
 /***
  * Function Name: sshsm_hw_plugin_get_plugin_functions
  * Descrpiton:  Every HW plugin is expected to define this function.
@@ -208,6 +247,9 @@ typedef struct sshsm_hw_functions_s
     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_plugin_rsa_sign_update xxx_rsa_sign_update;
+    sshsm_hw_plugin_rsa_sign_final xxx_rsa_sign_final;
+    sshsm_hw_plugin_rsa_sign_cleanup xxx_rsa_sign_cleanup;
 
 }SSHSM_HW_FUNCTIONS_t;
 
index 28d0f9b..5a56097 100644 (file)
@@ -294,6 +294,10 @@ CK_RV P11Attribute::retrieve(Token *token, bool isPrivate, CK_VOID_PTR pValue, C
                {
                        attrSize = attr.getAttributeMapValue().size() * sizeof(CK_ATTRIBUTE);
                }
+                else if (attr.isUnsignedLongAttribute())
+                {
+                        attrSize = sizeof(unsigned long);
+                }
                else
                {
                        // Should be impossible.
@@ -2512,3 +2516,33 @@ CK_RV P11AttrAllowedMechanisms::updateAttr(Token* /*token*/, bool /*isPrivate*/,
        osobject->setAttribute(type, OSAttribute(data));
        return CKR_OK;
 }
+
+
+// Set default value
+bool P11AttrPrivateHandle::setDefault()
+{
+        OSAttribute attr((CK_ULONG)0);
+        return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrPrivateHandle::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+        // Attribute specific checks
+        if (op != OBJECT_OP_CREATE)
+        {
+                return CKR_ATTRIBUTE_READ_ONLY;
+        }
+
+        if (ulValueLen !=sizeof(CK_ULONG))
+        {
+                return CKR_ATTRIBUTE_VALUE_INVALID;
+        }
+
+        // Store data
+        osobject->setAttribute(type, *((CK_ULONG*)pValue));
+
+        return CKR_OK;
+}
+
+
index 3cddf30..7cc9976 100644 (file)
@@ -36,6 +36,7 @@
 #include "cryptoki.h"
 #include "OSObject.h"
 #include "Token.h"
+#include "OSAttributes.h"
 
 // The operation types
 #define OBJECT_OP_NONE         0x0
@@ -1261,4 +1262,22 @@ protected:
        virtual CK_RV updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op);
 };
 
+/*****************************************
+ * CKA_COEFFICIENT
+ *****************************************/
+
+class P11AttrPrivateHandle : public P11Attribute
+{
+public:
+        // Constructor
+        P11AttrPrivateHandle(OSObject* inobject) : P11Attribute(inobject) { type = CKA_OS_PRIVATE_HANDLE; checks = ck1; }
+
+protected:
+        // Set the default value of the attribute
+        virtual bool setDefault();
+        // Update the value if allowed
+        virtual CK_RV updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op);
+};
+
+
 #endif // !_SOFTHSM_V2_P11ATTRIBUTES_H
index c58d4ec..3e663b2 100644 (file)
@@ -1107,6 +1107,7 @@ bool P11RSAPrivateKeyObj::init(OSObject *inobject)
        P11Attribute* attrExponent1 = new P11AttrExponent1(osobject);
        P11Attribute* attrExponent2 = new P11AttrExponent2(osobject);
        P11Attribute* attrCoefficient = new P11AttrCoefficient(osobject);
+        P11Attribute* attrPrivateHandle = new P11AttrPrivateHandle(osobject);
 
        // Initialize the attributes
        if
@@ -1118,6 +1119,7 @@ bool P11RSAPrivateKeyObj::init(OSObject *inobject)
                !attrPrime2->init() ||
                !attrExponent1->init() ||
                !attrExponent2->init() ||
+                !attrPrivateHandle->init() ||
                !attrCoefficient->init()
        )
        {
@@ -1130,6 +1132,7 @@ bool P11RSAPrivateKeyObj::init(OSObject *inobject)
                delete attrExponent1;
                delete attrExponent2;
                delete attrCoefficient;
+                delete attrPrivateHandle;
                return false;
        }
 
@@ -1142,6 +1145,7 @@ bool P11RSAPrivateKeyObj::init(OSObject *inobject)
        attributes[attrExponent1->getType()] = attrExponent1;
        attributes[attrExponent2->getType()] = attrExponent2;
        attributes[attrCoefficient->getType()] = attrCoefficient;
+        attributes[attrPrivateHandle->getType()] = attrPrivateHandle;
 
        initialized = true;
        return true;
@@ -1223,23 +1227,27 @@ bool P11ECPrivateKeyObj::init(OSObject *inobject)
        // Create attributes
        P11Attribute* attrEcParams = new P11AttrEcParams(osobject,P11Attribute::ck4|P11Attribute::ck6);
        P11Attribute* attrValue = new P11AttrValue(osobject,P11Attribute::ck1|P11Attribute::ck4|P11Attribute::ck6|P11Attribute::ck7);
+        P11Attribute* attrPrivateHandle = new P11AttrPrivateHandle(osobject);
 
        // Initialize the attributes
        if
        (
                !attrEcParams->init() ||
+                !attrPrivateHandle->init() ||
                !attrValue->init()
        )
        {
                ERROR_MSG("Could not initialize the attribute");
                delete attrEcParams;
                delete attrValue;
+                delete attrPrivateHandle;
                return false;
        }
 
        // Add them to the map
        attributes[attrEcParams->getType()] = attrEcParams;
        attributes[attrValue->getType()] = attrValue;
+        attributes[attrPrivateHandle->getType()] = attrPrivateHandle;
 
        initialized = true;
        return true;
index 214178f..acb90a3 100644 (file)
@@ -103,37 +103,26 @@ 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);
+static CK_RV Extract_key_handle(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, void *private_handle)
+{
+    CK_RV rv=CK_TRUE;
 
-  rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE));
+    // get value of the wrapped data (ck)
+    CK_ATTRIBUTE valAttrib[] = {
+      {CKA_OS_PRIVATE_HANDLE,  NULL_PTR,   sizeof(CK_ULONG)}
+    };
 
-  // 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);
+    *(CK_ULONG*)private_handle = 0;
+    valAttrib[0].pValue = private_handle;
 
-  if(!(valAttrib[0].pValue))
-  {
-    free(valAttrib[0].pValue);
-  }
+    rv = C_GetAttributeValue(hSession, hObject, valAttrib, sizeof(valAttrib)/sizeof(CK_ATTRIBUTE));
+    if (rv != CKR_OK)
+    {
+       LOG("C_GetAttributeValue() API failed ! %lx\n", rv);
+    }
 
-  return rv;
+    return rv;
 }
 
 static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERTIFICATE_TYPE certType, P11Object **p11object)
@@ -4214,24 +4203,25 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
                return CKR_MECHANISM_INVALID;
 #endif
         }
-
     // Initialize signing
     if(isHWavailable)
     {
         // Extract HW key handle
         CK_ULONG hwKeyHandle = 0;
-        if(!Extract_key_handle (hSession, hKey, &hwKeyHandle))
+        if(Extract_key_handle (hSession, hKey, &hwKeyHandle) != CKR_OK)
         {
             LOG("ERROR in extracting key handle \n");
             session->resetOp();
             return CKR_GENERAL_ERROR;
         }
         LOG("Extracted key handle value: %lu \n", hwKeyHandle);
+        void *hwCryptoOpaque;
 
-        if(! HwInfraSignInit(&hwKeyHandle, mechanism, param, paramLen))
+        if(HwInfraSignInit(&hwKeyHandle, mechanism, param, paramLen, &hwCryptoOpaque) != 0)
         {
             return CKR_MECHANISM_INVALID;
         }
+        session->setHwCryptoOpaque(hwCryptoOpaque);
     }
     else
     {
@@ -4249,8 +4239,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);
-
+        session->setKeyHandle(hKey);
        return CKR_OK;
 }
 
@@ -4403,7 +4392,7 @@ static CK_RV AsymSignHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PT
        AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
        AsymMech::Type mechanism = session->getMechanism();
        PrivateKey* privateKey = session->getPrivateKey();
-    CK_ULONG hwKeyHandle = 0;
+        CK_ULONG hwKeyHandle = 0;
        if (asymCrypto == NULL || !session->getAllowSinglePartOp() || privateKey == NULL)
        {
                session->resetOp();
@@ -4438,7 +4427,7 @@ static CK_RV AsymSignHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PT
 
        // Extract HW key handle
     CK_OBJECT_HANDLE hKey = session->getKeyHandle();
-    if(!Extract_key_handle (hSession, hKey, &hwKeyHandle))
+    if(Extract_key_handle (hSession, hKey, &hwKeyHandle) != CKR_OK)
     {
         LOG("ERROR in extracting key handle \n");
                session->resetOp();
@@ -4446,10 +4435,11 @@ static CK_RV AsymSignHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PT
     }
     LOG("Extracted key handle value: %lu \n", hwKeyHandle);
 
+    void *hwCryptoOpaque = session->getHwCryptoOpaque();
        // Sign the data
-    if(!HwInfraSign((void *)&hwKeyHandle, mechanism,
-                 pData, ulDataLen,
-                 pSignature, (int *) pulSignatureLen))
+    if(HwInfraSign((void *)&hwKeyHandle, mechanism,
+                 pData, ulDataLen, hwCryptoOpaque,
+                 pSignature, (int *) pulSignatureLen) != 0)
     {
                session->resetOp();
                return CKR_GENERAL_ERROR;
@@ -4559,6 +4549,60 @@ static CK_RV AsymSignUpdate(Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPart
        return CKR_OK;
 }
 
+// AsymmetricAlgorithm version of C_SignUpdate
+static CK_RV AsymSignUpdateHW( CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+        AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
+        if (asymCrypto == NULL || !session->getAllowMultiPartOp())
+        {
+                session->resetOp();
+                return CKR_OPERATION_NOT_INITIALIZED;
+        }
+
+        // Check if re-authentication is required
+        if (session->getReAuthentication())
+        {
+                session->resetOp();
+                return CKR_USER_NOT_LOGGED_IN;
+        }
+
+        // Get the part
+        ByteString part(pPart, ulPartLen);
+
+#if 0
+        // Sign the data
+        if (!asymCrypto->signUpdate(part))
+        {
+                session->resetOp();
+                return CKR_GENERAL_ERROR;
+        }
+#endif
+    AsymMech::Type mechanism = session->getMechanism();
+    // Extract HW key handle
+    CK_ULONG hwKeyHandle = 0;
+    CK_OBJECT_HANDLE hKey = session->getKeyHandle();
+    if(Extract_key_handle (hSession, hKey, &hwKeyHandle) != CKR_OK)
+    {
+        LOG("ERROR in extracting key handle \n");
+                session->resetOp();
+                return CKR_GENERAL_ERROR;
+    }
+
+    void *hwCryptoOpaque = session->getHwCryptoOpaque();
+        // Sign the data
+    if(HwInfraSignUpdate((void *)&hwKeyHandle, mechanism,
+                 pPart, ulPartLen, hwCryptoOpaque ) != 0)
+    {
+                session->resetOp();
+                return CKR_GENERAL_ERROR;
+    }
+
+        session->setAllowSinglePartOp(false);
+        return CKR_OK;
+}
+
+
+
 // Update a running signing operation with additional data
 CK_RV SoftHSM::C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
 {
@@ -4577,7 +4621,17 @@ CK_RV SoftHSM::C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_UL
        if (session->getMacOp() != NULL)
                return MacSignUpdate(session, pPart, ulPartLen);
        else
-               return AsymSignUpdate(session, pPart, ulPartLen);
+        {
+                if(isHWavailable)
+                {
+                  return AsymSignUpdateHW(hSession, session, pPart, ulPartLen);
+                }
+                else
+                {
+
+                 return AsymSignUpdate(session, pPart, ulPartLen);
+                }
+        }
 }
 
 // MacAlgorithm version of C_SignFinal
@@ -4682,6 +4736,81 @@ static CK_RV AsymSignFinal(Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PT
        return CKR_OK;
 }
 
+// AsymmetricAlgorithm version of C_SignFinal
+static CK_RV AsymSignFinalHW(CK_SESSION_HANDLE hSession, Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+        AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
+        PrivateKey* privateKey = session->getPrivateKey();
+        if (asymCrypto == NULL || privateKey == NULL)
+        {
+                session->resetOp();
+                return CKR_OPERATION_NOT_INITIALIZED;
+        }
+
+        // Check if re-authentication is required
+        if (session->getReAuthentication())
+        {
+                session->resetOp();
+                return CKR_USER_NOT_LOGGED_IN;
+        }
+
+        // Size of the signature
+        CK_ULONG size = privateKey->getOutputLength();
+        if (pSignature == NULL_PTR)
+        {
+                *pulSignatureLen = size;
+                return CKR_OK;
+        }
+
+        // Check buffer size
+        if (*pulSignatureLen < size)
+        {
+                *pulSignatureLen = size;
+                return CKR_BUFFER_TOO_SMALL;
+        }
+#if 0
+        // Get the signature
+        ByteString signature;
+        if (!asymCrypto->signFinal(signature))
+        {
+                session->resetOp();
+                return CKR_GENERAL_ERROR;
+        }
+#endif
+    AsymMech::Type mechanism = session->getMechanism();
+    // Extract HW key handle
+    CK_ULONG hwKeyHandle = 0;
+    CK_OBJECT_HANDLE hKey = session->getKeyHandle();
+    if(Extract_key_handle (hSession, hKey, &hwKeyHandle) != CKR_OK)
+    {
+        LOG("ERROR in extracting key handle \n");
+                session->resetOp();
+                return CKR_GENERAL_ERROR;
+    }
+    LOG("Extracted key handle value   : 0x%lx \n", hwKeyHandle);
+
+    void *hwCryptoOpaque = session->getHwCryptoOpaque();
+        // Sign the data
+    if(HwInfraSignFinal((void *)&hwKeyHandle, mechanism,
+                 hwCryptoOpaque, pSignature, (int *) pulSignatureLen) != 0 )
+    {
+                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;
+    }
+    *pulSignatureLen = size;
+
+     session->resetOp();
+     return CKR_OK;
+}
+
+
 // Finalise a running signing operation and return the signature
 CK_RV SoftHSM::C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
 {
@@ -4700,7 +4829,15 @@ CK_RV SoftHSM::C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, C
        if (session->getMacOp() != NULL)
                return MacSignFinal(session, pSignature, pulSignatureLen);
        else
-               return AsymSignFinal(session, pSignature, pulSignatureLen);
+                if(isHWavailable)
+                {
+                  return AsymSignFinalHW(hSession, session, pSignature, pulSignatureLen);
+                }
+                else
+                {
+
+                 return AsymSignFinal(session, pSignature, pulSignatureLen);
+                }
 }
 
 // Initialise a signing operation that allows recovery of the signed data
index d2515bd..a55a32a 100644 (file)
@@ -385,6 +385,7 @@ static bool isModifiable(CK_ATTRIBUTE_TYPE type)
        case CKA_OS_TOKENFLAGS:
        case CKA_OS_SOPIN:
        case CKA_OS_USERPIN:
+        case CKA_OS_PRIVATE_HANDLE:
                return true;
        default:
                return false;
@@ -516,6 +517,7 @@ static AttributeKind attributeKind(CK_ATTRIBUTE_TYPE type)
        case CKA_OS_TOKENFLAGS: return akInteger;
        case CKA_OS_SOPIN: return akBinary;
        case CKA_OS_USERPIN: return akBinary;
+        case CKA_OS_PRIVATE_HANDLE: return akInteger;
 
        default: return akUnknown;
        }
index dfc5869..176ca02 100644 (file)
@@ -46,5 +46,7 @@
 #define CKA_OS_SOPIN           (CKA_VENDOR_SOFTHSM + 4)
 #define CKA_OS_USERPIN         (CKA_VENDOR_SOFTHSM + 5)
 
+#define CKA_OS_PRIVATE_HANDLE                (CKA_VENDOR_SOFTHSM + 6)
+
 #endif // !_SOFTHSM_V2_OSATTRIBUTES_H
 
index 54c0ff7..67820ed 100644 (file)
@@ -61,6 +61,7 @@ Session::Session(Slot* inSlot, bool inIsReadWrite, CK_VOID_PTR inPApplication, C
 
        // Storing Key handle in session
        hKey = CK_INVALID_HANDLE;
+        hwCryptoOpaque = NULL;
 }
 
 // Constructor
@@ -91,6 +92,7 @@ Session::Session()
 
     // Storing Key handle in session
     hKey = CK_INVALID_HANDLE;
+       hwCryptoOpaque = NULL;
 }
 
 // Destructor
@@ -471,3 +473,14 @@ SymmetricKey* Session::getSymmetricKey()
 {
        return symmetricKey;
 }
+
+void Session::setHwCryptoOpaque(void *inHwCryptoOpaque )
+{
+        hwCryptoOpaque = inHwCryptoOpaque;
+}
+
+void*  Session::getHwCryptoOpaque()
+{
+        return hwCryptoOpaque;
+}
+
index 128fb2b..39f19db 100644 (file)
@@ -127,6 +127,9 @@ public:
        void setKeyHandle(CK_OBJECT_HANDLE inHKey);
        CK_OBJECT_HANDLE getKeyHandle();
 
+        void setHwCryptoOpaque(void* inHwCryptoOpaque);
+        void *getHwCryptoOpaque();
+
 private:
        // Constructor
        Session();
@@ -174,6 +177,9 @@ private:
        // Symmetric Crypto
        SymmetricKey* symmetricKey;
 
+        // hw plugin specific data
+        void *hwCryptoOpaque;
+
     // Storing Key handle in session
     CK_OBJECT_HANDLE hKey;
 };