]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
pts: Variable size PCR banks
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 19 Sep 2020 07:22:14 +0000 (09:22 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 7 Oct 2020 14:54:32 +0000 (16:54 +0200)
17 files changed:
conf/plugins/imc-attestation.opt
conf/plugins/imv-attestation.opt
src/libimcv/plugins/imc_attestation/imc_attestation_process.c
src/libimcv/plugins/imv_attestation/imv_attestation_agent.c
src/libimcv/plugins/imv_attestation/imv_attestation_build.c
src/libimcv/pts/components/ita/ita_comp_ima.c
src/libimcv/pts/pts.c
src/libimcv/pts/pts_ima_bios_list.c
src/libimcv/pts/pts_ima_bios_list.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/libtpmtss/tpm_tss.h
src/libtpmtss/tpm_tss_trousers.c
src/libtpmtss/tpm_tss_tss2_v1.c
src/libtpmtss/tpm_tss_tss2_v2.c

index 82af6b6498f7575f938c20c86e55544547171f95..25435ac535c782693de0dfe00f18a8a4f0a01192 100644 (file)
@@ -10,6 +10,9 @@ libimcv.plugins.imc-attestation.aik_pubkey =
 libimcv.plugins.imc-attestation.aik_handle =
        AIK object handle.
 
+libimcv.plugins.imc-attestation.hash_algorithm = sha384
+       Preferred measurement hash algorithm.
+
 libimcv.plugins.imc-attestation.mandatory_dh_groups = yes
        Enforce mandatory Diffie-Hellman groups.
 
index f552250231c7fa912f45593573351120cf5d2958..ca99ef42e92b6cd688ca3b07ef59fbcd4d324473 100644 (file)
@@ -7,7 +7,7 @@ libimcv.plugins.imv-attestation.mandatory_dh_groups = yes
 libimcv.plugins.imv-attestation.dh_group = ecp256
        Preferred Diffie-Hellman group.
 
-libimcv.plugins.imv-attestation.hash_algorithm = sha256
+libimcv.plugins.imv-attestation.hash_algorithm = sha384
        Preferred measurement hash algorithm.
 
 libimcv.plugins.imv-attestation.min_nonce_len = 0
index 56713bb0436917c79cd054a37f49900af11962d7..daf5c3b20ad7ee515bdcd5a7a06da3e2590c2287 100644 (file)
@@ -57,7 +57,9 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
        chunk_t attr_info;
        pts_t *pts;
        pts_error_code_t pts_error;
+       tpm_tss_t *tpm;
        pen_type_t attr_type;
+       char *hash_alg;
        bool valid_path;
 
        pts = attestation_state->get_pts(attestation_state);
@@ -85,8 +87,24 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
                        tcg_pts_attr_meas_algo_t *attr_cast;
                        pts_meas_algorithms_t offered_algorithms, selected_algorithm;
 
+
                        attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
                        offered_algorithms = attr_cast->get_algorithms(attr_cast);
+
+                       /* If a TPM is present choose only algorithms with a PCR bank */
+                       tpm = pts->get_tpm(pts);
+                       if (tpm)
+                       {
+                               pts_meas_algo_with_pcr(tpm, &supported_algorithms);
+                       }
+
+                       /* The algorithms can be restricted by the Attestation IMC */
+                       hash_alg = lib->settings->get_str(lib->settings,
+                               "%s.plugins.imc-attestation.hash_algorithm", "sha384", lib->ns);
+                       if (!pts_meas_algo_update(hash_alg, &supported_algorithms))
+                       {
+                               supported_algorithms = PTS_MEAS_ALGO_NONE;
+                       }
                        selected_algorithm = pts_meas_algo_select(supported_algorithms,
                                                                                                          offered_algorithms);
                        if (selected_algorithm == PTS_MEAS_ALGO_NONE)
@@ -146,7 +164,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
 
                        /* Send DH Nonce Parameters Response attribute */
                        attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
-                                        supported_algorithms, responder_nonce, responder_value);
+                                                               pts->get_meas_algorithm(pts), responder_nonce,
+                                                               responder_value);
                        msg->add_attribute(msg, attr);
                        break;
                }
index 51bcdc410b1278212ce6b3202a5be2de1d6d05be..fa7d59fbc69b005bf1580b9c5dcb413496579339 100644 (file)
@@ -887,7 +887,7 @@ imv_agent_if_t *imv_attestation_agent_create(const char *name, TNC_IMVID id,
        }
 
        hash_alg = lib->settings->get_str(lib->settings,
-                               "%s.plugins.imv-attestation.hash_algorithm", "sha256", lib->ns);
+                               "%s.plugins.imv-attestation.hash_algorithm", "sha2384", lib->ns);
        dh_group = lib->settings->get_str(lib->settings,
                                "%s.plugins.imv-attestation.dh_group", "ecp256", lib->ns);
        mandatory_dh_groups = lib->settings->get_bool(lib->settings,
index db93ac45ff1ebe1a540173778228339350a81a6b..ec54ce0cf5a30902f1c62c364418e40db4358291 100644 (file)
@@ -68,7 +68,7 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
                        }
 
                        /* Send DH nonce finish attribute */
