| Index: firmware/lib/tpm_lite/tlcl.c
|
| diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4ca8b87e48f0677991dca15ff675b6123be24777
|
| --- /dev/null
|
| +++ b/firmware/lib/tpm_lite/tlcl.c
|
| @@ -0,0 +1,241 @@
|
| +/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +/* A lightweight TPM command library.
|
| + *
|
| + * The general idea is that TPM commands are array of bytes whose
|
| + * fields are mostly compile-time constant. The goal is to build much
|
| + * of the commands at compile time (or build time) and change some of
|
| + * the fields at run time as needed. The code in
|
| + * utility/tlcl_generator.c builds structures containing the commands,
|
| + * as well as the offsets of the fields that need to be set at run
|
| + * time.
|
| + */
|
| +
|
| +#include "sysincludes.h"
|
| +#include "tlcl.h"
|
| +#include "tlcl_internal.h"
|
| +#include "tlcl_structures.h"
|
| +#include "tss_constants.h"
|
| +#include "utility.h"
|
| +
|
| +
|
| +/* Sets the size field of a TPM command. */
|
| +static INLINE void SetTpmCommandSize(uint8_t* buffer, uint32_t size) {
|
| + ToTpmUint32(buffer + sizeof(uint16_t), size);
|
| +}
|
| +
|
| +/* Gets the size field of a TPM command. */
|
| +POSSIBLY_UNUSED static INLINE int TpmCommandSize(const uint8_t* buffer) {
|
| + uint32_t size;
|
| + FromTpmUint32(buffer + sizeof(uint16_t), &size);
|
| + return (int) size;
|
| +}
|
| +
|
| +/* Gets the code field of a TPM command. */
|
| +static INLINE int TpmCommandCode(const uint8_t* buffer) {
|
| + uint32_t code;
|
| + FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
|
| + return code;
|
| +}
|
| +
|
| +/* Gets the return code field of a TPM result. */
|
| +static INLINE int TpmReturnCode(const uint8_t* buffer) {
|
| + return TpmCommandCode(buffer);
|
| +}
|
| +
|
| +/* Checks for errors in a TPM response. */
|
| +static void CheckResult(uint8_t* request, uint8_t* response, int warn_only) {
|
| + int command = TpmCommandCode(request);
|
| + int result = TpmReturnCode(response);
|
| + if (result != TPM_SUCCESS) {
|
| + if (warn_only)
|
| + VBDEBUG(("TPM command %d 0x%x failed: %d 0x%x\n",
|
| + command, command, result, result));
|
| + else
|
| + error("TPM command %d 0x%x failed: %d 0x%x\n",
|
| + command, command, result, result);
|
| + }
|
| +}
|
| +
|
| +/* Sends a TPM command and gets a response. */
|
| +static void TlclSendReceive(uint8_t* request, uint8_t* response,
|
| + int max_length) {
|
| + TlclStubSendReceive(request, TpmCommandSize(request),
|
| + response, max_length);
|
| +}
|
| +
|
| +
|
| +/* Sends a command and returns the error code. */
|
| +static uint32_t Send(uint8_t* command) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + TlclSendReceive(command, response, sizeof(response));
|
| + return TpmReturnCode(response);
|
| +}
|
| +
|
| +/* Exported functions. */
|
| +
|
| +void TlclLibInit(void) {
|
| + TlclStubInit();
|
| +}
|
| +
|
| +uint32_t TlclStartup(void) {
|
| + return Send(tpm_startup_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclSelftestfull(void) {
|
| + return Send(tpm_selftestfull_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclContinueSelfTest(void) {
|
| + return Send(tpm_continueselftest_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
|
| + ToTpmUint32(tpm_nv_definespace_cmd.index, index);
|
| + ToTpmUint32(tpm_nv_definespace_cmd.perm, perm);
|
| + ToTpmUint32(tpm_nv_definespace_cmd.size, size);
|
| + return Send(tpm_nv_definespace_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclWrite(uint32_t index, uint8_t* data, uint32_t length) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + const int total_length =
|
| + kTpmRequestHeaderLength + kWriteInfoLength + length;
|
| +
|
| + assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
|
| + SetTpmCommandSize(tpm_nv_write_cmd.buffer, total_length);
|
| +
|
| + ToTpmUint32(tpm_nv_write_cmd.index, index);
|
| + ToTpmUint32(tpm_nv_write_cmd.length, length);
|
| + Memcpy(tpm_nv_write_cmd.data, data, length);
|
| +
|
| + TlclSendReceive(tpm_nv_write_cmd.buffer, response, sizeof(response));
|
| + CheckResult(tpm_nv_write_cmd.buffer, response, 1);
|
| +
|
| + return TpmReturnCode(response);
|
| +}
|
| +
|
| +uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + uint32_t result_length;
|
| + uint32_t result;
|
| +
|
| + ToTpmUint32(tpm_nv_read_cmd.index, index);
|
| + ToTpmUint32(tpm_nv_read_cmd.length, length);
|
| +
|
| + TlclSendReceive(tpm_nv_read_cmd.buffer, response, sizeof(response));
|
| + result = TpmReturnCode(response);
|
| + if (result == TPM_SUCCESS && length > 0) {
|
| + uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
|
| + FromTpmUint32(nv_read_cursor, &result_length);
|
| + nv_read_cursor += sizeof(uint32_t);
|
| + Memcpy(data, nv_read_cursor, result_length);
|
| + }
|
| +
|
| + return result;
|
| +}
|
| +
|
| +uint32_t TlclWriteLock(uint32_t index) {
|
| + return TlclWrite(index, NULL, 0);
|
| +}
|
| +
|
| +uint32_t TlclReadLock(uint32_t index) {
|
| + return TlclRead(index, NULL, 0);
|
| +}
|
| +
|
| +uint32_t TlclAssertPhysicalPresence(void) {
|
| + return Send(tpm_ppassert_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclAssertPhysicalPresenceResult(void) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
|
| + return TpmReturnCode(response);
|
| +}
|
| +
|
| +uint32_t TlclLockPhysicalPresence(void) {
|
| + return Send(tpm_pplock_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclSetNvLocked(void) {
|
| + return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0);
|
| +}
|
| +
|
| +int TlclIsOwned(void) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
|
| + uint32_t result;
|
| + TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response));
|
| + result = TpmReturnCode(response);
|
| + return (result != TPM_SUCCESS);
|
| +}
|
| +
|
| +uint32_t TlclForceClear(void) {
|
| + return Send(tpm_forceclear_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclSetEnable(void) {
|
| + return Send(tpm_physicalenable_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclClearEnable(void) {
|
| + return Send(tpm_physicaldisable_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclSetDeactivated(uint8_t flag) {
|
| + *((uint8_t*)tpm_physicalsetdeactivated_cmd.deactivated) = flag;
|
| + return Send(tpm_physicalsetdeactivated_cmd.buffer);
|
| +}
|
| +
|
| +uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + TPM_PERMANENT_FLAGS* pflags;
|
| + uint32_t result;
|
| + uint32_t size;
|
| +
|
| + TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response));
|
| + result = TpmReturnCode(response);
|
| + if (result != TPM_SUCCESS) {
|
| + return result;
|
| + }
|
| + FromTpmUint32(response + kTpmResponseHeaderLength, &size);
|
| + assert(size == sizeof(TPM_PERMANENT_FLAGS));
|
| + pflags =
|
| + (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size));
|
| + *disable = pflags->disable;
|
| + *deactivated = pflags->deactivated;
|
| + return result;
|
| +}
|
| +
|
| +uint32_t TlclSetGlobalLock(void) {
|
| + uint32_t x;
|
| + return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0);
|
| +}
|
| +
|
| +uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest) {
|
| + uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
|
| + ToTpmUint32(tpm_extend_cmd.pcrNum, pcr_num);
|
| + Memcpy(tpm_extend_cmd.inDigest, in_digest, kPcrDigestLength);
|
| + TlclSendReceive(tpm_extend_cmd.buffer, response, sizeof(response));
|
| + Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength);
|
| + return TpmReturnCode(response);
|
| +}
|
| +
|
| +uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) {
|
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
| + uint8_t* nvdata;
|
| + uint32_t result;
|
| + uint32_t size;
|
| +
|
| + ToTpmUint32(tpm_getpermissions_cmd.index, index);
|
| + TlclSendReceive(tpm_getpermissions_cmd.buffer, response, sizeof(response));
|
| + result = TpmReturnCode(response);
|
| + if (result != TPM_SUCCESS) {
|
| + return result;
|
| + }
|
| + nvdata = response + kTpmResponseHeaderLength + sizeof(size);
|
| + FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
|
| + return result;
|
| +}
|
|
|