Skip to content

Commit 308b4f7

Browse files
JuergenReppSITAndreasFuchsTPM
authored andcommitted
tpm2_create: Fix creation of ctx file if TPM2_CreateLoaded is not available.
If the TPM2 command CreateLoaded is not available the creation of a ctx file with tpm2_create was not possible. Now a TPM2_Create and TPM2_Load is used to create a ctx file if CreateLoaded is not available. Signed-off-by: Juergen Repp <juergen_repp@web.de>
1 parent 9329438 commit 308b4f7

File tree

4 files changed

+117
-46
lines changed

4 files changed

+117
-46
lines changed

lib/tpm2.c

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,15 +2060,32 @@ tool_rc tpm2_create(ESYS_CONTEXT *esys_context, tpm2_loaded_object *parent_obj,
20602060
tool_rc tpm2_create_loaded(ESYS_CONTEXT *esys_context,
20612061
tpm2_loaded_object *parent_obj,
20622062
const TPM2B_SENSITIVE_CREATE *in_sensitive,
2063-
const TPM2B_TEMPLATE *in_public, ESYS_TR *object_handle,
2063+
const TPM2B_PUBLIC *in_public, ESYS_TR *object_handle,
20642064
TPM2B_PRIVATE **out_private, TPM2B_PUBLIC **out_public,
20652065
TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
20662066
TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,
20672067
ESYS_TR shandle3) {
2068-
2068+
TPM2B_TEMPLATE template = { .size = 0 };
2069+
20692070
TSS2_SYS_CONTEXT *sys_context = NULL;
2071+
bool create_loaded_exists;
20702072
tool_rc rc = tool_rc_success;
2071-
if (cp_hash->size || rp_hash->size) {
2073+
size_t offset = 0;
2074+
2075+
tool_rc tmp_rc = tpm2_mu_tpmt_public_marshal(
2076+
&in_public->publicArea, &template.buffer[0],
2077+
sizeof(TPMT_PUBLIC), &offset);
2078+
if (tmp_rc != tool_rc_success) {
2079+
return tmp_rc;
2080+
}
2081+
2082+
template.size = offset;
2083+
2084+
rc = tpm2_check_cc(esys_context, TPM2_CC_CreateLoaded, &create_loaded_exists);
2085+
if (rc != tool_rc_success) {
2086+
return rc;
2087+
}
2088+
if ((cp_hash->size || rp_hash->size) && create_loaded_exists) {
20722089
rc = tpm2_getsapicontext(esys_context, &sys_context);
20732090

20742091
if(rc != tool_rc_success) {
@@ -2077,9 +2094,9 @@ tool_rc tpm2_create_loaded(ESYS_CONTEXT *esys_context,
20772094
}
20782095
}
20792096

2080-
if (cp_hash->size) {
2097+
if (cp_hash->size && create_loaded_exists) {
20812098
TSS2_RC rval = Tss2_Sys_CreateLoaded_Prepare(sys_context,
2082-
parent_obj->handle, in_sensitive, in_public);
2099+
parent_obj->handle, in_sensitive, &template);
20832100
if (rval != TPM2_RC_SUCCESS) {
20842101
LOG_PERR(Tss2_Sys_CreateLoaded_Prepare, rval);
20852102
return tool_rc_general_error;
@@ -2115,19 +2132,39 @@ tool_rc tpm2_create_loaded(ESYS_CONTEXT *esys_context,
21152132
return rc;
21162133
}
21172134

2118-
TSS2_RC rval = Esys_CreateLoaded(esys_context, parent_obj->tr_handle,
2119-
shandle1, shandle2, shandle3, in_sensitive, in_public,
2135+
if (create_loaded_exists) {
2136+
TSS2_RC rval = Esys_CreateLoaded(esys_context, parent_obj->tr_handle,
2137+
shandle1, shandle2, shandle3, in_sensitive, &template,
21202138
object_handle, out_private, out_public);
2121-
if (rval != TSS2_RC_SUCCESS) {
2122-
LOG_PERR(Esys_CreateLoaded, rval);
2123-
return tool_rc_from_tpm(rval);
2124-
}
2139+
if (rval != TSS2_RC_SUCCESS) {
2140+
LOG_PERR(Esys_CreateLoaded, rval);
2141+
return tool_rc_from_tpm(rval);
2142+
}
21252143

2126-
if (rp_hash->size) {
2127-
rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
2128-
parameter_hash_algorithm);
2144+
if (rp_hash->size) {
2145+
rc = tpm2_sapi_getrphash(sys_context, rval, rp_hash,
2146+
parameter_hash_algorithm);
2147+
}
2148+
} else {
2149+
TPML_PCR_SELECTION creationPCR = {
2150+
.count = 0,
2151+
};
2152+
2153+
TSS2_RC rval = Esys_Create(esys_context, parent_obj->tr_handle,
2154+
shandle1, shandle2, shandle3, in_sensitive, in_public,
2155+
NULL, &creationPCR, out_private, out_public, NULL, NULL, NULL);
2156+
if (rval != TSS2_RC_SUCCESS) {
2157+
LOG_PERR(Esys_CreateLoaded, rval);
2158+
return tool_rc_from_tpm(rval);
2159+
}
2160+
rval = Esys_Load(esys_context, parent_obj->tr_handle,
2161+
shandle1, shandle2, shandle3, *out_private,
2162+
*out_public, object_handle);
2163+
if (rval != TPM2_RC_SUCCESS) {
2164+
LOG_PERR(Esys_Load, rval);
2165+
return tool_rc_from_tpm(rval);
2166+
}
21292167
}
2130-
21312168
tpm2_createloaded_skip_esapi_call:
21322169
return rc;
21332170
}

lib/tpm2.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ tool_rc tpm2_sess_get_noncetpm(ESYS_CONTEXT *esys_context,
6464
ESYS_TR session_handle, TPM2B_NONCE **nonce_tpm);
6565

6666
tool_rc tpm2_policy_restart(ESYS_CONTEXT *esys_context, ESYS_TR session_handle,
67-
ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3,
68-
TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm);
67+
ESYS_TR shandle1, ESYS_TR shandle2,
68+
ESYS_TR shandle3, TPM2B_DIGEST *cp_hash,
69+
TPMI_ALG_HASH parameter_hash_algorithm);
70+
71+
tool_rc tpm2_check_cc(ESYS_CONTEXT *ectx, uint32_t cc, bool *exists);
6972

7073
tool_rc tpm2_get_capability(ESYS_CONTEXT *esys_context, ESYS_TR shandle1,
7174
ESYS_TR shandle2, ESYS_TR shandle3, TPM2_CAP capability,
@@ -212,7 +215,7 @@ tool_rc tpm2_create(ESYS_CONTEXT *esys_context, tpm2_loaded_object *parent_obj,
212215
tool_rc tpm2_create_loaded(ESYS_CONTEXT *esys_context,
213216
tpm2_loaded_object *parent_obj,
214217
const TPM2B_SENSITIVE_CREATE *in_sensitive,
215-
const TPM2B_TEMPLATE *in_public, ESYS_TR *object_handle,
218+
const TPM2B_PUBLIC *in_public, ESYS_TR *object_handle,
216219
TPM2B_PRIVATE **out_private, TPM2B_PUBLIC **out_public,
217220
TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash,
218221
TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2,

lib/tpm2_capability.c

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,68 @@
55
#include <string.h>
66

77
#include "log.h"
8+
#include "tool_rc.h"
89
#include "tpm2.h"
910
#include "tpm2_capability.h"
1011

11-
#define APPEND_CAPABILITY_INFORMATION(capability, field, subfield, max_count) \
12-
if (fetched_data->data.capability.count > max_count - property_count) { \
13-
fetched_data->data.capability.count = max_count - property_count; \
14-
} \
15-
\
16-
memmove(&(*capability_data)->data.capability.field[property_count], \
17-
fetched_data->data.capability.field, \
18-
fetched_data->data.capability.count * sizeof(fetched_data->data.capability.field[0])); \
19-
property_count += fetched_data->data.capability.count; \
20-
\
21-
(*capability_data)->data.capability.count = property_count; \
22-
\
23-
if (more_data && property_count < count && fetched_data->data.capability.count) { \
24-
property = (*capability_data)->data.capability.field[property_count - 1]subfield + 1; \
25-
} else { \
26-
more_data = false; \
12+
#define APPEND_CAPABILITY_INFORMATION(capability, field, subfield, max_count) \
13+
if (fetched_data->data.capability.count > max_count - property_count) { \
14+
fetched_data->data.capability.count = max_count - property_count; \
15+
} \
16+
\
17+
memmove(&(*capability_data)->data.capability.field[property_count], \
18+
fetched_data->data.capability.field, \
19+
fetched_data->data.capability.count * \
20+
sizeof(fetched_data->data.capability.field[0])); \
21+
property_count += fetched_data->data.capability.count; \
22+
\
23+
(*capability_data)->data.capability.count = property_count; \
24+
\
25+
if (more_data && property_count < count && \
26+
fetched_data->data.capability.count) { \
27+
property = (*capability_data) \
28+
->data.capability.field[property_count - 1] subfield + \
29+
1; \
30+
} else { \
31+
more_data = false; \
32+
}
33+
34+
tool_rc tpm2_check_cc(ESYS_CONTEXT *ectx, uint32_t cc, bool *exists) {
35+
TPMI_YES_NO more_data = TPM2_NO;
36+
TPMS_CAPABILITY_DATA *cap = NULL;
37+
uint32_t count = 1;
38+
39+
40+
TSS2_RC rc = Esys_GetCapability(
41+
ectx,
42+
ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
43+
TPM2_CAP_COMMANDS,
44+
cc,
45+
count,
46+
&more_data,
47+
&cap
48+
);
49+
50+
if (rc != TSS2_RC_SUCCESS) {
51+
LOG_ERR("Esys_GetCapability(TPM2_CAP_COMMANDS, property=0x%08" PRIX32 " failed: 0x%x",
52+
cc, rc);
53+
return tool_rc_general_error;
2754
}
2855

56+
const TPML_CCA *cmds = &cap->data.command;
57+
58+
if (cmds->count == 1 && (cmds->commandAttributes[0] & 0xffff) == cc) {
59+
Esys_Free(cap);
60+
*exists = true;
61+
return tool_rc_success;
62+
}
63+
64+
Esys_Free(cap);
65+
*exists = false;
66+
return tool_rc_success;
67+
}
68+
69+
2970
tool_rc tpm2_capability_get_ex(ESYS_CONTEXT *ectx, TPM2_CAP capability,
3071
UINT32 property, UINT32 count, bool ignore_more_data,
3172
TPMS_CAPABILITY_DATA **capability_data) {

tools/tpm2_create.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,9 @@ static tool_rc create(ESYS_CONTEXT *ectx) {
134134

135135
/* TPM2_CC_CreateLoaded */
136136
if (ctx.is_createloaded) {
137-
size_t offset = 0;
138-
TPM2B_TEMPLATE template = { .size = 0 };
139-
tool_rc tmp_rc = tpm2_mu_tpmt_public_marshal(
140-
&ctx.object.in_public.publicArea, &template.buffer[0],
141-
sizeof(TPMT_PUBLIC), &offset);
142-
if (tmp_rc != tool_rc_success) {
143-
return tmp_rc;
144-
}
145-
146-
template.size = offset;
147-
137+
tool_rc tmp_rc;
148138
tmp_rc = tpm2_create_loaded(ectx, &ctx.parent.object,
149-
&ctx.object.sensitive, &template, &ctx.object.object_handle,
139+
&ctx.object.sensitive, &ctx.object.in_public, &ctx.object.object_handle,
150140
&ctx.object.out_private, &ctx.object.out_public, &ctx.cp_hash,
151141
&ctx.rp_hash, ctx.parameter_hash_algorithm,
152142
ctx.aux_session_handle[0], ctx.aux_session_handle[1]);

0 commit comments

Comments
 (0)