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 #include <stdlib.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <inttypes.h> 15 16 #include "trousers/tss.h" 17 #include "trousers/trousers.h" 18 #include "trousers_types.h" 19 #include "spi_utils.h" 20 #include "capabilities.h" 21 #include "tsplog.h" 22 #include "obj.h" 23 24 25 TSS_RESULT 26 Tspi_TPM_GetCapability(TSS_HTPM hTPM, /* in */ 27 TSS_FLAG capArea, /* in */ 28 UINT32 ulSubCapLength, /* in */ 29 BYTE * rgbSubCap, /* in */ 30 UINT32 * pulRespDataLength, /* out */ 31 BYTE ** prgbRespData) /* out */ 32 { 33 TSS_HCONTEXT tspContext; 34 TPM_CAPABILITY_AREA tcsCapArea; 35 UINT32 tcsSubCap = 0; 36 UINT32 tcsSubCapContainer; 37 TSS_RESULT result; 38 UINT32 nonVolFlags, volFlags, respLen; 39 BYTE *respData; 40 UINT64 offset; 41 TSS_BOOL fOwnerAuth = FALSE, endianFlag = TRUE; 42 43 if (pulRespDataLength == NULL || prgbRespData == NULL) 44 return TSPERR(TSS_E_BAD_PARAMETER); 45 46 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 47 return result; 48 49 /* Verify the caps and subcaps */ 50 switch (capArea) { 51 case TSS_TPMCAP_ORD: 52 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 53 return TSPERR(TSS_E_BAD_PARAMETER); 54 55 tcsCapArea = TCPA_CAP_ORD; 56 tcsSubCap = *(UINT32 *)rgbSubCap; 57 break; 58 case TSS_TPMCAP_FLAG: 59 fOwnerAuth = TRUE; 60 break; 61 case TSS_TPMCAP_AUTH_ENCRYPT: 62 case TSS_TPMCAP_ALG: 63 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 64 return TSPERR(TSS_E_BAD_PARAMETER); 65 66 /* Test capArea again here in order to keep from having to duplicate the switch 67 * statement below */ 68 tcsCapArea = (capArea == TSS_TPMCAP_ALG ? TPM_CAP_ALG : TPM_CAP_AUTH_ENCRYPT); 69 70 switch (*(UINT32 *)rgbSubCap) { 71 case TSS_ALG_RSA: 72 tcsSubCap = TPM_ALG_RSA; 73 break; 74 case TSS_ALG_AES128: 75 tcsSubCap = TPM_ALG_AES128; 76 break; 77 case TSS_ALG_AES192: 78 tcsSubCap = TPM_ALG_AES192; 79 break; 80 case TSS_ALG_AES256: 81 tcsSubCap = TPM_ALG_AES256; 82 break; 83 case TSS_ALG_3DES: 84 tcsSubCap = TPM_ALG_3DES; 85 break; 86 case TSS_ALG_DES: 87 tcsSubCap = TPM_ALG_DES; 88 break; 89 case TSS_ALG_SHA: 90 tcsSubCap = TPM_ALG_SHA; 91 break; 92 case TSS_ALG_HMAC: 93 tcsSubCap = TPM_ALG_HMAC; 94 break; 95 case TSS_ALG_MGF1: 96 tcsSubCap = TPM_ALG_MGF1; 97 break; 98 case TSS_ALG_XOR: 99 tcsSubCap = TPM_ALG_XOR; 100 break; 101 default: 102 tcsSubCap = *(UINT32 *)rgbSubCap; 103 break; 104 } 105 break; 106 #ifdef TSS_BUILD_NV 107 case TSS_TPMCAP_NV_LIST: 108 tcsCapArea = TPM_CAP_NV_LIST; 109 endianFlag = FALSE; 110 break; 111 case TSS_TPMCAP_NV_INDEX: 112 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 113 return TSPERR(TSS_E_BAD_PARAMETER); 114 115 tcsCapArea = TPM_CAP_NV_INDEX; 116 tcsSubCap = *(UINT32 *)rgbSubCap; 117 break; 118 #endif 119 case TSS_TPMCAP_PROPERTY: /* Determines a physical property of the TPM. */ 120 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 121 return TSPERR(TSS_E_BAD_PARAMETER); 122 123 tcsCapArea = TCPA_CAP_PROPERTY; 124 tcsSubCapContainer = *(UINT32 *)rgbSubCap; 125 126 switch (tcsSubCapContainer) { 127 case TSS_TPMCAP_PROP_PCR: 128 tcsSubCap = TPM_CAP_PROP_PCR; 129 break; 130 case TSS_TPMCAP_PROP_DIR: 131 tcsSubCap = TPM_CAP_PROP_DIR; 132 break; 133 /* case TSS_TPMCAP_PROP_SLOTS: */ 134 case TSS_TPMCAP_PROP_KEYS: 135 tcsSubCap = TPM_CAP_PROP_SLOTS; 136 break; 137 case TSS_TPMCAP_PROP_MANUFACTURER: 138 tcsSubCap = TPM_CAP_PROP_MANUFACTURER; 139 endianFlag = FALSE; 140 break; 141 case TSS_TPMCAP_PROP_COUNTERS: 142 tcsSubCap = TPM_CAP_PROP_COUNTERS; 143 break; 144 case TSS_TPMCAP_PROP_MAXCOUNTERS: 145 tcsSubCap = TPM_CAP_PROP_MAX_COUNTERS; 146 break; 147 /*case TSS_TPMCAP_PROP_MINCOUNTERINCTIME: */ 148 case TSS_TPMCAP_PROP_MIN_COUNTER: 149 tcsSubCap = TPM_CAP_PROP_MIN_COUNTER; 150 break; 151 case TSS_TPMCAP_PROP_ACTIVECOUNTER: 152 tcsSubCap = TPM_CAP_PROP_ACTIVE_COUNTER; 153 break; 154 case TSS_TPMCAP_PROP_TRANSESSIONS: 155 tcsSubCap = TPM_CAP_PROP_TRANSSESS; 156 break; 157 case TSS_TPMCAP_PROP_MAXTRANSESSIONS: 158 tcsSubCap = TPM_CAP_PROP_MAX_TRANSSESS; 159 break; 160 case TSS_TPMCAP_PROP_SESSIONS: 161 tcsSubCap = TPM_CAP_PROP_SESSIONS; 162 break; 163 case TSS_TPMCAP_PROP_MAXSESSIONS: 164 tcsSubCap = TPM_CAP_PROP_MAX_SESSIONS; 165 break; 166 case TSS_TPMCAP_PROP_FAMILYROWS: 167 tcsSubCap = TPM_CAP_PROP_FAMILYROWS; 168 break; 169 case TSS_TPMCAP_PROP_DELEGATEROWS: 170 tcsSubCap = TPM_CAP_PROP_DELEGATE_ROW; 171 break; 172 case TSS_TPMCAP_PROP_OWNER: 173 tcsSubCap = TPM_CAP_PROP_OWNER; 174 break; 175 case TSS_TPMCAP_PROP_MAXKEYS: 176 tcsSubCap = TPM_CAP_PROP_MAX_KEYS; 177 break; 178 case TSS_TPMCAP_PROP_AUTHSESSIONS: 179 tcsSubCap = TPM_CAP_PROP_AUTHSESS; 180 break; 181 case TSS_TPMCAP_PROP_MAXAUTHSESSIONS: 182 tcsSubCap = TPM_CAP_PROP_MAX_AUTHSESS; 183 break; 184 case TSS_TPMCAP_PROP_CONTEXTS: 185 tcsSubCap = TPM_CAP_PROP_CONTEXT; 186 break; 187 case TSS_TPMCAP_PROP_MAXCONTEXTS: 188 tcsSubCap = TPM_CAP_PROP_MAX_CONTEXT; 189 break; 190 case TSS_TPMCAP_PROP_DAASESSIONS: 191 tcsSubCap = TPM_CAP_PROP_SESSION_DAA; 192 break; 193 case TSS_TPMCAP_PROP_MAXDAASESSIONS: 194 tcsSubCap = TPM_CAP_PROP_DAA_MAX; 195 break; 196 case TSS_TPMCAP_PROP_TISTIMEOUTS: 197 tcsSubCap = TPM_CAP_PROP_TIS_TIMEOUT; 198 break; 199 case TSS_TPMCAP_PROP_STARTUPEFFECTS: 200 tcsSubCap = TPM_CAP_PROP_STARTUP_EFFECT; 201 endianFlag = FALSE; 202 break; 203 case TSS_TPMCAP_PROP_MAXCONTEXTCOUNTDIST: 204 tcsSubCap = TPM_CAP_PROP_CONTEXT_DIST; 205 break; 206 case TSS_TPMCAP_PROP_CMKRESTRICTION: 207 tcsSubCap = TPM_CAP_PROP_CMK_RESTRICTION; 208 break; 209 case TSS_TPMCAP_PROP_DURATION: 210 tcsSubCap = TPM_CAP_PROP_DURATION; 211 break; 212 case TSS_TPMCAP_PROP_MAXNVAVAILABLE: 213 tcsSubCap = TPM_CAP_PROP_NV_AVAILABLE; 214 break; 215 case TSS_TPMCAP_PROP_INPUTBUFFERSIZE: 216 tcsSubCap = TPM_CAP_PROP_INPUT_BUFFER; 217 break; 218 #if 0 219 /* There isn't a way to query the TPM for these, the TPMWG is considering how to 220 * address some of them in the next version of the TPM - KEY Oct 15, 2007*/ 221 case TSS_TPMCAP_PROP_MAXNVWRITE: 222 break; 223 case TSS_TPMCAP_PROP_REVISION: 224 break; 225 case TSS_TPMCAP_PROP_LOCALITIES_AVAIL: 226 break; 227 case TSS_TPMCAP_PROP_PCRMAP: 228 break; 229 #endif 230 default: 231 return TSPERR(TSS_E_BAD_PARAMETER); 232 } 233 break; 234 case TSS_TPMCAP_VERSION: /* Queries the current TPM version. */ 235 tcsCapArea = TCPA_CAP_VERSION; 236 endianFlag = FALSE; 237 break; 238 case TSS_TPMCAP_VERSION_VAL: /* Queries the current TPM version for 1.2 TPM device. */ 239 tcsCapArea = TPM_CAP_VERSION_VAL; 240 endianFlag = FALSE; 241 break; 242 case TSS_TPMCAP_MFR: 243 tcsCapArea = TPM_CAP_MFR; 244 endianFlag = FALSE; 245 break; 246 case TSS_TPMCAP_SYM_MODE: 247 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 248 return TSPERR(TSS_E_BAD_PARAMETER); 249 250 tcsCapArea = TPM_CAP_SYM_MODE; 251 tcsSubCap = *(UINT32 *)rgbSubCap; 252 break; 253 case TSS_TPMCAP_HANDLE: 254 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 255 return TSPERR(TSS_E_BAD_PARAMETER); 256 257 tcsCapArea = TPM_CAP_HANDLE; 258 tcsSubCap = *(UINT32 *)rgbSubCap; 259 break; 260 case TSS_TPMCAP_TRANS_ES: 261 if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) 262 return TSPERR(TSS_E_BAD_PARAMETER); 263 264 tcsCapArea = TPM_CAP_TRANS_ES; 265 switch (*(UINT32 *)rgbSubCap) { 266 case TSS_ES_NONE: 267 tcsSubCap = TPM_ES_NONE; 268 break; 269 case TSS_ES_RSAESPKCSV15: 270 tcsSubCap = TPM_ES_RSAESPKCSv15; 271 break; 272 case TSS_ES_RSAESOAEP_SHA1_MGF1: 273 tcsSubCap = TPM_ES_RSAESOAEP_SHA1_MGF1; 274 break; 275 case TSS_ES_SYM_CNT: 276 tcsSubCap = TPM_ES_SYM_CNT; 277 break; 278 case TSS_ES_SYM_OFB: 279 tcsSubCap = TPM_ES_SYM_OFB; 280 break; 281 case TSS_ES_SYM_CBC_PKCS5PAD: 282 tcsSubCap = TPM_ES_SYM_CBC_PKCS5PAD; 283 break; 284 default: 285 tcsSubCap = *(UINT32 *)rgbSubCap; 286 break; 287 } 288 break; 289 default: 290 return TSPERR(TSS_E_BAD_PARAMETER); 291 break; 292 } 293 294 if (fOwnerAuth) { 295 /* do an owner authorized get capability call */ 296 if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags))) 297 return result; 298 299 respLen = 2 * sizeof(UINT32); 300 respData = calloc_tspi(tspContext, respLen); 301 if (respData == NULL) { 302 LogError("malloc of %u bytes failed.", respLen); 303 return TSPERR(TSS_E_OUTOFMEMORY); 304 } 305 306 offset = 0; 307 Trspi_LoadBlob_UINT32(&offset, nonVolFlags, respData); 308 Trspi_LoadBlob_UINT32(&offset, volFlags, respData); 309 310 *pulRespDataLength = respLen; 311 *prgbRespData = respData; 312 313 return TSS_SUCCESS; 314 } 315 316 tcsSubCap = endian32(tcsSubCap); 317 318 if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, tcsCapArea, ulSubCapLength, 319 (BYTE *)&tcsSubCap, pulRespDataLength, 320 prgbRespData))) 321 return result; 322 323 if (endianFlag) { 324 if (*pulRespDataLength == sizeof(UINT32)) 325 *(UINT32 *)(*prgbRespData) = endian32(*(UINT32 *)(*prgbRespData)); 326 else if (*pulRespDataLength == sizeof(UINT16)) 327 *(UINT32 *)(*prgbRespData) = endian16(*(UINT32 *)(*prgbRespData)); 328 } 329 330 if ((result = __tspi_add_mem_entry(tspContext, *prgbRespData))) { 331 free(*prgbRespData); 332 *prgbRespData = NULL; 333 *pulRespDataLength = 0; 334 return result; 335 } 336 337 return TSS_SUCCESS; 338 } 339 340 TSS_RESULT 341 Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM, /* in */ 342 TSS_HTPM hKey, /* in */ 343 TSS_FLAG capArea, /* in */ 344 UINT32 ulSubCapLength, /* in */ 345 BYTE * rgbSubCap, /* in */ 346 TSS_VALIDATION * pValidationData, /* in, out */ 347 UINT32 * pulRespDataLength, /* out */ 348 BYTE ** prgbRespData) /* out */ 349 { 350 /* 351 * Function was found to have a vulnerability, so implementation is not 352 * required by the TSS 1.1b spec. 353 */ 354 return TSPERR(TSS_E_NOTIMPL); 355 } 356 357