check boot_aggregate value

This commit is contained in:
Andreas Steffen
2012-07-11 17:09:04 +02:00
parent ddafcda4d8
commit 5b35214a87
+65 -18
View File
@@ -32,6 +32,7 @@
#define SECURITY_DIR "/sys/kernel/security/" #define SECURITY_DIR "/sys/kernel/security/"
#define IMA_BIOS_MEASUREMENTS SECURITY_DIR "tpm0/binary_bios_measurements" #define IMA_BIOS_MEASUREMENTS SECURITY_DIR "tpm0/binary_bios_measurements"
#define IMA_RUNTIME_MEASUREMENTS SECURITY_DIR "ima/binary_runtime_measurements" #define IMA_RUNTIME_MEASUREMENTS SECURITY_DIR "ima/binary_runtime_measurements"
#define IMA_EVENT_NAME_LEN_MAX 255
#define IMA_PCR 10 #define IMA_PCR 10
#define IMA_PCR_MAX 16 #define IMA_PCR_MAX 16
#define IMA_TYPE_LEN 3 #define IMA_TYPE_LEN 3
@@ -44,7 +45,7 @@ typedef enum ima_state_t ima_state_t;
enum ima_state_t { enum ima_state_t {
IMA_STATE_INIT, IMA_STATE_INIT,
IMA_STATE_BIOS, IMA_STATE_BIOS,
IMA_STATE_BIOS_AGGREGATE, IMA_STATE_BOOT_AGGREGATE,
IMA_STATE_RUNTIME, IMA_STATE_RUNTIME,
IMA_STATE_END IMA_STATE_END
}; };
@@ -355,14 +356,16 @@ static bool load_runtime_measurements(char *file, linked_list_t *list,
* Extend measurement into PCR an create evidence * Extend measurement into PCR an create evidence
*/ */
pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, u_int32_t pcr, pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, u_int32_t pcr,
size_t pcr_len, chunk_t measurement) chunk_t measurement)
{ {
size_t pcr_len;
pts_pcr_transform_t pcr_transform; pts_pcr_transform_t pcr_transform;
pts_meas_algorithms_t hash_algo; pts_meas_algorithms_t hash_algo;
pts_comp_evidence_t *evidence; pts_comp_evidence_t *evidence;
chunk_t pcr_before, pcr_after; chunk_t pcr_before, pcr_after;
hash_algo = PTS_MEAS_ALGO_SHA1; hash_algo = PTS_MEAS_ALGO_SHA1;
pcr_len = HASH_SIZE_SHA1;
pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len); pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
pcr_before = chunk_clone(this->pcrs[pcr]); pcr_before = chunk_clone(this->pcrs[pcr]);
this->hasher->get_hash(this->hasher, pcr_before, NULL); this->hasher->get_hash(this->hasher, pcr_before, NULL);
@@ -377,6 +380,35 @@ pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, u_int32_t pcr,
return evidence; return evidence;
} }
/**
* Compute and check boot aggregate value by hashing PCR0 to PCR7
*/
void check_boot_aggregate(pts_ita_comp_ima_t *this, chunk_t measurement)
{
u_int32_t pcr;
u_char pcr_buffer[HASH_SIZE_SHA1];
u_char boot_aggregate_name[] = "boot_aggregate";
u_char filename_buffer[IMA_EVENT_NAME_LEN_MAX + 1];
chunk_t boot_aggregate, file_name;
/* See Linux kernel header: security/integrity/ima/ima.h */
boot_aggregate = chunk_create(pcr_buffer, sizeof(pcr_buffer));
memset(filename_buffer, 0, sizeof(filename_buffer));
strcpy(filename_buffer, boot_aggregate_name);
file_name = chunk_create(filename_buffer, sizeof(filename_buffer));
for (pcr = 0; pcr < 8; pcr++)
{
this->hasher->get_hash(this->hasher, this->pcrs[pcr], NULL);
}
this->hasher->get_hash(this->hasher, chunk_empty, pcr_buffer);
this->hasher->get_hash(this->hasher, boot_aggregate, NULL);
this->hasher->get_hash(this->hasher, file_name, pcr_buffer);
DBG1(DBG_PTS, "boot aggregate value is %scorrect",
chunk_equals(boot_aggregate, measurement) ? "":"in");
}
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*, METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
pts_ita_comp_ima_t *this) pts_ita_comp_ima_t *this)
{ {
@@ -420,7 +452,7 @@ METHOD(pts_component_t, measure, status_t,
DBG1(DBG_PTS, "could not retrieve bios measurement entry"); DBG1(DBG_PTS, "could not retrieve bios measurement entry");
return status; return status;
} }
*evidence = extend_pcr(this, bios_entry->pcr, pts->get_pcr_len(pts), *evidence = extend_pcr(this, bios_entry->pcr,
bios_entry->measurement); bios_entry->measurement);
free(bios_entry); free(bios_entry);
@@ -438,9 +470,9 @@ METHOD(pts_component_t, measure, status_t,
} }
this->state = this->ima_list->get_count(this->ima_list) ? this->state = this->ima_list->get_count(this->ima_list) ?
IMA_STATE_BIOS_AGGREGATE : IMA_STATE_END; IMA_STATE_BOOT_AGGREGATE : IMA_STATE_END;
break; break;
case IMA_STATE_BIOS_AGGREGATE: case IMA_STATE_BOOT_AGGREGATE:
case IMA_STATE_RUNTIME: case IMA_STATE_RUNTIME:
status = this->ima_list->remove_first(this->ima_list, status = this->ima_list->remove_first(this->ima_list,
(void**)&ima_entry); (void**)&ima_entry);
@@ -449,18 +481,18 @@ METHOD(pts_component_t, measure, status_t,
DBG1(DBG_PTS, "could not retrieve ima measurement entry"); DBG1(DBG_PTS, "could not retrieve ima measurement entry");
return status; return status;
} }
*evidence = extend_pcr(this, IMA_PCR, pts->get_pcr_len(pts), *evidence = extend_pcr(this, IMA_PCR, ima_entry->measurement);
ima_entry->measurement);
if (this->state == IMA_STATE_BOOT_AGGREGATE)
{
check_boot_aggregate(this, ima_entry->measurement);
}
/* TODO optionally send file measurements */ /* TODO optionally send file measurements */
chunk_free(&ima_entry->file_measurement); chunk_free(&ima_entry->file_measurement);
chunk_free(&ima_entry->filename); chunk_free(&ima_entry->filename);
free(ima_entry); free(ima_entry);
if (this->state == IMA_STATE_BIOS_AGGREGATE)
{
/* TODO check BIOS aggregate value */
}
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; IMA_STATE_RUNTIME : IMA_STATE_END;
break; break;
@@ -487,8 +519,9 @@ METHOD(pts_component_t, verify, status_t,
measurement = evidence->get_measurement(evidence, &extended_pcr, measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time); &algo, &transform, &measurement_time);
if (!this->keyid.ptr) switch (this->state)
{ {
case IMA_STATE_INIT:
if (!pts->get_aik_keyid(pts, &this->keyid)) if (!pts->get_aik_keyid(pts, &this->keyid))
{ {
return FAILED; return FAILED;
@@ -513,17 +546,20 @@ METHOD(pts_component_t, verify, status_t,
if (this->count) if (this->count)
{ {
DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence " DBG1(DBG_PTS, "checking %d %N '%N' functional component "
"measurements", this->count, pen_names, vid, names, name); "evidence measurements", this->count, pen_names,
vid, names, name);
} }
else else
{ {
DBG1(DBG_PTS, "registering %N '%N' functional component evidence " DBG1(DBG_PTS, "registering %N '%N' functional component "
"measurements", pen_names, vid, names, name); "evidence measurements", pen_names, vid, names,
name);
this->is_registering = TRUE; this->is_registering = TRUE;
} }
} this->state = IMA_STATE_BIOS;
/* fall through to next state */
case IMA_STATE_BIOS:
if (extended_pcr != IMA_PCR) if (extended_pcr != IMA_PCR)
{ {
if (this->is_registering) if (this->is_registering)
@@ -547,6 +583,17 @@ METHOD(pts_component_t, verify, status_t,
return status; return status;
} }
} }
break;
}
this->state = IMA_STATE_BOOT_AGGREGATE;
/* fall through to next state */
case IMA_STATE_BOOT_AGGREGATE:
this->state = IMA_STATE_RUNTIME;
break;
case IMA_STATE_RUNTIME:
break;
case IMA_STATE_END:
break;
} }
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after); has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);