예제 #1
0
파일: vboot.c 프로젝트: B-Rich/coreboot
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
}
예제 #2
0
파일: tlcl_tests.c 프로젝트: latelee/vboot
/**
 * Test assorted tlcl functions
 */
static void TlclTest(void)
{
	uint8_t buf[32], buf2[32];

	ResetMocks();
	TEST_EQ(TlclLibInit(), VBERROR_SUCCESS, "Init");

	ResetMocks();
	mock_retval = VBERROR_SIMULATED;
	TEST_EQ(TlclLibInit(), mock_retval, "Init bad");

	ResetMocks();
	TEST_EQ(TlclLibClose(), VBERROR_SUCCESS, "Close");

	ResetMocks();
	mock_retval = VBERROR_SIMULATED;
	TEST_EQ(TlclLibClose(), mock_retval, "Close bad");

	ResetMocks();
	ToTpmUint32(buf + 2, 123);
	TEST_EQ(TlclPacketSize(buf), 123, "TlclPacketSize");

	ResetMocks();
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 0, "SendReceive");
	TEST_PTR_EQ(calls[0].req, buf, "SendReceive req ptr");
	TEST_EQ(calls[0].req_size, 10, "SendReceive size");

	ResetMocks();
	calls[0].retval = VBERROR_SIMULATED;
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), VBERROR_SIMULATED,
		"SendReceive fail");

	ResetMocks();
	SetResponse(0, 123, 10);
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 123,
		"SendReceive error response");

	// TODO: continue self test (if needed or doing)
	// TODO: then retry doing self test

}
예제 #3
0
/****************************************************************************
 *
 * Open an OSAP session
 * Object Specific Authorization Protocol, returned handle must manipulate
 * a single object given as a parameter (can introduce AuthData).
 *                                                                          *
 ****************************************************************************/
uint32_t TSS_OSAPopen(struct tss_osapsess *sess, const uint8_t *key, uint16_t etype,
		      uint32_t evalue)
{
	struct s_tpm_osap_open_cmd cmd;
	uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
	uint32_t nonceSize;
	uint32_t result;

	debug("TPM: TSS_OSAPopen\n");
	/* check input arguments */
	if (key == NULL || sess == NULL) {
		return TPM_E_NULL_ARG;
	}

	TlclGetRandom(sess->ononceOSAP, TPM_NONCE_SIZE, &nonceSize);

	memcpy(&cmd, &tpm_osap_open_cmd, sizeof(cmd));
	ToTpmUint16(cmd.buffer + tpm_osap_open_cmd.type, etype);
	ToTpmUint32(cmd.buffer + tpm_osap_open_cmd.value, evalue);
	memcpy(cmd.buffer + tpm_osap_open_cmd.nonce, sess->ononceOSAP, TPM_NONCE_SIZE);

	result = TlclSendReceive(cmd.buffer, response, sizeof(response));

	if (result == TPM_SUCCESS) {
		FromTpmUint32(response + kTpmResponseHeaderLength, &(sess->handle));
		memcpy(sess->enonce, response + kTpmResponseHeaderLength + sizeof(uint32_t), TPM_NONCE_SIZE);
		memcpy(sess->enonceOSAP, response + kTpmResponseHeaderLength + sizeof(uint32_t) + TPM_NONCE_SIZE, TPM_NONCE_SIZE);

		debug("TPM: TSS_OSAPopen success, calculating HMAC\n");
		/*DATA_DEBUG("key", key, TPM_HASH_SIZE);
		DATA_DEBUG("enonceOSAP", sess->enonceOSAP, TPM_NONCE_SIZE);
		DATA_DEBUG("ononceOSAP", sess->ononceOSAP, TPM_NONCE_SIZE);*/

		/* not implemented */
		SHA1_CTX hmac;
		hmac_starts(&hmac, key, TPM_HASH_SIZE);
		hmac_update(&hmac, sess->enonceOSAP, TPM_NONCE_SIZE);
		hmac_update(&hmac, sess->ononceOSAP, TPM_NONCE_SIZE);
		hmac_finish(&hmac, key, TPM_HASH_SIZE, sess->ssecret);
	}

	return result;
}
예제 #4
0
/****************************************************************************
 *
 * Open an OIAP session
 * Object Independent Authorization Protocol, will not work on commands
 * that introduce new AuthData to the TPM
 *
 ****************************************************************************/
uint32_t TSS_OIAPopen(uint32_t *handle, uint8_t *enonce)
{
	struct s_tpm_oiap_open_cmd cmd;
	uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
	uint32_t result;

	debug("TPM: TSS_OIAPopen\n");
	/* check input arguments */
	if (handle == NULL || enonce == NULL) {
		return TPM_E_NULL_ARG;
	}

	memcpy(&cmd, &tpm_oiap_open_cmd, sizeof(cmd));
	result = TlclSendReceive(cmd.buffer, response, sizeof(response));

	if (result == TPM_SUCCESS) {
		FromTpmUint32(response + kTpmResponseHeaderLength, handle);
		memcpy(enonce, response + kTpmResponseHeaderLength + sizeof(uint32_t), TPM_NONCE_SIZE);
	}

	return result;
}
예제 #5
0
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();
	}
}