diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libpts/plugins/imc_attestation/imc_attestation_process.c | 21 | ||||
-rw-r--r-- | src/libpts/plugins/imc_attestation/imc_attestation_state.c | 16 | ||||
-rw-r--r-- | src/libpts/plugins/imc_attestation/imc_attestation_state.h | 12 | ||||
-rw-r--r-- | src/libpts/pts/components/ita/ita_comp_ima.c | 161 | ||||
-rw-r--r-- | src/libpts/pts/components/ita/ita_comp_tboot.c | 7 | ||||
-rw-r--r-- | src/libpts/pts/components/ita/ita_comp_tgrub.c | 3 | ||||
-rw-r--r-- | src/libpts/pts/components/pts_comp_evidence.c | 14 | ||||
-rw-r--r-- | src/libpts/pts/components/pts_comp_evidence.h | 4 | ||||
-rw-r--r-- | src/libpts/pts/components/pts_component.h | 3 | ||||
-rw-r--r-- | src/libpts/pts/pts_file_meas.c | 15 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c | 19 |
11 files changed, 156 insertions, 119 deletions
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_process.c b/src/libpts/plugins/imc_attestation/imc_attestation_process.c index 2b87a71e8..f2540a981 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation_process.c +++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.c @@ -321,7 +321,6 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, { tcg_pts_attr_req_func_comp_evid_t *attr_cast; pts_proto_caps_flag_t negotiated_caps; - pts_file_meas_t *measurements; pts_comp_func_name_t *name; pts_comp_evidence_t *evid; pts_component_t *comp; @@ -386,23 +385,15 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, continue; } - /* do the component evidence measurement[s] */ + /* do the component evidence measurement[s] and cache them */ do { - status = comp->measure(comp, pts, &evid, &measurements); + status = comp->measure(comp, pts, &evid); if (status == FAILED) { break; } - if (measurements) - { - DBG2(DBG_IMC, "collected %d file measurements", - measurements->get_file_count(measurements)); - attr = tcg_pts_attr_file_meas_create(measurements); - attestation_state->add_attr(attestation_state, attr); - } - attr = tcg_pts_attr_simple_comp_evid_create(evid); - attestation_state->add_attr(attestation_state, attr); + attestation_state->add_evidence(attestation_state, evid); } while (status == NEED_MORE); comp->destroy(comp); @@ -414,12 +405,14 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, { pts_simple_evid_final_flag_t flags; pts_meas_algorithms_t comp_hash_algorithm; + pts_comp_evidence_t *evid; chunk_t pcr_composite, quote_sig; bool use_quote2; - /* Send buffered PA-TNC attributes */ - while (attestation_state->next_attr(attestation_state, &attr)) + /* Send cached Component Evidence entries */ + while (attestation_state->next_evidence(attestation_state, &evid)) { + attr = tcg_pts_attr_simple_comp_evid_create(evid); attr_list->insert_last(attr_list, attr); } diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.c b/src/libpts/plugins/imc_attestation/imc_attestation_state.c index 83b1c7764..58727244a 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation_state.c +++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.c @@ -125,16 +125,16 @@ METHOD(imc_attestation_state_t, get_pts, pts_t*, return this->pts; } -METHOD(imc_attestation_state_t, add_attr, void, - private_imc_attestation_state_t *this, pa_tnc_attr_t *attr) +METHOD(imc_attestation_state_t, add_evidence, void, + private_imc_attestation_state_t *this, pts_comp_evidence_t *evid) { - this->list->insert_last(this->list, attr); + this->list->insert_last(this->list, evid); } -METHOD(imc_attestation_state_t, next_attr, bool, - private_imc_attestation_state_t *this, pa_tnc_attr_t **attr) +METHOD(imc_attestation_state_t, next_evidence, bool, + private_imc_attestation_state_t *this, pts_comp_evidence_t **evid) { - return this->list->remove_first(this->list, (void**)attr) == SUCCESS; + return this->list->remove_first(this->list, (void**)evid) == SUCCESS; } /** @@ -158,8 +158,8 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id) .destroy = _destroy, }, .get_pts = _get_pts, - .add_attr = _add_attr, - .next_attr = _next_attr, + .add_evidence = _add_evidence, + .next_evidence = _next_evidence, }, .connection_id = connection_id, .state = TNC_CONNECTION_STATE_CREATE, diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.h b/src/libpts/plugins/imc_attestation/imc_attestation_state.h index 9e7a1323b..548b128b9 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation_state.h +++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.h @@ -47,19 +47,19 @@ struct imc_attestation_state_t { pts_t* (*get_pts)(imc_attestation_state_t *this); /** - * Add an entry to the PA-TNC attribute cache list + * Add an entry to the Component Evidence cache list * - * @param attr PA-TNC attribute entry + * @param evid Component Evidence entry */ - void (*add_attr)(imc_attestation_state_t *this, pa_tnc_attr_t *attr); + void (*add_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t *evid); /** - * Removes next entry from the PA-TNC attribute cash list and returns it + * Removes next entry from the Component Evidence cache list and returns it * - * @param attr Next PA-TNC attribute entry + * @param evid Next Component Evidence entry * @return TRUE if next entry is available */ - bool (*next_attr)(imc_attestation_state_t *this, pa_tnc_attr_t** attr); + bool (*next_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t** evid); }; diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c index d57fe6a9d..b1a8b861a 100644 --- a/src/libpts/pts/components/ita/ita_comp_ima.c +++ b/src/libpts/pts/components/ita/ita_comp_ima.c @@ -32,7 +32,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_MEASUREMENT_BATCH_SIZE 200 #define IMA_PCR 10 #define IMA_TYPE_LEN 3 #define IMA_FILENAME_LEN_MAX 255 @@ -107,11 +106,6 @@ struct pts_ita_comp_ima_t { int bios_count; /** - * Count of IMA file measurements in current batch - */ - int ima_count; - - /** * IMA BIOS measurements */ linked_list_t *bios_list; @@ -135,6 +129,32 @@ struct pts_ita_comp_ima_t { * IMA state machine */ ima_state_t state; + + /** + * Total number of component measurements + */ + int count; + + /** + * Number of successful component measurements + */ + int count_ok; + + /** + * Number of unknown component measurements + */ + int count_unknown; + + /** + * Number of differing component measurements + */ + int count_differ; + + /** + * Number of failed component measurements + */ + int count_failed; + }; /** @@ -455,19 +475,15 @@ 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_file_meas_t **measurements) + pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence) { bios_entry_t *bios_entry; - ima_entry_t *ima_entry, *entry; - status_t status; - int count; - enumerator_t *e; + ima_entry_t *ima_entry; pts_pcr_t *pcrs; - pts_file_meas_t *file_meas; + pts_comp_evidence_t *evid = NULL; + status_t status; pcrs = pts->get_pcrs(pts); - *measurements = NULL; switch (this->state) { @@ -487,13 +503,9 @@ METHOD(pts_component_t, measure, status_t, DBG1(DBG_PTS, "could not retrieve bios measurement entry"); return status; } - *evidence = extend_pcr(this, pcrs, bios_entry->pcr, - bios_entry->measurement); + evid = extend_pcr(this, pcrs, bios_entry->pcr, + bios_entry->measurement); free(bios_entry); - if (!evidence) - { - return FAILED; - } /* break if still some BIOS measurements are left */ if (this->bios_list->get_count(this->bios_list)) @@ -513,28 +525,6 @@ METHOD(pts_component_t, measure, status_t, break; case IMA_STATE_BOOT_AGGREGATE: case IMA_STATE_RUNTIME: - /* ready to send next batch of file measurements ? */ - if (this->ima_count++ == 0) - { - file_meas = pts_file_meas_create(0); - count = 0; - - e = this->ima_list->create_enumerator(this->ima_list); - while (e->enumerate(e, &entry) && - count++ < IMA_MEASUREMENT_BATCH_SIZE) - { - file_meas->add(file_meas, entry->filename, - entry->file_measurement); - } - e->destroy(e); - *measurements = file_meas; - } - else if (this->ima_count == IMA_MEASUREMENT_BATCH_SIZE) - { - /* ready for file measurement batch in the next round */ - this->ima_count = 0; - } - status = this->ima_list->remove_first(this->ima_list, (void**)&ima_entry); if (status != SUCCESS) @@ -542,29 +532,31 @@ METHOD(pts_component_t, measure, status_t, DBG1(DBG_PTS, "could not retrieve ima measurement entry"); return status; } - *evidence = extend_pcr(this, pcrs, IMA_PCR, ima_entry->measurement); - 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->file_measurement.ptr); free(ima_entry->filename); free(ima_entry); - if (!evidence) - { - return FAILED; - } this->state = this->ima_list->get_count(this->ima_list) ? IMA_STATE_RUNTIME : IMA_STATE_END; break; case IMA_STATE_END: break; } - - return (this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE; + + *evidence = evid; + return evid ? ((this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE) : + FAILED; } METHOD(pts_component_t, verify, status_t, @@ -579,6 +571,7 @@ METHOD(pts_component_t, verify, status_t, time_t measurement_time; chunk_t measurement, pcr_before, pcr_after; status_t status; + char *uri; pcrs = pts->get_pcrs(pts); measurement = evidence->get_measurement(evidence, &extended_pcr, @@ -611,15 +604,13 @@ METHOD(pts_component_t, verify, status_t, if (this->bios_count) { - DBG1(DBG_PTS, "checking %d %N '%N' functional component " - "evidence measurements", this->bios_count, - pen_names, vid, names, name); + 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' functional component " - "evidence measurements", pen_names, vid, names, - name); + DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements", + pen_names, vid, names, name); this->is_registering = TRUE; } this->state = IMA_STATE_BIOS; @@ -653,9 +644,42 @@ METHOD(pts_component_t, verify, status_t, 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++; + } + break; case IMA_STATE_END: break; @@ -666,7 +690,7 @@ METHOD(pts_component_t, verify, status_t, { if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr))) { - DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value", + DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", extended_pcr); } if (pcrs->set(pcrs, extended_pcr, pcr_after)) @@ -700,17 +724,29 @@ METHOD(pts_component_t, finalize, bool, /* close registration */ this->is_registering = FALSE; - DBG1(DBG_PTS, "registered %d %N '%N' functional component 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' functional component evidence " - "measurements missing", this->bios_count - this->seq_no, - this->bios_count, pen_names, vid, names, name); + 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->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); + + return !this->count_differ && !this->count_failed; + } + return TRUE; } @@ -762,7 +798,6 @@ pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth, .pts_db = pts_db, .bios_list = linked_list_create(), .ima_list = linked_list_create(), - .ima_count = IMA_MEASUREMENT_BATCH_SIZE - 1, .pcr_info = lib->settings->get_bool(lib->settings, "libimcv.plugins.imc-attestation.pcr_info", TRUE), ); diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c index 40befc3e0..c3e4434d8 100644 --- a/src/libpts/pts/components/ita/ita_comp_tboot.c +++ b/src/libpts/pts/components/ita/ita_comp_tboot.c @@ -106,8 +106,7 @@ 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_file_meas_t **measurements) + pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence) { size_t pcr_len; @@ -165,7 +164,7 @@ METHOD(pts_component_t, measure, status_t, if (pcr_before.len != pcr_len || pcr_after.len != pcr_len || measurement.len != pcr_len) { - DBG1(DBG_PTS, "TBOOT measurement or pcr data have the wrong size"); + DBG1(DBG_PTS, "TBOOT measurement or PCR data have the wrong size"); free(measurement.ptr); free(pcr_before.ptr); free(pcr_after.ptr); @@ -263,7 +262,7 @@ METHOD(pts_component_t, verify, status_t, { if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr))) { - DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value", + DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", extended_pcr); } if (pcrs->set(pcrs, extended_pcr, pcr_after)) diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.c b/src/libpts/pts/components/ita/ita_comp_tgrub.c index 1d24b0a93..c6bbb6730 100644 --- a/src/libpts/pts/components/ita/ita_comp_tgrub.c +++ b/src/libpts/pts/components/ita/ita_comp_tgrub.c @@ -70,8 +70,7 @@ 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_file_meas_t **measurements) + pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence) { size_t pcr_len; pts_pcr_transform_t pcr_transform; diff --git a/src/libpts/pts/components/pts_comp_evidence.c b/src/libpts/pts/components/pts_comp_evidence.c index b4b54ff47..050717472 100644 --- a/src/libpts/pts/components/pts_comp_evidence.c +++ b/src/libpts/pts/components/pts_comp_evidence.c @@ -87,7 +87,7 @@ struct private_pts_comp_evidence_t { /** * Verification Policy URI */ - chunk_t policy_uri; + char *policy_uri; }; @@ -157,7 +157,7 @@ METHOD(pts_comp_evidence_t, set_pcr_info, void, } METHOD(pts_comp_evidence_t, get_validation, pts_comp_evid_validation_t, - private_pts_comp_evidence_t *this, chunk_t *uri) + private_pts_comp_evidence_t *this, char **uri) { if (uri) { @@ -168,10 +168,14 @@ METHOD(pts_comp_evidence_t, get_validation, pts_comp_evid_validation_t, METHOD(pts_comp_evidence_t, set_validation, void, private_pts_comp_evidence_t *this, pts_comp_evid_validation_t validation, - chunk_t uri) + char *uri) { this->validation = validation; - this->policy_uri = chunk_clone(uri); + if (uri) + { + this->policy_uri = strdup(uri); + DBG3(DBG_PTS, "'%s'", uri); + } } METHOD(pts_comp_evidence_t, destroy, void, @@ -181,7 +185,7 @@ METHOD(pts_comp_evidence_t, destroy, void, free(this->measurement.ptr); free(this->pcr_before.ptr); free(this->pcr_after.ptr); - free(this->policy_uri.ptr); + free(this->policy_uri); free(this); } diff --git a/src/libpts/pts/components/pts_comp_evidence.h b/src/libpts/pts/components/pts_comp_evidence.h index fe86aa940..55776ce8b 100644 --- a/src/libpts/pts/components/pts_comp_evidence.h +++ b/src/libpts/pts/components/pts_comp_evidence.h @@ -120,7 +120,7 @@ struct pts_comp_evidence_t { * @return validation Validation Result */ pts_comp_evid_validation_t (*get_validation)(pts_comp_evidence_t *this, - chunk_t *uri); + char **uri); /** * Sets Validation Result if available @@ -129,7 +129,7 @@ struct pts_comp_evidence_t { * @param uri Verification Policy URI */ void (*set_validation)(pts_comp_evidence_t *this, - pts_comp_evid_validation_t validation, chunk_t uri); + pts_comp_evid_validation_t validation, char* uri); /** * Destroys a pts_comp_evidence_t object. diff --git a/src/libpts/pts/components/pts_component.h b/src/libpts/pts/components/pts_component.h index 970b75e34..e1f4069cf 100644 --- a/src/libpts/pts/components/pts_component.h +++ b/src/libpts/pts/components/pts_component.h @@ -66,8 +66,7 @@ struct pts_component_t { * @return status return code */ status_t (*measure)(pts_component_t *this, pts_t *pts, - pts_comp_evidence_t** evidence, - pts_file_meas_t** measurements); + pts_comp_evidence_t** evidence); /** * Verify the evidence measurements of the PTS Functional Component diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c index c19618923..4fece6b3c 100644 --- a/src/libpts/pts/pts_file_meas.c +++ b/src/libpts/pts/pts_file_meas.c @@ -117,7 +117,6 @@ METHOD(pts_file_meas_t, check, bool, { enumerator_t *enumerator; entry_t *entry; - char *status_msg; int count_ok = 0, count_not_found = 0, count_differ = 0; status_t status; @@ -129,23 +128,25 @@ METHOD(pts_file_meas_t, check, bool, switch (status) { case SUCCESS: - status_msg = "is ok"; + DBG3(DBG_PTS, " %#B for '%s' is ok", &entry->measurement, + entry->filename); count_ok++; break; case NOT_FOUND: - status_msg = "not found"; + DBG2(DBG_PTS, " %#B for '%s' not found", &entry->measurement, + entry->filename); count_not_found++; break; case VERIFY_ERROR: - status_msg = "differs"; + DBG1(DBG_PTS, " %#B for '%s' differs", &entry->measurement, + entry->filename); count_differ++; break; case FAILED: default: - status_msg = "failed"; + DBG1(DBG_PTS, " %#B for '%s' failed", &entry->measurement, + entry->filename); } - DBG2(DBG_PTS, " %#B for '%s' %s", &entry->measurement, - entry->filename, status_msg); } enumerator->destroy(enumerator); diff --git a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c index 1e1f0417a..cd0848f7b 100644 --- a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c +++ b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c @@ -185,15 +185,16 @@ METHOD(pa_tnc_attr_t, build, void, { bio_writer_t *writer; bool has_pcr_info; - char utc_time_buf[25]; + char utc_time_buf[25], *policy_uri; u_int8_t flags; + u_int16_t len; u_int32_t depth, extended_pcr; pts_comp_func_name_t *name; pts_meas_algorithms_t hash_algorithm; pts_pcr_transform_t transform; pts_comp_evid_validation_t validation; time_t measurement_time; - chunk_t measurement, utc_time, pcr_before, pcr_after, policy_uri; + chunk_t measurement, utc_time, pcr_before, pcr_after; if (this->value.ptr) { @@ -239,8 +240,9 @@ METHOD(pa_tnc_attr_t, build, void, if (validation == PTS_COMP_EVID_VALIDATION_FAILED || validation == PTS_COMP_EVID_VALIDATION_PASSED) { - writer->write_uint16(writer, policy_uri.len); - writer->write_data (writer, policy_uri); + len = strlen(policy_uri); + writer->write_uint16(writer, len); + writer->write_data (writer, chunk_create(policy_uri, len)); } if (has_pcr_info) { @@ -414,8 +416,13 @@ METHOD(pa_tnc_attr_t, process, status_t, /* Add options */ if (has_validation) { - policy_uri = chunk_clone(policy_uri); - this->evidence->set_validation(this->evidence, validation, policy_uri); + char buf[BUF_LEN]; + size_t len; + + len = min(policy_uri.len, BUF_LEN-1); + memcpy(buf, policy_uri.ptr, len); + buf[len] = '\0'; + this->evidence->set_validation(this->evidence, validation, buf); } if (has_pcr_info) { |