1*9126SWyllys.Ingersoll@Sun.COM /* 2*9126SWyllys.Ingersoll@Sun.COM * CDDL HEADER START 3*9126SWyllys.Ingersoll@Sun.COM * 4*9126SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the 5*9126SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License"). 6*9126SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License. 7*9126SWyllys.Ingersoll@Sun.COM * 8*9126SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9126SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9126SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions 11*9126SWyllys.Ingersoll@Sun.COM * and limitations under the License. 12*9126SWyllys.Ingersoll@Sun.COM * 13*9126SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9126SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9126SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9126SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9126SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9126SWyllys.Ingersoll@Sun.COM * 19*9126SWyllys.Ingersoll@Sun.COM * CDDL HEADER END 20*9126SWyllys.Ingersoll@Sun.COM */ 21*9126SWyllys.Ingersoll@Sun.COM 22*9126SWyllys.Ingersoll@Sun.COM /* 23*9126SWyllys.Ingersoll@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9126SWyllys.Ingersoll@Sun.COM * Use is subject to license terms. 25*9126SWyllys.Ingersoll@Sun.COM */ 26*9126SWyllys.Ingersoll@Sun.COM 27*9126SWyllys.Ingersoll@Sun.COM 28*9126SWyllys.Ingersoll@Sun.COM #include <stdlib.h> 29*9126SWyllys.Ingersoll@Sun.COM #include <stdio.h> 30*9126SWyllys.Ingersoll@Sun.COM #include <unistd.h> 31*9126SWyllys.Ingersoll@Sun.COM #include <strings.h> 32*9126SWyllys.Ingersoll@Sun.COM #include <libintl.h> 33*9126SWyllys.Ingersoll@Sun.COM #include <locale.h> 34*9126SWyllys.Ingersoll@Sun.COM 35*9126SWyllys.Ingersoll@Sun.COM #include <tss/tspi.h> 36*9126SWyllys.Ingersoll@Sun.COM #include "tpmadm.h" 37*9126SWyllys.Ingersoll@Sun.COM 38*9126SWyllys.Ingersoll@Sun.COM extern cmdtable_t commands[]; 39*9126SWyllys.Ingersoll@Sun.COM 40*9126SWyllys.Ingersoll@Sun.COM static void 41*9126SWyllys.Ingersoll@Sun.COM print_usage(char *progname, cmdtable_t cmds[]) 42*9126SWyllys.Ingersoll@Sun.COM { 43*9126SWyllys.Ingersoll@Sun.COM cmdtable_t *p; 44*9126SWyllys.Ingersoll@Sun.COM 45*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, 46*9126SWyllys.Ingersoll@Sun.COM gettext("usage: %s command args ...\n"), progname); 47*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, 48*9126SWyllys.Ingersoll@Sun.COM gettext("where 'command' is one of the following:\n")); 49*9126SWyllys.Ingersoll@Sun.COM for (p = &cmds[0]; p->name != NULL; p++) { 50*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "\t%s %s\n", p->name, p->args); 51*9126SWyllys.Ingersoll@Sun.COM } 52*9126SWyllys.Ingersoll@Sun.COM } 53*9126SWyllys.Ingersoll@Sun.COM 54*9126SWyllys.Ingersoll@Sun.COM int 55*9126SWyllys.Ingersoll@Sun.COM main(int argc, char *argv[]) 56*9126SWyllys.Ingersoll@Sun.COM { 57*9126SWyllys.Ingersoll@Sun.COM char *progname; 58*9126SWyllys.Ingersoll@Sun.COM cmdtable_t *p; 59*9126SWyllys.Ingersoll@Sun.COM cmdfunc_t fptr = NULL; 60*9126SWyllys.Ingersoll@Sun.COM int ret; 61*9126SWyllys.Ingersoll@Sun.COM TSS_HCONTEXT hContext; 62*9126SWyllys.Ingersoll@Sun.COM TSS_HOBJECT hTPM; 63*9126SWyllys.Ingersoll@Sun.COM 64*9126SWyllys.Ingersoll@Sun.COM /* Set up for i18n/l10n. */ 65*9126SWyllys.Ingersoll@Sun.COM #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 66*9126SWyllys.Ingersoll@Sun.COM #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 67*9126SWyllys.Ingersoll@Sun.COM #endif 68*9126SWyllys.Ingersoll@Sun.COM (void) setlocale(LC_ALL, ""); 69*9126SWyllys.Ingersoll@Sun.COM (void) textdomain(TEXT_DOMAIN); 70*9126SWyllys.Ingersoll@Sun.COM 71*9126SWyllys.Ingersoll@Sun.COM progname = argv[0]; 72*9126SWyllys.Ingersoll@Sun.COM argc--; 73*9126SWyllys.Ingersoll@Sun.COM argv++; 74*9126SWyllys.Ingersoll@Sun.COM 75*9126SWyllys.Ingersoll@Sun.COM if (argc <= 0) { 76*9126SWyllys.Ingersoll@Sun.COM print_usage(progname, commands); 77*9126SWyllys.Ingersoll@Sun.COM return (ERR_USAGE); 78*9126SWyllys.Ingersoll@Sun.COM } 79*9126SWyllys.Ingersoll@Sun.COM 80*9126SWyllys.Ingersoll@Sun.COM for (p = &commands[0]; p->name != NULL; p++) { 81*9126SWyllys.Ingersoll@Sun.COM if (0 == strcmp(p->name, argv[0])) { 82*9126SWyllys.Ingersoll@Sun.COM fptr = p->func; 83*9126SWyllys.Ingersoll@Sun.COM break; 84*9126SWyllys.Ingersoll@Sun.COM } 85*9126SWyllys.Ingersoll@Sun.COM } 86*9126SWyllys.Ingersoll@Sun.COM if (fptr == NULL) { 87*9126SWyllys.Ingersoll@Sun.COM print_usage(progname, commands); 88*9126SWyllys.Ingersoll@Sun.COM return (ERR_USAGE); 89*9126SWyllys.Ingersoll@Sun.COM } 90*9126SWyllys.Ingersoll@Sun.COM 91*9126SWyllys.Ingersoll@Sun.COM if (tpm_preamble(&hContext, &hTPM)) 92*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 93*9126SWyllys.Ingersoll@Sun.COM ret = fptr(hContext, hTPM, argc, argv); 94*9126SWyllys.Ingersoll@Sun.COM (void) tpm_postamble(hContext); 95*9126SWyllys.Ingersoll@Sun.COM 96*9126SWyllys.Ingersoll@Sun.COM return (ret); 97*9126SWyllys.Ingersoll@Sun.COM } 98*9126SWyllys.Ingersoll@Sun.COM 99*9126SWyllys.Ingersoll@Sun.COM 100*9126SWyllys.Ingersoll@Sun.COM /* 101*9126SWyllys.Ingersoll@Sun.COM * Utility functions 102*9126SWyllys.Ingersoll@Sun.COM */ 103*9126SWyllys.Ingersoll@Sun.COM 104*9126SWyllys.Ingersoll@Sun.COM void 105*9126SWyllys.Ingersoll@Sun.COM print_bytes(BYTE *bytes, size_t len, int formatted) 106*9126SWyllys.Ingersoll@Sun.COM { 107*9126SWyllys.Ingersoll@Sun.COM int i; 108*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < len; i++) { 109*9126SWyllys.Ingersoll@Sun.COM (void) printf("%02X ", bytes[i]); 110*9126SWyllys.Ingersoll@Sun.COM if (formatted && i % 16 == 7) 111*9126SWyllys.Ingersoll@Sun.COM (void) printf(" "); 112*9126SWyllys.Ingersoll@Sun.COM if (formatted && i % 16 == 15) 113*9126SWyllys.Ingersoll@Sun.COM (void) printf("\n"); 114*9126SWyllys.Ingersoll@Sun.COM } 115*9126SWyllys.Ingersoll@Sun.COM (void) printf("\n"); 116*9126SWyllys.Ingersoll@Sun.COM } 117*9126SWyllys.Ingersoll@Sun.COM 118*9126SWyllys.Ingersoll@Sun.COM 119*9126SWyllys.Ingersoll@Sun.COM /* 120*9126SWyllys.Ingersoll@Sun.COM * TSS convenience functions 121*9126SWyllys.Ingersoll@Sun.COM */ 122*9126SWyllys.Ingersoll@Sun.COM 123*9126SWyllys.Ingersoll@Sun.COM void 124*9126SWyllys.Ingersoll@Sun.COM print_error(TSS_RESULT ret, char *msg) 125*9126SWyllys.Ingersoll@Sun.COM { 126*9126SWyllys.Ingersoll@Sun.COM char *err_string; 127*9126SWyllys.Ingersoll@Sun.COM extern char *Trspi_Error_String(); 128*9126SWyllys.Ingersoll@Sun.COM 129*9126SWyllys.Ingersoll@Sun.COM err_string = Trspi_Error_String(ret); 130*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "%s: %s (0x%0x)\n", msg, err_string, ret); 131*9126SWyllys.Ingersoll@Sun.COM } 132*9126SWyllys.Ingersoll@Sun.COM 133*9126SWyllys.Ingersoll@Sun.COM int 134*9126SWyllys.Ingersoll@Sun.COM get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap, 135*9126SWyllys.Ingersoll@Sun.COM UINT32 subcap, void *buf, size_t bufsize) 136*9126SWyllys.Ingersoll@Sun.COM { 137*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 138*9126SWyllys.Ingersoll@Sun.COM UINT32 datalen; 139*9126SWyllys.Ingersoll@Sun.COM BYTE *data; 140*9126SWyllys.Ingersoll@Sun.COM 141*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap), 142*9126SWyllys.Ingersoll@Sun.COM (BYTE *)&subcap, &datalen, &data); 143*9126SWyllys.Ingersoll@Sun.COM if (ret) { 144*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get TPM capability")); 145*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 146*9126SWyllys.Ingersoll@Sun.COM } 147*9126SWyllys.Ingersoll@Sun.COM 148*9126SWyllys.Ingersoll@Sun.COM if (datalen > bufsize) { 149*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, 150*9126SWyllys.Ingersoll@Sun.COM gettext("Capability 0x%x returned %u bytes " 151*9126SWyllys.Ingersoll@Sun.COM "(expected %u)\n"), cap, datalen, bufsize); 152*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 153*9126SWyllys.Ingersoll@Sun.COM } 154*9126SWyllys.Ingersoll@Sun.COM bcopy(data, buf, datalen); 155*9126SWyllys.Ingersoll@Sun.COM 156*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_FreeMemory(hContext, data); 157*9126SWyllys.Ingersoll@Sun.COM if (ret) { 158*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Free capability buffer")); 159*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 160*9126SWyllys.Ingersoll@Sun.COM } 161*9126SWyllys.Ingersoll@Sun.COM 162*9126SWyllys.Ingersoll@Sun.COM return (0); 163*9126SWyllys.Ingersoll@Sun.COM } 164*9126SWyllys.Ingersoll@Sun.COM 165*9126SWyllys.Ingersoll@Sun.COM int 166*9126SWyllys.Ingersoll@Sun.COM set_object_policy(TSS_HOBJECT handle, TSS_FLAG mode, UINT32 len, BYTE *secret) 167*9126SWyllys.Ingersoll@Sun.COM { 168*9126SWyllys.Ingersoll@Sun.COM TSS_HPOLICY hPolicy; 169*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 170*9126SWyllys.Ingersoll@Sun.COM 171*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetPolicyObject(handle, TSS_POLICY_USAGE, &hPolicy); 172*9126SWyllys.Ingersoll@Sun.COM if (ret) { 173*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get object policy")); 174*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 175*9126SWyllys.Ingersoll@Sun.COM } 176*9126SWyllys.Ingersoll@Sun.COM 177*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Policy_SetSecret(hPolicy, mode, len, secret); 178*9126SWyllys.Ingersoll@Sun.COM if (ret) { 179*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Set policy secret")); 180*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 181*9126SWyllys.Ingersoll@Sun.COM } 182*9126SWyllys.Ingersoll@Sun.COM 183*9126SWyllys.Ingersoll@Sun.COM return (0); 184*9126SWyllys.Ingersoll@Sun.COM } 185*9126SWyllys.Ingersoll@Sun.COM 186*9126SWyllys.Ingersoll@Sun.COM int 187*9126SWyllys.Ingersoll@Sun.COM tpm_preamble(TSS_HCONTEXT *hContext, TSS_HOBJECT *hTPM) 188*9126SWyllys.Ingersoll@Sun.COM { 189*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 190*9126SWyllys.Ingersoll@Sun.COM 191*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_Create(hContext); 192*9126SWyllys.Ingersoll@Sun.COM if (ret) { 193*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Create context")); 194*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 195*9126SWyllys.Ingersoll@Sun.COM } 196*9126SWyllys.Ingersoll@Sun.COM 197*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_Connect(*hContext, NULL); 198*9126SWyllys.Ingersoll@Sun.COM if (ret) { 199*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Connect context")); 200*9126SWyllys.Ingersoll@Sun.COM (void) Tspi_Context_Close(*hContext); 201*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 202*9126SWyllys.Ingersoll@Sun.COM } 203*9126SWyllys.Ingersoll@Sun.COM 204*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_GetTpmObject(*hContext, hTPM); 205*9126SWyllys.Ingersoll@Sun.COM if (ret) { 206*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get TPM object")); 207*9126SWyllys.Ingersoll@Sun.COM (void) Tspi_Context_Close(*hContext); 208*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 209*9126SWyllys.Ingersoll@Sun.COM } 210*9126SWyllys.Ingersoll@Sun.COM return (0); 211*9126SWyllys.Ingersoll@Sun.COM } 212*9126SWyllys.Ingersoll@Sun.COM 213*9126SWyllys.Ingersoll@Sun.COM int 214*9126SWyllys.Ingersoll@Sun.COM tpm_postamble(TSS_HCONTEXT hContext) 215*9126SWyllys.Ingersoll@Sun.COM { 216*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 217*9126SWyllys.Ingersoll@Sun.COM 218*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_Close(hContext); 219*9126SWyllys.Ingersoll@Sun.COM if (ret) { 220*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Close context")); 221*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 222*9126SWyllys.Ingersoll@Sun.COM } 223*9126SWyllys.Ingersoll@Sun.COM return (0); 224*9126SWyllys.Ingersoll@Sun.COM } 225