]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Implemented TPM_Quote2 on imc and constructing TPM_Quote_Info2 on imv
authorSansar Choinyambuu <schoinya@hsr.ch>
Fri, 11 Nov 2011 10:19:46 +0000 (11:19 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 20:20:23 +0000 (21:20 +0100)
src/libimcv/plugins/imc_attestation/imc_attestation_process.c
src/libimcv/plugins/imv_attestation/imv_attestation_process.c
src/libpts/pts/pts.c
src/libpts/pts/pts.h

index f91d8d8f5ccf98f936f9ae26f41391e96e96e005..8ff68e1e5f2689548eac0d28903e3e90e117ad87 100644 (file)
@@ -60,7 +60,7 @@ static u_int8_t* string_to_bytearray(char *str_value)
        for (i = 0; i < strlen(str_value)/2; i++)
        {
                char c1, c2;
-               u_int8_t d1, d2;
+               u_int8_t d1 = 0, d2 = 0;
 
                c1 = str_value[i*2];
                c2 = str_value[i*2 + 1];
@@ -547,6 +547,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        chunk_t pcr_composite, quote_signature;
                        u_int32_t num_of_evidences, i = 0;
                        u_int32_t *pcrs;
+                       bool use_quote2;
 
                        /* Send buffered Simple Component Evidences */
                        num_of_evidences = evidences->get_count(evidences);
@@ -568,9 +569,13 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                /* Send Simple Compoenent Evidence */
                                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;
                        
                        /* Quote */
-                       if (!pts->quote_tpm(pts, pcrs, num_of_evidences,
+                       if (!pts->quote_tpm(pts, use_quote2, pcrs, num_of_evidences,
                                &pcr_composite, &quote_signature))
                        {
                                DBG1(DBG_IMC, "error occured during TPM quote operation");
@@ -580,7 +585,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        }
        
                        /* Send Simple Evidence Final attribute */
-                       flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
+                       flags = use_quote2 ? PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2:
+                                                                PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
                        composite_algorithm |= PTS_MEAS_ALGO_SHA1;
                        
                        attr = tcg_pts_attr_simple_evid_final_create(FALSE, flags,
index 5e6f8bc8de3f85caea3645481ebe7a5edf4133f1..5c9cb987db4933355f56164382f257c38cb1b46e 100644 (file)
@@ -281,7 +281,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        chunk_t pcr_comp;
                        chunk_t tpm_quote_sign;
                        chunk_t evid_sign;
-                       bool evid_signature_included;
+                       bool evid_signature_included = FALSE, use_quote2 = FALSE,
+                                                                                               ver_info_included = FALSE;
+                       chunk_t pcr_composite, quote_info;
                        
                        attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
                        evid_signature_included = attr_cast->is_evid_sign_included(attr_cast);
@@ -293,16 +295,18 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                         */
                        composite_algorithm = attr_cast->get_comp_hash_algorithm(attr_cast);
 
-                       if ((flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2) ||
-                               (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER))
+                       if (flags != PTS_SIMPLE_EVID_FINAL_FLAG_NO)
                        {
-                               DBG1(DBG_IMV, "This version of Attestation IMV can not handle"
-                                        " TPM Quote Info2 structure");
-                               break;
-                       }
-                       if (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO)
-                       {
-                               chunk_t pcr_composite, quote_info;
+                               if ((flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2) ||
+                                       (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER))
+                               {
+                                       use_quote2 = TRUE;
+                               }
+                               if (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER)
+                               {
+                                       ver_info_included = TRUE;
+                               }
+
                                pcr_comp = attr_cast->get_pcr_comp(attr_cast);
                                tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast);
 
@@ -313,15 +317,15 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        DBG1(DBG_IMV, "Either PCR Composite or Quote Signature missing");
                                        return FALSE;
                                }
-                               
-                               /* Construct PCR Composite and TPM Quote Info structures*/
-                               if (!pts->get_quote_info(pts, composite_algorithm,
-                                       &pcr_composite, &quote_info))
+
+                               /* Construct PCR Composite and TPM Quote Info structures */
+                               if (!pts->get_quote_info(pts, use_quote2, ver_info_included,
+                                       composite_algorithm, &pcr_composite, &quote_info))
                                {
                                        DBG1(DBG_IMV, "unable to contruct TPM Quote Info");
                                        return FALSE;
                                }
-                               
+
                                /* Check calculated PCR composite matches with received */
                                if (!chunk_equals(pcr_comp, pcr_composite))
                                {
@@ -333,18 +337,18 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                }
                                DBG2(DBG_IMV, "received PCR Composite matches with constructed");
                                chunk_clear(&pcr_composite);
-                                                               
+
                                if (!pts->verify_quote_signature(pts, quote_info, tpm_quote_sign))
                                {
                                        chunk_clear(&quote_info);
                                        return FALSE;
                                }
-                               
+
                                DBG2(DBG_IMV, "signature verification succeeded for "
                                                          "TPM Quote Info");
                                chunk_clear(&quote_info);
                        }
-                       
+
                        if (evid_signature_included)
                        {
                                /** TODO: What to do with Evidence Signature */
index 504ef08b2a8b1e766869987ae78c9e8e3c7050d3..178ba64019ebea9fe0ae0dc66a9159154638e944 100644 (file)
@@ -792,7 +792,8 @@ METHOD(pts_t, extend_pcr, bool,
 }
 
 METHOD(pts_t, quote_tpm, bool,
-       private_pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
+       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)
 {
        TSS_HCONTEXT hContext;
@@ -804,9 +805,10 @@ METHOD(pts_t, quote_tpm, bool,
        BYTE secret[] = TSS_WELL_KNOWN_SECRET;
        TSS_HPCRS hPcrComposite;
        TSS_VALIDATION valData;
-       u_int32_t i;
+       u_int32_t i, versionInfoSize;
        TSS_RESULT result;
        chunk_t pcr_comp, quote_sign;
+       BYTE* versionInfo;
 
        result = Tspi_Context_Create(&hContext);
        if (result != TSS_SUCCESS)
@@ -854,8 +856,11 @@ METHOD(pts_t, quote_tpm, bool,
        }
 
        /* Create PCR composite object */
-       result = Tspi_Context_CreateObject(hContext,
-                                                                          TSS_OBJECT_TYPE_PCRS, 0, &hPcrComposite);
+       result = use_quote2 ?
+                       Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
+                                                       TSS_PCRS_STRUCT_INFO_SHORT, &hPcrComposite) :
+                       Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
+                                                       0, &hPcrComposite);
        if (result != TSS_SUCCESS)
        {
                goto err2;
@@ -869,7 +874,10 @@ METHOD(pts_t, quote_tpm, bool,
                        DBG1(DBG_PTS, "Invalid PCR number: %d", pcrs[i]);
                        goto err3;
                }
-               result = Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcrs[i]);
+               result = use_quote2 ?
+                               Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcrs[i],
+                                                                                                  TSS_PCRS_DIRECTION_RELEASE):
+                               Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcrs[i]);
                if (result != TSS_SUCCESS)
                {
                        goto err3;
@@ -882,7 +890,10 @@ METHOD(pts_t, quote_tpm, bool,
 
 
        /* TPM Quote */
-       result = Tspi_TPM_Quote(hTPM, hAIK, hPcrComposite, &valData);
+       result = use_quote2 ?
+                       Tspi_TPM_Quote2(hTPM, hAIK, FALSE, hPcrComposite, &valData,
+                                                       &versionInfoSize,&versionInfo):
+                       Tspi_TPM_Quote(hTPM, hAIK, hPcrComposite, &valData);
        if (result != TSS_SUCCESS)
        {
                goto err4;
@@ -890,7 +901,18 @@ METHOD(pts_t, quote_tpm, bool,
 
        /* Set output chunks */
        pcr_comp = chunk_alloc(HASH_SIZE_SHA1);
-       memcpy(pcr_comp.ptr, valData.rgbData + 8, HASH_SIZE_SHA1);
+       if (use_quote2)
+       {
+               /* TPM_Composite_Hash is last 20 bytes of TPM_Quote_Info2 structure */
+               memcpy(pcr_comp.ptr, valData.rgbData + valData.ulDataLength - HASH_SIZE_SHA1,
+                          HASH_SIZE_SHA1);
+       }
+       else
+       {
+               /* TPM_Composite_Hash is 8-28th bytes of TPM_Quote_Info structure */
+               memcpy(pcr_comp.ptr, valData.rgbData + 8, HASH_SIZE_SHA1);
+       }
+       
        *pcr_composite = pcr_comp;
        *pcr_composite = chunk_clone(*pcr_composite);
        DBG3(DBG_PTS, "Hash of PCR Composite: %B",pcr_composite);
@@ -903,7 +925,7 @@ METHOD(pts_t, quote_tpm, bool,
                                                          valData.ulValidationDataLength);
        *quote_signature = quote_sign;
        *quote_signature = chunk_clone(*quote_signature);
-       DBG3(DBG_PTS, "TOM Quote Signature: %B",quote_signature);
+       DBG3(DBG_PTS, "TPM Quote Signature: %B",quote_signature);
 
        chunk_clear(&quote_sign);
        Tspi_Context_FreeMemory(hContext, NULL);
@@ -1012,33 +1034,22 @@ METHOD(pts_t, does_pcr_value_match, bool,
 }
 
 /**
- * 1. build a TCPA_PCR_COMPOSITE structure which contains (pcrCompositeBuf)
- * TCPA_PCR_SELECTION structure (bitmask length + bitmask)
- * UINT32 (network order) gives the number of bytes following (pcr entries * 20)
- * TCPA_PCRVALUE[] with the pcr values
- *
- * The first two bytes of the message represent the length
- * of the bitmask that follows. The bitmask represents the
- * requested PCRs to be quoted.
- *
- * TPM Main-Part 2 TPM Structures_v1.2 8.1
- * The bitmask is in big endian order"
- *
- *        BYTE 1             BYTE 2                   ...
- * Bit:   1 1 1 1 0 0 0 0    1  1  1  1  0  0  0 0    ...
- * Pcr:   7 6 5 4 3 2 1 0    15 14 13 12 11 10 9 8    ...
- *
- * 2. SHA1(pcrCompositeBuf)
- *
- * 3. build a TCPA_QUOTE_INFO structure which contains
+ * TPM_QUOTE_INFO structure:
  *     4 bytes of version
  *     4 bytes 'Q' 'U' 'O' 'T'
  *     20 byte SHA1 of TCPA_PCR_COMPOSITE
  *     20 byte nonce
+ *
+ * TPM_QUOTE_INFO2 structure:
+ * 2 bytes Tag 0x0036 TPM_Tag_Quote_info2
+ * 4 bytes 'Q' 'U' 'T' '2'
+ * 20 bytes nonce
+ * 26 bytes PCR_INFO_SHORT
  */
 
 METHOD(pts_t, get_quote_info, bool,
-       private_pts_t *this, pts_meas_algorithms_t composite_algo,
+       private_pts_t *this, bool use_quote2, bool ver_info_included,
+       pts_meas_algorithms_t composite_algo,
        chunk_t *out_pcr_composite, chunk_t *out_quote_info)
 {
        enumerator_t *e;
@@ -1055,6 +1066,18 @@ METHOD(pts_t, get_quote_info, bool,
                                          "TPM Quote Info");
                return FALSE;
        }
+       if (!this->secret.ptr)
+       {
+               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");
+               return FALSE;
+       }
        
        bitmask_len = maximum_pcr_index/8 +1;
        u_int8_t mask_bytes[MAX_NUM_PCR/8] = {0};
@@ -1095,19 +1118,6 @@ METHOD(pts_t, get_quote_info, bool,
        DBG3(DBG_PTS, "PCR Composite: %B", &pcr_composite);
        writer->destroy(writer);
 
-       writer = bio_writer_create(TPM_QUOTE_INFO_LEN);
-       /* Version number */
-       writer->write_uint8(writer, 1);
-       writer->write_uint8(writer, 1);
-       writer->write_uint8(writer, 0);
-       writer->write_uint8(writer, 0);
-
-       /* Magic QUOT value, depends on TPM Ordinal */
-       writer->write_uint8(writer, 'Q');
-       writer->write_uint8(writer, 'U');
-       writer->write_uint8(writer, 'O');
-       writer->write_uint8(writer, 'T');
-
        /* Output the TPM_PCR_COMPOSITE expected from IMC */
        if (composite_algo)
        {
@@ -1152,20 +1162,68 @@ METHOD(pts_t, get_quote_info, bool,
        hasher->allocate_hash(hasher, pcr_composite, &hash_pcr_composite);
        hasher->destroy(hasher);
 
-       writer->write_data(writer, hash_pcr_composite);
-       chunk_clear(&pcr_composite);
-       chunk_clear(&hash_pcr_composite);
+       /* Construct TPM_QUOTE_INFO/TPM_QUOTE_INFO2 structure */
+       writer = bio_writer_create(TPM_QUOTE_INFO_LEN);
 
-       if (!this->secret.ptr)
+       if (use_quote2)
        {
-               DBG1(DBG_PTS, "Secret assessment value unavailable",
-                        "unable to construct TPM Quote Info");
-               chunk_clear(out_pcr_composite);
-               writer->destroy(writer);
-               return FALSE;
+               /* TPM Structure Tag */
+               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');
+
+               /* Secret assessment value 20 bytes (nonce) */
+               writer->write_data(writer, this->secret);
+
+               /* Lenght of the bist mask field */
+               writer->write_uint16(writer, bitmask_len);
+
+               /* PCR selection Bitmask */
+               for (i = 0; i< bitmask_len ; i++)
+               {
+                       writer->write_uint8(writer, mask_bytes[i]);
+               }
+               
+               /* TPM Locality Selection */
+               writer->write_uint8(writer, TPM_LOC_ZERO);
+
+               /* PCR Composite Hash */
+               writer->write_data(writer, hash_pcr_composite);
+
+               if (ver_info_included)
+               {
+                       /* TPM version Info */
+                       writer->write_data(writer, this->tpm_version_info);
+               }
+       }
+       else
+       {
+               /* Version number */
+               writer->write_uint8(writer, 1);
+               writer->write_uint8(writer, 1);
+               writer->write_uint8(writer, 0);
+               writer->write_uint8(writer, 0);
+
+               /* Magic QUOT value */
+               writer->write_uint8(writer, 'Q');
+               writer->write_uint8(writer, 'U');
+               writer->write_uint8(writer, 'O');
+               writer->write_uint8(writer, 'T');
+
+               /* PCR Composite Hash */
+               writer->write_data(writer, hash_pcr_composite);
+
+               /* Secret assessment value 20 bytes (nonce) */
+               writer->write_data(writer, this->secret);
        }
-       /* Secret assessment value 20 bytes (nonce) */
-       writer->write_data(writer, this->secret);
+       
+       chunk_clear(&pcr_composite);
+       chunk_clear(&hash_pcr_composite);
+
        /* TPM Quote Info */
        *out_quote_info = chunk_clone(writer->get_buf(writer));
        DBG3(DBG_PTS, "Calculated TPM Quote Info: %B", out_quote_info);
index b92bbdc209094af8c79401278be1f177b0f4f776..b3298b0e4ec4ad6ad3455773510d262ee238e760 100644 (file)
@@ -317,6 +317,7 @@ struct pts_t {
         * Quote over PCR's
         * 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
@@ -324,7 +325,8 @@ struct pts_t {
         *                                                      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, bool use_quote2,
+                                          u_int32_t *pcrs, u_int32_t num_of_pcrs,
                                           chunk_t *pcr_composite, chunk_t *quote_signature);
 
         /**
@@ -337,11 +339,14 @@ struct pts_t {
         /**
         * Constructs and returns TPM Quote Info structure expected from IMC
         *
-        * @param pcr_composite                 Output variable to store PCR Composite
-        * @param quote_info                    Output variable to store TPM Quote Info
+        * @param use_quote2            Version of the TPM_QUOTE_INFO to be constructed
+        * @param ver_info_included Version info is concatenated to TPM_QUOTE_INFO2
+        * @param pcr_composite         Output variable to store PCR Composite
+        * @param quote_info            Output variable to store TPM Quote Info
         * @return                                      FALSE in case of any error, TRUE otherwise
         */
-        bool (*get_quote_info)(pts_t *this, pts_meas_algorithms_t composite_algo,
+        bool (*get_quote_info)(pts_t *this, bool use_quote2, bool ver_info_included,
+                                                       pts_meas_algorithms_t composite_algo,
                                                        chunk_t *pcr_composite, chunk_t *quote_info);
 
         /**