Improved implementation of Read PCR/ Extend PCR/ Quote_TPM functions
authorSansar Choinyambuu <schoinya@hsr.ch>
Fri, 7 Oct 2011 13:15:56 +0000 (15:15 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 13:34:21 +0000 (14:34 +0100)
Implemented creating/handling of Simple Evidence Final attribute (incomplete)

src/libimcv/plugins/imc_attestation/imc_attestation.c
src/libimcv/plugins/imv_attestation/imv_attestation.c
src/libpts/pts/pts.c
src/libpts/pts/pts.h

index 1e0f360..0ed43e8 100644 (file)
@@ -409,7 +409,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        selected_dh_group = pts->get_dh_group(pts);
                                        if (!pts->create_dh(pts, selected_dh_group))
                                        {
-                                               return TNC_RESULT_FATAL;
+                                               goto err;
                                        }
                                        pts->get_my_pub_val(pts, &responder_pub_val);
 
@@ -450,7 +450,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        if (!pts->calculate_secret(pts, initiator_nonce,
                                                                                responder_non, selected_algorithm))
                                        {
-                                               return TNC_RESULT_FATAL;
+                                               goto err;
                                        }
 
                                        break;
@@ -672,13 +672,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                        {
                                                                DBG1(DBG_IMC, "  hasher %N not available",
                                                                         hash_algorithm_names, hash_alg);
-                                                               return TNC_RESULT_FATAL;
+                                                               goto err;
                                                        }
 
                                                        if (!pts->hash_file(pts, hasher, "/etc/tnc_config", hash_output))
                                                        {
                                                                hasher->destroy(hasher);
-                                                               return TNC_RESULT_FATAL;
+                                                               goto err;
                                                        }
                                                        
                                                        measurement_time_t = time(NULL);
@@ -698,9 +698,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                                                                                time_now->tm_sec) < 0)
                                                                {
                                                                        DBG1(DBG_IMC, "Couldn not format local time to UTC");
-                                                                       return TNC_RESULT_FATAL;
+                                                                       hasher->destroy(hasher);
+                                                                       goto err;
                                                                }
                                                                params.measurement_time = chunk_create(utc_time, 20);
+                                                               params.measurement_time = chunk_clone(params.measurement_time);
+                                                               free(utc_time);
+                                                               
                                                        }
                                                        
                                                        params.measurement = chunk_create(hash_output, hasher->get_hash_size(hasher));
@@ -710,13 +714,14 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                        if (!pts->read_pcr(pts, EXTEND_PCR, &params.pcr_before))
                                                        {
                                                                DBG1(DBG_IMC, "Error occured while reading PCR: %d", EXTEND_PCR);
-                                                               return TNC_RESULT_FATAL;
+                                                               goto err;
                                                        }
+                                                       
                                                        if (!pts->extend_pcr(pts, EXTEND_PCR,
                                                                params.measurement, &params.pcr_after))
                                                        {
                                                                DBG1(DBG_IMC, "Error occured while extending PCR: %d", EXTEND_PCR);
-                                                               return TNC_RESULT_FATAL;
+                                                               goto err;
                                                        }
 
                                                        /* Buffer Simple Component Evidence attribute */
@@ -744,22 +749,47 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                {
                                        enumerator_t *e;
                                        pts_simple_evid_final_flag_t flags;
-
+                                       chunk_t pcr_composite, quote_signature;
+                                       linked_list_t *pcrs;
+                                       
                                        /* Send buffered Simple Component Evidences */
+                                       pcrs = linked_list_create();
+                                       
                                        e = evidences->create_enumerator(evidences);
                                        while (e->enumerate(e, &attr))
                                        {
+                                               tcg_pts_attr_simple_comp_evid_t *attr_cast;
+                                               u_int32_t extended_pcr;
+                                               
+                                               attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
+                                               extended_pcr = attr_cast->get_extended_pcr(attr_cast);
+                                               
+                                               /* Add extended PCR number to PCR list to quote */
+                                               /* Duplicated PCR numbers have no influence */
+                                               pcrs->insert_last(pcrs, &extended_pcr);
+                                               /* Send Simple Compoenent Evidence */
                                                attr_list->insert_last(attr_list, attr);
                                        }
 
-                                       /* TODO: TPM quote operation over included PCR's */
+                                       /* Quote */
+                                       if (!pts->quote_tpm(pts, pcrs, &pcr_composite, &quote_signature))
+                                       {
+                                               DBG1(DBG_IMC, "Error occured while TPM quote operation");
+                                               DESTROY_IF(e);
+                                               DESTROY_IF(pcrs);
+                                               DESTROY_IF(evidences);
+                                               goto err;
+                                       }
+                                       
                                        /* Send Simple Evidence Final attribute */
-                                       flags = PTS_SIMPLE_EVID_FINAL_FLAG_NO;
+                                       flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
+                                       
                                        attr = tcg_pts_attr_simple_evid_final_create(flags, 0,
-                                                                               chunk_empty, chunk_empty, chunk_empty);
+                                                                               pcr_composite, quote_signature, chunk_empty);
                                        attr_list->insert_last(attr_list, attr);
                                        
