]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Refactoring to tpm_tss_quote_info object
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 20 Jun 2016 08:47:27 +0000 (10:47 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 26 Jun 2016 16:19:05 +0000 (18:19 +0200)
24 files changed:
src/libimcv/Makefile.am
src/libimcv/plugins/imc_attestation/Makefile.am
src/libimcv/plugins/imc_attestation/imc_attestation_process.c
src/libimcv/plugins/imv_attestation/Makefile.am
src/libimcv/plugins/imv_attestation/imv_attestation_process.c
src/libimcv/plugins/imv_hcd/Makefile.am
src/libimcv/plugins/imv_os/Makefile.am
src/libimcv/plugins/imv_scanner/Makefile.am
src/libimcv/plugins/imv_swid/Makefile.am
src/libimcv/pts/pts.c
src/libimcv/pts/pts.h
src/libimcv/pts/pts_meas_algo.c
src/libimcv/pts/pts_meas_algo.h
src/libimcv/pts/pts_pcr.c
src/libimcv/pts/pts_pcr.h
src/libimcv/pts/pts_simple_evid_final.h [deleted file]
src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.c
src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.h
src/libtpmtss/Makefile.am
src/libtpmtss/tpm_tss.h
src/libtpmtss/tpm_tss_quote_info.c [new file with mode: 0644]
src/libtpmtss/tpm_tss_quote_info.h [new file with mode: 0644]
src/libtpmtss/tpm_tss_trousers.c
src/libtpmtss/tpm_tss_tss2.c

index 90993adb1be172860a1d53fb92cfd795ef69d696..8cde4b7fce5246d9847f05e35ba575f45b684607 100644 (file)
@@ -64,7 +64,6 @@ libimcv_la_SOURCES = \
        pts/pts_pcr.h pts/pts_pcr.c \
        pts/pts_proto_caps.h \
        pts/pts_req_func_comp_evid.h \
-       pts/pts_simple_evid_final.h \
        pts/pts_creds.h pts/pts_creds.c \
        pts/pts_database.h pts/pts_database.c \
        pts/pts_dh_group.h pts/pts_dh_group.c \
@@ -205,5 +204,6 @@ imcv_tests_CFLAGS = \
 imcv_tests_LDFLAGS = @COVERAGE_LDFLAGS@
 imcv_tests_LDADD = \
        $(top_builddir)/src/libimcv/libimcv.la \
+       $(top_builddir)/src/libtpmtss/libtpmtss.la \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
        $(top_builddir)/src/libstrongswan/tests/libtest.la
index e7b1f1ce13c43c7b2e56c50f545663889ce66ede..14b1646e5e06e1243ff93ea6ea866d3a59046fe4 100644 (file)
@@ -1,7 +1,8 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
-       -I$(top_srcdir)/src/libimcv
+       -I$(top_srcdir)/src/libimcv \
+       -I$(top_srcdir)/src/libtpmtss 
 
 AM_CFLAGS = \
        $(PLUGIN_CFLAGS)
index a877211973e117bf7e298a4ebeb7e4046c7c376d..56713bb0436917c79cd054a37f49900af11962d7 100644 (file)
@@ -421,10 +421,10 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
                }
                case TCG_PTS_GEN_ATTEST_EVID:
                {
-                       pts_simple_evid_final_flag_t flags;
-                       pts_meas_algorithms_t comp_hash_algorithm;
                        pts_comp_evidence_t *evid;
-                       chunk_t pcr_composite, quote_sig;
+                       tpm_quote_mode_t quote_mode;
+                       tpm_tss_quote_info_t *quote_info;
+                       chunk_t quote_sig;
                        bool use_quote2, use_version_info;
 
                        /* Send cached Component Evidence entries */
@@ -440,22 +440,18 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
                        use_version_info = lib->settings->get_bool(lib->settings,
                                                        "%s.plugins.imc-attestation.use_version_info",
                                                        FALSE, lib->ns);
-                       if (!pts->quote_tpm(pts, use_quote2, use_version_info,
-                                                               &pcr_composite, &quote_sig))
+                       quote_mode = use_quote2 ? (use_version_info ?
+                                                                         TPM_QUOTE2_VERSION_INFO :
+                                                                         TPM_QUOTE2) :
+                                                                         TPM_QUOTE;
+
+                       if (!pts->quote(pts, &quote_mode, &quote_info, &quote_sig))
                        {
                                DBG1(DBG_IMC, "error occurred during TPM quote operation");
                                return FALSE;
                        }
 
-                       /* Send Simple Evidence Final attribute */
-                       flags = use_quote2 ? (use_version_info ?
-                                                                PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER :
-                                                                PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2) :
-                                                                PTS_SIMPLE_EVID_FINAL_QUOTE_INFO;
-                       comp_hash_algorithm = PTS_MEAS_ALGO_SHA1;
-
-                       attr = tcg_pts_attr_simple_evid_final_create(flags,
-                                                               comp_hash_algorithm, pcr_composite, quote_sig);
+                       attr = tcg_pts_attr_simple_evid_final_create(quote_info, quote_sig);
                        msg->add_attribute(msg, attr);
                        break;
                }
index 6c5bf891387fade676f567afb922d53a2c19255f..f353d30fc9e7082f9856b4b39c5cbfd32261e69b 100644 (file)
@@ -2,6 +2,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
        -I$(top_srcdir)/src/libimcv \
+       -I$(top_srcdir)/src/libtpmtss \
        -DPLUGINS=\""${attest_plugins}\""
 
 AM_CFLAGS = \
@@ -11,6 +12,7 @@ imcv_LTLIBRARIES = imv-attestation.la
 
 imv_attestation_la_LIBADD = \
        $(top_builddir)/src/libimcv/libimcv.la \
+       $(top_builddir)/src/libtpmtss/libtpmtss.la \
        $(top_builddir)/src/libstrongswan/libstrongswan.la
 
 imv_attestation_la_SOURCES = imv_attestation.c \
@@ -27,6 +29,7 @@ attest_SOURCES = attest.c \
        attest_db.h attest_db.c
 attest_LDADD = \
        $(top_builddir)/src/libimcv/libimcv.la \
+       $(top_builddir)/src/libtpmtss/libtpmtss.la \
        $(top_builddir)/src/libstrongswan/libstrongswan.la
 attest.o :     $(top_builddir)/config.status
 
