implemented support if functional sub-components

This commit is contained in:
Andreas Steffen
2012-07-30 20:49:42 +02:00
parent e0c66bebcf
commit af8354da1a
19 changed files with 637 additions and 292 deletions
+358 -204
View File
@@ -80,20 +80,30 @@ struct pts_ita_comp_ima_t {
*/
pts_database_t *pts_db;
/**
* Primary key for Component Functional Name database entry
*/
int cid;
/**
* Primary key for AIK database entry
*/
int kid;
/**
* Component is registering measurements
* Primary key for IMA BIOS Component Functional Name database entry
*/
bool is_registering;
int bios_cid;
/**
* Primary key for IMA Runtime Component Functional Name database entry
*/
int ima_cid;
/**
* Component is registering IMA BIOS measurements
*/
bool is_bios_registering;
/**
* Component is registering IMA boot aggregate measurement
*/
bool is_ima_registering;
/**
* Measurement sequence number
@@ -155,6 +165,11 @@ struct pts_ita_comp_ima_t {
*/
int count_failed;
/**
* Reference count
*/
refcount_t ref;
};
/**
@@ -369,12 +384,14 @@ static bool load_runtime_measurements(char *file, linked_list_t *list,
/**
* Extend measurement into PCR an create evidence
*/
static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs,
static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this,
u_int8_t qualifier, pts_pcr_t *pcrs,
u_int32_t pcr, chunk_t measurement)
{
size_t pcr_len;
pts_pcr_transform_t pcr_transform;
pts_meas_algorithms_t hash_algo;
pts_comp_func_name_t *name;
pts_comp_evidence_t *evidence;
chunk_t pcr_before = chunk_empty, pcr_after = chunk_empty;
@@ -392,9 +409,10 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
free(pcr_before.ptr);
return NULL;
}
evidence = pts_comp_evidence_create(this->name->clone(this->name),
this->depth, pcr, hash_algo, pcr_transform,
this->measurement_time, measurement);
name = this->name->clone(this->name);
name->set_qualifier(name, qualifier);
evidence = pts_comp_evidence_create(name, this->depth, pcr, hash_algo,
pcr_transform, this->measurement_time, measurement);
if (this->pcr_info)
{
pcr_after =chunk_clone(pcrs->get(pcrs, pcr));
@@ -406,20 +424,21 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
/**
* Compute and check boot aggregate value by hashing PCR0 to PCR7
*/
static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
static bool check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
{
u_int32_t i;
u_char filename_buffer[IMA_FILENAME_LEN_MAX + 1];
u_char pcr_buffer[HASH_SIZE_SHA1];
chunk_t file_name, boot_aggregate;
hasher_t *hasher;
bool pcr_ok = TRUE;
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++)
{
@@ -440,12 +459,15 @@ static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
if (pcr_ok)
{
success = chunk_equals(boot_aggregate, measurement);
DBG1(DBG_PTS, "boot aggregate value is %scorrect",
chunk_equals(boot_aggregate, measurement) ? "":"in");
success ? "":"in");
return success;
}
else
{
DBG1(DBG_PTS, "failed to compute boot aggregate value");
return FALSE;
}
}
@@ -468,7 +490,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
pts_ita_comp_ima_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t **evidence)
{
bios_entry_t *bios_entry;
ima_entry_t *ima_entry;
@@ -478,84 +501,107 @@ METHOD(pts_component_t, measure, status_t,
pcrs = pts->get_pcrs(pts);
switch (this->state)
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
{
case IMA_STATE_INIT:
if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS, this->bios_list,
&this->measurement_time))
{
return FAILED;
}
this->state = IMA_STATE_BIOS;
/* fall through to next state */
case IMA_STATE_BIOS:
status = this->bios_list->remove_first(this->bios_list,
(void**)&bios_entry);
if (status != SUCCESS)
{
DBG1(DBG_PTS, "could not retrieve bios measurement entry");
return status;
}
evid = extend_pcr(this, pcrs, bios_entry->pcr,
bios_entry->measurement);
free(bios_entry);
switch (this->state)
{
case IMA_STATE_INIT:
if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS,
this->bios_list, &this->measurement_time))
{
return FAILED;
}
this->bios_count = this->bios_list->get_count(this->bios_list);
this->state = IMA_STATE_BIOS;
/* fall through to next state */
case IMA_STATE_BIOS:
status = this->bios_list->remove_first(this->bios_list,
(void**)&bios_entry);
if (status != SUCCESS)
{
DBG1(DBG_PTS, "could not retrieve bios measurement entry");
return status;
}
evid = extend_pcr(this, qualifier, pcrs, bios_entry->pcr,
bios_entry->measurement);
free(bios_entry);
/* break if still some BIOS measurements are left */
if (this->bios_list->get_count(this->bios_list))
{
this->state = this->bios_list->get_count(this->bios_list) ?
IMA_STATE_BIOS : IMA_STATE_INIT;
break;
}
/* check if IMA runtime measurements are enabled */
if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
this->ima_list, &this->measurement_time))
{
default:
return FAILED;
}
}
}
else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_OS))
{
switch (this->state)
{
case IMA_STATE_INIT:
if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
this->ima_list, &this->measurement_time))
{
return FAILED;
}
this->state = IMA_STATE_BOOT_AGGREGATE;
/* fall through to next state */
case IMA_STATE_BOOT_AGGREGATE:
case IMA_STATE_RUNTIME:
status = this->ima_list->remove_first(this->ima_list,
(void**)&ima_entry);
if (status != SUCCESS)
{
DBG1(DBG_PTS, "could not retrieve ima measurement entry");
return status;
}
if (this->state == IMA_STATE_BOOT_AGGREGATE && this->bios_count)
{
if (!check_boot_aggregate(pcrs, ima_entry->measurement))
{
return FAILED;
}
}
evid = extend_pcr(this, qualifier, pcrs, IMA_PCR,
ima_entry->measurement);
if (evid)
{
evid->set_validation(evid, PTS_COMP_EVID_VALIDATION_PASSED,
ima_entry->filename);
}
free(ima_entry->filename);
free(ima_entry);
this->state = this->ima_list->get_count(this->ima_list) ?
IMA_STATE_BOOT_AGGREGATE : IMA_STATE_END;
break;
case IMA_STATE_BOOT_AGGREGATE:
case IMA_STATE_RUNTIME:
status = this->ima_list->remove_first(this->ima_list,
(void**)&ima_entry);
if (status != SUCCESS)
{
DBG1(DBG_PTS, "could not retrieve ima measurement entry");
return status;
}
if (this->state == IMA_STATE_BOOT_AGGREGATE)
{
check_boot_aggregate(pcrs, ima_entry->measurement);
}
evid = extend_pcr(this, pcrs, IMA_PCR, ima_entry->measurement);
if (evid)
{
evid->set_validation(evid, PTS_COMP_EVID_VALIDATION_PASSED,
ima_entry->filename);
}
free(ima_entry->filename);
free(ima_entry);
this->state = this->ima_list->get_count(this->ima_list) ?
this->state = this->ima_list->get_count(this->ima_list) ?
IMA_STATE_RUNTIME : IMA_STATE_END;
break;
case IMA_STATE_END:
break;
break;
default:
return FAILED;
}
}
else
{
DBG1(DBG_PTS, "unsupported functional component name qualifier");
return FAILED;
}
*evidence = evid;
return evid ? ((this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE) :
FAILED;
if (!evid)
{
return FAILED;
}
return (this->state == IMA_STATE_INIT || this->state == IMA_STATE_END) ?
SUCCESS : NEED_MORE;
}
METHOD(pts_component_t, verify, status_t,
pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
pts_ita_comp_ima_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t *evidence)
{
bool has_pcr_info;
u_int32_t extended_pcr, vid, name;
u_int32_t pcr, vid, name;
enum_name_t *names;
pts_meas_algorithms_t algo;
pts_pcr_transform_t transform;
@@ -565,56 +611,65 @@ METHOD(pts_component_t, verify, status_t,
status_t status;
char *uri;
pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
switch (this->state)
/* some first time initializations */
if (!this->keyid.ptr)
{
case IMA_STATE_INIT:
if (!pts->get_aik_keyid(pts, &this->keyid))
{
return FAILED;
}
this->keyid = chunk_clone(this->keyid);
if (!pts->get_aik_keyid(pts, &this->keyid))
{
DBG1(DBG_PTS, "AIK keyid not available");
return FAILED;
}
this->keyid = chunk_clone(this->keyid);
if (!this->pts_db)
{
DBG1(DBG_PTS, "pts database not available");
return FAILED;
}
}
if (!this->pts_db)
{
DBG1(DBG_PTS, "pts database not available");
return FAILED;
}
status = this->pts_db->get_comp_measurement_count(this->pts_db,
this->name, this->keyid, algo,
&this->cid, &this->kid, &this->bios_count);
if (status != SUCCESS)
{
return status;
}
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
&measurement_time);
if (this->bios_count)
{
DBG1(DBG_PTS, "checking %d %N '%N' BIOS evidence measurements",
this->bios_count, pen_names, vid, names, name);
}
else
{
DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements",
pen_names, vid, names, name);
this->is_registering = TRUE;
}
this->state = IMA_STATE_BIOS;
/* fall through to next state */
case IMA_STATE_BIOS:
if (extended_pcr != IMA_PCR)
{
if (this->is_registering)
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
{
switch (this->state)
{
case IMA_STATE_INIT:
this->name->set_qualifier(this->name, qualifier);
status = this->pts_db->get_comp_measurement_count(this->pts_db,
this->name, this->keyid, algo, &this->bios_cid,
&this->kid, &this->bios_count);
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
if (status != SUCCESS)
{
return status;
}
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
if (this->bios_count)
{
DBG1(DBG_PTS, "checking %d %N '%N' BIOS evidence measurements",
this->bios_count, pen_names, vid, names, name);
}
else
{
DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements",
pen_names, vid, names, name);
this->is_bios_registering = TRUE;
}
this->state = IMA_STATE_BIOS;
/* fall through to next state */
case IMA_STATE_BIOS:
if (this->is_bios_registering)
{
status = this->pts_db->insert_comp_measurement(this->pts_db,
measurement, this->cid, this->kid,
++this->seq_no, extended_pcr, algo);
measurement, this->bios_cid, this->kid,
++this->seq_no, pcr, algo);
if (status != SUCCESS)
{
return status;
@@ -624,75 +679,129 @@ METHOD(pts_component_t, verify, status_t,
else
{
status = this->pts_db->check_comp_measurement(this->pts_db,
measurement, this->cid, this->kid,
++this->seq_no, extended_pcr, algo);
measurement, this->bios_cid, this->kid,
++this->seq_no, pcr, algo);
if (status != SUCCESS)
{
return status;
}
}
break;
}
this->state = IMA_STATE_BOOT_AGGREGATE;
/* fall through to next state */
case IMA_STATE_BOOT_AGGREGATE:
check_boot_aggregate(pcrs, measurement);
this->state = IMA_STATE_RUNTIME;
break;
case IMA_STATE_RUNTIME:
this->count++;
if (evidence->get_validation(evidence, &uri) !=
PTS_COMP_EVID_VALIDATION_PASSED)
{
DBG1(DBG_PTS, "policy URI could no be retrieved");
this->count_failed++;
return FAILED;
}
status = this->pts_db->check_file_measurement(this->pts_db,
pts->get_platform_info(pts),
PTS_MEAS_ALGO_SHA1_IMA,
measurement, uri);
switch (status)
{
case SUCCESS:
DBG3(DBG_PTS, "%#B for '%s' is ok", &measurement, uri);
this->count_ok++;
break;
case NOT_FOUND:
DBG2(DBG_PTS, "%#B for '%s' not found", &measurement, uri);
this->count_unknown++;
break;
case VERIFY_ERROR:
DBG1(DBG_PTS, "%#B for '%s' differs", &measurement, uri);
this->count_differ++;
break;
case FAILED:
default:
DBG1(DBG_PTS, "%#B for '%s' failed", &measurement, uri);
this->count_failed++;
return FAILED;
}
}
else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_OS))
{
int ima_count;
break;
case IMA_STATE_END:
break;
switch (this->state)
{
case IMA_STATE_BIOS:
if (!check_boot_aggregate(pcrs, measurement))
{
return FAILED;
}
this->state = IMA_STATE_INIT;
/* fall through to next state */
case IMA_STATE_INIT:
this->name->set_qualifier(this->name, qualifier);
status = this->pts_db->get_comp_measurement_count(this->pts_db,
this->name, this->keyid, algo,
&this->ima_cid, &this->kid, &ima_count);
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
if (status != SUCCESS)
{
return status;
}
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
if (ima_count)
{
DBG1(DBG_PTS, "checking %N '%N' boot aggregate evidence "
"measurement", pen_names, vid, names, name);
status = this->pts_db->check_comp_measurement(this->pts_db,
measurement, this->ima_cid,
this->kid, 1, pcr, algo);
}
else
{
DBG1(DBG_PTS, "registering %N '%N' boot aggregate evidence "
"measurement", pen_names, vid, names, name);
this->is_ima_registering = TRUE;
status = this->pts_db->insert_comp_measurement(this->pts_db,
measurement, this->ima_cid,
this->kid, 1, pcr, algo);
}
if (status != SUCCESS)
{
return status;
}
this->state = IMA_STATE_RUNTIME;
break;
case IMA_STATE_RUNTIME:
this->count++;
if (evidence->get_validation(evidence, &uri) !=
PTS_COMP_EVID_VALIDATION_PASSED)
{
DBG1(DBG_PTS, "policy URI could no be retrieved");
this->count_failed++;
return FAILED;
}
status = this->pts_db->check_file_measurement(this->pts_db,
pts->get_platform_info(pts),
PTS_MEAS_ALGO_SHA1_IMA,
measurement, uri);
switch (status)
{
case SUCCESS:
DBG3(DBG_PTS, "%#B for '%s' is ok", &measurement, uri);
this->count_ok++;
break;
case NOT_FOUND:
DBG2(DBG_PTS, "%#B for '%s' not found", &measurement, uri);
this->count_unknown++;
break;
case VERIFY_ERROR:
DBG1(DBG_PTS, "%#B for '%s' differs", &measurement, uri);
this->count_differ++;
break;
case FAILED:
default:
DBG1(DBG_PTS, "%#B for '%s' failed", &measurement, uri);
this->count_failed++;
}
break;
default:
return FAILED;
}
}
else
{
DBG1(DBG_PTS, "unsupported functional component name qualifier");
return FAILED;
}
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
if (has_pcr_info)
{
if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr)))
if (!chunk_equals(pcr_before, pcrs->get(pcrs, pcr)))
{
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
extended_pcr);
pcr);
}
if (pcrs->set(pcrs, extended_pcr, pcr_after))
if (pcrs->set(pcrs, pcr, pcr_after))
{
return SUCCESS;
}
}
else
{
pcr_after = pcrs->extend(pcrs, extended_pcr, measurement);
pcr_after = pcrs->extend(pcrs, pcr, measurement);
if (pcr_after.ptr)
{
return SUCCESS;
@@ -702,44 +811,74 @@ METHOD(pts_component_t, verify, status_t,
}
METHOD(pts_component_t, finalize, bool,
pts_ita_comp_ima_t *this)
pts_ita_comp_ima_t *this, u_int8_t qualifier)
{
u_int32_t vid, name;
enum_name_t *names;
bool success = TRUE;
this->name->set_qualifier(this->name, qualifier);
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
if (this->is_registering)
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
{
/* close registration */
this->is_registering = FALSE;
/* finalize BIOS measurements */
if (this->is_bios_registering)
{
/* close registration */
this->is_bios_registering = FALSE;
DBG1(DBG_PTS, "registered %d %N '%N' BIOS evidence measurements",
this->seq_no, pen_names, vid, names, name);
DBG1(DBG_PTS, "registered %d %N '%N' BIOS evidence measurements",
this->seq_no, pen_names, vid, names, name);
}
else if (this->seq_no < this->bios_count)
{
DBG1(DBG_PTS, "%d of %d %N '%N' BIOS evidence measurements missing",
this->bios_count - this->seq_no, this->bios_count,
pen_names, vid, names, name);
success = FALSE;
}
}
else if (this->seq_no < this->bios_count)
else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_OS))
{
DBG1(DBG_PTS, "%d of %d %N '%N' BIOS evidence measurements missing",
this->bios_count - this->seq_no, this->bios_count,
pen_names, vid, names, name);
return FALSE;
}
/* finalize IMA file measurements */
if (this->is_ima_registering)
{
/* close registration */
this->is_ima_registering = FALSE;
/* finalize IMA file measurements */
if (this->count)
DBG1(DBG_PTS, "registered %N '%N' boot aggregate evidence "
"measurement", pen_names, vid, names, name);
}
if (this->count)
{
DBG1(DBG_PTS, "processed %d %N '%N' file evidence measurements: "
"%d ok, %d unknown, %d differ, %d failed",
this->count, pen_names, vid, names, name,
this->count_ok, this->count_unknown,
this->count_differ, this->count_failed);
success = !this->count_differ && !this->count_failed;
}
}
else
{
DBG1(DBG_PTS, "processed %d %N '%N' file evidence measurements: "
"%d ok, %d unknown, %d differ, %d failed",
this->count, pen_names, vid, names, name,
this->count_ok, this->count_unknown, this->count_differ,
this->count_failed);
return !this->count_differ && !this->count_failed;
DBG1(DBG_PTS, "unsupported functional component name qualifier");
success = FALSE;
}
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
return TRUE;
return success;
}
METHOD(pts_component_t, get_ref, pts_component_t*,
pts_ita_comp_ima_t *this)
{
ref_get(&this->ref);
return &this->public;
}
METHOD(pts_component_t, destroy, void,
@@ -749,27 +888,40 @@ METHOD(pts_component_t, destroy, void,
u_int32_t vid, name;
enum_name_t *names;
if (this->is_registering)
if (ref_put(&this->ref))
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->cid, this->kid);
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
"evidence measurements", count, pen_names, vid, names, name);
if (this->is_bios_registering)
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->bios_cid, this->kid);
DBG1(DBG_PTS, "deleted %d registered %N '%N' BIOS evidence "
"measurements", count, pen_names, vid, names, name);
}
if (this->is_ima_registering)
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->ima_cid, this->kid);
DBG1(DBG_PTS, "deleted registered %N '%N' boot aggregate evidence "
"measurement", pen_names, vid, names, name);
}
this->bios_list->destroy_function(this->bios_list,
(void *)free_bios_entry);
this->ima_list->destroy_function(this->ima_list,
(void *)free_ima_entry);
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
this->bios_list->destroy_function(this->bios_list, (void *)free_bios_entry);
this->ima_list->destroy_function(this->ima_list, (void *)free_ima_entry);
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
/**
* See header
*/
pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t *pts_ita_comp_ima_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_ima_t *this;
@@ -782,16 +934,18 @@ pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
.measure = _measure,
.verify = _verify,
.finalize = _finalize,
.get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
qualifier),
PTS_QUALIFIER_UNKNOWN),
.depth = depth,
.pts_db = pts_db,
.bios_list = linked_list_create(),
.ima_list = linked_list_create(),
.pcr_info = lib->settings->get_bool(lib->settings,
"libimcv.plugins.imc-attestation.pcr_info", TRUE),
.ref = 1,
);
return &this->public;
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Andreas Steffen
* Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* Create a PTS ITS Functional Component object
*
* @param qualifier PTS Component Functional Name Qualifier
* @param depth Sub-component depth
* @param pts_db PTS measurement database
*/
pts_component_t* pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t* pts_ita_comp_ima_create(u_int32_t depth,
pts_database_t *pts_db);
#endif /** PTS_ITA_COMP_IMA_H_ @}*/
+36 -16
View File
@@ -85,6 +85,11 @@ struct pts_ita_comp_tboot_t {
*/
int seq_no;
/**
* Reference count
*/
refcount_t ref;
};
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -106,7 +111,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
pts_ita_comp_tboot_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t **evidence)
{
size_t pcr_len;
@@ -182,7 +188,8 @@ METHOD(pts_component_t, measure, status_t,
}
METHOD(pts_component_t, verify, status_t,
pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
pts_ita_comp_tboot_t *this, u_int8_t qualifier,pts_t *pts,
pts_comp_evidence_t *evidence)
{
bool has_pcr_info;
u_int32_t extended_pcr, vid, name;
@@ -275,7 +282,7 @@ METHOD(pts_component_t, verify, status_t,
}
METHOD(pts_component_t, finalize, bool,
pts_ita_comp_tboot_t *this)
pts_ita_comp_tboot_t *this, u_int8_t qualifier)
{
u_int32_t vid, name;
enum_name_t *names;
@@ -303,6 +310,13 @@ METHOD(pts_component_t, finalize, bool,
return TRUE;
}
METHOD(pts_component_t, get_ref, pts_component_t*,
pts_ita_comp_tboot_t *this)
{
ref_get(&this->ref);
return &this->public;
}
METHOD(pts_component_t, destroy, void,
pts_ita_comp_tboot_t *this)
{
@@ -310,25 +324,28 @@ METHOD(pts_component_t, destroy, void,
u_int32_t vid, name;
enum_name_t *names;
if (this->is_registering)
if (ref_put(&this->ref))
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->cid, this->kid);
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
"evidence measurements", count, pen_names, vid, names, name);
if (this->is_registering)
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->cid, this->kid);
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
names = pts_components->get_comp_func_names(pts_components, vid);
DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
"evidence measurements", count, pen_names, vid, names, name);
}
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
/**
* See header
*/
pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t *pts_ita_comp_tboot_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_tboot_t *this;
@@ -341,12 +358,15 @@ pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
.measure = _measure,
.verify = _verify,
.finalize = _finalize,
.get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
qualifier),
PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED),
.depth = depth,
.pts_db = pts_db,
.ref = 1,
);
return &this->public;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* Create a PTS ITS Functional Component object
*
* @param qualifier PTS Component Functional Name Qualifier
* @param depth Sub-component depth
* @param pts_db PTS measurement database
*/
pts_component_t* pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t* pts_ita_comp_tboot_create(u_int32_t depth,
pts_database_t *pts_db);
#endif /** PTS_ITA_COMP_TBOOT_H_ @}*/
+28 -7
View File
@@ -49,6 +49,12 @@ struct pts_ita_comp_tgrub_t {
*/
pts_database_t *pts_db;
/**
* Reference count
*/
refcount_t ref;
};
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -70,7 +76,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
pts_ita_comp_tgrub_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t **evidence)
{
size_t pcr_len;
pts_pcr_transform_t pcr_transform;
@@ -110,7 +117,8 @@ METHOD(pts_component_t, measure, status_t,
}
METHOD(pts_component_t, verify, status_t,
pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
pts_ita_comp_tgrub_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t *evidence)
{
bool has_pcr_info;
u_int32_t extended_pcr;
@@ -147,22 +155,32 @@ METHOD(pts_component_t, verify, status_t,
}
METHOD(pts_component_t, finalize, bool,
pts_ita_comp_tgrub_t *this)
pts_ita_comp_tgrub_t *this, u_int8_t qualifier)
{
return FALSE;
}
METHOD(pts_component_t, get_ref, pts_component_t*,
pts_ita_comp_tgrub_t *this)
{
ref_get(&this->ref);
return &this->public;
}
METHOD(pts_component_t, destroy, void,
pts_ita_comp_tgrub_t *this)
{
this->name->destroy(this->name);
free(this);
if (ref_put(&this->ref))
{
this->name->destroy(this->name);
free(this);
}
}
/**
* See header
*/
pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t *pts_ita_comp_tgrub_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_tgrub_t *this;
@@ -175,12 +193,15 @@ pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
.measure = _measure,
.verify = _verify,
.finalize = _finalize,
.get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
qualifier),
PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED),
.depth = depth,
.pts_db = pts_db,
.ref = 1,
);
return &this->public;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* Create a PTS ITS Functional Component object
*
* @param qualifier PTS Component Functional Name Qualifier
* @param depth Sub-component depth
* @param pts_db PTS measurement database
*/
pts_component_t* pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
pts_component_t* pts_ita_comp_tgrub_create(u_int32_t depth,
pts_database_t *pts_db);
#endif /** PTS_ITA_COMP_TGRUB_H_ @}*/
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Andreas Steffen
* Copyright (C) 2011-2012 Andreas Steffen
*
* HSR Hochschule fuer Technik Rapperswil
*
@@ -67,6 +67,12 @@ METHOD(pts_comp_func_name_t, get_qualifier, u_int8_t,
return this->qualifier;
}
METHOD(pts_comp_func_name_t, set_qualifier, void,
private_pts_comp_func_name_t *this, u_int8_t qualifier)
{
this->qualifier = qualifier;
}
static bool equals(private_pts_comp_func_name_t *this,
private_pts_comp_func_name_t *other)
{
@@ -137,6 +143,7 @@ pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
.get_vendor_id = _get_vendor_id,
.get_name = _get_name,
.get_qualifier = _get_qualifier,
.set_qualifier = _set_qualifier,
.equals = (bool(*)(pts_comp_func_name_t*,pts_comp_func_name_t*))equals,
.clone = _clone_,
.log = _log_,
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -54,6 +54,13 @@ struct pts_comp_func_name_t {
*/
u_int8_t (*get_qualifier)(pts_comp_func_name_t *this);
/**
* Set the PTS Component Functional Name Qualifier
*
* @param qualifier PTS Component Functional Name Qualifier to be set
*/
void (*set_qualifier)(pts_comp_func_name_t *this, u_int8_t qualifier);
/**
* Check to PTS Component Functional Names for equality
*
+13 -3
View File
@@ -60,31 +60,41 @@ struct pts_component_t {
/**
* Do evidence measurements on the PTS Functional Component
*
* @param qualifier PTS Component Functional Name Qualifier
* @param pts PTS interface
* @param evidence returns component evidence measureemt
* @param measurements additional file measurements (NULL if not present)
* @return status return code
*/
status_t (*measure)(pts_component_t *this, pts_t *pts,
status_t (*measure)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t** evidence);
/**
* Verify the evidence measurements of the PTS Functional Component
*
* @param qualifier PTS Component Functional Name Qualifier
* @param pts PTS interface
* @param evidence component evidence measurement to be verified
* @return status return code
*/
status_t (*verify)(pts_component_t *this, pts_t *pts,
status_t (*verify)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t *evidence);
/**
* Tell the PTS Functional Component to finalize pending registrations
* and check for missing measurements
*
* @param qualifier PTS Component Functional Name Qualifier
* @return TRUE if finalization successful
*/
bool (*finalize)(pts_component_t *this);
bool (*finalize)(pts_component_t *this, u_int8_t qualifier);
/**
* Get a new reference to the PTS Functional Component
*
* @return this, with an increased refcount
*/
pts_component_t* (*get_ref)(pts_component_t *this);
/**
* Destroys a pts_component_t object.
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2011 Andreas Steffen
*
* Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -270,8 +269,7 @@ METHOD(pts_component_manager_t, create, pts_component_t*,
{
if (entry2->name == name->get_name(name) && entry2->create)
{
component = entry2->create(name->get_qualifier(name),
depth, pts_db);
component = entry2->create(depth, pts_db);
break;
}
}
@@ -30,8 +30,7 @@ typedef struct pts_component_manager_t pts_component_manager_t;
#include <library.h>
#include <pen/pen.h>
typedef pts_component_t* (*pts_component_create_t)(u_int8_t qualifier,
u_int32_t depth,
typedef pts_component_t* (*pts_component_create_t)(u_int32_t depth,
pts_database_t *pts_db);
/**