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
print_tpm_version(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)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
tpm_is_owned(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)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
print_tpm_resources(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)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
print_tpm_pcrs(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)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
cmd_status(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])191 cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
192 {
193 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, NULL, 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 *
decode(decode_map_t * table,UINT32 code)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
print_key_info(TSS_HCONTEXT hContext,TSS_HOBJECT hKey)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 *
hash_insert(TSS_UUID uuid,TSS_KM_KEYINFO2 * key_data)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
add_child(hash_node_t * parent,hash_node_t * child)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
print_all(hash_node_t * parent,int indent)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
cmd_keyinfo(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])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
cmd_deletekey(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])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
clearowner(TSS_HTPM hTPM)519 clearowner(TSS_HTPM hTPM)
520 {
521 	TSS_RESULT ret;
522 
523 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
524 	    gettext("= TPM owner passphrase ="), 0, NULL))
525 		return (ERR_FAIL);
526 
527 	ret = Tspi_TPM_ClearOwner(hTPM, FALSE);
528 	if (ret) {
529 		print_error(ret, gettext("Clear TPM owner"));
530 		return (ERR_FAIL);
531 	}
532 	return (0);
533 }
534 
535 static int
resetlock(TSS_HTPM hTPM)536 resetlock(TSS_HTPM hTPM)
537 {
538 	TSS_RESULT ret;
539 
540 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
541 	    gettext("= TPM owner passphrase ="), 0, NULL))
542 		return (ERR_FAIL);
543 
544 	ret = Tspi_TPM_SetStatus(hTPM, TSS_TPMSTATUS_RESETLOCK, TRUE);
545 	if (ret) {
546 		print_error(ret, gettext("Reset Lock"));
547 		return (ERR_FAIL);
548 	}
549 	return (0);
550 }
551 
552 /*ARGSUSED*/
553 int
cmd_clear(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])554 cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
555 {
556 	char *subcmd = argv[1];
557 
558 	if (subcmd && strcmp(subcmd, "lock") == 0) {
559 		return (resetlock(hTPM));
560 	} else if (subcmd && strcmp(subcmd, "owner") == 0) {
561 		return (clearowner(hTPM));
562 	} else {
563 		(void) fprintf(stderr, gettext("Usage:\n"));
564 		(void) fprintf(stderr, "\tclear owner\n");
565 		(void) fprintf(stderr, "\tclear lock\n");
566 		return (ERR_USAGE);
567 	}
568 }
569 
570 
571 /*
572  * TPM initialization
573  */
574 
575 static int
get_random(UINT32 size,BYTE * randomBytes)576 get_random(UINT32 size,	BYTE *randomBytes)
577 {
578 	int fd, len;
579 	BYTE *buf;
580 
581 	fd = open("/dev/random", O_RDONLY);
582 	if (fd == -1) {
583 		(void) fprintf(stderr, gettext("Unable to open /dev/random"));
584 		return (-1);
585 	}
586 
587 	buf = randomBytes;
588 	while (size > 0) {
589 		len = read(fd, buf, size);
590 		if (len <= 0) {
591 			(void) close(fd);
592 			(void) fprintf(stderr,
593 			    gettext("Error reading /dev/random"));
594 			return (-1);
595 		}
596 		size -= len;
597 		buf += len;
598 	}
599 
600 	(void) close(fd);
601 	return (0);
602 }
603 
604 static int
createek(TSS_HCONTEXT hContext,TSS_HTPM hTPM)605 createek(TSS_HCONTEXT hContext, TSS_HTPM hTPM)
606 {
607 	TSS_RESULT ret;
608 	TSS_HOBJECT hKeyEK;
609 	TSS_VALIDATION ValidationData;
610 	TPM_NONCE nonce;
611 	TPM_DIGEST digest;
612 
613 	/* Create the empty key struct for EK */
614 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
615 	    (TSS_KEY_NO_AUTHORIZATION | TSS_KEY_NON_VOLATILE |
616 	    TSS_KEY_NOT_MIGRATABLE | TSS_KEY_TYPE_STORAGE |
617 	    TSS_KEY_SIZE_2048 | TSS_KEY_NOT_CERTIFIED_MIGRATABLE |
618 	    TSS_KEY_STRUCT_KEY12 | TSS_KEY_EMPTY_KEY),
619 	    &hKeyEK);
620 	if (ret) {
621 		print_error(ret, gettext("Create endorsement key object"));
622 		return (ERR_FAIL);
623 	}
624 
625 	ValidationData.ulExternalDataLength = sizeof (nonce);
626 	ValidationData.rgbExternalData = (BYTE *) &nonce;
627 	ret = get_random(sizeof (nonce), (BYTE *) &nonce);
628 	if (ret)
629 		return (ERR_FAIL);
630 	ValidationData.ulValidationDataLength = sizeof (digest);
631 	ValidationData.rgbValidationData = (BYTE *) &digest;
632 
633 	ret = Tspi_TPM_CreateEndorsementKey(hTPM, hKeyEK, &ValidationData);
634 	if (ret) {
635 		print_error(ret, gettext("Create endorsement key"));
636 		return (ERR_FAIL);
637 	}
638 
639 	return (0);
640 }
641 
642 /*ARGSUSED*/
643 int
cmd_init(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])644 cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
645 {
646 	TSS_RESULT ret;
647 	TSS_HOBJECT hKeySRK;
648 
649 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
650 	    gettext("= TPM owner passphrase ="), 0, NULL))
651 		return (ERR_FAIL);
652 
653 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
654 	    TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION, &hKeySRK);
655 	if (ret) {
656 		print_error(ret, gettext("Create storage root key"));
657 		return (ERR_FAIL);
658 	}
659 
660 	if (set_object_policy(hKeySRK, TSS_SECRET_MODE_SHA1, NULL,
661 	    sizeof (well_known), well_known))
662 		return (ERR_FAIL);
663 
664 	ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, 0);
665 	if (ret == TPM_E_NO_ENDORSEMENT) {
666 		if (createek(hContext, hTPM))
667 			return (ERR_FAIL);
668 		ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, 0);
669 	}
670 	if (ret) {
671 		print_error(ret, gettext("Take ownership"));
672 		return (ERR_FAIL);
673 	}
674 
675 	return (0);
676 }
677 
678 /*
679  * Auth
680  */
681 
682 /*ARGSUSED*/
683 int
cmd_auth(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])684 cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
685 {
686 	TSS_RESULT ret;
687 	TSS_HPOLICY hNewPolicy;
688 
689 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
690 	    gettext("= TPM owner passphrase ="), 0, NULL))
691 		return (ERR_FAIL);
692 
693 	/* policy object for new passphrase */
694 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY,
695 	    TSS_POLICY_USAGE, &hNewPolicy);
696 	if (ret) {
697 		print_error(ret, gettext("Create policy object"));
698 		return (ERR_FAIL);
699 	}
700 	if (set_policy_options(hNewPolicy, TSS_SECRET_MODE_POPUP,
701 	    gettext("= New TPM owner passphrase ="), 0, NULL))
702 		return (ERR_FAIL);
703 
704 	ret = Tspi_ChangeAuth(hTPM, 0, hNewPolicy);
705 	if (ret && ret != TSP_ERROR(TSS_E_POLICY_NO_SECRET)) {
706 		print_error(ret, gettext("Change authorization"));
707 		return (ERR_FAIL);
708 	}
709 
710 	return (0);
711 }
712