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