1 /********************************************************************************/
2 /* */
3 /* GetSessionAuditDigest */
4 /* Written by Ken Goldman */
5 /* IBM Thomas J. Watson Research Center */
6 /* */
7 /* (c) Copyright IBM Corporation 2015 - 2020. */
8 /* */
9 /* All rights reserved. */
10 /* */
11 /* Redistribution and use in source and binary forms, with or without */
12 /* modification, are permitted provided that the following conditions are */
13 /* met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright notice, */
16 /* this list of conditions and the following disclaimer. */
17 /* */
18 /* Redistributions in binary form must reproduce the above copyright */
19 /* notice, this list of conditions and the following disclaimer in the */
20 /* documentation and/or other materials provided with the distribution. */
21 /* */
22 /* Neither the names of the IBM Corporation nor the names of its */
23 /* contributors may be used to endorse or promote products derived from */
24 /* this software without specific prior written permission. */
25 /* */
26 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
27 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
28 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
29 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
30 /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
31 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
32 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
33 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
34 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
35 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
36 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37 /********************************************************************************/
38
39 /*
40
41 */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <stdint.h>
47
48 #include <ibmtss/tss.h>
49 #include <ibmtss/tssutils.h>
50 #include <ibmtss/tssresponsecode.h>
51 #include <ibmtss/tssmarshal.h>
52 #include <ibmtss/Unmarshal_fp.h>
53
54 static void printUsage(void);
55
56 extern int tssUtilsVerbose;
57
main(int argc,char * argv[])58 int main(int argc, char *argv[])
59 {
60 TPM_RC rc = 0;
61 int i; /* argc iterator */
62 TSS_CONTEXT *tssContext = NULL;
63 GetSessionAuditDigest_In in;
64 GetSessionAuditDigest_Out out;
65 const char *privacyAdminPassword = NULL;
66 TPMI_DH_OBJECT signHandle = TPM_RH_NULL;
67 const char *signPassword = NULL;
68 TPMI_SH_HMAC sessionHandle = 0;
69 TPMI_ALG_HASH halg = TPM_ALG_SHA256;
70 const char *signatureFilename = NULL;
71 const char *attestInfoFilename = NULL;
72 const char *qualifyingDataFilename = NULL;
73 TPMS_ATTEST tpmsAttest;
74 const char *sessionDigestFilename = NULL;
75 TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
76 unsigned int sessionAttributes0 = 0;
77 TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RS_PW;
78 unsigned int sessionAttributes1 = 0;
79 TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
80 unsigned int sessionAttributes2 = 0;
81
82 setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe to log file */
83 TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1");
84 tssUtilsVerbose = FALSE;
85
86 /* command line argument defaults */
87 for (i=1 ; (i<argc) && (rc == 0) ; i++) {
88 if (strcmp(argv[i],"-pwde") == 0) {
89 i++;
90 if (i < argc) {
91 privacyAdminPassword = argv[i];
92 }
93 else {
94 printf("-pwde option needs a value\n");
95 printUsage();
96 }
97 }
98 else if (strcmp(argv[i],"-hk") == 0) {
99 i++;
100 if (i < argc) {
101 sscanf(argv[i],"%x",&signHandle);
102 }
103 else {
104 printf("Missing parameter for -hk\n");
105 printUsage();
106 }
107 }
108 else if (strcmp(argv[i],"-pwdk") == 0) {
109 i++;
110 if (i < argc) {
111 signPassword = argv[i];
112 }
113 else {
114 printf("-pwdk option needs a value\n");
115 printUsage();
116 }
117 }
118 else if (strcmp(argv[i],"-hs") == 0) {
119 i++;
120 if (i < argc) {
121 sscanf(argv[i],"%x",&sessionHandle);
122 }
123 else {
124 printf("Missing parameter for -hs\n");
125 printUsage();
126 }
127 }
128 else if (strcmp(argv[i],"-halg") == 0) {
129 i++;
130 if (i < argc) {
131 if (strcmp(argv[i],"sha1") == 0) {
132 halg = TPM_ALG_SHA1;
133 }
134 else if (strcmp(argv[i],"sha256") == 0) {
135 halg = TPM_ALG_SHA256;
136 }
137 else if (strcmp(argv[i],"sha384") == 0) {
138 halg = TPM_ALG_SHA384;
139 }
140 else if (strcmp(argv[i],"sha512") == 0) {
141 halg = TPM_ALG_SHA512;
142 }
143 else {
144 printf("Bad parameter %s for -halg\n", argv[i]);
145 printUsage();
146 }
147 }
148 else {
149 printf("-halg option needs a value\n");
150 printUsage();
151 }
152 }
153 else if (strcmp(argv[i],"-os") == 0) {
154 i++;
155 if (i < argc) {
156 signatureFilename = argv[i];
157 }
158 else {
159 printf("-os option needs a value\n");
160 printUsage();
161 }
162 }
163 else if (strcmp(argv[i],"-oa") == 0) {
164 i++;
165 if (i < argc) {
166 attestInfoFilename = argv[i];
167 }
168 else {
169 printf("-oa option needs a value\n");
170 printUsage();
171 }
172 }
173 else if (strcmp(argv[i],"-od") == 0) {
174 i++;
175 if (i < argc) {
176 sessionDigestFilename = argv[i];
177 }
178 else {
179 printf("-od option needs a value\n");
180 printUsage();
181 }
182 }
183 else if (strcmp(argv[i],"-qd") == 0) {
184 i++;
185 if (i < argc) {
186 qualifyingDataFilename = argv[i];
187 }
188 else {
189 printf("-qd option needs a value\n");
190 printUsage();
191 }
192 }
193 else if (strcmp(argv[i],"-se0") == 0) {
194 i++;
195 if (i < argc) {
196 sscanf(argv[i],"%x", &sessionHandle0);
197 }
198 else {
199 printf("Missing parameter for -se0\n");
200 printUsage();
201 }
202 i++;
203 if (i < argc) {
204 sscanf(argv[i],"%x", &sessionAttributes0);
205 if (sessionAttributes0 > 0xff) {
206 printf("Out of range session attributes for -se0\n");
207 printUsage();
208 }
209 }
210 else {
211 printf("Missing parameter for -se0\n");
212 printUsage();
213 }
214 }
215 else if (strcmp(argv[i],"-se1") == 0) {
216 i++;
217 if (i < argc) {
218 sscanf(argv[i],"%x", &sessionHandle1);
219 }
220 else {
221 printf("Missing parameter for -se1\n");
222 printUsage();
223 }
224 i++;
225 if (i < argc) {
226 sscanf(argv[i],"%x", &sessionAttributes1);
227 if (sessionAttributes1 > 0xff) {
228 printf("Out of range session attributes for -se1\n");
229 printUsage();
230 }
231 }
232 else {
233 printf("Missing parameter for -se1\n");
234 printUsage();
235 }
236 }
237 else if (strcmp(argv[i],"-se2") == 0) {
238 i++;
239 if (i < argc) {
240 sscanf(argv[i],"%x", &sessionHandle2);
241 }
242 else {
243 printf("Missing parameter for -se2\n");
244 printUsage();
245 }
246 i++;
247 if (i < argc) {
248 sscanf(argv[i],"%x", &sessionAttributes2);
249 if (sessionAttributes2 > 0xff) {
250 printf("Out of range session attributes for -se2\n");
251 printUsage();
252 }
253 }
254 else {
255 printf("Missing parameter for -se2\n");
256 printUsage();
257 }
258 }
259 else if (strcmp(argv[i],"-h") == 0) {
260 printUsage();
261 }
262 else if (strcmp(argv[i],"-v") == 0) {
263 tssUtilsVerbose = TRUE;
264 TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "2");
265 }
266 else {
267 printf("\n%s is not a valid option\n", argv[i]);
268 printUsage();
269 }
270 }
271 if (sessionHandle == 0) {
272 printf("Missing session handle parameter -hs\n");
273 printUsage();
274 }
275 if (rc == 0) {
276 /* Handle of key that authorizes the audit */
277 in.privacyAdminHandle = TPM_RH_ENDORSEMENT;
278 in.signHandle = signHandle;
279 in.sessionHandle = sessionHandle;
280 /* Table 145 - Definition of TPMT_SIG_SCHEME Structure */
281 in.inScheme.scheme = TPM_ALG_RSASSA;
282 /* Table 144 - Definition of TPMU_SIG_SCHEME Union <IN/OUT, S> */
283 /* Table 142 - Definition of {RSA} Types for RSA Signature Schemes */
284 /* Table 135 - Definition of TPMS_SCHEME_HASH Structure */
285 in.inScheme.details.rsassa.hashAlg = halg;
286 }
287 /* data supplied by the caller */
288 if (rc == 0) {
289 if (qualifyingDataFilename != NULL) {
290 rc = TSS_File_Read2B(&in.qualifyingData.b,
291 sizeof(in.qualifyingData.t.buffer),
292 qualifyingDataFilename);
293 }
294 else {
295 in.qualifyingData.t.size = 0;
296 }
297 }
298 /* Start a TSS context */
299 if (rc == 0) {
300 rc = TSS_Create(&tssContext);
301 }
302 /* call TSS to execute the command */
303 if (rc == 0) {
304 rc = TSS_Execute(tssContext,
305 (RESPONSE_PARAMETERS *)&out,
306 (COMMAND_PARAMETERS *)&in,
307 NULL,
308 TPM_CC_GetSessionAuditDigest,
309 sessionHandle0, privacyAdminPassword, sessionAttributes0,
310 sessionHandle1, signPassword, sessionAttributes1,
311 sessionHandle2, NULL, sessionAttributes2,
312 TPM_RH_NULL, NULL, 0);
313 }
314 {
315 TPM_RC rc1 = TSS_Delete(tssContext);
316 if (rc == 0) {
317 rc = rc1;
318 }
319 }
320 if (rc == 0) {
321 uint8_t *tmpBuffer = out.auditInfo.t.attestationData;
322 uint32_t tmpSize = out.auditInfo.t.size;
323 rc = TSS_TPMS_ATTEST_Unmarshalu(&tpmsAttest, &tmpBuffer, &tmpSize);
324 }
325 if (rc == 0) {
326 if (tssUtilsVerbose) TSS_TPMS_ATTEST_Print(&tpmsAttest, 0);
327 }
328 if (rc == 0) {
329 int match;
330 match = TSS_TPM2B_Compare(&in.qualifyingData.b, &tpmsAttest.extraData.b);
331 if (!match) {
332 printf("getsessionauditdigest: failed, extraData != qualifyingData\n");
333 rc = EXIT_FAILURE;
334 }
335 }
336 if ((rc == 0) && (signatureFilename != NULL)) {
337 rc = TSS_File_WriteStructure(&out.signature,
338 (MarshalFunction_t)TSS_TPMT_SIGNATURE_Marshalu,
339 signatureFilename);
340
341
342 }
343 if ((rc == 0) && (attestInfoFilename != NULL)) {
344 rc = TSS_File_WriteBinaryFile(out.auditInfo.t.attestationData,
345 out.auditInfo.t.size,
346 attestInfoFilename);
347 }
348 if ((rc == 0) && (sessionDigestFilename != NULL)) {
349 rc = TSS_File_WriteBinaryFile(tpmsAttest.attested.sessionAudit.sessionDigest.t.buffer,
350 tpmsAttest.attested.sessionAudit.sessionDigest.t.size,
351 sessionDigestFilename);
352 }
353 if (rc == 0) {
354 if (tssUtilsVerbose) TSS_TPMT_SIGNATURE_Print(&out.signature, 0);
355 if (tssUtilsVerbose) printf("getsessionauditdigest: success\n");
356 }
357 else {
358 const char *msg;
359 const char *submsg;
360 const char *num;
361 printf("getsessionauditdigest: failed, rc %08x\n", rc);
362 TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
363 printf("%s%s%s\n", msg, submsg, num);
364 rc = EXIT_FAILURE;
365 }
366 return rc;
367 }
368
printUsage(void)369 static void printUsage(void)
370 {
371 printf("\n");
372 printf("getsessionauditdigest\n");
373 printf("\n");
374 printf("Runs TPM2_GetSessionAuditDigest\n");
375 printf("\n");
376 printf("\t[-pwde\tendorsement hierarchy password (default empty)]\n");
377 printf("\t[-hk\tsigning key handle]\n");
378 printf("\t[-pwdk\tpassword for key (default empty)]\n");
379 printf("\t-hs\taudit session handle\n");
380 printf("\t[-halg\t(sha1, sha256, sha384, sha512) (default sha256)]\n");
381 printf("\t[-qd\tqualifying data file name]\n");
382 printf("\t[-os\tsignature file name (default do not save)]\n");
383 printf("\t[-oa\tattestation output file name (default do not save)]\n");
384 printf("\t[-od\tsession digest file name (default do not save)]\n");
385 printf("\n");
386 printf("\t-se[0-2] session handle / attributes (default PWAP)\n");
387 printf("\t01\tcontinue\n");
388 printf("\t20\tcommand decrypt\n");
389 printf("\t40\tresponse encrypt\n");
390 exit(1);
391 }
392