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-2007 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_SetStatus(TSS_HTPM hTPM, /* in */ 27 TSS_FLAG statusFlag, /* in */ 28 TSS_BOOL fTpmState) /* in */ 29 { 30 TPM_AUTH auth, *pAuth; 31 TSS_RESULT result; 32 TCPA_DIGEST hashDigest; 33 TSS_HCONTEXT tspContext; 34 TSS_HPOLICY hPolicy; 35 TSS_HPOLICY hOperatorPolicy; 36 Trspi_HashCtx hashCtx; 37 UINT32 tpmVersion; 38 39 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 40 return result; 41 42 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) 43 return result; 44 45 switch (statusFlag) { 46 case TSS_TPMSTATUS_DISABLEOWNERCLEAR: 47 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 48 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear); 49 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 50 return result; 51 52 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisableOwnerClear, hPolicy, 53 FALSE, &hashDigest, &auth))) 54 return result; 55 56 if ((result = TCS_API(tspContext)->DisableOwnerClear(tspContext, &auth))) 57 return result; 58 59 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 60 result |= Trspi_Hash_UINT32(&hashCtx, result); 61 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear); 62 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 63 return result; 64 65 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) 66 return result; 67 break; 68 case TSS_TPMSTATUS_DISABLEFORCECLEAR: 69 result = TCS_API(tspContext)->DisableForceClear(tspContext); 70 break; 71 case TSS_TPMSTATUS_DISABLED: 72 case TSS_TPMSTATUS_OWNERSETDISABLE: 73 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 74 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable); 75 result |= Trspi_Hash_BOOL(&hashCtx, fTpmState); 76 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 77 return result; 78 79 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerSetDisable, hPolicy, 80 FALSE, &hashDigest, &auth))) 81 return result; 82 83 if ((result = TCS_API(tspContext)->OwnerSetDisable(tspContext, fTpmState, &auth))) 84 return result; 85 86 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 87 result |= Trspi_Hash_UINT32(&hashCtx, result); 88 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable); 89 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 90 return result; 91 92 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) 93 return result; 94 break; 95 case TSS_TPMSTATUS_PHYSICALDISABLE: 96 if (fTpmState) 97 result = TCS_API(tspContext)->PhysicalDisable(tspContext); 98 else 99 result = TCS_API(tspContext)->PhysicalEnable(tspContext); 100 break; 101 case TSS_TPMSTATUS_DEACTIVATED: 102 case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED: 103 result = TCS_API(tspContext)->PhysicalSetDeactivated(tspContext, fTpmState); 104 break; 105 case TSS_TPMSTATUS_SETTEMPDEACTIVATED: 106 if ((result = obj_context_get_tpm_version(tspContext, &tpmVersion))) 107 return result; 108 109 /* XXX Change 0,1,2 to #defines */ 110 switch (tpmVersion) { 111 case 0: 112 case 1: 113 result = TCS_API(tspContext)->SetTempDeactivated(tspContext); 114 break; 115 case 2: 116 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_OPERATOR, &hOperatorPolicy))) 117 return result; 118 119 if (hOperatorPolicy != NULL_HPOLICY) { 120 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 121 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated); 122 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 123 return result; 124 125 pAuth = &auth; 126 if ((result = secret_PerformAuth_OIAP(hTPM, 127 TPM_ORD_SetTempDeactivated, 128 hOperatorPolicy, FALSE, 129 &hashDigest, pAuth))) 130 return result; 131 } 132 else 133 pAuth = NULL; 134 135 if ((result = TCS_API(tspContext)->SetTempDeactivated2(tspContext, pAuth))) 136 return result; 137 138 if (pAuth) { 139 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 140 result |= Trspi_Hash_UINT32(&hashCtx, result); 141 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated); 142 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 143 return result; 144 145 if ((result = obj_policy_validate_auth_oiap(hOperatorPolicy, 146 &hashDigest, 147 pAuth))) 148 return result; 149 } 150 break; 151 default: 152 return TSPERR(TSS_E_INTERNAL_ERROR); 153 } 154 break; 155 case TSS_TPMSTATUS_SETOWNERINSTALL: 156 result = TCS_API(tspContext)->SetOwnerInstall(tspContext, fTpmState); 157 break; 158 case TSS_TPMSTATUS_DISABLEPUBEKREAD: 159 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 160 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead); 161 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 162 return result; 163 164 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisablePubekRead, hPolicy, 165 FALSE, &hashDigest, &auth))) 166 return result; 167 168 if ((result = TCS_API(tspContext)->DisablePubekRead(tspContext, &auth))) 169 return result; 170 171 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 172 result |= Trspi_Hash_UINT32(&hashCtx, result); 173 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead); 174 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 175 return result; 176 177 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) 178 return result; 179 break; 180 case TSS_TPMSTATUS_ALLOWMAINTENANCE: 181 /* Allow maintenance cannot be set to TRUE in the TPM */ 182 if (fTpmState) 183 return TSPERR(TSS_E_BAD_PARAMETER); 184 185 /* The path to setting allow maintenance to FALSE is through 186 * KillMaintenanceFeature */ 187 return Tspi_TPM_KillMaintenanceFeature(hTPM); 188 break; 189 #ifdef TSS_BUILD_TSS12 190 case TSS_TPMSTATUS_DISABLEPUBSRKREAD: 191 /* The logic of setting a 'disable' flag is reversed in the TPM, where setting this 192 * flag to TRUE will enable the SRK read, while FALSE disables it. So we need to 193 * flip the bool here. Sigh... */ 194 fTpmState = fTpmState ? FALSE : TRUE; 195 196 result = TSP_SetCapability(tspContext, hTPM, hPolicy, TPM_SET_PERM_FLAGS, 197 TPM_PF_READSRKPUB, fTpmState); 198 break; 199 case TSS_TPMSTATUS_RESETLOCK: 200 /* ignoring the bool here */ 201 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 202 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue); 203 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 204 return result; 205 206 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ResetLockValue, hPolicy, 207 FALSE, &hashDigest, &auth))) 208 return result; 209 210 if ((result = TCS_API(tspContext)->ResetLockValue(tspContext, &auth))) 211 return result; 212 213 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 214 result |= Trspi_Hash_UINT32(&hashCtx, result); 215 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue); 216 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 217 return result; 218 219 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) 220 return result; 221 break; 222 #endif 223 #ifndef TSS_SPEC_COMPLIANCE 224 case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK: 225 /* set the lifetime lock bit */ 226 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 227 TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK); 228 break; 229 case TSS_TPMSTATUS_PHYSPRES_HWENABLE: 230 /* HWENABLE, TRUE -> set the TPM_PHYSICAL_PRESENCE_HW_ENABLE bit 231 * HWENABLE, FALSE -> set the TPM_PHYSICAL_PRESENCE_HW_DISABLE bit */ 232 if (fTpmState) 233 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 234 TPM_PHYSICAL_PRESENCE_HW_ENABLE); 235 else 236 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 237 TPM_PHYSICAL_PRESENCE_HW_DISABLE); 238 break; 239 case TSS_TPMSTATUS_PHYSPRES_CMDENABLE: 240 /* CMDENABLE, TRUE -> set the TPM_PHYSICAL_PRESENCE_CMD_ENABLE bit 241 * CMDENABLE, FALSE -> set the TPM_PHYSICAL_PRESENCE_CMD_DISABLE bit */ 242 if (fTpmState) 243 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 244 TPM_PHYSICAL_PRESENCE_CMD_ENABLE); 245 else 246 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 247 TPM_PHYSICAL_PRESENCE_CMD_DISABLE); 248 break; 249 case TSS_TPMSTATUS_PHYSPRES_LOCK: 250 /* set the physical presence lock bit */ 251 result = TCS_API(tspContext)->PhysicalPresence(tspContext, 252 TPM_PHYSICAL_PRESENCE_LOCK); 253 break; 254 case TSS_TPMSTATUS_PHYSPRESENCE: 255 /* set the physical presence state */ 256 result = TCS_API(tspContext)->PhysicalPresence(tspContext, (fTpmState ? 257 TPM_PHYSICAL_PRESENCE_PRESENT : 258 TPM_PHYSICAL_PRESENCE_NOTPRESENT)); 259 break; 260 #endif 261 default: 262 return TSPERR(TSS_E_BAD_PARAMETER); 263 break; 264 } 265 266 return result; 267 } 268 269 TSS_RESULT 270 Tspi_TPM_GetStatus(TSS_HTPM hTPM, /* in */ 271 TSS_FLAG statusFlag, /* in */ 272 TSS_BOOL * pfTpmState) /* out */ 273 { 274 TSS_HCONTEXT tspContext; 275 TSS_RESULT result; 276 UINT32 nonVolFlags; 277 UINT32 volFlags; 278 279 if (pfTpmState == NULL) 280 return TSPERR(TSS_E_BAD_PARAMETER); 281 282 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 283 return result; 284 285 if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags))) 286 return result; 287 288 switch (statusFlag) { 289 case TSS_TPMSTATUS_DISABLEOWNERCLEAR: 290 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLEOWNERCLEAR_BIT); 291 break; 292 case TSS_TPMSTATUS_DISABLEFORCECLEAR: 293 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DISABLEFORCECLEAR_BIT); 294 break; 295 case TSS_TPMSTATUS_DISABLED: 296 case TSS_TPMSTATUS_OWNERSETDISABLE: 297 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLE_BIT); 298 break; 299 case TSS_TPMSTATUS_DEACTIVATED: 300 case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED: 301 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DEACTIVATED_BIT); 302 break; 303 case TSS_TPMSTATUS_SETTEMPDEACTIVATED: 304 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DEACTIVATED_BIT); 305 break; 306 case TSS_TPMSTATUS_SETOWNERINSTALL: 307 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OWNERSHIP_BIT); 308 break; 309 case TSS_TPMSTATUS_DISABLEPUBEKREAD: 310 *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READPUBEK_BIT); 311 break; 312 case TSS_TPMSTATUS_ALLOWMAINTENANCE: 313 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ALLOWMAINTENANCE_BIT); 314 break; 315 case TSS_TPMSTATUS_MAINTENANCEUSED: 316 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_MAINTENANCEDONE_BIT); 317 break; 318 case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK: 319 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCELIFETIMELOCK_BIT); 320 break; 321 case TSS_TPMSTATUS_PHYSPRES_HWENABLE: 322 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCEHWENABLE_BIT); 323 break; 324 case TSS_TPMSTATUS_PHYSPRES_CMDENABLE: 325 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCECMDENABLE_BIT); 326 break; 327 case TSS_TPMSTATUS_CEKP_USED: 328 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_CEKPUSED_BIT); 329 break; 330 case TSS_TPMSTATUS_PHYSPRESENCE: 331 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCE_BIT); 332 break; 333 case TSS_TPMSTATUS_PHYSPRES_LOCK: 334 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCELOCK_BIT); 335 break; 336 case TSS_TPMSTATUS_TPMPOST: 337 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOST_BIT); 338 break; 339 case TSS_TPMSTATUS_TPMPOSTLOCK: 340 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOSTLOCK_BIT); 341 break; 342 case TSS_TPMSTATUS_FIPS: 343 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_FIPS_BIT); 344 break; 345 case TSS_TPMSTATUS_ENABLE_REVOKEEK: 346 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ENABLEREVOKEEK_BIT); 347 break; 348 case TSS_TPMSTATUS_TPM_ESTABLISHED: 349 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_RESETESTABLISHMENTBIT_BIT); 350 break; 351 case TSS_TPMSTATUS_NV_LOCK: 352 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_NV_LOCKED_BIT); 353 break; 354 case TSS_TPMSTATUS_POSTINITIALISE: 355 /* There is no way to query the TPM for this flag. */ 356 result = TSPERR(TSS_E_NOTIMPL); 357 break; 358 #ifdef TSS_BUILD_TSS12 359 case TSS_TPMSTATUS_DISABLEPUBSRKREAD: 360 *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READSRKPUB_BIT); 361 break; 362 case TSS_TPMSTATUS_OPERATORINSTALLED: 363 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OPERATOR_BIT); 364 break; 365 #endif 366 default: 367 return TSPERR(TSS_E_BAD_PARAMETER); 368 break; 369 } 370 371 return TSS_SUCCESS; 372 } 373