-                                       e->destroy(e);
+                                       DESTROY_IF(e);
+                                       DESTROY_IF(pcrs);
                                        DESTROY_IF(evidences);
                                        
                                        break;
@@ -806,7 +836,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        if (!metadata)
                                        {
                                                /* TODO handle error codes from measurements */
-                                               return TNC_RESULT_FATAL;
+                                               goto err;
                                        }
                                        attr = tcg_pts_attr_unix_file_meta_create(metadata);
                                        attr->set_noskip_flag(attr, TRUE);
@@ -862,7 +892,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        if (!measurements)
                                        {
                                                /* TODO handle error codes from measurements */
-                                               return TNC_RESULT_FATAL;
+                                               goto err;
                                        }
                                        attr = tcg_pts_attr_file_meas_create(measurements);
                                        attr->set_noskip_flag(attr, TRUE);
@@ -918,9 +948,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                        pa_tnc_msg->get_encoding(pa_tnc_msg));
                pa_tnc_msg->destroy(pa_tnc_msg);
        }
-       attr_list->destroy(attr_list);
 
+       DESTROY_IF(attr_list);
        return result;
+
+       err:
+       DESTROY_IF(attr_list);
+       return TNC_RESULT_FATAL;
 }
 
 /**
index bdf37ab..719f849 100644 (file)
@@ -750,9 +750,31 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
 
                                case TCG_PTS_SIMPLE_EVID_FINAL:
                                {
-                                       /** TODO: Implement construct Quote structure over saved values from
-                                        * TCG_PTS_SIMPLE_COMP_EVID and compare with received one
+                                       tcg_pts_attr_simple_evid_final_t *attr_cast;
+                                       pts_simple_evid_final_flag_t flags;
+                                       chunk_t pcr_comp = chunk_empty;
+                                       chunk_t tpm_quote_sign = chunk_empty;
+                                       chunk_t evid_sign = chunk_empty;
+                                       
+                                       /** TODO: Ignoring Composite Hash Algorithm field
+                                        * No flag defined which indicates the precense of it
                                         */
+                                       attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
+                                       flags = attr_cast->get_flags(attr_cast);
+
+                                       if ((flags >> 6) & PTS_SIMPLE_EVID_FINAL_FLAG_NO)
+                                       {
+                                               pcr_comp = attr_cast->get_pcr_comp(attr_cast);
+                                               tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast);
+                                               
+                                               /** TODO: Construct PCR Composite */
+                                       }
+                                       if (flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID)
+                                       {
+                                               /** TODO: What to do with Evidence Signature */
+                                               evid_sign = attr_cast->get_evid_sign(attr_cast);
+                                       }
+
                                        break;
                                }
 
