1 /********************************************************************************/
2 /*										*/
3 /*			    NV SetBits		 				*/
4 /*			     Written by Ken Goldman				*/
5 /*		       IBM Thomas J. Watson Research Center			*/
6 /*										*/
7 /* (c) Copyright IBM Corporation 2015 - 2019.					*/
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 #include <inttypes.h>
48 
49 #include <ibmtss/tss.h>
50 #include <ibmtss/tssutils.h>
51 #include <ibmtss/tssresponsecode.h>
52 
53 static void printUsage(void);
54 
55 extern int tssUtilsVerbose;
56 
main(int argc,char * argv[])57 int main(int argc, char *argv[])
58 {
59     TPM_RC			rc = 0;
60     int				i;    /* argc iterator */
61     TSS_CONTEXT			*tssContext = NULL;
62     NV_SetBits_In 		in;
63     TPMI_RH_NV_INDEX		nvIndex = 0;
64     const char			*nvPassword = NULL; 		/* default no password */
65     TPMI_SH_AUTH_SESSION    	sessionHandle0 = TPM_RS_PW;
66     unsigned int		sessionAttributes0 = 0;
67     TPMI_SH_AUTH_SESSION    	sessionHandle1 = TPM_RH_NULL;
68     unsigned int		sessionAttributes1 = 0;
69     TPMI_SH_AUTH_SESSION    	sessionHandle2 = TPM_RH_NULL;
70     unsigned int		sessionAttributes2 = 0;
71 
72     setvbuf(stdout, 0, _IONBF, 0);      /* output may be going through pipe to log file */
73     TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1");
74     tssUtilsVerbose = FALSE;
75 
76     in.bits = 0;	/* default no bits */
77 
78     for (i=1 ; (i<argc) && (rc == 0) ; i++) {
79 	if (strcmp(argv[i],"-pwdn") == 0) {
80 	    i++;
81 	    if (i < argc) {
82 		nvPassword = argv[i];
83 	    }
84 	    else {
85 		printf("-pwdn option needs a value\n");
86 		printUsage();
87 	    }
88 	}
89 	else if (strcmp(argv[i],"-ha") == 0) {
90 	    i++;
91 	    if (i < argc) {
92 		sscanf(argv[i],"%x", &nvIndex);
93 	    }
94 	    else {
95 		printf("Missing parameter for -ha\n");
96 		printUsage();
97 	    }
98 	}
99 	else if (strcmp(argv[i],"-bit") == 0) {
100 	    unsigned int bit;
101 	    i++;
102 	    if (i < argc) {
103 		bit = atoi(argv[i]);
104 		if (bit < 64) {
105 		    in.bits |= (uint64_t)1 << bit;
106 		}
107 		else {
108 		    printf("-bit out of range\n");
109 		    printUsage();
110 		}
111 	    }
112 	    else {
113 		printf("-bit option needs a value\n");
114 		printUsage();
115 	    }
116 	}
117 	else if (strcmp(argv[i],"-se0") == 0) {
118 	    i++;
119 	    if (i < argc) {
120 		sscanf(argv[i],"%x", &sessionHandle0);
121 	    }
122 	    else {
123 		printf("Missing parameter for -se0\n");
124 		printUsage();
125 	    }
126 	    i++;
127 	    if (i < argc) {
128 		sscanf(argv[i],"%x", &sessionAttributes0);
129 		if (sessionAttributes0 > 0xff) {
130 		    printf("Out of range session attributes for -se0\n");
131 		    printUsage();
132 		}
133 	    }
134 	    else {
135 		printf("Missing parameter for -se0\n");
136 		printUsage();
137 	    }
138 	}
139 	else if (strcmp(argv[i],"-se1") == 0) {
140 	    i++;
141 	    if (i < argc) {
142 		sscanf(argv[i],"%x", &sessionHandle1);
143 	    }
144 	    else {
145 		printf("Missing parameter for -se1\n");
146 		printUsage();
147 	    }
148 	    i++;
149 	    if (i < argc) {
150 		sscanf(argv[i],"%x", &sessionAttributes1);
151 		if (sessionAttributes1 > 0xff) {
152 		    printf("Out of range session attributes for -se1\n");
153 		    printUsage();
154 		}
155 	    }
156 	    else {
157 		printf("Missing parameter for -se1\n");
158 		printUsage();
159 	    }
160 	}
161 	else if (strcmp(argv[i],"-se2") == 0) {
162 	    i++;
163 	    if (i < argc) {
164 		sscanf(argv[i],"%x", &sessionHandle2);
165 	    }
166 	    else {
167 		printf("Missing parameter for -se2\n");
168 		printUsage();
169 	    }
170 	    i++;
171 	    if (i < argc) {
172 		sscanf(argv[i],"%x", &sessionAttributes2);
173 		if (sessionAttributes2 > 0xff) {
174 		    printf("Out of range session attributes for -se2\n");
175 		    printUsage();
176 		}
177 	    }
178 	    else {
179 		printf("Missing parameter for -se2\n");
180 		printUsage();
181 	    }
182 	}
183 	else if (strcmp(argv[i],"-h") == 0) {
184 	    printUsage();
185 	}
186 	else if (strcmp(argv[i],"-v") == 0) {
187 	    tssUtilsVerbose = TRUE;
188 	    TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "2");
189 	}
190 	else {
191 	    printf("\n%s is not a valid option\n", argv[i]);
192 	    printUsage();
193 	}
194     }
195     if ((nvIndex >> 24) != TPM_HT_NV_INDEX) {
196 	printf("NV index handle not specified or out of range, MSB not 01\n");
197 	printUsage();
198     }
199     if (rc == 0) {
200 	in.authHandle = nvIndex;
201 	in.nvIndex = nvIndex;
202     }
203     /* Start a TSS context */
204     if (rc == 0) {
205 	rc = TSS_Create(&tssContext);
206     }
207     /* call TSS to execute the command */
208     if (rc == 0) {
209 	rc = TSS_Execute(tssContext,
210 			 NULL,
211 			 (COMMAND_PARAMETERS *)&in,
212 			 NULL,
213 			 TPM_CC_NV_SetBits,
214 			 sessionHandle0, nvPassword, sessionAttributes0,
215 			 sessionHandle1, NULL, sessionAttributes1,
216 			 sessionHandle2, NULL, sessionAttributes2,
217 			 TPM_RH_NULL, NULL, 0);
218     }
219     {
220 	TPM_RC rc1 = TSS_Delete(tssContext);
221 	if (rc == 0) {
222 	    rc = rc1;
223 	}
224     }
225     if (rc == 0) {
226 	if (tssUtilsVerbose) printf("nvsetbits: success\n");
227     }
228     else {
229 	const char *msg;
230 	const char *submsg;
231 	const char *num;
232 	printf("nvsetbits: failed, rc %08x\n", rc);
233 	TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
234 	printf("%s%s%s\n", msg, submsg, num);
235 	rc = EXIT_FAILURE;
236     }
237     return rc;
238 }
239 
printUsage(void)240 static void printUsage(void)
241 {
242     printf("\n");
243     printf("nvsetbits\n");
244     printf("\n");
245     printf("Runs TPM2_NV_SetBits\n");
246     printf("\n");
247     printf("\t-ha\tNV index handle\n");
248     printf("\t[-pwdn\tpassword for NV index (default empty)]\n");
249     printf("\t[-bit\tbit to set, can be specified multiple times]\n");
250     printf("\n");
251     printf("\t-se[0-2] session handle / attributes (default PWAP)\n");
252     printf("\t01\tcontinue\n");
253     exit(1);
254 }
255