mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
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:
committed by
Luigi Semenzato
parent
93a892ce8b
commit
946370d012
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user