/*
- * Copyright (C) 2011-2017 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
status_t status;
pcrs = pts->get_pcrs(pts);
+ if (!pcrs)
+ {
+ return FAILED;
+ }
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
switch (this->state)
{
case IMA_STATE_INIT:
- this->bios_list = pts_ima_bios_list_create(
- IMA_BIOS_MEASUREMENTS);
+ this->bios_list = pts_ima_bios_list_create(pts->get_tpm(pts),
+ IMA_BIOS_MEASUREMENTS);
if (!this->bios_list)
{
return FAILED;
this->aik_id = pts->get_aik_id(pts);
pcrs = pts->get_pcrs(pts);
+ if (!pcrs)
+ {
+ return FAILED;
+ }
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
&creation_time);
/*
- * Copyright (C) 2011-2015 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
}
pcrs = pts->get_pcrs(pts);
+ if (!pcrs)
+ {
+ return FAILED;
+ }
pcrs->set(pcrs, extended_pcr, pcr_after);
evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
this->depth, extended_pcr, hash_algo, pcr_transform,
this->aik_id = pts->get_aik_id(pts);
pcrs = pts->get_pcrs(pts);
+ if (!pcrs)
+ {
+ return FAILED;
+ }
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
/*
- * Copyright (C) 2011-2012 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
chunk_t measurement __attribute__((unused));
pcrs = pts->get_pcrs(pts);
+ if (!pcrs)
+ {
+ return FAILED;
+ }
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
if (extended_pcr != PCR_DEBUG)
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2012-2016 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
#include <bio/bio_writer.h>
#include <bio/bio_reader.h>
-#include <tpm_tss.h>
#include <tpm_tss_trousers.h>
#include <sys/types.h>
bool is_imc;
/**
- * Active TPM
+ * IMC-PTS: own TPM / IMV-PTS: unused
*/
tpm_tss_t *tpm;
/**
- * Contains a TPM_CAP_VERSION_INFO struct
+ * IMC-PTS: own TPM version / IMV-PTS: peer TPM version
+ */
+ tpm_version_t tpm_version;
+
+ /**
+ * Contains a TPM Version Info struct
*/
chunk_t tpm_version_info;
this->platform_id = pid;
}
+METHOD(pts_t, get_tpm, tpm_tss_t*,
+ private_pts_t *this)
+{
+ return this->tpm;
+}
+
METHOD(pts_t, get_tpm_version_info, bool,
private_pts_t *this, chunk_t *info)
{
return info->len > 0;
}
+#define TPM_VERSION_INFO_TAG_1_2 0x0030
+#define TPM_VERSION_INFO_TAG_2_0 0x0200
+#define TPM_VERSION_INFO_LABEL "Version Information: TPM"
+
METHOD(pts_t, set_tpm_version_info, void,
private_pts_t *this, chunk_t info)
{
+ bio_reader_t *reader;
+ uint16_t tpm_version_info_tag;
+ chunk_t vendor;
+
+ reader = bio_reader_create(info);
+ reader->read_uint16(reader, &tpm_version_info_tag);
+
+ if (tpm_version_info_tag == TPM_VERSION_INFO_TAG_1_2)
+ {
+ uint8_t major, minor, rev_major, rev_minor, errata_rev;
+ uint16_t spec_level;
+
+ this->tpm_version = TPM_VERSION_1_2;
+
+ if (reader->read_uint8 (reader, &major) &&
+ reader->read_uint8 (reader, &minor) &&
+ reader->read_uint8 (reader, &rev_major) &&
+ reader->read_uint8 (reader, &rev_minor) &&
+ reader->read_uint16(reader, &spec_level) &&
+ reader->read_uint8 (reader, &errata_rev) &&
+ reader->read_data (reader, 4, &vendor))
+ {
+ DBG2(DBG_PTS, "%s 1.2 rev. %u.%u.%u.%u %.*s", TPM_VERSION_INFO_LABEL,
+ (uint32_t)major, (uint32_t)minor, (uint32_t)rev_major,
+ (uint32_t)rev_minor, vendor.len, vendor.ptr);
+ }
+ else
+ {
+ DBG2(DBG_PTS, "%s 1.2", TPM_VERSION_INFO_LABEL);
+ }
+
+ }
+ else if (tpm_version_info_tag == TPM_VERSION_INFO_TAG_2_0)
+ {
+ uint32_t revision, year;
+ uint8_t reserved, locality;
+
+ this->tpm_version = TPM_VERSION_2_0;
+
+ if (reader->read_uint16(reader, &reserved) &&
+ reader->read_uint32(reader, &revision) &&
+ reader->read_uint32(reader, &year) &&
+ reader->read_data (reader, 4, &vendor))
+ {
+ DBG2(DBG_PTS, "%s 2.0 rev. %4.2f %u %.*s - startup locality: %u",
+ TPM_VERSION_INFO_LABEL, revision/100.0, year,
+ vendor.len, vendor.ptr, (uint32_t)locality);
+ }
+ else
+ {
+ DBG2(DBG_PTS, "%s 2.0", TPM_VERSION_INFO_LABEL);
+ }
+ }
+ reader->destroy(reader);
+
this->tpm_version_info = chunk_clone(info);
}
METHOD(pts_t, get_pcrs, pts_pcr_t*,
private_pts_t *this)
{
+ if (!this->pcrs)
+ {
+ this->pcrs = pts_pcr_create(this->tpm_version);
+ }
return this->pcrs;
}
pts_t *pts_create(bool is_imc)
{
private_pts_t *this;
- pts_pcr_t *pcrs;
-
- pcrs = pts_pcr_create();
- if (!pcrs)
- {
- DBG1(DBG_PTS, "shadow PCR set could not be created");
- return NULL;
- }
INIT(this,
.public = {
.calculate_secret = _calculate_secret,
.get_platform_id = _get_platform_id,
.set_platform_id = _set_platform_id,
+ .get_tpm = _get_tpm,
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
.get_aik = _get_aik,
.proto_caps = PTS_PROTO_CAPS_V,
.algorithm = PTS_MEAS_ALGO_SHA256,
.dh_hash_algorithm = PTS_MEAS_ALGO_SHA256,
- .pcrs = pcrs,
);
if (is_imc)
if (this->tpm)
{
this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_D;
+ this->tpm_version = this->tpm->get_version(this->tpm);
load_aik(this);
}
}
else
{
this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_D;
+ this->tpm_version = TPM_VERSION_2_0;
}
return &this->public;
/*
* Copyright (C) 2011 Sansar Choinyambuu
- * Copyright (C) 2012-2016 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
#include "components/pts_comp_func_name.h"
#include <tpm_tss_quote_info.h>
+#include <tpm_tss.h>
#include <library.h>
#include <collections/linked_list.h>
*/
void (*set_platform_id)(pts_t *this, int pid);
+ /**
+ * Get TPM object handle
+ *
+ * @return TPM object handle
+ */
+ tpm_tss_t* (*get_tpm)(pts_t *this);
+
/**
* Get TPM 1.2 Version Info
*
- * @param info chunk containing a TPM_CAP_VERSION_INFO struct
- * @return TRUE if TPM Version Info available
+ * @param info chunk containing a TPM_Version Info struct
+ * @return TRUE if TPM Version_Info available
*/
bool (*get_tpm_version_info)(pts_t *this, chunk_t *info);
/**
* Set TPM 1.2 Version Info
*
- * @param info chunk containing a TPM_CAP_VERSION_INFO struct
+ * @param info chunk containing a TPM Version Info struct
*/
void (*set_tpm_version_info)(pts_t *this, chunk_t info);
/*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
typedef struct bios_entry_t bios_entry_t;
typedef enum event_type_t event_type_t;
+/* BIOS Events (TCG PC Client Specification for Conventional BIOS 1.21) */
enum event_type_t {
- /* BIOS Events (TCG PC Client Specification for Conventional BIOS 1.21) */
EV_PREBOOT_CERT = 0x00000000,
EV_POST_CODE = 0x00000001,
EV_UNUSED = 0x00000002,
EV_OMIT_BOOT_DEVICE_EVENTS = 0x00000012,
/* EFI Events (TCG EFI Platform Specification 1.22) */
- EV_EFI_EVENT_BASE = 0x80000000,
- EV_EFI_VARIABLE_DRIVER_CONFIG = 0x80000001,
- EV_EFI_VARIABLE_BOOT = 0x80000002,
- EV_EFI_BOOT_SERVICES_APPLICATION = 0x80000003,
- EV_EFI_BOOT_SERVICES_DRIVER = 0x80000004,
- EV_EFI_RUNTIME_SERVICES_DRIVER = 0x80000005,
- EV_EFI_GPT_EVENT = 0x80000006,
- EV_EFI_ACTION = 0x80000007,
- EV_EFI_PLATFORM_FIRMWARE_BLOB = 0x80000008,
- EV_EFI_HANDOFF_TABLES = 0x80000009,
-
- EV_EFI_HCRTM_EVENT = 0x80000010,
-
- EV_EFI_VARIABLE_AUTHORITY = 0x800000E0
+ EV_EFI_VARIABLE_DRIVER_CONFIG = 0x70000001,
+ EV_EFI_VARIABLE_BOOT = 0x70000002,
+ EV_EFI_BOOT_SERVICES_APPLICATION = 0x70000003,
+ EV_EFI_BOOT_SERVICES_DRIVER = 0x70000004,
+ EV_EFI_RUNTIME_SERVICES_DRIVER = 0x70000005,
+ EV_EFI_GPT_EVENT = 0x70000006,
+ EV_EFI_ACTION = 0x70000007,
+ EV_EFI_PLATFORM_FIRMWARE_BLOB = 0x70000008,
+ EV_EFI_HANDOFF_TABLES = 0x70000009,
+
+ EV_EFI_HCRTM_EVENT = 0x70000010,
+
+ EV_EFI_VARIABLE_AUTHORITY = 0x700000E0,
};
+/* By subtracting an offset from EFI events the enum will always be positive */
+#define EV_EFI_EVENT_BASE 0x80000000
+#define EV_EFI_OFFSET 0x10000000
+
ENUM_BEGIN(event_type_names, EV_PREBOOT_CERT, EV_OMIT_BOOT_DEVICE_EVENTS,
"Preboot Cert",
"POST Code",
"Nonhost Info",
"Omit Boot Device Events"
);
-ENUM_NEXT(event_type_names, EV_EFI_EVENT_BASE, EV_EFI_HANDOFF_TABLES,
+ENUM_NEXT(event_type_names, EV_EFI_VARIABLE_DRIVER_CONFIG, EV_EFI_HANDOFF_TABLES,
EV_OMIT_BOOT_DEVICE_EVENTS,
- "EFI Event Base",
"EFI Variable Driver Config",
"EFI Variable Boot",
"EFI Boot Services Application",
/**
* See header
*/
-pts_ima_bios_list_t* pts_ima_bios_list_create(char *file)
+pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file)
{
private_pts_ima_bios_list_t *this;
- uint32_t pcr, event_type, event_len, seek_len;
- uint32_t buf_len = 2048;
+ uint32_t pcr, ev_type, event_type, event_len, seek_len, count = 1;
+ uint32_t buf_len = 8192;
uint8_t event_buf[buf_len];
chunk_t event;
bios_entry_t *entry;
ssize_t res;
int fd;
+ if (!tpm)
+ {
+ DBG1(DBG_PTS, "no TPM available");
+ return NULL;
+ }
+
fd = open(file, O_RDONLY);
if (fd == -1)
{
.list = linked_list_create(),
);
- DBG2(DBG_PTS, "PCR Event Type (Size)");
+ DBG2(DBG_PTS, "No. PCR Event Type (Size)");
while (TRUE)
{
res = read(fd, &pcr, 4);
entry = malloc_thing(bios_entry_t);
entry->pcr = pcr;
- entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
+ entry->measurement = chunk_empty;
if (res != 4)
{
{
break;
}
- if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
+ if (!tpm->get_event_digest(tpm, fd, &entry->measurement))
{
break;
}
{
break;
}
- DBG2(DBG_PTS, "%2u %N (%u bytes)", pcr, event_type_names, event_type,
- event_len);
-
+ ev_type = (event_type < EV_EFI_EVENT_BASE) ?
+ event_type : event_type - EV_EFI_OFFSET;
+ DBG2(DBG_PTS, "%3u %2u %N (%u bytes)", count, pcr, event_type_names,
+ ev_type, event_len);
seek_len = (event_len > buf_len) ? event_len - buf_len : 0;
event_len -= seek_len;
{
break;
}
- event = chunk_create(event_buf, event_len);
- DBG3(DBG_PTS,"%B", &event);
- if (event_type == EV_ACTION || event_type == EV_EFI_ACTION)
+ switch (event_type)
{
- DBG2(DBG_PTS, " '%.*s'", event_len, event_buf);
+ case EV_PREBOOT_CERT:
+ case EV_POST_CODE:
+ case EV_NO_ACTION:
+ case EV_ACTION:
+ case EV_EFI_ACTION:
+ case EV_S_CRTM_CONTENTS:
+ case EV_IPL:
+ if (event_type == EV_NO_ACTION && event_len == 17 &&
+ streq(event_buf, "StartupLocality"))
+ {
+ DBG2(DBG_PTS, " 'StartupLocality' %x", event_buf[16]);
+ }
+ else
+ {
+ DBG2(DBG_PTS, " '%.*s'", event_len, event_buf);
+ }
+ break;
+ default:
+ break;
}
+ event = chunk_create(event_buf, event_len);
+ DBG3(DBG_PTS,"%B", &event);
if (seek_len > 0 && lseek(fd, seek_len, SEEK_CUR) == -1)
{
break;
}
- this->list->insert_last(this->list, entry);
+ if (event_type == EV_NO_ACTION || entry->measurement.len == 0)
+ {
+ free_bios_entry(entry);
+ DBG2(DBG_PTS, " Not extended into PCR!");
+ }
+ else
+ {
+ this->list->insert_last(this->list, entry);
+ count++;
+ }
}
- DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s", file,
- strerror(errno));
+ DBG1(DBG_PTS, "loading bios measurements '%s' failed", file);
free_bios_entry(entry);
close(fd);
destroy(this);
/*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <time.h>
#include <library.h>
+#include <tpm_tss.h>
typedef struct pts_ima_bios_list_t pts_ima_bios_list_t;
/**
* Create a PTS IMA BIOS measurement object
*
+ * @param tpm TPM object
* @param file Pathname pointing to the BIOS measurements
*/
-pts_ima_bios_list_t* pts_ima_bios_list_create(char *file);
+pts_ima_bios_list_t* pts_ima_bios_list_create(tpm_tss_t *tpm, char *file);
#endif /** PTS_IMA_BIOS_LIST_H_ @}*/
/**
* See header
*/
-pts_pcr_t *pts_pcr_create(void)
+pts_pcr_t *pts_pcr_create(tpm_version_t tpm_version)
{
private_pts_pcr_t *this;
hasher_t *hasher;
memset(this->pcrs[i].ptr, 0x00, PTS_PCR_LEN);
}
+ /* Set locality indicator in PCR[0] */
+ if (tpm_version == TPM_VERSION_2_0)
+ {
+ const uint8_t locality = 3;
+
+ DBG2(DBG_PTS, "TPM 2.0 - locality indicator set to %u",
+ (uint32_t)locality);
+ this->pcrs[0].ptr[PTS_PCR_LEN - 1] = locality;
+ }
+
return &this->public;
}
#include <library.h>
+#include <tpm_tss.h>
#include <tpm_tss_quote_info.h>
/**
/**
* Creates an pts_pcr_t object
+ *
+ * @param tpm_version TPM version
*/
-pts_pcr_t* pts_pcr_create(void);
+pts_pcr_t* pts_pcr_create(tpm_version_t tpm_version);
#endif /** PTS_PCR_H_ @}*/
/*
* Copyright (C) 2018 Tobias Brunner
- * Copyright (C) 2016-2018 Andreas Steffen
+ * Copyright (C) 2016-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
bool (*get_data)(tpm_tss_t *this, uint32_t hierarchy, uint32_t handle,
chunk_t pin, chunk_t *data);
+ /**
+ * Get an event digest from a TPM measurement log
+ *
+ * @param fd file descriptor of the measurement log
+ * @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);
+
/**
* Destroy a tpm_tss_t.
*/
/*
- * Copyright (C) 2016 Andreas Steffen
+ * Copyright (C) 2016-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (c) 2008 Hal Finney
#include <trousers/tss.h>
#include <trousers/trousers.h>
+#include <unistd.h>
+
#define LABEL "TPM 1.2 -"
/* size in bytes of a TSS AIK public key blob */
return FALSE;
}
+METHOD(tpm_tss_t, get_event_digest, bool,
+ private_tpm_tss_trousers_t *this, int fd, chunk_t *digest)
+{
+ *digest = chunk_alloc(HASH_SIZE_SHA1);
+
+ return read(fd, digest->ptr, digest->len) == digest->len;
+}
+
METHOD(tpm_tss_t, destroy, void,
private_tpm_tss_trousers_t *this)
{
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
+ .get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.load_aik = _load_aik,
/*
* Copyright (C) 2018 Tobias Brunner
- * Copyright (C) 2016-2019 Andreas Steffen
+ * Copyright (C) 2016-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <asn1/asn1.h>
#include <asn1/oid.h>
#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
#include <threading/mutex.h>
#include <tpm20.h>
+#include <unistd.h>
+
#ifdef TSS2_TCTI_TABRMD
#include <tcti/tcti-tabrmd.h>
#endif /* TSS2_TCTI_TABRMD */
*/
size_t supported_algs_count;
+ /**
+ * TPM version info
+ */
+ chunk_t version_info;
+
/**
* List of supported algorithms
*/
}
/**
- * Get a list of supported algorithms
+ * Get the TPM version_info and a list of supported algorithms
+ *
+ * 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
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TPM 2.0 Version_Info Tag | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Revision |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Year |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Vendor |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
+#define TPM2_VERSION_INFO_TAG 0x0200
+#define TPM2_VERSION_INFO_RESERVED 0x0000
+#define TPM2_VERSION_INFO_SIZE 16
+
static bool get_algs_capability(private_tpm_tss_tss2_t *this)
{
TPMS_CAPABILITY_DATA cap_data;
TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM_ALG_ID alg;
+ bio_writer_t *writer;
bool fips_140_2 = FALSE;
- uint32_t rval, i, offset, revision = 0, year = 0;
+ uint32_t rval, i, offset, revision = 0, year = 0, vendor = 0;
size_t len = BUF_LEN;
char buf[BUF_LEN], manufacturer[5], vendor_string[17];
char *pos = buf;
year = tp.value;
break;
case TPM_PT_MANUFACTURER:
+ vendor = tp.value;
htoun32(manufacturer, tp.value);
break;
case TPM_PT_VENDOR_STRING_1:
manufacturer, vendor_string, (float)revision/100, year,
fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
+ /* construct TPM 2.0 version_info object */
+ writer = bio_writer_create( TPM2_VERSION_INFO_SIZE);
+ writer->write_uint16(writer, TPM2_VERSION_INFO_TAG);
+ writer->write_uint16(writer, TPM2_VERSION_INFO_RESERVED);
+ writer->write_uint32(writer, revision);
+ writer->write_uint32(writer, year);
+ writer->write_uint32(writer, vendor);
+ this->version_info = writer->extract_buf(writer);
+ writer->destroy(writer);
+
/* get supported algorithms */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS,
METHOD(tpm_tss_t, get_version_info, chunk_t,
private_tpm_tss_tss2_t *this)
{
- return chunk_empty;
+ return this->version_info;
}
/**
return TRUE;
}
+METHOD(tpm_tss_t, get_event_digest, bool,
+ private_tpm_tss_tss2_t *this, int fd, chunk_t *digest)
+{
+ return FALSE;
+}
+
METHOD(tpm_tss_t, destroy, void,
private_tpm_tss_tss2_t *this)
{
finalize_context(this);
this->mutex->destroy(this->mutex);
+ free(this->version_info.ptr);
free(this);
}
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
+ .get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
/*
* Copyright (C) 2018 Tobias Brunner
- * Copyright (C) 2018-2019 Andreas Steffen
+ * Copyright (C) 2018-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <asn1/asn1.h>
#include <asn1/oid.h>
#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
#include <threading/mutex.h>
#include <tss2/tss2_sys.h>
*/
size_t supported_algs_count;
+ /**
+ * TPM version info
+ */
+ chunk_t version_info;
+
/**
* List of supported algorithms
*/
}
/**
- * Get a list of supported algorithms
+ * Get the TPM version_info and a list of supported algorithms
+ *
+ * 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
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TPM 2.0 Version_Info Tag | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Revision |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Year |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Vendor |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
+#define TPM2_VERSION_INFO_TAG 0x0200
+#define TPM2_VERSION_INFO_RESERVED 0x0000
+#define TPM2_VERSION_INFO_SIZE 16
+
static bool get_algs_capability(private_tpm_tss_tss2_t *this)
{
TPMS_CAPABILITY_DATA cap_data;
TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM2_ALG_ID alg;
+ bio_writer_t *writer;
bool fips_140_2 = FALSE;
- uint32_t rval, i, offset, revision = 0, year = 0;
+ uint32_t rval, i, offset, revision = 0, year = 0, vendor = 0;
size_t len = BUF_LEN;
char buf[BUF_LEN], manufacturer[5], vendor_string[17];
char *pos = buf;
year = tp.value;
break;
case TPM2_PT_MANUFACTURER:
+ vendor = tp.value;
htoun32(manufacturer, tp.value);
break;
case TPM2_PT_VENDOR_STRING_1:
manufacturer, vendor_string, (float)revision/100, year,
fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
+ /* construct TPM 2.0 version_info object */
+ writer = bio_writer_create( TPM2_VERSION_INFO_SIZE);
+ writer->write_uint16(writer, TPM2_VERSION_INFO_TAG);
+ writer->write_uint16(writer, TPM2_VERSION_INFO_RESERVED);
+ writer->write_uint32(writer, revision);
+ writer->write_uint32(writer, year);
+ writer->write_uint32(writer, vendor);
+ this->version_info = writer->extract_buf(writer);
+ writer->destroy(writer);
+
/* get supported algorithms */
this->mutex->lock(this->mutex);
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ALGS,
METHOD(tpm_tss_t, get_version_info, chunk_t,
private_tpm_tss_tss2_t *this)
{
- return chunk_empty;
+ return this->version_info;
}
/**
return TRUE;
}
+METHOD(tpm_tss_t, get_event_digest, bool,
+ private_tpm_tss_tss2_t *this, int fd, chunk_t *digest)
+{
+ uint8_t digest_buf[HASH_SIZE_SHA512];
+ uint32_t digest_count;
+ size_t digest_len = 0;
+ hash_algorithm_t hash_alg;
+ TPM2_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 == HASH_SHA1)
+ {
+ *digest = chunk_alloc(digest_len);
+ if (read(fd, digest->ptr, digest_len) != digest_len)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* currently skip non-SHA1 digests */
+ if (read(fd, digest_buf, digest_len) != digest_len)
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
METHOD(tpm_tss_t, destroy, void,
private_tpm_tss_tss2_t *this)
{
finalize_context(this);
this->mutex->destroy(this->mutex);
+ free(this->version_info.ptr);
free(this);
}
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
+ .get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),