I have an TPM 1.2 and Ivy Bridge processor that supports TXT, however the new tools (lcptools-v2) do not produce the a legacy PCONF element that will boot like the old lcptools did (the other elements seems to work fine).

I created some patches, and with tboot finally starts:

# HG changeset patch
# User Christopher Byrne <salah.coro...@gmail.com>
# Date 1641179189 21600
#      Sun Jan 02 21:06:29 2022 -0600
# Node ID 58b9fd5375215c662b7ba9db0155872c5196d2b4
# Parent  212289468e2d8ba2bf5f4d4b869f1a2f42262f18
Fix endianness of pcr_info->pcr_selection.size_of_select

This field is big endian, and the wrong endianness causes a 0xc0111c61
error (field wrong size)

Signed-off-by: Christopher Byrne <salah.coro...@gmail.com>

diff -r 212289468e2d -r 58b9fd537521 lcptools-v2/pconf_legacy.c
--- a/lcptools-v2/pconf_legacy.c        Thu Dec 16 12:26:24 2021 +0100
+++ b/lcptools-v2/pconf_legacy.c        Sun Jan 02 21:06:29 2022 -0600
@@ -324,7 +324,7 @@
             return false;
         }
         pcr_info->locality_at_release = locality;
-        pcr_info->pcr_selection.size_of_select = 1;
+        pcr_info->pcr_selection.size_of_select = htons(1);
         pcr_info->pcr_selection.pcr_select = pcr_select;
         memcpy_s((void *)&pcr_info->digest_at_release, SHA1_DIGEST_SIZE,
(const void *)&digest->sha1, SHA1_DIGEST_SIZE);
@@ -359,7 +359,7 @@
     for (int i = 0; i < pconf->num_pcr_infos; i++) {
         DISPLAY("%sPCRInfos[%d]\n", prefix, i);
         DISPLAY("%s%sTPM_PCR_SELECTION.sizeOfSelect: 0x%x\n", prefix,
- prefix, pcr_info->pcr_selection.size_of_select); + prefix, ntohs(pcr_info->pcr_selection.size_of_select));
         DISPLAY("%s%sTPM_PCR_SELECTION.pcrSelect: 0x%x\n", prefix, prefix,

pcr_info->pcr_selection.pcr_select);
         DISPLAY("%s%s:PCR-0:PCR-1:PCR-2:PCR-3:PCR-4:PCR-5:PCR-6:PCR-7:\n",
# HG changeset patch
# User Christopher Byrne <salah.coro...@gmail.com>
# Date 1641179723 21600
#      Sun Jan 02 21:15:23 2022 -0600
# Node ID 39ee48b3220fe67cf442c24c5db1397a6e7bc2b8
# Parent  58b9fd5375215c662b7ba9db0155872c5196d2b4
Don't ignore locality in PCR file

The locality was always set to 0x1f no matter what was in the PCR file
because the value read from the file was never written to to the global
variable, which seems to mostly unused anyway.

Signed-off-by: Christopher Byrne <salah.coro...@gmail.com>

diff -r 58b9fd537521 -r 39ee48b3220f lcptools-v2/pconf_legacy.c
--- a/lcptools-v2/pconf_legacy.c        Sun Jan 02 21:06:29 2022 -0600
+++ b/lcptools-v2/pconf_legacy.c        Sun Jan 02 21:15:23 2022 -0600
@@ -68,7 +68,6 @@
 } pcr_data;

 //Global vars:
-uint8_t locality = DEFAULT_LOCALITY_SELECT;
 char pcr_info_files[MAX_FILES][MAX_PATH];
 uint8_t num_files = 0;
 int prevOpt = 'i';
@@ -169,6 +168,7 @@
         if (this_pcr.locality != 0xFF && this_pcr.num != 0xFF) {
             this_pcr.valid = true;
             pcrs[this_pcr.num] = this_pcr;
+           pcrs[0].locality = locality;
         }
         else {
             ERROR("Error: failed to read PCR data. Check input file.\n");
@@ -323,7 +323,7 @@
             free(elt);
             return false;
         }
