1 /********************************************************************************/
2 /*										*/
3 /*			   Rewrap		 				*/
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 
48 #include <ibmtss/tss.h>
49 #include <ibmtss/tssutils.h>
50 #include <ibmtss/tssresponsecode.h>
51 
52 static void printUsage(void);
53 
54 extern int tssUtilsVerbose;
55 
main(int argc,char * argv[])56 int main(int argc, char *argv[])
57 {
58     TPM_RC			rc = 0;
59     int				i;    /* argc iterator */
60     TSS_CONTEXT			*tssContext = NULL;
61     Rewrap_In 			in;
62     Rewrap_Out 			out;
63     TPMI_DH_OBJECT		oldParent = 0;
64     TPMI_DH_OBJECT		newParent = 0;
65     const char			*oldParentPassword = NULL;
66     const char			*inDuplicateFilename = NULL;
67     const char			*nameFilename = NULL;
68     const char			*inSymSeedFilename = NULL;
69     const char			*outDuplicateFilename = NULL;
70     const char			*outSymSeedFilename = NULL;
71     TPMI_SH_AUTH_SESSION    	sessionHandle0 = TPM_RS_PW;
72     unsigned int		sessionAttributes0 = 0;
73     TPMI_SH_AUTH_SESSION    	sessionHandle1 = TPM_RH_NULL;
74     unsigned int		sessionAttributes1 = 0;
75     TPMI_SH_AUTH_SESSION    	sessionHandle2 = TPM_RH_NULL;
76     unsigned int		sessionAttributes2 = 0;
77 
78     setvbuf(stdout, 0, _IONBF, 0);      /* output may be going through pipe to log file */
79     TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1");
80     tssUtilsVerbose = FALSE;
81 
82     for (i=1 ; (i<argc) && (rc == 0) ; i++) {
83 	if (strcmp(argv[i],"-ho") == 0) {
84 	    i++;
85 	    if (i < argc) {
86 		sscanf(argv[i],"%x", &oldParent);
87 	    }
88 	    else {
89 		printf("Missing parameter for -ho\n");
90 		printUsage();
91 	    }
92 	}
93 	else if (strcmp(argv[i],"-pwdo") == 0) {
94 	    i++;
95 	    if (i < argc) {
96 		oldParentPassword = argv[i];
97 	    }
98 	    else {
99 		printf("-pwdo option needs a value\n");
100 		printUsage();
101 	    }
102 	}
103 	else if (strcmp(argv[i],"-hn") == 0) {
104 	    i++;
105 	    if (i < argc) {
106 		sscanf(argv[i],"%x", &newParent);
107 	    }
108 	    else {
109 		printf("Missing parameter for -hp\n");
110 		printUsage();
111 	    }
112 	}
113 	else if (strcmp(argv[i],"-id") == 0) {
114 	    i++;
115 	    if (i < argc) {
116 		inDuplicateFilename = argv[i];
117 	    }
118 	    else {
119 		printf("-id option needs a value\n");
120 		printUsage();
121 	    }
122 	}
123 	else if (strcmp(argv[i],"-in") == 0) {
124 	    i++;
125 	    if (i < argc) {
126 		nameFilename = argv[i];
127 	    }
128 	    else {
129 		printf("-in option needs a value\n");
130 		printUsage();
131 	    }
132 	}
133 	else if (strcmp(argv[i],"-iss") == 0) {
134 	    i++;
135 	    if (i < argc) {
136 		inSymSeedFilename = argv[i];
137 	    }
138 	    else {
139 		printf("-iss option needs a value\n");
140 		printUsage();
141 	    }
142 	}
143 	else if (strcmp(argv[i],"-od") == 0) {
144 	    i++;
145 	    if (i < argc) {
146 		outDuplicateFilename = argv[i];
147 	    }
148 	    else {
149 		printf("-od option needs a value\n");
150 		printUsage();
151 	    }
152 	}
153 	else if (strcmp(argv[i],"-oss") == 0) {
154 	    i++;
155 	    if (i < argc) {
156 		outSymSeedFilename = argv[i];
157 	    }
158 	    else {
159 		printf("-oss option needs a value\n");
160 		printUsage();
161 	    }
162 	}
163 	else if (strcmp(argv[i],"-se0") == 0) {
164 	    i++;
165 	    if (i < argc) {
166 		sscanf(argv[i],"%x", &sessionHandle0);
167 	    }
168 	    else {
169 		printf("Missing parameter for -se0\n");
170 		printUsage();
171 	    }
172 	    i++;
173 	    if (i < argc) {
174 		sscanf(argv[i],"%x", &sessionAttributes0);
175 		if (sessionAttributes0 > 0xff) {
176 		    printf("Out of range session attributes for -se0\n");
177 		    printUsage();
178 		}
179 	    }
180 	    else {
181 		printf("Missing parameter for -se0\n");
182 		printUsage();
183 	    }
184 	}
185 	else if (strcmp(argv[i],"-se1") == 0) {
186 	    i++;
187 	    if (i < argc) {
188 		sscanf(argv[i],"%x", &sessionHandle1);
189 	    }
190 	    else {
191 		printf("Missing parameter for -se1\n");
192 		printUsage();
193 	    }
194 	    i++;
195 	    if (i < argc) {
196 		sscanf(argv[i],"%x", &sessionAttributes1);
197 		if (sessionAttributes1 > 0xff) {
198 		    printf("Out of range session attributes for -se1\n");
199 		    printUsage();
200 		}
201 	    }
202 	    else {
203 		printf("Missing parameter for -se1\n");
204 		printUsage();
205 	    }
206 	}
207 	else if (strcmp(argv[i],"-se2") == 0) {
208 	    i++;
209 	    if (i < argc) {
210 		sscanf(argv[i],"%x", &sessionHandle2);
211 	    }
212 	    else {
213 		printf("Missing parameter for -se2\n");
214 		printUsage();
215 	    }
216 	    i++;
217 	    if (i < argc) {
218 		sscanf(argv[i],"%x", &sessionAttributes2);
219 		if (sessionAttributes2 > 0xff) {
220 		    printf("Out of range session attributes for -se2\n");
221 		    printUsage();
222 		}
223 	    }
224 	    else {
225 		printf("Missing parameter for -se2\n");
226 		printUsage();
227 	    }
228 	}
229 	else if (strcmp(argv[i],"-h") == 0) {
230 	    printUsage();
231 	}
232 	else if (strcmp(argv[i],"-v") == 0) {
233 	    tssUtilsVerbose = TRUE;
234 	    TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "2");
235 	}
236 	else {
237 	    printf("\n%s is not a valid option\n", argv[i]);
238 	    printUsage();
239 	}
240     }
241     if (oldParent == 0) {
242 	printf("Missing or bad object old parent handle -ho\n");
243 	printUsage();
244     }
245     if (newParent == 0) {
246 	printf("Missing or bad object new parent handle -hn\n");
247 	printUsage();
248     }
249     if (inDuplicateFilename == NULL) {
250 	printf("Missing duplicate private area parameter -id\n");
251 	printUsage();
252     }
253     if (nameFilename == NULL) {
254 	printf("Missing name parameter -in\n");
255 	printUsage();
256     }
257     if (inSymSeedFilename == NULL) {
258 	printf("Missing input symmetric seed parameter -iss\n");
259 	printUsage();
260     }
261     if (rc == 0) {
262 	in.oldParent = oldParent;
263 	in.newParent = newParent;
264     }
265     if (rc == 0) {
266 	rc = TSS_File_Read2B(&in.inDuplicate.b,
267 			     sizeof(in.inDuplicate.t.buffer),
268 			     inDuplicateFilename);
269     }
270     if (rc == 0) {
271 	rc = TSS_File_Read2B(&in.name.b,
272 			     sizeof(in.name.t.name),
273 			     nameFilename);
274     }
275     if (rc == 0) {
276 	rc = TSS_File_Read2B(&in.inSymSeed.b,
277 			     sizeof(in.inSymSeed.t.secret),
278 			     inSymSeedFilename);
279     }
280     /* Start a TSS context */
281     if (rc == 0) {
282 	rc = TSS_Create(&tssContext);
283     }
284     /* call TSS to execute the command */
285     if (rc == 0) {
286 	rc = TSS_Execute(tssContext,
287 			 (RESPONSE_PARAMETERS *)&out,
288 			 (COMMAND_PARAMETERS *)&in,
289 			 NULL,
290 			 TPM_CC_Rewrap,
291 			 sessionHandle0, oldParentPassword, sessionAttributes0,
292 			 sessionHandle1, NULL, sessionAttributes1,
293 			 sessionHandle2, NULL, sessionAttributes2,
294 			 TPM_RH_NULL, NULL, 0);
295     }
296     {
297 	TPM_RC rc1 = TSS_Delete(tssContext);
298 	if (rc == 0) {
299 	    rc = rc1;
300 	}
301     }
302     if ((rc == 0) && (outDuplicateFilename != NULL)) {
303 	rc = TSS_File_WriteBinaryFile(out.outDuplicate.t.buffer,
304 				      out.outDuplicate.t.size,
305 				      outDuplicateFilename);
306     }
307     if ((rc == 0) && (outSymSeedFilename != NULL)) {
308 	rc = TSS_File_WriteBinaryFile(out.outSymSeed.t.secret,
309 				      out.outSymSeed.t.size,
310 				      outSymSeedFilename);
311     }
312     if (rc == 0) {
313 	if (tssUtilsVerbose) printf("rewrap: success\n");
314     }
315     else {
316 	const char *msg;
317 	const char *submsg;
318 	const char *num;
319 	printf("rewrap: failed, rc %08x\n", rc);
320 	TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
321 	printf("%s%s%s\n", msg, submsg, num);
322 	rc = EXIT_FAILURE;
323     }
324     return rc;
325 }
326 
printUsage(void)327 static void printUsage(void)
328 {
329     printf("\n");
330     printf("rewrap\n");
331     printf("\n");
332     printf("Runs TPM2_Rewrap\n");
333     printf("\n");
334     printf("\t-ho\thandle of object old parent\n");
335     printf("\t[-pwdo\tpassword for old parent (default empty)]\n");
336     printf("\t-hn\thandle of object new parent\n");
337     printf("\t-id\tduplicate private area file name\n");
338     printf("\t-in\tobject name file name\n");
339     printf("\t-iss\tinput symmetric seed file name");
340     printf("\n");
341     printf("\t[-od\trewrap private area file name (default do not save)]\n");
342     printf("\t[-oss\tsymmetric seed file name (default do not save)]\n");
343     printf("\n");
344     printf("\t-se[0-2] session handle / attributes (default PWAP)\n");
345     printf("\t01\tcontinue\n");
346     printf("\t20\tcommand decrypt\n");
347     printf("\t40\tresponse encrypt\n");
348     exit(1);
349 }
350