index c3e053d9bbf653cb64182f1dfc9818354d5ac2fb..b1ee16bf808e7385ed14cf10d758495a6640a0c0 100644 (file)
@@ -418,45 +418,31 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                case TCG_PTS_SIMPLE_EVID_FINAL:
                {
                        tcg_pts_attr_simple_evid_final_t *attr_cast;
-                       uint8_t flags;
-                       pts_meas_algorithms_t comp_hash_algorithm;
-                       chunk_t pcr_comp, tpm_quote_sig, evid_sig;
-                       chunk_t pcr_composite, quote_info, result_buf;
+                       tpm_tss_quote_info_t *quote_info;
+                       chunk_t quoted = chunk_empty, quote_sig, evid_sig, result_buf;
                        imv_workitem_t *workitem;
                        imv_reason_string_t *reason_string;
+                       hash_algorithm_t digest_alg;
                        enumerator_t *enumerator;
-                       bool use_quote2, use_ver_info;
                        bio_writer_t *result;
 
                        attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
-                       flags = attr_cast->get_quote_info(attr_cast, &comp_hash_algorithm,
-                                                                                         &pcr_comp, &tpm_quote_sig);
+                       attr_cast->get_quote_info(attr_cast, &quote_info, &quote_sig);
 
-                       if (flags != PTS_SIMPLE_EVID_FINAL_NO)
+                       if (quote_info->get_quote_mode(quote_info) != TPM_QUOTE_NONE)
                        {
-                               use_quote2   = (flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 ||
-                                                           flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER);
-                               use_ver_info = (flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER);
-
                                /* Construct PCR Composite and TPM Quote Info structures */
-                               if (!pts->get_quote_info(pts, use_quote2, use_ver_info,
-                                               comp_hash_algorithm, &pcr_composite, &quote_info))
-                               {
-                                       DBG1(DBG_IMV, "unable to construct TPM Quote Info");
-                                       return FALSE;
-                               }
-
-                               if (!chunk_equals_const(pcr_comp, pcr_composite))
+                               if (!pts->get_quote(pts, quote_info, &quoted))
                                {
-                                       DBG1(DBG_IMV, "received PCR Composite does not match "
-                                                                 "constructed one");
+                                       DBG1(DBG_IMV, "unable to construct TPM Quote Info digest");
                                        attestation_state->set_measurement_error(attestation_state,
                                                                                IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL);
                                        goto quote_error;
                                }
-                               DBG2(DBG_IMV, "received PCR Composite matches constructed one");
+                               digest_alg = quote_info->get_pcr_digest_alg(quote_info);
 
-                               if (!pts->verify_quote_signature(pts, quote_info, tpm_quote_sig))
+                               if (!pts->verify_quote_signature(pts, digest_alg, quoted,
+                                                                                                quote_sig))
                                {
                                        attestation_state->set_measurement_error(attestation_state,
                                                                                IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL);
@@ -465,8 +451,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                                DBG2(DBG_IMV, "TPM Quote Info signature verification successful");
 
 quote_error:
-                               free(pcr_composite.ptr);
-                               free(quote_info.ptr);
+                               chunk_free(&quoted);
 
                                /**
                                 * Finalize any pending measurement registrations and check
index 28926d45eeb861ee1be2cf92048c676c7074d861..0dce300ef5957d455b315b067e551f3478924570 100644 (file)
@@ -1,6 +1,7 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
+       -I$(top_srcdir)/src/libtpmtss \
        -I$(top_srcdir)/src/libimcv
 
 AM_CFLAGS = \
index 3b3f793f1cbdc53d7ca7d204d3ceb870bb18e9de..f5bc9010c8f41e672a87f3fbca88639758e1baa3 100644 (file)
@@ -1,7 +1,8 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
-       -I$(top_srcdir)/src/libimcv
+       -I$(top_srcdir)/src/libimcv \
+       -I$(top_srcdir)/src/libtpmtss
 
 AM_CFLAGS = \
        $(PLUGIN_CFLAGS)
index 98814437eb7d8becd10cd9026037a5e70b50448f..3b3ee818faf1202bd00434be0210cde0224ba00c 100644 (file)
@@ -1,7 +1,8 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
-       -I$(top_srcdir)/src/libimcv
+       -I$(top_srcdir)/src/libimcv \
+       -I$(top_srcdir)/src/libtpmtss
 
 AM_CFLAGS = \
        $(PLUGIN_CFLAGS)
index 3a63b67d2a64a92e48d0cf13eb0548fd54bab663..73da84b55a4752a5e99e8305d9eb6a4707109911 100644 (file)
@@ -1,6 +1,7 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
        -I$(top_srcdir)/src/libtncif \
+       -I$(top_srcdir)/src/libtpmtss \
        -I$(top_srcdir)/src/libimcv
 
 AM_CFLAGS = \
index e21f2d51c3ad8c318eeddfe1f326d65d5f15f444..2ba949e401e8d258cf12b150c291dae2384f0254 100644 (file)
@@ -622,14 +622,13 @@ METHOD(pts_t, extend_pcr, bool,
        return TRUE;
 }
 
-METHOD(pts_t, quote_tpm, bool,
-       private_pts_t *this, bool use_quote2, bool use_version_info,
-       chunk_t *pcr_comp, chunk_t *quote_sig)
+METHOD(pts_t, quote, bool,
+       private_pts_t *this, tpm_quote_mode_t *quote_mode,
+       tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
 {
-       chunk_t pcr_value;
+       chunk_t pcr_value, pcr_computed;
        uint32_t pcr, pcr_sel = 0;
        enumerator_t *enumerator;
-       tpm_quote_mode_t quote_mode;
 
        /* select PCRs */
        DBG2(DBG_PTS, "PCR values hashed into PCR Composite:");
@@ -638,7 +637,9 @@ METHOD(pts_t, quote_tpm, bool,
        {
                if (this->tpm->read_pcr(this->tpm, pcr, &pcr_value, HASH_SHA1))
                {
-                       DBG2(DBG_PTS, "PCR %2d %#B", pcr, &pcr_value);
+                       pcr_computed = this->pcrs->get(this->pcrs, pcr);
+                       DBG2(DBG_PTS, "PCR %2d %#B  %s", pcr, &pcr_value,
+                                chunk_equals(pcr_value, pcr_computed) ? "ok" : "differs");
                        chunk_free(&pcr_value);
                };
 
@@ -647,36 +648,16 @@ METHOD(pts_t, quote_tpm, bool,
        }
        enumerator->destroy(enumerator);
 
-       quote_mode = use_quote2 ? (use_version_info ? TPM_QUOTE2_VERSION_INFO :
-                                                                                                 TPM_QUOTE2) : TPM_QUOTE;
-
        /* TPM Quote */
        return this->tpm->quote(this->tpm, this->aik_handle, pcr_sel, HASH_SHA1,
-                                                       this->secret, quote_mode, pcr_comp, quote_sig);
+                                                       this->secret, quote_mode, quote_info, quote_sig);
 }
 
-/**
- * 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, bool use_quote2, bool use_version_info,
-       pts_meas_algorithms_t comp_hash_algo,
-       chunk_t *out_pcr_comp, chunk_t *out_quote_info)
+METHOD(pts_t, get_quote, bool,
+       private_pts_t *this, tpm_tss_quote_info_t *quote_info, chunk_t *quoted)
 {
-       chunk_t selection, pcr_comp, hash_pcr_comp;
-       bio_writer_t *writer;
-       hasher_t *hasher;
+       tpm_tss_pcr_composite_t *pcr_composite;
+       bool success;
 
        if (!this->pcrs->get_count(this->pcrs))
        {
@@ -690,111 +671,33 @@ METHOD(pts_t, get_quote_info, bool,
                                          "unable to construct TPM Quote Info");
                return FALSE;
        }
-       if (use_quote2 && use_version_info && !this->tpm_version_info.ptr)
+       if (quote_info->get_quote_mode(quote_info) == TPM_QUOTE2_VERSION_INFO)
        {
-               DBG1(DBG_PTS, "TPM Version Information unavailable, ",
-                                         "unable to construct TPM Quote Info2");
-               return FALSE;
-       }
-
-       pcr_comp = this->pcrs->get_composite(this->pcrs);
-
-
-       /* Output the TPM_PCR_COMPOSITE expected from IMC */
-       if (comp_hash_algo)
-       {
-               hash_algorithm_t algo;
-
-               algo = pts_meas_algo_to_hash(comp_hash_algo);
-               hasher = lib->crypto->create_hasher(lib->crypto, algo);
-
-               /* Hash the PCR Composite Structure */
-               if (!hasher || !hasher->allocate_hash(hasher, pcr_comp, out_pcr_comp))
+               if (!this->tpm_version_info.ptr)
                {
-                       DESTROY_IF(hasher);
-                       free(pcr_comp.ptr);
+                       DBG1(DBG_PTS, "TPM Version Information unavailable, ",
+                                                 "unable to construct TPM Quote Info2");
                        return FALSE;
                }
-               DBG3(DBG_PTS, "constructed PCR Composite hash: %#B", out_pcr_comp);
-               hasher->destroy(hasher);
-       }
-       else
-       {
-               *out_pcr_comp = chunk_clone(pcr_comp);
+               quote_info->set_version_info(quote_info, this->tpm_version_info);
        }
+       pcr_composite = this->pcrs->get_composite(this->pcrs);
 
-       /* SHA1 hash of PCR Composite to construct TPM_QUOTE_INFO */
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-       if (!hasher || !hasher->allocate_hash(hasher, pcr_comp, &hash_pcr_comp))
-       {
-               DESTROY_IF(hasher);
-               chunk_free(out_pcr_comp);
-               free(pcr_comp.ptr);
-               return FALSE;
-       }
-       hasher->destroy(hasher);
-
-       /* Construct TPM_QUOTE_INFO/TPM_QUOTE_INFO2 structure */
-       writer = bio_writer_create(TPM_QUOTE_INFO_LEN);
-
-       if (use_quote2)
-       {
-               /* TPM Structure Tag */
-               writer->write_uint16(writer, TPM_TAG_QUOTE_INFO2);
-
-               /* Magic QUT2 value */
-               writer->write_data(writer, chunk_create("QUT2", 4));
+       success = quote_info->get_quote(quote_info, this->secret,
+                                                                       pcr_composite, quoted);
+       chunk_free(&pcr_composite->pcr_select);
+       chunk_free(&pcr_composite->pcr_composite);
+       free(pcr_composite);
 
-               /* Secret assessment value 20 bytes (nonce) */
-               writer->write_data(writer, this->secret);
-
-               /* PCR selection */
-               selection.ptr = pcr_comp.ptr;
-               selection.len = 2 + this->pcrs->get_selection_size(this->pcrs);
-               writer->write_data(writer, selection);
-
-               /* TPM Locality Selection */
-               writer->write_uint8(writer, TPM_LOC_ZERO);
-
-               /* PCR Composite Hash */
-               writer->write_data(writer, hash_pcr_comp);
-
-               if (use_version_info)
-               {
-                       /* TPM version Info */
-                       writer->write_data(writer, this->tpm_version_info);
-               }
-       }
-       else
-       {
-               /* Version number */
-               writer->write_data(writer, chunk_from_chars(1, 1, 0, 0));
-
-               /* Magic QUOT value */
-               writer->write_data(writer, chunk_create("QUOT", 4));
-
-               /* PCR Composite Hash */
-               writer->write_data(writer, hash_pcr_comp);
-
-               /* Secret assessment value 20 bytes (nonce) */
-               writer->write_data(writer, this->secret);
-       }
-
-       /* TPM Quote Info */
-       *out_quote_info = writer->extract_buf(writer);
-       DBG3(DBG_PTS, "constructed TPM Quote Info: %B", out_quote_info);
-
-       writer->destroy(writer);
-       free(pcr_comp.ptr);
-       free(hash_pcr_comp.ptr);
-
-       return TRUE;
+       return success;
 }
 
 METHOD(pts_t, verify_quote_signature, bool,
-                               private_pts_t *this, chunk_t data, chunk_t signature)
+       private_pts_t *this, hash_algorithm_t digest_alg, chunk_t digest,
+       chunk_t signature)
 {
        public_key_t *aik_pubkey;
+       signature_scheme_t scheme;
 
        aik_pubkey = this->aik_cert->get_public_key(this->aik_cert);
        if (!aik_pubkey)
@@ -803,8 +706,51 @@ METHOD(pts_t, verify_quote_signature, bool,
                return FALSE;
        }
 
-       if (!aik_pubkey->verify(aik_pubkey, SIGN_RSA_EMSA_PKCS1_SHA1,
-               data, signature))
+       /* Determine signing scheme */
+       switch (aik_pubkey->get_type(aik_pubkey))
+       {
+               case KEY_RSA:
+                       switch (digest_alg)
+                       {
+                               case HASH_SHA1:
+                                       scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+                                       break;
+                               case HASH_SHA256:
+                                       scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+                                       break;
+                               case HASH_SHA384:
+                                       scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+                                       break;
+                               case HASH_SHA512:
+                                       scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+                                       break;
+                               default:
+                                       scheme = SIGN_UNKNOWN;
+                       }
+                       break;
+               case KEY_ECDSA:
+                       switch (digest_alg)
+                       {
+                               case HASH_SHA256:
+                                       scheme = SIGN_ECDSA_256;
+                                       break;
+                               case HASH_SHA384:
+                                       scheme = SIGN_ECDSA_384;
+                                       break;
+                               case HASH_SHA512:
+                                       scheme = SIGN_ECDSA_521;
+                                       break;
+                               default:
+                                       scheme = SIGN_UNKNOWN;
+                       }
+                       break;
+               default:
+                       DBG1(DBG_PTS, "%N AIK key type not supported", key_type_names,
+                                                  aik_pubkey->get_type(aik_pubkey));
+                       return FALSE;
+       }
+
+       if (!aik_pubkey->verify(aik_pubkey, scheme, digest, signature))
        {
                DBG1(DBG_PTS, "signature verification failed for TPM Quote Info");
                DESTROY_IF(aik_pubkey);
@@ -873,9 +819,9 @@ pts_t *pts_create(bool is_imc)
                        .get_metadata = _get_metadata,
                        .read_pcr = _read_pcr,
                        .extend_pcr = _extend_pcr,
-                       .quote_tpm = _quote_tpm,
+                       .quote = _quote,
                        .get_pcrs = _get_pcrs,
-                       .get_quote_info = _get_quote_info,
+                       .get_quote = _get_quote,
                        .verify_quote_signature  = _verify_quote_signature,
                        .destroy = _destroy,
                },
index ba9a87a8281e67379675fa9d22465cb7decc497c..f3da659dc8b713b1d240f2c56d0c84676da75b9a 100644 (file)
@@ -32,9 +32,10 @@ typedef struct pts_t pts_t;
 #include "pts_dh_group.h"
 #include "pts_pcr.h"
 #include "pts_req_func_comp_evid.h"
-#include "pts_simple_evid_final.h"
 #include "components/pts_comp_func_name.h"
 
+#include <tpm_tss_quote_info.h>
+
 #include <library.h>
 #include <collections/linked_list.h>
 
@@ -70,11 +71,6 @@ typedef struct pts_t pts_t;
  */
 #define ASSESSMENT_SECRET_LEN  20
 
-/**
- * Length of the TPM_QUOTE_INFO structure, TPM Spec 1.2
- */
-#define TPM_QUOTE_INFO_LEN             48
-
 /**
  * Hashing algorithm used by tboot and trustedGRUB
  */
@@ -262,15 +258,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 use_quote2            Version of the Quote function to be used
-        * @param use_version_info      Version info is concatenated to TPM_QUOTE_INFO2
-        * @param pcr_comp                      Chunk to save PCR composite structure
-        * @param quote_sig                     Chunk to save quote operation output
-        *                                                      without external data (anti-replay protection)
-        * @return                                      FALSE in case of TSS error, TRUE otherwise
+        * @param quote_mode    type of Quote signature
+        * @param quote_info    returns various info covered by Quote signature
+        * @param quote_sig             returns Quote signature
+        * @return                              FALSE in case of Quote error, TRUE otherwise
         */
-        bool (*quote_tpm)(pts_t *this, bool use_quote2, bool use_version_info,
-                                          chunk_t *pcr_comp, chunk_t *quote_sig);
+        bool (*quote)(pts_t *this, tpm_quote_mode_t *quote_mode,
+                                  tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig);
 
        /**
         * Get the shadow PCR set
@@ -279,28 +273,26 @@ struct pts_t {
         */
        pts_pcr_t* (*get_pcrs)(pts_t *this);
 
-        /**
-        * Constructs and returns TPM Quote Info structure expected from IMC
+       /**
+        * Computes digest of the constructed TPM Quote Info structure
         *
-        * @param use_quote2            Version of the TPM_QUOTE_INFO to be constructed
-        * @param use_version_info      Version info is concatenated to TPM_QUOTE_INFO2
-        * @param comp_hash_algo        Composite Hash Algorithm
-        * @param pcr_comp                      Output variable to store PCR Composite
-        * @param quote_info            Output variable to store TPM Quote Info
+        * @param quote_info            TPM Quote Info as received from IMC
+        * @param quoted                        Encoding of TPM Quote Info
         * @return                                      FALSE in case of any error, TRUE otherwise
         */
-        bool (*get_quote_info)(pts_t *this, bool use_quote2, bool use_version_info,
-                                                       pts_meas_algorithms_t comp_hash_algo,
-                                                       chunk_t *pcr_comp, chunk_t *quote_info);
+        bool (*get_quote)(pts_t *this, tpm_tss_quote_info_t *quote_info,
+                                          chunk_t *quoted);
 
         /**
         * Constructs and returns PCR Quote Digest structure expected from IMC
         *
-        * @param data                          Calculated TPM Quote Digest
+        * @param digest_alg            Hash algorithm used for TPM Quote Digest
+        * @param digest                        Calculated TPM Quote Digest
         * @param signature                     TPM Quote Signature received from IMC
         * @return                                      FALSE if signature is not verified
         */
-        bool (*verify_quote_signature)(pts_t *this, chunk_t data, chunk_t signature);
+        bool (*verify_quote_signature)(pts_t *this, hash_algorithm_t digest_alg,
+                                                                       chunk_t digest, chunk_t signature);
 
        /**
         * Destroys a pts_t object.
index c0637112396a35d5a0be04afb096c3deddbaed6d..246c37714670ba70fb0eed8860a0d6ec876445d6 100644 (file)
@@ -155,6 +155,24 @@ hash_algorithm_t pts_meas_algo_to_hash(pts_meas_algorithms_t algorithm)
        }
 }
 
+/**
+ * Described in header.
+ */
+pts_meas_algorithms_t pts_meas_algo_from_hash(hash_algorithm_t algorithm)
+{
+       switch (algorithm)
+       {
+               case HASH_SHA1:
+                       return PTS_MEAS_ALGO_SHA1;
+               case HASH_SHA256:
+                       return PTS_MEAS_ALGO_SHA256;
+               case HASH_SHA384:
+                       return PTS_MEAS_ALGO_SHA384;
+               default:
+                       return PTS_MEAS_ALGO_NONE;
+       }
+}
+
 /**
  * Described in header.
  */
index eec7e79811950ab8fd0369ffe73717cebe804076..d7031067972d2b7d668f1f3725cce8cc1307a1b6 100644 (file)
@@ -95,6 +95,14 @@ pts_meas_algorithms_t pts_meas_algo_select(pts_meas_algorithms_t supported_algos
  */
 hash_algorithm_t pts_meas_algo_to_hash(pts_meas_algorithms_t algorithm);
 
+/**
+ * Convert hash_algorithm_t to pts_meas_algorithms_t
+ *
+ * @param algorithm            PTS measurement algorithm type
+ * @return                             libstrongswan hash algorithm type
+ */
+pts_meas_algorithms_t pts_meas_algo_from_hash(hash_algorithm_t algorithm);
+
 /**
  * Return the hash size of a pts_meas_algorithm
  *
index 895c273bbf8811d021577c7dcd36a15b7981bb1d..d514532c5e36a9e52ed52e76ba38ca7624c7e647 100644 (file)
@@ -200,10 +200,10 @@ METHOD(pts_pcr_t, extend, chunk_t,
        return this->pcrs[pcr];
 }
 
-METHOD(pts_pcr_t, get_composite, chunk_t,
+METHOD(pts_pcr_t, get_composite, tpm_tss_pcr_composite_t*,
        private_pts_pcr_t *this)
 {
-       chunk_t composite;
+       tpm_tss_pcr_composite_t *pcr_composite;
        enumerator_t *enumerator;
        uint16_t selection_size;
        uint32_t pcr_field_size, pcr;
@@ -212,14 +212,13 @@ METHOD(pts_pcr_t, get_composite, chunk_t,
        selection_size = get_selection_size(this);
        pcr_field_size = this->pcr_count * PTS_PCR_LEN;
 
-       composite = chunk_alloc(2 + selection_size + 4 + pcr_field_size);
-       pos = composite.ptr;
-       htoun16(pos, selection_size);
-       pos += 2;
-       memcpy(pos, this->pcr_select, selection_size);
-       pos += selection_size;
-       htoun32(pos, pcr_field_size);
-       pos += 4;
+       INIT(pcr_composite,
+               .pcr_select    = chunk_alloc(selection_size),
+               .pcr_composite = chunk_alloc(pcr_field_size),
+       );
+
+       memcpy(pcr_composite->pcr_select.ptr, this->pcr_select, selection_size);
+       pos = pcr_composite->pcr_composite.ptr;
 
        enumerator = create_enumerator(this);
        while (enumerator->enumerate(enumerator, &pcr))
@@ -229,8 +228,7 @@ METHOD(pts_pcr_t, get_composite, chunk_t,
        }
        enumerator->destroy(enumerator);
 
-       DBG3(DBG_PTS, "constructed PCR Composite: %B", &composite);
-       return composite;
+       return pcr_composite;
 }
 
 METHOD(pts_pcr_t, destroy, void,
index b6ca73edc3ad9355e1302a8863a43ff624206307..df84c679f29d3a20e8ed24b964e7fd04f4b4204a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@ typedef struct pts_pcr_t pts_pcr_t;
 
 #include <library.h>
 
+#include <tpm_tss_quote_info.h>
+
 /**
  * Maximum number of PCR's of TPM, TPM Spec 1.2
  */
@@ -100,7 +102,7 @@ struct pts_pcr_t {
         *
         * @return                              PCR Composite object (must be freed)
         */
-       chunk_t (*get_composite)(pts_pcr_t *this);
+       tpm_tss_pcr_composite_t* (*get_composite)(pts_pcr_t *this);
 
        /**
 
diff --git a/src/libimcv/pts/pts_simple_evid_final.h b/src/libimcv/pts/pts_simple_evid_final.h
deleted file mode 100644 (file)
index 0c8dea0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 Sansar Choinyambuu
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup pts_simple_evid_final pts_rsimple_evid_final
- * @{ @ingroup pts
- */
-
-#ifndef PTS_SIMPLE_EVID_FINAL_H_
-#define PTS_SIMPLE_EVID_FINAL_H_
-
-typedef enum pts_simple_evid_final_flag_t pts_simple_evid_final_flag_t;
-
-#include <library.h>
-
-/**
- * PTS Simple Evidence Final Flags
- */
-enum pts_simple_evid_final_flag_t {
-       /** TPM PCR Composite and TPM Quote Signature not included   */
-       PTS_SIMPLE_EVID_FINAL_NO =                                              0x00,
-       /** TPM PCR Composite and TPM Quote Signature included
-         * using TPM_QUOTE_INFO                                     */
-       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO =                              0x40,
-       /** TPM PCR Composite and TPM Quote Signature included
-         * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO not appended */
-       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 =                             0x80,
-       /** TPM PCR Composite and TPM Quote Signature included
-         * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO appended     */
-       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER =             0xC0,
-    /** Evidence Signature included                              */
-       PTS_SIMPLE_EVID_FINAL_EVID_SIG =                                0x20,
-};
-
-#endif /** PTS_SIMPLE_EVID_FINAL_H_ @}*/
index a847dcb70b02ca24c491dd393b8d569aa8ee36f5..267c8577678c950aa38bc24b586bef30bd678912 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,7 +15,6 @@
  */
 
 #include "tcg_pts_attr_simple_evid_final.h"
-#include "pts/pts_simple_evid_final.h"
 
 #include <pa_tnc/pa_tnc_msg.h>
 #include <bio/bio_writer.h>
@@ -27,6 +26,7 @@ typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_sim
 /**
  * Simple Evidence Final
  * see section 3.15.2 of PTS Protocol: Binding to TNC IF-M Specification
+ * plus non-standard extensions to cover the TPM 2.0 Quote Info format
  *
  *                                        1                               2                               3
  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -37,17 +37,57 @@ typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_sim
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  ~          Optional TPM PCR Composite (Variable Length)         ~
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Opt. TPM Qual. Signer Length  | Optional TPM Qualified Signer ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  ~        Optional TPM Qualified Signer (Variable Length)        ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Opt. TPM Clock Info Length    | Optional TPM Clock Info       ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  ~        Optional TPM Clock Info (Variable Length)              ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Opt. TPM Version Info Length  | Optional TPM Version Info     ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  ~        Optional TPM Version Info (Variable Length)            |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Opt. TPM PCR Selection Length | Opt. TPM PCR Selection        ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  ~        Optional TPM PCR Selection (Variable Length)           ~
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  |              Optional TPM Quote Signature Length              |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  ~        Optional TPM Quote Signature (Variable Length)         ~
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  ~        Optional Evidence Signature (Variable Length)          ~
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
+*/
 
 #define PTS_SIMPLE_EVID_FINAL_SIZE                     2
 #define PTS_SIMPLE_EVID_FINAL_RESERVED         0x00
-#define PTS_SIMPLE_EVID_FINAL_FLAG_MASK                0xC0
+
+/**
+ * PTS Simple Evidence Final Flags
+ */
+enum pts_simple_evid_final_flag_t {
+       /** TPM PCR Composite and TPM Quote Signature not included   */
+       PTS_SIMPLE_EVID_FINAL_NO =                                              0x00,
+       /** TPM Quote Info and TPM Quite Signature included
+         * using TPM 2.0 Quote Info format                          */         
+       PTS_SIMPLE_EVID_FINAL_EVID_QUOTE_INFO_TPM2 =    0x10,
+    /** Evidence Signature included                              */
+       PTS_SIMPLE_EVID_FINAL_EVID_SIG =                                0x20,
+       /** TPM PCR Composite and TPM Quote Signature included
+         * using TPM_QUOTE_INFO                                     */
+       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO =                              0x40,
+       /** TPM PCR Composite and TPM Quote Signature included
+         * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO not appended */
+       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 =                             0x80,
+       /** TPM PCR Composite and TPM Quote Signature included
+         * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO appended     */
+       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER =             0xC0,
+       /** Mask for the TPM Quote Info flags                        */
+       PTS_SIMPLE_EVID_FINAL_QUOTE_INFO_MASK =                 0xD0
+};
+
 /**
  * Private data of an tcg_pts_attr_simple_evid_final_t object.
  */
@@ -79,24 +119,14 @@ struct private_tcg_pts_attr_simple_evid_final_t {
        bool noskip_flag;
 
        /**
-        * Set of flags for Simple Evidence Final
-        */
-       uint8_t flags;
-
-       /**
-        * Optional Composite Hash Algorithm
-        */
-       pts_meas_algorithms_t comp_hash_algorithm;
-
-       /**
-        * Optional TPM PCR Composite
+        * Optional TPM Quote Info
         */
-       chunk_t pcr_comp;
+       tpm_tss_quote_info_t *quote_info;
 
        /**
         * Optional TPM Quote Signature
         */
-       chunk_t tpm_quote_sig;
+       chunk_t quote_sig;
 
        /**
         * Is Evidence Signature included?
@@ -156,9 +186,9 @@ METHOD(pa_tnc_attr_t, destroy, void,
 {
        if (ref_put(&this->ref))
        {
+               DESTROY_IF(this->quote_info);
                free(this->value.ptr);
-               free(this->pcr_comp.ptr);
-               free(this->tpm_quote_sig.ptr);
+               free(this->quote_sig.ptr);
                free(this->evid_sig.ptr);
                free(this);
        }
@@ -167,6 +197,9 @@ METHOD(pa_tnc_attr_t, destroy, void,
 METHOD(pa_tnc_attr_t, build, void,
        private_tcg_pts_attr_simple_evid_final_t *this)
 {
+       chunk_t pcr_digest, pcr_select, qualified_signer, clock_info, version_info;
+       hash_algorithm_t pcr_digest_alg;
+       tpm_quote_mode_t quote_mode;
        bio_writer_t *writer;
        uint8_t flags;
 
@@ -174,7 +207,26 @@ METHOD(pa_tnc_attr_t, build, void,
        {
                return;
        }
-       flags = this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
+
+       quote_mode = this->quote_info->get_quote_mode(this->quote_info); 
+       switch (quote_mode)
+       {
+               case TPM_QUOTE:
+                       flags = PTS_SIMPLE_EVID_FINAL_QUOTE_INFO;
+                       break;
+               case TPM_QUOTE2:
+                       flags = PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2;
+                       break;
+               case TPM_QUOTE2_VERSION_INFO:
+                       flags = PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER;
+                       break;
+               case TPM_QUOTE_TPM2:
+                       flags = PTS_SIMPLE_EVID_FINAL_EVID_QUOTE_INFO_TPM2;
+                       break;
+               case TPM_QUOTE_NONE:
+               default:
+                       flags = PTS_SIMPLE_EVID_FINAL_NO;
+       }
 
        if (this->has_evid_sig)
        {
@@ -185,25 +237,35 @@ METHOD(pa_tnc_attr_t, build, void,
        writer->write_uint8 (writer, flags);
        writer->write_uint8 (writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
 
-       /** Optional Composite Hash Algorithm field is always present
-        * Field has value of all zeroes if not used.
-        * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
-        */
-       writer->write_uint16(writer, this->comp_hash_algorithm);
+       pcr_digest_alg = this->quote_info->get_pcr_digest_alg(this->quote_info);
+       pcr_digest     = this->quote_info->get_pcr_digest(this->quote_info);
+
+       writer->write_uint16(writer, pts_meas_algo_from_hash(pcr_digest_alg));
 
        /* Optional fields */
-       if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+       if (quote_mode != TPM_QUOTE_NONE)
        {
-               writer->write_uint32 (writer, this->pcr_comp.len);
-               writer->write_data (writer, this->pcr_comp);
-
-               writer->write_uint32 (writer, this->tpm_quote_sig.len);
-               writer->write_data (writer, this->tpm_quote_sig);
+               writer->write_data32(writer, pcr_digest);
        }
 
-       if (this->has_evid_sig)
+       if (quote_mode == TPM_QUOTE_TPM2)
+       {
+               version_info = this->quote_info->get_version_info(this->quote_info);
+               this->quote_info->get_tpm2_info(this->quote_info, &qualified_signer,
+                                                                               &clock_info, &pcr_select);
+               writer->write_data16(writer, qualified_signer);
+               writer->write_data16(writer, clock_info);
+               writer->write_data16(writer, version_info);
+               writer->write_data16(writer, pcr_select);
+       }
+               
+       if (quote_mode != TPM_QUOTE_NONE)
        {
-               writer->write_data (writer, this->evid_sig);
+               writer->write_data32(writer, this->quote_sig);
+               if (this->has_evid_sig)
+               {
+                       writer->write_data(writer, this->evid_sig);
+               }
        }
 
        this->value = writer->extract_buf(writer);
@@ -214,10 +276,14 @@ METHOD(pa_tnc_attr_t, build, void,
 METHOD(pa_tnc_attr_t, process, status_t,
        private_tcg_pts_attr_simple_evid_final_t *this, uint32_t *offset)
 {
+       hash_algorithm_t pcr_digest_alg;
+       tpm_quote_mode_t quote_mode;
        bio_reader_t *reader;
        uint8_t flags, reserved;
        uint16_t algorithm;
-       uint32_t pcr_comp_len, tpm_quote_sig_len, evid_sig_len;
+       uint32_t evid_sig_len;
+       chunk_t pcr_digest = chunk_empty, quote_sig, evid_sig;
+       chunk_t qualified_signer, clock_info, version_info, pcr_select;
        status_t status = FAILED;
 
        *offset = 0;
@@ -236,56 +302,99 @@ METHOD(pa_tnc_attr_t, process, status_t,
        reader->read_uint8(reader, &flags);
        reader->read_uint8(reader, &reserved);
 
-       this->flags = flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
-
        this->has_evid_sig = (flags & PTS_SIMPLE_EVID_FINAL_EVID_SIG) != 0;
 
+       flags &= PTS_SIMPLE_EVID_FINAL_QUOTE_INFO_MASK;
+
+       switch (flags)
+       {
+               case PTS_SIMPLE_EVID_FINAL_QUOTE_INFO:
+                       quote_mode = TPM_QUOTE;
+                       break;
+               case PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2:
+                       quote_mode = TPM_QUOTE2;
+                       break;
+               case PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER:
+                       quote_mode = TPM_QUOTE2_VERSION_INFO;
+                       break;
+               case PTS_SIMPLE_EVID_FINAL_EVID_QUOTE_INFO_TPM2:
+                       quote_mode = TPM_QUOTE_TPM2;
+                       break;
+               case PTS_SIMPLE_EVID_FINAL_NO:
+               default:
+                       quote_mode = TPM_QUOTE_NONE;
+                       break;
+       }
+
        /** Optional Composite Hash Algorithm field is always present
         * Field has value of all zeroes if not used.
         * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
         */
-
        reader->read_uint16(reader, &algorithm);
-       this->comp_hash_algorithm = algorithm;
+       pcr_digest_alg = pts_meas_algo_to_hash(algorithm);
+
+       /*  Optional fields */
+       if (quote_mode != TPM_QUOTE_NONE)
+       {
+               if (!reader->read_data32(reader, &pcr_digest))
+               {
+                       DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+                                                 "PCR Composite");
+                       goto end;
+               }
+       }
+       this->quote_info = tpm_tss_quote_info_create(quote_mode, pcr_digest_alg,
+                                                                                                                        pcr_digest);
 
-       /*  Optional Composite Hash Algorithm and TPM PCR Composite fields */
-       if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+       if (quote_mode == TPM_QUOTE_TPM2)
        {
-               if (!reader->read_uint32(reader, &pcr_comp_len))
+               if (!reader->read_data16(reader, &qualified_signer))
                {
                        DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
-                                                 "PCR Composite Length");
+                                                 "Qualified Signer");
                        goto end;
                }
-               if (!reader->read_data(reader, pcr_comp_len, &this->pcr_comp))
+               if (!reader->read_data16(reader, &clock_info))
                {
                        DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
-                                                 "PCR Composite");
+                                                 "Clock Info");
                        goto end;
                }
-               this->pcr_comp = chunk_clone(this->pcr_comp);
-
-               if (!reader->read_uint32(reader, &tpm_quote_sig_len))
+               if (!reader->read_data16(reader, &version_info))
                {
                        DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
-                                                 "TPM Quote Singature Length");
+                                                 "Version Info");
                        goto end;
                }
-               if (!reader->read_data(reader, tpm_quote_sig_len, &this->tpm_quote_sig))
+               if (!reader->read_data16(reader, &pcr_select))
+               {
+                       DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+                                                 "PCR select");
+                       goto end;
+               }
+               this->quote_info->set_tpm2_info(this->quote_info, qualified_signer,
+                                                                               clock_info, pcr_select);
+               this->quote_info->set_version_info(this->quote_info, version_info);
+       }
+
+       
+       if (quote_mode != TPM_QUOTE_NONE)
+       {
+               if (!reader->read_data32(reader, &quote_sig))
                {
                        DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
                                                  "TPM Quote Singature");
                        goto end;
                }
-               this->tpm_quote_sig = chunk_clone(this->tpm_quote_sig);
+               this->quote_sig = chunk_clone(quote_sig);
        }
 
        /*  Optional Evidence Signature field */
        if (this->has_evid_sig)
        {
                evid_sig_len = reader->remaining(reader);
-               reader->read_data(reader, evid_sig_len, &this->evid_sig);
-               this->evid_sig = chunk_clone(this->evid_sig);
+               reader->read_data(reader, evid_sig_len, &evid_sig);
+               this->evid_sig = chunk_clone(evid_sig);
        }
 
        reader->destroy(reader);
@@ -296,23 +405,18 @@ end:
        return status;
 }
 
-METHOD(tcg_pts_attr_simple_evid_final_t, get_quote_info, uint8_t,
+METHOD(tcg_pts_attr_simple_evid_final_t, get_quote_info, void,
        private_tcg_pts_attr_simple_evid_final_t *this,
-       pts_meas_algorithms_t *comp_hash_algo, chunk_t *pcr_comp, chunk_t *tpm_quote_sig)
+       tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
 {
-       if (comp_hash_algo)
-       {
-               *comp_hash_algo = this->comp_hash_algorithm;
-       }
-       if (pcr_comp)
+       if (quote_info)
        {
-               *pcr_comp = this->pcr_comp;
+               *quote_info = this->quote_info;
        }
-       if (tpm_quote_sig)
+       if (quote_sig)
        {
-               *tpm_quote_sig = this->tpm_quote_sig;
+               *quote_sig = this->quote_sig;
        }
-       return this->flags;
 }
 
 METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sig, bool,
@@ -335,9 +439,8 @@ METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sig, void,
 /**
  * Described in header.
  */
-pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(uint8_t flags,
-                                                       pts_meas_algorithms_t comp_hash_algorithm,
-                                                       chunk_t pcr_comp, chunk_t tpm_quote_sig)
+pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(
+                                               tpm_tss_quote_info_t *quote_info, chunk_t quote_sig)
 {
        private_tcg_pts_attr_simple_evid_final_t *this;
 
@@ -359,10 +462,8 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(uint8_t flags,
                        .set_evid_sig = _set_evid_sig,
                },
                .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL },
-               .flags = flags,
-               .comp_hash_algorithm = comp_hash_algorithm,
-               .pcr_comp = pcr_comp,
-               .tpm_quote_sig = tpm_quote_sig,
+               .quote_info = quote_info,
+               .quote_sig = quote_sig,
                .ref = 1,
        );
 
index aed4d941fbdf6c165cfc65f93f7936f38264987b..c12e520fd2f597db799bc3a6abe50981caf28132 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Sansar Choinyambuu
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@ typedef struct tcg_pts_attr_simple_evid_final_t tcg_pts_attr_simple_evid_final_t
 #include "tcg_pts_attr_meas_algo.h"
 #include "pa_tnc/pa_tnc_attr.h"
 
+#include <tpm_tss_quote_info.h>
+
 /**
  * Class implementing the TCG PTS Simple Evidence Final attribute
  *
@@ -40,16 +42,14 @@ struct tcg_pts_attr_simple_evid_final_t {
        pa_tnc_attr_t pa_tnc_attribute;
 
        /**
-        * Get Optional PCR Composite and TPM Quote Signature
+        * Get Optional TPM Quote Info and TPM Quote Signature
         *
-        * @param comp_hash_algo        Optional Composite Hash Algorithm
-        * @param pcr_comp                      Optional PCR Composite
-        * @param tpm_quote sig         Optional TPM Quote Signature
-        * @return                                      PTS_SIMPLE_EVID_FINAL flags
+        * @param quote_info            Optional TPM Quote Info
+        * @param quote sig                     Optional TPM Quote Signature
         */
-       uint8_t (*get_quote_info)(tcg_pts_attr_simple_evid_final_t *this,
-                                                          pts_meas_algorithms_t *comp_hash_algo,
-                                                          chunk_t *pcr_comp, chunk_t *tpm_quote_sig);
+       void (*get_quote_info)(tcg_pts_attr_simple_evid_final_t *this,
+                                                  tpm_tss_quote_info_t **quote_info,
+                                                  chunk_t *quote_sig);
 
        /**
         * Get Optional Evidence Signature
@@ -73,16 +73,11 @@ struct tcg_pts_attr_simple_evid_final_t {
 /**
  * Creates an tcg_pts_attr_simple_evid_final_t object
  *
- * @param flags                                        Set of flags
- * @param comp_hash_algorithm  Composite Hash Algorithm
- * @param pcr_comp                             Optional TPM PCR Composite
- * @param tpm_quote_sign               Optional TPM Quote Signature
+ * @param quote_info                   Optional TPM Quote Info
+ * @param quote_sign                   Optional TPM Quote Signature
  */
 pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create(
-                                                       uint8_t flags,
-                                                       pts_meas_algorithms_t comp_hash_algorithm,
-                                                       chunk_t pcr_comp,
-                                                       chunk_t tpm_quote_sign);
+                                               tpm_tss_quote_info_t *quote_info, chunk_t quote_sig);
 
 /**
  * Creates an tcg_pts_attr_simple_evid_final_t object from received data
index 1f3a397922e322d7304e5b30e20804a4b6978205..8fcb44f6a8d3eb67315503275a400106e02ed160 100644 (file)
@@ -7,6 +7,7 @@ AM_LDFLAGS = \
 ipseclib_LTLIBRARIES = libtpmtss.la
 libtpmtss_la_SOURCES = \
        tpm_tss.h tpm_tss.c \
+       tpm_tss_quote_info.h tpm_tss_quote_info.c \
        tpm_tss_trousers.h tpm_tss_trousers.c \
        tpm_tss_tss2.h tpm_tss_tss2.c \
        tpm_tss_tss2_names.h tpm_tss_tss2_names.c
index 82cb4c60ffe11b0e7838e7c56ef50a7cec7baa70..9f95f4da4bd113332b238ca0a1f7f38f9394d323 100644 (file)
 #ifndef TPM_TSS_H_
 #define TPM_TSS_H_
 
+#include "tpm_tss_quote_info.h"
+
 #include <library.h>
+#include <crypto/hashers/hasher.h>
 
 typedef enum tpm_version_t tpm_version_t;
-typedef enum tpm_quote_mode_t tpm_quote_mode_t;
 typedef struct tpm_tss_t tpm_tss_t;
 
 /**
@@ -36,15 +38,6 @@ enum tpm_version_t {
        TPM_VERSION_2_0,
 };
 
-/**
- * TPM Quote Modes
- */
-enum tpm_quote_mode_t {
-       TPM_QUOTE,
-       TPM_QUOTE2,
-       TPM_QUOTE2_VERSION_INFO
-};
-
 /**
  * TPM access via TSS public interface
  */
