From 4932278e4b13022718898a8c5b621460e51bd02b Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Mon, 28 Nov 2011 14:27:03 +0100 Subject: [PATCH] improved performance of database access by caching primary keys --- src/libpts/pts/components/ita/ita_comp_ima.c | 31 ++++--- .../pts/components/ita/ita_comp_tboot.c | 31 ++++--- src/libpts/pts/pts_database.c | 90 +++++++++---------- src/libpts/pts/pts_database.h | 30 ++++--- 4 files changed, 102 insertions(+), 80 deletions(-) diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c index c8a546951..a7da76651 100644 --- a/src/libpts/pts/components/ita/ita_comp_ima.c +++ b/src/libpts/pts/components/ita/ita_comp_ima.c @@ -51,6 +51,11 @@ struct pts_ita_comp_ima_t { */ pts_comp_func_name_t *name; + /** + * AIK keyid + */ + chunk_t keyid; + /** * Sub-component depth */ @@ -62,9 +67,14 @@ struct pts_ita_comp_ima_t { pts_database_t *pts_db; /** - * AIK keyid + * Primary key for Component Functional Name database entry */ - chunk_t keyid; + int cid; + + /** + * Primary key for AIK database entry + */ + int kid; /** * Component is registering measurements @@ -289,8 +299,9 @@ METHOD(pts_component_t, verify, status_t, DBG1(DBG_PTS, "pts database not available"); return FAILED; } - if (this->pts_db->get_comp_measurement_count(this->pts_db, this->name, - this->keyid, algo, &this->count) != SUCCESS) + if (this->pts_db->get_comp_measurement_count(this->pts_db, + this->name, this->keyid, algo, + &this->cid, &this->kid, &this->count) != SUCCESS) { return FAILED; } @@ -314,8 +325,8 @@ METHOD(pts_component_t, verify, status_t, if (this->is_registering) { if (this->pts_db->insert_comp_measurement(this->pts_db, measurement, - this->name, this->keyid, ++this->seq_no, - extended_pcr, algo) != SUCCESS) + this->cid, this->kid, ++this->seq_no, + extended_pcr, algo) != SUCCESS) { return FAILED; } @@ -324,8 +335,8 @@ METHOD(pts_component_t, verify, status_t, else { if (this->pts_db->check_comp_measurement(this->pts_db, measurement, - this->name, this->keyid, ++this->seq_no, - extended_pcr, algo) != SUCCESS) + this->cid, this->kid, ++this->seq_no, + extended_pcr, algo) != SUCCESS) { return FAILED; } @@ -378,8 +389,8 @@ METHOD(pts_component_t, destroy, void, } if (this->is_registering) { - count = this->pts_db->delete_comp_measurements(this->pts_db, this->name, - this->keyid); + 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); diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c index 57b809142..287aae727 100644 --- a/src/libpts/pts/components/ita/ita_comp_tboot.c +++ b/src/libpts/pts/components/ita/ita_comp_tboot.c @@ -41,6 +41,11 @@ struct pts_ita_comp_tboot_t { */ pts_comp_func_name_t *name; + /** + * AIK keyid + */ + chunk_t keyid; + /** * Sub-component depth */ @@ -52,9 +57,14 @@ struct pts_ita_comp_tboot_t { pts_database_t *pts_db; /** - * AIK keyid + * Primary key for Component Functional Name database entry */ - chunk_t keyid; + int cid; + + /** + * Primary key for AIK database entry + */ + int kid; /** * Component is registering measurements @@ -192,8 +202,9 @@ METHOD(pts_component_t, verify, status_t, DBG1(DBG_PTS, "pts database not available"); return FAILED; } - if (this->pts_db->get_comp_measurement_count(this->pts_db, this->name, - this->keyid, algo, &this->count) != SUCCESS) + if (this->pts_db->get_comp_measurement_count(this->pts_db, + this->name, this->keyid, algo, + &this->cid, &this->kid, &this->count) != SUCCESS) { return FAILED; } @@ -217,8 +228,8 @@ METHOD(pts_component_t, verify, status_t, if (this->is_registering) { if (this->pts_db->insert_comp_measurement(this->pts_db, measurement, - this->name, this->keyid, ++this->seq_no, - extended_pcr, algo) != SUCCESS) + this->cid, this->kid, ++this->seq_no, + extended_pcr, algo) != SUCCESS) { return FAILED; } @@ -227,8 +238,8 @@ METHOD(pts_component_t, verify, status_t, else { if (this->pts_db->check_comp_measurement(this->pts_db, measurement, - this->name, this->keyid, ++this->seq_no, - extended_pcr, algo) != SUCCESS) + this->cid, this->kid, ++this->seq_no, + extended_pcr, algo) != SUCCESS) { return FAILED; } @@ -277,8 +288,8 @@ METHOD(pts_component_t, destroy, void, if (this->is_registering) { - count = this->pts_db->delete_comp_measurements(this->pts_db, this->name, - this->keyid); + 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); diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c index 1b7b00e4d..aedabc83f 100644 --- a/src/libpts/pts/pts_database.c +++ b/src/libpts/pts/pts_database.c @@ -114,8 +114,7 @@ METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*, } METHOD(pts_database_t, check_comp_measurement, status_t, - private_pts_database_t *this, chunk_t measurement, - pts_comp_func_name_t *comp_name, chunk_t keyid, + private_pts_database_t *this, chunk_t measurement, int cid, int kid, int seq_no, int pcr, pts_meas_algorithms_t algo) { enumerator_t *e; @@ -123,16 +122,11 @@ METHOD(pts_database_t, check_comp_measurement, status_t, status_t status = NOT_FOUND; e = this->db->query(this->db, - "SELECT ch.hash FROM component_hashes AS ch " - "JOIN keys AS k ON ch.key = k.id " - "JOIN components AS c ON ch.component = c.id " - "WHERE c.vendor_id = ? AND c.name = ? AND c.qualifier = ? " - "AND k.keyid = ? AND ch.seq_no = ? AND ch.pcr = ? AND ch.algo = ? ", - DB_INT, comp_name->get_vendor_id(comp_name), - DB_INT, comp_name->get_name(comp_name), - DB_INT, comp_name->get_qualifier(comp_name), - DB_BLOB, keyid, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo, - DB_BLOB); + "SELECT hash FROM component_hashes " + "WHERE component = ? AND key = ? " + "AND seq_no = ? AND pcr = ? AND algo = ? ", + DB_INT, cid, DB_INT, kid, DB_INT, seq_no, + DB_INT, pcr, DB_INT, algo, DB_BLOB); if (!e) { DBG1(DBG_PTS, "no database query enumerator returned"); @@ -168,23 +162,17 @@ METHOD(pts_database_t, check_comp_measurement, status_t, } METHOD(pts_database_t, insert_comp_measurement, status_t, - private_pts_database_t *this, chunk_t measurement, - pts_comp_func_name_t *comp_name, chunk_t keyid, + private_pts_database_t *this, chunk_t measurement, int cid, int kid, int seq_no, int pcr, pts_meas_algorithms_t algo) { int id; if (this->db->execute(this->db, &id, - "INSERT INTO component_hashes " - "(component, key, seq_no, pcr, algo, hash) VALUES (" - "(SELECT id FROM components" - " WHERE vendor_id = ? AND name = ? AND qualifier = ?), " - "(SELECT id FROM keys WHERE keyid = ?), ?, ?, ?, ?)", - DB_INT, comp_name->get_vendor_id(comp_name), - DB_INT, comp_name->get_name(comp_name), - DB_INT, comp_name->get_qualifier(comp_name), - DB_BLOB, keyid, DB_INT, seq_no, DB_INT, pcr, - DB_INT, algo, DB_BLOB, measurement) == 1) + "INSERT INTO component_hashes " + "(component, key, seq_no, pcr, algo, hash) " + "VALUES (?, ?, ?, ?, ?, ?)", + DB_INT, cid, DB_INT, kid, DB_INT, seq_no, DB_INT, pcr, + DB_INT, algo, DB_BLOB, measurement) == 1) { return SUCCESS; } @@ -194,39 +182,33 @@ METHOD(pts_database_t, insert_comp_measurement, status_t, } METHOD(pts_database_t, delete_comp_measurements, int, - private_pts_database_t *this, pts_comp_func_name_t *comp_name, chunk_t keyid) + private_pts_database_t *this, int cid, int kid) { return this->db->execute(this->db, NULL, - "DELETE FROM component_hashes WHERE " - "component = (SELECT id FROM components" - " WHERE vendor_id = ? AND name = ? AND qualifier = ?) AND " - "key = (SELECT id FROM keys WHERE keyid = ?)", - DB_INT, comp_name->get_vendor_id(comp_name), - DB_INT, comp_name->get_name(comp_name), - DB_INT, comp_name->get_qualifier(comp_name), - DB_BLOB, keyid); + "DELETE FROM component_hashes " + "WHERE component = ? AND key = ?", + DB_INT, cid, DB_INT, kid); } METHOD(pts_database_t, get_comp_measurement_count, status_t, private_pts_database_t *this, pts_comp_func_name_t *comp_name, - chunk_t keyid, pts_meas_algorithms_t algo, int *count) + chunk_t keyid, pts_meas_algorithms_t algo, int *cid, int *kid, int *count) { enumerator_t *e; - int kid; status_t status = SUCCESS; /* Initialize count */ *count = 0; - /* Is the AIK registered? */ + /* If the AIK is registered get the primary key */ e = this->db->query(this->db, - "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT); + "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT); if (!e) { DBG1(DBG_PTS, "no database query enumerator returned"); return FAILED; } - if (!e->enumerate(e, &kid)) + if (!e->enumerate(e, kid)) { DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid); e->destroy(e); @@ -234,16 +216,32 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t, } e->destroy(e); + /* Get the primary key of the Component Functional Name */ + e = this->db->query(this->db, + "SELECT id FROM components " + " WHERE vendor_id = ? AND name = ? AND qualifier = ?", + DB_INT, comp_name->get_vendor_id(comp_name), + DB_INT, comp_name->get_name(comp_name), + DB_INT, comp_name->get_qualifier(comp_name), + DB_INT); + if (!e) + { + DBG1(DBG_PTS, "no database query enumerator returned"); + return FAILED; + } + if (!e->enumerate(e, cid)) + { + DBG1(DBG_PTS, "component functional name not found in database"); + e->destroy(e); + return FAILED; + } + e->destroy(e); + /* Get the number of stored measurements for a given AIK and component */ e = this->db->query(this->db, - "SELECT COUNT(*) FROM component_hashes AS ch " - "JOIN components AS c ON ch.component = c.id " - "WHERE c.vendor_id = ? AND c.name = ? AND c.qualifier = ? " - "AND ch.key = ? AND ch.algo = ? ", - DB_INT, comp_name->get_vendor_id(comp_name), - DB_INT, comp_name->get_name(comp_name), - DB_INT, comp_name->get_qualifier(comp_name), - DB_INT, kid, DB_INT, algo, DB_INT); + "SELECT COUNT(*) FROM component_hashes AS ch " + "WHERE component = ? AND key = ? AND algo = ?", + DB_INT, *cid, DB_INT, *kid, DB_INT, algo, DB_INT); if (!e) { DBG1(DBG_PTS, "no database query enumerator returned"); diff --git a/src/libpts/pts/pts_database.h b/src/libpts/pts/pts_database.h index dd87a5be3..a9f5fa451 100644 --- a/src/libpts/pts/pts_database.h +++ b/src/libpts/pts/pts_database.h @@ -77,41 +77,40 @@ struct pts_database_t { * Check a functional component measurement against value stored in database * * @param measurement measurement hash - * @param comp_name Component Functional Name - * @param keyid SHA-1 hash of AIK public key info + * @param cid Primary key of Component Functional Name entry + * @param kid Primary key of AIK entry in keys table * @param seq_no Measurement sequence number * @param prc Number of the PCR the measurement was extended into * @param algo Hash algorithm used for measurement * @return SUCCESS if check was successful */ status_t (*check_comp_measurement)(pts_database_t *this, chunk_t measurement, - pts_comp_func_name_t *comp_name, chunk_t keyid, - int seq_no, int pcr, pts_meas_algorithms_t algo); + int cid, int kid, int seq_no, int pcr, + pts_meas_algorithms_t algo); /** * Insert a functional component measurement into the database * - * @param measurement measurement hash - * @param comp_name Component Functional Name - * @param keyid SHA-1 hash of AIK public key info + * @param measurement Measurement hash + * @param cid Primary key of Component Functional Name entry + * @param kid Primary key of AIK entry in keys table * @param seq_no Measurement sequence number * @param prc Number of the PCR the measurement was extended into * @param algo Hash algorithm used for measurement * @return SUCCESS if INSERT was successful */ status_t (*insert_comp_measurement)(pts_database_t *this, chunk_t measurement, - pts_comp_func_name_t *comp_name, chunk_t keyid, - int seq_no, int pcr, pts_meas_algorithms_t algo); + int cid, int kid, int seq_no, int pcr, + pts_meas_algorithms_t algo); /** * Delete functional component measurements from the database * - * @param comp_name Component Functional Name - * @param keyid SHA-1 hash of AIK public key info + * @param cid Primary key of Component Functional Name entry + * @param kid Primary key of AIK entry in keys table * @return number of deleted measurement entries */ - int (*delete_comp_measurements)(pts_database_t *this, - pts_comp_func_name_t *comp_name, chunk_t keyid); + int (*delete_comp_measurements)(pts_database_t *this, int cid, int kid); /** * Get the number of measurements for a functional component and AIK @@ -119,12 +118,15 @@ struct pts_database_t { * @param comp_name Component Functional Name * @param keyid SHA-1 hash of AIK public key info * @param algo Hash algorithm used for measurement + * @param cid Primary key of Component Functional Name entry + * @param kid Primary key of AIK entry in keys table * @param count measurement count * @return SUCCESS if COUNT was successful */ status_t (*get_comp_measurement_count)(pts_database_t *this, pts_comp_func_name_t *comp_name, chunk_t keyid, - pts_meas_algorithms_t algo, int *count); + pts_meas_algorithms_t algo, int *cid, int *kid, + int *count); /** * Destroys a pts_database_t object.