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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}