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