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