xref: /titanic_50/usr/src/cmd/cmd-crypto/tpmadm/main.c (revision 47e946e784719ae402ace34695f67b0e6e76ae5c)
1*47e946e7SWyllys Ingersoll /*
2*47e946e7SWyllys Ingersoll  * CDDL HEADER START
3*47e946e7SWyllys Ingersoll  *
4*47e946e7SWyllys Ingersoll  * The contents of this file are subject to the terms of the
5*47e946e7SWyllys Ingersoll  * Common Development and Distribution License (the "License").
6*47e946e7SWyllys Ingersoll  * You may not use this file except in compliance with the License.
7*47e946e7SWyllys Ingersoll  *
8*47e946e7SWyllys Ingersoll  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*47e946e7SWyllys Ingersoll  * or http://www.opensolaris.org/os/licensing.
10*47e946e7SWyllys Ingersoll  * See the License for the specific language governing permissions
11*47e946e7SWyllys Ingersoll  * and limitations under the License.
12*47e946e7SWyllys Ingersoll  *
13*47e946e7SWyllys Ingersoll  * When distributing Covered Code, include this CDDL HEADER in each
14*47e946e7SWyllys Ingersoll  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*47e946e7SWyllys Ingersoll  * If applicable, add the following below this CDDL HEADER, with the
16*47e946e7SWyllys Ingersoll  * fields enclosed by brackets "[]" replaced with your own identifying
17*47e946e7SWyllys Ingersoll  * information: Portions Copyright [yyyy] [name of copyright owner]
18*47e946e7SWyllys Ingersoll  *
19*47e946e7SWyllys Ingersoll  * CDDL HEADER END
20*47e946e7SWyllys Ingersoll  */
21*47e946e7SWyllys Ingersoll 
22*47e946e7SWyllys Ingersoll /*
23*47e946e7SWyllys Ingersoll  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*47e946e7SWyllys Ingersoll  * Use is subject to license terms.
25*47e946e7SWyllys Ingersoll  */
26*47e946e7SWyllys Ingersoll 
27*47e946e7SWyllys Ingersoll 
28*47e946e7SWyllys Ingersoll #include <stdlib.h>
29*47e946e7SWyllys Ingersoll #include <stdio.h>
30*47e946e7SWyllys Ingersoll #include <unistd.h>
31*47e946e7SWyllys Ingersoll #include <strings.h>
32*47e946e7SWyllys Ingersoll #include <libintl.h>
33*47e946e7SWyllys Ingersoll #include <locale.h>
34*47e946e7SWyllys Ingersoll 
35*47e946e7SWyllys Ingersoll #include <tss/tspi.h>
36*47e946e7SWyllys Ingersoll #include "tpmadm.h"
37*47e946e7SWyllys Ingersoll 
38*47e946e7SWyllys Ingersoll extern cmdtable_t commands[];
39*47e946e7SWyllys Ingersoll 
40*47e946e7SWyllys Ingersoll static void
41*47e946e7SWyllys Ingersoll print_usage(char *progname, cmdtable_t cmds[])
42*47e946e7SWyllys Ingersoll {
43*47e946e7SWyllys Ingersoll 	cmdtable_t *p;
44*47e946e7SWyllys Ingersoll 
45*47e946e7SWyllys Ingersoll 	(void) fprintf(stderr,
46*47e946e7SWyllys Ingersoll 	    gettext("usage: %s command args ...\n"), progname);
47*47e946e7SWyllys Ingersoll 	(void) fprintf(stderr,
48*47e946e7SWyllys Ingersoll 	    gettext("where 'command' is one of the following:\n"));
49*47e946e7SWyllys Ingersoll 	for (p = &cmds[0]; p->name != NULL; p++) {
50*47e946e7SWyllys Ingersoll 		(void) fprintf(stderr, "\t%s %s\n", p->name, p->args);
51*47e946e7SWyllys Ingersoll 	}
52*47e946e7SWyllys Ingersoll }
53*47e946e7SWyllys Ingersoll 
54*47e946e7SWyllys Ingersoll int
55*47e946e7SWyllys Ingersoll main(int argc, char *argv[])
56*47e946e7SWyllys Ingersoll {
57*47e946e7SWyllys Ingersoll 	char *progname;
58*47e946e7SWyllys Ingersoll 	cmdtable_t *p;
59*47e946e7SWyllys Ingersoll 	cmdfunc_t fptr = NULL;
60*47e946e7SWyllys Ingersoll 	int ret;
61*47e946e7SWyllys Ingersoll 	TSS_HCONTEXT hContext;
62*47e946e7SWyllys Ingersoll 	TSS_HOBJECT hTPM;
63*47e946e7SWyllys Ingersoll 
64*47e946e7SWyllys Ingersoll 	/* Set up for i18n/l10n. */
65*47e946e7SWyllys Ingersoll #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D. */
66*47e946e7SWyllys Ingersoll #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it isn't. */
67*47e946e7SWyllys Ingersoll #endif
68*47e946e7SWyllys Ingersoll 	(void) setlocale(LC_ALL, "");
69*47e946e7SWyllys Ingersoll 	(void) textdomain(TEXT_DOMAIN);
70*47e946e7SWyllys Ingersoll 
71*47e946e7SWyllys Ingersoll 	progname = argv[0];
72*47e946e7SWyllys Ingersoll 	argc--;
73*47e946e7SWyllys Ingersoll 	argv++;
74*47e946e7SWyllys Ingersoll 
75*47e946e7SWyllys Ingersoll 	if (argc <= 0) {
76*47e946e7SWyllys Ingersoll 		print_usage(progname, commands);
77*47e946e7SWyllys Ingersoll 		return (ERR_USAGE);
78*47e946e7SWyllys Ingersoll 	}
79*47e946e7SWyllys Ingersoll 
80*47e946e7SWyllys Ingersoll 	for (p = &commands[0]; p->name != NULL; p++) {
81*47e946e7SWyllys Ingersoll 		if (0 == strcmp(p->name, argv[0])) {
82*47e946e7SWyllys Ingersoll 			fptr = p->func;
83*47e946e7SWyllys Ingersoll 			break;
84*47e946e7SWyllys Ingersoll 		}
85*47e946e7SWyllys Ingersoll 	}
86*47e946e7SWyllys Ingersoll 	if (fptr == NULL) {
87*47e946e7SWyllys Ingersoll 		print_usage(progname, commands);
88*47e946e7SWyllys Ingersoll 		return (ERR_USAGE);
89*47e946e7SWyllys Ingersoll 	}
90*47e946e7SWyllys Ingersoll 
91*47e946e7SWyllys Ingersoll 	if (tpm_preamble(&hContext, &hTPM))
92*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
93*47e946e7SWyllys Ingersoll 	ret = fptr(hContext, hTPM, argc, argv);
94*47e946e7SWyllys Ingersoll 	(void) tpm_postamble(hContext);
95*47e946e7SWyllys Ingersoll 
96*47e946e7SWyllys Ingersoll 	return (ret);
97*47e946e7SWyllys Ingersoll }
98*47e946e7SWyllys Ingersoll 
99*47e946e7SWyllys Ingersoll 
100*47e946e7SWyllys Ingersoll /*
101*47e946e7SWyllys Ingersoll  * Utility functions
102*47e946e7SWyllys Ingersoll  */
103*47e946e7SWyllys Ingersoll 
104*47e946e7SWyllys Ingersoll void
105*47e946e7SWyllys Ingersoll print_bytes(BYTE *bytes, size_t len, int formatted)
106*47e946e7SWyllys Ingersoll {
107*47e946e7SWyllys Ingersoll 	int i;
108*47e946e7SWyllys Ingersoll 	for (i = 0; i < len; i++) {
109*47e946e7SWyllys Ingersoll 		(void) printf("%02X ", bytes[i]);
110*47e946e7SWyllys Ingersoll 		if (formatted && i % 16 == 7)
111*47e946e7SWyllys Ingersoll 			(void) printf("  ");
112*47e946e7SWyllys Ingersoll 		if (formatted && i % 16 == 15)
113*47e946e7SWyllys Ingersoll 			(void) printf("\n");
114*47e946e7SWyllys Ingersoll 	}
115*47e946e7SWyllys Ingersoll 	(void) printf("\n");
116*47e946e7SWyllys Ingersoll }
117*47e946e7SWyllys Ingersoll 
118*47e946e7SWyllys Ingersoll 
119*47e946e7SWyllys Ingersoll /*
120*47e946e7SWyllys Ingersoll  * TSS convenience functions
121*47e946e7SWyllys Ingersoll  */
122*47e946e7SWyllys Ingersoll 
123*47e946e7SWyllys Ingersoll void
124*47e946e7SWyllys Ingersoll print_error(TSS_RESULT ret, char *msg)
125*47e946e7SWyllys Ingersoll {
126*47e946e7SWyllys Ingersoll 	char *err_string;
127*47e946e7SWyllys Ingersoll 	extern char *Trspi_Error_String();
128*47e946e7SWyllys Ingersoll 
129*47e946e7SWyllys Ingersoll 	err_string = Trspi_Error_String(ret);
130*47e946e7SWyllys Ingersoll 	(void) fprintf(stderr, "%s: %s (0x%0x)\n", msg, err_string, ret);
131*47e946e7SWyllys Ingersoll }
132*47e946e7SWyllys Ingersoll 
133*47e946e7SWyllys Ingersoll int
134*47e946e7SWyllys Ingersoll get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap,
135*47e946e7SWyllys Ingersoll UINT32 subcap, void *buf, size_t bufsize)
136*47e946e7SWyllys Ingersoll {
137*47e946e7SWyllys Ingersoll 	TSS_RESULT ret;
138*47e946e7SWyllys Ingersoll 	UINT32 datalen;
139*47e946e7SWyllys Ingersoll 	BYTE *data;
140*47e946e7SWyllys Ingersoll 
141*47e946e7SWyllys Ingersoll 	ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap),
142*47e946e7SWyllys Ingersoll 	    (BYTE *)&subcap, &datalen, &data);
143*47e946e7SWyllys Ingersoll 	if (ret) {
144*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get TPM capability"));
145*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
146*47e946e7SWyllys Ingersoll 	}
147*47e946e7SWyllys Ingersoll 
148*47e946e7SWyllys Ingersoll 	if (datalen > bufsize) {
149*47e946e7SWyllys Ingersoll 		(void) fprintf(stderr,
150*47e946e7SWyllys Ingersoll 		    gettext("Capability 0x%x returned %u bytes "
151*47e946e7SWyllys Ingersoll 		    "(expected %u)\n"), cap, datalen, bufsize);
152*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
153*47e946e7SWyllys Ingersoll 	}
154*47e946e7SWyllys Ingersoll 	bcopy(data, buf, datalen);
155*47e946e7SWyllys Ingersoll 
156*47e946e7SWyllys Ingersoll 	ret = Tspi_Context_FreeMemory(hContext, data);
157*47e946e7SWyllys Ingersoll 	if (ret) {
158*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Free capability buffer"));
159*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
160*47e946e7SWyllys Ingersoll 	}
161*47e946e7SWyllys Ingersoll 
162*47e946e7SWyllys Ingersoll 	return (0);
163*47e946e7SWyllys Ingersoll }
164*47e946e7SWyllys Ingersoll 
165*47e946e7SWyllys Ingersoll int
166*47e946e7SWyllys Ingersoll set_object_policy(TSS_HOBJECT handle, TSS_FLAG mode, UINT32 len, BYTE *secret)
167*47e946e7SWyllys Ingersoll {
168*47e946e7SWyllys Ingersoll 	TSS_HPOLICY hPolicy;
169*47e946e7SWyllys Ingersoll 	TSS_RESULT ret;
170*47e946e7SWyllys Ingersoll 
171*47e946e7SWyllys Ingersoll 	ret = Tspi_GetPolicyObject(handle, TSS_POLICY_USAGE, &hPolicy);
172*47e946e7SWyllys Ingersoll 	if (ret) {
173*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get object policy"));
174*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
175*47e946e7SWyllys Ingersoll 	}
176*47e946e7SWyllys Ingersoll 
177*47e946e7SWyllys Ingersoll 	ret = Tspi_Policy_SetSecret(hPolicy, mode, len, secret);
178*47e946e7SWyllys Ingersoll 	if (ret) {
179*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Set policy secret"));
180*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
181*47e946e7SWyllys Ingersoll 	}
182*47e946e7SWyllys Ingersoll 
183*47e946e7SWyllys Ingersoll 	return (0);
184*47e946e7SWyllys Ingersoll }
185*47e946e7SWyllys Ingersoll 
186*47e946e7SWyllys Ingersoll int
187*47e946e7SWyllys Ingersoll tpm_preamble(TSS_HCONTEXT *hContext, TSS_HOBJECT *hTPM)
188*47e946e7SWyllys Ingersoll {
189*47e946e7SWyllys Ingersoll 	TSS_RESULT ret;
190*47e946e7SWyllys Ingersoll 
191*47e946e7SWyllys Ingersoll 	ret = Tspi_Context_Create(hContext);
192*47e946e7SWyllys Ingersoll 	if (ret) {
193*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Create context"));
194*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
195*47e946e7SWyllys Ingersoll 	}
196*47e946e7SWyllys Ingersoll 
197*47e946e7SWyllys Ingersoll 	ret = Tspi_Context_Connect(*hContext, NULL);
198*47e946e7SWyllys Ingersoll 	if (ret) {
199*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Connect context"));
200*47e946e7SWyllys Ingersoll 		(void) Tspi_Context_Close(*hContext);
201*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
202*47e946e7SWyllys Ingersoll 	}
203*47e946e7SWyllys Ingersoll 
204*47e946e7SWyllys Ingersoll 	ret = Tspi_Context_GetTpmObject(*hContext, hTPM);
205*47e946e7SWyllys Ingersoll 	if (ret) {
206*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get TPM object"));
207*47e946e7SWyllys Ingersoll 		(void) Tspi_Context_Close(*hContext);
208*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
209*47e946e7SWyllys Ingersoll 	}
210*47e946e7SWyllys Ingersoll 	return (0);
211*47e946e7SWyllys Ingersoll }
212*47e946e7SWyllys Ingersoll 
213*47e946e7SWyllys Ingersoll int
214*47e946e7SWyllys Ingersoll tpm_postamble(TSS_HCONTEXT hContext)
215*47e946e7SWyllys Ingersoll {
216*47e946e7SWyllys Ingersoll 	TSS_RESULT ret;
217*47e946e7SWyllys Ingersoll 
218*47e946e7SWyllys Ingersoll 	ret = Tspi_Context_Close(hContext);
219*47e946e7SWyllys Ingersoll 	if (ret) {
220*47e946e7SWyllys Ingersoll 		print_error(ret, gettext("Close context"));
221*47e946e7SWyllys Ingersoll 		return (ERR_FAIL);
222*47e946e7SWyllys Ingersoll 	}
223*47e946e7SWyllys Ingersoll 	return (0);
224*47e946e7SWyllys Ingersoll }
225