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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 #include <sys/types.h>
33 #include <netinet/in.h>
36 #include <uuid/uuid.h>
40 #include <tss/tss_defines.h>
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
[]);
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
},
62 BYTE well_known
[] = TSS_WELL_KNOWN_SECRET
;
63 TSS_UUID srk_uuid
= TSS_UUID_SRK
;
71 print_tpm_version(TSS_HCONTEXT hContext
, TSS_HOBJECT hTPM
)
74 TPM_CAP_VERSION_INFO vers_info
;
75 char extra
[20]; /* vendor extensions */
78 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_VERSION_VAL
,
79 0, &info
, sizeof (info
)))
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
);
99 tpm_is_owned(TSS_HCONTEXT hContext
, TSS_HOBJECT hTPM
)
103 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
104 TSS_TPMCAP_PROP_OWNER
, &owned
, sizeof (owned
)))
111 print_tpm_resources(TSS_HCONTEXT hContext
, TSS_HOBJECT hTPM
)
115 (void) printf(gettext("TPM resources\n"));
117 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
118 TSS_TPMCAP_PROP_MAXCONTEXTS
, &max
, sizeof (max
)))
120 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
121 TSS_TPMCAP_PROP_CONTEXTS
, &avail
, sizeof (avail
)))
123 (void) printf(gettext("\tContexts: %d/%d available\n"), avail
, max
);
125 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
126 TSS_TPMCAP_PROP_MAXSESSIONS
, &max
, sizeof (max
)))
128 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
129 TSS_TPMCAP_PROP_SESSIONS
, &avail
, sizeof (avail
)))
131 (void) printf(gettext("\tSessions: %d/%d available\n"), avail
, max
);
133 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
134 TSS_TPMCAP_PROP_MAXAUTHSESSIONS
, &max
, sizeof (max
)))
136 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
137 TSS_TPMCAP_PROP_AUTHSESSIONS
, &avail
, sizeof (avail
)))
139 (void) printf(gettext("\tAuth Sessions: %d/%d available\n"),
142 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
143 TSS_TPMCAP_PROP_MAXKEYS
, &max
, sizeof (max
)))
145 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
146 TSS_TPMCAP_PROP_KEYS
, &avail
, sizeof (avail
)))
148 (void) printf(gettext("\tLoaded Keys: %d/%d available\n"), avail
, max
);
154 print_tpm_pcrs(TSS_HCONTEXT hContext
, TSS_HOBJECT hTPM
)
159 if (get_tpm_capability(hContext
, hTPM
, TSS_TPMCAP_PROPERTY
,
160 TSS_TPMCAP_PROP_PCR
, &num_pcrs
, sizeof (num_pcrs
)))
162 (void) printf(gettext("Platform Configuration Registers (%u)\n"),
166 for (i
= 0; i
< num_pcrs
; i
++) {
171 ret
= Tspi_TPM_PcrRead(hTPM
, i
, &datalen
, &data
);
173 print_error(ret
, gettext("Read PCR"));
177 (void) printf("\tPCR %u:\t", i
);
178 print_bytes(data
, datalen
, FALSE
);
180 ret
= Tspi_Context_FreeMemory(hContext
, data
);
182 print_error(ret
, gettext("Free PCR memory"));
191 cmd_status(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
193 if (set_object_policy(hTPM
, TSS_SECRET_MODE_POPUP
, NULL
, 0, NULL
))
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
);
201 (void) printf(gettext("No TPM owner installed.\n"));
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" },
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" },
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" },
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" },
259 decode(decode_map_t
*table
, UINT32 code
)
264 for (i
= 0; table
[i
].str
!= NULL
; i
++) {
265 if (table
[i
].code
== code
)
266 return (table
[i
].str
);
269 (void) snprintf(buf
, sizeof (buf
), gettext("Unknown (%u)"), code
);
274 print_key_info(TSS_HCONTEXT hContext
, TSS_HOBJECT hKey
)
282 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
283 TSS_TSPATTRIB_KEYINFO_SIZE
, &attrib
);
285 print_error(ret
, gettext("Get key size"));
287 (void) printf(gettext("Key Size: %d bits\n"), attrib
);
290 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
291 TSS_TSPATTRIB_KEYINFO_USAGE
, &attrib
);
293 print_error(ret
, gettext("Get key usage"));
295 (void) printf(gettext("Key Usage: %s\n"), decode(key_usage
, attrib
));
298 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
299 TSS_TSPATTRIB_KEYINFO_ALGORITHM
, &attrib
);
301 print_error(ret
, gettext("Get key algorithm"));
303 (void) printf(gettext("Algorithm: %s\n"),
304 decode(key_algorithm
, attrib
));
306 /* Authorization required */
307 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
308 TSS_TSPATTRIB_KEYINFO_AUTHUSAGE
, &attrib
);
310 print_error(ret
, gettext("Get key authusage"));
312 (void) printf(gettext("Authorization required: %s\n"),
313 attrib
? gettext("Yes") : gettext("No"));
315 /* Signature scheme */
316 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
317 TSS_TSPATTRIB_KEYINFO_SIGSCHEME
, &attrib
);
319 print_error(ret
, gettext("Get key signature scheme"));
321 (void) printf(gettext("Signature scheme: %s\n"),
322 decode(key_sigscheme
, attrib
));
324 /* Encoding scheme */
325 ret
= Tspi_GetAttribUint32(hKey
, TSS_TSPATTRIB_KEY_INFO
,
326 TSS_TSPATTRIB_KEYINFO_ENCSCHEME
, &attrib
);
328 print_error(ret
, gettext("Get key encoding scheme"));
330 (void) printf(gettext("Encoding scheme: %s\n"),
331 decode(key_encscheme
, attrib
));
334 ret
= Tspi_GetAttribData(hKey
, TSS_TSPATTRIB_KEY_BLOB
,
335 TSS_TSPATTRIB_KEYBLOB_BLOB
, &keyInfoSize
, &keyInfo
);
337 print_error(ret
, gettext("Get key blob"));
339 (void) printf(gettext("TPM Key Blob:\n"));
340 print_bytes(keyInfo
, keyInfoSize
, TRUE
);
341 ret
= Tspi_Context_FreeMemory(hContext
, keyInfo
);
343 print_error(ret
, gettext("Free key info buffer"));
347 typedef struct hash_node
{
348 struct hash_node
*next
, *sibling
, *child
;
350 TSS_KM_KEYINFO2
*key_data
;
354 hash_node_t
*hash_table
[HASHSIZE
];
357 hash_insert(TSS_UUID uuid
, TSS_KM_KEYINFO2
*key_data
)
364 for (i
= 0; i
< sizeof (TSS_UUID
); i
++)
366 index
= index
% HASHSIZE
;
368 for (node
= hash_table
[index
]; node
!= NULL
; node
= node
->next
) {
369 if (memcmp(&(node
->uuid
), &uuid
, sizeof (TSS_UUID
)) == 0)
374 node
= calloc(1, sizeof (hash_node_t
));
376 node
->next
= hash_table
[index
];
377 hash_table
[index
] = node
;
379 if (node
->key_data
== NULL
)
380 node
->key_data
= key_data
;
386 add_child(hash_node_t
*parent
, hash_node_t
*child
)
390 for (node
= parent
->child
; node
!= NULL
; node
= node
->next
) {
395 child
->sibling
= parent
->child
;
396 parent
->child
= child
;
400 print_all(hash_node_t
*parent
, int indent
)
402 char uuidstr
[UUID_PRINTABLE_STRING_LENGTH
];
406 uuid_unparse(*(uuid_t
*)&parent
->uuid
, uuidstr
);
407 type
= (parent
->key_data
->persistentStorageType
== TSS_PS_TYPE_USER
) ?
409 loaded
= parent
->key_data
->fIsLoaded
? "(loaded)" : "";
410 (void) printf("%*s[%s] %s %s\n", indent
, "",
411 type
, uuidstr
, loaded
);
413 for (node
= parent
->child
; node
!= NULL
; node
= node
->sibling
)
414 print_all(node
, indent
+ 4);
419 cmd_keyinfo(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
423 TSS_KM_KEYINFO2
*keys
;
424 hash_node_t
*parent
, *child
, *srk
= NULL
;
433 /* Print key hierarchy */
434 ret
= Tspi_Context_GetRegisteredKeysByUUID2(hContext
,
435 TSS_PS_TYPE_USER
, NULL
, &num_keys
, &keys
);
437 print_error(ret
, gettext("Get key hierarchy"));
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)
452 ret
= Tspi_Context_FreeMemory(hContext
, (BYTE
*) keys
);
454 print_error(ret
, gettext("Free key list"));
460 /* Print detailed info about a single key */
461 if (uuid_parse(argv
[1], uuid
.arr_uuid
))
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
);
470 print_error(ret
, gettext("Get key by UUID"));
473 print_key_info(hContext
, hKey
);
477 (void) fprintf(stderr
, gettext("Usage:\n"));
478 (void) fprintf(stderr
, "\tkeyinfo [uuid]\n");
485 cmd_deletekey(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
495 (void) fprintf(stderr
, gettext("Usage:\n"));
496 (void) fprintf(stderr
, "\tdeletekey [uuid]\n");
499 if (uuid_parse(argv
[1], uuid
.arr_uuid
))
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
);
508 print_error(ret
, gettext("Unregister key"));
519 clearowner(TSS_HTPM hTPM
)
523 if (set_object_policy(hTPM
, TSS_SECRET_MODE_POPUP
,
524 gettext("= TPM owner passphrase ="), 0, NULL
))
527 ret
= Tspi_TPM_ClearOwner(hTPM
, FALSE
);
529 print_error(ret
, gettext("Clear TPM owner"));
536 resetlock(TSS_HTPM hTPM
)
540 if (set_object_policy(hTPM
, TSS_SECRET_MODE_POPUP
,
541 gettext("= TPM owner passphrase ="), 0, NULL
))
544 ret
= Tspi_TPM_SetStatus(hTPM
, TSS_TPMSTATUS_RESETLOCK
, TRUE
);
546 print_error(ret
, gettext("Reset Lock"));
554 cmd_clear(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
556 char *subcmd
= argv
[1];
558 if (subcmd
&& strcmp(subcmd
, "lock") == 0) {
559 return (resetlock(hTPM
));
560 } else if (subcmd
&& strcmp(subcmd
, "owner") == 0) {
561 return (clearowner(hTPM
));
563 (void) fprintf(stderr
, gettext("Usage:\n"));
564 (void) fprintf(stderr
, "\tclear owner\n");
565 (void) fprintf(stderr
, "\tclear lock\n");
576 get_random(UINT32 size
, BYTE
*randomBytes
)
581 fd
= open("/dev/random", O_RDONLY
);
583 (void) fprintf(stderr
, gettext("Unable to open /dev/random"));
589 len
= read(fd
, buf
, size
);
592 (void) fprintf(stderr
,
593 gettext("Error reading /dev/random"));
605 createek(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
)
609 TSS_VALIDATION ValidationData
;
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
),
621 print_error(ret
, gettext("Create endorsement key object"));
625 ValidationData
.ulExternalDataLength
= sizeof (nonce
);
626 ValidationData
.rgbExternalData
= (BYTE
*) &nonce
;
627 ret
= get_random(sizeof (nonce
), (BYTE
*) &nonce
);
630 ValidationData
.ulValidationDataLength
= sizeof (digest
);
631 ValidationData
.rgbValidationData
= (BYTE
*) &digest
;
633 ret
= Tspi_TPM_CreateEndorsementKey(hTPM
, hKeyEK
, &ValidationData
);
635 print_error(ret
, gettext("Create endorsement key"));
644 cmd_init(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
649 if (set_object_policy(hTPM
, TSS_SECRET_MODE_POPUP
,
650 gettext("= TPM owner passphrase ="), 0, NULL
))
653 ret
= Tspi_Context_CreateObject(hContext
, TSS_OBJECT_TYPE_RSAKEY
,
654 TSS_KEY_TSP_SRK
| TSS_KEY_AUTHORIZATION
, &hKeySRK
);
656 print_error(ret
, gettext("Create storage root key"));
660 if (set_object_policy(hKeySRK
, TSS_SECRET_MODE_SHA1
, NULL
,
661 sizeof (well_known
), well_known
))
664 ret
= Tspi_TPM_TakeOwnership(hTPM
, hKeySRK
, NULL
);
665 if (ret
== TPM_E_NO_ENDORSEMENT
) {
666 if (createek(hContext
, hTPM
))
668 ret
= Tspi_TPM_TakeOwnership(hTPM
, hKeySRK
, NULL
);
671 print_error(ret
, gettext("Take ownership"));
684 cmd_auth(TSS_HCONTEXT hContext
, TSS_HTPM hTPM
, int argc
, char *argv
[])
687 TSS_HPOLICY hNewPolicy
;
689 if (set_object_policy(hTPM
, TSS_SECRET_MODE_POPUP
,
690 gettext("= TPM owner passphrase ="), 0, NULL
))
693 /* policy object for new passphrase */
694 ret
= Tspi_Context_CreateObject(hContext
, TSS_OBJECT_TYPE_POLICY
,
695 TSS_POLICY_USAGE
, &hNewPolicy
);
697 print_error(ret
, gettext("Create policy object"));
700 if (set_policy_options(hNewPolicy
, TSS_SECRET_MODE_POPUP
,
701 gettext("= New TPM owner passphrase ="), 0, NULL
))
704 ret
= Tspi_ChangeAuth(hTPM
, NULL
, hNewPolicy
);
705 if (ret
&& ret
!= TSP_ERROR(TSS_E_POLICY_NO_SECRET
)) {
706 print_error(ret
, gettext("Change authorization"));