uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated, uint8_t *nvlocked) { TPM_PERMANENT_FLAGS pflags; uint32_t result = tlcl_get_permanent_flags(&pflags); if (result == TPM_SUCCESS) { if (disable) *disable = pflags.disable; if (deactivated) *deactivated = pflags.deactivated; if (nvlocked) *nvlocked = pflags.nvLocked; VBDEBUG("TPM: flags disable=%d, deactivated=%d, nvlocked=%d\n", pflags.disable, pflags.deactivated, pflags.nvLocked); } return result; }
uint32_t factory_initialize_tpm(struct vb2_context *ctx) { TPM_PERMANENT_FLAGS pflags; uint32_t result; /* this is derived from rollback_index.h of vboot_reference. see struct * RollbackSpaceKernel for details. */ static const uint8_t secdata_kernel[] = { 0x02, 0x4C, 0x57, 0x52, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, }; VBDEBUG("TPM: factory initialization\n"); /* * Do a full test. This only happens the first time the device is * turned on in the factory, so performance is not an issue. This is * almost certainly not necessary, but it gives us more confidence * about some code paths below that are difficult to * test---specifically the ones that set lifetime flags, and are only * executed once per physical TPM. */ result = tlcl_self_test_full(); if (result != TPM_SUCCESS) return result; result = tlcl_get_permanent_flags(&pflags); if (result != TPM_SUCCESS) return result; /* * TPM may come from the factory without physical presence finalized. * Fix if necessary. */ VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n", pflags.physicalPresenceLifetimeLock); if (!pflags.physicalPresenceLifetimeLock) { VBDEBUG("TPM: Finalizing physical presence\n"); RETURN_ON_FAILURE(tlcl_finalize_physical_presence()); } /* * The TPM will not enforce the NV authorization restrictions until the * execution of a TPM_NV_DefineSpace with the handle of * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already * exist. */ VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked); if (!pflags.nvLocked) { VBDEBUG("TPM: Enabling NV locking\n"); RETURN_ON_FAILURE(tlcl_set_nv_locked()); } /* Clear TPM owner, in case the TPM is already owned for some reason. */ VBDEBUG("TPM: Clearing owner\n"); RETURN_ON_FAILURE(tpm_clear_and_reenable()); /* Define the backup space. No need to initialize it, though. */ RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX, TPM_NV_PER_PPWRITE, VB2_NVDATA_SIZE)); /* Define and initialize the kernel space */ RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX, TPM_NV_PER_PPWRITE, sizeof(secdata_kernel))); RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX, secdata_kernel, sizeof(secdata_kernel))); /* Defines and sets vb2 secdata space */ vb2api_secdata_create(ctx); RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX, TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE, VB2_SECDATA_SIZE)); RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE)); VBDEBUG("TPM: factory initialization successful\n"); return TPM_SUCCESS; }