-                       selected_algorithm = pts->get_meas_algorithm(pts);
+                       selected_algorithm = pts->get_dh_hash_algorithm(pts);
                        if (!pts->get_my_public_value(pts, &initiator_value,
                                                                                  &initiator_nonce))
                        {
index a2820b3422450b0a6d88a070a7a0903b7f1d72b3..703d2e16a362033ee3462b125fd70d94ca4d0ed2 100644 (file)
@@ -167,16 +167,14 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this,
                                                                           uint8_t qualifier, pts_pcr_t *pcrs,
                                                                           uint32_t pcr, chunk_t measurement)
 {
-       size_t pcr_len;
        pts_pcr_transform_t pcr_transform;
-       pts_meas_algorithms_t hash_algo;
+       pts_meas_algorithms_t pcr_algo;
        pts_comp_func_name_t *name;
        pts_comp_evidence_t *evidence;
        chunk_t pcr_before = chunk_empty, pcr_after = chunk_empty;
 
-       hash_algo = PTS_MEAS_ALGO_SHA1;
-       pcr_len = HASH_SIZE_SHA1;
-       pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+       pcr_algo = pcrs->get_pcr_algo(pcrs);
+       pcr_transform = PTS_PCR_TRANSFORM_MATCH;
 
        if (this->pcr_info)
        {
@@ -190,7 +188,7 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this,
        }
        name = this->name->clone(this->name);
        name->set_qualifier(name, qualifier);
-       evidence = pts_comp_evidence_create(name, this->depth, pcr, hash_algo,
+       evidence = pts_comp_evidence_create(name, this->depth, pcr, pcr_algo,
                                                pcr_transform, this->creation_time, measurement);
        if (this->pcr_info)
        {
@@ -362,7 +360,8 @@ METHOD(pts_component_t, measure, status_t,
                {
                        case IMA_STATE_INIT:
                                this->bios_list = pts_ima_bios_list_create(pts->get_tpm(pts),
-                                                                                                       IMA_BIOS_MEASUREMENTS);
+                                                                                                       IMA_BIOS_MEASUREMENTS,
+                                                                                                       pcrs->get_pcr_algo(pcrs));
                                if (!this->bios_list)
                                {
                                        return FAILED;
index 2df30369d141052564655e82fd7b6aee85033abb..b7f1a0e1fe7fe53405c6cbc91f6f53610715d2d9 100644 (file)
@@ -290,16 +290,10 @@ METHOD(pts_t, calculate_secret, bool,
                return FALSE;
        }
        hasher->destroy(hasher);
-
-       /* The DH secret must be destroyed */
        chunk_clear(&shared_secret);
 
-       /*
-        * Truncate the hash to 20 bytes to fit the ExternalData
-        * argument of the TPM Quote command
-        */
-       this->secret.len = min(this->secret.len, 20);
        DBG3(DBG_PTS, "secret assessment value: %B", &this->secret);
+
        return TRUE;
 }
 
@@ -698,15 +692,18 @@ METHOD(pts_t, quote, bool,
        tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
 {
        chunk_t pcr_value, pcr_computed;
+       hash_algorithm_t hash_alg;
        uint32_t pcr, pcr_sel = 0;
        enumerator_t *enumerator;
 
+       hash_alg = pts_meas_algo_to_hash(this->pcrs->get_pcr_algo(this->pcrs));
+
        /* select PCRs */
        DBG2(DBG_PTS, "PCR values hashed into PCR Composite:");
        enumerator = this->pcrs->create_enumerator(this->pcrs);
        while (enumerator->enumerate(enumerator, &pcr))
        {
-               if (this->tpm->read_pcr(this->tpm, pcr, &pcr_value, HASH_SHA1))
+               if (this->tpm->read_pcr(this->tpm, pcr, &pcr_value, hash_alg))
                {
                        pcr_computed = this->pcrs->get(this->pcrs, pcr);
                        DBG2(DBG_PTS, "PCR %2d %#B  %s", pcr, &pcr_value,
@@ -720,7 +717,7 @@ METHOD(pts_t, quote, bool,
        enumerator->destroy(enumerator);
 
        /* TPM Quote */
-       return this->tpm->quote(this->tpm, this->aik_handle, pcr_sel, HASH_SHA1,
+       return this->tpm->quote(this->tpm, this->aik_handle, pcr_sel, hash_alg,
                                                        this->secret, quote_mode, quote_info, quote_sig);
 }
 
@@ -846,7 +843,7 @@ METHOD(pts_t, get_pcrs, pts_pcr_t*,
 {
        if (!this->pcrs)
        {
-               this->pcrs = pts_pcr_create(this->tpm_version);
+               this->pcrs = pts_pcr_create(this->tpm_version, this->algorithm);
        }
        return this->pcrs;
 }
@@ -904,8 +901,8 @@ pts_t *pts_create(bool is_imc)
                },
                .is_imc = is_imc,
                .proto_caps = PTS_PROTO_CAPS_V,
-               .algorithm = PTS_MEAS_ALGO_SHA256,
-               .dh_hash_algorithm = PTS_MEAS_ALGO_SHA256,
+               .algorithm = PTS_MEAS_ALGO_SHA384,
+               .dh_hash_algorithm = PTS_MEAS_ALGO_SHA384,
        );
 
        if (is_imc)
index 8695ab153cdae42a315b92830dbc5f40b7b7a337..2c798cf0a414e32c7a63a5d05966a5e2fd50daaf 100644 (file)
@@ -196,12 +196,14 @@ METHOD(pts_ima_bios_list_t, destroy, void,
 /**
  * See header
  */
-pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file)
+pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file,
+                                                                                         pts_meas_algorithms_t algo)
 {
        private_pts_ima_bios_list_t *this;
        uint32_t pcr, ev_type, event_type, event_len, seek_len, count = 1;
        uint32_t buf_len = 8192;
        uint8_t event_buf[buf_len];
+       hash_algorithm_t hash_alg;
        chunk_t event;
        bios_entry_t *entry;
        struct stat st;
@@ -228,6 +230,7 @@ pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file)
                close(fd);
                return FALSE;
        }
+       hash_alg = pts_meas_algo_to_hash(algo);
 
        INIT(this,
                .public = {
@@ -264,7 +267,7 @@ pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file)
                {
                        break;
                }
-               if (!tpm->get_event_digest(tpm, fd, &entry->measurement))
+               if (!tpm->get_event_digest(tpm, fd, hash_alg, &entry->measurement))
                {
                        break;
                }
index 701a0876aede1a44cf01779cb07e9b1e21ed4450..619a4ae45809b8f63cc1d1425f871c23702c66b2 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PTS_IMA_BIOS_LIST_H_
 #define PTS_IMA_BIOS_LIST_H_
 
+#include "pts_meas_algo.h"
+
 #include <time.h>
 
 #include <library.h>
@@ -70,7 +72,10 @@ struct pts_ima_bios_list_t {
  *
  * @param tpm                          TPM object
  * @param file                         Pathname pointing to the BIOS measurements
+ * @param algo                         hash measurement algorithm to be used
  */
-pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file);
+pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file,
+                                                                                         pts_meas_algorithms_t algo);
+
 
 #endif /** PTS_IMA_BIOS_LIST_H_ @}*/
index 246c37714670ba70fb0eed8860a0d6ec876445d6..18f78826085fe1aacca94cb4bf7b29769135fdbc 100644 (file)
 
 ENUM_BEGIN(pts_meas_algorithm_names, PTS_MEAS_ALGO_NONE, PTS_MEAS_ALGO_NONE,
        "None");
-ENUM_NEXT(pts_meas_algorithm_names,    PTS_MEAS_ALGO_SHA384, PTS_MEAS_ALGO_SHA384,
+ENUM_NEXT(pts_meas_algorithm_names,    PTS_MEAS_ALGO_SHA512, PTS_MEAS_ALGO_SHA512,
                                                                        PTS_MEAS_ALGO_NONE,
+       "SHA512");
+ENUM_NEXT(pts_meas_algorithm_names,    PTS_MEAS_ALGO_SHA384, PTS_MEAS_ALGO_SHA384,
+                                                                       PTS_MEAS_ALGO_SHA512,
        "SHA384");
 ENUM_NEXT(pts_meas_algorithm_names,    PTS_MEAS_ALGO_SHA256, PTS_MEAS_ALGO_SHA256,
                                                                        PTS_MEAS_ALGO_SHA384,
@@ -64,9 +67,19 @@ bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms)
                        DBG2(DBG_PTS, format1, "optional ", hash_algorithm_names, hash_alg,
                                                                  plugin_name);
                }
+               else if (hash_alg == HASH_SHA512)
+               {
+                       *algorithms |= PTS_MEAS_ALGO_SHA512;
+                       DBG2(DBG_PTS, format1, "optional ", hash_algorithm_names, hash_alg,
+                                                                 plugin_name);
+               }
        }
        enumerator->destroy(enumerator);
 
+       if (!(*algorithms & PTS_MEAS_ALGO_SHA512))
+       {
+               DBG1(DBG_PTS, format2, "optional ", hash_algorithm_names, HASH_SHA512);
+       }
        if (!(*algorithms & PTS_MEAS_ALGO_SHA384))
        {
                DBG1(DBG_PTS, format2, "optional ", hash_algorithm_names, HASH_SHA384);
@@ -76,14 +89,14 @@ bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms)
        {
                return TRUE;
        }
-       if (!(*algorithms & PTS_MEAS_ALGO_SHA1))
-       {
-               DBG1(DBG_PTS, format2, "mandatory", hash_algorithm_names, HASH_SHA1);
-       }
        if (!(*algorithms & PTS_MEAS_ALGO_SHA256))
        {
                DBG1(DBG_PTS, format2, "mandatory", hash_algorithm_names, HASH_SHA256);
        }
+       if (!(*algorithms & PTS_MEAS_ALGO_SHA1))
+       {
+               DBG1(DBG_PTS, format2, "mandatory", hash_algorithm_names, HASH_SHA1);
+       }
        return FALSE;
 }
 
@@ -92,33 +105,67 @@ bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms)
  */
 bool pts_meas_algo_update(char *hash_alg, pts_meas_algorithms_t *algorithms)
 {
-       if (strcaseeq(hash_alg, "sha384") || strcaseeq(hash_alg, "sha2_384"))
+       if (strcaseeq(hash_alg, "sha512") || strcaseeq(hash_alg, "sha2_512"))
        {
                /* nothing to update, all algorithms are supported */
                return TRUE;
        }
+       if (strcaseeq(hash_alg, "sha384") || strcaseeq(hash_alg, "sha2_384"))
+       {
+               /* remove SHA512 algorithm */
+               *algorithms &= ~PTS_MEAS_ALGO_SHA512;
+               return TRUE;
+       }
        if (strcaseeq(hash_alg, "sha256") || strcaseeq(hash_alg, "sha2_256"))
        {
-               /* remove SHA384algorithm */
-               *algorithms &= ~PTS_MEAS_ALGO_SHA384;
+               /* remove SHA512 and SHA384 algorithms */
+               *algorithms &= ~(PTS_MEAS_ALGO_SHA512 | PTS_MEAS_ALGO_SHA384);
                return TRUE;
        }
        if (strcaseeq(hash_alg, "sha1"))
        {
-               /* remove SHA384 and SHA256 algorithms */
-               *algorithms &= ~(PTS_MEAS_ALGO_SHA384 | PTS_MEAS_ALGO_SHA256);
+               /* remove SHA512, SHA384 and SHA256 algorithms */
+               *algorithms &= ~(PTS_MEAS_ALGO_SHA512 | PTS_MEAS_ALGO_SHA384 |
+                                                PTS_MEAS_ALGO_SHA256);
                return TRUE;
        }
        DBG1(DBG_PTS, "unknown hash algorithm '%s' configured", hash_alg);
        return FALSE;
 }
 
+/**
+ * Described in header.
+ */
+void pts_meas_algo_with_pcr(tpm_tss_t *tpm, pts_meas_algorithms_t *algorithms)
+{
+       pts_meas_algorithms_t algo_set[] = { PTS_MEAS_ALGO_SHA1,
+                                                                               PTS_MEAS_ALGO_SHA256,
+                                                                               PTS_MEAS_ALGO_SHA384,
+                                                                               PTS_MEAS_ALGO_SHA512
+                                                                         };
+       int i;
+
+       for (i = 0; i < countof(algo_set); i++)
+       {
+               if (!tpm->has_pcr_bank(tpm, pts_meas_algo_to_hash(algo_set[i])))
+               {
+                       /* remove algorithm */
+                       *algorithms &= ~algo_set[i];
+               }
+       }
+}
+
 /**
  * Described in header.
  */
 pts_meas_algorithms_t pts_meas_algo_select(pts_meas_algorithms_t supported_algos,
                                                                                   pts_meas_algorithms_t offered_algos)
 {
+       if ((supported_algos & PTS_MEAS_ALGO_SHA512) &&
+               (offered_algos   & PTS_MEAS_ALGO_SHA512))
+       {
+               return PTS_MEAS_ALGO_SHA512;
+       }
        if ((supported_algos & PTS_MEAS_ALGO_SHA384) &&
                (offered_algos   & PTS_MEAS_ALGO_SHA384))
        {
@@ -150,6 +197,8 @@ hash_algorithm_t pts_meas_algo_to_hash(pts_meas_algorithms_t algorithm)
                        return HASH_SHA256;
                case PTS_MEAS_ALGO_SHA384:
                        return HASH_SHA384;
+               case PTS_MEAS_ALGO_SHA512:
+                       return HASH_SHA512;
                default:
                        return HASH_UNKNOWN;
        }
@@ -168,6 +217,8 @@ pts_meas_algorithms_t pts_meas_algo_from_hash(hash_algorithm_t algorithm)
                        return PTS_MEAS_ALGO_SHA256;
                case HASH_SHA384:
                        return PTS_MEAS_ALGO_SHA384;
+               case HASH_SHA512:
+                       return PTS_MEAS_ALGO_SHA512;
                default:
                        return PTS_MEAS_ALGO_NONE;
        }
@@ -186,9 +237,10 @@ size_t pts_meas_algo_hash_size(pts_meas_algorithms_t algorithm)
                        return HASH_SIZE_SHA256;
                case PTS_MEAS_ALGO_SHA384:
                        return HASH_SIZE_SHA384;
+               case PTS_MEAS_ALGO_SHA512:
+                       return HASH_SIZE_SHA512;
                case PTS_MEAS_ALGO_NONE:
                default:
                        return 0;
        }
 }
-
index 36d0ab1f567904df4483c2e253fb0e20bf35daf2..38504be952fe48665b071dad04151a6f8e94a4d8 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <library.h>
 #include <crypto/hashers/hasher.h>
+#include <tpm_tss.h>
 
 typedef enum pts_meas_algorithms_t pts_meas_algorithms_t;
 
@@ -32,6 +33,7 @@ typedef enum pts_meas_algorithms_t pts_meas_algorithms_t;
  */
 enum pts_meas_algorithms_t {
        PTS_MEAS_ALGO_NONE     =      0,
+       PTS_MEAS_ALGO_SHA512   = (1<<12),
        PTS_MEAS_ALGO_SHA384   = (1<<13),
        PTS_MEAS_ALGO_SHA256   = (1<<14),
        PTS_MEAS_ALGO_SHA1     = (1<<15)
@@ -68,6 +70,8 @@ bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms);
  * sha1 :  PTS_MEAS_ALGO_SHA1
  * sha256: PTS_MEAS_ALGO_SHA1 | PTS_MEAS_ALGO_SHA256
  * sha384: PTS_MEAS_ALGO_SHA1 | PTS_MEAS_ALGO_SHA256 | PTS_MEAS_ALGO_SHA384
+ * sha512: PTS_MEAS_ALGO_SHA1 | PTS_MEAS_ALGO_SHA256 | PTS_MEAS_ALGO_SHA384 |
+           PTS_MEAS_ALGO_SHA512
  *
  * The PTS-IMC is expected to select the strongest supported algorithm
  *
@@ -76,6 +80,15 @@ bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms);
  */
 bool pts_meas_algo_update(char *hash_alg, pts_meas_algorithms_t *algorithms);
 
+/**
+ * Remove the PTS measurement algorithms not having an assigned PCR bank
+ *
+ * @param tpm                          handle to TPM object
+ * @param algorithm                    reduced set of algorithms with assigned PCR banks
+ * @
+ */
+void pts_meas_algo_with_pcr(tpm_tss_t *tpm, pts_meas_algorithms_t *algorithms);
+
 /**
  * Select the strongest PTS measurement algorithm
  * among a set of offered PTS measurement algorithms
index 28593a9b988643deefade21ef30233f2613a058f..68d36282b3323d05ab1d6f1648a03dbf999660d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2020 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -52,6 +52,16 @@ struct private_pts_pcr_t {
         */
        uint8_t pcr_select[PTS_PCR_MAX_NUM / 8];
 
+       /**
+        * Length in bytes of a PCR register (size of hash used)
+        */
+       size_t pcr_len;
+
+       /**
+        * Hash algorithm of PCR bank
+        */
+       pts_meas_algorithms_t pcr_algo;
+
        /**
         * Hasher used to extend shadow PCRs
         */
@@ -59,6 +69,12 @@ struct private_pts_pcr_t {
 
 };
 
+METHOD(pts_pcr_t, get_pcr_algo, pts_meas_algorithms_t,
+       private_pts_pcr_t *this)
+{
+       return this->pcr_algo;
+}
+
 METHOD(pts_pcr_t, get_count, uint32_t,
        private_pts_pcr_t *this)
 {
@@ -162,14 +178,14 @@ METHOD(pts_pcr_t, get, chunk_t,
 METHOD(pts_pcr_t, set, bool,
        private_pts_pcr_t *this, uint32_t pcr, chunk_t value)
 {
-       if (value.len != PTS_PCR_LEN)
+       if (value.len != this->pcr_len)
        {
                DBG1(DBG_PTS, "PCR %2u: value does not fit", pcr);
                return FALSE;
        }
        if (select_pcr(this, pcr))
        {
-               memcpy(this->pcrs[pcr].ptr, value.ptr, PTS_PCR_LEN);
+               memcpy(this->pcrs[pcr].ptr, value.ptr, this->pcr_len);
                return TRUE;
        }
        return FALSE;
@@ -178,7 +194,7 @@ METHOD(pts_pcr_t, set, bool,
 METHOD(pts_pcr_t, extend, chunk_t,
        private_pts_pcr_t *this, uint32_t pcr, chunk_t measurement)
 {
-       if (measurement.len != PTS_PCR_LEN)
+       if (measurement.len != this->pcr_len)
        {
                DBG1(DBG_PTS, "PCR %2u: measurement does not fit", pcr);
                return chunk_empty;
@@ -206,7 +222,7 @@ METHOD(pts_pcr_t, get_composite, tpm_tss_pcr_composite_t*,
        u_char *pos;
 
        selection_size = get_selection_size(this);
-       pcr_field_size = this->pcr_count * PTS_PCR_LEN;
+       pcr_field_size = this->pcr_count * this->pcr_len;
 
        INIT(pcr_composite,
                .pcr_select    = chunk_alloc(selection_size),
@@ -219,8 +235,8 @@ METHOD(pts_pcr_t, get_composite, tpm_tss_pcr_composite_t*,
        enumerator = create_enumerator(this);
        while (enumerator->enumerate(enumerator, &pcr))
        {
-               memcpy(pos, this->pcrs[pcr].ptr, PTS_PCR_LEN);
-               pos += PTS_PCR_LEN;
+               memcpy(pos, this->pcrs[pcr].ptr, this->pcr_len);
+               pos += this->pcr_len;
        }
        enumerator->destroy(enumerator);
 
@@ -243,22 +259,25 @@ METHOD(pts_pcr_t, destroy, void,
 /**
  * See header
  */
-pts_pcr_t *pts_pcr_create(tpm_version_t tpm_version)
+pts_pcr_t *pts_pcr_create(tpm_version_t tpm_version, pts_meas_algorithms_t algo)
 {
        private_pts_pcr_t *this;
+       hash_algorithm_t hash_alg;
        hasher_t *hasher;
        uint32_t i;
 
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       hash_alg = pts_meas_algo_to_hash(algo);
+       hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
        if (!hasher)
        {
                DBG1(DBG_PTS, "%N hasher could not be created",
-                        hash_algorithm_short_names, HASH_SHA1);
+                        hash_algorithm_short_names, hash_alg);
                return NULL;
        }
 
        INIT(this,
                .public = {
+                       .get_pcr_algo = _get_pcr_algo,
                        .get_count = _get_count,
                        .select_pcr = _select_pcr,
                        .get_selection_size = _get_selection_size,
@@ -269,13 +288,15 @@ pts_pcr_t *pts_pcr_create(tpm_version_t tpm_version)
                        .get_composite = _get_composite,
                        .destroy = _destroy,
                },
+               .pcr_algo = algo,
+               .pcr_len = pts_meas_algo_hash_size(algo),
                .hasher = hasher,
        );
 
        for (i = 0; i < PTS_PCR_MAX_NUM; i++)
        {
-               this->pcrs[i] = chunk_alloc(PTS_PCR_LEN);
-               memset(this->pcrs[i].ptr, 0x00, PTS_PCR_LEN);
+               this->pcrs[i] = chunk_alloc(this->pcr_len);
+               memset(this->pcrs[i].ptr, 0x00, this->pcr_len);
        }
 
        /* Set locality indicator in PCR[0] */
@@ -285,7 +306,7 @@ pts_pcr_t *pts_pcr_create(tpm_version_t tpm_version)
 
                DBG2(DBG_PTS, "TPM 2.0 - locality indicator set to %u",
                                          (uint32_t)locality);
-               this->pcrs[0].ptr[PTS_PCR_LEN - 1] = locality;
+               this->pcrs[0].ptr[this->pcr_len - 1] = locality;
        }
 
        return &this->public;
index ad3670539877d3413b1122794491d98d874c5259..6b399e466e1f12aa29638264decdfa4721245767 100644 (file)
@@ -23,6 +23,8 @@
 
 typedef struct pts_pcr_t pts_pcr_t;
 
+#include "pts_meas_algo.h"
+
 #include <library.h>
 
 #include <tpm_tss.h>
@@ -33,16 +35,18 @@ typedef struct pts_pcr_t pts_pcr_t;
  */
 #define PTS_PCR_MAX_NUM                                24
 
-/**
- * Number of bytes that can be saved in a PCR of TPM, TPM Spec 1.2
- */
-#define PTS_PCR_LEN                                    20
-
 /**
  * Class implementing a shadow PCR register set
  */
 struct pts_pcr_t {
 
+       /**
+        * Get the hash algorithm used by the PCR bank
+        *
+        * @return                              hash_measurement algorithm
+        */
+       pts_meas_algorithms_t(*get_pcr_algo)(pts_pcr_t *this);
+
        /**
         * Get the number of selected PCRs
         *
@@ -117,7 +121,8 @@ struct pts_pcr_t {
  * Creates an pts_pcr_t object
  *
  * @param tpm_version          TPM version
+ * @param algo                         Hash algorithm used by PCR bank
  */
-pts_pcr_t* pts_pcr_create(tpm_version_t tpm_version);
+pts_pcr_t* pts_pcr_create(tpm_version_t tpm_version, pts_meas_algorithms_t algo);
 
 #endif /** PTS_PCR_H_ @}*/
index bf8cff3ea4735911ce08db99dbeb3943d7071513..e3dd0333463dede85d4bc2aec4c4c6b4c5367e19 100644 (file)
@@ -89,6 +89,14 @@ struct tpm_tss_t {
        enumerator_t *(*supported_signature_schemes)(tpm_tss_t *this,
                                                                                                 uint32_t handle);
 
+       /**
+        * Check if there is an assigned PCR bank for the given hash algorithm
+        *
+        * @param alg                   hash algorithm
+        * @return                              TRUE if a PCR bank for this algorithm exists
+        */
+       bool (*has_pcr_bank)(tpm_tss_t *this, hash_algorithm_t alg);
+
        /**
         * Retrieve the current value of a PCR register in a given PCR bank
         *
@@ -170,10 +178,12 @@ struct tpm_tss_t {
         * Get an event digest from a TPM measurement log
         *
         * @param fd                    file descriptor of the measurement log
+        * @param hash                  hash algorithm of the digest to be extracted
         * @param digest                allocated chunk_t containing event digest
         * @return                              TRUE if event digest was successfully extracted
         */
-       bool (*get_event_digest)(tpm_tss_t *this, int fd, chunk_t *digest);
+       bool (*get_event_digest)(tpm_tss_t *this, int fd, hash_algorithm_t alg,
+                                                        chunk_t *digest);
 
        /**
         * Destroy a tpm_tss_t.
index c84b04167b0f70f3f06c05ecf1ca6ae918742789..64764bfa9255d7366e729d2cce36414dbc149fd4 100644 (file)
@@ -398,6 +398,12 @@ METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
        return enumerator_create_empty();
 }
 
+METHOD(tpm_tss_t, has_pcr_bank, bool,
+       private_tpm_tss_trousers_t *this, hash_algorithm_t alg)
+{
+       return alg == HASH_SHA1;
+}
+
 METHOD(tpm_tss_t, read_pcr, bool,
        private_tpm_tss_trousers_t *this, uint32_t pcr_num, chunk_t *pcr_value,
        hash_algorithm_t alg)
@@ -406,6 +412,10 @@ METHOD(tpm_tss_t, read_pcr, bool,
        uint8_t *value;
        uint32_t len;
 
+       if (alg != HASH_SHA1)
+       {
+               return FALSE;
+       }
        result = Tspi_TPM_PcrRead(this->hTPM, pcr_num, &len, &value);
        if (result != TSS_SUCCESS)
        {
@@ -425,6 +435,10 @@ METHOD(tpm_tss_t, extend_pcr, bool,
        uint32_t pcr_len;
        uint8_t *pcr_ptr;
 
+       if (alg != HASH_SHA1)
+       {
+               return FALSE;
+       }
        result = Tspi_TPM_PcrExtend(this->hTPM, pcr_num, data.len, data.ptr,
                                                                NULL, &pcr_len, &pcr_ptr);
        if (result != TSS_SUCCESS)
@@ -458,6 +472,11 @@ METHOD(tpm_tss_t, quote, bool,
        enumerator_t *enumerator;
        bool success = FALSE;
 
+       if (alg != HASH_SHA1)
+       {
+               return FALSE;
+       }
+
        /* Retrieve SRK from TPM and set the authentication to well known secret*/
        result = Tspi_Context_LoadKeyByUUID(this->hContext, TSS_PS_TYPE_SYSTEM,
                                                                                SRK_UUID, &hSRK);
@@ -612,8 +631,13 @@ METHOD(tpm_tss_t, get_data, bool,
 }
 
 METHOD(tpm_tss_t, get_event_digest, bool,
-       private_tpm_tss_trousers_t *this, int fd, chunk_t *digest)
+       private_tpm_tss_trousers_t *this, int fd, hash_algorithm_t alg,
+       chunk_t *digest)
 {
+       if (alg != HASH_SHA1)
+       {
+               return FALSE;
+       }
        *digest = chunk_alloc(HASH_SIZE_SHA1);
 
        return read(fd, digest->ptr, digest->len) == digest->len;
@@ -659,6 +683,7 @@ tpm_tss_t *tpm_tss_trousers_create()
                                .generate_aik = _generate_aik,
                                .get_public = _get_public,
                                .supported_signature_schemes = _supported_signature_schemes,
+                               .has_pcr_bank = _has_pcr_bank,
                                .read_pcr = _read_pcr,
                                .extend_pcr = _extend_pcr,
                                .quote = _quote,
index cbc3118dfe6740b2a87e5f05fd1fd4214d9fac65..fb5a6e93a15442643cf1c2ec9fe3d3289e3e4da5 100644 (file)
@@ -42,6 +42,9 @@
 
 #define LABEL  "TPM 2.0 -"
 
+#define PLATFORM_PCR   24
+#define MAX_PCR_BANKS   4
+
 typedef struct private_tpm_tss_tss2_t private_tpm_tss_tss2_t;
 
 /**
@@ -65,20 +68,30 @@ struct private_tpm_tss_tss2_t {
        TSS2_SYS_CONTEXT  *sys_context;
 
        /**
-        * Number of supported algorithms
+        * TPM version info
         */
-       size_t supported_algs_count;
+       chunk_t version_info;
 
        /**
-        * TPM version info
+        * Number of supported algorithms
         */
-       chunk_t version_info;
+       size_t supported_algs_count;
 
        /**
         * List of supported algorithms
         */
        TPM_ALG_ID supported_algs[TPM_PT_ALGORITHM_SET];
 
+               /**
+        * Number of assigned PCR banks
+        */
+       size_t assigned_pcrs_count;
+
+       /**
+        * List of assigned PCR banks
+        */
+       TPM_ALG_ID assigned_pcrs[MAX_PCR_BANKS];
+
        /**
         * Is TPM FIPS 186-4 compliant ?
         */
@@ -304,7 +317,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
        this->mutex->unlock(this->mutex);
        if (rval != TPM_RC_SUCCESS)
        {
-               DBG1(DBG_PTS, "%s GetCapability failed for TPM_ECC_CURVES: 0x%06x",
+               DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_ECC_CURVES: 0x%06x",
                                           LABEL, rval);
                return FALSE;
        }
@@ -327,6 +340,40 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
        }
        DBG2(DBG_PTS, "%s ECC curves:%s", LABEL, buf);
 
+       /* get assigned PCR banks */
+       this->mutex->lock(this->mutex);
+       rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_PCRS,
+                                               0, MAX_PCR_BANKS, &more_data, &cap_data, 0);
+       this->mutex->unlock(this->mutex);
+       if (rval != TPM_RC_SUCCESS)
+       {
+               DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_PCRS: 0x%06x",
+                                          LABEL, rval);
+               return FALSE;
+       }
+
+       /* Number of assigned PCR banks */
+       this->assigned_pcrs_count = cap_data.data.assignedPCR.count;
+
+       /* reset print buffer */
+       pos = buf;
+       len = BUF_LEN;
+
+       /* store and print assigned PCR banks */
+       for (i = 0; i < cap_data.data.assignedPCR.count; i++)
+       {
+               alg = cap_data.data.assignedPCR.pcrSelections[i].hash;
+               this->assigned_pcrs[i] = alg;
+               written = snprintf(pos, len, " %N", tpm_alg_id_names, alg);
+               if (written < 0 || written >= len)
+               {
+                       break;
+               }
+               pos += written;
+               len -= written;
+       }
+       DBG2(DBG_PTS, "%s PCR banks:%s", LABEL, buf);
+
        return TRUE;
 }
 
@@ -685,27 +732,44 @@ METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
                                                                        (void*)signature_params_destroy);
 }
 
+METHOD(tpm_tss_t, has_pcr_bank, bool,
+       private_tpm_tss_tss2_t *this, hash_algorithm_t alg)
+{
+       TPM_ALG_ID alg_id;
+       int i;
+
+       alg_id = hash_alg_to_tpm_alg_id(alg);
+
+       for (i = 0; i < this->assigned_pcrs_count; i++)
+       {
+               if (this->assigned_pcrs[i] == alg_id)
+               {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
 /**
  * Configure a PCR Selection assuming a maximum of 24 registers
  */
 static bool init_pcr_selection(private_tpm_tss_tss2_t *this, uint32_t pcrs,
                                                           hash_algorithm_t alg, TPML_PCR_SELECTION *pcr_sel)
 {
-       TPM_ALG_ID alg_id;
        uint32_t pcr;
 
-       /* check if hash algorithm is supported by TPM */
-       alg_id = hash_alg_to_tpm_alg_id(alg);
-       if (!is_supported_alg(this, alg_id))
+       /* check if there is an assigned PCR bank for this hash algorithm */
+       if (!has_pcr_bank(this, alg))
        {
-               DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
+               DBG1(DBG_PTS, "%s %N hash algorithm not supported by any PCR bank",
                         LABEL, hash_algorithm_short_names, alg);
                return FALSE;
        }
 
        /* initialize the PCR Selection structure,*/
        pcr_sel->count = 1;
-       pcr_sel->pcrSelections[0].hash = alg_id;
+       pcr_sel->pcrSelections[0].hash = hash_alg_to_tpm_alg_id(alg);
        pcr_sel->pcrSelections[0].sizeofSelect = 3;
        pcr_sel->pcrSelections[0].pcrSelect[0] = 0;
        pcr_sel->pcrSelections[0].pcrSelect[1] = 0;
@@ -772,7 +836,6 @@ METHOD(tpm_tss_t, extend_pcr, bool,
        chunk_t data, hash_algorithm_t alg)
 {
        uint32_t rval;
-       TPM_ALG_ID alg_id;
        TPML_DIGEST_VALUES digest_values;
        TPMS_AUTH_COMMAND  session_data_cmd;
        TPMS_AUTH_RESPONSE session_data_rsp;
@@ -796,17 +859,16 @@ METHOD(tpm_tss_t, extend_pcr, bool,
 
        *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
 
-       /* check if hash algorithm is supported by TPM */
-       alg_id = hash_alg_to_tpm_alg_id(alg);
-       if (!is_supported_alg(this, alg_id))
+       /* check if there is an assigned PCR bank for this hash algorithm */
+       if (!has_pcr_bank(this, alg))
        {
-               DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
+               DBG1(DBG_PTS, "%s %N hash algorithm not supported by any PCR bank",
                         LABEL, hash_algorithm_short_names, alg);
                return FALSE;
        }
 
        digest_values.count = 1;
-       digest_values.digests[0].hashAlg = alg_id;
+       digest_values.digests[0].hashAlg = hash_alg_to_tpm_alg_id(alg);
 
        switch (alg)
        {
@@ -1337,9 +1399,63 @@ METHOD(tpm_tss_t, get_data, bool,
 }
 
 METHOD(tpm_tss_t, get_event_digest, bool,
-       private_tpm_tss_tss2_t *this, int fd, chunk_t *digest)
+       private_tpm_tss_tss2_t *this, int fd, hash_algorithm_t alg, chunk_t *digest)
 {
-       return FALSE;
+       uint8_t digest_buf[HASH_SIZE_SHA512];
+       uint32_t digest_count;
+       size_t digest_len = 0;
+       hash_algorithm_t hash_alg;
+       TPM_ALG_ID alg_id;
+
+       if (read(fd, &digest_count, 4) != 4)
+       {
+               return FALSE;
+       }
+       while (digest_count--)
+       {
+               if (read(fd, &alg_id, 2) != 2)
+               {
+                       return FALSE;
+               }
+               hash_alg = hash_alg_from_tpm_alg_id(alg_id);
+
+               switch (hash_alg)
+               {
+                       case HASH_SHA1:
+                               digest_len = HASH_SIZE_SHA1;
+                               break;
+                       case HASH_SHA256:
+                               digest_len = HASH_SIZE_SHA256;
+                               break;
+                       case HASH_SHA384:
+                               digest_len = HASH_SIZE_SHA384;
+                               break;
+                       case HASH_SHA512:
+                               digest_len = HASH_SIZE_SHA512;
+                               break;
+                       default:
+                               DBG2(DBG_PTS, "alg_id: 0x%04x", alg_id);
+                               return FALSE;
+               }
+               if (hash_alg == alg)
+               {
+                       *digest = chunk_alloc(digest_len);
+                       if (read(fd, digest->ptr, digest_len) != digest_len)
+                       {
+                               return FALSE;
+                       }
+               }
+               else
+               {
+                       /* read without storing */
+                       if (read(fd, digest_buf, digest_len) != digest_len)
+                       {
+                               return FALSE;
+                       }
+               }
+       }
+
+       return TRUE;
 }
 
 METHOD(tpm_tss_t, destroy, void,
@@ -1366,6 +1482,7 @@ tpm_tss_t *tpm_tss_tss2_create()
                        .generate_aik = _generate_aik,
                        .get_public = _get_public,
                        .supported_signature_schemes = _supported_signature_schemes,
+                       .has_pcr_bank = _has_pcr_bank,
                        .read_pcr = _read_pcr,
                        .extend_pcr = _extend_pcr,
                        .quote = _quote,
index 0f4e9ce869be276ebe144b3eeaabd324b95edba6..914f953f5ffb8b8e70e6289d67d8ab1fcc5ee85a 100644 (file)
@@ -35,6 +35,7 @@
 #define LABEL  "TPM 2.0 -"
 
 #define PLATFORM_PCR   24
+#define MAX_PCR_BANKS   4
 
 typedef struct private_tpm_tss_tss2_t private_tpm_tss_tss2_t;
 
@@ -59,20 +60,30 @@ struct private_tpm_tss_tss2_t {
        TSS2_SYS_CONTEXT  *sys_context;
 
        /**
-        * Number of supported algorithms
+        * TPM version info
         */
-       size_t supported_algs_count;
+       chunk_t version_info;
 
        /**
-        * TPM version info
+        * Number of supported algorithms
         */
-       chunk_t version_info;
+       size_t supported_algs_count;
 
        /**
         * List of supported algorithms
         */
        TPM2_ALG_ID supported_algs[TPM2_PT_ALGORITHM_SET];
 
+       /**
+        * Number of assigned PCR banks
+        */
+       size_t assigned_pcrs_count;
+
+       /**
+        * List of assigned PCR banks
+        */
+       TPM2_ALG_ID assigned_pcrs[MAX_PCR_BANKS];
+
        /**
         * Is TPM FIPS 186-4 compliant ?
         */
@@ -314,7 +325,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
        this->mutex->unlock(this->mutex);
        if (rval != TPM2_RC_SUCCESS)
        {
-               DBG1(DBG_PTS, "%s GetCapability failed for TPM2_ECC_CURVES: 0x%06x",
+               DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_ECC_CURVES: 0x%06x",
                                           LABEL, rval);
                return FALSE;
        }
@@ -337,6 +348,40 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
        }
        DBG2(DBG_PTS, "%s ECC curves:%s", LABEL, buf);
 
+       /* get assigned PCR banks */
+       this->mutex->lock(this->mutex);
+       rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_PCRS,
+                                               0, MAX_PCR_BANKS, &more_data, &cap_data, 0);
+       this->mutex->unlock(this->mutex);
+       if (rval != TPM2_RC_SUCCESS)
+       {
+               DBG1(DBG_PTS, "%s GetCapability failed for TPM2_CAP_PCRS: 0x%06x",
+                                          LABEL, rval);
+               return FALSE;
+       }
+
+       /* Number of assigned PCR banks */
+       this->assigned_pcrs_count = cap_data.data.assignedPCR.count;
+
+       /* reset print buffer */
+       pos = buf;
+       len = BUF_LEN;
+
+       /* store and print assigned PCR banks */
+       for (i = 0; i < cap_data.data.assignedPCR.count; i++)
+       {
+               alg = cap_data.data.assignedPCR.pcrSelections[i].hash;
+               this->assigned_pcrs[i] = alg;
+               written = snprintf(pos, len, " %N", tpm_alg_id_names, alg);
+               if (written < 0 || written >= len)
+               {
+                       break;
+               }
+               pos += written;
+               len -= written;
+       }
+       DBG2(DBG_PTS, "%s PCR banks:%s", LABEL, buf);
+
        return TRUE;
 }
 
@@ -649,27 +694,45 @@ METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
                                                                        (void*)signature_params_destroy);
 }
 
+METHOD(tpm_tss_t, has_pcr_bank, bool,
+       private_tpm_tss_tss2_t *this, hash_algorithm_t alg)
+{
+       TPM2_ALG_ID alg_id;
+       int i;
+
+       alg_id = hash_alg_to_tpm_alg_id(alg);
+
+       for (i = 0; i < this->assigned_pcrs_count; i++)
+       {
+               if (this->assigned_pcrs[i] == alg_id)
+               {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
 /**
  * Configure a PCR Selection assuming a maximum of 24 registers
  */
 static bool init_pcr_selection(private_tpm_tss_tss2_t *this, uint32_t pcrs,
                                                           hash_algorithm_t alg, TPML_PCR_SELECTION *pcr_sel)
 {
-       TPM2_ALG_ID alg_id;
        uint32_t pcr;
 
-       /* check if hash algorithm is supported by TPM */
-       alg_id = hash_alg_to_tpm_alg_id(alg);
-       if (!is_supported_alg(this, alg_id))
+       /* check if there is an assigned PCR bank for this hash algorithm */
+       if (!has_pcr_bank(this, alg))
        {
-               DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
+               DBG1(DBG_PTS, "%s %N hash algorithm not supported by any PCR bank",
                         LABEL, hash_algorithm_short_names, alg);
                return FALSE;
        }
 
        /* initialize the PCR Selection structure,*/
        pcr_sel->count = 1;
-       pcr_sel->pcrSelections[0].hash = alg_id;
+       pcr_sel->pcrSelections[0].hash = hash_alg_to_tpm_alg_id(alg);
+;
        pcr_sel->pcrSelections[0].sizeofSelect = 3;
        pcr_sel->pcrSelections[0].pcrSelect[0] = 0;
        pcr_sel->pcrSelections[0].pcrSelect[1] = 0;
@@ -736,24 +799,22 @@ METHOD(tpm_tss_t, extend_pcr, bool,
        chunk_t data, hash_algorithm_t alg)
 {
        uint32_t rval;
-       TPM2_ALG_ID alg_id;
        TPML_DIGEST_VALUES digest_values;
        TSS2L_SYS_AUTH_COMMAND  auth_cmd = { 1, { auth_cmd_empty } };
        TSS2L_SYS_AUTH_RESPONSE auth_rsp;
 
        auth_cmd.auths[0].sessionHandle = TPM2_RS_PW;
 
-       /* check if hash algorithm is supported by TPM */
-       alg_id = hash_alg_to_tpm_alg_id(alg);
-       if (!is_supported_alg(this, alg_id))
+       /* check if there is an assigned PCR bank for this hash algorithm */
+       if (!has_pcr_bank(this, alg))
        {
-               DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
+               DBG1(DBG_PTS, "%s %N hash algorithm not supported by any PCR bank",
                         LABEL, hash_algorithm_short_names, alg);
                return FALSE;
        }
 
        digest_values.count = 1;
-       digest_values.digests[0].hashAlg = alg_id;
+       digest_values.digests[0].hashAlg = hash_alg_to_tpm_alg_id(alg);
 
        switch (alg)
        {
@@ -1237,7 +1298,7 @@ METHOD(tpm_tss_t, get_data, bool,
 }
 
 METHOD(tpm_tss_t, get_event_digest, bool,
-       private_tpm_tss_tss2_t *this, int fd, chunk_t *digest)
+       private_tpm_tss_tss2_t *this, int fd, hash_algorithm_t alg, chunk_t *digest)
 {
        uint8_t digest_buf[HASH_SIZE_SHA512];
        uint32_t digest_count;
@@ -1275,7 +1336,7 @@ METHOD(tpm_tss_t, get_event_digest, bool,
                                DBG2(DBG_PTS, "alg_id: 0x%04x", alg_id);
                                return FALSE;
                }
-               if (hash_alg == HASH_SHA1)
+               if (hash_alg == alg)
                {
                        *digest = chunk_alloc(digest_len);
                        if (read(fd, digest->ptr, digest_len) != digest_len)
@@ -1285,7 +1346,7 @@ METHOD(tpm_tss_t, get_event_digest, bool,
                }
                else
                {
-                       /* currently skip non-SHA1 digests */
+                       /* read without storing */
                        if (read(fd, digest_buf, digest_len) != digest_len)
                        {
                                return FALSE;
@@ -1320,6 +1381,7 @@ tpm_tss_t *tpm_tss_tss2_create()
                        .generate_aik = _generate_aik,
                        .get_public = _get_public,
                        .supported_signature_schemes = _supported_signature_schemes,
+                       .has_pcr_bank = _has_pcr_bank,
                        .read_pcr = _read_pcr,
                        .extend_pcr = _extend_pcr,
                        .quote = _quote,