1 /*
2 * SPDX-License-Identifier: BSD-2-Clause
3 * Copyright (c) 2019, Intel Corporation
4 */
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <inttypes.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "tss2_sys.h"
16
17 #include "context-util.h"
18 #include "sapi-util.h"
19 #include "session-util.h"
20 #include "util/aux_util.h"
21 #define LOGMODULE test
22 #include "util/log.h"
23
24 #define NV_PS_INDEX_SIZE 34
25 #define INDEX_LCP_OWN 0x01400001
26 #define INDEX_LCP_SUP 0x01800001
27
28 #define TPM2B_SIZE_MAX(type) (sizeof (type) - 2)
29
30 const TSS2L_SYS_AUTH_COMMAND auth_cmd_null_pwd = {
31 .count = 1,
32 .auths = {
33 {
34 .sessionHandle = TPM2_RS_PW,
35 },
36 },
37 };
38
39 static TSS2_RC
create_policy_session(TSS2_SYS_CONTEXT * sys_ctx,TPMI_SH_AUTH_SESSION * handle)40 create_policy_session (
41 TSS2_SYS_CONTEXT *sys_ctx,
42 TPMI_SH_AUTH_SESSION *handle)
43 {
44 TSS2_RC rc;
45 TPM2B_ENCRYPTED_SECRET salt = { 0 };
46 TPM2B_NONCE nonce = {
47 .size = GetDigestSize (TPM2_ALG_SHA1),
48 };
49 TPM2B_NONCE nonce_tpm = { 0, };
50 TPMT_SYM_DEF symmetric = {
51 .algorithm = TPM2_ALG_NULL,
52 };
53
54 rc = Tss2_Sys_StartAuthSession (sys_ctx,
55 TPM2_RH_NULL,
56 TPM2_RH_NULL,
57 0,
58 &nonce,
59 &salt,
60 TPM2_SE_POLICY,
61 &symmetric,
62 TPM2_ALG_SHA1,
63 handle,
64 &nonce_tpm,
65 0);
66 return_if_error (rc, "Tss2_Sys_StartAuthSession");
67 return TSS2_RC_SUCCESS;
68 }
69
70 static TSS2_RC
setup_nv(TSS2_SYS_CONTEXT * sys_ctx,TPMI_RH_NV_INDEX index)71 setup_nv (TSS2_SYS_CONTEXT *sys_ctx,
72 TPMI_RH_NV_INDEX index)
73 {
74 TSS2_RC rc;
75 TPMI_SH_AUTH_SESSION auth_handle;
76 TPM2B_DIGEST policy_hash = {
77 .size = TPM2B_SIZE_MAX (policy_hash),
78 };
79 TPM2B_AUTH nv_auth = { 0, };
80 TSS2L_SYS_AUTH_RESPONSE auth_rsp;
81 TPM2B_NV_PUBLIC public_info = {
82 .nvPublic = {
83 .nameAlg = TPM2_ALG_SHA1,
84 .attributes = TPMA_NV_AUTHREAD | TPMA_NV_AUTHWRITE |
85 TPMA_NV_PLATFORMCREATE | TPMA_NV_WRITEDEFINE | TPMA_NV_ORDERLY,
86 .dataSize = NV_PS_INDEX_SIZE,
87 .nvIndex = index,
88 },
89 };
90
91 rc = create_policy_session (sys_ctx, &auth_handle);
92 return_if_error (rc, "create_policy_session");
93
94 rc = Tss2_Sys_PolicyGetDigest (sys_ctx, auth_handle, 0, &policy_hash, 0);
95 return_if_error (rc, "Tss2_Sys_PolicyGetDigest");
96 LOGBLOB_INFO (policy_hash.buffer, policy_hash.size, "policy_hash");
97
98 rc = Tss2_Sys_NV_DefineSpace (sys_ctx,
99 TPM2_RH_PLATFORM,
100 &auth_cmd_null_pwd,
101 &nv_auth,
102 &public_info,
103 &auth_rsp);
104 return_if_error (rc, "Tss2_Sys_NV_DefineSpace");
105
106 rc = Tss2_Sys_FlushContext (sys_ctx, auth_handle);
107 return_if_error (rc, "Tss2_Sys_FlushContext");
108
109 return TSS2_RC_SUCCESS;
110 }
111
112 static TSS2_RC
nv_write_read_test(TSS2_SYS_CONTEXT * sys_ctx,TPMI_RH_NV_INDEX index)113 nv_write_read_test (TSS2_SYS_CONTEXT *sys_ctx,
114 TPMI_RH_NV_INDEX index)
115 {
116 TSS2_RC rc;
117 TPM2B_MAX_NV_BUFFER write_data = {
118 .size = 4,
119 .buffer = { 0xde, 0xad, 0xbe, 0xef },
120 };
121 TPM2B_MAX_NV_BUFFER nv_buf = { 0, };
122 TSS2L_SYS_AUTH_RESPONSE auth_resp = { 0, };
123
124 rc = TSS2_RETRY_EXP (Tss2_Sys_NV_Write (sys_ctx,
125 index,
126 index,
127 &auth_cmd_null_pwd,
128 &write_data,
129 0,
130 &auth_resp));
131 return_if_error (rc, "Tss2_Sys_NV_Write");
132
133 rc = Tss2_Sys_NV_Read (sys_ctx,
134 index,
135 index,
136 &auth_cmd_null_pwd,
137 4,
138 0,
139 &nv_buf,
140 &auth_resp);
141 return_if_error (rc, "Tss2_Sys_NV_Read");
142
143 if (memcmp (nv_buf.buffer, write_data.buffer, write_data.size) != 0) {
144 LOG_ERROR ("%s: data read from NV is different from data written",
145 __func__);
146 LOGBLOB_DEBUG (write_data.buffer, write_data.size, "write_data");
147 LOGBLOB_DEBUG (nv_buf.buffer, nv_buf.size, "nv_buf");
148 return 1;
149 }
150
151 return TSS2_RC_SUCCESS;
152 }
153
154 static TSS2_RC
teardown_nv(TSS2_SYS_CONTEXT * sys_ctx,TPMI_RH_NV_INDEX index)155 teardown_nv (TSS2_SYS_CONTEXT *sys_ctx,
156 TPMI_RH_NV_INDEX index)
157 {
158 TSS2_RC rc;
159 TSS2L_SYS_AUTH_RESPONSE auth_resp = { 0, };
160
161 rc = Tss2_Sys_NV_UndefineSpace (sys_ctx,
162 TPM2_RH_PLATFORM,
163 index,
164 &auth_cmd_null_pwd,
165 &auth_resp);
166 return_if_error (rc, "Tss2_Sys_NV_UndefineSpace");
167
168 return TSS2_RC_SUCCESS;
169 }
170
171 int
test_invoke(TSS2_SYS_CONTEXT * sys_ctx)172 test_invoke (TSS2_SYS_CONTEXT *sys_ctx)
173 {
174 TSS2_RC rc, rc_teardown;
175
176 rc = setup_nv (sys_ctx, INDEX_LCP_OWN);
177 return_if_error (rc, "setup_nv for INDEX_LCP_OWN");
178 rc = nv_write_read_test (sys_ctx, INDEX_LCP_OWN);
179 LOG_ERROR ("nv_write_read_test for INDEX_LCP_OWN");
180 rc_teardown = teardown_nv (sys_ctx, INDEX_LCP_OWN);
181 return_if_error (rc, "INDEX_LCP_OWN test");
182 return_if_error (rc_teardown, "teardown_nv for INDEX_LCP_OWN");
183
184 rc = setup_nv (sys_ctx, INDEX_LCP_SUP);
185 return_if_error (rc, "setup_nv for INDEX_LCP_SUP");
186 rc = nv_write_read_test (sys_ctx, INDEX_LCP_SUP);
187 LOG_ERROR ("nv_write_read_test for INDEX_LCP_SUP");
188 rc_teardown = teardown_nv (sys_ctx, INDEX_LCP_SUP);
189 return_if_error (rc, "INDEX_LCP_SUP test");
190 return_if_error (rc_teardown, "teardown_nv for INDEX_LCP_SUP");
191
192 return 0;
193 }
194