diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2014-07-02 08:37:23 -0700 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2015-01-27 01:43:57 +0100 |
commit | efb5cde87fb0afef7a0e3c1c6bf3a7cc9cb8dbeb (patch) | |
tree | beb9af9b1610e26fdc7f606643f36d0c196e052a /src/lib | |
parent | 3c21e4687bae7169ee8c3b07cad095cf35106ecb (diff) |
vboot2: copy tlcl from vboot_reference as a preparation for vboot2 integration
vboot2 abtracts tpm storage as some 'secure' space. Thus, it's firmware's
responsibility to handle vboot specific operations with tpm. This CL just copies
related files from vboot_reference so that we can see how code was modified in
the next CL. Note rollback_index.c/h were renamed to antirollback.c/h.
TEST=none
BUG=none
Branch=none
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Change-Id: I1792a622058f70a8fcd3c4037547539ad2870420
Original-Reviewed-on: https://chromium-review.googlesource.com/206462
Original-Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org>
Original-Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Reviewed-by: Randall Spangler <rspangler@chromium.org>
(cherry picked from commit 2ae188b29242bf09c5e79e31f98b330a30bf7b93)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I5fa5a636003e8472127194e961fea4309489b1d9
Reviewed-on: http://review.coreboot.org/8164
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/tlcl.c | 466 | ||||
-rw-r--r-- | src/lib/tlcl_internal.h | 61 | ||||
-rw-r--r-- | src/lib/tlcl_structures.h | 138 | ||||
-rw-r--r-- | src/lib/tpm_error_messages.h | 250 |
4 files changed, 915 insertions, 0 deletions
diff --git a/src/lib/tlcl.c b/src/lib/tlcl.c new file mode 100644 index 0000000000..bf2d27f99c --- /dev/null +++ b/src/lib/tlcl.c @@ -0,0 +1,466 @@ +/* Copyright (c) 2012 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 "utility.h" +#include "vboot_api.h" + +#ifdef FOR_TEST +/* Allow unit testing implementation of TlclSendReceive() */ +#undef CHROMEOS_ENVIRONMENT +#endif + +/* 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. */ +__attribute__((unused)) +static inline int TpmCommandSize(const uint8_t* buffer) { + uint32_t size; + FromTpmUint32(buffer + sizeof(uint16_t), &size); + return (int) size; +} + +/* Gets the size field of a TPM request or response. */ +int TlclPacketSize(const uint8_t* packet) { + return TpmCommandSize(packet); +} + +/* 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); +} + +/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or + * DOING_SELFTEST errors are returned. + */ +static uint32_t TlclSendReceiveNoRetry(const uint8_t* request, + uint8_t* response, int max_length) { + + uint32_t response_length = max_length; + uint32_t result; + +#ifdef EXTRA_LOGGING + VBDEBUG(("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 = VbExTpmSendReceive(request, TpmCommandSize(request), + response, &response_length); + if (0 != result) { + /* Communication with TPM failed, so response is garbage */ + VBDEBUG(("TPM: command 0x%x send/receive failed: 0x%x\n", + TpmCommandCode(request), result)); + return result; + } + /* 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 + VBDEBUG(("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 + + VBDEBUG(("TPM: command 0x%x returned 0x%x\n", + TpmCommandCode(request), result)); + + return result; +} + + +/* Sends a TPM command and gets a response. Returns 0 if success or the TPM + * error code if error. In the firmware, waits for the self test to complete + * if needed. In the host, reports the first error without retries. */ +uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, + int max_length) { + uint32_t result = TlclSendReceiveNoRetry(request, response, max_length); + /* When compiling for the firmware, hide command failures due to the self + * test not having run or completed. */ +#ifndef CHROMEOS_ENVIRONMENT + /* If the command fails because the self test has not completed, try it + * again after attempting to ensure that the self test has completed. */ + if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) { + result = TlclContinueSelfTest(); + if (result != TPM_SUCCESS) { + return result; + } +#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) + /* Retry only once */ + result = TlclSendReceiveNoRetry(request, response, max_length); +#else + /* This needs serious testing. The TPM specification says: "iii. The + * caller MUST wait for the actions of TPM_ContinueSelfTest to complete + * before reissuing the command C1." But, if ContinueSelfTest is + * non-blocking, how do we know that the actions have completed other than + * trying again? */ + do { + result = TlclSendReceiveNoRetry(request, response, max_length); + } while (result == TPM_E_DOING_SELFTEST); +#endif + } +#endif /* ! defined(CHROMEOS_ENVIRONMENT) */ + return result; +} + +/* Sends a command and returns the error code. */ +static uint32_t Send(const uint8_t* command) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + return TlclSendReceive(command, response, sizeof(response)); +} + +/* Exported functions. */ + +uint32_t TlclLibInit(void) { + return VbExTpmInit(); +} + +uint32_t TlclLibClose(void) { + return VbExTpmClose(); +} + +uint32_t TlclStartup(void) { + VBDEBUG(("TPM: Startup\n")); + return Send(tpm_startup_cmd.buffer); +} + +uint32_t TlclSaveState(void) { + VBDEBUG(("TPM: SaveState\n")); + return Send(tpm_savestate_cmd.buffer); +} + +uint32_t TlclResume(void) { + VBDEBUG(("TPM: Resume\n")); + return Send(tpm_resume_cmd.buffer); +} + +uint32_t TlclSelfTestFull(void) { + VBDEBUG(("TPM: Self test full\n")); + return Send(tpm_selftestfull_cmd.buffer); +} + +uint32_t TlclContinueSelfTest(void) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + VBDEBUG(("TPM: Continue self test\n")); + /* Call the No Retry version of SendReceive to avoid recursion. */ + return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer, + response, sizeof(response)); +} + +uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { + struct s_tpm_nv_definespace_cmd cmd; + VBDEBUG(("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size)); + Memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.index, index); + ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm); + ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.size, size); + return Send(cmd.buffer); +} + +uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length) { + struct s_tpm_nv_write_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + const int total_length = + kTpmRequestHeaderLength + kWriteInfoLength + length; + + VBDEBUG(("TPM: TlclWrite(0x%x, %d)\n", index, length)); + Memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd)); + VbAssert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE); + SetTpmCommandSize(cmd.buffer, total_length); + + ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index); + ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length); + Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length); + + return TlclSendReceive(cmd.buffer, response, sizeof(response)); +} + +uint32_t TlclRead(uint32_t index, void* data, uint32_t length) { + struct s_tpm_nv_read_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t result_length; + uint32_t result; + + VBDEBUG(("TPM: TlclRead(0x%x, %d)\n", index, length)); + Memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index); + ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length); + + result = TlclSendReceive(cmd.buffer, response, sizeof(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 TlclPCRRead(uint32_t index, void* data, uint32_t length) { + struct s_tpm_pcr_read_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t result; + + VBDEBUG(("TPM: TlclPCRRead(0x%x, %d)\n", index, length)); + if (length < kPcrDigestLength) { + return TPM_E_IOERROR; + } + Memcpy(&cmd, &tpm_pcr_read_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_pcr_read_cmd.pcrNum, index); + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result == TPM_SUCCESS) { + uint8_t* pcr_read_cursor = response + kTpmResponseHeaderLength; + Memcpy(data, pcr_read_cursor, kPcrDigestLength); + } + + return result; +} + +uint32_t TlclWriteLock(uint32_t index) { + VBDEBUG(("TPM: Write lock 0x%x\n", index)); + return TlclWrite(index, NULL, 0); +} + +uint32_t TlclReadLock(uint32_t index) { + VBDEBUG(("TPM: Read lock 0x%x\n", index)); + return TlclRead(index, NULL, 0); +} + +uint32_t TlclAssertPhysicalPresence(void) { + VBDEBUG(("TPM: Asserting physical presence\n")); + return Send(tpm_ppassert_cmd.buffer); +} + +uint32_t TlclPhysicalPresenceCMDEnable(void) { + VBDEBUG(("TPM: Enable the physical presence command\n")); + return Send(tpm_ppenable_cmd.buffer); +} + +uint32_t TlclFinalizePhysicalPresence(void) { + VBDEBUG(("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n")); + return Send(tpm_finalizepp_cmd.buffer); +} + +uint32_t TlclAssertPhysicalPresenceResult(void) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); +} + +uint32_t TlclLockPhysicalPresence(void) { + VBDEBUG(("TPM: Lock physical presence\n")); + return Send(tpm_pplock_cmd.buffer); +} + +uint32_t TlclSetNvLocked(void) { + VBDEBUG(("TPM: Set NV locked\n")); + 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; + result = TlclSendReceive(tpm_readpubek_cmd.buffer, + response, sizeof(response)); + return (result != TPM_SUCCESS); +} + +uint32_t TlclForceClear(void) { + VBDEBUG(("TPM: Force clear\n")); + return Send(tpm_forceclear_cmd.buffer); +} + +uint32_t TlclSetEnable(void) { + VBDEBUG(("TPM: Enabling TPM\n")); + return Send(tpm_physicalenable_cmd.buffer); +} + +uint32_t TlclClearEnable(void) { + VBDEBUG(("TPM: Disabling TPM\n")); + return Send(tpm_physicaldisable_cmd.buffer); +} + +uint32_t TlclSetDeactivated(uint8_t flag) { + struct s_tpm_physicalsetdeactivated_cmd cmd; + VBDEBUG(("TPM: SetDeactivated(%d)\n", flag)); + Memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd)); + *(cmd.buffer + cmd.deactivated) = flag; + return Send(cmd.buffer); +} + +uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t size; + uint32_t result = + TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + FromTpmUint32(response + kTpmResponseHeaderLength, &size); + /* TODO(crbug.com/379255): This fails. Find out why. + * VbAssert(size == sizeof(TPM_PERMANENT_FLAGS)); + */ + Memcpy(pflags, + response + kTpmResponseHeaderLength + sizeof(size), + sizeof(TPM_PERMANENT_FLAGS)); + return result; +} + +uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t size; + uint32_t result = + TlclSendReceive(tpm_getstclearflags_cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + FromTpmUint32(response + kTpmResponseHeaderLength, &size); + /* Ugly assertion, but the struct is padded up by one byte. */ + /* TODO(crbug.com/379255): This fails. Find out why. + * VbAssert(size == 7 && sizeof(TPM_STCLEAR_FLAGS) - 1 == 7); + */ + Memcpy(vflags, + response + kTpmResponseHeaderLength + sizeof(size), + sizeof(TPM_STCLEAR_FLAGS)); + return result; +} + +uint32_t TlclGetFlags(uint8_t* disable, + uint8_t* deactivated, + uint8_t *nvlocked) { + TPM_PERMANENT_FLAGS pflags; + uint32_t result = TlclGetPermanentFlags(&pflags); + if (result == TPM_SUCCESS) { + if (disable) + *disable = pflags.disable; + if (deactivated) + *deactivated = pflags.deactivated; + if (nvlocked) + *nvlocked = pflags.nvLocked; + VBDEBUG(("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n", + pflags.disable, pflags.deactivated, pflags.nvLocked)); + } + return result; +} + +uint32_t TlclSetGlobalLock(void) { + uint32_t x; + VBDEBUG(("TPM: Set global lock\n")); + return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); +} + +uint32_t TlclExtend(int pcr_num, const uint8_t* in_digest, + uint8_t* out_digest) { + struct s_tpm_extend_cmd cmd; + uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength]; + uint32_t result; + + Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num); + Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength); + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + + Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength); + return result; +} + +uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { + struct s_tpm_getpermissions_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint8_t* nvdata; + uint32_t result; + uint32_t size; + + Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + + nvdata = response + kTpmResponseHeaderLength + sizeof(size); + FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); + return result; +} + +uint32_t TlclGetOwnership(uint8_t* owned) { + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t size; + uint32_t result = + TlclSendReceive(tpm_getownership_cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + FromTpmUint32(response + kTpmResponseHeaderLength, &size); + /* TODO(crbug.com/379255): This fails. Find out why. + * VbAssert(size == sizeof(*owned)); + */ + Memcpy(owned, + response + kTpmResponseHeaderLength + sizeof(size), + sizeof(*owned)); + return result; +} + +uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) { + struct s_tpm_get_random_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t result; + + VBDEBUG(("TPM: TlclGetRandom(%d)\n", length)); + Memcpy(&cmd, &tpm_get_random_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_get_random_cmd.bytesRequested, length); + /* There must be room in the response buffer for the bytes. */ + if (length > TPM_LARGE_ENOUGH_COMMAND_SIZE - kTpmResponseHeaderLength + - sizeof(uint32_t)) { + return TPM_E_IOERROR; + } + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result == TPM_SUCCESS) { + uint8_t* get_random_cursor; + FromTpmUint32(response + kTpmResponseHeaderLength, size); + + /* There must be room in the target buffer for the bytes. */ + if (*size > length) { + return TPM_E_RESPONSE_TOO_LARGE; + } + get_random_cursor = response + kTpmResponseHeaderLength + + sizeof(uint32_t); + Memcpy(data, get_random_cursor, *size); + } + + return result; +} diff --git a/src/lib/tlcl_internal.h b/src/lib/tlcl_internal.h new file mode 100644 index 0000000000..51fe6ef3f0 --- /dev/null +++ b/src/lib/tlcl_internal.h @@ -0,0 +1,61 @@ +/* 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. + */ + +#ifndef TPM_LITE_TLCL_INTERNAL_H_ +#define TPM_LITE_TLCL_INTERNAL_H_ + +/* + * These numbers derive from adding the sizes of command fields as shown in the + * TPM commands manual. + */ +#define kTpmRequestHeaderLength 10 +#define kTpmResponseHeaderLength 10 +#define kTpmReadInfoLength 12 +#define kEncAuthLength 20 +#define kPcrDigestLength 20 + + +/* + * Conversion functions. ToTpmTYPE puts a value of type TYPE into a TPM + * command buffer. FromTpmTYPE gets a value of type TYPE from a TPM command + * buffer into a variable. + */ +__attribute__((unused)) +static inline void ToTpmUint32(uint8_t *buffer, uint32_t x) { + buffer[0] = (uint8_t)(x >> 24); + buffer[1] = (uint8_t)((x >> 16) & 0xff); + buffer[2] = (uint8_t)((x >> 8) & 0xff); + buffer[3] = (uint8_t)(x & 0xff); +} + +/* + * See comment for above function. + */ +__attribute__((unused)) +static inline void FromTpmUint32(const uint8_t *buffer, uint32_t *x) { + *x = ((buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + buffer[3]); +} + +/* + * See comment for above function. + */ +__attribute__((unused)) +static inline void ToTpmUint16(uint8_t *buffer, uint16_t x) { + buffer[0] = (uint8_t)(x >> 8); + buffer[1] = (uint8_t)(x & 0xff); +} + +/* + * See comment for above function. + */ +__attribute__((unused)) +static inline void FromTpmUint16(const uint8_t *buffer, uint16_t *x) { + *x = (buffer[0] << 8) | buffer[1]; +} + +#endif /* TPM_LITE_TLCL_INTERNAL_H_ */ diff --git a/src/lib/tlcl_structures.h b/src/lib/tlcl_structures.h new file mode 100644 index 0000000000..36c1bb9ed8 --- /dev/null +++ b/src/lib/tlcl_structures.h @@ -0,0 +1,138 @@ +/* This file is automatically generated */ + +const struct s_tpm_extend_cmd{ + uint8_t buffer[34]; + uint16_t pcrNum; + uint16_t inDigest; +} tpm_extend_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, }, +10, 14, }; + +const struct s_tpm_get_random_cmd{ + uint8_t buffer[14]; + uint16_t bytesRequested; +} tpm_get_random_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x46, }, +10, }; + +const struct s_tpm_getownership_cmd{ + uint8_t buffer[22]; +} tpm_getownership_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x11, }, +}; + +const struct s_tpm_getpermissions_cmd{ + uint8_t buffer[22]; + uint16_t index; +} tpm_getpermissions_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x4, }, +18, }; + +const struct s_tpm_getstclearflags_cmd{ + uint8_t buffer[22]; +} tpm_getstclearflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x9, }, +}; + +const struct s_tpm_getflags_cmd{ + uint8_t buffer[22]; +} tpm_getflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x8, }, +}; + +const struct s_tpm_physicalsetdeactivated_cmd{ + uint8_t buffer[11]; + uint16_t deactivated; +} tpm_physicalsetdeactivated_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, }, +10, }; + +const struct s_tpm_physicalenable_cmd{ + uint8_t buffer[10]; +} tpm_physicalenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, }, +}; + +const struct s_tpm_physicaldisable_cmd{ + uint8_t buffer[10]; +} tpm_physicaldisable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, }, +}; + +const struct s_tpm_forceclear_cmd{ + uint8_t buffer[10]; +} tpm_forceclear_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, }, +}; + +const struct s_tpm_readpubek_cmd{ + uint8_t buffer[30]; +} tpm_readpubek_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, }, +}; + +const struct s_tpm_continueselftest_cmd{ + uint8_t buffer[10]; +} tpm_continueselftest_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, }, +}; + +const struct s_tpm_selftestfull_cmd{ + uint8_t buffer[10]; +} tpm_selftestfull_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, }, +}; + +const struct s_tpm_resume_cmd{ + uint8_t buffer[12]; +} tpm_resume_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x2, }, +}; + +const struct s_tpm_savestate_cmd{ + uint8_t buffer[10]; +} tpm_savestate_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x98, }, +}; + +const struct s_tpm_startup_cmd{ + uint8_t buffer[12]; +} tpm_startup_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1, }, +}; + +const struct s_tpm_finalizepp_cmd{ + uint8_t buffer[12]; +} tpm_finalizepp_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, }, +}; + +const struct s_tpm_pplock_cmd{ + uint8_t buffer[12]; +} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, }, +}; + +const struct s_tpm_ppenable_cmd{ + uint8_t buffer[12]; +} tpm_ppenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x20, }, +}; + +const struct s_tpm_ppassert_cmd{ + uint8_t buffer[12]; +} tpm_ppassert_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x8, }, +}; + +const struct s_tpm_pcr_read_cmd{ + uint8_t buffer[14]; + uint16_t pcrNum; +} tpm_pcr_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, }, +10, }; + +const struct s_tpm_nv_read_cmd{ + uint8_t buffer[22]; + uint16_t index; + uint16_t length; +} tpm_nv_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, }, +10, 18, }; + +const struct s_tpm_nv_write_cmd{ + uint8_t buffer[256]; + uint16_t index; + uint16_t length; + uint16_t data; +} tpm_nv_write_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, }, +10, 18, 22, }; + +const struct s_tpm_nv_definespace_cmd{ + uint8_t buffer[101]; + uint16_t index; + uint16_t perm; + uint16_t size; +} tpm_nv_definespace_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0xcc, 0x0, 0x18, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x17, }, +12, 70, 77, }; + +const int kWriteInfoLength = 12; +const int kNvDataPublicPermissionsOffset = 60; diff --git a/src/lib/tpm_error_messages.h b/src/lib/tpm_error_messages.h new file mode 100644 index 0000000000..14cb86beae --- /dev/null +++ b/src/lib/tpm_error_messages.h @@ -0,0 +1,250 @@ +/* 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.
+ */
+
+/* TPM error codes.
+ *
+ * Copy-pasted and lightly edited from TCG TPM Main Part 2 TPM Structures
+ * Version 1.2 Level 2 Revision 103 26 October 2006 Draft.
+ */
+
+#ifndef TPM_ERROR_MESSAGES_H
+#define TPM_ERROR_MESSAGES_H
+
+#define TPM_E_BASE 0x0
+#define TPM_E_NON_FATAL 0x800
+
+typedef struct tpm_error_info {
+ const char* name;
+ uint32_t code;
+ const char* description;
+} tpm_error_info;
+
+tpm_error_info tpm_error_table[] = {
+{ "TPM_AUTHFAIL", TPM_E_BASE + 1,
+"Authentication failed" },
+{ "TPM_BADINDEX", TPM_E_BASE + 2,
+"The index to a PCR, DIR or other register is incorrect" },
+{ "TPM_BAD_PARAMETER", TPM_E_BASE + 3,
+"One or more parameter is bad" },
+{ "TPM_AUDITFAILURE", TPM_E_BASE + 4,
+"An operation completed successfully\n\
+but the auditing of that operation failed" },
+{ "TPM_CLEAR_DISABLED", TPM_E_BASE + 5,
+"The clear disable flag is set and all clear operations now require\n\
+physical access" },
+{ "TPM_DEACTIVATED", TPM_E_BASE + 6,
+"The TPM is deactivated" },
+{ "TPM_DISABLED", TPM_E_BASE + 7,
+"The TPM is disabled" },
+{ "TPM_DISABLED_CMD", TPM_E_BASE + 8,
+"The target command has been disabled" },
+{ "TPM_FAIL", TPM_E_BASE + 9,
+"The operation failed" },
+{ "TPM_BAD_ORDINAL", TPM_E_BASE + 10,
+"The ordinal was unknown or inconsistent" },
+{ "TPM_INSTALL_DISABLED", TPM_E_BASE + 11,
+"The ability to install an owner is disabled" },
+{ "TPM_INVALID_KEYHANDLE", TPM_E_BASE + 12,
+"The key handle can not be interpreted" },
+{ "TPM_KEYNOTFOUND", TPM_E_BASE + 13,
+"The key handle points to an invalid key" },
+{ "TPM_INAPPROPRIATE_ENC", TPM_E_BASE + 14,
+"Unacceptable encryption scheme" },
+{ "TPM_MIGRATEFAIL", TPM_E_BASE + 15,
+"Migration authorization failed" },
+{ "TPM_INVALID_PCR_INFO", TPM_E_BASE + 16,
+"PCR information could not be interpreted" },
+{ "TPM_NOSPACE", TPM_E_BASE + 17,
+"No room to load key" },
+{ "TPM_NOSRK", TPM_E_BASE + 18,
+"There is no SRK set" },
+{ "TPM_NOTSEALED_BLOB", TPM_E_BASE + 19,
+"An encrypted blob is invalid or was not created by this TPM" },
+{ "TPM_OWNER_SET", TPM_E_BASE + 20,
+"There is already an Owner" },
+{ "TPM_RESOURCES", TPM_E_BASE + 21,
+"The TPM has insufficient internal resources to perform the requested action" },
+{ "TPM_SHORTRANDOM", TPM_E_BASE + 22,
+"A random string was too short" },
+{ "TPM_SIZE", TPM_E_BASE + 23,
+"The TPM does not have the space to perform the operation" },
+{ "TPM_WRONGPCRVAL", TPM_E_BASE + 24,
+"The named PCR value does not match the current PCR value" },
+{ "TPM_BAD_PARAM_SIZE", TPM_E_BASE + 25,
+"The paramSize argument to the command has the incorrect value" },
+{ "TPM_SHA_THREAD", TPM_E_BASE + 26,
+"There is no existing SHA-1 thread" },
+{ "TPM_SHA_ERROR", TPM_E_BASE + 27,
+"The calculation is unable to proceed because the existing SHA-1\n\
+thread has already encountered an error" },
+{ "TPM_FAILEDSELFTEST", TPM_E_BASE + 28,
+"Self-test has failed and the TPM has shutdown" },
+{ "TPM_AUTH2FAIL", TPM_E_BASE + 29,
+"The authorization for the second key in a 2 key function\n\
+failed authorization" },
+{ "TPM_BADTAG", TPM_E_BASE + 30,
+"The tag value sent to for a command is invalid" },
+{ "TPM_IOERROR", TPM_E_BASE + 31,
+"An IO error occurred transmitting information to the TPM" },
+{ "TPM_ENCRYPT_ERROR", TPM_E_BASE + 32,
+"The encryption process had a problem" },
+{ "TPM_DECRYPT_ERROR", TPM_E_BASE + 33,
+"The decryption process did not complete" },
+{ "TPM_INVALID_AUTHHANDLE", TPM_E_BASE + 34,
+"An invalid handle was used" },
+{ "TPM_NO_ENDORSEMENT", TPM_E_BASE + 35,
+"The TPM does not a EK installed" },
+{ "TPM_INVALID_KEYUSAGE", TPM_E_BASE + 36,
+"The usage of a key is not allowed" },
+{ "TPM_WRONG_ENTITYTYPE", TPM_E_BASE + 37,
+"The submitted entity type is not allowed" },
+{ "TPM_INVALID_POSTINIT", TPM_E_BASE + 38,
+"The command was received in the wrong sequence relative to TPM_Init\n\
+and a subsequent TPM_Startup" },
+{ "TPM_INAPPROPRIATE_SIG", TPM_E_BASE + 39,
+"Signed data cannot include additional DER information" },
+{ "TPM_BAD_KEY_PROPERTY", TPM_E_BASE + 40,
+"The key properties in TPM_KEY_PARMs are not supported by this TPM" },
+{ "TPM_BAD_MIGRATION", TPM_E_BASE + 41,
+"The migration properties of this key are incorrect" },
+{ "TPM_BAD_SCHEME", TPM_E_BASE + 42,
+"The signature or encryption scheme for this key is incorrect or not\n\
+permitted in this situation" },
+{ "TPM_BAD_DATASIZE", TPM_E_BASE + 43,
+"The size of the data (or blob) parameter is bad or inconsistent\n\
+with the referenced key" },
+{ "TPM_BAD_MODE", TPM_E_BASE + 44,
+"A mode parameter is bad, such as capArea or subCapArea for\n\
+TPM_GetCapability, physicalPresence parameter for TPM_PhysicalPresence,\n\
+or migrationType for, TPM_CreateMigrationBlob" },
+{ "TPM_BAD_PRESENCE", TPM_E_BASE + 45,
+"Either the physicalPresence or physicalPresenceLock bits\n\
+have the wrong value" },
+{ "TPM_BAD_VERSION", TPM_E_BASE + 46,
+"The TPM cannot perform this version of the capability" },
+{ "TPM_NO_WRAP_TRANSPORT", TPM_E_BASE + 47,
+"The TPM does not allow for wrapped transport sessions" },
+{ "TPM_AUDITFAIL_UNSUCCESSFUL", TPM_E_BASE + 48,
+"TPM audit construction failed and the underlying command\n\
+was returning a failure code also" },
+{ "TPM_AUDITFAIL_SUCCESSFUL", TPM_E_BASE + 49,
+"TPM audit construction failed and the underlying command\n\
+was returning success" },
+{ "TPM_NOTRESETABLE", TPM_E_BASE + 50,
+"Attempt to reset a PCR register that does not have the resettable attribute" },
+{ "TPM_NOTLOCAL", TPM_E_BASE + 51,
+"Attempt to reset a PCR register that requires locality\n\
+and locality modifier not part of command transport" },
+{ "TPM_BAD_TYPE", TPM_E_BASE + 52,
+"Make identity blob not properly typed" },
+{ "TPM_INVALID_RESOURCE", TPM_E_BASE + 53,
+"When saving context identified resource type does not match actual resource" },
+{ "TPM_NOTFIPS", TPM_E_BASE + 54,
+"The TPM is attempting to execute a command only available when in FIPS mode" },
+{ "TPM_INVALID_FAMILY", TPM_E_BASE + 55,
+"The command is attempting to use an invalid family ID" },
+{ "TPM_NO_NV_PERMISSION", TPM_E_BASE + 56,
+"The permission to manipulate the NV storage is not available" },
+{ "TPM_REQUIRES_SIGN", TPM_E_BASE + 57,
+"The operation requires a signed command" },
+{ "TPM_KEY_NOTSUPPORTED", TPM_E_BASE + 58,
+"Wrong operation to load an NV key" },
+{ "TPM_AUTH_CONFLICT", TPM_E_BASE + 59,
+"NV_LoadKey blob requires both owner and blob authorization" },
+{ "TPM_AREA_LOCKED", TPM_E_BASE + 60,
+"The NV area is locked and not writable" },
+{ "TPM_BAD_LOCALITY", TPM_E_BASE + 61,
+"The locality is incorrect for the attempted operation" },
+{ "TPM_READ_ONLY", TPM_E_BASE + 62,
+"The NV area is read only and canât be written to" },
+{ "TPM_PER_NOWRITE", TPM_E_BASE + 63,
+"There is no protection on the write to the NV area" },
+{ "TPM_FAMILYCOUNT", TPM_E_BASE + 64,
+"The family count value does not match" },
+{ "TPM_WRITE_LOCKED", TPM_E_BASE + 65,
+"The NV area has already been written to" },
+{ "TPM_BAD_ATTRIBUTES", TPM_E_BASE + 66,
+"The NV area attributes conflict" },
+{ "TPM_INVALID_STRUCTURE", TPM_E_BASE + 67,
+"The structure tag and version are invalid or inconsistent" },
+{ "TPM_KEY_OWNER_CONTROL", TPM_E_BASE + 68,
+"The key is under control of the TPM Owner and can only be evicted\n\
+by the TPM Owner" },
+{ "TPM_BAD_COUNTER", TPM_E_BASE + 69,
+"The counter handle is incorrect" },
+{ "TPM_NOT_FULLWRITE", TPM_E_BASE + 70,
+"The write is not a complete write of the area" },
+{ "TPM_CONTEXT_GAP", TPM_E_BASE + 71,
+"The gap between saved context counts is too large" },
+{ "TPM_MAXNVWRITES", TPM_E_BASE + 72,
+"The maximum number of NV writes without an owner has been exceeded" },
+{ "TPM_NOOPERATOR", TPM_E_BASE + 73,
+"No operator AuthData value is set" },
+{ "TPM_RESOURCEMISSING", TPM_E_BASE + 74,
+"The resource pointed to by context is not loaded" },
+{ "TPM_DELEGATE_LOCK", TPM_E_BASE + 75,
+"The delegate administration is locked" },
+{ "TPM_DELEGATE_FAMILY", TPM_E_BASE + 76,
+"Attempt to manage a family other then the delegated family" },
+{ "TPM_DELEGATE_ADMIN", TPM_E_BASE + 77,
+"Delegation table management not enabled" },
+{ "TPM_TRANSPORT_NOTEXCLUSIVE", TPM_E_BASE + 78,
+"There was a command executed outside of an exclusive transport session" },
+{ "TPM_OWNER_CONTROL", TPM_E_BASE + 79,
+"Attempt to context save a owner evict controlled key" },
+{ "TPM_DAA_RESOURCES", TPM_E_BASE + 80,
+"The DAA command has no resources available to execute the command" },
+{ "TPM_DAA_INPUT_DATA0", TPM_E_BASE + 81,
+"The consistency check on DAA parameter inputData0 has failed" },
+{ "TPM_DAA_INPUT_DATA1", TPM_E_BASE + 82,
+"The consistency check on DAA parameter inputData1 has failed" },
+{ "TPM_DAA_ISSUER_SETTINGS", TPM_E_BASE + 83,
+"The consistency check on DAA_issuerSettings has failed" },
+{ "TPM_DAA_TPM_SETTINGS", TPM_E_BASE + 84,
+"The consistency check on DAA_tpmSpecific has failed" },
+{ "TPM_DAA_STAGE", TPM_E_BASE + 85,
+"The atomic process indicated by the submitted DAA command is not\n\
+the expected process" },
+{ "TPM_DAA_ISSUER_VALIDITY", TPM_E_BASE + 86,
+"The issuerâs validity check has detected an inconsistency" },
+{ "TPM_DAA_WRONG_W", TPM_E_BASE + 87,
+"The consistency check on w has failed" },
+{ "TPM_BAD_HANDLE", TPM_E_BASE + 88,
+"The handle is incorrect" },
+{ "TPM_BAD_DELEGATE", TPM_E_BASE + 89,
+"Delegation is not correct" },
+{ "TPM_BADCONTEXT", TPM_E_BASE + 90,
+"The context blob is invalid" },
+{ "TPM_TOOMANYCONTEXTS", TPM_E_BASE + 91,
+"Too many contexts held by the TPM" },
+{ "TPM_MA_TICKET_SIGNATURE", TPM_E_BASE + 92,
+"Migration authority signature validation failure" },
+{ "TPM_MA_DESTINATION", TPM_E_BASE + 93,
+"Migration destination not authenticated" },
+{ "TPM_MA_SOURCE", TPM_E_BASE + 94,
+"Migration source incorrect" },
+{ "TPM_MA_AUTHORITY", TPM_E_BASE + 95,
+"Incorrect migration authority" },
+{ "TPM_PERMANENTEK", TPM_E_BASE + 97,
+"Attempt to revoke the EK and the EK is not revocable" },
+{ "TPM_BAD_SIGNATURE", TPM_E_BASE + 98,
+"Bad signature of CMK ticket" },
+{ "TPM_NOCONTEXTSPACE", TPM_E_BASE + 99,
+"There is no room in the context list for additional contexts" },
+{ "TPM_RETRY", TPM_E_BASE + TPM_E_NON_FATAL,
+"The TPM is too busy to respond to the command immediately, but\n\
+the command could be resubmitted at a later time. The TPM MAY\n\
+return TPM_RETRY for any command at any time" },
+{ "TPM_NEEDS_SELFTEST", TPM_E_BASE + TPM_E_NON_FATAL + 1,
+"TPM_ContinueSelfTest has not been run" },
+{ "TPM_DOING_SELFTEST", TPM_E_BASE + TPM_E_NON_FATAL + 2,
+"The TPM is currently executing the actions of TPM_ContinueSelfTest\n\
+because the ordinal required resources that have not been tested" },
+{ "TPM_DEFEND_LOCK_RUNNING", TPM_E_BASE + TPM_E_NON_FATAL + 3,
+"The TPM is defending against dictionary attacks and is in some\n\
+time-out period" },
+ };
+
+#endif /* TPM_ERROR_MESSAGES_H */
|