summaryrefslogtreecommitdiff
path: root/src/tspi/obj_rsakey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tspi/obj_rsakey.c')
-rw-r--r--src/tspi/obj_rsakey.c2136
1 files changed, 2136 insertions, 0 deletions
diff --git a/src/tspi/obj_rsakey.c b/src/tspi/obj_rsakey.c
new file mode 100644
index 0000000..3f509f1
--- /dev/null
+++ b/src/tspi/obj_rsakey.c
@@ -0,0 +1,2136 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2005, 2007
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "trousers/tss.h"
+#include "trousers/trousers.h"
+#include "trousers_types.h"
+#include "spi_utils.h"
+#include "capabilities.h"
+#include "tsplog.h"
+#include "obj.h"
+
+TSS_RESULT
+obj_rsakey_add(TSS_HCONTEXT tspContext, TSS_FLAG initFlags, TSS_HOBJECT *phObject)
+{
+ UINT64 offset;
+ TSS_RESULT result;
+ TCPA_RSA_KEY_PARMS rsaKeyParms;
+ TSS_FLAG flags = 0;
+ struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj));
+ TPM_STRUCT_VER ver = { 1, 1, 0, 0 }; // Must be 1.1.0.0 for 1.2 TPMs
+ UINT32 ctx_ver;
+
+ if (rsakey == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj));
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) {
+ free(rsakey);
+ return result;
+ }
+
+ if ((initFlags & TSS_KEY_STRUCT_BITMASK) == TSS_KEY_STRUCT_DEFAULT) {
+ /* Its not set, go with the context's default */
+ if ((result = obj_context_get_connection_version(tspContext, &ctx_ver))) {
+ free(rsakey);
+ return result;
+ }
+
+ switch (ctx_ver) {
+ case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2:
+ initFlags |= TSS_KEY_STRUCT_KEY12;
+ break;
+ case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1:
+ /* fall through */
+ default:
+ initFlags |= TSS_KEY_STRUCT_KEY;
+ break;
+ }
+ }
+
+ offset = 0;
+ switch (initFlags & TSS_KEY_STRUCT_BITMASK) {
+ case TSS_KEY_STRUCT_KEY:
+ rsakey->key.hdr.key11.ver = ver;
+ rsakey->type = TSS_KEY_STRUCT_KEY;
+ rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO;
+ rsakey->key.keyFlags = 0;
+ break;
+ case TSS_KEY_STRUCT_KEY12:
+ rsakey->key.hdr.key12.tag = TPM_TAG_KEY12;
+ rsakey->key.hdr.key12.fill = 0;
+ rsakey->type = TSS_KEY_STRUCT_KEY12;
+ rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
+ rsakey->key.keyFlags = TPM_PCRIGNOREDONREAD;
+ break;
+ default:
+ free(rsakey);
+ return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG);
+ break;
+ }
+
+ if (initFlags == TSS_KEY_EMPTY_KEY)
+ goto add_key;
+
+ memset(&rsaKeyParms, 0, sizeof(TCPA_RSA_KEY_PARMS));
+
+ rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA;
+ rsakey->key.algorithmParms.parmSize = sizeof(TCPA_RSA_KEY_PARMS);
+
+ rsakey->key.algorithmParms.parms = calloc(1, sizeof(TCPA_RSA_KEY_PARMS));
+ if (rsakey->key.algorithmParms.parms == NULL) {
+ LogError("calloc of %u bytes failed.", rsakey->key.algorithmParms.parmSize);
+ free(rsakey);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ rsaKeyParms.exponentSize = 0;
+ rsaKeyParms.numPrimes = 2;
+
+ rsakey->key.pubKey.keyLength = 0;
+ rsakey->key.encSize = 0;
+ rsakey->key.PCRInfoSize = 0;
+
+ /* End of all the default stuff */
+
+ if (initFlags & TSS_KEY_VOLATILE)
+ rsakey->key.keyFlags |= TPM_VOLATILE;
+ if (initFlags & TSS_KEY_MIGRATABLE)
+ rsakey->key.keyFlags |= TPM_MIGRATABLE;
+ if (initFlags & TSS_KEY_AUTHORIZATION) {
+ rsakey->key.authDataUsage = TPM_AUTH_ALWAYS;
+ flags |= TSS_OBJ_FLAG_USAGEAUTH;
+ }
+
+#ifdef TSS_BUILD_CMK
+ if (initFlags & TSS_KEY_CERTIFIED_MIGRATABLE) {
+ if (rsakey->type == TSS_KEY_STRUCT_KEY) {
+ free(rsakey);
+ return TSPERR(TSS_E_BAD_PARAMETER);
+ }
+ rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY;
+ }
+#endif
+
+ /* set the key length */
+ if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_512) {
+ rsaKeyParms.keyLength = 512;
+ } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_1024) {
+ rsaKeyParms.keyLength = 1024;
+ } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_2048) {
+ rsaKeyParms.keyLength = 2048;
+ } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_4096) {
+ rsaKeyParms.keyLength = 4096;
+ } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_8192) {
+ rsaKeyParms.keyLength = 8192;
+ } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_16384) {
+ rsaKeyParms.keyLength = 16384;
+ }
+
+ /* assign encryption and signature schemes */
+ if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_SIGNING) {
+ rsakey->key.keyUsage = TPM_KEY_SIGNING;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
+ } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_BIND) {
+ rsakey->key.keyUsage = TPM_KEY_BIND;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
+ } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_LEGACY) {
+ rsakey->key.keyUsage = TPM_KEY_LEGACY;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
+ } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_STORAGE) {
+ rsakey->key.keyUsage = TPM_KEY_STORAGE;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
+ } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_IDENTITY) {
+ rsakey->key.keyUsage = TPM_KEY_IDENTITY;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
+ } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_AUTHCHANGE) {
+ rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE;
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
+ }
+
+ /* Load the RSA key parms into the blob in the TCPA_KEY_PARMS pointer.
+ * If the exponent is left NULL, the parmSize variable will change
+ * here */
+ offset = 0;
+ Trspi_LoadBlob_RSA_KEY_PARMS(&offset, rsakey->key.algorithmParms.parms, &rsaKeyParms);
+ rsakey->key.algorithmParms.parmSize = offset;
+
+add_key:
+ if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phObject))) {
+ free(rsakey->key.algorithmParms.parms);
+ free(rsakey);
+ return result;
+ }
+
+ return TSS_SUCCESS;
+}
+
+/* Add a new rsakey to the list when its pulled from user PS */
+TSS_RESULT
+obj_rsakey_add_by_key(TSS_HCONTEXT tspContext, TSS_UUID *uuid, BYTE *key, TSS_FLAG flags,
+ TSS_HKEY *phKey)
+{
+ TSS_RESULT result;
+ UINT64 offset;
+ struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj));
+
+ if (rsakey == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj));
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID));
+
+ offset = 0;
+ if ((result = UnloadBlob_TSS_KEY(&offset, key, &rsakey->key))) {
+ free(rsakey);
+ return result;
+ }
+ if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
+ rsakey->type = TSS_KEY_STRUCT_KEY12;
+ else
+ rsakey->type = TSS_KEY_STRUCT_KEY;
+
+ flags |= TSS_OBJ_FLAG_KEY_SET;
+ if (rsakey->key.authDataUsage)
+ flags |= TSS_OBJ_FLAG_USAGEAUTH;
+
+ if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) {
+ free(rsakey);
+ return result;
+ }
+
+ if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phKey))) {
+ free_key_refs(&rsakey->key);
+ free(rsakey);
+ return result;
+ }
+
+ return TSS_SUCCESS;
+}
+
+TSS_BOOL
+obj_is_rsakey(TSS_HOBJECT hObject)
+{
+ TSS_BOOL answer = FALSE;
+
+ if ((obj_list_get_obj(&rsakey_list, hObject))) {
+ answer = TRUE;
+ obj_list_put(&rsakey_list);
+ }
+
+ return answer;
+}
+
+TSS_RESULT
+obj_rsakey_set_flags(TSS_HKEY hKey, UINT32 flags)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ rsakey->key.keyFlags = flags;
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_size(TSS_HKEY hKey, UINT32 len)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ rsakey->key.pubKey.keyLength = len/8;
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_key_parms(TSS_HKEY hKey, TCPA_KEY_PARMS *parms)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ free(rsakey->key.algorithmParms.parms);
+
+ memcpy(&rsakey->key.algorithmParms, parms, sizeof(TCPA_KEY_PARMS));
+
+ if (parms->parmSize > 0) {
+ if ((rsakey->key.algorithmParms.parms =
+ malloc(parms->parmSize)) == NULL) {
+ LogError("calloc of %d bytes failed.", parms->parmSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ memcpy(rsakey->key.algorithmParms.parms, parms->parms,
+ parms->parmSize);
+ } else {
+ rsakey->key.algorithmParms.parms = NULL;
+ }
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_policy(TSS_HKEY hKey, TSS_HPOLICY hPolicy)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ UINT32 policyType;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((result = obj_policy_get_type(hPolicy, &policyType)))
+ return result;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (policyType) {
+ case TSS_POLICY_USAGE:
+ rsakey->usagePolicy = hPolicy;
+ break;
+ case TSS_POLICY_MIGRATION:
+ rsakey->migPolicy = hPolicy;
+ break;
+ default:
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_pstype(TSS_HKEY hKey, UINT32 type)
+{
+ struct tsp_object *obj;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ switch (type) {
+ case TSS_PS_TYPE_USER:
+ obj->flags |= TSS_OBJ_FLAG_USER_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
+ break;
+ case TSS_PS_TYPE_SYSTEM:
+ obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
+ break;
+ case TSS_PS_TYPE_NO:
+ default:
+ obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+/* WARN: Nobody should call this function directly except for the
+ * Get/Set Attrib functions. The TCPA_KEY structure wants values
+ * for keyUsage to be TPM_KEY_* values, and this function translates
+ * to TSS_KEYUSAGE_* values for passing to an app. */
+TSS_RESULT
+obj_rsakey_get_usage(TSS_HKEY hKey, UINT32 *usage)
+{
+ TSS_RESULT result = TSS_SUCCESS;
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (rsakey->key.keyUsage) {
+ case TPM_KEY_SIGNING:
+ *usage = TSS_KEYUSAGE_SIGN;
+ break;
+ case TPM_KEY_BIND:
+ *usage = TSS_KEYUSAGE_BIND;
+ break;
+ case TPM_KEY_LEGACY:
+ *usage = TSS_KEYUSAGE_LEGACY;
+ break;
+ case TPM_KEY_AUTHCHANGE:
+ *usage = TSS_KEYUSAGE_AUTHCHANGE;
+ break;
+ case TPM_KEY_IDENTITY:
+ *usage = TSS_KEYUSAGE_IDENTITY;
+ break;
+ case TPM_KEY_STORAGE:
+ *usage = TSS_KEYUSAGE_STORAGE;
+ break;
+ default:
+ result = TSPERR(TSS_E_INVALID_ATTRIB_DATA);
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+/* WARN: Nobody should call this function directly except for the
+ * Get/Set Attrib functions. The TCPA_KEY structure wants values
+ * for keyUsage to be TPM_KEY_* values, and this function translates
+ * to TSS_KEYUSAGE_* values for passing to an app. */
+TSS_RESULT
+obj_rsakey_set_usage(TSS_HKEY hKey, UINT32 usage)
+{
+ TSS_RESULT result = TSS_SUCCESS;
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (usage) {
+ case TSS_KEYUSAGE_SIGN:
+ rsakey->key.keyUsage = TPM_KEY_SIGNING;
+ break;
+ case TSS_KEYUSAGE_BIND:
+ rsakey->key.keyUsage = TPM_KEY_BIND;
+ break;
+ case TSS_KEYUSAGE_LEGACY:
+ rsakey->key.keyUsage = TPM_KEY_LEGACY;
+ break;
+ case TSS_KEYUSAGE_AUTHCHANGE:
+ rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE;
+ break;
+ case TSS_KEYUSAGE_IDENTITY:
+ rsakey->key.keyUsage = TPM_KEY_IDENTITY;
+ break;
+ case TSS_KEYUSAGE_STORAGE:
+ rsakey->key.keyUsage = TPM_KEY_STORAGE;
+ break;
+ default:
+ result = TSPERR(TSS_E_INVALID_ATTRIB_DATA);
+ break;
+ }
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_migratable(TSS_HKEY hKey, UINT32 mig)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (mig)
+ rsakey->key.keyFlags |= TPM_MIGRATABLE;
+ else
+ rsakey->key.keyFlags &= (~TPM_MIGRATABLE);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_redirected(TSS_HKEY hKey, UINT32 redir)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (redir)
+ rsakey->key.keyFlags |= TPM_REDIRECTION;
+ else
+ rsakey->key.keyFlags &= (~TPM_REDIRECTION);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_volatile(TSS_HKEY hKey, UINT32 vol)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (vol)
+ rsakey->key.keyFlags |= TPM_VOLATILE;
+ else
+ rsakey->key.keyFlags &= (~TPM_VOLATILE);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_authdata_usage(TSS_HKEY hKey, UINT32 *usage)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ *usage = (UINT32)rsakey->key.authDataUsage ? TRUE : FALSE;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_authdata_usage(TSS_HKEY hKey, UINT32 usage)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ rsakey->key.authDataUsage = (BYTE)usage;
+ if (usage)
+ obj->flags |= TSS_OBJ_FLAG_USAGEAUTH;
+ else
+ obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH;
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_alg(TSS_HKEY hKey, UINT32 *alg)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (rsakey->key.algorithmParms.algorithmID) {
+ case TCPA_ALG_RSA:
+ *alg = TSS_ALG_RSA;
+ break;
+ default:
+ *alg = rsakey->key.algorithmParms.algorithmID;
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_alg(TSS_HKEY hKey, UINT32 alg)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ switch (alg) {
+ case TSS_ALG_RSA:
+ rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA;
+ break;
+ default:
+ rsakey->key.algorithmParms.algorithmID = alg;
+ break;
+ }
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_es(TSS_HKEY hKey, UINT32 *es)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* translate TPM numbers to TSS numbers */
+ switch (rsakey->key.algorithmParms.encScheme) {
+ case TCPA_ES_NONE:
+ *es = TSS_ES_NONE;
+ break;
+ case TCPA_ES_RSAESPKCSv15:
+ *es = TSS_ES_RSAESPKCSV15;
+ break;
+ case TCPA_ES_RSAESOAEP_SHA1_MGF1:
+ *es = TSS_ES_RSAESOAEP_SHA1_MGF1;
+ break;
+ default:
+ *es = rsakey->key.algorithmParms.encScheme;
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_es(TSS_HKEY hKey, UINT32 es)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* translate TSS numbers to TPM numbers */
+ switch (es) {
+ case TSS_ES_NONE:
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
+ break;
+ case TSS_ES_RSAESPKCSV15:
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESPKCSv15;
+ break;
+ case TSS_ES_RSAESOAEP_SHA1_MGF1:
+ rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
+ break;
+ default:
+ rsakey->key.algorithmParms.encScheme = es;
+ break;
+ }
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_ss(TSS_HKEY hKey, UINT32 *ss)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* translate TPM numbers to TSS numbers */
+ switch (rsakey->key.algorithmParms.sigScheme) {
+ case TCPA_SS_NONE:
+ *ss = TSS_SS_NONE;
+ break;
+ case TCPA_SS_RSASSAPKCS1v15_SHA1:
+ *ss = TSS_SS_RSASSAPKCS1V15_SHA1;
+ break;
+ case TCPA_SS_RSASSAPKCS1v15_DER:
+ *ss = TSS_SS_RSASSAPKCS1V15_DER;
+ break;
+ case TCPA_SS_RSASSAPKCS1v15_INFO:
+ *ss = TSS_SS_RSASSAPKCS1V15_INFO;
+ break;
+ default:
+ *ss = rsakey->key.algorithmParms.sigScheme;
+ break;
+ }
+
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_ss(TSS_HKEY hKey, UINT32 ss)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* translate TSS numbers to TPM numbers */
+ switch (ss) {
+ case TSS_SS_NONE:
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
+ break;
+ case TSS_SS_RSASSAPKCS1V15_SHA1:
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
+ break;
+ case TSS_SS_RSASSAPKCS1V15_DER:
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_DER;
+ break;
+ case TSS_SS_RSASSAPKCS1V15_INFO:
+ rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_INFO;
+ break;
+ default:
+ rsakey->key.algorithmParms.sigScheme = ss;
+ break;
+ }
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_num_primes(TSS_HKEY hKey, UINT32 num)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ UINT32ToArray(num, &rsakey->key.algorithmParms.parms[4]);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_num_primes(TSS_HKEY hKey, UINT32 *num)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TCPA_RSA_KEY_PARMS *parms;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
+ *num = endian32(parms->numPrimes);
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_flags(TSS_HKEY hKey, UINT32 *flags)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ *flags = rsakey->key.keyFlags;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_size(TSS_HKEY hKey, UINT32 *len)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (rsakey->key.pubKey.keyLength) {
+ case 512/8:
+ *len = TSS_KEY_SIZEVAL_512BIT;
+ break;
+ case 1024/8:
+ *len = TSS_KEY_SIZEVAL_1024BIT;
+ break;
+ case 2048/8:
+ *len = TSS_KEY_SIZEVAL_2048BIT;
+ break;
+ default:
+ *len = rsakey->key.pubKey.keyLength * 8;
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_pstype(TSS_HKEY hKey, UINT32 *type)
+{
+ struct tsp_object *obj;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_SYSTEM_PS)
+ *type = TSS_PS_TYPE_SYSTEM;
+ else if (obj->flags & TSS_OBJ_FLAG_USER_PS)
+ *type = TSS_PS_TYPE_USER;
+ else
+ *type = TSS_PS_TYPE_NO;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_BOOL
+obj_rsakey_is_migratable(TSS_HKEY hKey)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_BOOL answer = FALSE;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return answer;
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->key.keyFlags & TPM_MIGRATABLE)
+ answer = TRUE;
+
+ obj_list_put(&rsakey_list);
+
+ return answer;
+}
+
+TSS_BOOL
+obj_rsakey_is_redirected(TSS_HKEY hKey)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_BOOL answer = FALSE;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return answer;
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->key.keyFlags & TPM_REDIRECTION)
+ answer = TRUE;
+
+ obj_list_put(&rsakey_list);
+
+ return answer;
+}
+
+TSS_BOOL
+obj_rsakey_is_volatile(TSS_HKEY hKey)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_BOOL answer = FALSE;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return answer;
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->key.keyFlags & TPM_VOLATILE)
+ answer = TRUE;
+
+ obj_list_put(&rsakey_list);
+
+ return answer;
+}
+
+TSS_RESULT
+obj_rsakey_get_tsp_context(TSS_HKEY hKey, TSS_HCONTEXT *tspContext)
+{
+ struct tsp_object *obj;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ *tspContext = obj->tspContext;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_policies(TSS_HKEY hKey, TSS_HPOLICY *usage, TSS_HPOLICY *mig, TSS_BOOL *auth)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ *mig = rsakey->migPolicy;
+ *usage = rsakey->usagePolicy;
+ *auth = rsakey->key.authDataUsage ? TRUE : FALSE;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_policy(TSS_HKEY hKey, UINT32 policyType,
+ TSS_HPOLICY *phPolicy, TSS_BOOL *auth)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ switch (policyType) {
+ case TSS_POLICY_USAGE:
+ *phPolicy = rsakey->usagePolicy;
+ if (auth != NULL) {
+ if (obj->flags & TSS_OBJ_FLAG_USAGEAUTH)
+ *auth = TRUE;
+ else
+ *auth = FALSE;
+ }
+ break;
+ case TSS_POLICY_MIGRATION:
+ if (!rsakey->migPolicy) {
+ result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY);
+ break;
+ }
+
+ *phPolicy = rsakey->migPolicy;
+ if (auth != NULL) {
+ if (obj->flags & TSS_OBJ_FLAG_MIGAUTH)
+ *auth = TRUE;
+ else
+ *auth = FALSE;
+ }
+ break;
+ default:
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT64 offset;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ offset = 0;
+ LoadBlob_TSS_KEY(&offset, NULL, &rsakey->key);
+
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %" PRIu64 " bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ LoadBlob_TSS_KEY(&offset, *data, &rsakey->key);
+ *size = offset;
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_priv_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ *data = calloc_tspi(obj->tspContext, rsakey->key.encSize);
+ if (*data == NULL) {
+ LogError("malloc of %u bytes failed.", rsakey->key.encSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ *size = rsakey->key.encSize;
+ memcpy(*data, rsakey->key.encData, rsakey->key.encSize);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_modulus(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* if this key object represents the SRK and the public key
+ * data here is all 0's, then we shouldn't return it, we
+ * should return TSS_E_BAD_PARAMETER. This is part of protecting
+ * the SRK public key. */
+ if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
+ BYTE zeroBlob[2048] = { 0, };
+
+ if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ }
+
+ *data = calloc_tspi(obj->tspContext, rsakey->key.pubKey.keyLength);
+ if (*data == NULL) {
+ LogError("malloc of %u bytes failed.", rsakey->key.pubKey.keyLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ *size = rsakey->key.pubKey.keyLength;
+ memcpy(*data, rsakey->key.pubKey.key, rsakey->key.pubKey.keyLength);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_modulus(TSS_HKEY hKey, UINT32 size, BYTE *data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ BYTE *free_ptr;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ free_ptr = rsakey->key.pubKey.key;
+
+ rsakey->key.pubKey.key = malloc(size);
+ if (rsakey->key.pubKey.key == NULL) {
+ rsakey->key.pubKey.key = free_ptr; // restore
+ LogError("malloc of %u bytes failed.", size);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ rsakey->key.pubKey.keyLength = size;
+ memcpy(rsakey->key.pubKey.key, data, size);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_pub_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT64 offset;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* if this key object represents the SRK and the public key
+ * data here is all 0's, then we shouldn't return it, we
+ * should return TSS_E_BAD_PARAMETER. This is part of protecting
+ * the SRK public key. */
+ if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
+ BYTE zeroBlob[2048] = { 0, };
+
+ if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_KEY_PARMS(&offset, NULL, &rsakey->key.algorithmParms);
+ Trspi_LoadBlob_STORE_PUBKEY(&offset, NULL, &rsakey->key.pubKey);
+
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %" PRIu64 " bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_KEY_PARMS(&offset, *data, &rsakey->key.algorithmParms);
+ Trspi_LoadBlob_STORE_PUBKEY(&offset, *data, &rsakey->key.pubKey);
+ *size = offset;
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_version(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT64 offset;
+ TPM_STRUCT_VER ver = {1, 2, 0, 0}, *pVer;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
+ pVer = &ver;
+ else
+ pVer = &rsakey->key.hdr.key11.ver;
+
+ offset = 0;
+ Trspi_LoadBlob_TCPA_VERSION(&offset, NULL, *pVer);
+
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %" PRIu64 " bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_TCPA_VERSION(&offset, *data, *pVer);
+ *size = offset;
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_exponent(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ TCPA_RSA_KEY_PARMS *parms;
+ BYTE default_exp[3] = { 0x1, 0x0, 0x1 };
+ UINT32 offset;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
+ offset = parms->exponentSize;
+
+ /* see TPM 1.1b spec pg. 51. If exponentSize is 0, we're using the
+ * default exponent of 2^16 + 1. */
+ if (offset == 0) {
+ offset = 3;
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %u bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ *size = offset;
+ memcpy(*data, default_exp, offset);
+ } else {
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %u bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ *size = offset;
+ memcpy(*data, parms->exponent, offset);
+ }
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_exponent(TSS_HKEY hKey, UINT32 size, BYTE *data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ TCPA_RSA_KEY_PARMS *parms;
+ BYTE *free_ptr;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
+
+ free_ptr = parms->exponent;
+
+ parms->exponent = malloc(size);
+ if (parms->exponent == NULL) {
+ parms->exponent = free_ptr; // restore
+ LogError("malloc of %u bytes failed.", size);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ parms->exponentSize = size;
+ memcpy(parms->exponent, data, size);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_uuid(TSS_HKEY hKey, UINT32 *size, BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT64 offset;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ offset = 0;
+ Trspi_LoadBlob_UUID(&offset, NULL, rsakey->uuid);
+
+ *data = calloc_tspi(obj->tspContext, offset);
+ if (*data == NULL) {
+ LogError("malloc of %" PRIu64 " bytes failed.", offset);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_UUID(&offset, *data, rsakey->uuid);
+ *size = offset;
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_uuid(TSS_HKEY hKey, TSS_FLAG ps_type, TSS_UUID *uuid)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID));
+
+ switch (ps_type) {
+ case TSS_PS_TYPE_SYSTEM:
+ obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
+ break;
+ case TSS_PS_TYPE_USER:
+ obj->flags |= TSS_OBJ_FLAG_USER_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
+ break;
+ case TSS_PS_TYPE_NO:
+ default:
+ obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
+ obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
+ break;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE tcsHandle)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ rsakey->tcsHandle = tcsHandle;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE *tcsHandle)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->tcsHandle)
+ *tcsHandle = rsakey->tcsHandle;
+ else
+ result = TSPERR(TSS_E_KEY_NOT_LOADED);
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_tcpakey(TSS_HKEY hKey, UINT32 size, BYTE *data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ UINT64 offset;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ free_key_refs(&rsakey->key);
+
+ offset = 0;
+ if ((result = UnloadBlob_TSS_KEY(&offset, data, &rsakey->key)))
+ goto done;
+ if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
+ rsakey->type = TSS_KEY_STRUCT_KEY12;
+ else
+ rsakey->type = TSS_KEY_STRUCT_KEY;
+
+ if (rsakey->key.authDataUsage)
+ obj->flags |= TSS_OBJ_FLAG_USAGEAUTH;
+ else
+ obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH;
+
+ if (rsakey->key.PCRInfoSize && rsakey->key.PCRInfo) {
+ offset = 0;
+ if (rsakey->type == TSS_KEY_STRUCT_KEY12) {
+ if ((result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, rsakey->key.PCRInfo,
+ &rsakey->pcrInfo.infolong)))
+ goto done;
+ } else {
+ if ((result = Trspi_UnloadBlob_PCR_INFO(&offset, rsakey->key.PCRInfo,
+ &rsakey->pcrInfo.info11)))
+ goto done;
+ }
+ }
+
+ obj->flags |= TSS_OBJ_FLAG_KEY_SET;
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_pcr_digest(TSS_HKEY hKey,
+ TSS_FLAG pcrInfoType,
+ TSS_FLAG dir,
+ UINT32 *size,
+ BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ TPM_DIGEST *digest = NULL;
+ UINT64 offset;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (pcrInfoType != rsakey->pcrInfoType) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ switch (pcrInfoType) {
+ case TSS_PCRS_STRUCT_INFO:
+ if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATCREATION)
+ digest = &rsakey->pcrInfo.info11.digestAtCreation;
+ else if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATRELEASE)
+ digest = &rsakey->pcrInfo.info11.digestAtRelease;
+ else {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ break;
+ case TSS_PCRS_STRUCT_INFO_LONG:
+ if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATCREATION)
+ digest = &rsakey->pcrInfo.infolong.digestAtCreation;
+ else if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATRELEASE)
+ digest = &rsakey->pcrInfo.infolong.digestAtRelease;
+ else {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ break;
+ default:
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+
+ *size = sizeof(TPM_DIGEST);
+
+ if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
+ LogError("malloc of %u bytes failed.", *size);
+ *size = 0;
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_DIGEST(&offset, *data, digest);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+
+TSS_RESULT
+obj_rsakey_get_pcr_locality(TSS_HKEY hKey, TSS_FLAG dir, UINT32 *locality)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (rsakey->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) {
+ if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATCREATION)
+ *locality = rsakey->pcrInfo.infolong.localityAtCreation;
+ else if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATRELEASE)
+ *locality = rsakey->pcrInfo.infolong.localityAtRelease;
+ else
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ } else
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_pcr_selection(TSS_HKEY hKey,
+ UINT32 pcrInfoType,
+ TSS_FLAG dir,
+ UINT32 *size,
+ BYTE **data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT64 offset;
+ TPM_PCR_SELECTION *selection = NULL;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (pcrInfoType != rsakey->pcrInfoType) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ switch (pcrInfoType) {
+ case TSS_PCRS_STRUCT_INFO:
+ if (dir == TSS_TSPATTRIB_KEYPCR_SELECTION)
+ selection = &rsakey->pcrInfo.info11.pcrSelection;
+ else {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ break;
+ case TSS_PCRS_STRUCT_INFO_LONG:
+ if (dir == TSS_TSPATTRIB_KEYPCRLONG_CREATION_SELECTION)
+ selection = &rsakey->pcrInfo.infolong.creationPCRSelection;
+ else if (dir == TSS_TSPATTRIB_KEYPCRLONG_RELEASE_SELECTION)
+ selection = &rsakey->pcrInfo.infolong.releasePCRSelection;
+ else {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ break;
+ default:
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+
+ *size = sizeof(UINT16) + selection->sizeOfSelect;
+
+ if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
+ LogError("malloc of %u bytes failed.", *size);
+ *size = 0;
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ offset = 0;
+ Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+rsakey_set_pubkey(struct tr_rsakey_obj *rsakey, BYTE *pubkey)
+{
+ TSS_RESULT result;
+ UINT64 offset = 0;
+ TPM_PUBKEY pub;
+
+ if ((result = Trspi_UnloadBlob_PUBKEY(&offset, pubkey, &pub)))
+ return result;
+
+ free(rsakey->key.pubKey.key);
+ free(rsakey->key.algorithmParms.parms);
+
+ memcpy(&rsakey->key.pubKey, &pub.pubKey, sizeof(TPM_STORE_PUBKEY));
+ memcpy(&rsakey->key.algorithmParms, &pub.algorithmParms, sizeof(TPM_KEY_PARMS));
+
+ return TSS_SUCCESS;
+}
+
+/* Expect a TPM_PUBKEY as is explained in the portable data section of the spec */
+TSS_RESULT
+obj_rsakey_set_pubkey(TSS_HKEY hKey, UINT32 force, BYTE *data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ result = rsakey_set_pubkey(rsakey, data);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_srk_pubkey(BYTE *pubkey)
+{
+ struct tsp_object *obj;
+ struct obj_list *list = &rsakey_list;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* we found the SRK, set this data as its public key */
+ if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
+ result = rsakey_set_pubkey(rsakey, pubkey);
+ MUTEX_UNLOCK(list->lock);
+ return result;
+ }
+ }
+
+ MUTEX_UNLOCK(list->lock);
+
+ return TSPERR(TSS_E_INVALID_HANDLE);
+}
+
+TSS_RESULT
+obj_rsakey_set_privkey(TSS_HKEY hKey, UINT32 force, UINT32 size, BYTE *data)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ void *to_free;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ to_free = rsakey->key.encData;
+
+ rsakey->key.encData = calloc(1, size);
+ if (rsakey->key.encData == NULL) {
+ rsakey->key.encData = to_free; // restore
+ LogError("malloc of %u bytes failed.", size);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ free(to_free);
+ rsakey->key.encSize = size;
+ memcpy(rsakey->key.encData, data, size);
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_pcr_data(TSS_HKEY hKey, TSS_HPCRS hPcrComposite)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT32 pcrType, pcrSize;
+ BYTE *pcrInfo;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ /* passing in a pcrType of TSS_PCRS_STRUCT_DEFAULT will tell the pcr routine to create
+ * a structure matching the type of the hPcrComposite object */
+ pcrType = TSS_PCRS_STRUCT_DEFAULT;
+ if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrType, &pcrSize, &pcrInfo)))
+ goto done;
+
+ rsakey->key.PCRInfo = pcrInfo;
+ rsakey->key.PCRInfoSize = pcrSize;
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+void
+__tspi_rsakey_free(void *data)
+{
+ struct tr_rsakey_obj *rsakey = (struct tr_rsakey_obj *)data;
+
+ free(rsakey->key.algorithmParms.parms);
+ free(rsakey->key.encData);
+ free(rsakey->key.PCRInfo);
+ free(rsakey->key.pubKey.key);
+ free(rsakey);
+}
+
+/* Remove an individual rsakey object from the rsakey list with handle
+ * equal to hObject. Clean up the TSP's key handle table. */
+TSS_RESULT
+obj_rsakey_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
+{
+ TSS_RESULT result;
+
+ if ((result = obj_list_remove(&rsakey_list, &__tspi_rsakey_free, hObject, tspContext)))
+ return result;
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_get_by_pub(UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey)
+{
+ struct obj_list *list = &rsakey_list;
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (rsakey->key.pubKey.keyLength == pub_size &&
+ !memcmp(&rsakey->key.pubKey.key, pub, pub_size)) {
+ *hKey = obj->handle;
+ goto done;
+ }
+ }
+
+ *hKey = 0;
+done:
+ MUTEX_UNLOCK(list->lock);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_by_uuid(TSS_UUID *uuid, TSS_HKEY *hKey)
+{
+ struct obj_list *list = &rsakey_list;
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (!memcmp(&rsakey->uuid, uuid, sizeof(TSS_UUID))) {
+ *hKey = obj->handle;
+ goto done;
+ }
+ }
+
+ result = TSPERR(TSS_E_PS_KEY_NOTFOUND);
+done:
+ MUTEX_UNLOCK(list->lock);
+
+ return result;
+}
+
+void
+obj_rsakey_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext)
+{
+ struct tsp_object *obj;
+ struct obj_list *list = &rsakey_list;
+ struct tr_rsakey_obj *rsakey;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ if (obj->tspContext != tspContext)
+ continue;
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->usagePolicy == hPolicy)
+ rsakey->usagePolicy = NULL_HPOLICY;
+
+ if (rsakey->migPolicy == hPolicy)
+ rsakey->migPolicy = NULL_HPOLICY;
+ }
+
+ MUTEX_UNLOCK(list->lock);
+}
+
+#if 0
+TSS_RESULT
+obj_rsakey_get_transport_attribs(TSS_HKEY hKey, TCS_KEY_HANDLE *hTCSKey, TPM_DIGEST *pubDigest)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result;
+ Trspi_HashCtx hashCtx;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ *hTCSKey = rsakey->tcsHandle;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_STORE_PUBKEY(&hashCtx, &rsakey->key.pubKey);
+ result |= Trspi_HashFinal(&hashCtx, pubDigest->digest);
+
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+#endif
+
+#ifdef TSS_BUILD_CMK
+TSS_BOOL
+obj_rsakey_is_cmk(TSS_HKEY hKey)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_BOOL answer = FALSE;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return answer;
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->type != TSS_KEY_STRUCT_KEY) {
+ if (rsakey->key.keyFlags & TPM_MIGRATEAUTHORITY)
+ answer = TRUE;
+ }
+
+ obj_list_put(&rsakey_list);
+
+ return answer;
+}
+
+TSS_RESULT
+obj_rsakey_set_cmk(TSS_HKEY hKey, UINT32 cmk)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->type == TSS_KEY_STRUCT_KEY) {
+ result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
+ goto done;
+ }
+
+ if (cmk)
+ rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY;
+ else
+ rsakey->key.keyFlags &= (~TPM_MIGRATEAUTHORITY);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_msa_approval(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (blobSize != sizeof(rsakey->msaApproval.digest)) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ memcpy(rsakey->msaApproval.digest, blob, sizeof(rsakey->msaApproval.digest));
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_msa_approval(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaApproval.digest))) == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaApproval.digest));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ memcpy(*blob, rsakey->msaApproval.digest, sizeof(rsakey->msaApproval.digest));
+ *blobSize = sizeof(rsakey->msaApproval.digest);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_set_msa_digest(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (blobSize != sizeof(rsakey->msaDigest.digest)) {
+ result = TSPERR(TSS_E_BAD_PARAMETER);
+ goto done;
+ }
+ memcpy(rsakey->msaDigest.digest, blob, sizeof(rsakey->msaDigest.digest));
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+
+TSS_RESULT
+obj_rsakey_get_msa_digest(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+ TSS_RESULT result = TSS_SUCCESS;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaDigest.digest))) == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaDigest.digest));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ memcpy(*blob, rsakey->msaDigest.digest, sizeof(rsakey->msaDigest.digest));
+ *blobSize = sizeof(rsakey->msaDigest.digest);
+
+done:
+ obj_list_put(&rsakey_list);
+
+ return result;
+}
+#endif
+
+TSS_RESULT
+obj_rsakey_get_ownerevict(TSS_HKEY hKey, UINT32 *value)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ *value = rsakey->flags & TSS_RSAKEY_FLAG_OWNEREVICT;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_rsakey_set_ownerevict(TSS_HKEY hKey, TSS_BOOL value)
+{
+ struct tsp_object *obj;
+ struct tr_rsakey_obj *rsakey;
+
+ if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+
+ if (value)
+ rsakey->flags |= TSS_RSAKEY_FLAG_OWNEREVICT;
+ else
+ rsakey->flags &= ~TSS_RSAKEY_FLAG_OWNEREVICT;
+
+ obj_list_put(&rsakey_list);
+
+ return TSS_SUCCESS;
+}