index 14271f6..d661308 100644 (file)
@@ -650,6 +650,7 @@ METHOD(pts_t, read_pcr, bool,
        {
                goto err;
        }
+       pcr_value = chunk_alloc(PCR_LEN);
        result = Tspi_TPM_PcrRead(hTPM, pcr_num, &pcr_length, &pcr_value.ptr);
        if (result != TSS_SUCCESS)
        {
@@ -659,11 +660,13 @@ METHOD(pts_t, read_pcr, bool,
        *output = pcr_value;
        *output = chunk_clone(*output);
 
+       chunk_clear(&pcr_value);
        Tspi_Context_Close(hContext);
        DBG3(DBG_PTS, "PCR %d value:%B", pcr_num, output);
        return TRUE;
 
        err:
+       chunk_clear(&pcr_value);
        DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
        Tspi_Context_Close(hContext);
        return FALSE;
@@ -694,7 +697,10 @@ METHOD(pts_t, extend_pcr, bool,
        {
                goto err;
        }
-       result = Tspi_TPM_PcrExtend(hTPM, pcr_num, 20, input.ptr, NULL, &pcr_length, &pcr_value.ptr);
+
+       pcr_value = chunk_alloc(PCR_LEN);
+       result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PCR_LEN, input.ptr,
+                                                               NULL, &pcr_length, &pcr_value.ptr);
        if (result != TSS_SUCCESS)
        {
                goto err;
@@ -703,20 +709,21 @@ METHOD(pts_t, extend_pcr, bool,
        *output = pcr_value;
        *output = chunk_clone(*output);
 
+       chunk_clear(&pcr_value);
        Tspi_Context_Close(hContext);
        DBG3(DBG_PTS, "PCR %d extended with:      %B", pcr_num, &input);
        DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output);
-       
        return TRUE;
 
        err:
+       chunk_clear(&pcr_value);
        DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
        Tspi_Context_Close(hContext);
        return FALSE;
 }
 
 METHOD(pts_t, quote_tpm, bool,
-          private_pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
+          private_pts_t *this, linked_list_t *pcrs,
           chunk_t *pcr_composite, chunk_t *quote_signature)
 {
        TSS_HCONTEXT hContext;
@@ -729,10 +736,11 @@ METHOD(pts_t, quote_tpm, bool,
        TSS_HPCRS hPcrComposite;
        TSS_VALIDATION valData;
        TPM_QUOTE_INFO *quoteInfo;
-       u_int32_t i;
+       u_int32_t i, pcr;
        TSS_RESULT result;
        chunk_t aik_key_encoding;
        chunk_t pcr_composite_without_nonce;
+       enumerator_t *enumerator;
 
        result = Tspi_Context_Create(&hContext);
        if (result != TSS_SUCCESS)
@@ -774,7 +782,7 @@ METHOD(pts_t, quote_tpm, bool,
        /* Create from AIK public key a HKEY object to sign Quote operation output*/
        if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY)
        {
-               if (!this->aik->get_encoding(this->aik, CERT_ASN1_DER, &aik_key_encoding))
+               if (!this->aik->get_encoding(this->aik, CERT_PEM, &aik_key_encoding))
                {
                        DBG1(DBG_PTS, "encoding AIK certificate for quote operation failed");
                        goto err1;
@@ -789,7 +797,7 @@ METHOD(pts_t, quote_tpm, bool,
                        DBG1(DBG_PTS, "unable to retrieve public key from AIK certificate");
                        goto err1;
                }
-               if (!key->get_encoding(key, PUBKEY_ASN1_DER, &aik_key_encoding))
+               if (!key->get_encoding(key, PUBKEY_PEM, &aik_key_encoding))
                {
                        DBG1(DBG_PTS, "encoding AIK Public Key for quote operation failed");
                        goto err1;
@@ -816,9 +824,9 @@ METHOD(pts_t, quote_tpm, bool,
        }
 
        /* Select PCR's */
-       for (i = 0; i < num_of_pcrs; i++)
+       enumerator = pcrs->create_enumerator(pcrs);
+       while (enumerator->enumerate(enumerator, &pcr))
        {
-               u_int32_t pcr = pcrs[i];
                if (pcr < 0 || pcr >= MAX_NUM_PCR )
                {
                        DBG1(DBG_PTS, "Invalid PCR number: %d", pcr);
@@ -830,6 +838,7 @@ METHOD(pts_t, quote_tpm, bool,
                        goto err3;
                }
        }
+       enumerator->destroy(enumerator);
 
        /* Set the Validation Data */
        valData.ulExternalDataLength = this->secret.len;
@@ -872,6 +881,9 @@ METHOD(pts_t, quote_tpm, bool,
        memcpy(pcr_composite_without_nonce.ptr, valData.rgbData,
                   valData.ulDataLength - ASSESSMENT_SECRET_LEN);
        *pcr_composite = pcr_composite_without_nonce;
+       *pcr_composite = chunk_clone(*pcr_composite);
+       free(pcr_composite_without_nonce.ptr);
+       
        *quote_signature = chunk_from_thing(valData.rgbValidationData);
        *quote_signature = chunk_clone(*quote_signature);
        
index efc7271..d0c03ee 100644 (file)
@@ -31,6 +31,7 @@ typedef struct pts_t pts_t;
 #include "pts_dh_group.h"
 
 #include <library.h>
+#include <utils/linked_list.h>
 
 /**
  * UTF-8 encoding of the character used to delimiter the filename
@@ -54,6 +55,11 @@ typedef struct pts_t pts_t;
 #define MAX_NUM_PCR                            24
 
 /**
+ * Number of bytes can be savedin a PCR of TPM, TPM Spec 1.2
+ */
+#define PCR_LEN                                        20
+
+/**
  * Class implementing the TCG Platform Trust System (PTS)
  *
  */
@@ -249,14 +255,13 @@ struct pts_t {
         * Quote over PCR's
         * Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
         *
-        * @param pcrs                                  Set of PCR's to make quotation over
-        * @param num_of_pcr                    Number of PCR's
+        * @param pcrs                                  List of PCR's to make quotation over
         * @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, u_int32_t *pcrs, u_int32_t num_of_pcrs,
+        bool (*quote_tpm)(pts_t *this, linked_list_t *pcrs,
                                           chunk_t *pcr_composite, chunk_t *quote_signature);
 
        /**