int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len) { uint8_t buf[TPM_BUFSIZE]; if (!opened && tis_open()) return -1; if (sizeof(buf) < sbuf_size) return -1; memcpy(buf, sendbuf, sbuf_size); int len = tpm_transmit(buf, sbuf_size); if (len < 10) { *rbuf_len = 0; return -1; } if (len > *rbuf_len) { *rbuf_len = len; return -1; } memcpy(recvbuf, buf, len); *rbuf_len = len; return 0; }
static int do_tpm_many(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int repeat_count) { int rv = 0; if (argc < 7 && repeat_count == 0) { puts("command should be at least six bytes in size\n"); return -1; } if (repeat_count > 0) { rv = tpm_process_stress(repeat_count); return rv; } if (tis_init()) { puts("tis_init() failed!\n"); return -1; } if (tis_open()) { puts("tis_open() failed!\n"); return -1; } rv = tpm_process(argc - 1, argv + 1, cmdtp); if (tis_close()) { puts("tis_close() failed!\n"); rv = -1; } return rv; }
uint32_t tlcl_lib_init(void) { if (tis_init()) return VB2_ERROR_UNKNOWN; if (tis_open()) return VB2_ERROR_UNKNOWN; return VB2_SUCCESS; }
static void init_vboot(int bootmode) { u32 result; u8 response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; #ifdef UBOOT_DOES_TPM_STARTUP /* Doing TPM startup when we're not coming in on the S3 resume path * saves us roughly 20ms in boot time only. This does not seem to * be worth an API change to vboot_reference-firmware right now, so * let's keep the code around, but just bail out early: */ if (bootmode != 2) return; #endif printk(BIOS_DEBUG, "Verified boot TPM initialization.\n"); printk(BIOS_SPEW, "TPM: Init\n"); if (tis_init()) return; printk(BIOS_SPEW, "TPM: Open\n"); if (tis_open()) return; if (bootmode == 2) { /* S3 Resume */ printk(BIOS_SPEW, "TPM: Resume\n"); result = TlclSendReceive(tpm_resume_cmd.buffer, response, sizeof(response)); if (result == TPM_E_INVALID_POSTINIT) { /* We're on a platform where the TPM maintains power * in S3, so it's already initialized. */ printk(BIOS_DEBUG, "TPM: Already initialized.\n"); return; } } else { printk(BIOS_SPEW, "TPM: Startup\n"); result = TlclSendReceive(tpm_startup_cmd.buffer, response, sizeof(response)); } if (result == TPM_SUCCESS) { printk(BIOS_SPEW, "TPM: OK.\n"); return; } #if !MOCK_TPM printk(BIOS_ERR, "TPM: Error code 0x%x. Hard reset!\n", result); hard_reset(); #endif }
uint32_t tlcl_lib_init(void) { /* * This function is called directly by vboot, uses vboot return * types. */ if (tis_init()) return VB2_ERROR_UNKNOWN; if (tis_open()) return VB2_ERROR_UNKNOWN; return VB2_SUCCESS; }
static int tpm_process_stress(int repeat_count) { int i; int rv = 0; u8 request[] = {0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x9}; u8 response[MAX_TRANSACTION_SIZE]; u32 rlength = MAX_TRANSACTION_SIZE; CHECK(tis_init()); for (i = 0; i < repeat_count; i++) { CHECK(tis_open()); rv = tis_sendrecv(request, sizeof(request), response, &rlength); if (rv) { printf("tpm test failed at step %d with 0x%x\n", i, rv); CHECK(tis_close()); break; } CHECK(tis_close()); if ((response[6] || response[7] || response[8] || response[9]) && response[9] != 0x26) { /* Ignore postinit errors */ printf("tpm command failed at step %d\n" "tpm error code: %02x%02x%02x%02x\n", i, response[6], response[7], response[8], response[9]); rv = -1; break; } } return rv; }
void init_tpm(int s3resume) { u32 result; u8 response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; if (CONFIG_TPM_DEACTIVATE) { printk(BIOS_SPEW, "TPM: Deactivate\n"); result = TlclSendReceive(tpm_deactivate_cmd.buffer, response, sizeof(response)); if (result == TPM_SUCCESS) { printk(BIOS_SPEW, "TPM: OK.\n"); return; } printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result); return; } /* Doing TPM startup when we're not coming in on the S3 resume path * saves us roughly 20ms in boot time only. This does not seem to * be worth an API change to vboot_reference-firmware right now, so * let's keep the code around, but just bail out early: */ if (s3resume ? CONFIG_NO_TPM_RESUME : CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT) return; printk(BIOS_DEBUG, "TPM initialization.\n"); printk(BIOS_SPEW, "TPM: Init\n"); if (tis_init()) return; printk(BIOS_SPEW, "TPM: Open\n"); if (tis_open()) return; if (s3resume) { /* S3 Resume */ printk(BIOS_SPEW, "TPM: Resume\n"); result = TlclSendReceive(tpm_resume_cmd.buffer, response, sizeof(response)); if (result == TPM_E_INVALID_POSTINIT) { /* We're on a platform where the TPM maintains power * in S3, so it's already initialized. */ printk(BIOS_DEBUG, "TPM: Already initialized.\n"); return; } } else { printk(BIOS_SPEW, "TPM: Startup\n"); result = TlclSendReceive(tpm_startup_cmd.buffer, response, sizeof(response)); } if (result == TPM_SUCCESS) { printk(BIOS_SPEW, "TPM: OK.\n"); return; } printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result); if (CONFIG_TPM_INIT_FAILURE_IS_FATAL) { printk(BIOS_ERR, "Hard reset!\n"); post_code(POST_TPM_FAILURE); if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART)) cbmem_dump_console(); hard_reset(); } }
VbError_t VbExTpmOpen(void) { if (tis_open()) return TPM_E_IOERROR; return TPM_SUCCESS; }