On 02/01/2016 05:05 PM, Kevin O'Connor wrote:
On Fri, Jan 22, 2016 at 05:47:20PM -0500, Stefan Berger wrote:
From: Stefan Berger <[email protected]>
Introduce a log_entry 'object' that we use to hold the data to be logged in
one log entry. Pass this object around rather than the TPM 1.2 specific 'pcpes'
structure.
Write this log_entry in the format that is appropriate for the version of the
host's TPM. For TPM 1.2 write it in the 'pcpes' structure's format, for TPM 2
in the new TPM 2 format.
By using this method we can keep the API interface on systems with a TPM 2 even
though applications pass in the 'pcpes' structures directly. The log will still
be
written in the appropriate format.
The TPM 2 log contains a TPM 1.2 type of entry of event type EV_NO_ACTION and
entry of type TCG_EfiSpeIdEventStruct as the first entry. This is described
in the EFI specification (section 5.3):
TCG EFI Protocol Specification for TPM Family 2.0
http://www.trustedcomputinggroup.org/resources/tcg_efi_protocol_specification
Signed-off-by: Stefan Berger <[email protected]>
---
src/std/tcg.h | 35 ++++++++++++
src/tcgbios.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 183 insertions(+), 25 deletions(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h
index 8466b14..1e8b250 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -89,6 +89,7 @@ enum irq_ids {
/* event types: 10.4.1 / table 11 */
#define EV_POST_CODE 1
+#define EV_NO_ACTION 3
#define EV_SEPARATOR 4
#define EV_ACTION 5
#define EV_EVENT_TAG 6
@@ -472,4 +473,38 @@ struct tpm2_req_hierarchycontrol {
u8 state;
} PACKED;
+/* TPM 2 log entry */
+
+struct tpml_digest_values_sha1 {
+ u16 hashtype;
+ u8 sha1[SHA1_BUFSIZE];
+};
+
+struct tcg_pcr_event2_sha1 {
+ u32 pcrindex;
+ u32 eventtype;
+ u32 count; /* number of digests */
+ struct tpml_digest_values_sha1 digests[1];
+ u32 eventsize;
+ u8 event[0];
+} PACKED;
+
+struct TCG_EfiSpecIdEventStruct {
+ u8 signature[16];
+ u32 platformClass;
+ u8 specVersionMinor;
+ u8 specVersionMajor;
+ u8 specErrata;
+ u8 uintnSize;
+ u32 numberOfAlgorithms;
+ struct TCG_EfiSpecIdEventAlgorithmSize {
+ u16 algorithmId;
+ u16 digestSize;
+ } digestSizes[1];
+ u8 vendorInfoSize;
+ u8 vendorInfo[0];
+};
+
+#define TPM_TCPA_ACPI_CLASS_CLIENT 0
+
#endif // tcg.h
diff --git a/src/tcgbios.c b/src/tcgbios.c
index f5500b1..369736c 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -52,6 +52,71 @@ static const u8 TPM2_SelfTest_YES[] = { TPM2_YES }; /* full
test */
typedef u8 tpm_ppi_code;
+
+static TPMVersion TPM_version;
+
+/****************************************************************
+ * Log entry 'object'
+ ****************************************************************/
This section looks like it could be merged into the "ACPI TCPA table
interface" section as both sections are focused solely on logging.
+struct log_entry {
+ u32 pcrindex;
+ u32 eventtype;
+ /* we only support SHA1 for TPM 2 */
+ u8 sha1[SHA1_BUFSIZE];
+ u32 eventdatasize;
+ const void *event; /* TPM 1.2 & 2 */
+};
Instead of introducing 'struct log_entry' to be the superset of
tcg_pcr_event2_sha1 and pcpes, why not use tcg_pcr_event2_sha1
everywhere? That is, replace all the 'struct pcpes *' with 'struct
tcg_pcr_event2_sha1 *' and then enhance tpm_log_event() to translate
to a pcpes for older logs.
Sure, can do that also.
Of course, the above is assuming the log should be in an "efi" format
- see previous email on that.
The format doesn't depend on the kind of firmware (efi vs. bios), it's
more a TPM 2 type of log that supports different types of hashes per
measurement.
[...]
+void tpm_log_init(void)
+{
+ struct TCG_EfiSpecIdEventStruct event = {
+ .signature = "Spec ID Event03",
+ .platformClass = TPM_TCPA_ACPI_CLASS_CLIENT,
+ .specVersionMinor = 0,
+ .specVersionMajor = 2,
+ .specErrata = 0,
+ .uintnSize = 2,
+ .numberOfAlgorithms = 1,
+ .digestSizes[0] = {
+ .algorithmId = TPM2_ALG_SHA1,
+ .digestSize = SHA1_BUFSIZE,
+ },
+ .vendorInfoSize = 0,
+ };
+ struct log_entry le = {
+ .eventtype = EV_NO_ACTION,
+ .event = &event,
+ };
+
+ switch (TPM_version) {
+ case TPM_VERSION_NONE:
+ case TPM_VERSION_1_2:
+ break;
+ case TPM_VERSION_2:
+ /* write a 1.2 type of entry */
+ TPM_version = 1;
+ tpm_log_event(&le);
+ TPM_version = 2;
Altering the TPM_version seems ugly - I think tpm_log_event() could
take the version as a parameter to avoid that.
:-)
Stefan
_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios