From 9b4a2322d656f3e816bc40fcccd5823d5c2a4067 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Thu, 17 Dec 2020 12:14:23 +0100 Subject: [PATCH] libimcv: Evaluate IMA SHA-256 measurements --- conf/plugins/imc-attestation.opt | 4 + src/libimcv/pts/components/ita/ita_comp_ima.c | 226 +++++++++--------- src/libimcv/pts/pts_ima_event_list.c | 94 +++++++- src/libimcv/pts/pts_ima_event_list.h | 22 +- 4 files changed, 231 insertions(+), 115 deletions(-) diff --git a/conf/plugins/imc-attestation.opt b/conf/plugins/imc-attestation.opt index 25435ac53..34fec0a7e 100644 --- a/conf/plugins/imc-attestation.opt +++ b/conf/plugins/imc-attestation.opt @@ -47,3 +47,7 @@ libimcv.plugins.imc-attestation.pcr18_meas = libimcv.plugins.imc-attestation.pcr18_after = PCR18 value after measurement. + +libimcv.plugins.imc-attestation.pcr_padding = no + Whether to pad IMA SHA1 measurements values when extending into + SHA256 PCR bank. diff --git a/src/libimcv/pts/components/ita/ita_comp_ima.c b/src/libimcv/pts/components/ita/ita_comp_ima.c index 703d2e16a..752aa267d 100644 --- a/src/libimcv/pts/components/ita/ita_comp_ima.c +++ b/src/libimcv/pts/components/ita/ita_comp_ima.c @@ -29,7 +29,6 @@ #define SECURITY_DIR "/sys/kernel/security/" #define IMA_BIOS_MEASUREMENTS SECURITY_DIR "tpm0/binary_bios_measurements" #define IMA_RUNTIME_MEASUREMENTS SECURITY_DIR "ima/binary_runtime_measurements" -#define IMA_FILENAME_LEN_MAX 255 typedef struct pts_ita_comp_ima_t pts_ita_comp_ima_t; typedef enum ima_state_t ima_state_t; @@ -118,6 +117,11 @@ struct pts_ita_comp_ima_t { */ bool pcr_info; + /** + * Whether to pad PCR measurements if matching hash is not available + */ + bool pcr_padding; + /** * Creation time of measurement */ @@ -165,16 +169,15 @@ struct pts_ita_comp_ima_t { */ 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) + uint32_t pcr, chunk_t measurement, + pts_pcr_transform_t pcr_transform) { - pts_pcr_transform_t pcr_transform; 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; pcr_algo = pcrs->get_pcr_algo(pcrs); - pcr_transform = PTS_PCR_TRANSFORM_MATCH; if (this->pcr_info) { @@ -199,24 +202,31 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, } /** - * Generate an IMA or IMA-NG hash from an event digest and event name - * - * @param digest event digest - * @param ima_algo hash algorithm string ("sha1:", "sha256:", etc.) - * @param ima_name event name - * @param little_endian endianness of client platform - * @param algo hash algorithm used by TPM - * @param hash_buf hash value to be compared with TPM measurement + * Compute and check boot aggregate value by hashing PCR0 to PCR7 */ -static bool ima_hash(chunk_t digest, char *ima_algo, char *ima_name, - bool little_endian, pts_meas_algorithms_t algo, - char *hash_buf) +static bool check_boot_aggregate(pts_pcr_t *pcrs, char *algo, bool pcr_padding, + chunk_t boot_aggregate, chunk_t measurement) + { + chunk_t ba_measurement; + uint8_t meas_buffer[HASH_SIZE_SHA512]; + size_t hash_size; + pts_meas_algorithms_t pcr_algo; hash_algorithm_t hash_alg; hasher_t *hasher; - bool success; + uint32_t i, pcr_max; + bool success, pcr_ok = TRUE; - hash_alg = pts_meas_algo_to_hash(algo); + /* determine PCR hash algorithm and the need for PCR padding */ + pcr_algo = pcrs->get_pcr_algo(pcrs); + if (pcr_algo == PTS_MEAS_ALGO_SHA1) + { + pcr_padding = FALSE; + } + + + /* create hasher for boot aggregate computation */ + hash_alg = pts_meas_algo_to_hash(pcr_algo); hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); if (!hasher) { @@ -224,90 +234,39 @@ static bool ima_hash(chunk_t digest, char *ima_algo, char *ima_name, hash_algorithm_short_names, hash_alg); return FALSE; } + hash_size = hasher->get_hash_size(hasher); - if (ima_algo) - { - uint32_t d_len, n_len; - chunk_t algo_name, event_name, digest_len, name_len; + /* Include PCR8 and PCR9 in boot aggregate with unpadded non-SHA1 hashes */ + pcr_max = (pcr_algo == PTS_MEAS_ALGO_SHA1 || pcr_padding) ? 7 : 9; - /* IMA-NG hash */ - algo_name = chunk_create(ima_algo, strlen(ima_algo) + 1); - event_name = chunk_create(ima_name, strlen(ima_name) + 1); - - d_len = algo_name.len + digest.len; - digest_len = chunk_create((uint8_t*)&d_len, sizeof(d_len)); - /* TODO handle endianness of both client and server platforms */ - - n_len = event_name.len; - name_len = chunk_create((uint8_t*)&n_len, sizeof(n_len)); - /* TODO handle endianness of both client and server platforms */ - - success = hasher->get_hash(hasher, digest_len, NULL) && - hasher->get_hash(hasher, algo_name, NULL) && - hasher->get_hash(hasher, digest, NULL) && - hasher->get_hash(hasher, name_len, NULL) && - hasher->get_hash(hasher, event_name, hash_buf); - } - else - { - u_char filename_buffer[IMA_FILENAME_LEN_MAX + 1]; - chunk_t file_name; - - /* IMA legacy hash */ - memset(filename_buffer, 0, sizeof(filename_buffer)); - strncpy(filename_buffer, ima_name, IMA_FILENAME_LEN_MAX); - file_name = chunk_create (filename_buffer, sizeof(filename_buffer)); - - success = hasher->get_hash(hasher, digest, NULL) && - hasher->get_hash(hasher, file_name, hash_buf); - } - hasher->destroy(hasher); - - return success; -} - -/** - * Compute and check boot aggregate value by hashing PCR0 to PCR7 - */ -static bool check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement, - char *algo) -{ - u_char pcr_buffer[HASH_SIZE_SHA1]; - chunk_t boot_aggregate; - hasher_t *hasher; - uint32_t i; - bool success, pcr_ok = TRUE; - - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) - { - DBG1(DBG_PTS, "%N hasher could not be created", - hash_algorithm_short_names, HASH_SHA1); - return FALSE; - } - for (i = 0; i < 8 && pcr_ok; i++) + /* the boot aggregate hash is computed over PCR0 .. PCR7/PCR9 */ + for (i = 0; i <= pcr_max && pcr_ok; i++) { pcr_ok = hasher->get_hash(hasher, pcrs->get(pcrs, i), NULL); } if (pcr_ok) { - pcr_ok = hasher->get_hash(hasher, chunk_empty, pcr_buffer); + pcr_ok = hasher->get_hash(hasher, chunk_empty, boot_aggregate.ptr); } hasher->destroy(hasher); + if (pcr_ok) { - boot_aggregate = chunk_create(pcr_buffer, sizeof(pcr_buffer)); - - /* TODO handle endianness of client platform */ - pcr_ok = ima_hash(boot_aggregate, algo, "boot_aggregate", - TRUE, PTS_MEAS_ALGO_SHA1, pcr_buffer); + ba_measurement = chunk_create(meas_buffer, hash_size); + if (pcr_padding) + { + memset(meas_buffer, 0x00, hash_size); + pcr_algo = PTS_MEAS_ALGO_SHA1; + } + pcr_ok = pts_ima_event_hash(boot_aggregate, algo, "boot_aggregate", + pcr_algo, meas_buffer); } if (pcr_ok) { - success = chunk_equals_const(boot_aggregate, measurement); - DBG1(DBG_PTS, "boot aggregate value is %scorrect", - success ? "":"in"); + success = chunk_equals_const(ba_measurement, measurement); + DBG1(DBG_PTS, "boot aggregate computed over PCR0..PCR%d is %scorrect", + pcr_max, success ? "":"in"); return success; } else @@ -340,9 +299,11 @@ METHOD(pts_component_t, measure, status_t, pts_comp_evidence_t **evidence) { pts_pcr_t *pcrs; + pts_meas_algorithms_t pcr_algo; pts_comp_evidence_t *evid = NULL; - size_t algo_len, name_len; - chunk_t measurement; + size_t algo_len, name_len, pcr_size; + chunk_t measurement, boot_aggregate; + uint8_t pcr_buffer[HASH_SIZE_SHA512]; char *uri, *algo, *name; uint32_t pcr; status_t status; @@ -352,6 +313,8 @@ METHOD(pts_component_t, measure, status_t, { return FAILED; } + pcr_algo = pcrs->get_pcr_algo(pcrs); + pcr_size = pts_meas_algo_hash_size(pcr_algo); if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL | PTS_ITA_QUALIFIER_TYPE_TRUSTED)) @@ -360,8 +323,7 @@ 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, - pcrs->get_pcr_algo(pcrs)); + IMA_BIOS_MEASUREMENTS, pcr_algo); if (!this->bios_list) { return FAILED; @@ -378,7 +340,8 @@ METHOD(pts_component_t, measure, status_t, DBG1(DBG_PTS, "could not retrieve bios measurement entry"); return status; } - evid = extend_pcr(this, qualifier, pcrs, pcr, measurement); + evid = extend_pcr(this, qualifier, pcrs, pcr, measurement, + PTS_PCR_TRANSFORM_MATCH); this->state = this->bios_list->get_count(this->bios_list) ? IMA_STATE_BIOS : IMA_STATE_INIT; @@ -393,8 +356,16 @@ METHOD(pts_component_t, measure, status_t, switch (this->state) { case IMA_STATE_INIT: + + /* disable padding for SHA1 legacy hash */ + if (pcr_algo == PTS_MEAS_ALGO_SHA1) + { + this->pcr_padding = FALSE; + } + this->ima_list = pts_ima_event_list_create( - IMA_RUNTIME_MEASUREMENTS); + IMA_RUNTIME_MEASUREMENTS, + pcr_algo, this->pcr_padding); if (!this->ima_list) { return FAILED; @@ -414,13 +385,17 @@ METHOD(pts_component_t, measure, status_t, } if (this->state == IMA_STATE_BOOT_AGGREGATE && this->bios_count) { - if (!check_boot_aggregate(pcrs, measurement, algo)) + boot_aggregate = chunk_create(pcr_buffer, pcr_size); + if (!check_boot_aggregate(pcrs, algo, this->pcr_padding, + boot_aggregate, measurement)) { return FAILED; } } - evid = extend_pcr(this, qualifier, pcrs, IMA_PCR, - measurement); + + evid = extend_pcr(this, qualifier, pcrs, IMA_PCR, measurement, + this->pcr_padding ? PTS_PCR_TRANSFORM_SHORT : + PTS_PCR_TRANSFORM_MATCH); if (evid) { if (algo) @@ -528,7 +503,8 @@ METHOD(pts_component_t, verify, status_t, { bool has_pcr_info; uint32_t pcr; - pts_meas_algorithms_t algo; + size_t pcr_size; + pts_meas_algorithms_t algo, pcr_algo; pts_pcr_transform_t transform; pts_pcr_t *pcrs; time_t creation_time; @@ -536,13 +512,25 @@ METHOD(pts_component_t, verify, status_t, status_t status = NOT_FOUND; this->aik_id = pts->get_aik_id(pts); + + pcrs = pts->get_pcrs(pts); if (!pcrs) { return FAILED; } + pcr_algo = pcrs->get_pcr_algo(pcrs); + pcr_size = pts_meas_algo_hash_size(pcr_algo); + measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform, &creation_time); + if (algo != pcr_algo) + { + DBG1(DBG_PTS, "received %N measurement hash but PCR bank is %N", + pts_meas_algorithm_names, algo, pts_meas_algorithm_names, algo); + return FAILED; + } + this->pcr_padding = (transform == PTS_PCR_TRANSFORM_SHORT); if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL | PTS_ITA_QUALIFIER_TYPE_TRUSTED)) @@ -606,6 +594,8 @@ METHOD(pts_component_t, verify, status_t, int ima_count; char *ima_algo, *ima_name; char algo_buf[IMA_ALGO_LEN_MAX]; + uint8_t pcr_buffer[HASH_SIZE_SHA512]; + chunk_t boot_aggregate; pts_meas_algorithms_t hash_algo; hash_algo = parse_validation_uri(evidence, &ima_name, &ima_algo, @@ -622,15 +612,17 @@ METHOD(pts_component_t, verify, status_t, "but is '%s'", ima_name); return FAILED; } - if (hash_algo != PTS_MEAS_ALGO_SHA1) + if (hash_algo != pcr_algo) { DBG1(DBG_PTS, "ima: boot_aggregate algorithm must be %N " "but is %N", - pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1, + pts_meas_algorithm_names, pcr_algo, pts_meas_algorithm_names, hash_algo); return FAILED; } - if (!check_boot_aggregate(pcrs, measurement, ima_algo)) + boot_aggregate = chunk_create(pcr_buffer, pcr_size); + if (!check_boot_aggregate(pcrs, ima_algo, this->pcr_padding, + boot_aggregate, measurement)) { return FAILED; } @@ -652,8 +644,8 @@ METHOD(pts_component_t, verify, status_t, DBG1(DBG_PTS, "checking boot aggregate evidence " "measurement"); status = this->pts_db->check_comp_measurement(this->pts_db, - measurement, this->ima_cid, - this->aik_id, 1, pcr, algo); + boot_aggregate, this->ima_cid, + this->aik_id, 1, pcr, algo); } else { @@ -661,8 +653,8 @@ METHOD(pts_component_t, verify, status_t, "measurement"); this->is_ima_registering = TRUE; status = this->pts_db->insert_comp_measurement(this->pts_db, - measurement, this->ima_cid, - this->aik_id, 1, pcr, algo); + boot_aggregate, this->ima_cid, + this->aik_id, 1, pcr, algo); } this->state = IMA_STATE_RUNTIME; @@ -673,20 +665,33 @@ METHOD(pts_component_t, verify, status_t, break; case IMA_STATE_RUNTIME: { - uint8_t hash_buf[HASH_SIZE_SHA512]; - uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf; chunk_t hex_digest, digest, hash; + uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf; + uint8_t hash_buf[HASH_SIZE_SHA512]; + size_t hash_size; + pts_meas_algorithms_t meas_algo; enumerator_t *e; this->count++; if (evidence->get_validation(evidence, NULL) != - PTS_COMP_EVID_VALIDATION_PASSED) + PTS_COMP_EVID_VALIDATION_PASSED) { DBG1(DBG_PTS, "evidence validation failed"); this->count_failed++; return FAILED; } - hash = chunk_create(hash_buf, pts_meas_algo_hash_size(algo)); + hash_size = pts_meas_algo_hash_size(algo); + hash = chunk_create(hash_buf, hash_size); + + if (this->pcr_padding) + { + memset(hash_buf, 0x00, hash_size); + meas_algo = PTS_MEAS_ALGO_SHA1; + } + else + { + meas_algo = algo; + } e = this->pts_db->create_file_meas_enumerator(this->pts_db, pts->get_platform_id(pts), @@ -697,8 +702,9 @@ METHOD(pts_component_t, verify, status_t, { hex_digest = chunk_from_str(hex_digest_buf); digest = chunk_from_hex(hex_digest, digest_buf); - if (!ima_hash(digest, ima_algo, ima_name, - FALSE, algo, hash_buf)) + + if (!pts_ima_event_hash(digest, ima_algo, ima_name, + meas_algo, hash_buf)) { status = FAILED; break; @@ -916,6 +922,8 @@ pts_component_t *pts_ita_comp_ima_create(uint32_t depth, .pts_db = pts_db, .pcr_info = lib->settings->get_bool(lib->settings, "%s.plugins.imc-attestation.pcr_info", FALSE, lib->ns), + .pcr_padding = lib->settings->get_bool(lib->settings, + "%s.plugins.imc-attestation.pcr_padding", FALSE, lib->ns), .ref = 1, ); diff --git a/src/libimcv/pts/pts_ima_event_list.c b/src/libimcv/pts/pts_ima_event_list.c index 9bff4654b..f361f2f94 100644 --- a/src/libimcv/pts/pts_ima_event_list.c +++ b/src/libimcv/pts/pts_ima_event_list.c @@ -31,6 +31,9 @@ typedef struct event_entry_t event_entry_t; #define IMA_NG_TYPE_LEN 6 #define IMA_TYPE_LEN_MAX 10 #define IMA_ALGO_DIGEST_LEN_MAX IMA_ALGO_LEN_MAX + HASH_SIZE_SHA512 +#define IMA_FILENAME_LEN_MAX 255 + + /** * Private data of a pts_ima_event_list_t object. @@ -61,7 +64,7 @@ struct private_pts_ima_event_list_t { struct event_entry_t { /** - * SHA1 measurement hash + * Special IMA measurement hash */ chunk_t measurement; @@ -125,11 +128,14 @@ METHOD(pts_ima_event_list_t, destroy, void, /** * See header */ -pts_ima_event_list_t* pts_ima_event_list_create(char *file) +pts_ima_event_list_t* pts_ima_event_list_create(char *file, + pts_meas_algorithms_t pcr_algo, bool pcr_padding) { private_pts_ima_event_list_t *this; event_entry_t *entry; + chunk_t digest; uint32_t pcr, type_len, name_len, eventdata_len, algo_digest_len, algo_len; + size_t hash_size; char type[IMA_TYPE_LEN_MAX]; char algo_digest[IMA_ALGO_DIGEST_LEN_MAX]; char *pos, *error = ""; @@ -164,6 +170,8 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) .list = linked_list_create(), ); + hash_size = pts_meas_algo_hash_size(pcr_algo); + while (TRUE) { /* read 32 bit PCR number in host order */ @@ -175,12 +183,13 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) DBG2(DBG_PTS, "loaded ima measurements '%s' (%d entries)", file, this->list->get_count(this->list)); close(fd); + return &this->public; } /* create and initialize new IMA entry */ entry = malloc_thing(event_entry_t); - entry->measurement = chunk_alloc(HASH_SIZE_SHA1); + entry->measurement = chunk_alloc(hash_size); entry->algo = NULL; entry->name = NULL; @@ -190,7 +199,12 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) break; } - /* read 20 byte SHA-1 measurement digest */ + if (pcr_padding) + { + memset(entry->measurement.ptr, 0x00, hash_size); + } + + /* read 20 byte SHA-1 IMA measurement digest */ if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1) { error = "invalid SHA-1 digest field"; @@ -271,6 +285,9 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) entry->algo = malloc(algo_len); memcpy(entry->algo, algo_digest, algo_len); + /* extract the digest */ + digest = chunk_create(pos + 1, algo_digest_len - algo_len); + /* read the 32 bit length of the event name in host order */ if (read(fd, &name_len, 4) != 4 || eventdata_len != 4 + algo_digest_len + 4 + name_len) @@ -288,6 +305,17 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) error = "invalid filename field"; break; } + + /* re-compute IMA measurement digest for non-SHA1 hash algorithms */ + if (pcr_algo != PTS_MEAS_ALGO_SHA1 && !pcr_padding) + { + if (!pts_ima_event_hash(digest, entry->algo, entry->name, + pcr_algo, entry->measurement.ptr)) + { + break; + } + + } } else { @@ -328,3 +356,61 @@ pts_ima_event_list_t* pts_ima_event_list_create(char *file) return NULL; } + +/** + * See header + */ +bool pts_ima_event_hash(chunk_t digest, char *ima_algo, char *ima_name, + pts_meas_algorithms_t pcr_algo, char *hash_buf) +{ + hash_algorithm_t hash_alg; + hasher_t *hasher; + bool success; + + hash_alg = pts_meas_algo_to_hash(pcr_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_alg); + return FALSE; + } + + if (ima_algo) + { + uint32_t ad_len, n_len; + chunk_t algo_name, event_name, algo_digest_len, name_len; + + /* IMA-NG hash */ + algo_name = chunk_create(ima_algo, strlen(ima_algo) + 1); + event_name = chunk_create(ima_name, strlen(ima_name) + 1); + + ad_len = htole32(algo_name.len + digest.len); + algo_digest_len = chunk_create((uint8_t*)&ad_len, sizeof(ad_len)); + + n_len = htole32(event_name.len); + name_len = chunk_create((uint8_t*)&n_len, sizeof(n_len)); + + success = hasher->get_hash(hasher, algo_digest_len, NULL) && + hasher->get_hash(hasher, algo_name, NULL) && + hasher->get_hash(hasher, digest, NULL) && + hasher->get_hash(hasher, name_len, NULL) && + hasher->get_hash(hasher, event_name, hash_buf); + } + else + { + u_char filename_buffer[IMA_FILENAME_LEN_MAX + 1]; + chunk_t file_name; + + /* IMA legacy hash */ + memset(filename_buffer, 0, sizeof(filename_buffer)); + strncpy(filename_buffer, ima_name, IMA_FILENAME_LEN_MAX); + file_name = chunk_create (filename_buffer, sizeof(filename_buffer)); + + success = hasher->get_hash(hasher, digest, NULL) && + hasher->get_hash(hasher, file_name, hash_buf); + } + hasher->destroy(hasher); + + return success; +} diff --git a/src/libimcv/pts/pts_ima_event_list.h b/src/libimcv/pts/pts_ima_event_list.h index bab2e9586..e793c63e2 100644 --- a/src/libimcv/pts/pts_ima_event_list.h +++ b/src/libimcv/pts/pts_ima_event_list.h @@ -21,6 +21,8 @@ #ifndef PTS_IMA_EVENT_LIST_H_ #define PTS_IMA_EVENT_LIST_H_ +#include "pts_meas_algo.h" + #include #include @@ -56,7 +58,7 @@ struct pts_ima_event_list_t { * Get the next file measurement and remove it from the list * * @param measurement Measurement hash - * @param algo Algorithm used to hash files + * @param algo Algorithm used to compute file digests " @param name Event name (absolute filename or boot_aggregate) * @return Return code */ @@ -74,7 +76,23 @@ struct pts_ima_event_list_t { * Create a PTS IMA runtime file measurement object * * @param file Pathname pointing to the IMA runtime measurements + * @param pcr_algo PCR hash measurement algorithm to be used + * @param pcr_padding Apply PCR hash padding if hash algorithm is lacking */ -pts_ima_event_list_t* pts_ima_event_list_create(char *file); +pts_ima_event_list_t* pts_ima_event_list_create(char *file, + pts_meas_algorithms_t pcr_algo, bool pcr_padding); + +/** + * Generate an IMA or IMA-NG hash from an event digest and event name + * + * @param digest event digest + * @param ima_algo event digest algorithm string ("sha1:", "sha256:", etc.) + * @param ima_name event name + * @param pcr_algo hash algorithm used by TPM PCR extension + * @param hash_buf hash value to be compared with TPM measurement + * @return TRUE if computation successful + */ +bool pts_ima_event_hash(chunk_t digest, char *ima_algo, char *ima_name, + pts_meas_algorithms_t pcr_algo, char *hash_buf); #endif /** PTS_IMA_EVENT_LIST_H_ @}*/