xref: /titanic_52/usr/src/cmd/cmd-crypto/tpmadm/admin_cmds.c (revision 0a0e9771ca0211c15f3ac4466b661c145feeb9e4)
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 #include <unistd.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <strings.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <netinet/in.h>
34 #include <inttypes.h>
35 #include <sha1.h>
36 #include <uuid/uuid.h>
37 #include <sys/stat.h>
38 #include <libintl.h>
39 
40 #include <tss/tss_defines.h>
41 #include <tss/tspi.h>
42 
43 #include "tpmadm.h"
44 
45 int cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
46 int cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
47 int cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
48 int cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
49 int cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
50 int cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
51 
52 cmdtable_t commands[] = {
53 	{"status", "", cmd_status},
54 	{"init", "", cmd_init},
55 	{"clear", "[owner | lock]", cmd_clear},
56 	{"auth", "", cmd_auth},
57 	{"keyinfo", "[uuid]", cmd_keyinfo},
58 	{"deletekey", "uuid", cmd_deletekey},
59 	{NULL, NULL, NULL},
60 };
61 
62 BYTE well_known[] = TSS_WELL_KNOWN_SECRET;
63 TSS_UUID srk_uuid = TSS_UUID_SRK;
64 
65 
66 /*
67  * TPM status
68  */
69 
70 static int
71 print_tpm_version(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
72 {
73 	struct {
74 		TPM_CAP_VERSION_INFO vers_info;
75 		char extra[20]; /* vendor extensions */
76 	} info;
77 
78 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_VERSION_VAL,
79 	    0, &info, sizeof (info)))
80 		return (ERR_FAIL);
81 
82 	(void) printf(gettext("TPM Version: %d.%d (%c%c%c%c Rev: %d.%d, "
83 	    "SpecLevel: %d, ErrataRev: %d)\n"),
84 	    info.vers_info.version.major,
85 	    info.vers_info.version.minor,
86 	    info.vers_info.tpmVendorID[0],
87 	    info.vers_info.tpmVendorID[1],
88 	    info.vers_info.tpmVendorID[2],
89 	    info.vers_info.tpmVendorID[3],
90 	    info.vers_info.version.revMajor,
91 	    info.vers_info.version.revMinor,
92 	    (int)ntohs(info.vers_info.specLevel),
93 	    info.vers_info.errataRev);
94 
95 	return (0);
96 }
97 
98 static int
99 tpm_is_owned(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
100 {
101 	BYTE owned;
102 
103 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
104 	    TSS_TPMCAP_PROP_OWNER, &owned, sizeof (owned)))
105 		return (0);
106 
107 	return (owned);
108 }
109 
110 static int
111 print_tpm_resources(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
112 {
113 	UINT32 avail, max;
114 
115 	(void) printf(gettext("TPM resources\n"));
116 
117 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
118 	    TSS_TPMCAP_PROP_MAXCONTEXTS, &max, sizeof (max)))
119 		return (ERR_FAIL);
120 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
121 	    TSS_TPMCAP_PROP_CONTEXTS, &avail, sizeof (avail)))
122 		return (ERR_FAIL);
123 	(void) printf(gettext("\tContexts: %d/%d available\n"), avail, max);
124 
125 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
126 	    TSS_TPMCAP_PROP_MAXSESSIONS, &max, sizeof (max)))
127 		return (ERR_FAIL);
128 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
129 	    TSS_TPMCAP_PROP_SESSIONS, &avail, sizeof (avail)))
130 		return (ERR_FAIL);
131 	(void) printf(gettext("\tSessions: %d/%d available\n"), avail, max);
132 
133 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
134 	    TSS_TPMCAP_PROP_MAXAUTHSESSIONS, &max, sizeof (max)))
135 		return (ERR_FAIL);
136 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
137 	    TSS_TPMCAP_PROP_AUTHSESSIONS, &avail, sizeof (avail)))
138 		return (ERR_FAIL);
139 	(void) printf(gettext("\tAuth Sessions: %d/%d available\n"),
140 	    avail, max);
141 
142 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
143 	    TSS_TPMCAP_PROP_MAXKEYS, &max, sizeof (max)))
144 		return (ERR_FAIL);
145 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
146 	    TSS_TPMCAP_PROP_KEYS, &avail, sizeof (avail)))
147 		return (ERR_FAIL);
148 	(void) printf(gettext("\tLoaded Keys: %d/%d available\n"), avail, max);
149 
150 	return (0);
151 }
152 
153 static int
154 print_tpm_pcrs(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
155 {
156 	UINT32 num_pcrs;
157 	int i;
158 
159 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
160 	    TSS_TPMCAP_PROP_PCR, &num_pcrs, sizeof (num_pcrs)))
161 		return (ERR_FAIL);
162 	(void) printf(gettext("Platform Configuration Registers (%u)\n"),
163 	    num_pcrs);
164 
165 	/* Print each PCR */
166 	for (i = 0; i < num_pcrs; i++) {
167 		TSS_RESULT ret;
168 		UINT32 datalen;
169 		BYTE *data;
170 
171 		ret = Tspi_TPM_PcrRead(hTPM, i, &datalen, &data);
172 		if (ret) {
173 			print_error(ret, gettext("Read PCR"));
174 			return (ret);
175 		}
176 
177 		(void) printf("\tPCR %u:\t", i);
178 		print_bytes(data, datalen, FALSE);
179 
180 		ret = Tspi_Context_FreeMemory(hContext, data);
181 		if (ret) {
182 			print_error(ret, gettext("Free PCR memory"));
183 			return (ret);
184 		}
185 	}
186 	return (0);
187 }
188 
189 /*ARGSUSED*/
190 int
191 cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
192 {
193 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL))
194 		return (ERR_FAIL);
195 
196 	(void) print_tpm_version(hContext, hTPM);
197 	if (tpm_is_owned(hContext, hTPM)) {
198 		(void) print_tpm_resources(hContext, hTPM);
199 		(void) print_tpm_pcrs(hContext, hTPM);
200 	} else {
201 		(void) printf(gettext("No TPM owner installed.\n"));
202 	}
203 
204 	return (0);
205 }
206 
207 
208 /*
209  * Key Information
210  */
211 
212 typedef struct {
213 	UINT32 code;
214 	char *str;
215 } decode_map_t;
216 
217 decode_map_t key_usage[] = {
218 	{ TSS_KEYUSAGE_SIGN, "Signing" },
219 	{ TSS_KEYUSAGE_STORAGE, "Storage" },
220 	{ TSS_KEYUSAGE_IDENTITY, "Identity" },
221 	{ TSS_KEYUSAGE_AUTHCHANGE, "Authchange" },
222 	{ TSS_KEYUSAGE_BIND, "Bind" },
223 	{ TSS_KEYUSAGE_LEGACY, "Legacy" },
224 	{ TSS_KEYUSAGE_MIGRATE, "Migrate" },
225 	{ 0, NULL },
226 };
227 
228 decode_map_t key_algorithm[] = {
229 	{ TSS_ALG_RSA, "RSA" },
230 	{ TSS_ALG_DES, "DES" },
231 	{ TSS_ALG_3DES, "3-DES" },
232 	{ TSS_ALG_SHA, "SHA" },
233 	{ TSS_ALG_HMAC, "HMAC" },
234 	{ TSS_ALG_AES, "AES" },
235 	{ TSS_ALG_MGF1, "MGF1" },
236 	{ TSS_ALG_AES192, "AES192" },
237 	{ TSS_ALG_AES256, "AES256" },
238 	{ TSS_ALG_XOR, "XOR" },
239 	{ 0, NULL },
240 };
241 
242 decode_map_t key_sigscheme[] = {
243 	{ TSS_SS_NONE, "None" },
244 	{ TSS_SS_RSASSAPKCS1V15_SHA1, "RSASSAPKCS1v15_SHA1" },
245 	{ TSS_SS_RSASSAPKCS1V15_DER, "RSASSAPKCS1v15_DER" },
246 	{ 0, NULL },
247 };
248 
249 decode_map_t key_encscheme[] = {
250 	{ TSS_ES_NONE, "None" },
251 	{ TSS_ES_RSAESPKCSV15, "RSAESPKCSv15" },
252 	{ TSS_ES_RSAESOAEP_SHA1_MGF1, "RSAESOAEP_SHA1_MGF1" },
253 	{ TSS_ES_SYM_CNT, "SYM_CNT" },
254 	{ TSS_ES_SYM_OFB, "SYM_OFB" },
255 	{ 0, NULL },
256 };
257 
258 static char *
259 decode(decode_map_t *table, UINT32 code)
260 {
261 	static char buf[20];
262 	int i;
263 
264 	for (i = 0; table[i].str != NULL; i++) {
265 		if (table[i].code == code)
266 			return (table[i].str);
267 	}
268 
269 	(void) snprintf(buf, sizeof (buf), gettext("Unknown (%u)"), code);
270 	return (buf);
271 }
272 
273 static void
274 print_key_info(TSS_HCONTEXT hContext, TSS_HOBJECT hKey)
275 {
276 	TSS_RESULT ret;
277 	UINT32 attrib;
278 	UINT32 keyInfoSize;
279 	BYTE *keyInfo;
280 
281 	/* Key size */
282 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
283 	    TSS_TSPATTRIB_KEYINFO_SIZE, &attrib);
284 	if (ret) {
285 		print_error(ret, gettext("Get key size"));
286 	}
287 	(void) printf(gettext("Key Size: %d bits\n"), attrib);
288 
289 	/* Key usage */
290 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
291 	    TSS_TSPATTRIB_KEYINFO_USAGE, &attrib);
292 	if (ret) {
293 		print_error(ret, gettext("Get key usage"));
294 	}
295 	(void) printf(gettext("Key Usage: %s\n"), decode(key_usage, attrib));
296 
297 	/* Algorithm */
298 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
299 	    TSS_TSPATTRIB_KEYINFO_ALGORITHM, &attrib);
300 	if (ret) {
301 		print_error(ret, gettext("Get key algorithm"));
302 	}
303 	(void) printf(gettext("Algorithm: %s\n"),
304 	    decode(key_algorithm, attrib));
305 
306 	/* Authorization required */
307 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
308 	    TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &attrib);
309 	if (ret) {
310 		print_error(ret, gettext("Get key authusage"));
311 	}
312 	(void) printf(gettext("Authorization required: %s\n"),
313 	    attrib ? gettext("Yes") : gettext("No"));
314 
315 	/* Signature scheme */
316 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
317 	    TSS_TSPATTRIB_KEYINFO_SIGSCHEME, &attrib);
318 	if (ret) {
319 		print_error(ret, gettext("Get key signature scheme"));
320 	}
321 	(void) printf(gettext("Signature scheme: %s\n"),
322 	    decode(key_sigscheme, attrib));
323 
324 	/* Encoding scheme */
325 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
326 	    TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &attrib);
327 	if (ret) {
328 		print_error(ret, gettext("Get key encoding scheme"));
329 	}
330 	(void) printf(gettext("Encoding scheme: %s\n"),
331 	    decode(key_encscheme, attrib));
332 
333 	/* Key blob */
334 	ret = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
335 	    TSS_TSPATTRIB_KEYBLOB_BLOB, &keyInfoSize, &keyInfo);
336 	if (ret) {
337 		print_error(ret, gettext("Get key blob"));
338 	}
339 	(void) printf(gettext("TPM Key Blob:\n"));
340 	print_bytes(keyInfo, keyInfoSize, TRUE);
341 	ret = Tspi_Context_FreeMemory(hContext, keyInfo);
342 	if (ret) {
343 		print_error(ret, gettext("Free key info buffer"));
344 	}
345 }
346 
347 typedef struct hash_node {
348 	struct hash_node *next, *sibling, *child;
349 	TSS_UUID uuid;
350 	TSS_KM_KEYINFO2 *key_data;
351 } hash_node_t;
352 
353 #define	HASHSIZE 17
354 hash_node_t *hash_table[HASHSIZE];
355 
356 static hash_node_t *
357 hash_insert(TSS_UUID uuid, TSS_KM_KEYINFO2 *key_data)
358 {
359 	UINT32 i, index = 0;
360 	hash_node_t *node;
361 	char *cp;
362 
363 	cp = (char *)&uuid;
364 	for (i = 0; i < sizeof (TSS_UUID); i++)
365 		index += cp[i];
366 	index = index % HASHSIZE;
367 
368 	for (node = hash_table[index]; node != NULL; node = node->next) {
369 		if (memcmp(&(node->uuid), &uuid, sizeof (TSS_UUID)) == 0)
370 			break;
371 	}
372 
373 	if (node == NULL) {
374 		node = calloc(1, sizeof (hash_node_t));
375 		node->uuid = uuid;
376 		node->next = hash_table[index];
377 		hash_table[index] = node;
378 	}
379 	if (node->key_data == NULL)
380 		node->key_data = key_data;
381 
382 	return (node);
383 }
384 
385 static void
386 add_child(hash_node_t *parent, hash_node_t *child)
387 {
388 	hash_node_t *node;
389 
390 	for (node = parent->child; node != NULL; node = node->next) {
391 		if (node == child)
392 			return;
393 	}
394 
395 	child->sibling = parent->child;
396 	parent->child = child;
397 }
398 
399 static void
400 print_all(hash_node_t *parent, int indent)
401 {
402 	char uuidstr[UUID_PRINTABLE_STRING_LENGTH];
403 	hash_node_t *node;
404 	char *type, *loaded;
405 
406 	uuid_unparse(*(uuid_t *)&parent->uuid, uuidstr);
407 	type = (parent->key_data->persistentStorageType == TSS_PS_TYPE_USER) ?
408 	    "USER" : "SYSTEM";
409 	loaded = parent->key_data->fIsLoaded ? "(loaded)" : "";
410 	(void) printf("%*s[%s] %s %s\n", indent, "",
411 	    type, uuidstr, loaded);
412 
413 	for (node = parent->child; node != NULL; node = node->sibling)
414 		print_all(node, indent + 4);
415 }
416 
417 /*ARGSUSED*/
418 int
419 cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
420 {
421 	TSS_RESULT ret;
422 	UINT32 i, num_keys;
423 	TSS_KM_KEYINFO2 *keys;
424 	hash_node_t *parent, *child, *srk = NULL;
425 	TSS_HKEY hKey;
426 	union {
427 		uuid_t arr_uuid;
428 		TSS_UUID tss_uuid;
429 	} uuid;
430 
431 	switch (argc) {
432 		case 1:
433 		/* Print key hierarchy */
434 		ret = Tspi_Context_GetRegisteredKeysByUUID2(hContext,
435 		    TSS_PS_TYPE_USER, NULL, &num_keys, &keys);
436 		if (ret) {
437 			print_error(ret, gettext("Get key hierarchy"));
438 			return (ERR_FAIL);
439 		}
440 
441 		for (i = 0; i < num_keys; i++) {
442 			parent = hash_insert(keys[i].parentKeyUUID, NULL);
443 			child = hash_insert(keys[i].keyUUID, &keys[i]);
444 			add_child(parent, child);
445 			if (memcmp(&(keys[i].keyUUID), &srk_uuid,
446 			    sizeof (TSS_UUID)) == 0)
447 				srk = child;
448 		}
449 
450 		if (srk != NULL)
451 			print_all(srk, 0);
452 		ret = Tspi_Context_FreeMemory(hContext, (BYTE *) keys);
453 		if (ret) {
454 			print_error(ret, gettext("Free key list"));
455 			return (ERR_FAIL);
456 		}
457 		return (0);
458 
459 		case 2:
460 		/* Print detailed info about a single key */
461 		if (uuid_parse(argv[1], uuid.arr_uuid))
462 			return (ERR_FAIL);
463 		ret = Tspi_Context_GetKeyByUUID(hContext, TSS_PS_TYPE_USER,
464 		    uuid.tss_uuid, &hKey);
465 		if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) {
466 			ret = Tspi_Context_GetKeyByUUID(hContext,
467 			    TSS_PS_TYPE_SYSTEM, uuid.tss_uuid, &hKey);
468 		}
469 		if (ret) {
470 			print_error(ret, gettext("Get key by UUID"));
471 			return (ERR_FAIL);
472 		}
473 		print_key_info(hContext, hKey);
474 		return (0);
475 
476 		default:
477 		(void) fprintf(stderr, gettext("Usage:\n"));
478 		(void) fprintf(stderr, "\tkeyinfo [uuid]\n");
479 		return (ERR_USAGE);
480 	}
481 }
482 
483 /*ARGSUSED*/
484 int
485 cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
486 {
487 	TSS_RESULT ret;
488 	TSS_HOBJECT hKey;
489 	union {
490 		uuid_t arr_uuid;
491 		TSS_UUID tss_uuid;
492 	} uuid;
493 
494 	if (argc < 2) {
495 		(void) fprintf(stderr, gettext("Usage:\n"));
496 		(void) fprintf(stderr, "\tdeletekey [uuid]\n");
497 		return (ERR_USAGE);
498 	}
499 	if (uuid_parse(argv[1], uuid.arr_uuid))
500 		return (ERR_FAIL);
501 	ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_USER,
502 	    uuid.tss_uuid, &hKey);
503 	if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) {
504 		ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_SYSTEM,
505 		    uuid.tss_uuid, &hKey);
506 	}
507 	if (ret) {
508 		print_error(ret, gettext("Unregister key"));
509 		return (ERR_FAIL);
510 	}
511 	return (0);
512 }
513 
514 /*
515  * Clear
516  */
517 
518 static int
519 clearowner(TSS_HTPM hTPM)
520 {
521 	TSS_RESULT ret;
522 
523 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL))
524 		return (ERR_FAIL);
525 
526 	ret = Tspi_TPM_ClearOwner(hTPM, FALSE);
527 	if (ret) {
528 		print_error(ret, gettext("Clear TPM owner"));
529 		return (ERR_FAIL);
530 	}
531 	return (0);
532 }
533 
534 static int
535 resetlock(TSS_HTPM hTPM)
536 {
537 	TSS_RESULT ret;
538 
539 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL))
540 		return (ERR_FAIL);
541 
542 	ret = Tspi_TPM_SetStatus(hTPM, TSS_TPMSTATUS_RESETLOCK, TRUE);
543 	if (ret) {
544 		print_error(ret, gettext("Reset Lock"));
545 		return (ERR_FAIL);
546 	}
547 	return (0);
548 }
549 
550 /*ARGSUSED*/
551 int
552 cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
553 {
554 	char *subcmd = argv[1];
555 
556 	if (subcmd && strcmp(subcmd, "lock") == 0) {
557 		return (resetlock(hTPM));
558 	} else if (subcmd && strcmp(subcmd, "owner") == 0) {
559 		return (clearowner(hTPM));
560 	} else {
561 		(void) fprintf(stderr, gettext("Usage:\n"));
562 		(void) fprintf(stderr, "\tclear owner\n");
563 		(void) fprintf(stderr, "\tclear lock\n");
564 		return (ERR_USAGE);
565 	}
566 }
567 
568 
569 /*
570  * TPM initialization
571  */
572 
573 static int
574 get_random(UINT32 size,	BYTE *randomBytes)
575 {
576 	int fd, len;
577 	BYTE *buf;
578 
579 	fd = open("/dev/random", O_RDONLY);
580 	if (fd == -1) {
581 		(void) fprintf(stderr, gettext("Unable to open /dev/random"));
582 		return (-1);
583 	}
584 
585 	buf = randomBytes;
586 	while (size > 0) {
587 		len = read(fd, buf, size);
588 		if (len <= 0) {
589 			(void) close(fd);
590 			(void) fprintf(stderr,
591 			    gettext("Error reading /dev/random"));
592 			return (-1);
593 		}
594 		size -= len;
595 		buf += len;
596 	}
597 
598 	(void) close(fd);
599 	return (0);
600 }
601 
602 static int
603 createek(TSS_HCONTEXT hContext, TSS_HTPM hTPM)
604 {
605 	TSS_RESULT ret;
606 	TSS_HOBJECT hKeyEK;
607 	TSS_VALIDATION ValidationData;
608 	TPM_NONCE nonce;
609 	TPM_DIGEST digest;
610 
611 	/* Create the empty key struct for EK */
612 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
613 	    (TSS_KEY_NO_AUTHORIZATION | TSS_KEY_NON_VOLATILE |
614 	    TSS_KEY_NOT_MIGRATABLE | TSS_KEY_TYPE_STORAGE |
615 	    TSS_KEY_SIZE_2048 | TSS_KEY_NOT_CERTIFIED_MIGRATABLE |
616 	    TSS_KEY_STRUCT_KEY12 | TSS_KEY_EMPTY_KEY),
617 	    &hKeyEK);
618 	if (ret) {
619 		print_error(ret, gettext("Create endorsement key object"));
620 		return (ERR_FAIL);
621 	}
622 
623 	ValidationData.ulExternalDataLength = sizeof (nonce);
624 	ValidationData.rgbExternalData = (BYTE *) &nonce;
625 	ret = get_random(sizeof (nonce), (BYTE *) &nonce);
626 	if (ret)
627 		return (ERR_FAIL);
628 	ValidationData.ulValidationDataLength = sizeof (digest);
629 	ValidationData.rgbValidationData = (BYTE *) &digest;
630 
631 	ret = Tspi_TPM_CreateEndorsementKey(hTPM, hKeyEK, &ValidationData);
632 	if (ret) {
633 		print_error(ret, gettext("Create endorsement key"));
634 		return (ERR_FAIL);
635 	}
636 
637 	return (0);
638 }
639 
640 /*ARGSUSED*/
641 int
642 cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
643 {
644 	TSS_RESULT ret;
645 	TSS_HOBJECT hKeySRK;
646 
647 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL))
648 		return (ERR_FAIL);
649 
650 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
651 	    TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION, &hKeySRK);
652 	if (ret) {
653 		print_error(ret, gettext("Create storage root key"));
654 		return (ERR_FAIL);
655 	}
656 
657 	if (set_object_policy(hKeySRK, TSS_SECRET_MODE_SHA1,
658 	    sizeof (well_known), well_known))
659 		return (ERR_FAIL);
660 
661 	ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL);
662 	if (ret == TPM_E_NO_ENDORSEMENT) {
663 		if (createek(hContext, hTPM))
664 			return (ERR_FAIL);
665 		ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL);
666 	}
667 	if (ret) {
668 		print_error(ret, gettext("Take ownership"));
669 		return (ERR_FAIL);
670 	}
671 
672 	return (0);
673 }
674 
675 /*
676  * Auth
677  */
678 
679 /*ARGSUSED*/
680 int
681 cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
682 {
683 	TSS_RESULT ret;
684 	TSS_HPOLICY hNewPolicy;
685 
686 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL))
687 		return (ERR_FAIL);
688 
689 	/* new policy object */
690 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY,
691 	    TSS_POLICY_USAGE, &hNewPolicy);
692 	if (ret) {
693 		print_error(ret, gettext("Create policy object"));
694 		return (ERR_FAIL);
695 	}
696 	ret = Tspi_Policy_SetSecret(hNewPolicy, TSS_SECRET_MODE_POPUP,
697 	    0, NULL);
698 	if (ret) {
699 		print_error(ret, gettext("Set policy object secret"));
700 		return (ERR_FAIL);
701 	}
702 
703 	ret = Tspi_ChangeAuth(hTPM, NULL, hNewPolicy);
704 	if (ret) {
705 		print_error(ret, gettext("Change authorization"));
706 		return (ERR_FAIL);
707 	}
708 	return (0);
709 }
710