1 2 /* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2006 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <unistd.h> 16 #include <sys/types.h> 17 #include <sys/stat.h> 18 #include <sys/mman.h> 19 #include <fcntl.h> 20 #include <errno.h> 21 22 #include "trousers/tss.h" 23 #include "trousers_types.h" 24 #include "tcs_tsp.h" 25 #include "tcs_utils.h" 26 #include "tcs_int_literals.h" 27 #include "capabilities.h" 28 #include "tcsps.h" 29 #include "tcslog.h" 30 #include "tddl.h" 31 #include "req_mgr.h" 32 33 34 TSS_RESULT 35 get_current_version(TPM_VERSION *version) 36 { 37 TCPA_CAPABILITY_AREA capArea = TPM_CAP_VERSION_VAL; 38 UINT32 respSize; 39 BYTE *resp; 40 TSS_RESULT result; 41 UINT64 offset; 42 43 /* try the 1.2 way first */ 44 result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize, &resp); 45 if (result == TSS_SUCCESS) { 46 offset = sizeof(UINT16); // XXX hack 47 UnloadBlob_VERSION(&offset, resp, version); 48 free(resp); 49 } else if (result == TCPA_E_BAD_MODE) { 50 /* if the TPM doesn't understand VERSION_VAL, try the 1.1 way */ 51 capArea = TCPA_CAP_VERSION; 52 result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize, 53 &resp); 54 if (result == TSS_SUCCESS) { 55 offset = 0; 56 UnloadBlob_VERSION(&offset, resp, version); 57 free(resp); 58 } 59 } 60 61 return result; 62 } 63 64 TSS_RESULT 65 get_cap_uint32(TCPA_CAPABILITY_AREA capArea, BYTE *subCap, UINT32 subCapSize, UINT32 *v) 66 { 67 UINT32 respSize; 68 BYTE *resp; 69 TSS_RESULT result; 70 UINT64 offset; 71 72 result = TCSP_GetCapability_Internal(InternalContext, capArea, subCapSize, subCap, 73 &respSize, &resp); 74 if (!result) { 75 offset = 0; 76 switch (respSize) { 77 case 1: 78 UnloadBlob_BYTE(&offset, (BYTE *)v, resp); 79 break; 80 case sizeof(UINT16): 81 UnloadBlob_UINT16(&offset, (UINT16 *)v, resp); 82 break; 83 case sizeof(UINT32): 84 UnloadBlob_UINT32(&offset, v, resp); 85 break; 86 default: 87 LogDebug("TCSP_GetCapability_Internal returned" 88 " %u bytes", respSize); 89 result = TCSERR(TSS_E_FAIL); 90 break; 91 } 92 free(resp); 93 } 94 95 return result; 96 } 97 98 99 TSS_RESULT 100 get_max_auths(UINT32 *auths) 101 { 102 TCS_AUTHHANDLE handles[TSS_MAX_AUTHS_CAP]; 103 TCPA_NONCE nonce; 104 UINT32 subCap; 105 TSS_RESULT result; 106 int i; 107 108 if (TPM_VERSION_IS(1,2)) { 109 UINT32ToArray(TPM_CAP_PROP_MAX_AUTHSESS, (BYTE *)(&subCap)); 110 result = get_cap_uint32(TPM_CAP_PROPERTY, (BYTE *)&subCap, sizeof(subCap), auths); 111 } else if (TPM_VERSION_IS(1,1)) { 112 /* open auth sessions until we get a failure */ 113 for (i = 0; i < TSS_MAX_AUTHS_CAP; i++) { 114 result = TCSP_OIAP_Internal(InternalContext, &(handles[i]), &nonce); 115 if (result != TSS_SUCCESS) { 116 /* this is not off by one since we're 0 indexed */ 117 *auths = i; 118 break; 119 } 120 } 121 122 if (i == TSS_MAX_AUTHS_CAP) 123 *auths = TSS_MAX_AUTHS_CAP; 124 125 /* close the auth sessions */ 126 for (i = 0; (UINT32)i < *auths; i++) { 127 internal_TerminateHandle(handles[i]); 128 } 129 } else { 130 result = TCSERR(TSS_E_INTERNAL_ERROR); 131 *auths = 0; 132 } 133 134 if (*auths < 2) { 135 LogError("%s reported only %u auth available!", __FUNCTION__, *auths); 136 LogError("Your TPM must be reset before the TCSD can be started."); 137 } else { 138 LogDebug("get_max_auths reports %u auth contexts found", *auths); 139 result = TSS_SUCCESS; 140 } 141 142 return result; 143 } 144 145 /* This is only called from init paths, so printing an error message is 146 * appropriate if something goes wrong */ 147 TSS_RESULT 148 get_tpm_metrics(struct tpm_properties *p) 149 { 150 TSS_RESULT result; 151 UINT32 subCap, rv = 0; 152 153 if ((result = get_current_version(&p->version))) 154 goto err; 155 156 UINT32ToArray(TPM_ORD_SaveKeyContext, (BYTE *)&subCap); 157 if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv))) 158 goto err; 159 p->keyctx_swap = rv ? TRUE : FALSE; 160 161 rv = 0; 162 UINT32ToArray(TPM_ORD_SaveAuthContext, (BYTE *)&subCap); 163 if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv))) 164 goto err; 165 p->authctx_swap = rv ? TRUE : FALSE; 166 167 UINT32ToArray(TPM_CAP_PROP_PCR, (BYTE *)&subCap); 168 if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), 169 &p->num_pcrs))) 170 goto err; 171 172 UINT32ToArray(TPM_CAP_PROP_DIR, (BYTE *)&subCap); 173 if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), 174 &p->num_dirs))) 175 goto err; 176 177 UINT32ToArray(TPM_CAP_PROP_SLOTS, (BYTE *)&subCap); 178 if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), 179 &p->num_keys))) 180 goto err; 181 182 UINT32ToArray(TPM_CAP_PROP_MANUFACTURER, (BYTE *)&subCap); 183 if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), 184 (UINT32 *)&p->manufacturer))) 185 goto err; 186 187 result = get_max_auths(&(p->num_auths)); 188 189 err: 190 if (result) 191 LogError("TCS GetCapability failed with result = 0x%x", result); 192 193 return result; 194 } 195 196