The following series addresses Kevin's recent comments about the TPM driver. It also continues the refactoring of those functions called by the BIOS interrupt.
Regards, Stefan
Stefan Berger (5): tpm: Drop code using the TPM for sha1 tpm: Set timeouts and durations to microsecond values tpm: Cache all log related pointers in tpm_state tpm: Refactor pass_through_to_tpm tpm: Rename remaining interrupt functions
src/hw/tpm_drivers.c | 32 +++-- src/hw/tpm_drivers.h | 26 ++-- src/std/tcg.h | 15 --- src/tcgbios.c | 352 ++++++++++++++++++--------------------------------- 4 files changed, 154 insertions(+), 271 deletions(-)
From: Stefan Berger stefanb@linux.vnet.ibm.com
Drop the code that is using the TPM for sha1 calculations.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/hw/tpm_drivers.c | 1 - src/hw/tpm_drivers.h | 3 -- src/std/tcg.h | 3 -- src/tcgbios.c | 112 ++++----------------------------------------------- 4 files changed, 7 insertions(+), 112 deletions(-)
diff --git a/src/hw/tpm_drivers.c b/src/hw/tpm_drivers.c index b5cde00..0bf5997 100644 --- a/src/hw/tpm_drivers.c +++ b/src/hw/tpm_drivers.c @@ -286,6 +286,5 @@ struct tpm_driver tpm_drivers[TPM_NUM_DRIVERS] = { .readresp = tis_readresp, .waitdatavalid = tis_waitdatavalid, .waitrespready = tis_waitrespready, - .sha1threshold = 100 * 1024, }, }; diff --git a/src/hw/tpm_drivers.h b/src/hw/tpm_drivers.h index 48c6615..6357d02 100644 --- a/src/hw/tpm_drivers.h +++ b/src/hw/tpm_drivers.h @@ -23,9 +23,6 @@ struct tpm_driver { u32 (*readresp)(u8 *buffer, u32 *len); u32 (*waitdatavalid)(void); u32 (*waitrespready)(enum tpmDurationType to_t); - /* the TPM will be used for buffers of sizes below the sha1threshold - for calculating the hash */ - u32 sha1threshold; };
extern struct tpm_driver tpm_drivers[]; diff --git a/src/std/tcg.h b/src/std/tcg.h index 464d494..ba2e243 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -60,9 +60,6 @@ #define TPM_ORD_Startup 0x00000099 #define TPM_ORD_PhysicalPresence 0x4000000a #define TPM_ORD_Extend 0x00000014 -#define TPM_ORD_SHA1Start 0x000000a0 -#define TPM_ORD_SHA1Update 0x000000a1 -#define TPM_ORD_SHA1Complete 0x000000a2 #define TSC_ORD_ResetEstablishmentBit 0x4000000b
diff --git a/src/tcgbios.c b/src/tcgbios.c index 9ae075a..decf0fd 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -323,18 +323,16 @@ transmit(u8 locty, const struct iovec iovec[], * If a buffer is provided, the response will be copied into it. */ static u32 -build_and_send_cmd_od(u8 locty, u32 ordinal, const u8 *append, u32 append_size, - u8 *resbuffer, u32 return_size, u32 *returnCode, - const u8 *otherdata, u32 otherdata_size, - enum tpmDurationType to_t) +build_and_send_cmd(u8 locty, u32 ordinal, const u8 *append, u32 append_size, + u8 *resbuffer, u32 return_size, u32 *returnCode, + enum tpmDurationType to_t) { u32 rc; u8 obuffer[64]; struct tpm_req_header trqh; struct tpm_rsp_header *trsh = (struct tpm_rsp_header *)obuffer; - struct iovec iovec[4] = {{ 0 }}; + struct iovec iovec[3] = {{ 0 }}; u32 obuffer_len = sizeof(obuffer); - u32 idx = 1;
if (return_size > sizeof(obuffer)) { dprintf(DEBUG_tcg, "TCGBIOS: size of requested response too big."); @@ -342,8 +340,7 @@ build_and_send_cmd_od(u8 locty, u32 ordinal, const u8 *append, u32 append_size, }
trqh.tag = cpu_to_be16(TPM_TAG_RQU_CMD); - trqh.totlen = cpu_to_be32(TPM_REQ_HEADER_SIZE + append_size + - otherdata_size); + trqh.totlen = cpu_to_be32(TPM_REQ_HEADER_SIZE + append_size); trqh.ordinal = cpu_to_be32(ordinal);
iovec[0].data = &trqh; @@ -352,12 +349,6 @@ build_and_send_cmd_od(u8 locty, u32 ordinal, const u8 *append, u32 append_size, if (append_size) { iovec[1].data = append; iovec[1].length = append_size; - idx = 2; - } - - if (otherdata) { - iovec[idx].data = (void *)otherdata; - iovec[idx].length = otherdata_size; }
memset(obuffer, 0x0, sizeof(obuffer)); @@ -374,18 +365,6 @@ build_and_send_cmd_od(u8 locty, u32 ordinal, const u8 *append, u32 append_size, return 0; }
- -static u32 -build_and_send_cmd(u8 locty, u32 ordinal, const u8 *append, u32 append_size, - u8 *resbuffer, u32 return_size, u32 *returnCode, - enum tpmDurationType to_t) -{ - return build_and_send_cmd_od(locty, ordinal, append, append_size, - resbuffer, return_size, returnCode, - NULL, 0, to_t); -} - - static u32 determine_timeouts(void) { @@ -619,83 +598,6 @@ get_lasa_last_ptr(u16 *entry_count, u8 **log_area_start_address_next) return log_area_start_address_last; }
- -static u32 -tpm_sha1_calc(const u8 *data, u32 length, u8 *hash) -{ - u32 rc; - u32 returnCode; - struct tpm_res_sha1start start; - struct tpm_res_sha1complete complete; - u32 blocks = length / 64; - u32 rest = length & 0x3f; - u32 numbytes, numbytes_no; - u32 offset = 0; - - rc = build_and_send_cmd(0, TPM_ORD_SHA1Start, - NULL, 0, - (u8 *)&start, sizeof(start), - &returnCode, TPM_DURATION_TYPE_SHORT); - - if (rc || returnCode) - goto err_exit; - - while (blocks > 0) { - - numbytes = be32_to_cpu(start.max_num_bytes); - if (numbytes > blocks * 64) - numbytes = blocks * 64; - - numbytes_no = cpu_to_be32(numbytes); - - rc = build_and_send_cmd_od(0, TPM_ORD_SHA1Update, - (u8 *)&numbytes_no, sizeof(numbytes_no), - NULL, 0, &returnCode, - &data[offset], numbytes, - TPM_DURATION_TYPE_SHORT); - - if (rc || returnCode) - goto err_exit; - - offset += numbytes; - blocks -= (numbytes / 64); - } - - numbytes_no = cpu_to_be32(rest); - - rc = build_and_send_cmd_od(0, TPM_ORD_SHA1Complete, - (u8 *)&numbytes_no, sizeof(numbytes_no), - (u8 *)&complete, sizeof(complete), - &returnCode, - &data[offset], rest, TPM_DURATION_TYPE_SHORT); - - if (rc || returnCode) - goto err_exit; - - memcpy(hash, complete.hash, sizeof(complete.hash)); - - return 0; - -err_exit: - dprintf(DEBUG_tcg, "TCGBIOS: TPM SHA1 malfunctioning.\n"); - - tpm_set_failure(); - if (rc) - return rc; - return TCG_TCG_COMMAND_ERROR; -} - - -static u32 -sha1_calc(const u8 *data, u32 length, u8 *hash) -{ - if (length < tpm_drivers[tpm_state.tpm_driver_to_use].sha1threshold) - return tpm_sha1_calc(data, length, hash); - - return sha1(data, length, hash); -} - - /* * Extend the ACPI log with the given entry by copying the * entry data into the log. @@ -887,7 +789,7 @@ hash_all(const struct hai *hai, u8 *hash) hai->algorithmid != TPM_ALG_SHA) return TCG_INVALID_INPUT_PARA;
- return sha1_calc((const u8 *)hai->hashdataptr, hai->hashdatalen, hash); + return sha1((const u8 *)hai->hashdataptr, hai->hashdatalen, hash); }
static u32 @@ -902,7 +804,7 @@ hash_log_event(const void *hashdata, u32 hashdata_length, return TCG_INVALID_INPUT_PARA;
if (hashdata) { - rc = sha1_calc(hashdata, hashdata_length, pcpes->digest); + rc = sha1(hashdata, hashdata_length, pcpes->digest); if (rc) return rc; }
From: Stefan Berger stefanb@linux.vnet.ibm.com
Fix the timeouts and durations -- they are provided in microseconds. Adapt the TPM driver for it.
Get TPM specific timeout and duration values earlier from the device.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/hw/tpm_drivers.c | 31 ++++++++++++++++++++----------- src/hw/tpm_drivers.h | 23 ++++++++++++++--------- src/tcgbios.c | 8 ++++---- 3 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/src/hw/tpm_drivers.c b/src/hw/tpm_drivers.c index 0bf5997..0932797 100644 --- a/src/hw/tpm_drivers.c +++ b/src/hw/tpm_drivers.c @@ -10,8 +10,10 @@ #include "config.h" // CONFIG_TPM_TIS_SHA1THRESHOLD #include "hw/tpm_drivers.h" // struct tpm_driver #include "std/tcg.h" // TCG_NO_RESPONSE +#include "output.h" // warn_timeout +#include "stacks.h" // yield #include "string.h" // memcpy -#include "util.h" // msleep +#include "util.h" // timer_calc_usec #include "x86.h" // readl
static const u32 tis_default_timeouts[4] = { @@ -93,15 +95,19 @@ static u32 tis_wait_sts(u8 locty, u32 time, u8 mask, u8 expect) return 0;
u32 rc = 1; + u32 end = timer_calc_usec(time);
- while (time > 0) { + for (;;) { u8 sts = readb(TIS_REG(locty, TIS_REG_STS)); if ((sts & mask) == expect) { rc = 0; break; } - msleep(1); - time--; + if (timer_check(end)) { + warn_timeout(); + break; + } + yield(); } return rc; } @@ -178,18 +184,21 @@ static u32 tis_senddata(const u8 *const data, u32 len)
u32 rc = 0; u32 offset = 0; - u32 end = 0; + u32 end_loop = 0; u16 burst = 0; - u32 ctr = 0; u8 locty = tis_find_active_locality(); u32 timeout_d = tpm_drivers[TIS_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_D]; + u32 end = timer_calc_usec(timeout_d);
do { - while (burst == 0 && ctr < timeout_d) { + while (burst == 0) { burst = readl(TIS_REG(locty, TIS_REG_STS)) >> 8; if (burst == 0) { - msleep(1); - ctr++; + if (timer_check(end)) { + warn_timeout(); + break; + } + yield(); } }
@@ -207,8 +216,8 @@ static u32 tis_senddata(const u8 *const data, u32 len) }
if (offset == len) - end = 1; - } while (end == 0); + end_loop = 1; + } while (end_loop == 0);
return rc; } diff --git a/src/hw/tpm_drivers.h b/src/hw/tpm_drivers.h index 6357d02..d0e6c19 100644 --- a/src/hw/tpm_drivers.h +++ b/src/hw/tpm_drivers.h @@ -66,12 +66,13 @@ extern struct tpm_driver tpm_drivers[]; #define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */ #define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
-#define SCALER 10 - -#define TIS_DEFAULT_TIMEOUT_A (750 * SCALER) -#define TIS_DEFAULT_TIMEOUT_B (2000 * SCALER) -#define TIS_DEFAULT_TIMEOUT_C (750 * SCALER) -#define TIS_DEFAULT_TIMEOUT_D (750 * SCALER) +/* + * Default TIS timeouts used before getting them from the TPM itself + */ +#define TIS_DEFAULT_TIMEOUT_A 750000 /* ms */ +#define TIS_DEFAULT_TIMEOUT_B 2000000 /* us */ +#define TIS_DEFAULT_TIMEOUT_C 750000 /* us */ +#define TIS_DEFAULT_TIMEOUT_D 750000 /* us */
enum tisTimeoutType { TIS_TIMEOUT_TYPE_A = 0, @@ -80,8 +81,12 @@ enum tisTimeoutType { TIS_TIMEOUT_TYPE_D, };
-#define TPM_DEFAULT_DURATION_SHORT (2000 * SCALER) -#define TPM_DEFAULT_DURATION_MEDIUM (20000 * SCALER) -#define TPM_DEFAULT_DURATION_LONG (60000 * SCALER) +/* + * Default command durations used before getting them from the + * TPM itself + */ +#define TPM_DEFAULT_DURATION_SHORT 2000000 /* us */ +#define TPM_DEFAULT_DURATION_MEDIUM 20000000 /* us */ +#define TPM_DEFAULT_DURATION_LONG 60000000 /* us */
#endif /* TPM_DRIVERS_H */ diff --git a/src/tcgbios.c b/src/tcgbios.c index decf0fd..38bc737 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -459,6 +459,10 @@ tpm_startup(void) if (rc || returnCode) goto err_exit;
+ rc = determine_timeouts(); + if (rc) + goto err_exit; + rc = build_and_send_cmd(0, TPM_ORD_SelfTestFull, NULL, 0, NULL, 0, &returnCode, TPM_DURATION_TYPE_LONG);
@@ -477,10 +481,6 @@ tpm_startup(void) if (rc || (returnCode != 0 && returnCode != TPM_BAD_LOCALITY)) goto err_exit;
- rc = determine_timeouts(); - if (rc) - goto err_exit; - rc = tpm_smbios_measure(); if (rc) goto err_exit;
From: Stefan Berger stefanb@linux.vnet.ibm.com
Move the tpm_state to RAM area and add all log related pointers to it so they can be cached. Remove functions that previously determined these pointers by searching for the TCPA ACPI table and walking the log.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/tcgbios.c | 110 +++++++++++++++++++++++++--------------------------------- 1 file changed, 48 insertions(+), 62 deletions(-)
diff --git a/src/tcgbios.c b/src/tcgbios.c index 38bc737..018c580 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -90,10 +90,26 @@ typedef struct { u8 tpm_working:1; u8 if_shutdown:1; u8 tpm_driver_to_use:4; + struct tcpa_descriptor_rev2 *tcpa; + + /* length of the TCPA log buffer */ + u32 log_area_minimum_length; + + /* start address of TCPA log buffer */ + u8 * log_area_start_address; + + /* number of log entries written */ + u32 entry_count; + + /* address to write next log entry to */ + u8 * log_area_next_entry; + + /* address of last entry written (need for TCG_StatusCheck) */ + u8 * log_area_last_entry; } tpm_state_t;
-static tpm_state_t tpm_state = { +tpm_state_t tpm_state VARLOW = { .tpm_driver_to_use = TPM_INVALID_DRIVER, };
@@ -195,6 +211,10 @@ find_tcpa_by_rsdp(struct rsdp_descriptor *rsdp) ctr++; }
+ /* cache it */ + if (tcpa) + tpm_state.tcpa = tcpa; + return tcpa; }
@@ -205,6 +225,9 @@ find_tcpa_table(void) struct tcpa_descriptor_rev2 *tcpa = NULL; struct rsdp_descriptor *rsdp = RsdpAddr;
+ if (tpm_state.tcpa) + return tpm_state.tcpa; + if (rsdp) tcpa = find_tcpa_by_rsdp(rsdp); else @@ -240,11 +263,16 @@ get_lasa_base_ptr(u32 *log_area_minimum_length) static void reset_acpi_log(void) { - u32 log_area_minimum_length; - u8 *log_area_start_address = get_lasa_base_ptr(&log_area_minimum_length); + tpm_state.log_area_start_address = + get_lasa_base_ptr(&tpm_state.log_area_minimum_length); + + if (tpm_state.log_area_start_address) + memset(tpm_state.log_area_start_address, 0, + tpm_state.log_area_minimum_length);
- if (log_area_start_address) - memset(log_area_start_address, 0x0, log_area_minimum_length); + tpm_state.log_area_next_entry = tpm_state.log_area_start_address; + tpm_state.log_area_last_entry = NULL; + tpm_state.entry_count = 0; }
@@ -557,47 +585,6 @@ err_exit: tpm_set_failure(); }
-static int -is_valid_pcpes(struct pcpes *pcpes) -{ - return (pcpes->eventtype != 0); -} - - -static u8 * -get_lasa_last_ptr(u16 *entry_count, u8 **log_area_start_address_next) -{ - struct pcpes *pcpes; - u32 log_area_minimum_length = 0; - u8 *log_area_start_address_base = - get_lasa_base_ptr(&log_area_minimum_length); - u8 *log_area_start_address_last = NULL; - u8 *end = log_area_start_address_base + log_area_minimum_length; - u32 size; - - if (entry_count) - *entry_count = 0; - - if (!log_area_start_address_base) - return NULL; - - while (log_area_start_address_base < end) { - pcpes = (struct pcpes *)log_area_start_address_base; - if (!is_valid_pcpes(pcpes)) - break; - if (entry_count) - (*entry_count)++; - size = pcpes->eventdatasize + offsetof(struct pcpes, event); - log_area_start_address_last = log_area_start_address_base; - log_area_start_address_base += size; - } - - if (log_area_start_address_next) - *log_area_start_address_next = log_area_start_address_base; - - return log_area_start_address_last; -} - /* * Extend the ACPI log with the given entry by copying the * entry data into the log. @@ -615,20 +602,16 @@ tpm_extend_acpi_log(struct pcpes *pcpes, const char *event, u32 event_length, u16 *entry_count) { - u32 log_area_minimum_length, size; - u8 *log_area_start_address_base = - get_lasa_base_ptr(&log_area_minimum_length); - u8 *log_area_start_address_next = NULL; + u32 size;
if (!has_working_tpm()) return TCG_GENERAL_ERROR;
- get_lasa_last_ptr(entry_count, &log_area_start_address_next); + dprintf(DEBUG_tcg, "TCGBIOS: LASA = %p, next entry = %p\n", + tpm_state.log_area_start_address, tpm_state.log_area_next_entry);
- dprintf(DEBUG_tcg, "TCGBIOS: LASA_BASE = %p, LASA_NEXT = %p\n", - log_area_start_address_base, log_area_start_address_next); + if (tpm_state.log_area_next_entry == NULL) {
- if (log_area_start_address_next == NULL || log_area_minimum_length == 0) { tpm_set_failure();
return TCG_PC_LOGOVERFLOW; @@ -636,8 +619,8 @@ tpm_extend_acpi_log(struct pcpes *pcpes,
size = offsetof(struct pcpes, event) + event_length;
- if ((log_area_start_address_next + size - log_area_start_address_base) > - log_area_minimum_length) { + if ((tpm_state.log_area_next_entry + size - tpm_state.log_area_start_address) > + tpm_state.log_area_minimum_length) { dprintf(DEBUG_tcg, "TCGBIOS: LOG OVERFLOW: size = %d\n", size);
tpm_set_failure(); @@ -647,12 +630,16 @@ tpm_extend_acpi_log(struct pcpes *pcpes,
pcpes->eventdatasize = event_length;
- memcpy(log_area_start_address_next, pcpes, offsetof(struct pcpes, event)); - memcpy(log_area_start_address_next + offsetof(struct pcpes, event), + memcpy(tpm_state.log_area_next_entry, pcpes, offsetof(struct pcpes, event)); + memcpy(tpm_state.log_area_next_entry + offsetof(struct pcpes, event), event, event_length);
+ tpm_state.log_area_last_entry = tpm_state.log_area_next_entry; + tpm_state.log_area_next_entry += size; + tpm_state.entry_count++; + if (entry_count) - (*entry_count)++; + *entry_count = tpm_state.entry_count;
return 0; } @@ -1013,9 +1000,8 @@ tpm_interrupt_handler32(struct bregs *regs) regs->ch = TCG_VERSION_MAJOR; regs->cl = TCG_VERSION_MINOR; regs->edx = 0x0; - regs->esi = (u32)get_lasa_base_ptr(NULL); - regs->edi = - (u32)get_lasa_last_ptr(NULL, NULL); + regs->esi = (u32)tpm_state.log_area_start_address; + regs->edi = (u32)tpm_state.log_area_last_entry; } break;
From: Stefan Berger stefanb@linux.vnet.ibm.com
Refactor the signature of the pass_through_to_tpm function to take individual pointers as parameters and introduce pass_through_to_tpm_int as a function to be called with the parameters passed from the BIOS interrupt.
Refactor existing callers that now do not have to build up the data structure expected by the BIOS interface.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/std/tcg.h | 12 --------- src/tcgbios.c | 82 +++++++++++++++++++++++++++-------------------------------- 2 files changed, 37 insertions(+), 57 deletions(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h index ba2e243..da3e1f6 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -329,18 +329,6 @@ struct tpm_res_sha1complete { u8 hash[20]; } PACKED;
-struct pttti_extend { - struct pttti pttti; - struct tpm_req_extend req; -} PACKED; - - -struct pttto_extend { - struct pttto pttto; - struct tpm_rsp_extend rsp; -} PACKED; - - enum ipltype { IPL_BCV = 0, IPL_EL_TORITO_1, diff --git a/src/tcgbios.c b/src/tcgbios.c index 018c580..7a60138 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -666,24 +666,34 @@ shutdown_preboot_interface(void) return rc; }
- -static void -tpm_shutdown(void) +static u32 +pass_through_to_tpm(u8 locty, const u8 *cmd, u32 cmd_length, + u8 *resp, u32 *resp_length) { - reset_acpi_log(); - shutdown_preboot_interface(); -} + struct iovec iovec[2] = {{ 0 }}; + const u32 *tmp; + + if (cmd_length < TPM_REQ_HEADER_SIZE) + return TCG_INVALID_INPUT_PARA; + + iovec[0].data = cmd; + tmp = (const u32 *)&((u8 *)iovec[0].data)[2]; + iovec[0].length = cpu_to_be32(*tmp); + + if (cmd_length != iovec[0].length) + return TCG_INVALID_INPUT_PARA; + + return transmit(locty, iovec, resp, resp_length, + TPM_DURATION_TYPE_LONG /* worst case */);
+}
static u32 -pass_through_to_tpm(struct pttti *pttti, struct pttto *pttto) +pass_through_to_tpm_int(struct pttti *pttti, struct pttto *pttto) { u32 rc = 0; u32 resbuflen = 0; struct tpm_req_header *trh; - u8 locty = 0; - struct iovec iovec[2]; - const u32 *tmp;
if (is_preboot_if_shutdown()) { rc = TCG_INTERFACE_SHUTDOWN; @@ -701,15 +711,10 @@ pass_through_to_tpm(struct pttti *pttti, struct pttto *pttto)
resbuflen = pttti->opblength - offsetof(struct pttto, tpmopout);
- iovec[0].data = pttti->tpmopin; - tmp = (const u32 *)&((u8 *)iovec[0].data)[2]; - iovec[0].length = cpu_to_be32(*tmp); - - iovec[1].data = NULL; - iovec[1].length = 0; + rc = pass_through_to_tpm(0, pttti->tpmopin, + pttti->ipblength - offsetof(struct pttti, tpmopin), + pttto->tpmopout, &resbuflen);
- rc = transmit(locty, iovec, pttto->tpmopout, &resbuflen, - TPM_DURATION_TYPE_LONG /* worst case */); if (rc) goto err_exit;
@@ -730,35 +735,22 @@ static u32 tpm_extend(u8 *hash, u32 pcrindex) { u32 rc; - struct pttto_extend pttto; - struct pttti_extend pttti = { - .pttti = { - .ipblength = sizeof(struct pttti_extend), - .opblength = sizeof(struct pttto_extend), - }, - .req = { - .tag = cpu_to_be16(0xc1), - .totlen = cpu_to_be32(sizeof(pttti.req)), - .ordinal = cpu_to_be32(TPM_ORD_Extend), - .pcrindex = cpu_to_be32(pcrindex), - }, + struct tpm_req_extend tre = { + .tag = cpu_to_be16(TPM_TAG_RQU_CMD), + .totlen = cpu_to_be32(sizeof(tre)), + .ordinal = cpu_to_be32(TPM_ORD_Extend), + .pcrindex = cpu_to_be32(pcrindex), }; + struct tpm_rsp_extend rsp; + u32 resp_length = sizeof(rsp);
- memcpy(pttti.req.digest, hash, sizeof(pttti.req.digest)); - - rc = pass_through_to_tpm(&pttti.pttti, &pttto.pttto); + memcpy(tre.digest, hash, sizeof(tre.digest));
- if (rc == 0) { - if (pttto.pttto.opblength < TPM_RSP_HEADER_SIZE || - pttto.pttto.opblength != - sizeof(struct pttto) + be32_to_cpu(pttto.rsp.totlen) || - be16_to_cpu(pttto.rsp.tag) != 0xc4) { - rc = TCG_FATAL_COM_ERROR; - } - } + rc = pass_through_to_tpm(0, (u8 *)&tre, sizeof(tre), + (u8 *)&rsp, &resp_length);
- if (rc) - tpm_shutdown(); + if (rc || resp_length != sizeof(rsp)) + tpm_set_failure();
return rc; } @@ -1014,8 +1006,8 @@ tpm_interrupt_handler32(struct bregs *regs)
case TCG_PassThroughToTPM: regs->eax = - pass_through_to_tpm((struct pttti *)input_buf32(regs), - (struct pttto *)output_buf32(regs)); + pass_through_to_tpm_int((struct pttti *)input_buf32(regs), + (struct pttto *)output_buf32(regs)); break;
case TCG_ShutdownPreBootInterface:
From: Stefan Berger stefanb@linux.vnet.ibm.com
Rename all remaining functions called directly by the BIOS interrupt by adding the suffix '_int' to them.
Add the check for whether the preboot interface is shut down where missing.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/tcgbios.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/src/tcgbios.c b/src/tcgbios.c index 7a60138..5229b4e 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -757,7 +757,7 @@ tpm_extend(u8 *hash, u32 pcrindex)
static u32 -hash_all(const struct hai *hai, u8 *hash) +hash_all_int(const struct hai *hai, u8 *hash) { if (is_preboot_if_shutdown() != 0) return TCG_INTERFACE_SHUTDOWN; @@ -869,6 +869,11 @@ hash_log_extend_event_int(const struct hleei_short *hleei_s, struct pcpes *pcpes; u32 pcrindex;
+ if (is_preboot_if_shutdown() != 0) { + rc = TCG_INTERFACE_SHUTDOWN; + goto err_exit; + } + /* short or long version? */ switch (hleei_s->ipblength) { case sizeof(struct hleei_short): @@ -923,7 +928,7 @@ err_exit:
static u32 -tss(struct ti *ti, struct to *to) +tss_int(struct ti *ti, struct to *to) { u32 rc = 0;
@@ -941,11 +946,11 @@ tss(struct ti *ti, struct to *to)
static u32 -compact_hash_log_extend_event(u8 *buffer, - u32 info, - u32 length, - u32 pcrindex, - u32 *edx_ptr) +compact_hash_log_extend_event_int(u8 *buffer, + u32 info, + u32 length, + u32 pcrindex, + u32 *edx_ptr) { u32 rc = 0; struct pcpes pcpes = { @@ -956,6 +961,9 @@ compact_hash_log_extend_event(u8 *buffer, }; u16 entry_count;
+ if (is_preboot_if_shutdown() != 0) + return TCG_INTERFACE_SHUTDOWN; + rc = hash_log_extend_event(buffer, length, &pcpes, (char *)&pcpes.event, pcpes.eventdatasize, @@ -1021,22 +1029,22 @@ tpm_interrupt_handler32(struct bregs *regs)
case TCG_HashAll: regs->eax = - hash_all((struct hai*)input_buf32(regs), - (u8 *)output_buf32(regs)); + hash_all_int((struct hai*)input_buf32(regs), + (u8 *)output_buf32(regs)); break;
case TCG_TSS: - regs->eax = tss((struct ti*)input_buf32(regs), - (struct to*)output_buf32(regs)); + regs->eax = tss_int((struct ti*)input_buf32(regs), + (struct to*)output_buf32(regs)); break;
case TCG_CompactHashLogExtendEvent: regs->eax = - compact_hash_log_extend_event((u8 *)input_buf32(regs), - regs->esi, - regs->ecx, - regs->edx, - ®s->edx); + compact_hash_log_extend_event_int((u8 *)input_buf32(regs), + regs->esi, + regs->ecx, + regs->edx, + ®s->edx); break;
default: