]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
refactored PCR functionality
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 22 Nov 2011 16:00:38 +0000 (17:00 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 20:22:02 +0000 (21:22 +0100)
src/libimcv/plugins/imc_attestation/imc_attestation_process.c
src/libimcv/plugins/imc_attestation/imc_attestation_state.c
src/libimcv/plugins/imc_attestation/imc_attestation_state.h
src/libimcv/plugins/imv_attestation/imv_attestation_process.c
src/libpts/pts/components/ita/ita_comp_tboot.c
src/libpts/pts/components/ita/ita_comp_tgrub.c
src/libpts/pts/pts.c
src/libpts/pts/pts.h

index 5f9ca19ecd0abf04346fd3a3192bdb409a075b49..42d7c3f735a77a20f0fa976ccfeaeb3e37fae536 100644 (file)
@@ -406,39 +406,25 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                {
                        pts_simple_evid_final_flag_t flags;
                        pts_meas_algorithms_t composite_algorithm = 0;
-                       pts_comp_evidence_t *evidence;
+                       pts_comp_evidence_t *evid;
                        chunk_t pcr_composite, quote_signature;
-                       u_int32_t i, evid_count, extended_pcr;
-                       u_int32_t *pcrs;
                        bool use_quote2;
 
                        /* Send buffered Simple Component Evidences */
-                       evid_count = attestation_state->get_evid_count(attestation_state);
-                       pcrs = (u_int32_t*)malloc(sizeof(u_int32_t)*evid_count);
-
-                       for (i = 0; i < evid_count; i++)
+                       while (attestation_state->next_evidence(attestation_state, &evid))
                        {
-                               evidence = attestation_state->next_evidence(attestation_state);
-                               extended_pcr = evidence->get_extended_pcr(evidence);
-
-                               /**
-                                * Add extended PCR number to PCR list to quote
-                                * Duplicated PCR numbers have no influence 
-                                */
-                               pcrs[i] = extended_pcr;
+                               pts->select_pcr(pts, evid->get_extended_pcr(evid));
 
                                /* Send Simple Component Evidence */
-                               attr = tcg_pts_attr_simple_comp_evid_create(evidence);
+                               attr = tcg_pts_attr_simple_comp_evid_create(evid);
                                attr_list->insert_last(attr_list, attr);
                        }
 
-                       use_quote2 = (lib->settings->get_int(lib->settings,
-                                       "libimcv.plugins.imc-attestation.quote_version", 1) == 1) ?
-                                                       FALSE : TRUE;
+                       use_quote2 = lib->settings->get_bool(lib->settings,
+                                                       "libimcv.plugins.imc-attestation.use_quote2", TRUE);
 
                        /* Quote */
-                       if (!pts->quote_tpm(pts, use_quote2, pcrs, evid_count,
-                               &pcr_composite, &quote_signature))
+                       if (!pts->quote_tpm(pts, use_quote2, &pcr_composite, &quote_signature))
                        {
                                DBG1(DBG_IMC, "error occured during TPM quote operation");
                                return FALSE;
index 4a99cf800b63067df2066576a8232256e088e691..d900224a0cbfbd8d42254f42da52caa6de0e92ad 100644 (file)
@@ -85,26 +85,12 @@ METHOD(imc_attestation_state_t, add_evidence, void,
        this->list->insert_last(this->list, evidence);
 }
 
-METHOD(imc_attestation_state_t, get_evid_count, int,
-       private_imc_attestation_state_t *this)
+METHOD(imc_attestation_state_t, next_evidence, bool,
+       private_imc_attestation_state_t *this, pts_comp_evidence_t **evid)
 {
-       return this->list->get_count(this->list);
+       return this->list->remove_first(this->list, (void**)evid) == SUCCESS;
 }
 
-METHOD(imc_attestation_state_t, next_evidence, pts_comp_evidence_t*,
-       private_imc_attestation_state_t *this)
-{
-       pts_comp_evidence_t *evidence;
-
-       if (this->list->remove_first(this->list, (void**)&evidence) == SUCCESS)
-       {
-               return evidence;
-       }
-       else
-       {       
-               return NULL;
-       }
-}
 /**
  * Described in header.
  */
@@ -122,7 +108,6 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
                        },
                        .get_pts = _get_pts,
                        .add_evidence = _add_evidence,
-                       .get_evid_count = _get_evid_count,
                        .next_evidence = _next_evidence,
                },
                .connection_id = connection_id,
index 3b9ebaf22b34a8366b602009a4d5f2ce0142d8d1..22b0bba23277ce0888c4e44206f3a70e490f26a5 100644 (file)
@@ -53,19 +53,13 @@ struct imc_attestation_state_t {
         */
        void (*add_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t *entry);
 
-       /**
-        * Get the number of entries in the Component Evidence list
-        *
-        * @return                                      number of Component Evidence entries
-        */
-       int (*get_evid_count)(imc_attestation_state_t *this);
-
        /**
         * Removes next Component Evidence entry from list and returns it
         *
-        * @return                                      Next Component Evidence entry
+        * @param evid                          Next Component Evidence entry
+        * @return                                      TRUE if next entry is available
         */
-       pts_comp_evidence_t* (*next_evidence)(imc_attestation_state_t *this);
+       bool (*next_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t** evid);
 
 };
 
index 29f1140b946a1e1cf45e99b3da765a0caa14c153..c0f30abca7397423ba9dc098bf84dce7f165b32e 100644 (file)
@@ -304,7 +304,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        chunk_t tpm_quote_sign;
                        chunk_t evid_sign;
                        bool evid_signature_included = FALSE, use_quote2 = FALSE,
-                                                                                               ver_info_included = FALSE;
+                                ver_info_included = FALSE;
                        chunk_t pcr_composite, quote_info;
 
                        attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
@@ -348,11 +348,10 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        return FALSE;
                                }
 
-                               /* Check calculated PCR composite matches with received */
                                if (!chunk_equals(pcr_comp, pcr_composite))
                                {
-                                       DBG1(DBG_IMV, "received PCR Compsosite didn't match"
-                                                                 " with constructed");
+                                       DBG1(DBG_IMV, "received PCR Composite didn't match "
+                                                                 "with constructed");
                                        chunk_clear(&pcr_composite);
                                        chunk_clear(&quote_info);
                                        return FALSE;
index dc47e4b11795af994f09e9bc15c3192835354b0c..e00de61d9d2ef25adb51b7bf45b53ef6cfd606f6 100644 (file)
@@ -124,7 +124,6 @@ METHOD(pts_component_t, verify, status_t,
        pts_pcr_transform_t transform;
        time_t measurement_time;
        chunk_t measurement, pcr_before, pcr_after;
-       pcr_entry_t *entry;
 
        switch (this->extended_pcr)
        {
@@ -150,10 +149,10 @@ METHOD(pts_component_t, verify, status_t,
        has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
        if (has_pcr_info)
        {
-               entry = malloc_thing(pcr_entry_t);
-               entry->pcr_number = extended_pcr;
-               memcpy(entry->pcr_value, pcr_after.ptr, PCR_LEN);
-               pts->add_pcr_entry(pts, entry);
+               if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+               {
+                       return FAILED;
+               }
        }
 
        return (this->extended_pcr == PCR_TBOOT_MLE) ? SUCCESS : NEED_MORE;
index 9a4da6d93daab7193b047149f79072b75764451f..91d84b9ba81dafe3069b2ae43ff27311032ee6b2 100644 (file)
@@ -96,7 +96,6 @@ METHOD(pts_component_t, verify, status_t,
        pts_pcr_transform_t transform;
        time_t measurement_time;
        chunk_t measurement, pcr_before, pcr_after;
-       pcr_entry_t *entry;
 
        measurement = evidence->get_measurement(evidence, &extended_pcr,
                                                                &algo, &transform, &measurement_time);
@@ -110,10 +109,10 @@ METHOD(pts_component_t, verify, status_t,
        has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
        if (has_pcr_info)
        {
-               entry = malloc_thing(pcr_entry_t);
-               entry->pcr_number = extended_pcr;
-               memcpy(entry->pcr_value, pcr_after.ptr, PCR_LEN);
-               pts->add_pcr_entry(pts, entry);
+               if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+               {
+                       return FAILED;
+               }
        }
        
        return SUCCESS;
index 178ba64019ebea9fe0ae0dc66a9159154638e944..7df2ff035f59eafa952736779811081755cdb5ce 100644 (file)
@@ -108,9 +108,30 @@ struct private_pts_t {
        certificate_t *aik;
 
        /**
-        * List of extended PCR's with corresponding values
+        * Table of extended PCRs with corresponding values
         */
-       linked_list_t *pcrs;
+       u_char* pcrs[PCR_MAX_NUM];
+
+       /**
+        * Length of PCR registers
+        */
+       size_t pcr_len;
+
+       /**
+        * Number of extended PCR registers
+        */
+       u_int32_t pcr_count;
+
+       /**
+        * Highest extended PCR register
+        */
+       u_int32_t pcr_max;
+
+       /**
+        * Bitmap of extended PCR registers
+        */
+       u_int8_t pcr_select[PCR_MAX_NUM / 8];
+
 };
 
 METHOD(pts_t, get_proto_caps, pts_proto_caps_flag_t,
@@ -784,17 +805,32 @@ METHOD(pts_t, extend_pcr, bool,
        DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output);
        return TRUE;
 
-       err:
+err:
        chunk_clear(&pcr_value);
        DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
        Tspi_Context_Close(hContext);
        return FALSE;
 }
 
+
+static void clear_pcrs(private_pts_t *this)
+{
+       int i;
+
+       for (i = 0; i <= this->pcr_max; i++)
+       {
+               free(this->pcrs[i]);
+               this->pcrs[i] = NULL;
+       }
+       this->pcr_count = 0;
+       this->pcr_max = 0;
+
+       memset(this->pcr_select, 0x00, sizeof(this->pcr_select));
+}
+
 METHOD(pts_t, quote_tpm, bool,
-       private_pts_t *this, bool use_quote2,
-       u_int32_t *pcrs, u_int32_t num_of_pcrs,
-       chunk_t *pcr_composite, chunk_t *quote_signature)
+       private_pts_t *this, bool use_quote2, chunk_t *pcr_composite,
+       chunk_t *quote_signature)
 {
        TSS_HCONTEXT hContext;
        TSS_HTPM hTPM;
@@ -805,10 +841,11 @@ METHOD(pts_t, quote_tpm, bool,
        BYTE secret[] = TSS_WELL_KNOWN_SECRET;
        TSS_HPCRS hPcrComposite;
        TSS_VALIDATION valData;
-       u_int32_t i, versionInfoSize;
        TSS_RESULT result;
        chunk_t pcr_comp, quote_sign;
        BYTE* versionInfo;
+       u_int32_t versionInfoSize, pcr, i = 0, f = 1;
+       bool success = FALSE;
 
        result = Tspi_Context_Create(&hContext);
        if (result != TSS_SUCCESS)
@@ -866,22 +903,27 @@ METHOD(pts_t, quote_tpm, bool,
                goto err2;
        }
 
-       /* Select PCR's */
-       for (i = 0; i < num_of_pcrs ; i++)
+       /* Select PCRs */
+       for (pcr = 0; pcr <= this->pcr_max ; pcr++)
        {
-               if (pcrs[i] < 0 || pcrs[i] >= MAX_NUM_PCR )
+               if (f == 256)
                {
-                       DBG1(DBG_PTS, "Invalid PCR number: %d", pcrs[i]);
-                       goto err3;
-               }
-               result = use_quote2 ?
-                               Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcrs[i],
-                                                                                                  TSS_PCRS_DIRECTION_RELEASE):
-                               Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcrs[i]);
-               if (result != TSS_SUCCESS)
+                       i++;
+                       f = 1;
+               }               
+               if (this->pcr_select[i] & f)
                {
-                       goto err3;
+                       DBG2(DBG_TNC, "PCR %02d selected for TPM Quote", pcr);
+                       result = use_quote2 ?
+                                       Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
+                                                                                               TSS_PCRS_DIRECTION_RELEASE) :
+                                       Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr);
+                       if (result != TSS_SUCCESS)
+                       {
+                               goto err3;
+                       }
                }
+               f <<= 1;
        }
 
        /* Set the Validation Data */
@@ -928,82 +970,106 @@ METHOD(pts_t, quote_tpm, bool,
        DBG3(DBG_PTS, "TPM Quote Signature: %B",quote_signature);
 
        chunk_clear(&quote_sign);
-       Tspi_Context_FreeMemory(hContext, NULL);
-       Tspi_Context_CloseObject(hContext, hPcrComposite);
-       Tspi_Context_CloseObject(hContext, hAIK);
-       Tspi_Context_Close(hContext);
-       free(pcrs);
-       return TRUE;
+       success = TRUE;
 
        /* Cleanup */
-       err4:
+err4:
        Tspi_Context_FreeMemory(hContext, NULL);
 
-       err3:
+err3:
        Tspi_Context_CloseObject(hContext, hPcrComposite);
 
-       err2:
+err2:
        Tspi_Context_CloseObject(hContext, hAIK);
 
-       err1:
+err1:
        Tspi_Context_Close(hContext);
-       free(pcrs);
-       DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
-       return FALSE;
+
+       if (!success)
+       {
+               DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
+       }
+       clear_pcrs(this);
+
+       return success;
 }
 
-METHOD(pts_t, add_pcr_entry, void,
-       private_pts_t *this, pcr_entry_t *new)
+METHOD(pts_t, select_pcr, bool,
+       private_pts_t *this, u_int32_t pcr)
 {
-       enumerator_t *e;
-       pcr_entry_t *entry;
+       u_int32_t i, f;
 
-       if (!this->pcrs)
+       if (pcr >= PCR_MAX_NUM)
        {
-               this->pcrs = linked_list_create();
+               DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
+                                          pcr, PCR_MAX_NUM-1);
+               return FALSE;
        }
 
-       e = this->pcrs->create_enumerator(this->pcrs);
-       while (e->enumerate(e, &entry))
+       /* Determine PCR selection flag */
+       i = pcr / 8;
+       f = 1 << (pcr - 8*i);
+
+       /* Has this PCR already been selected? */
+       if (!(this->pcr_select[i] & f))
        {
-               if (entry->pcr_number == new->pcr_number)
-               {
-                       DBG3(DBG_PTS, "updating already added PCR%d value",
-                                entry->pcr_number);
-                       this->pcrs->remove_at(this->pcrs, e);
-                       free(entry);
-                       break;
-               }
+               this->pcr_select[i] |= f;
+               this->pcr_max = max(this->pcr_max, pcr);
+               this->pcr_count++;
        }
-       DESTROY_IF(e);
-       this->pcrs->insert_last(this->pcrs, new);
+
+       return TRUE;
 }
 
-/**
- * Get the maximum PCR index received in pcr_after_value field
- */
-static u_int32_t get_max_pcr_index(private_pts_t *this)
+METHOD(pts_t, add_pcr, bool,
+       private_pts_t *this, u_int32_t pcr, chunk_t pcr_before, chunk_t pcr_after)
 {
-       enumerator_t *e;
-       pcr_entry_t *pcr_entry;
-       u_int32_t ret = 0;
+       if (pcr >= PCR_MAX_NUM)
+       {
+               DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
+                                          pcr, PCR_MAX_NUM-1);
+               return FALSE;
+       }
 
-       if (this->pcrs->get_count(this->pcrs) == 0)
+       /* Is the length of the PCR registers already set? */
+       if (this->pcr_len)
        {
-               return -1;
+               if (pcr_after.len != this->pcr_len)
+               {
+                       DBG1(DBG_PTS, "PCR %02u: length is %d bytes but should be %d bytes",
+                                                  pcr_after.len, this->pcr_len);
+                       return FALSE;
+               }
        }
-       
-       e = this->pcrs->create_enumerator(this->pcrs);
-       while (e->enumerate(e, &pcr_entry))
+       else
+       {
+               this->pcr_len = pcr_after.len;
+       }
+
+       /* Has the value of the PCR register already been assigned? */
+       if (this->pcrs[pcr])
        {
-               if (pcr_entry->pcr_number > ret)
+               if (!memeq(this->pcrs[pcr], pcr_before.ptr, this->pcr_len))
                {
-                       ret = pcr_entry->pcr_number;
+                       DBG1(DBG_PTS, "PCR %02u: new pcr_before value does not equal "
+                                                 "old pcr_after value");
                }
+               /* remove the old PCR value */
+               free(this->pcrs[pcr]);
        }
-       e->destroy(e);
+       else
+       {
+               /* add extended PCR Register */
+               this->pcr_select[pcr / 8] |= 1 << (pcr % 8);
+               this->pcr_max = max(this->pcr_max, pcr);
+               this->pcr_count++;
+       }
+
+       /* Duplicate and store current PCR value */
+       pcr_after = chunk_clone(pcr_after);
+       this->pcrs[pcr] = pcr_after.ptr;
 
-       return ret;
+       return TRUE;
 }
 
 METHOD(pts_t, does_pcr_value_match, bool,
@@ -1052,70 +1118,54 @@ METHOD(pts_t, get_quote_info, bool,
        pts_meas_algorithms_t composite_algo,
        chunk_t *out_pcr_composite, chunk_t *out_quote_info)
 {
-       enumerator_t *e;
-       pcr_entry_t *pcr_entry;
+       u_int8_t size_of_select;
+       int pcr_composite_len, i;
        chunk_t pcr_composite, hash_pcr_composite;
-       u_int32_t pcr_composite_len, i, maximum_pcr_index, bitmask_len;
        bio_writer_t *writer;
        hasher_t *hasher;
 
-       maximum_pcr_index = get_max_pcr_index(this);
-       if (maximum_pcr_index == -1)
+       if (this->pcr_count == 0)
        {
-               DBG1(DBG_PTS, "PCR entries unavailable, unable to construct "
-                                         "TPM Quote Info");
+               DBG1(DBG_PTS, "No extended PCR entries available, "
+                                         "unable to construct TPM Quote Info");
                return FALSE;
        }
        if (!this->secret.ptr)
        {
-               DBG1(DBG_PTS, "Secret assessment value unavailable",
-                        "unable to construct TPM Quote Info");
+               DBG1(DBG_PTS, "Secret assessment value unavailable",
+                                         "unable to construct TPM Quote Info");
                return FALSE;
        }
        if (use_quote2 && ver_info_included && !this->tpm_version_info.ptr)
        {
-               DBG1(DBG_PTS, "TPM Version Information unavailable",
-                        "unable to construct TPM Quote Info2");
+               DBG1(DBG_PTS, "TPM Version Information unavailable",
+                                         "unable to construct TPM Quote Info2");
                return FALSE;
        }
        
-       bitmask_len = maximum_pcr_index/8 +1;
-       u_int8_t mask_bytes[MAX_NUM_PCR/8] = {0};
-       
-       pcr_composite_len = 2 + bitmask_len + 4 +
-                                               this->pcrs->get_count(this->pcrs) * PCR_LEN;
+       size_of_select = 1 + this->pcr_max / 8; 
+       pcr_composite_len = 2 + size_of_select +
+                                               4 + this->pcr_count * this->pcr_len;
        
        writer = bio_writer_create(pcr_composite_len);
-       /* Lenght of the bist mask field */
-       writer->write_uint16(writer, bitmask_len);
-       /* Bit mask indicating selected PCRs */
-       e = this->pcrs->create_enumerator(this->pcrs);
-       while (e->enumerate(e, &pcr_entry))
-       {
-               u_int32_t index = pcr_entry->pcr_number;
-               mask_bytes[index / 8] |= (1 << (index % 8));
-       }
-       e->destroy(e);
 
-       for (i = 0; i< bitmask_len ; i++)
+       writer->write_uint16(writer, size_of_select);
+       for (i = 0; i < size_of_select; i++)
        {
-               writer->write_uint8(writer, mask_bytes[i]);
+               writer->write_uint8(writer, this->pcr_select[i]);
        }
 
-       /* Lenght of the pcr entries */
-       writer->write_uint32(writer, this->pcrs->get_count(this->pcrs) * PCR_LEN);
-       /* Actual PCR values */
-       e = this->pcrs->create_enumerator(this->pcrs);
-       while (e->enumerate(e, &pcr_entry))
+       writer->write_uint32(writer, this->pcr_count * this->pcr_len);
+       for (i = 0; i < 8 * size_of_select; i++)
        {
-               writer->write_data(writer, chunk_create(pcr_entry->pcr_value, PCR_LEN));
+               if (this->pcrs[i])
+               {
+                       writer->write_data(writer, chunk_create(this->pcrs[i], this->pcr_len));
+               }
        }
-       free(pcr_entry);
-       e->destroy(e);
-
-       /* PCR Composite structure */
        pcr_composite = chunk_clone(writer->get_buf(writer));
        DBG3(DBG_PTS, "PCR Composite: %B", &pcr_composite);
+
        writer->destroy(writer);
 
        /* Output the TPM_PCR_COMPOSITE expected from IMC */
@@ -1171,21 +1221,18 @@ METHOD(pts_t, get_quote_info, bool,
                writer->write_uint16(writer, TPM_TAG_QUOTE_INFO2);
 
                /* Magic QUT2 value */
-               writer->write_uint8(writer, 'Q');
-               writer->write_uint8(writer, 'U');
-               writer->write_uint8(writer, 'T');
-               writer->write_uint8(writer, '2');
+               writer->write_data(writer, chunk_create("QUT2", 4));
 
                /* Secret assessment value 20 bytes (nonce) */
                writer->write_data(writer, this->secret);
 
-               /* Lenght of the bist mask field */
-               writer->write_uint16(writer, bitmask_len);
+               /* Length of the PCR selection field */
+               writer->write_uint16(writer, size_of_select);
 
-               /* PCR selection Bitmask */
-               for (i = 0; i< bitmask_len ; i++)
+               /* PCR selection */
+               for (i = 0; i < size_of_select ; i++)
                {
-                       writer->write_uint8(writer, mask_bytes[i]);
+                       writer->write_uint8(writer, this->pcr_select[i]);
                }
                
                /* TPM Locality Selection */
@@ -1203,16 +1250,10 @@ METHOD(pts_t, get_quote_info, bool,
        else
        {
                /* Version number */
-               writer->write_uint8(writer, 1);
-               writer->write_uint8(writer, 1);
-               writer->write_uint8(writer, 0);
-               writer->write_uint8(writer, 0);
+               writer->write_data(writer, chunk_from_chars(1, 1, 0, 0));
 
                /* Magic QUOT value */
-               writer->write_uint8(writer, 'Q');
-               writer->write_uint8(writer, 'U');
-               writer->write_uint8(writer, 'O');
-               writer->write_uint8(writer, 'T');
+               writer->write_data(writer, chunk_create("QUOT", 4));
 
                /* PCR Composite Hash */
                writer->write_data(writer, hash_pcr_composite);
@@ -1227,7 +1268,9 @@ METHOD(pts_t, get_quote_info, bool,
        /* TPM Quote Info */
        *out_quote_info = chunk_clone(writer->get_buf(writer));
        DBG3(DBG_PTS, "Calculated TPM Quote Info: %B", out_quote_info);
+
        writer->destroy(writer);
+       clear_pcrs(this);
 
        return TRUE;
 }
@@ -1267,9 +1310,9 @@ METHOD(pts_t, verify_quote_signature, bool,
 METHOD(pts_t, destroy, void,
        private_pts_t *this)
 {
+       clear_pcrs(this);
        DESTROY_IF(this->aik);
        DESTROY_IF(this->dh);
-       DESTROY_IF(this->pcrs);
        free(this->initiator_nonce.ptr);
        free(this->responder_nonce.ptr);
        free(this->secret.ptr);
@@ -1463,7 +1506,8 @@ pts_t *pts_create(bool is_imc)
                        .read_pcr = _read_pcr,
                        .extend_pcr = _extend_pcr,
                        .quote_tpm = _quote_tpm,
-                       .add_pcr_entry = _add_pcr_entry,
+                       .select_pcr = _select_pcr,
+                       .add_pcr = _add_pcr,
                        .get_quote_info = _get_quote_info,
                        .verify_quote_signature  = _verify_quote_signature,
                        .destroy = _destroy,
index 571c51d024704e8908038fc6f0787607af5118db..b5e77242847ec79090181751b37ee9ed53062138 100644 (file)
@@ -22,7 +22,6 @@
 #define PTS_H_
 
 typedef struct pts_t pts_t;
-typedef struct pcr_entry_t pcr_entry_t;
 
 #include "pts_error.h"
 #include "pts_proto_caps.h"
@@ -81,7 +80,7 @@ typedef struct pcr_entry_t pcr_entry_t;
 /**
  * Maximum number of PCR's of TPM, TPM Spec 1.2
  */
-#define MAX_NUM_PCR                            24
+#define PCR_MAX_NUM                            24
 
 /**
  * Number of bytes that can be saved in a PCR of TPM, TPM Spec 1.2
@@ -98,14 +97,6 @@ typedef struct pcr_entry_t pcr_entry_t;
  */
 #define TRUSTED_HASH_ALGO              PTS_MEAS_ALGO_SHA1
 
-/**
- * PCR Entry structure which contains PCR number and current value
- */
-struct pcr_entry_t {
-       u_int32_t pcr_number;
-       char pcr_value[PCR_LEN];
-};
-
 /**
  * Class implementing the TCG Platform Trust Service (PTS)
  *
@@ -331,23 +322,32 @@ struct pts_t {
         * Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
         *
         * @param use_quote2            Version of the Quote funtion to be used
-        * @param pcrs                          Array of PCR's to make quotation over
-        * @param num_of_pcrs           Number of elements in pcrs array
         * @param pcr_composite         Chunk to save pcr composite structure
         * @param quote_signature       Chunk to save quote operation output
         *                                                      without external data (anti-replay protection)
         * @return                                      FALSE in case of TSS error, TRUE otherwise
         */
-        bool (*quote_tpm)(pts_t *this, bool use_quote2,
-                                          u_int32_t *pcrs, u_int32_t num_of_pcrs,
-                                          chunk_t *pcr_composite, chunk_t *quote_signature);
+        bool (*quote_tpm)(pts_t *this, bool use_quote2, chunk_t *pcr_composite,
+                                          chunk_t *quote_signature);
 
         /**
-        * Add extended PCR with its corresponding value
+        * Mark an extended PCR as selected
         *
-        * @return                      FALSE in case of any error or non-match, TRUE otherwise
+        * @param pcr                           Number of the extended PCR
+        * @return                                      TRUE if PCR number is valid
         */
-        void (*add_pcr_entry)(pts_t *this, pcr_entry_t *entry);
+        bool (*select_pcr)(pts_t *this, u_int32_t pcr);
+
+        /**
+        * Add an extended PCR with its corresponding value
+        *
+        * @param pcr                           Number of the extended PCR
+        * @param pcr_before            PCR value before extension
+        * @param pcr_after                     PCR value after extension
+        * @return                                      TRUE if PCR number and register length is valid
+        */
+       bool (*add_pcr)(pts_t *this, u_int32_t pcr, chunk_t pcr_before,
+                                                                                                chunk_t pcr_after);
 
         /**
         * Constructs and returns TPM Quote Info structure expected from IMC