147e946e7SWyllys Ingersoll /* 247e946e7SWyllys Ingersoll * CDDL HEADER START 347e946e7SWyllys Ingersoll * 447e946e7SWyllys Ingersoll * The contents of this file are subject to the terms of the 547e946e7SWyllys Ingersoll * Common Development and Distribution License (the "License"). 647e946e7SWyllys Ingersoll * You may not use this file except in compliance with the License. 747e946e7SWyllys Ingersoll * 847e946e7SWyllys Ingersoll * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 947e946e7SWyllys Ingersoll * or http://www.opensolaris.org/os/licensing. 1047e946e7SWyllys Ingersoll * See the License for the specific language governing permissions 1147e946e7SWyllys Ingersoll * and limitations under the License. 1247e946e7SWyllys Ingersoll * 1347e946e7SWyllys Ingersoll * When distributing Covered Code, include this CDDL HEADER in each 1447e946e7SWyllys Ingersoll * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1547e946e7SWyllys Ingersoll * If applicable, add the following below this CDDL HEADER, with the 1647e946e7SWyllys Ingersoll * fields enclosed by brackets "[]" replaced with your own identifying 1747e946e7SWyllys Ingersoll * information: Portions Copyright [yyyy] [name of copyright owner] 1847e946e7SWyllys Ingersoll * 1947e946e7SWyllys Ingersoll * CDDL HEADER END 2047e946e7SWyllys Ingersoll */ 2147e946e7SWyllys Ingersoll 2247e946e7SWyllys Ingersoll /* 2347e946e7SWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2447e946e7SWyllys Ingersoll * Use is subject to license terms. 2547e946e7SWyllys Ingersoll */ 2647e946e7SWyllys Ingersoll 2747e946e7SWyllys Ingersoll 2847e946e7SWyllys Ingersoll #include <stdlib.h> 2947e946e7SWyllys Ingersoll #include <stdio.h> 3047e946e7SWyllys Ingersoll #include <unistd.h> 3147e946e7SWyllys Ingersoll #include <strings.h> 3247e946e7SWyllys Ingersoll #include <libintl.h> 3347e946e7SWyllys Ingersoll #include <locale.h> 3447e946e7SWyllys Ingersoll 3547e946e7SWyllys Ingersoll #include <tss/tspi.h> 3647e946e7SWyllys Ingersoll #include "tpmadm.h" 3747e946e7SWyllys Ingersoll 3847e946e7SWyllys Ingersoll extern cmdtable_t commands[]; 3947e946e7SWyllys Ingersoll 4047e946e7SWyllys Ingersoll static void 4147e946e7SWyllys Ingersoll print_usage(char *progname, cmdtable_t cmds[]) 4247e946e7SWyllys Ingersoll { 4347e946e7SWyllys Ingersoll cmdtable_t *p; 4447e946e7SWyllys Ingersoll 4547e946e7SWyllys Ingersoll (void) fprintf(stderr, 4647e946e7SWyllys Ingersoll gettext("usage: %s command args ...\n"), progname); 4747e946e7SWyllys Ingersoll (void) fprintf(stderr, 4847e946e7SWyllys Ingersoll gettext("where 'command' is one of the following:\n")); 4947e946e7SWyllys Ingersoll for (p = &cmds[0]; p->name != NULL; p++) { 5047e946e7SWyllys Ingersoll (void) fprintf(stderr, "\t%s %s\n", p->name, p->args); 5147e946e7SWyllys Ingersoll } 5247e946e7SWyllys Ingersoll } 5347e946e7SWyllys Ingersoll 5447e946e7SWyllys Ingersoll int 5547e946e7SWyllys Ingersoll main(int argc, char *argv[]) 5647e946e7SWyllys Ingersoll { 5747e946e7SWyllys Ingersoll char *progname; 5847e946e7SWyllys Ingersoll cmdtable_t *p; 5947e946e7SWyllys Ingersoll cmdfunc_t fptr = NULL; 6047e946e7SWyllys Ingersoll int ret; 6147e946e7SWyllys Ingersoll TSS_HCONTEXT hContext; 6247e946e7SWyllys Ingersoll TSS_HOBJECT hTPM; 6347e946e7SWyllys Ingersoll 6447e946e7SWyllys Ingersoll /* Set up for i18n/l10n. */ 6547e946e7SWyllys Ingersoll #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 6647e946e7SWyllys Ingersoll #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 6747e946e7SWyllys Ingersoll #endif 6847e946e7SWyllys Ingersoll (void) setlocale(LC_ALL, ""); 6947e946e7SWyllys Ingersoll (void) textdomain(TEXT_DOMAIN); 7047e946e7SWyllys Ingersoll 7147e946e7SWyllys Ingersoll progname = argv[0]; 7247e946e7SWyllys Ingersoll argc--; 7347e946e7SWyllys Ingersoll argv++; 7447e946e7SWyllys Ingersoll 7547e946e7SWyllys Ingersoll if (argc <= 0) { 7647e946e7SWyllys Ingersoll print_usage(progname, commands); 7747e946e7SWyllys Ingersoll return (ERR_USAGE); 7847e946e7SWyllys Ingersoll } 7947e946e7SWyllys Ingersoll 8047e946e7SWyllys Ingersoll for (p = &commands[0]; p->name != NULL; p++) { 8147e946e7SWyllys Ingersoll if (0 == strcmp(p->name, argv[0])) { 8247e946e7SWyllys Ingersoll fptr = p->func; 8347e946e7SWyllys Ingersoll break; 8447e946e7SWyllys Ingersoll } 8547e946e7SWyllys Ingersoll } 8647e946e7SWyllys Ingersoll if (fptr == NULL) { 8747e946e7SWyllys Ingersoll print_usage(progname, commands); 8847e946e7SWyllys Ingersoll return (ERR_USAGE); 8947e946e7SWyllys Ingersoll } 9047e946e7SWyllys Ingersoll 9147e946e7SWyllys Ingersoll if (tpm_preamble(&hContext, &hTPM)) 9247e946e7SWyllys Ingersoll return (ERR_FAIL); 9347e946e7SWyllys Ingersoll ret = fptr(hContext, hTPM, argc, argv); 9447e946e7SWyllys Ingersoll (void) tpm_postamble(hContext); 9547e946e7SWyllys Ingersoll 9647e946e7SWyllys Ingersoll return (ret); 9747e946e7SWyllys Ingersoll } 9847e946e7SWyllys Ingersoll 9947e946e7SWyllys Ingersoll 10047e946e7SWyllys Ingersoll /* 10147e946e7SWyllys Ingersoll * Utility functions 10247e946e7SWyllys Ingersoll */ 10347e946e7SWyllys Ingersoll 10447e946e7SWyllys Ingersoll void 10547e946e7SWyllys Ingersoll print_bytes(BYTE *bytes, size_t len, int formatted) 10647e946e7SWyllys Ingersoll { 10747e946e7SWyllys Ingersoll int i; 10847e946e7SWyllys Ingersoll for (i = 0; i < len; i++) { 10947e946e7SWyllys Ingersoll (void) printf("%02X ", bytes[i]); 11047e946e7SWyllys Ingersoll if (formatted && i % 16 == 7) 11147e946e7SWyllys Ingersoll (void) printf(" "); 11247e946e7SWyllys Ingersoll if (formatted && i % 16 == 15) 11347e946e7SWyllys Ingersoll (void) printf("\n"); 11447e946e7SWyllys Ingersoll } 11547e946e7SWyllys Ingersoll (void) printf("\n"); 11647e946e7SWyllys Ingersoll } 11747e946e7SWyllys Ingersoll 11847e946e7SWyllys Ingersoll 11947e946e7SWyllys Ingersoll /* 12047e946e7SWyllys Ingersoll * TSS convenience functions 12147e946e7SWyllys Ingersoll */ 12247e946e7SWyllys Ingersoll 12347e946e7SWyllys Ingersoll void 12447e946e7SWyllys Ingersoll print_error(TSS_RESULT ret, char *msg) 12547e946e7SWyllys Ingersoll { 12647e946e7SWyllys Ingersoll char *err_string; 12747e946e7SWyllys Ingersoll extern char *Trspi_Error_String(); 12847e946e7SWyllys Ingersoll 129*35494a3dSScott Rotondo /* Print the standard error string and error code. */ 13047e946e7SWyllys Ingersoll err_string = Trspi_Error_String(ret); 13147e946e7SWyllys Ingersoll (void) fprintf(stderr, "%s: %s (0x%0x)\n", msg, err_string, ret); 132*35494a3dSScott Rotondo 133*35494a3dSScott Rotondo /* For a few special cases, add a more verbose error message. */ 134*35494a3dSScott Rotondo switch (ret) { 135*35494a3dSScott Rotondo case TPM_E_DEACTIVATED: 136*35494a3dSScott Rotondo case TPM_E_DISABLED: 137*35494a3dSScott Rotondo (void) fprintf(stderr, 138*35494a3dSScott Rotondo gettext("Enable the TPM and restart Solaris.\n")); 139*35494a3dSScott Rotondo break; 140*35494a3dSScott Rotondo case TSP_ERROR(TSS_E_COMM_FAILURE): 141*35494a3dSScott Rotondo (void) fprintf(stderr, 142*35494a3dSScott Rotondo gettext("Make sure the tcsd service " 143*35494a3dSScott Rotondo "(svc:/application/security/tcsd) is running.\n")); 144*35494a3dSScott Rotondo break; 145*35494a3dSScott Rotondo } 14647e946e7SWyllys Ingersoll } 14747e946e7SWyllys Ingersoll 14847e946e7SWyllys Ingersoll int 14947e946e7SWyllys Ingersoll get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap, 15047e946e7SWyllys Ingersoll UINT32 subcap, void *buf, size_t bufsize) 15147e946e7SWyllys Ingersoll { 15247e946e7SWyllys Ingersoll TSS_RESULT ret; 15347e946e7SWyllys Ingersoll UINT32 datalen; 15447e946e7SWyllys Ingersoll BYTE *data; 15547e946e7SWyllys Ingersoll 15647e946e7SWyllys Ingersoll ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap), 15747e946e7SWyllys Ingersoll (BYTE *)&subcap, &datalen, &data); 15847e946e7SWyllys Ingersoll if (ret) { 15947e946e7SWyllys Ingersoll print_error(ret, gettext("Get TPM capability")); 16047e946e7SWyllys Ingersoll return (ERR_FAIL); 16147e946e7SWyllys Ingersoll } 16247e946e7SWyllys Ingersoll 16347e946e7SWyllys Ingersoll if (datalen > bufsize) { 16447e946e7SWyllys Ingersoll (void) fprintf(stderr, 16547e946e7SWyllys Ingersoll gettext("Capability 0x%x returned %u bytes " 16647e946e7SWyllys Ingersoll "(expected %u)\n"), cap, datalen, bufsize); 16747e946e7SWyllys Ingersoll return (ERR_FAIL); 16847e946e7SWyllys Ingersoll } 16947e946e7SWyllys Ingersoll bcopy(data, buf, datalen); 17047e946e7SWyllys Ingersoll 17147e946e7SWyllys Ingersoll ret = Tspi_Context_FreeMemory(hContext, data); 17247e946e7SWyllys Ingersoll if (ret) { 17347e946e7SWyllys Ingersoll print_error(ret, gettext("Free capability buffer")); 17447e946e7SWyllys Ingersoll return (ERR_FAIL); 17547e946e7SWyllys Ingersoll } 17647e946e7SWyllys Ingersoll 17747e946e7SWyllys Ingersoll return (0); 17847e946e7SWyllys Ingersoll } 17947e946e7SWyllys Ingersoll 18047e946e7SWyllys Ingersoll int 18147e946e7SWyllys Ingersoll set_object_policy(TSS_HOBJECT handle, TSS_FLAG mode, UINT32 len, BYTE *secret) 18247e946e7SWyllys Ingersoll { 18347e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy; 18447e946e7SWyllys Ingersoll TSS_RESULT ret; 18547e946e7SWyllys Ingersoll 18647e946e7SWyllys Ingersoll ret = Tspi_GetPolicyObject(handle, TSS_POLICY_USAGE, &hPolicy); 18747e946e7SWyllys Ingersoll if (ret) { 18847e946e7SWyllys Ingersoll print_error(ret, gettext("Get object policy")); 18947e946e7SWyllys Ingersoll return (ERR_FAIL); 19047e946e7SWyllys Ingersoll } 19147e946e7SWyllys Ingersoll 19247e946e7SWyllys Ingersoll ret = Tspi_Policy_SetSecret(hPolicy, mode, len, secret); 19347e946e7SWyllys Ingersoll if (ret) { 19447e946e7SWyllys Ingersoll print_error(ret, gettext("Set policy secret")); 19547e946e7SWyllys Ingersoll return (ERR_FAIL); 19647e946e7SWyllys Ingersoll } 19747e946e7SWyllys Ingersoll 19847e946e7SWyllys Ingersoll return (0); 19947e946e7SWyllys Ingersoll } 20047e946e7SWyllys Ingersoll 20147e946e7SWyllys Ingersoll int 20247e946e7SWyllys Ingersoll tpm_preamble(TSS_HCONTEXT *hContext, TSS_HOBJECT *hTPM) 20347e946e7SWyllys Ingersoll { 20447e946e7SWyllys Ingersoll TSS_RESULT ret; 20547e946e7SWyllys Ingersoll 20647e946e7SWyllys Ingersoll ret = Tspi_Context_Create(hContext); 20747e946e7SWyllys Ingersoll if (ret) { 20847e946e7SWyllys Ingersoll print_error(ret, gettext("Create context")); 20947e946e7SWyllys Ingersoll return (ERR_FAIL); 21047e946e7SWyllys Ingersoll } 21147e946e7SWyllys Ingersoll 21247e946e7SWyllys Ingersoll ret = Tspi_Context_Connect(*hContext, NULL); 21347e946e7SWyllys Ingersoll if (ret) { 21447e946e7SWyllys Ingersoll print_error(ret, gettext("Connect context")); 21547e946e7SWyllys Ingersoll (void) Tspi_Context_Close(*hContext); 21647e946e7SWyllys Ingersoll return (ERR_FAIL); 21747e946e7SWyllys Ingersoll } 21847e946e7SWyllys Ingersoll 21947e946e7SWyllys Ingersoll ret = Tspi_Context_GetTpmObject(*hContext, hTPM); 22047e946e7SWyllys Ingersoll if (ret) { 22147e946e7SWyllys Ingersoll print_error(ret, gettext("Get TPM object")); 22247e946e7SWyllys Ingersoll (void) Tspi_Context_Close(*hContext); 22347e946e7SWyllys Ingersoll return (ERR_FAIL); 22447e946e7SWyllys Ingersoll } 22547e946e7SWyllys Ingersoll return (0); 22647e946e7SWyllys Ingersoll } 22747e946e7SWyllys Ingersoll 22847e946e7SWyllys Ingersoll int 22947e946e7SWyllys Ingersoll tpm_postamble(TSS_HCONTEXT hContext) 23047e946e7SWyllys Ingersoll { 23147e946e7SWyllys Ingersoll TSS_RESULT ret; 23247e946e7SWyllys Ingersoll 23347e946e7SWyllys Ingersoll ret = Tspi_Context_Close(hContext); 23447e946e7SWyllys Ingersoll if (ret) { 23547e946e7SWyllys Ingersoll print_error(ret, gettext("Close context")); 23647e946e7SWyllys Ingersoll return (ERR_FAIL); 23747e946e7SWyllys Ingersoll } 23847e946e7SWyllys Ingersoll return (0); 23947e946e7SWyllys Ingersoll } 240