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 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <strings.h> 32 #include <libintl.h> 33 #include <locale.h> 34 35 #include <tss/tspi.h> 36 #include "tpmadm.h" 37 38 extern cmdtable_t commands[]; 39 40 static void 41 print_usage(char *progname, cmdtable_t cmds[]) 42 { 43 cmdtable_t *p; 44 45 (void) fprintf(stderr, 46 gettext("usage: %s command args ...\n"), progname); 47 (void) fprintf(stderr, 48 gettext("where 'command' is one of the following:\n")); 49 for (p = &cmds[0]; p->name != NULL; p++) { 50 (void) fprintf(stderr, "\t%s %s\n", p->name, p->args); 51 } 52 } 53 54 int 55 main(int argc, char *argv[]) 56 { 57 char *progname; 58 cmdtable_t *p; 59 cmdfunc_t fptr = NULL; 60 int ret; 61 TSS_HCONTEXT hContext; 62 TSS_HOBJECT hTPM; 63 64 /* Set up for i18n/l10n. */ 65 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 66 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 67 #endif 68 (void) setlocale(LC_ALL, ""); 69 (void) textdomain(TEXT_DOMAIN); 70 71 progname = argv[0]; 72 argc--; 73 argv++; 74 75 if (argc <= 0) { 76 print_usage(progname, commands); 77 return (ERR_USAGE); 78 } 79 80 for (p = &commands[0]; p->name != NULL; p++) { 81 if (0 == strcmp(p->name, argv[0])) { 82 fptr = p->func; 83 break; 84 } 85 } 86 if (fptr == NULL) { 87 print_usage(progname, commands); 88 return (ERR_USAGE); 89 } 90 91 if (tpm_preamble(&hContext, &hTPM)) 92 return (ERR_FAIL); 93 ret = fptr(hContext, hTPM, argc, argv); 94 (void) tpm_postamble(hContext); 95 96 return (ret); 97 } 98 99 100 /* 101 * Utility functions 102 */ 103 104 void 105 print_bytes(BYTE *bytes, size_t len, int formatted) 106 { 107 int i; 108 for (i = 0; i < len; i++) { 109 (void) printf("%02X ", bytes[i]); 110 if (formatted && i % 16 == 7) 111 (void) printf(" "); 112 if (formatted && i % 16 == 15) 113 (void) printf("\n"); 114 } 115 (void) printf("\n"); 116 } 117 118 119 /* 120 * TSS convenience functions 121 */ 122 123 void 124 print_error(TSS_RESULT ret, char *msg) 125 { 126 char *err_string; 127 extern char *Trspi_Error_String(); 128 129 /* Print the standard error string and error code. */ 130 err_string = Trspi_Error_String(ret); 131 (void) fprintf(stderr, "%s: %s (0x%0x)\n", msg, err_string, ret); 132 133 /* For a few special cases, add a more verbose error message. */ 134 switch (ret) { 135 case TPM_E_DEACTIVATED: 136 case TPM_E_DISABLED: 137 (void) fprintf(stderr, 138 gettext("Enable the TPM and restart Solaris.\n")); 139 break; 140 case TSP_ERROR(TSS_E_COMM_FAILURE): 141 (void) fprintf(stderr, 142 gettext("Make sure the tcsd service " 143 "(svc:/application/security/tcsd) is running.\n")); 144 break; 145 } 146 } 147 148 int 149 get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap, 150 UINT32 subcap, void *buf, size_t bufsize) 151 { 152 TSS_RESULT ret; 153 UINT32 datalen; 154 BYTE *data; 155 156 ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap), 157 (BYTE *)&subcap, &datalen, &data); 158 if (ret) { 159 print_error(ret, gettext("Get TPM capability")); 160 return (ERR_FAIL); 161 } 162 163 if (datalen > bufsize) { 164 (void) fprintf(stderr, 165 gettext("Capability 0x%x returned %u bytes " 166 "(expected %u)\n"), cap, datalen, bufsize); 167 return (ERR_FAIL); 168 } 169 bcopy(data, buf, datalen); 170 171 ret = Tspi_Context_FreeMemory(hContext, data); 172 if (ret) { 173 print_error(ret, gettext("Free capability buffer")); 174 return (ERR_FAIL); 175 } 176 177 return (0); 178 } 179 180 int 181 set_object_policy(TSS_HOBJECT handle, TSS_FLAG mode, UINT32 len, BYTE *secret) 182 { 183 TSS_HPOLICY hPolicy; 184 TSS_RESULT ret; 185 186 ret = Tspi_GetPolicyObject(handle, TSS_POLICY_USAGE, &hPolicy); 187 if (ret) { 188 print_error(ret, gettext("Get object policy")); 189 return (ERR_FAIL); 190 } 191 192 ret = Tspi_Policy_SetSecret(hPolicy, mode, len, secret); 193 if (ret) { 194 print_error(ret, gettext("Set policy secret")); 195 return (ERR_FAIL); 196 } 197 198 return (0); 199 } 200 201 int 202 tpm_preamble(TSS_HCONTEXT *hContext, TSS_HOBJECT *hTPM) 203 { 204 TSS_RESULT ret; 205 206 ret = Tspi_Context_Create(hContext); 207 if (ret) { 208 print_error(ret, gettext("Create context")); 209 return (ERR_FAIL); 210 } 211 212 ret = Tspi_Context_Connect(*hContext, NULL); 213 if (ret) { 214 print_error(ret, gettext("Connect context")); 215 (void) Tspi_Context_Close(*hContext); 216 return (ERR_FAIL); 217 } 218 219 ret = Tspi_Context_GetTpmObject(*hContext, hTPM); 220 if (ret) { 221 print_error(ret, gettext("Get TPM object")); 222 (void) Tspi_Context_Close(*hContext); 223 return (ERR_FAIL); 224 } 225 return (0); 226 } 227 228 int 229 tpm_postamble(TSS_HCONTEXT hContext) 230 { 231 TSS_RESULT ret; 232 233 ret = Tspi_Context_Close(hContext); 234 if (ret) { 235 print_error(ret, gettext("Close context")); 236 return (ERR_FAIL); 237 } 238 return (0); 239 } 240