pts: Parse TPM 2.0 BIOS/EFI event log

This commit is contained in:
Andreas Steffen
2020-10-07 16:54:32 +02:00
parent da1d7815ef
commit d647a8f91d
13 changed files with 376 additions and 69 deletions
+10 -1
View File
@@ -1,6 +1,6 @@
/*
* 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
@@ -166,6 +166,15 @@ struct tpm_tss_t {
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.
*/
+12 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Andreas Steffen
* Copyright (C) 2016-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (c) 2008 Hal Finney
@@ -35,6 +35,8 @@
#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 */
@@ -609,6 +611,14 @@ METHOD(tpm_tss_t, get_data, bool,
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)
{
@@ -655,6 +665,7 @@ tpm_tss_t *tpm_tss_trousers_create()
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
.get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.load_aik = _load_aik,
+49 -4
View File
@@ -1,6 +1,6 @@
/*
* 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
@@ -22,10 +22,13 @@
#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 */
@@ -66,6 +69,11 @@ struct private_tpm_tss_tss2_t {
*/
size_t supported_algs_count;
/**
* TPM version info
*/
chunk_t version_info;
/**
* List of supported algorithms
*/
@@ -158,16 +166,34 @@ static bool is_supported_alg(private_tpm_tss_tss2_t *this, TPM_ALG_ID alg_id)
}
/**
* 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;
@@ -200,6 +226,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
year = tp.value;
break;
case TPM_PT_MANUFACTURER:
vendor = tp.value;
htoun32(manufacturer, tp.value);
break;
case TPM_PT_VENDOR_STRING_1:
@@ -229,6 +256,16 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
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,
@@ -429,7 +466,7 @@ METHOD(tpm_tss_t, get_version, tpm_version_t,
METHOD(tpm_tss_t, get_version_info, chunk_t,
private_tpm_tss_tss2_t *this)
{
return chunk_empty;
return this->version_info;
}
/**
@@ -1302,11 +1339,18 @@ METHOD(tpm_tss_t, get_data, bool,
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);
}
@@ -1331,6 +1375,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
.get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+101 -4
View File
@@ -1,6 +1,6 @@
/*
* 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
@@ -22,6 +22,7 @@
#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>
@@ -62,6 +63,11 @@ struct private_tpm_tss_tss2_t {
*/
size_t supported_algs_count;
/**
* TPM version info
*/
chunk_t version_info;
/**
* List of supported algorithms
*/
@@ -169,16 +175,34 @@ static bool is_supported_alg(private_tpm_tss_tss2_t *this, TPM2_ALG_ID alg_id)
}
/**
* 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;
@@ -212,6 +236,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
year = tp.value;
break;
case TPM2_PT_MANUFACTURER:
vendor = tp.value;
htoun32(manufacturer, tp.value);
break;
case TPM2_PT_VENDOR_STRING_1:
@@ -241,6 +266,16 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
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,
@@ -401,7 +436,7 @@ METHOD(tpm_tss_t, get_version, tpm_version_t,
METHOD(tpm_tss_t, get_version_info, chunk_t,
private_tpm_tss_tss2_t *this)
{
return chunk_empty;
return this->version_info;
}
/**
@@ -1204,11 +1239,72 @@ METHOD(tpm_tss_t, get_data, bool,
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);
}
@@ -1233,6 +1329,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.sign = _sign,
.get_random = _get_random,
.get_data = _get_data,
.get_event_digest = _get_event_digest,
.destroy = _destroy,
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),