aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SoftHSMv2/src/lib/HwInfra/HwInfra.cpp (renamed from SoftHSMv2/src/lib/HwInfra/HwInfra.c)181
-rw-r--r--SoftHSMv2/src/lib/HwInfra/HwInfra.h21
-rw-r--r--SoftHSMv2/src/lib/HwInfra/Makefile.am2
-rwxr-xr-xSoftHSMv2/src/lib/HwInfra/hwpluginif.h60
-rw-r--r--SoftHSMv2/src/lib/P11Attributes.cpp34
-rw-r--r--SoftHSMv2/src/lib/P11Attributes.h19
-rw-r--r--SoftHSMv2/src/lib/P11Objects.cpp8
-rw-r--r--SoftHSMv2/src/lib/SoftHSM.cpp213
-rw-r--r--SoftHSMv2/src/lib/object_store/DBObject.cpp2
-rw-r--r--SoftHSMv2/src/lib/object_store/OSAttributes.h2
-rw-r--r--SoftHSMv2/src/lib/session_mgr/Session.cpp13
-rw-r--r--SoftHSMv2/src/lib/session_mgr/Session.h6
-rw-r--r--[-rwxr-xr-x]TPM2-Plugin/bootstrap0
-rw-r--r--TPM2-Plugin/lib/include/hwpluginif.h35
-rw-r--r--TPM2-Plugin/lib/include/tpm2_plugin_api.h63
-rw-r--r--TPM2-Plugin/lib/tpm2_plugin_api.c132
-rw-r--r--TPM2-Plugin/lib/tpm2_plugin_init.c16
-rw-r--r--TPM2-Plugin/test/main.c5
-rw-r--r--bin/README.md27
-rwxr-xr-xbin/entrypoint.sh11
-rw-r--r--bin/tpmdockerfile62
-rw-r--r--build.sh2
22 files changed, 766 insertions, 148 deletions
diff --git a/SoftHSMv2/src/lib/HwInfra/HwInfra.c b/SoftHSMv2/src/lib/HwInfra/HwInfra.cpp
index 528097d..557630b 100644
--- a/SoftHSMv2/src/lib/HwInfra/HwInfra.c
+++ b/SoftHSMv2/src/lib/HwInfra/HwInfra.cpp
@@ -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) );
}
diff --git a/SoftHSMv2/src/lib/HwInfra/HwInfra.h b/SoftHSMv2/src/lib/HwInfra/HwInfra.h
index a62bd7d..8cbbada 100644
--- a/SoftHSMv2/src/lib/HwInfra/HwInfra.h
+++ b/SoftHSMv2/src/lib/HwInfra/HwInfra.h
@@ -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)
}
diff --git a/SoftHSMv2/src/lib/HwInfra/Makefile.am b/SoftHSMv2/src/lib/HwInfra/Makefile.am
index b327b15..3ff3726 100644
--- a/SoftHSMv2/src/lib/HwInfra/Makefile.am
+++ b/SoftHSMv2/src/lib/HwInfra/Makefile.am
@@ -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 =
diff --git a/SoftHSMv2/src/lib/HwInfra/hwpluginif.h b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h
index b078be3..a8ade2a 100755
--- a/SoftHSMv2/src/lib/HwInfra/hwpluginif.h
+++ b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h
@@ -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;
diff --git a/SoftHSMv2/src/lib/P11Attributes.cpp b/SoftHSMv2/src/lib/P11Attributes.cpp
index 28d0f9b..5a56097 100644
--- a/SoftHSMv2/src/lib/P11Attributes.cpp
+++ b/SoftHSMv2/src/lib/P11Attributes.cpp
@@ -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;
+}
+
+
diff --git a/SoftHSMv2/src/lib/P11Attributes.h b/SoftHSMv2/src/lib/P11Attributes.h
index 3cddf30..7cc9976 100644
--- a/SoftHSMv2/src/lib/P11Attributes.h
+++ b/SoftHSMv2/src/lib/P11Attributes.h
@@ -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
diff --git a/SoftHSMv2/src/lib/P11Objects.cpp b/SoftHSMv2/src/lib/P11Objects.cpp
index c58d4ec..3e663b2 100644
--- a/SoftHSMv2/src/lib/P11Objects.cpp
+++ b/SoftHSMv2/src/lib/P11Objects.cpp
@@ -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;
diff --git a/SoftHSMv2/src/lib/SoftHSM.cpp b/SoftHSMv2/src/lib/SoftHSM.cpp
index 214178f..acb90a3 100644
--- a/SoftHSMv2/src/lib/SoftHSM.cpp
+++ b/SoftHSMv2/src/lib/SoftHSM.cpp
@@ -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
diff --git a/SoftHSMv2/src/lib/object_store/DBObject.cpp b/SoftHSMv2/src/lib/object_store/DBObject.cpp
index d2515bd..a55a32a 100644
--- a/SoftHSMv2/src/lib/object_store/DBObject.cpp
+++ b/SoftHSMv2/src/lib/object_store/DBObject.cpp
@@ -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;
}
diff --git a/SoftHSMv2/src/lib/object_store/OSAttributes.h b/SoftHSMv2/src/lib/object_store/OSAttributes.h
index dfc5869..176ca02 100644
--- a/SoftHSMv2/src/lib/object_store/OSAttributes.h
+++ b/SoftHSMv2/src/lib/object_store/OSAttributes.h
@@ -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
diff --git a/SoftHSMv2/src/lib/session_mgr/Session.cpp b/SoftHSMv2/src/lib/session_mgr/Session.cpp
index 54c0ff7..67820ed 100644
--- a/SoftHSMv2/src/lib/session_mgr/Session.cpp
+++ b/SoftHSMv2/src/lib/session_mgr/Session.cpp
@@ -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;
+}
+
diff --git a/SoftHSMv2/src/lib/session_mgr/Session.h b/SoftHSMv2/src/lib/session_mgr/Session.h
index 128fb2b..39f19db 100644
--- a/SoftHSMv2/src/lib/session_mgr/Session.h
+++ b/SoftHSMv2/src/lib/session_mgr/Session.h
@@ -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;
};
diff --git a/TPM2-Plugin/bootstrap b/TPM2-Plugin/bootstrap
index 2a09c33..2a09c33 100755..100644
--- a/TPM2-Plugin/bootstrap
+++ b/TPM2-Plugin/bootstrap
diff --git a/TPM2-Plugin/lib/include/hwpluginif.h b/TPM2-Plugin/lib/include/hwpluginif.h
index d016e37..aa40411 100644
--- a/TPM2-Plugin/lib/include/hwpluginif.h
+++ b/TPM2-Plugin/lib/include/hwpluginif.h
@@ -143,7 +143,7 @@ typedef int (*sshsm_hw_plugin_load_key)(
);
typedef int (*sshsm_hw_plugin_unload_key)(
- void **keyHandle
+ void **keyHandle
);
/***
@@ -156,7 +156,8 @@ typedef int (*sshsm_hw_plugin_rsa_sign_init)(
void *keyHandle,
unsigned long mechanism,
void *param,
- int len
+ int len,
+ void **plugin_data_ref
);
/***
@@ -175,10 +176,37 @@ typedef int (*sshsm_hw_plugin_rsa_sign)(
unsigned long mechanism,
unsigned char *msg,
int msg_len,
+ void *plugin_data_ref,
unsigned char *outsig,
int *outsiglen
);
+typedef int (*sshsm_hw_plugin_rsa_sign_update)(
+ void *keyHandle,
+ unsigned long mechnaism,
+ unsigned char *msg,
+ int msg_len,
+ void *plugin_data_ref
+ );
+
+typedef int (*sshsm_hw_plugin_rsa_sign_final)(
+ void *keyHandle,
+ unsigned long mechnaism,
+ void *plugin_data_ref,
+ 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 mechnaism,
+ void *plugin_data_ref
+ );
+
/***
* Function Name: sshsm_hw_plugin_get_plugin_functions
* Descrpiton: Every HW plugin is expected to define this function.
@@ -202,6 +230,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;
int sshsm_hw_plugin_get_plugin_functions(SSHSM_HW_FUNCTIONS_t *funcs);
diff --git a/TPM2-Plugin/lib/include/tpm2_plugin_api.h b/TPM2-Plugin/lib/include/tpm2_plugin_api.h
index f45c0bd..d96d2f9 100644
--- a/TPM2-Plugin/lib/include/tpm2_plugin_api.h
+++ b/TPM2-Plugin/lib/include/tpm2_plugin_api.h
@@ -141,6 +141,15 @@ typedef struct {
int version;
} common_opts_t;
+#define MAX_DATA_SIGNUPDATE 0x2000
+#define MAX_SESSIONS 0x1000
+
+typedef struct concatenate_data_signupdate {
+ unsigned long int session_handle;
+ unsigned char data_signupdate[MAX_DATA_SIGNUPDATE];
+ int data_length;
+}CONCATENATE_DATA_SIGNUPDATE_t;
+
int tpm2_plugin_init();
int tpm2_plugin_uninit();
int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info);
@@ -150,43 +159,49 @@ int tpm2_plugin_load_key(
SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *importkey_info
);
-int tpm2_rsa_create_object(
- unsigned long appHandle,
- //DhsmWPKRSAFormat* wpk,
- void *wpk,
- unsigned char* swk,
- int swk_len,
- unsigned char* iv,
- int iv_len,
- int tag_len,
- void **cb_object);
-
-int tpm2_rsa_delete_object(
- void *cb_object);
-
int tpm2_plugin_rsa_sign_init(
void *keyHandle,
unsigned long mechanism,
void *param,
- int len);
+ int len,
+ void **plugin_data_ref
+ );
int tpm2_plugin_rsa_sign(
void *keyHandle,
unsigned long mechanism,
unsigned char *msg,
int msg_len,
+ void *plugin_data_ref,
unsigned char *sig,
- int *sig_len);
+ int *sig_len
+ );
+
+int tpm2_plugin_rsa_sign_update(
+ void *keyHandle,
+ unsigned long mechnaism,
+ unsigned char *msg,
+ int msg_len,
+ void *plugin_data_ref
+ );
+
+int tpm2_plugin_rsa_sign_final(
+ void *keyHandle,
+ unsigned long mechnaism,
+ void *plugin_data_ref,
+ 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.
+***/
-int tpm2_import_object(
- unsigned long appHandle,
- unsigned char* tlvbuffer,
- int buflen,
- unsigned char* iv,
- int iv_len,
- unsigned char* tpm_pwd,
- int tpm_pwd_len);
+typedef int (*sshsm_hw_plugin_rsa_sign_cleanup)(
+ void *keyHandle,
+ unsigned long mechnaism,
+ void *plugin_data_ref
+ );
#ifdef __cplusplus
diff --git a/TPM2-Plugin/lib/tpm2_plugin_api.c b/TPM2-Plugin/lib/tpm2_plugin_api.c
index b949e48..75e4fc1 100644
--- a/TPM2-Plugin/lib/tpm2_plugin_api.c
+++ b/TPM2-Plugin/lib/tpm2_plugin_api.c
@@ -134,7 +134,6 @@ tcti_device_init (char const *device_file)
}
#endif
-
#ifdef HAVE_TCTI_SOCK
TSS2_TCTI_CONTEXT* tcti_socket_init (char const *address, uint16_t port)
{
@@ -491,17 +490,65 @@ struct tpm_sign_ctx {
TSS2_SYS_CONTEXT *sapi_context;
};
+//create a table to consolidate all parts of data from multiple SignUpdate from sessions
+CONCATENATE_DATA_SIGNUPDATE_t data_signupdate_session[MAX_SESSIONS];
+unsigned long sign_sequence_id = 0;
int tpm2_plugin_rsa_sign_init(
void *keyHandle,
unsigned long mechanism,
void *param,
- int len)
+ int len,
+ void **plugin_data_ref
+ )
{
- printf("rsa_sign_init API mechanism is %lx \n", mechanism);
+ printf("rsa_sign_init API mechanism is %ld \n", mechanism);
+ printf("rsa_sign_init API len is %d \n", len);
+ int i, j;
+
+ sign_sequence_id++;
+ unsigned long hSession = sign_sequence_id;
+
+ for (i = 0; i < MAX_SESSIONS; i++){
+ if (data_signupdate_session[i].session_handle == 0){
+ data_signupdate_session[i].session_handle = hSession;
+ for (j = 0; j < MAX_DATA_SIGNUPDATE; j++ )
+ data_signupdate_session[i].data_signupdate[j] = 0;
+ data_signupdate_session[i].data_length = 0;
+ }
+ }
+ *plugin_data_ref = (void *)hSession;
+
printf("rsa_sign_init API done for tpm2_plugin... \n");
return 0;
}
+/** 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.
+***/
+
+int tpm2_plugin_rsa_sign_cleanup(
+ void *keyHandle,
+ unsigned long mechnaism,
+ void *plugin_data_ref
+ )
+{
+ int i, j;
+ unsigned long hSession = (unsigned long)plugin_data_ref;
+ for (i = 0; i < MAX_SESSIONS; i++) {
+ if (data_signupdate_session[i].session_handle == hSession){
+ data_signupdate_session[i].session_handle = 0;
+ for (j =0; j < MAX_DATA_SIGNUPDATE; j++ )
+ data_signupdate_session[i].data_signupdate[j] =0;
+ data_signupdate_session[i].data_length = 0;
+ }
+ }
+
+ if (sign_sequence_id>0xfffffffe)
+ sign_sequence_id =0;
+ return 0;
+}
+
+
UINT32 tpm_hash(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH hashAlg,
UINT16 size, BYTE *data, TPM2B_DIGEST *result) {
TPM2B_MAX_BUFFER dataSizedBuffer;
@@ -570,8 +617,10 @@ int tpm_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, BYTE *buffer,
if (length <= MAX_DIGEST_BUFFER) {
if (tpm_hash(sapi_context, halg, length, buffer,
- result) == TPM_RC_SUCCESS)
+ result) == TPM_RC_SUCCESS){
+ printf("Single hash result size: %d\n", result->t.size);
return 0;
+ }
else
return -1;
}
@@ -595,6 +644,7 @@ int tpm_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, BYTE *buffer,
TPM_RC rval = hash_sequence_ex(sapi_context, halg, numBuffers, bufferList, result);
free(bufferList);
+ printf("Sequence hash result size: %d\n", result->t.size);
return rval == TPM_RC_SUCCESS ? 0 : -3;
}
@@ -661,12 +711,10 @@ static bool set_scheme(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT keyHandle,
return true;
}
-static bool sign_and_save(tpm_sign_ctx *ctx, unsigned char *sig, int *sig_len) {
+static bool sign_and_save(tpm_sign_ctx *ctx, TPMT_SIGNATURE *sig) {
TPM2B_DIGEST digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
TPMT_SIG_SCHEME in_scheme;
- TPMT_SIGNATURE signature;
- int signature_len;
TSS2_SYS_CMD_AUTHS sessions_data;
TPMS_AUTH_RESPONSE session_data_out;
TSS2_SYS_RSP_AUTHS sessions_data_out;
@@ -686,6 +734,8 @@ static bool sign_and_save(tpm_sign_ctx *ctx, unsigned char *sig, int *sig_len)
return false;
}
+ printf("Compute message hash digest size : %d \n", digest.t.size);
+
bool result = set_scheme(ctx->sapi_context, ctx->keyHandle, ctx->halg, &in_scheme);
if (!result) {
return false;
@@ -693,17 +743,14 @@ static bool sign_and_save(tpm_sign_ctx *ctx, unsigned char *sig, int *sig_len)
TPM_RC rval = Tss2_Sys_Sign(ctx->sapi_context, ctx->keyHandle,
&sessions_data, &digest, &in_scheme,
- &ctx->validation, &signature,
+ &ctx->validation, sig,
&sessions_data_out);
if (rval != TPM_RC_SUCCESS) {
printf("Sys_Sign failed, error code: 0x%x", rval);
return false;
}
- signature_len = sizeof(signature);
- sig_len = &signature_len;
- sig = (unsigned char *)&signature;
-
+
return true;
}
@@ -712,11 +759,13 @@ int tpm2_plugin_rsa_sign(
unsigned long mechanism,
unsigned char *msg,
int msg_len,
+ void *plugin_data_ref,
unsigned char *sig,
int *sig_len)
{
TPM_RC rval;
common_opts_t opts = COMMON_OPTS_INITIALIZER;
+ TPMT_SIGNATURE signature;
TSS2_TCTI_CONTEXT *tcti_ctx;
tcti_ctx = tcti_init_from_options(&opts);
if (tcti_ctx == NULL)
@@ -739,12 +788,15 @@ int tpm2_plugin_rsa_sign(
.validation = { 0 },
.sapi_context = sapi_context
};
-
+
printf("rsa_sign API mechanism is %lx \n", mechanism);
ctx.sessionData.sessionHandle = TPM_RS_PW;
ctx.validation.tag = TPM_ST_HASHCHECK;
ctx.validation.hierarchy = TPM_RH_NULL;
- ctx.halg = TPM_ALG_SHA256;
+ if (mechanism == 7)
+ ctx.halg = TPM_ALG_SHA256;
+ else
+ printf("mechanism not supported! \n");
ctx.keyHandle = *(TPMI_DH_OBJECT *)keyHandle;
rval = Tss2_Sys_ContextLoad(ctx.sapi_context, &loaded_key_context, &ctx.keyHandle);
@@ -755,11 +807,15 @@ int tpm2_plugin_rsa_sign(
ctx.length = msg_len;
ctx.msg = msg;
- if (!sign_and_save(&ctx, sig, sig_len)){
+ if (!sign_and_save(&ctx, &signature)){
printf("RSA sign failed\n");
goto out;
}
+ *sig_len = (int)signature.signature.rsassa.sig.t.size;
+ printf("signature length: %d \n", *sig_len);
+ memcpy(sig, signature.signature.rsassa.sig.t.buffer, *sig_len);
+ printf("signature buffer size: %ld \n", sizeof(signature.signature.rsassa.sig.t.buffer));
printf("RSA sign API successful in TPM plugin ! \n");
out:
@@ -769,4 +825,50 @@ out:
}
+int tpm2_plugin_rsa_sign_update(
+ void *keyHandle,
+ unsigned long mechanism,
+ unsigned char *msg,
+ int msg_len,
+ void *plugin_data_ref
+ )
+{
+ int i, j, n;
+ unsigned long hSession = (unsigned long)plugin_data_ref;
+ for (i = 0; i < MAX_SESSIONS; i++){
+ if (data_signupdate_session[i].session_handle == hSession){
+ n = data_signupdate_session[i].data_length;
+ for (j =0; j < msg_len; j++ )
+ data_signupdate_session[i].data_signupdate[n + j] = msg[j];
+ data_signupdate_session[i].data_length += msg_len;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int tpm2_plugin_rsa_sign_final(
+ void *keyHandle,
+ unsigned long mechanism,
+ void *plugin_data_ref,
+ unsigned char *outsig,
+ int *outsiglen
+ )
+{
+ int i, j;
+ unsigned long hSession = (unsigned long)plugin_data_ref;
+ unsigned char *msg;
+ int msg_len;
+ for (i = 0; i < MAX_SESSIONS; i++){
+ if (data_signupdate_session[i].session_handle == hSession){
+ msg = data_signupdate_session[i].data_signupdate;
+ msg_len = data_signupdate_session[i].data_length;
+ tpm2_plugin_rsa_sign(keyHandle, mechanism, msg, msg_len, plugin_data_ref, outsig, outsiglen);
+ tpm2_plugin_rsa_sign_cleanup(keyHandle, mechanism, plugin_data_ref);
+ return 0;
+ }
+ }
+
+ return -1;
+}
diff --git a/TPM2-Plugin/lib/tpm2_plugin_init.c b/TPM2-Plugin/lib/tpm2_plugin_init.c
index b221bd2..ef32330 100644
--- a/TPM2-Plugin/lib/tpm2_plugin_init.c
+++ b/TPM2-Plugin/lib/tpm2_plugin_init.c
@@ -20,13 +20,15 @@
int sshsm_hw_plugin_get_plugin_functions(SSHSM_HW_FUNCTIONS_t *funcs)
{
printf("%s(): Assigning Function pointers for TPM (dTPM or PTT) mode \n", __func__);
- funcs->xxx_init = &tpm2_plugin_init;
- funcs->xxx_uninit = &tpm2_plugin_uninit;
- funcs->xxx_activate = &tpm2_plugin_activate;
- funcs->xxx_load_key = &tpm2_plugin_load_key;
- funcs->xxx_unload_key = NULL;
- funcs->xxx_rsa_sign_init = &tpm2_plugin_rsa_sign_init;
- funcs->xxx_rsa_sign = &tpm2_plugin_rsa_sign;
+ funcs->xxx_init = &tpm2_plugin_init;
+ funcs->xxx_uninit = &tpm2_plugin_uninit;
+ funcs->xxx_activate = &tpm2_plugin_activate;
+ funcs->xxx_load_key = &tpm2_plugin_load_key;
+ funcs->xxx_unload_key = NULL;
+ funcs->xxx_rsa_sign_init = &tpm2_plugin_rsa_sign_init;
+ funcs->xxx_rsa_sign_update = &tpm2_plugin_rsa_sign_update;
+ funcs->xxx_rsa_sign_final = &tpm2_plugin_rsa_sign_final;
+ funcs->xxx_rsa_sign = &tpm2_plugin_rsa_sign;
return 0;
}
diff --git a/TPM2-Plugin/test/main.c b/TPM2-Plugin/test/main.c
index 31fa7d6..046b3d7 100644
--- a/TPM2-Plugin/test/main.c
+++ b/TPM2-Plugin/test/main.c
@@ -24,6 +24,7 @@ void main(void)
void *param = NULL;
size_t len = 100;
void *keyHandle_sign = NULL;
+ unsigned long int hSession = 1;
unsigned char *msg;
int msg_len;
@@ -59,12 +60,12 @@ void main(void)
tpm2_plugin_activate(activate_in_info);
printf("---------------------------------------------\n");
- tpm2_plugin_rsa_sign_init(keyHandle_sign, mechanism, param, len);
+ tpm2_plugin_rsa_sign_init(keyHandle_sign, mechanism, param, len, (void *)hSession);
printf("---------------------------------------------\n");
tpm2_plugin_load_key(loadkey_in_info, keyHandle, importkey_info);
printf("---------------------------------------------\n");
- tpm2_plugin_rsa_sign(keyHandle_sign, mechanism, msg, msg_len, sig, sig_len);
+ tpm2_plugin_rsa_sign(keyHandle_sign, mechanism, msg, msg_len, (void *)hSession, sig, sig_len);
}
diff --git a/bin/README.md b/bin/README.md
new file mode 100644
index 0000000..c4c54ca
--- /dev/null
+++ b/bin/README.md
@@ -0,0 +1,27 @@
+### Building Docker Images
+
+```
+$ docker build -t <image name> -f tpmdockerfile .
+```
+
+### Running ABRMD Container
+
+```
+$ docker run -d --privileged -v /tmp/run/dbus:/var/run/dbus --name <container name> <image name>
+```
+
+### Running Tools Container
+This command will drop you into the tools container with everything setup appropriately:
+```
+# Runs without any privileges.
+# Requires that the dbus be mounted from the same host folder
+# This is to enable communication between the tools and ABRMD
+$ docker run -v /tmp/run/dbus:/var/run/dbus --name <container name> -it --entrypoint /bin/bash <image name>
+```
+
+##### Sanity Check
+Run the following command in the tools container to see if everything is setup correctly:
+
+```
+tpm2_listpcrs
+```
diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh
new file mode 100755
index 0000000..b13c681
--- /dev/null
+++ b/bin/entrypoint.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -e
+
+# Start DBUS
+mkdir -p /var/run/dbus
+stdbuf -oL -eL dbus-daemon --system --nofork 2>&1 1> /var/log/dbus-daemon.log &
+
+# Start Resource Manager
+hostip=$(ip route show | awk '/default/ {print $3}')
+echo "Connecting to $hostip\n"
+tpm2-abrmd -a $hostip -t socket \ No newline at end of file
diff --git a/bin/tpmdockerfile b/bin/tpmdockerfile
new file mode 100644
index 0000000..d1c9480
--- /dev/null
+++ b/bin/tpmdockerfile
@@ -0,0 +1,62 @@
+FROM ubuntu:xenial
+
+RUN apt-get -y update && \
+ apt-get -y install \
+ autoconf \
+ autoconf-archive \
+ libglib2.0-dev \
+ libdbus-1-dev \
+ automake \
+ libtool \
+ autotools-dev \
+ libcppunit-dev \
+ p11-kit \
+ libcurl4-gnutls-dev \
+ libcmocka0 \
+ libcmocka-dev \
+ build-essential \
+ git \
+ pkg-config \
+ gcc \
+ g++ \
+ m4 \
+ wget \
+ liburiparser-dev \
+ libssl-dev \
+ pandoc
+
+RUN apt-get -y install libgcrypt20-dev
+
+RUN git clone https://github.com/tpm2-software/tpm2-tss.git
+RUN git clone https://github.com/tpm2-software/tpm2-abrmd.git
+RUN git clone https://github.com/tpm2-software/tpm2-tools.git
+
+RUN cd tpm2-tss && \
+ git checkout 1.2.0 && \
+ ./bootstrap && \
+ ./configure && \
+ make && \
+ make install
+
+RUN cd tpm2-abrmd && \
+ git checkout 1.1.1 && \
+ useradd --system --user-group tss && \
+ ./bootstrap && \
+ ./configure --with-dbuspolicydir=/etc/dbus-1/system.d \
+ --with-udevrulesdir=/etc/udev/rules.d/ \
+ --with-systemdsystemunitdir=/lib/systemd/system && \
+ make && \
+ make install
+
+RUN cd tpm2-tools && \
+ git checkout 2.1.0 && \
+ ./bootstrap && \
+ ./configure --with-tcti-tabrmd=yes && \
+ make && \
+ make install
+
+RUN echo "/usr/local/lib" > /etc/ld.so.conf.d/tpm2.conf && \
+ ldconfig
+
+ADD entrypoint.sh /entrypoint.sh
+ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file
diff --git a/build.sh b/build.sh
index 369974c..8e44eb9 100644
--- a/build.sh
+++ b/build.sh
@@ -1,4 +1,4 @@
-#!/etc/bash
+#!/bin/bash
#set -e
sudo kill -9 $(ps -ef | grep "apt" | grep -v grep | awk '{print $2}')