@@ -114,14 +107,15 @@ struct tpm_tss_t {
         * @param pcr_sel               selection of PCR registers
         * @param alg                   hash algorithm to be used for quote signature
         * @param data                  additional data to be hashed into the quote
-        * @param mode                  define current and legacy TPM quote modes
-        * @param pcr_comp              returns hash of PCR composite
-        * @param sig                   returns quote signature
+        * @param quote_mode    define current and legacy TPM quote modes
+        * @param quote_info    returns various info covered by quote signature
+        * @param quote_sig             returns quote signature
         * @return                              TRUE if quote signature succeeded
         */
        bool (*quote)(tpm_tss_t *this, uint32_t aik_handle, uint32_t pcr_sel,
-                                 hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t mode,
-                                 chunk_t *pcr_comp, chunk_t *quote_sig);
+                                 hash_algorithm_t alg, chunk_t data,
+                                 tpm_quote_mode_t *quote_mode,
+                                 tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig);
 
        /**
         * Destroy a tpm_tss_t.
diff --git a/src/libtpmtss/tpm_tss_quote_info.c b/src/libtpmtss/tpm_tss_quote_info.c
new file mode 100644 (file)
index 0000000..6a58448
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <tpm_tss_quote_info.h>
+
+#include <bio/bio_writer.h>
+
+#ifndef TPM_TAG_QUOTE_INFO2
+#define TPM_TAG_QUOTE_INFO2 0x0036
+#endif
+#ifndef TPM_LOC_ZERO
+#define TPM_LOC_ZERO 0x01
+#endif
+
+typedef struct private_tpm_tss_quote_info_t private_tpm_tss_quote_info_t;
+
+/**
+ * Private data of an tpm_tss_quote_info_t object.
+ */
+struct private_tpm_tss_quote_info_t {
+
+       /**
+        * Public tpm_tss_quote_info_t interface.
+        */
+       tpm_tss_quote_info_t public;
+
+       /**
+        * TPM Quote Mode
+        */
+       tpm_quote_mode_t quote_mode;
+
+       /**
+        * TPM Qualified Signer
+        */
+       chunk_t qualified_signer;
+
+       /**
+        * TPM Clock Info
+        */
+       chunk_t clock_info;
+
+       /**
+        * TPM Version Info
+        */
+       chunk_t version_info;
+
+       /**
+        * TPM PCR Selection
+        */
+       chunk_t pcr_select;
+
+       /**
+        * TPM PCR Composite Hash
+        */
+       chunk_t pcr_digest;
+
+       /**
+        * TPM PCR Composite Hash algoritm
+        */
+       hash_algorithm_t pcr_digest_alg;
+
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+
+};
+
+METHOD(tpm_tss_quote_info_t, get_quote_mode, tpm_quote_mode_t,
+       private_tpm_tss_quote_info_t *this)
+{
+       return this->quote_mode;
+}
+
+METHOD(tpm_tss_quote_info_t, get_pcr_digest_alg, hash_algorithm_t,
+       private_tpm_tss_quote_info_t *this)
+{
+       return this->pcr_digest_alg;
+}
+
+METHOD(tpm_tss_quote_info_t, get_pcr_digest, chunk_t,
+       private_tpm_tss_quote_info_t *this)
+{
+       return this->pcr_digest;
+}
+
+METHOD(tpm_tss_quote_info_t, get_quote, bool,
+       private_tpm_tss_quote_info_t *this, chunk_t nonce,
+       tpm_tss_pcr_composite_t *composite, chunk_t *quoted)
+{
+       chunk_t pcr_composite, pcr_digest;
+       bio_writer_t *writer;
+       hasher_t *hasher;
+       bool equal_digests;
+
+       /* Construct PCR Composite */
+       writer = bio_writer_create(32);
+
+       switch (this->quote_mode)
+       {
+               case TPM_QUOTE:
+               case TPM_QUOTE2:
+               case TPM_QUOTE2_VERSION_INFO:
+                       writer->write_data16(writer, composite->pcr_select);
+                       writer->write_data32(writer, composite->pcr_composite);
+
+                       break;
+               case TPM_QUOTE_TPM2:
+                       writer->write_data(writer, composite->pcr_composite);
+                       break;
+               case TPM_QUOTE_NONE:
+                       break;
+       }
+
+       pcr_composite = writer->extract_buf(writer);
+       writer->destroy(writer);
+
+       DBG2(DBG_PTS, "constructed PCR Composite: %B", &pcr_composite);
+
+       /* Compute PCR Composite Hash */
+       hasher = lib->crypto->create_hasher(lib->crypto, this->pcr_digest_alg);
+       if (!hasher || !hasher->allocate_hash(hasher, pcr_composite, &pcr_digest))
+       {
+               DESTROY_IF(hasher);
+               chunk_free(&pcr_composite);
+               return FALSE;
+       }
+       hasher->destroy(hasher);
+       chunk_free(&pcr_composite);
+
+       DBG2(DBG_PTS, "constructed PCR Composite digest: %B", &pcr_digest);
+
+       equal_digests = chunk_equals(pcr_digest, this->pcr_digest);
+
+       /* Construct Quote Info */
+       writer = bio_writer_create(32);
+
+       switch (this->quote_mode)
+       {
+               case TPM_QUOTE:
+                       /* Version number */
+                       writer->write_data(writer, chunk_from_chars(1, 1, 0, 0));
+
+                       /* Magic QUOT value */
+                       writer->write_data(writer, chunk_from_str("QUOT"));
+
+                       /* PCR Composite Hash */
+                       writer->write_data(writer, pcr_digest);
+
+                       /* Secret assessment value 20 bytes (nonce) */
+                       writer->write_data(writer, nonce);
+                       break;
+               case TPM_QUOTE2:
+               case TPM_QUOTE2_VERSION_INFO:
+                       /* TPM Structure Tag */
+                       writer->write_uint16(writer, TPM_TAG_QUOTE_INFO2);
+
+                       /* Magic QUT2 value */
+                       writer->write_data(writer, chunk_from_str("QUT2"));
+
+                       /* Secret assessment value 20 bytes (nonce) */
+                       writer->write_data(writer, nonce);
+
+                       /* PCR selection */
+                       writer->write_data16(writer, composite->pcr_select);
+
+                       /* TPM Locality Selection */
+                       writer->write_uint8(writer, TPM_LOC_ZERO);
+
+                       /* PCR Composite Hash */
+                       writer->write_data(writer, pcr_digest);
+
+                       if (this->quote_mode == TPM_QUOTE2_VERSION_INFO)
+                       {
+                               /* TPM version Info */
+                               writer->write_data(writer, this->version_info);
+                       }
+                       break;
+               case TPM_QUOTE_TPM2:
+                       /* Magic */
+                       writer->write_data(writer, chunk_from_chars(0xff,0x54,0x43,0x47));
+
+                       /* Type */
+                       writer->write_uint16(writer, 0x8018);
+
+                       /* Qualified Signer */
+                       writer->write_data16(writer, this->qualified_signer);
+
+                       /* Extra Data */
+                       writer->write_data16(writer, nonce);
+
+                       /* Clock Info */
+                       writer->write_data(writer, this->clock_info);
+
+                       /* Firmware Version */
+                       writer->write_data(writer, this->version_info);         
+
+                       /* PCR Selection */
+                       writer->write_data(writer, this->pcr_select);
+
+                       /* PCR Composite Hash */
+                       writer->write_data16(writer, pcr_digest);
+                       break;
+               case TPM_QUOTE_NONE:
+                       break;
+       }
+       chunk_free(&pcr_digest);
+       *quoted = writer->extract_buf(writer);
+       writer->destroy(writer);
+
+       DBG2(DBG_PTS, "constructed TPM Quote Info: %B", quoted);
+
+       if (!equal_digests)
+       {
+               DBG1(DBG_IMV, "received PCR Composite digest does not match "
+                                         "constructed one");
+               chunk_free(quoted);
+       }
+       return equal_digests;
+}
+
+METHOD(tpm_tss_quote_info_t, set_version_info, void,
+       private_tpm_tss_quote_info_t *this, chunk_t version_info)
+{
+       chunk_free(&this->version_info);
+       this->version_info = chunk_clone(version_info);
+}
+
+METHOD(tpm_tss_quote_info_t, get_version_info, chunk_t,
+       private_tpm_tss_quote_info_t *this)
+{
+       return this->version_info;
+}
+
+METHOD(tpm_tss_quote_info_t, set_tpm2_info, void,
+       private_tpm_tss_quote_info_t *this, chunk_t qualified_signer,
+       chunk_t clock_info, chunk_t pcr_select)
+{
+       chunk_free(&this->qualified_signer);
+       this->qualified_signer = chunk_clone(qualified_signer);
+
+       chunk_free(&this->clock_info);
+       this->clock_info = chunk_clone(clock_info);
+
+       chunk_free(&this->pcr_select);
+       this->pcr_select = chunk_clone(pcr_select);
+}
+
+METHOD(tpm_tss_quote_info_t, get_tpm2_info, void,
+       private_tpm_tss_quote_info_t *this, chunk_t *qualified_signer,
+       chunk_t *clock_info, chunk_t *pcr_select)
+{
+       if (qualified_signer)
+       {
+               *qualified_signer = this->qualified_signer;
+       }
+       if (clock_info)
+       {
+               *clock_info = this->clock_info;
+       }
+       if (pcr_select)
+       {
+               *pcr_select = this->pcr_select;
+       }
+}
+
+METHOD(tpm_tss_quote_info_t, get_ref, tpm_tss_quote_info_t*,
+       private_tpm_tss_quote_info_t *this)
+{
+       ref_get(&this->ref);
+
+       return &this->public;
+}
+
+METHOD(tpm_tss_quote_info_t, destroy, void,
+       private_tpm_tss_quote_info_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               chunk_free(&this->qualified_signer);
+               chunk_free(&this->clock_info);
+               chunk_free(&this->version_info);
+               chunk_free(&this->pcr_select);
+               chunk_free(&this->pcr_digest);
+               free(this);
+       }
+}
+
+/**
+ * See header
+ */
+tpm_tss_quote_info_t *tpm_tss_quote_info_create(tpm_quote_mode_t quote_mode,
+                                               hash_algorithm_t pcr_digest_alg, chunk_t pcr_digest)
+
+{
+       private_tpm_tss_quote_info_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_quote_mode = _get_quote_mode,
+                       .get_pcr_digest_alg = _get_pcr_digest_alg,
+                       .get_pcr_digest = _get_pcr_digest,
+                       .get_quote = _get_quote,
+                       .set_version_info = _set_version_info,
+                       .get_version_info = _get_version_info,
+                       .set_tpm2_info = _set_tpm2_info,
+                       .get_tpm2_info = _get_tpm2_info,
+                       .get_ref = _get_ref,
+                       .destroy = _destroy,
+               },
+               .quote_mode = quote_mode,
+               .pcr_digest_alg = pcr_digest_alg,
+               .pcr_digest = chunk_clone(pcr_digest),
+               .ref = 1,
+       );
+
+       return &this->public;
+}
diff --git a/src/libtpmtss/tpm_tss_quote_info.h b/src/libtpmtss/tpm_tss_quote_info.h
new file mode 100644 (file)
index 0000000..5b1c457
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tpm_tss_quote_info tpm_tss_quote_info
+ * @{ @ingroup libtpmtss
+ */
+
+#ifndef TPM_TSS_QUOTE_INFO_H_
+#define TPM_TSS_QUOTE_INFO_H_
+
+#include <library.h>
+
+#include <crypto/hashers/hasher.h>
+
+typedef enum tpm_quote_mode_t tpm_quote_mode_t;
+typedef struct tpm_tss_quote_info_t tpm_tss_quote_info_t;
+typedef struct tpm_tss_pcr_composite_t tpm_tss_pcr_composite_t;
+
+/**
+ * TPM Quote Modes
+ */
+enum tpm_quote_mode_t {
+       TPM_QUOTE_NONE,
+       TPM_QUOTE,
+       TPM_QUOTE2,
+       TPM_QUOTE2_VERSION_INFO,
+       TPM_QUOTE_TPM2
+};
+
+struct tpm_tss_pcr_composite_t {
+
+       /**
+        * Bit map of selected PCRs
+        */
+       chunk_t pcr_select;
+
+       /**
+        * Array of selected PCRs
+        */
+       chunk_t pcr_composite;
+
+};
+
+/**
+ * TPM Quote Information needed to verify the Quote Signature
+ */
+struct tpm_tss_quote_info_t {
+
+       /**
+        * Get TPM Quote Mode
+        *
+        * @return                              TPM Quote Mode
+        */
+       tpm_quote_mode_t (*get_quote_mode)(tpm_tss_quote_info_t *this);
+
+       /**
+        * Get PCR Composite digest algorithm
+        *
+        * @return                                      PCR Composite digest algorithm
+        */
+       hash_algorithm_t (*get_pcr_digest_alg)(tpm_tss_quote_info_t *this);
+
+       /**
+        * Get PCR Composite digest
+        *
+        * @return                                      PCR Composite digest
+        */
+       chunk_t (*get_pcr_digest)(tpm_tss_quote_info_t *this);
+
+       /**
+        * Get TPM Quote Info digest, the basis of the TPM Quote Singature
+        *
+        * @param nonce                         Derived from the Diffie-Hellman exchange
+        * @param composite                     PCR Composite as computed by IMV
+        * @param quoted                        Encoded TPM Quote
+        * @return                                      TRUE if TPM Quote was successfully constructed
+        */
+       bool (*get_quote)(tpm_tss_quote_info_t *this, chunk_t nonce,
+                                                        tpm_tss_pcr_composite_t *composite,
+                                                        chunk_t *quoted);
+
+       /**
+        * Set TPM version info (needed for TPM 1.2)
+        *
+        * @param version_info          TPM 1.2 version info
+        */
+       void (*set_version_info)(tpm_tss_quote_info_t *this, chunk_t version_info);
+
+       /**
+        * Get TPM 2.0 version info (needed for TPM 2.0)
+        *
+        * @return                                      TPM 2.0 firmwareVersioin
+        */
+       chunk_t (*get_version_info)(tpm_tss_quote_info_t *this);
+
+       /**
+        * Set TPM 2.0 info parameters (needed for TPM 2.0)
+        *
+        * @param qualified_signer      TPM 2.0 qualifiedSigner
+        * @param clock_info            TPM 2.0 clockInfo
+        * @param pcr_select            TPM 2.0 pcrSelect
+        */
+       void (*set_tpm2_info)(tpm_tss_quote_info_t *this, chunk_t qualified_signer,
+                                                 chunk_t clock_info, chunk_t pcr_select);
+
+
+       /**
+        * Get TPM 2.0 info parameters (needed for TPM 2.0)
+        *
+        * @param qualified_signer      TPM 2.0 qualifiedSigner
+        * @param clock_info            TPM 2.0 clockInfo
+        * @param pcr_select            TPM 2.0 pcrSelect
+        */
+       void (*get_tpm2_info)(tpm_tss_quote_info_t *this, chunk_t *qualified_signer,
+                                                 chunk_t *clock_info, chunk_t *pcr_select);
+
+       /**
+        * Get reference to Quote Info object.
+        */
+       tpm_tss_quote_info_t* (*get_ref)(tpm_tss_quote_info_t *this);
+
+       /**
+        * Destroy a tpm_tss_quote_info_t.
+        */
+       void (*destroy)(tpm_tss_quote_info_t *this);
+};
+
+/**
+ * Create a tpm_tss_quote_info instance.
+ *
+ * @param quote_mode                   TPM Quote mode
+ * @param pcr_digest_alg               PCR Composite digest algorithm
+ * @param pcr_digest                   PCR Composite digest
+ */
+tpm_tss_quote_info_t *tpm_tss_quote_info_create(tpm_quote_mode_t quote_mode,
+                                               hash_algorithm_t pcr_digest_alg, chunk_t pcr_digest);
+
+#endif /** TPM_TSS_QUOTE_INFO_H_ @}*/
index 7d39c043e648385dd62270c2b27f7f82fa1aec54..8be3ad8778b7ec93db7e0c071609651ef1fccfd1 100644 (file)
@@ -431,8 +431,8 @@ METHOD(tpm_tss_t, extend_pcr, bool,
 
 METHOD(tpm_tss_t, quote, bool,
        private_tpm_tss_trousers_t *this, uint32_t aik_handle, uint32_t pcr_sel,
-       hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t mode, chunk_t *pcr_comp,
-       chunk_t *quote_sig)
+       hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t *quote_mode,
+       tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
 {
        TSS_HKEY hAIK;
        TSS_HKEY hSRK;
@@ -446,7 +446,7 @@ METHOD(tpm_tss_t, quote, bool,
        uint32_t version_info_size, pcr;
        aik_t *aik;
        chunk_t aik_blob = chunk_empty;
-       chunk_t quote_info;
+       chunk_t quote_chunk, pcr_digest;
        enumerator_t *enumerator;
        bool success = FALSE;
 
@@ -503,8 +503,8 @@ METHOD(tpm_tss_t, quote, bool,
 
        /* Create PCR composite object */
        result = Tspi_Context_CreateObject(this->hContext, TSS_OBJECT_TYPE_PCRS,
-                                       (mode == TPM_QUOTE) ? TSS_PCRS_STRUCT_INFO :
-                                                                                 TSS_PCRS_STRUCT_INFO_SHORT,
+                                       (*quote_mode == TPM_QUOTE) ? TSS_PCRS_STRUCT_INFO :
+                                                                                                TSS_PCRS_STRUCT_INFO_SHORT,
                                        &hPcrComposite);
        if (result != TSS_SUCCESS)
        {
@@ -518,7 +518,7 @@ METHOD(tpm_tss_t, quote, bool,
        {
                if (pcr_sel & (1 << pcr))
                {
-                       result = (mode == TPM_QUOTE) ?
+                       result = (*quote_mode == TPM_QUOTE) ?
                                Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr) :
                                Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
                                                                                TSS_PCRS_DIRECTION_RELEASE);
@@ -536,22 +536,20 @@ METHOD(tpm_tss_t, quote, bool,
        valData.rgbExternalData      = data.ptr;
 
        /* TPM Quote */
-       result = (mode == TPM_QUOTE) ?
+       result = (*quote_mode == TPM_QUOTE) ?
                        Tspi_TPM_Quote (this->hTPM, hAIK, hPcrComposite, &valData) :
-                       Tspi_TPM_Quote2(this->hTPM, hAIK, mode == TPM_QUOTE2_VERSION_INFO,
+                       Tspi_TPM_Quote2(this->hTPM, hAIK,
+                                                       *quote_mode == TPM_QUOTE2_VERSION_INFO,
                                                    hPcrComposite, &valData, &version_info_size,
                                                        &version_info);
        if (result != TSS_SUCCESS)
        {
                DBG1(DBG_PTS, "%s Tspi_TPM_Quote%s failed: 0x%x", LABEL,
-                                         (mode == TPM_QUOTE) ? "" : "2", result);
+                                         (*quote_mode == TPM_QUOTE) ? "" : "2", result);
                goto err2;
        }
 
-       /* Extract TPM_Composite_Hash */
-       *pcr_comp = chunk_alloc(HASH_SIZE_SHA1);
-
-       if (mode == TPM_QUOTE)
+       if (*quote_mode == TPM_QUOTE)
        {
                /* TPM_Composite_Hash starts at byte 8 of TPM_Quote_Info structure */
                comp_hash = valData.rgbData + 8;
@@ -562,15 +560,17 @@ METHOD(tpm_tss_t, quote, bool,
                comp_hash = valData.rgbData + valData.ulDataLength - version_info_size -
                                        HASH_SIZE_SHA1;
        }
-       memcpy(pcr_comp->ptr, comp_hash, HASH_SIZE_SHA1);
-       DBG3(DBG_PTS, "Hash of PCR Composite: %#B", pcr_comp);
+       pcr_digest = chunk_create(comp_hash, HASH_SIZE_SHA1);
+       DBG2(DBG_PTS, "PCR composite digest: %B", &pcr_digest);
+
+       quote_chunk = chunk_create(valData.rgbData, valData.ulDataLength);
+       DBG2(DBG_PTS, "TPM Quote Info: %B", &quote_chunk);
 
-       quote_info = chunk_create(valData.rgbData, valData.ulDataLength);
-       DBG3(DBG_PTS, "TPM Quote Info: %B",&quote_info);
+       *quote_info = tpm_tss_quote_info_create(*quote_mode, HASH_SHA1, pcr_digest);
 
        *quote_sig = chunk_clone(chunk_create(valData.rgbValidationData,
                                                                                  valData.ulValidationDataLength));
-       DBG3(DBG_PTS, "TPM Quote Signature: %B",quote_sig);
+       DBG2(DBG_PTS, "TPM Quote Signature: %B", quote_sig);
 
        success = TRUE;
 
index 81d659cdbeb61800d2d058b07322eb2550d595c4..bbe23b1fb0e4120e4cc347f794df918e5d795b62 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <asn1/asn1.h>
 #include <asn1/oid.h>
+#include <bio/bio_reader.h>
 
 #include <tss2/tpm20.h>
 #include <tcti/tcti_socket.h>
@@ -90,6 +91,26 @@ static TPM_ALG_ID hash_alg_to_tpm_alg_id(hash_algorithm_t alg)
        }
 }
 
+/**
+ * Convert TPM_ALG_ID to hash algorithm
+ */
+static hash_algorithm_t hash_alg_from_tpm_alg_id(TPM_ALG_ID alg)
+{
+       switch (alg)
+       {
+               case TPM_ALG_SHA1:
+                       return HASH_SHA1;
+               case TPM_ALG_SHA256:
+                       return HASH_SHA256;
+               case TPM_ALG_SHA384:
+                       return HASH_SHA384;
+               case TPM_ALG_SHA512:
+                       return HASH_SHA512;
+               default:
+                       return HASH_UNKNOWN;
+       }
+}
+
 /**
  * Check if an algorithm given by its TPM_ALG_ID is supported by the TPM
  */
@@ -483,19 +504,21 @@ METHOD(tpm_tss_t, extend_pcr, bool,
 
 METHOD(tpm_tss_t, quote, bool,
        private_tpm_tss_tss2_t *this, uint32_t aik_handle, uint32_t pcr_sel,
-       hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t mode, chunk_t *pcr_comp,
-       chunk_t *quote_sig)
+       hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t *quote_mode,
+       tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
 {
-       chunk_t quote_info;
+       chunk_t quoted_chunk, qualified_signer, extra_data, clock_info,
+                       firmware_version, pcr_select, pcr_digest;
+       hash_algorithm_t pcr_digest_alg;
+       bio_reader_t *reader;
        uint32_t rval;
 
        TPM2B_DATA qualifying_data;
        TPML_PCR_SELECTION  pcr_selection;
-       TPMS_ATTEST *attest;
        TPM2B_ATTEST quoted = { { sizeof(TPM2B_ATTEST)-2, } };
-       TPM2B_DIGEST digest;
-       TPMT_SIGNATURE sig;
        TPMT_SIG_SCHEME scheme;
+       TPMT_SIGNATURE sig;
+       TPMI_ALG_HASH hash_alg;
        TPMS_AUTH_COMMAND  session_data_cmd;
        TPMS_AUTH_RESPONSE session_data_rsp;
        TSS2_SYS_CMD_AUTHS sessions_data_cmd;
@@ -524,11 +547,8 @@ METHOD(tpm_tss_t, quote, bool,
        scheme.scheme = TPM_ALG_NULL;
        memset(&sig, 0x00, sizeof(sig));
 
-       if (mode == TPM_QUOTE || mode == TPM_QUOTE2_VERSION_INFO)
-       {
-               DBG1(DBG_PTS, "%s TPM Quote mode not supported", LABEL);
-               return FALSE;
-       }
+       /* set Quote mode */
+       *quote_mode = TPM_QUOTE_TPM2;
 
        if (!init_pcr_selection(this, pcr_sel, alg, &pcr_selection))
        {
@@ -543,14 +563,29 @@ METHOD(tpm_tss_t, quote, bool,
                DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval);
                return FALSE;
        }
+       quoted_chunk = chunk_create(quoted.t.attestationData, quoted.t.size);
+
+       reader = bio_reader_create(chunk_skip(quoted_chunk, 6));
+       if (!reader->read_data16(reader, &qualified_signer) ||
+               !reader->read_data16(reader, &extra_data) ||
+               !reader->read_data  (reader, 17, &clock_info) ||
+               !reader->read_data  (reader,  8, &firmware_version) ||
+               !reader->read_data  (reader, 10, &pcr_select) ||
+               !reader->read_data16(reader, &pcr_digest))
+       {
+               DBG1(DBG_PTS, "%s parsing of quoted struct failed", LABEL);
+               reader->destroy(reader);
+               return FALSE;
+       }
+       reader->destroy(reader);
 
-       attest = (TPMS_ATTEST *)quoted.t.attestationData;
-       digest = attest->attested.quote.pcrDigest;
-       *pcr_comp = chunk_clone(chunk_create(digest.t.buffer, digest.t.size));
-       DBG2(DBG_PTS, "Hash of PCR Composite: %#B", pcr_comp);
-
-       quote_info = chunk_create(quoted.t.attestationData, quoted.t.size);
-       DBG2(DBG_PTS, "TPM Quote Info: %B",&quote_info);
+       DBG2(DBG_PTS, "PCR Composite digest: %B", &pcr_digest);
+       DBG2(DBG_PTS, "TPM Quote Info: %B", &quoted_chunk);
+       DBG2(DBG_PTS, "qualifiedSigner: %B", &qualified_signer);
+       DBG2(DBG_PTS, "extraData: %B", &extra_data);
+       DBG2(DBG_PTS, "clockInfo: %B", &clock_info);
+       DBG2(DBG_PTS, "firmwareVersion: %B", &firmware_version);
+       DBG2(DBG_PTS, "pcrSelect: %B", &pcr_select);
 
        /* extract signature */
        switch (sig.sigAlg)
@@ -561,6 +596,7 @@ METHOD(tpm_tss_t, quote, bool,
                                                        chunk_create(
                                                                sig.signature.rsassa.sig.t.buffer,
                                                                sig.signature.rsassa.sig.t.size));
+                       hash_alg = sig.signature.rsassa.hash;
                        break;
                case TPM_ALG_ECDSA:
                case TPM_ALG_ECDAA:
@@ -573,14 +609,26 @@ METHOD(tpm_tss_t, quote, bool,
                                                        chunk_create(
                                                                sig.signature.ecdsa.signatureS.t.buffer,
                                                                sig.signature.ecdsa.signatureS.t.size));
+                       hash_alg = sig.signature.ecdsa.hash;
                        break;
                default:
                        DBG1(DBG_PTS, "%s unsupported %N signature algorithm",
                                                   LABEL, tpm_alg_id_names, sig.sigAlg);
                        return FALSE;
        };
+
+       DBG2(DBG_PTS, "PCR digest algorithm is %N", tpm_alg_id_names, hash_alg);
+       pcr_digest_alg = hash_alg_from_tpm_alg_id(hash_alg);
+
        DBG2(DBG_PTS, "TPM Quote Signature: %B", quote_sig);
 
+       /* Create and initialize Quote Info object */
+       *quote_info = tpm_tss_quote_info_create(*quote_mode, pcr_digest_alg,
+                                                                                                                pcr_digest);
+       (*quote_info)->set_tpm2_info(*quote_info, qualified_signer, clock_info,
+                                                                                                                pcr_select);
+       (*quote_info)->set_version_info(*quote_info, firmware_version);
+
        return TRUE;
 }