-        pcr_info->locality_at_release = locality;
+        pcr_info->locality_at_release = pcrs[0].locality;
         pcr_info->pcr_selection.size_of_select = htons(1);
         pcr_info->pcr_selection.pcr_select = pcr_select;
         memcpy_s((void *)&pcr_info->digest_at_release, SHA1_DIGEST_SIZE,
# HG changeset patch
# User Christopher Byrne <salah.coro...@gmail.com>
# Date 1641194772 21600
#      Mon Jan 03 01:26:12 2022 -0600
# Node ID 78997bf8e6fb9ace37e40a188a47f8a0aaada5b0
# Parent  39ee48b3220fe67cf442c24c5db1397a6e7bc2b8
Fix composite hasing algorithm for pconf element to match lcptools-1

lcptools-v2 implements the pconf composite hashing algorithm described
in IntelĀ® Trusted Execution Technology (IntelĀ® TXT): Software Development
Guide (01/05/2021). The problem is doesn't work. TXT aborts wtih an error
"No match is found for Element." or "PCR info integrity failure".
lcptools (v1) did work, but hashed a different structure.

The structure to actually be hashed is:

typedef struct __packed {
   tpm_pcr_selection       pcr_selection;
   uint32_t                size_of_pcrs; // Big endian
   unsigned char           pcrs[][SHA1_DIGEST_SIZE];
} pcr_composite_buffer;

Rather then just "pcrs" (which is what is described and what lcptools-v2
currently does.

Signed-off-by: Christopher Byrne <salah.coro...@gmail.com>

diff -r 39ee48b3220f -r 78997bf8e6fb lcptools-v2/pconf_legacy.c
--- a/lcptools-v2/pconf_legacy.c        Sun Jan 02 21:15:23 2022 -0600
+++ b/lcptools-v2/pconf_legacy.c        Mon Jan 03 01:26:12 2022 -0600
@@ -67,6 +67,12 @@
     uint8_t digest[SHA1_DIGEST_SIZE];
 } pcr_data;

+typedef struct __packed {
+   tpm_pcr_selection      pcr_selection;
+   uint32_t                size_of_pcrs; // Big endian
+   unsigned char           pcrs[][SHA1_DIGEST_SIZE];
+} pcr_composite_buffer;
+
 //Global vars:
 char pcr_info_files[MAX_FILES][MAX_PATH];
 uint8_t num_files = 0;
@@ -207,19 +213,20 @@
     }
 }

-static bool generate_composite_hash(pcr_data *pcrs, tb_hash_t *dest, uint8_t no_of_pcrs) +static bool generate_composite_hash(tpm_pcr_selection *pcr_selection, pcr_data *pcrs, tb_hash_t *dest, uint8_t no_of_pcrs)
 {
     /*
This function: concatenates pcr values to one blob and hashes it using sha1

-    in: array of pcrs, allocated destination buffer, no of pcrs
+ in: pcr selection, array of pcrs, allocated destination buffer, no of pcrs
     out: true/false on success/failure. Dest gets the composite hash

     */
     int count = 0;
     bool result;
-    size_t buff_size;
-    unsigned char *buff;
+    pcr_composite_buffer *buff;
+    size_t buff_size = 0;
+
     if (pcrs == NULL || dest == NULL) {
         ERROR("Error: pcrs or buffer for digest are not defined.\n");
         return false;
@@ -228,12 +235,20 @@
         ERROR("Error: at least 1 and at most 8 pcrs must be selected.\n");
         return false;
     }
-    buff_size = no_of_pcrs * SHA1_DIGEST_SIZE;
+    buff_size = no_of_pcrs * SHA1_DIGEST_SIZE + sizeof(buff) -
+               sizeof(buff->pcrs[0][0]);
     buff = calloc(1, buff_size);
     if (buff == NULL) {
         ERROR("Error: failed to allocate buffer for composite digest.\n");
         return false;
     }
+    memcpy_s(
+       &buff->pcr_selection,
+       sizeof buff->pcr_selection,
+       pcr_selection,
+       sizeof buff->pcr_selection
+       );
+    buff->size_of_pcrs = htonl(no_of_pcrs * SHA1_DIGEST_SIZE);
     for (int i = 0; i < MAX_PCRS; i++) {
         if (pcrs[i].valid) {
             if (verbose) {
@@ -241,8 +256,8 @@
print_hex("", (const void *) pcrs[i].digest, SHA1_DIGEST_SIZE);
             }
             memcpy_s(
-                buff + (count * SHA1_DIGEST_SIZE), //Dest
-                buff_size - (count * SHA1_DIGEST_SIZE), //Dest size
+                buff->pcrs[count], //Dest
+                SHA1_DIGEST_SIZE, //Dest size
                 (const void *) pcrs[i].digest, //Src
                 SHA1_DIGEST_SIZE //Src size
             );
@@ -251,7 +266,7 @@
         if (count == no_of_pcrs)
             break;
     }
-    result = hash_buffer(buff, buff_size, dest, LCP_POLHALG_SHA1);
+ result = hash_buffer((unsigned char *)buff, buff_size, dest, LCP_POLHALG_SHA1);
     if (verbose) {
         DISPLAY("Composite hash value: ");
         print_hex("", (const void *) dest, SHA1_DIGEST_SIZE);
@@ -316,16 +331,17 @@
ERROR("Error: failed to allocate memory for digest buffer.\n");
             return NULL;
         }
-        result = generate_composite_hash(pcrs, digest, no_of_pcrs);
+        pcr_info->locality_at_release = pcrs[0].locality;
+        pcr_info->pcr_selection.size_of_select = htons(1);
+        pcr_info->pcr_selection.pcr_select = pcr_select;
+ result = generate_composite_hash(&pcr_info->pcr_selection, pcrs, digest, no_of_pcrs);
         if (!result) {
             ERROR("Error: failed to generate composite hash.\n");
             free(digest);
             free(elt);
             return false;
         }
-        pcr_info->locality_at_release = pcrs[0].locality;
-        pcr_info->pcr_selection.size_of_select = htons(1);
-        pcr_info->pcr_selection.pcr_select = pcr_select;
+
         memcpy_s((void *)&pcr_info->digest_at_release, SHA1_DIGEST_SIZE,
(const void *)&digest->sha1, SHA1_DIGEST_SIZE);
         pcr_info++; //Move to next one


_______________________________________________
tboot-devel mailing list
tboot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tboot-devel

Reply via email to