1 /********************************************************************************/
2 /*										*/
3 /*			    GetCommandAuditDigest				*/
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     GetCommandAuditDigest_In 	in;
64     GetCommandAuditDigest_Out 	out;
65     const char			*privacyAdminPassword = NULL;
66     TPMI_DH_OBJECT		signHandle = 0;
67     const char			*signPassword = NULL;
68     TPMI_ALG_HASH		halg = TPM_ALG_SHA256;
69     const char			*signatureFilename = NULL;
70     const char			*attestInfoFilename = NULL;
71     const char			*qualifyingDataFilename = NULL;
72     TPM_ALG_ID			sigAlg = TPM_ALG_RSA;
73     TPMS_ATTEST 		tpmsAttest;
74     TPMI_SH_AUTH_SESSION    	sessionHandle0 = TPM_RS_PW;
75     unsigned int		sessionAttributes0 = 0;
76     TPMI_SH_AUTH_SESSION    	sessionHandle1 = TPM_RS_PW;
77     unsigned int		sessionAttributes1 = 0;
78     TPMI_SH_AUTH_SESSION    	sessionHandle2 = TPM_RH_NULL;
79     unsigned int		sessionAttributes2 = 0;
80 
81     setvbuf(stdout, 0, _IONBF, 0);      /* output may be going through pipe to log file */
82     TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1");
83     tssUtilsVerbose = FALSE;
84 
85     /* command line argument defaults */
86     for (i=1 ; (i<argc) && (rc == 0) ; i++) {
87 	if (strcmp(argv[i],"-pwde") == 0) {
88 	    i++;
89 	    if (i < argc) {
90 		privacyAdminPassword = argv[i];
91 	    }
92 	    else {
93 		printf("-pwde option needs a value\n");
94 		printUsage();
95 	    }
96 	}
97 	else if (strcmp(argv[i],"-hk") == 0) {
98 	    i++;
99 	    if (i < argc) {
100 		sscanf(argv[i],"%x",&signHandle);
101 	    }
102 	    else {
103 		printf("Missing parameter for -hk\n");
104 		printUsage();
105 	    }
106 	}
107 	else if (strcmp(argv[i],"-pwdk") == 0) {
108 	    i++;
109 	    if (i < argc) {
110 		signPassword = argv[i];
111 	    }
112 	    else {
113 		printf("-pwdk option needs a value\n");
114 		printUsage();
115 	    }
116 	}
117 	else if (strcmp(argv[i],"-halg") == 0) {
118 	    i++;
119 	    if (i < argc) {
120 		if (strcmp(argv[i],"sha1") == 0) {
121 		    halg = TPM_ALG_SHA1;
122 		}
123 		else if (strcmp(argv[i],"sha256") == 0) {
124 		    halg = TPM_ALG_SHA256;
125 		}
126 		else if (strcmp(argv[i],"sha384") == 0) {
127 		    halg = TPM_ALG_SHA384;
128 		}
129 		else if (strcmp(argv[i],"sha512") == 0) {
130 		    halg = TPM_ALG_SHA512;
131 		}
132 		else {
133 		    printf("Bad parameter %s for -halg\n", argv[i]);
134 		    printUsage();
135 		}
136 	    }
137 	    else {
138 		printf("-halg option needs a value\n");
139 		printUsage();
140 	    }
141 	}
142 	else if (strcmp(argv[i],"-salg") == 0) {
143 	    i++;
144 	    if (i < argc) {
145 		if (strcmp(argv[i],"rsa") == 0) {
146 		    sigAlg = TPM_ALG_RSA;
147 		}
148 		else if (strcmp(argv[i],"ecc") == 0) {
149 		    sigAlg = TPM_ALG_ECDSA;
150 		}
151 		else if (strcmp(argv[i],"hmac") == 0) {
152 		    sigAlg = TPM_ALG_HMAC;
153 		}
154 		else {
155 		    printf("Bad parameter %s for -salg\n", argv[i]);
156 		    printUsage();
157 		}
158 	    }
159 	    else {
160 		printf("-salg option needs a value\n");
161 		printUsage();
162 	    }
163 	}
164 	else if (strcmp(argv[i],"-os") == 0) {
165 	    i++;
166 	    if (i < argc) {
167 		signatureFilename = argv[i];
168 	    }
169 	    else {
170 		printf("-os option needs a value\n");
171 		printUsage();
172 	    }
173 	}
174 	else if (strcmp(argv[i],"-oa") == 0) {
175 	    i++;
176 	    if (i < argc) {
177 		attestInfoFilename = argv[i];
178 	    }
179 	    else {
180 		printf("-oa option needs a value\n");
181 		printUsage();
182 	    }
183 	}
184 	else if (strcmp(argv[i],"-qd") == 0) {
185 	    i++;
186 	    if (i < argc) {
187 		qualifyingDataFilename = argv[i];
188 	    }
189 	    else {
190 		printf("-qd option needs a value\n");
191 		printUsage();
192 	    }
193 	}
194 	else if (strcmp(argv[i],"-se0") == 0) {
195 	    i++;
196 	    if (i < argc) {
197 		sscanf(argv[i],"%x", &sessionHandle0);
198 	    }
199 	    else {
200 		printf("Missing parameter for -se0\n");
201 		printUsage();
202 	    }
203 	    i++;
204 	    if (i < argc) {
205 		sscanf(argv[i],"%x", &sessionAttributes0);
206 		if (sessionAttributes0 > 0xff) {
207 		    printf("Out of range session attributes for -se0\n");
208 		    printUsage();
209 		}
210 	    }
211 	    else {
212 		printf("Missing parameter for -se0\n");
213 		printUsage();
214 	    }
215 	}
216 	else if (strcmp(argv[i],"-se1") == 0) {
217 	    i++;
218 	    if (i < argc) {
219 		sscanf(argv[i],"%x", &sessionHandle1);
220 	    }
221 	    else {
222 		printf("Missing parameter for -se1\n");
223 		printUsage();
224 	    }
225 	    i++;
226 	    if (i < argc) {
227 		sscanf(argv[i],"%x", &sessionAttributes1);
228 		if (sessionAttributes1 > 0xff) {
229 		    printf("Out of range session attributes for -se1\n");
230 		    printUsage();
231 		}
232 	    }
233 	    else {
234 		printf("Missing parameter for -se1\n");
235 		printUsage();
236 	    }
237 	}
238 	else if (strcmp(argv[i],"-se2") == 0) {
239 	    i++;
240 	    if (i < argc) {
241 		sscanf(argv[i],"%x", &sessionHandle2);
242 	    }
243 	    else {
244 		printf("Missing parameter for -se2\n");
245 		printUsage();
246 	    }
247 	    i++;
248 	    if (i < argc) {
249 		sscanf(argv[i],"%x", &sessionAttributes2);
250 		if (sessionAttributes2 > 0xff) {
251 		    printf("Out of range session attributes for -se2\n");
252 		    printUsage();
253 		}
254 	    }
255 	    else {
256 		printf("Missing parameter for -se2\n");
257 		printUsage();
258 	    }
259 	}
260  	else if (strcmp(argv[i],"-h") == 0) {
261 	    printUsage();
262 	}
263 	else if (strcmp(argv[i],"-v") == 0) {
264 	    tssUtilsVerbose = TRUE;
265 	    TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "2");
266 	}
267 	else {
268 	    printf("\n%s is not a valid option\n", argv[i]);
269 	    printUsage();
270 	}
271     }
272    if (signHandle == 0) {
273 	printf("Missing sign handle parameter -hk\n");
274 	printUsage();
275     }
276    if (rc == 0) {
277        /* Handle of key that authorized the audit */
278        in.privacyHandle = TPM_RH_ENDORSEMENT;
279        in.signHandle = signHandle;
280        if (sigAlg == TPM_ALG_RSA) {
281 	   /* Table 145 - Definition of TPMT_SIG_SCHEME Structure */
282 	   in.inScheme.scheme = TPM_ALG_RSASSA;
283 	   /* Table 144 - Definition of TPMU_SIG_SCHEME Union <IN/OUT, S> */
284 	   /* Table 142 - Definition of {RSA} Types for RSA Signature Schemes */
285 	   /* Table 135 - Definition of TPMS_SCHEME_HASH Structure */
286 	   in.inScheme.details.rsassa.hashAlg = halg;
287        }
288        else if (sigAlg == TPM_ALG_ECDSA) {
289 	   in.inScheme.scheme = TPM_ALG_ECDSA;
290 	   in.inScheme.details.ecdsa.hashAlg = halg;
291        }
292        else {	/* HMAC */
293 	   in.inScheme.scheme = TPM_ALG_HMAC;
294 	   in.inScheme.details.hmac.hashAlg = halg;
295        }
296     }
297     /* data supplied by the caller */
298     if (rc == 0) {
299 	if (qualifyingDataFilename != NULL) {
300 	    rc = TSS_File_Read2B(&in.qualifyingData.b,
301 				 sizeof(in.qualifyingData.t.buffer),
302 				 qualifyingDataFilename);
303 	}
304 	else {
305 	    in.qualifyingData.t.size = 0;
306 	}
307     }
308     /* Start a TSS context */
309     if (rc == 0) {
310 	rc = TSS_Create(&tssContext);
311     }
312     /* call TSS to execute the command */
313     if (rc == 0) {
314 	rc = TSS_Execute(tssContext,
315 			 (RESPONSE_PARAMETERS *)&out,
316 			 (COMMAND_PARAMETERS *)&in,
317 			 NULL,
318 			 TPM_CC_GetCommandAuditDigest,
319 			 sessionHandle0, privacyAdminPassword, sessionAttributes0,
320 			 sessionHandle1, signPassword, sessionAttributes1,
321 			 sessionHandle2, NULL, sessionAttributes2,
322 			 TPM_RH_NULL, NULL, 0);
323     }
324     {
325 	TPM_RC rc1 = TSS_Delete(tssContext);
326 	if (rc == 0) {
327 	    rc = rc1;
328 	}
329     }
330     if (rc == 0) {
331 	uint8_t *tmpBuffer = out.auditInfo.t.attestationData;
332 	uint32_t tmpSize = out.auditInfo.t.size;
333 	rc = TSS_TPMS_ATTEST_Unmarshalu(&tpmsAttest, &tmpBuffer, &tmpSize);
334     }
335     if (rc == 0) {
336 	if (tssUtilsVerbose) TSS_TPMS_ATTEST_Print(&tpmsAttest, 0);
337     }
338     if (rc == 0) {
339 	int match;
340 	match = TSS_TPM2B_Compare(&in.qualifyingData.b, &tpmsAttest.extraData.b);
341 	if (!match) {
342 	    printf("getcommandauditdigest: failed, extraData != qualifyingData\n");
343 	    rc = EXIT_FAILURE;
344 	}
345     }
346     if ((rc == 0) && (signatureFilename != NULL)) {
347 	rc = TSS_File_WriteStructure(&out.signature,
348 				     (MarshalFunction_t)TSS_TPMT_SIGNATURE_Marshalu,
349 				     signatureFilename);
350 
351 
352     }
353     if ((rc == 0) && (attestInfoFilename != NULL)) {
354 	rc = TSS_File_WriteBinaryFile(out.auditInfo.t.attestationData,
355 				      out.auditInfo.t.size,
356 				      attestInfoFilename);
357     }
358     if (rc == 0) {
359 	if (tssUtilsVerbose) TSS_TPMT_SIGNATURE_Print(&out.signature, 0);
360 	if (tssUtilsVerbose) printf("getcommandauditdigest: success\n");
361     }
362     else {
363 	const char *msg;
364 	const char *submsg;
365 	const char *num;
366 	printf("getcommandauditdigest: failed, rc %08x\n", rc);
367 	TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
368 	printf("%s%s%s\n", msg, submsg, num);
369 	rc = EXIT_FAILURE;
370     }
371     return rc;
372 }
373 
printUsage(void)374 static void printUsage(void)
375 {
376     printf("\n");
377     printf("getcommandauditdigest\n");
378     printf("\n");
379     printf("Runs TPM2_GetCommandAuditDigest\n");
380     printf("\n");
381     printf("\t[-pwde\tendorsement hierarchy password (default empty)]\n");
382     printf("\t-hk\tsigning key handle\n");
383     printf("\t[-pwdk\tpassword for key (default empty)]\n");
384     printf("\t[-halg\t(sha1, sha256, sha384, sha512) (default sha256)]\n");
385     printf("\t[-salg\tsignature algorithm (rsa, ecc, hmac) (default rsa)]\n");
386     printf("\t[-qd\tqualifying data file name]\n");
387     printf("\t[-os\tsignature file name (default do not save)]\n");
388     printf("\t[-oa\tattestation output file name (default do not save)]\n");
389     printf("\n");
390     printf("\t-se[0-2] session handle / attributes (default PWAP)\n");
391     printf("\t01\tcontinue\n");
392     printf("\t20\tcommand decrypt\n");
393     printf("\t40\tresponse encrypt\n");
394     exit(1);
395 }
396