VbError_t VbExTpmSendReceive(const uint8_t* request, uint32_t request_length, uint8_t* response, uint32_t* response_length) { if (tis_sendrecv(request, request_length, response, response_length)) return TPM_E_IOERROR; return TPM_SUCCESS; }
static void *tpm_process_command(TPM_CC command, void *command_body) { ssize_t out_size; size_t in_size; /* Command/response buffer. */ static uint8_t cr_buffer[TPM_BUFFER_SIZE] CAR_GLOBAL; uint8_t *cr_buffer_ptr = car_get_var_ptr(cr_buffer); out_size = tpm_marshal_command(command, command_body, cr_buffer_ptr, sizeof(cr_buffer)); if (out_size < 0) { printk(BIOS_ERR, "command %#x, cr size %zd\n", command, out_size); return NULL; } in_size = sizeof(cr_buffer); if (tis_sendrecv(cr_buffer_ptr, out_size, cr_buffer_ptr, &in_size)) { printk(BIOS_ERR, "tpm transaction failed\n"); return NULL; } return tpm_unmarshal_response(command, cr_buffer_ptr, in_size); }
/* * tpm_write() expects a variable number of parameters: the internal address * followed by data to write, byte by byte. * * Returns 0 on success or -1 on errors (wrong arguments or TPM failure). */ static int tpm_process(int argc, char * const argv[], cmd_tbl_t *cmdtp) { u8 tpm_buffer[MAX_TRANSACTION_SIZE]; u32 write_size, read_size; char *p; int rv = -1; for (write_size = 0; write_size < argc; write_size++) { u32 datum = simple_strtoul(argv[write_size], &p, 0); if (*p || (datum > 0xff)) { printf("\n%s: bad data value\n\n", argv[write_size]); cmd_usage(cmdtp); return rv; } tpm_buffer[write_size] = (u8)datum; } read_size = sizeof(tpm_buffer); if (!tis_sendrecv(tpm_buffer, write_size, tpm_buffer, &read_size)) { int i; puts("Got TPM response:\n"); for (i = 0; i < read_size; i++) printf(" %2.2x", tpm_buffer[i]); puts("\n"); rv = 0; } else { puts("tpm command failed\n"); } return rv; }
static int tpm_send_receive(const uint8_t *request, uint32_t request_length, uint8_t *response, uint32_t *response_length) { size_t len = *response_length; if (tis_sendrecv(request, request_length, response, &len)) return VB2_ERROR_UNKNOWN; /* check 64->32bit overflow and (re)check response buffer overflow */ if (len > *response_length) return VB2_ERROR_UNKNOWN; *response_length = len; return VB2_SUCCESS; }
/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or * DOING_SELFTEST errors are returned. */ static u32 TlclSendReceiveNoRetry(const u8 * request, u8 * response, int max_length) { size_t response_length = max_length; u32 result; #ifdef EXTRA_LOGGING printk(BIOS_DEBUG, "TPM: command: %x%x %x%x%x%x %x%x%x%x\n", request[0], request[1], request[2], request[3], request[4], request[5], request[6], request[7], request[8], request[9]); #endif result = TPM_SUCCESS; if (tis_sendrecv (request, TpmCommandSize(request), response, &response_length)) result = TPM_E_IOERROR; if (0 != result) { /* Communication with TPM failed, so response is garbage */ printk(BIOS_DEBUG, "TPM: command 0x%x send/receive failed: 0x%x\n", TpmCommandCode(request), result); return TPM_E_COMMUNICATION_ERROR; } /* Otherwise, use the result code from the response */ result = TpmReturnCode(response); /* TODO: add paranoia about returned response_length vs. max_length * (and possibly expected length from the response header). See * crosbug.com/17017 */ #ifdef EXTRA_LOGGING printk(BIOS_DEBUG, "TPM: response: %x%x %x%x%x%x %x%x%x%x\n", response[0], response[1], response[2], response[3], response[4], response[5], response[6], response[7], response[8], response[9]); #endif printk(BIOS_DEBUG, "TPM: command 0x%x returned 0x%x\n", TpmCommandCode(request), result); return result; }
static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void *command; uint8_t response[1024]; size_t count, response_length = sizeof(response); uint32_t rc; command = parse_byte_string(argv[1], NULL, &count); if (!command) { printf("Couldn't parse byte string %s\n", argv[1]); return CMD_RET_FAILURE; } rc = tis_sendrecv(command, count, response, &response_length); free(command); if (!rc) { puts("tpm response:\n"); print_byte_string(response, response_length); } return convert_return_code(rc); }
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; }