tpmc: add PCR reading function

Add ability to report a single PCR value via the tpmc utility. Using
/sys/devices/platform/tpm_tis/pcrs is too slow, since it reads all
PCRs before returning. Anything wanting to read PCR0 on a time-critical
path needs maximum speed.

BUG=chromium-os:22172
TEST=install and test x86-alex.

Change-Id: I2d450961d33fa314d54b909135a74aa756279ec6
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/13891
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
This commit is contained in:
Kees Cook
2012-01-09 14:17:40 -08:00
committed by Luigi Semenzato
parent 93a892ce8b
commit 946370d012
6 changed files with 68 additions and 0 deletions

View File

@@ -68,6 +68,11 @@ uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length);
*/
uint32_t TlclRead(uint32_t index, void* data, uint32_t length);
/* Reads PCR at [index] into [data]. [length] must be TPM_PCR_DIGEST or
* larger. The TPM error code is returned.
*/
uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length);
/* Write-locks space at [index]. The TPM error code is returned.
*/
uint32_t TlclWriteLock(uint32_t index);

View File

@@ -14,6 +14,7 @@
#define TPM_MAX_COMMAND_SIZE 4096
#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
#define TPM_PUBEK_SIZE 256
#define TPM_PCR_DIGEST 20
#define TPM_E_NON_FATAL 0x800

View File

@@ -94,6 +94,12 @@ const struct s_tpm_ppassert_cmd{
} 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;

View File

@@ -214,6 +214,28 @@ uint32_t TlclRead(uint32_t index, void* data, uint32_t length) {
return result;
}
uint32_t TlclPCRRead(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: 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);

View File

@@ -170,6 +170,14 @@ Command* BuildReadCommand(void) {
return cmd;
}
Command* BuildPCRReadCommand(void) {
int size = kTpmRequestHeaderLength + sizeof(uint32_t);
Command* cmd = newCommand(TPM_ORD_PcrRead, size);
cmd->name = "tpm_pcr_read_cmd";
AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
return cmd;
}
Command* BuildPPAssertCommand(void) {
int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
@@ -454,6 +462,7 @@ Command* (*builders[])(void) = {
BuildDefineSpaceCommand,
BuildWriteCommand,
BuildReadCommand,
BuildPCRReadCommand,
BuildPPAssertCommand,
BuildPPEnableCommand,
BuildPPLockCommand,

View File

@@ -160,6 +160,29 @@ static uint32_t HandlerWrite(void) {
return TlclWrite(index, value, size);
}
static uint32_t HandlerPCRRead(void) {
uint32_t index;
uint8_t value[TPM_PCR_DIGEST];
uint32_t result;
int i;
if (nargs != 3) {
fprintf(stderr, "usage: tpmc pcrread <index>\n");
exit(OTHER_ERROR);
}
if (HexStringToUint32(args[2], &index) != 0) {
fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
exit(OTHER_ERROR);
}
result = TlclPCRRead(index, value, sizeof(value));
if (result == 0) {
for (i = 0; i < TPM_PCR_DIGEST; i++) {
printf("%02x", value[i]);
}
printf("\n");
}
return result;
}
static uint32_t HandlerRead(void) {
uint32_t index, size;
uint8_t value[4096];
@@ -283,6 +306,8 @@ command_record command_table[] = {
HandlerWrite },
{ "read", "read", "read from a space (read <index> <size>)",
HandlerRead },
{ "pcrread", "pcr", "read from a PCR (pcrread <index>)",
HandlerPCRRead },
{ "getpermissions", "getp", "print space permissions (getp <index>)",
HandlerGetPermissions },
{ "getpermanentflags", "getpf", "print all permanent flags",