diff options
author | Franklin Wei <me@fwei.tk> | 2018-07-08 14:51:34 -0400 |
---|---|---|
committer | Franklin Wei <me@fwei.tk> | 2018-07-08 14:51:34 -0400 |
commit | 945f11f3f70ead44cff2ac76faf68f328a968abc (patch) | |
tree | 2b54422f0150c1de8df6ffa5910b77f6d5881372 | |
parent | 3e7b74359f56c0518abcd420e85a5e3e778e8fd1 (diff) | |
download | csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.zip csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.gz csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.bz2 csaa-945f11f3f70ead44cff2ac76faf68f328a968abc.tar.xz |
Refactor and optimize
-rw-r--r-- | crypto.c | 19 | ||||
-rw-r--r-- | crypto.h | 3 | ||||
-rw-r--r-- | iomt.c | 169 | ||||
-rw-r--r-- | iomt.h | 2 | ||||
-rw-r--r-- | service_provider.c | 43 | ||||
-rw-r--r-- | sqlinit.c | 236 | ||||
-rw-r--r-- | sqlinit.txt | 20 | ||||
-rwxr-xr-x | tabulate.sh | 11 | ||||
-rwxr-xr-x | testall.sh | 21 | ||||
-rwxr-xr-x | testcreate.sh | 2 | ||||
-rwxr-xr-x | testdummy.sh | 24 | ||||
-rwxr-xr-x | testmain.sh | 25 | ||||
-rwxr-xr-x | testmodify.sh | 6 | ||||
-rwxr-xr-x | testmodifyenc.sh | 5 | ||||
-rwxr-xr-x | testretrieve.sh | 5 | ||||
-rw-r--r-- | trusted_module.c | 3 |
16 files changed, 389 insertions, 205 deletions
@@ -41,12 +41,7 @@ hash_t sha256(const void *data, size_t datalen) bool is_zero(hash_t u) { - /* constant-time comparison */ - volatile char c = 0; - for(int i = 0; i < 32; ++i) - c |= u.hash[i]; - - return c == 0; + return !memcmp(u.hash, hash_null.hash, sizeof(u.hash)); } void dump_hash(hash_t u) @@ -484,6 +479,18 @@ void warn(const char *fmt, ...) fprintf(stderr, "\033[31;1mWARNING\033[0m: %s\n", buf); } +void begin_transaction(void *db) +{ + sqlite3 *handle = db; + sqlite3_exec(handle, "BEGIN;", 0, 0, 0); +} + +void commit_transaction(void *db) +{ + sqlite3 *handle = db; + sqlite3_exec(handle, "COMMIT;", 0, 0, 0); +} + void crypto_test(void) { #if 1 @@ -90,6 +90,9 @@ hash_t generate_nonce(void); hash_t derive_key(const char *passphrase, hash_t nonce); hash_t calc_kf(hash_t encryption_key, uint64_t file_idx); +void begin_transaction(void *db); +void commit_transaction(void *db); + void warn(const char *fmt, ...) __attribute__((format(printf, 1, 2))); /* self-test */ @@ -17,9 +17,8 @@ hash_t hash_node(const struct iomt_node node) return hash_null; } -static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st) +static void bind_placeholders(const struct iomt *tree, sqlite3_stmt *st) { - sqlite3_reset(st); if(tree->db.key1_name) { sqlite3_bind_int(st, 1, tree->db.key1_val); @@ -30,6 +29,12 @@ static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st) } } +static void reset_and_bind(const struct iomt *tree, sqlite3_stmt *st) +{ + sqlite3_reset(st); + bind_placeholders(tree, st); +} + /* internal nodes only */ hash_t iomt_getnode(const struct iomt *tree, uint64_t idx) { @@ -190,6 +195,9 @@ hash_t *merkle_complement(const struct iomt *tree, uint64_t leafidx, int **order * be called once, namely when the service provider is created. */ void iomt_fill(struct iomt *tree) { + if(!tree->in_memory) + begin_transaction(tree->db.db); + for(uint64_t i = 0; i < tree->mt_leafcount; ++i) { uint64_t mt_idx = ((uint64_t)1 << tree->mt_logleaves) - 1 + i; @@ -208,6 +216,9 @@ void iomt_fill(struct iomt *tree) 0)); } } + + if(!tree->in_memory) + commit_transaction(tree->db.db); } /* A bit of a hack: our complement calculation returns the *indices* @@ -218,6 +229,8 @@ void iomt_fill(struct iomt *tree) * to modify each function to take the array of all nodes in the tree * in addition to the complement indices, but this function will serve * as a shim in the meantime. */ + +/* TODO: database query? */ hash_t *lookup_nodes(const struct iomt *tree, const uint64_t *indices, int n) { hash_t *ret = calloc(n, sizeof(hash_t)); @@ -228,8 +241,14 @@ hash_t *lookup_nodes(const struct iomt *tree, const uint64_t *indices, int n) void restore_nodes(struct iomt *tree, const uint64_t *indices, const hash_t *values, int n) { + if(!tree->in_memory) + begin_transaction(tree->db.db); + for(int i = 0; i < n; ++i) iomt_setnode(tree, indices[i], values[i]); + + if(!tree->in_memory) + commit_transaction(tree->db.db); } /* Update mt_nodes to reflect a change to a leaf node's @@ -245,6 +264,9 @@ void merkle_update(struct iomt *tree, uint64_t leafidx, hash_t newval, hash_t ** uint64_t idx = ((uint64_t)1 << tree->mt_logleaves) - 1 + leafidx; + if(!tree->in_memory) + begin_transaction(tree->db.db); + iomt_setnode(tree, idx, newval); for(int i = 0; i < tree->mt_logleaves; ++i) { @@ -255,12 +277,16 @@ void merkle_update(struct iomt *tree, uint64_t leafidx, hash_t newval, hash_t ** idx = bintree_parent(idx); + /* TODO: optimize */ /* save old value */ if(old_dep) (*old_dep)[i] = iomt_getnode(tree, idx); iomt_setnode(tree, idx, parent); } + + if(!tree->in_memory) + commit_transaction(tree->db.db); } hash_t iomt_getroot(const struct iomt *tree) @@ -271,7 +297,6 @@ hash_t iomt_getroot(const struct iomt *tree) } /* find a node with given idx */ -/* TODO: replace with database update */ struct iomt_node iomt_find_leaf(const struct iomt *tree, uint64_t idx, uint64_t *leafidx) { if(tree->in_memory) @@ -451,6 +476,7 @@ struct iomt *iomt_new(int logleaves) } /* Assumes `buf' is large enough */ +/* */ static void generate_and_clauses(const struct iomt *tree, char *buf) { buf[0] = '\0'; @@ -461,6 +487,25 @@ static void generate_and_clauses(const struct iomt *tree, char *buf) buf += sprintf(buf, " AND %s = ?2", tree->db.key2_name); } +static void generate_where_clause(const struct iomt *tree, char *buf) +{ + buf[0] = '\0'; + + if(tree->db.key1_name || tree->db.key2_name) + { + buf += sprintf(buf, " WHERE "); + if(tree->db.key1_name) + buf += sprintf(buf, "%s = ?1", tree->db.key1_name); + if(tree->db.key2_name) + { + if(tree->db.key1_name) + buf += sprintf(buf, " AND "); + + buf += sprintf(buf, "%s = ?2", tree->db.key1_name); + } + } +} + /* returns one of the following: "" - no keys ", key1" - key1 only @@ -572,6 +617,73 @@ struct iomt *iomt_new_from_db(void *db, return tree; } +static void iomt_copy_from_db(struct iomt *newtree, const struct iomt *oldtree) +{ + /* Write nodes which are not null (others are assumed to be + * zero), with database query. */ + + assert(!oldtree->in_memory); + + /* PROBLEM: the database could have nodes or leaves whose indexes + * are too large for this logleaves level (from when the tree is + * shrunk) */ + + char and_clauses[1000]; + generate_and_clauses(oldtree, and_clauses); + + char sql[1000]; + sprintf(sql, "SELECT LeafIdx, Idx, NextIdx, Val FROM %s WHERE LeafIdx < ?3%s;", + oldtree->db.leaves_table, + and_clauses); + + sqlite3_stmt *st; + sqlite3_prepare_v2(oldtree->db.db, sql, -1, &st, 0); + bind_placeholders(oldtree, st); + + sqlite3_bind_int64(st, 3, newtree->mt_leafcount); + + int rc; + do { + rc = sqlite3_step(st); + + if(rc == SQLITE_ROW) + { + struct iomt_node node; + + node.idx = sqlite3_column_int64(st, 1); + node.next_idx = sqlite3_column_int64(st, 2); + memcpy(&node.val, sqlite3_column_blob(st, 3), sizeof(node.val)); + + iomt_setleaf(newtree, sqlite3_column_int64(st, 0), node); + } + } while(rc == SQLITE_ROW); + + sqlite3_finalize(st); + + sprintf(sql, "SELECT NodeIdx, Val FROM %s WHERE NodeIdx < ?3%s;", + oldtree->db.nodes_table, + and_clauses); + + sqlite3_prepare_v2(oldtree->db.db, sql, -1, &st, 0); + bind_placeholders(oldtree, st); + + sqlite3_bind_int64(st, 3, 2 * newtree->mt_leafcount - 1); + + do { + rc = sqlite3_step(st); + + if(rc == SQLITE_ROW) + { + hash_t val; + memcpy(&val, sqlite3_column_blob(st, 1), sizeof(val)); + + iomt_setnode(newtree, sqlite3_column_int64(st, 0), val); + } + } while(rc == SQLITE_ROW); + + sqlite3_finalize(st); +} + /* make a copy of the IOMT with database backing (there will be no * pointer semantics between the two trees when this function * returns) */ @@ -586,12 +698,32 @@ struct iomt *iomt_dup_in_db(void *db, key2_name, key2_val, oldtree->mt_logleaves); + /* TODO: make a single DB query for all the leaves/nodes, then insert from there */ + /* This is extremely slow. */ + begin_transaction(newtree->db.db); + /* copy nodes, leaves (we do not recalculate the tree) */ - for(uint64_t i = 0; i < newtree->mt_leafcount; ++i) - iomt_setleaf(newtree, i, iomt_getleaf(oldtree, i)); - for(uint64_t i = 0; i < 2 * newtree->mt_leafcount - 1; ++i) - iomt_setnode(newtree, i, iomt_getnode(oldtree, i)); + if(!oldtree->in_memory) + { + iomt_copy_from_db(newtree, oldtree); + } + else + { + /* Loop over all nodes, but only write the nonzero ones (to + * save time) */ + for(uint64_t i = 0; i < oldtree->mt_leafcount; ++i) + if(oldtree->mem.mt_leaves[i].idx != 0) + iomt_setleaf(newtree, i, oldtree->mem.mt_leaves[i]); + + for(uint64_t i = 0; i < 2 * oldtree->mt_leafcount - 1; ++i) + { + if(!is_zero(oldtree->mem.mt_nodes[i])) + iomt_setnode(newtree, i, oldtree->mem.mt_nodes[i]); + } + } + + commit_transaction(newtree->db.db); return newtree; } @@ -618,12 +750,7 @@ struct iomt *iomt_dup(const struct iomt *oldtree) } else { - /* copy nodes, leaves (we do not recalculate the tree) */ - for(uint64_t i = 0; i < newtree->mt_leafcount; ++i) - iomt_setleaf(newtree, i, iomt_getleaf(oldtree, i)); - - for(uint64_t i = 0; i < 2 * newtree->mt_leafcount - 1; ++i) - iomt_setnode(newtree, i, iomt_getnode(oldtree, i)); + iomt_copy_from_db(newtree, oldtree); } return newtree; @@ -662,6 +789,7 @@ void iomt_serialize(const struct iomt *tree, write_fn(userdata, tree->mem.mt_leaves, sizeof(struct iomt_node) * tree->mt_leafcount); else { + /* TODO: replace with database query */ for(uint64_t i = 0; i < tree->mt_leafcount; ++i) { struct iomt_node node = iomt_getleaf(tree, i); @@ -768,6 +896,14 @@ struct iomt *iomt_from_lines(const char *filename) return tree; } +void print_leaf(struct iomt_node node) +{ + printf("(%lu, %s, %lu)", + node.idx, + hash_format(node.val, 4).str, + node.next_idx); +} + void iomt_dump(const struct iomt *tree) { if(tree) @@ -775,11 +911,8 @@ void iomt_dump(const struct iomt *tree) for(uint64_t i = 0; i < tree->mt_leafcount; ++i) { struct iomt_node node = iomt_getleaf(tree, i); - printf("(%lu, %s, %lu)%s", - node.idx, - hash_format(node.val, 4).str, - node.next_idx, - (i == tree->mt_leafcount - 1) ? "\n" : ", "); + print_leaf(node); + printf("%s", (i == tree->mt_leafcount - 1) ? "\n" : ", "); } } else @@ -106,6 +106,8 @@ struct iomt *iomt_deserialize(int (*read_fn)(void *userdata, void *buf, size_t l void *userdata); void iomt_fill(struct iomt *tree); + +void print_leaf(struct iomt_node node); void iomt_dump(const struct iomt *tree); hash_t iomt_getroot(const struct iomt *tree); diff --git a/service_provider.c b/service_provider.c index 3bca02f..45fc4b0 100644 --- a/service_provider.c +++ b/service_provider.c @@ -240,18 +240,6 @@ void *db_init(const char *filename, bool overwrite, bool *need_init) return db; } -void begin_transaction(void *db) -{ - sqlite3 *handle = db; - sqlite3_exec(handle, "BEGIN;", 0, 0, 0); -} - -void commit_transaction(void *db) -{ - sqlite3 *handle = db; - sqlite3_exec(handle, "COMMIT;", 0, 0, 0); -} - int count_placeholders(void *db) { sqlite3 *handle = db; @@ -397,6 +385,8 @@ void sp_free(struct service_provider *sp) } } +/* TODO: pre-compile these statements */ + /* linear search for record given idx */ static struct file_record *lookup_record(struct service_provider *sp, uint64_t idx) { @@ -433,10 +423,6 @@ static struct file_record *lookup_record(struct service_provider *sp, uint64_t i return NULL; } -/* Should we insert sorted (for O(logn) lookup), or just at the end to - * avoid copying (O(n) lookup, O(1) insertion)? Eventually this will - * be replaced with a SQL backend. We do not check to ensure that - * there are no duplicate file indices; that is up to the caller. */ static void insert_record(struct service_provider *sp, const struct file_record *rec) { //printf("Inserting record %lu\n", rec->idx); @@ -538,7 +524,9 @@ static struct file_version *lookup_version(struct service_provider *sp, sqlite3 *handle = sp->db; if(!version) - version = count_versions(sp, file_idx); + { + return NULL; + } const char *sql = "SELECT * FROM Versions WHERE FileIdx = ?1 AND Version = ?2;"; @@ -638,7 +626,7 @@ struct tm_cert sp_request(struct service_provider *sp, iomt_free(rec->acl); - /* copy the ACL into our database tables */ + /* copy the ACL into our database tables (extremely slow) */ rec->acl = iomt_dup_in_db(sp->db, "ACLNodes", "ACLLeaves", "FileIdx", fr.fr.idx, @@ -793,6 +781,8 @@ struct tm_request sp_createfile(struct service_provider *sp, sp->n_placeholders++; } + printf("Allocated leaf index %lu\n", i); + int *file_orders; hash_t *file_comp = merkle_complement(sp->iomt, i, &file_orders); @@ -1019,6 +1009,9 @@ struct version_info sp_fileinfo(struct service_provider *sp, user_id, &rv2_hmac); + if(!version) + version = rec->version; + struct file_version *ver = lookup_version(sp, rec->idx, version); if(acl_out) @@ -1038,7 +1031,7 @@ struct version_info sp_fileinfo(struct service_provider *sp, return ret; } -/* This file retrieves the file given by file_idx for a given +/* This function retrieves the file given by file_idx for a given * user. *encrypted_secret will be set to the encryption key XOR'd * with HMAC(kf, K). kf will be returned via the *kf pointer. The * returned value is dynamically allocated and must be freed by the @@ -1057,16 +1050,18 @@ void *sp_retrieve_file(struct service_provider *sp, { struct file_record *rec = lookup_record(sp, file_idx); - if(!rec || !count_versions(sp, file_idx)) + if(!rec || !rec->version) { /* Newly created file, no contents. We don't bother to set - * *encrypted_secret or *len. Or, file does not exist. */ + * *encrypted_secret or *len. Or, file does not exist. No + * authenticated denial; the client can use sp_fileinfo() to + * verify this for themselves. */ *len = 0; return NULL; } if(!version) - version = count_versions(sp, file_idx); + version = rec->version; struct file_version *ver = lookup_version(sp, file_idx, version); @@ -1172,7 +1167,7 @@ static void sp_handle_client(struct service_provider *sp, int cl) } case MODIFY_FILE: { - printf("Client: modify file\n"); + printf("Client: modify file %lu\n", user_req.modify_file.file_idx); struct iomt *buildcode = iomt_deserialize(read_from_fd, &cl); struct iomt *composefile = iomt_deserialize(read_from_fd, &cl); size_t filelen; @@ -1206,7 +1201,7 @@ static void sp_handle_client(struct service_provider *sp, int cl) } case RETRIEVE_INFO: { - printf("Client: retrieve info\n"); + printf("Client: retrieve info %lu\n", user_req.retrieve.file_idx); struct iomt *acl = NULL; struct version_info verinfo = sp_fileinfo(sp, user_req.user_id, @@ -32,88 +32,129 @@ unsigned char sqlinit_txt[] = { 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x28, 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x74, 0x72, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x41, 0x43, 0x4c, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, - 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, - 0x20, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, - 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, - 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, - 0x20, 0x28, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78, - 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, - 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, - 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, - 0x28, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, - 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, - 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, - 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, - 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, - 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, - 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, - 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x4e, 0x6f, 0x64, - 0x65, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, - 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, - 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, - 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a, - 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, - 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4b, 0x46, - 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, - 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42, - 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c, - 0x4f, 0x42, 0x2c, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x63, 0x6f, 0x64, - 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x6f, 0x6d, - 0x70, 0x6f, 0x73, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x67, + 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x0a, + 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, + 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, + 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, + 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4c, 0x65, 0x61, 0x66, + 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, + 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x2c, + 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, + 0x4c, 0x4f, 0x42, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, + 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x46, + 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x4e, + 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, + 0x45, 0x52, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, + 0x45, 0x59, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, + 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, + 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, + 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, + 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, + 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4b, 0x46, 0x20, 0x42, 0x4c, 0x4f, 0x42, + 0x2c, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, + 0x0a, 0x43, 0x65, 0x72, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, + 0x48, 0x4d, 0x41, 0x43, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, - 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, - 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, - 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x0a, - 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, - 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, - 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, - 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, - 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c, - 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, - 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, - 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, - 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, - 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, - 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, + 0x45, 0x52, 0x2c, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x76, 0x65, + 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, - 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65, 0x61, - 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, + 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, - 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65, 0x73, - 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, + 0x53, 0x54, 0x53, 0x20, 0x41, 0x43, 0x4c, 0x4c, 0x65, 0x61, 0x76, 0x65, + 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, + 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61, + 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x2c, 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, + 0x52, 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, + 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, + 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, + 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, + 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, + 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, + 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, + 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, + 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, + 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x41, + 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, + 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, + 0x52, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, + 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, + 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, + 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, + 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29, + 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, + 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, + 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, + 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, + 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x42, + 0x43, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, + 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, + 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, + 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, - 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, - 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, - 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x6f, 0x64, - 0x65, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, - 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, - 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, - 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x0a, 0x29, 0x3b, 0x0a, + 0x0a, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x2c, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, + 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, + 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, + 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, + 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, + 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, + 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x2c, + 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, + 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x52, + 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, + 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x42, + 0x43, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, + 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, + 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, + 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, + 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, + 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, + 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, + 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, + 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, + 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, + 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, - 0x53, 0x54, 0x53, 0x20, 0x42, 0x43, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, @@ -136,7 +177,7 @@ unsigned char sqlinit_txt[] = { 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x45, 0x58, 0x49, - 0x53, 0x54, 0x53, 0x20, 0x42, 0x43, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, + 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, @@ -155,48 +196,21 @@ unsigned char sqlinit_txt[] = { 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, - 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4c, - 0x65, 0x61, 0x76, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, - 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, - 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x64, - 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x49, - 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, - 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, - 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, - 0x42, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, - 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, - 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x4c, 0x65, - 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, - 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, - 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, - 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, - 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, 0x78, 0x29, 0x2c, 0x0a, 0x46, - 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x52, 0x45, 0x46, - 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, - 0x54, 0x20, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x43, 0x46, 0x4e, - 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x49, - 0x64, 0x78, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, - 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x56, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, - 0x42, 0x2c, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x20, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x50, 0x52, 0x49, 0x4d, - 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x28, 0x46, 0x69, 0x6c, - 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x2c, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29, 0x2c, - 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, 0x4b, 0x45, 0x59, - 0x20, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x29, 0x20, 0x52, - 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x28, 0x49, 0x64, - 0x78, 0x29, 0x2c, 0x0a, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x20, - 0x4b, 0x45, 0x59, 0x20, 0x28, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x29, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, - 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x00 + 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x31, 0x20, + 0x4f, 0x4e, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, + 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x32, + 0x20, 0x4f, 0x4e, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x61, 0x76, + 0x65, 0x73, 0x28, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e, 0x65, 0x78, 0x74, + 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, 0x33, 0x20, + 0x4f, 0x4e, 0x20, 0x41, 0x43, 0x4c, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4c, 0x65, + 0x61, 0x66, 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x20, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x49, 0x64, 0x78, + 0x34, 0x20, 0x4f, 0x4e, 0x20, 0x41, 0x43, 0x4c, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x28, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x78, 0x2c, 0x20, 0x4e, + 0x6f, 0x64, 0x65, 0x49, 0x64, 0x78, 0x29, 0x3b, 0x0a, 0x00 }; -unsigned int sqlinit_txt_len = 2386; +unsigned int sqlinit_txt_len = 2553; diff --git a/sqlinit.txt b/sqlinit.txt index 72634ea..b8e34ec 100644 --- a/sqlinit.txt +++ b/sqlinit.txt @@ -12,27 +12,24 @@ DROP TABLE IF EXISTS CFLeaves; DROP TABLE IF EXISTS CFNodes; CREATE TABLE IF NOT EXISTS FileRecords ( -Idx INTEGER, +Idx INTEGER PRIMARY KEY, Ver INTEGER, Ctr INTEGER, Cert BLOB, HMAC BLOB, -ACL_logleaves INTEGER, -PRIMARY KEY (Idx) +ACL_logleaves INTEGER ); CREATE TABLE IF NOT EXISTS FileLeaves ( -LeafIdx INTEGER, +LeafIdx INTEGER PRIMARY KEY, Idx INTEGER, NextIdx INTEGER, -Val BLOB, -PRIMARY KEY (LeafIdx) +Val BLOB ); CREATE TABLE IF NOT EXISTS FileNodes ( -NodeIdx INTEGER, -Val BLOB, -PRIMARY KEY (NodeIdx) +NodeIdx INTEGER PRIMARY KEY, +Val BLOB ); CREATE TABLE IF NOT EXISTS Versions ( @@ -109,3 +106,8 @@ PRIMARY KEY (FileIdx, Version, NodeIdx), FOREIGN KEY (FileIdx) REFERENCES FileRecords(Idx), FOREIGN KEY (Version) REFERENCES Versions(Version) ); + +CREATE INDEX Idx1 ON Versions(FileIdx, Version); +CREATE INDEX Idx2 ON FileLeaves(Idx, NextIdx); +CREATE INDEX Idx3 ON ACLLeaves(FileIdx, LeafIdx); +CREATE INDEX Idx4 ON ACLNodes(FileIdx, NodeIdx); diff --git a/tabulate.sh b/tabulate.sh index 3db27e5..4d10f73 100755 --- a/tabulate.sh +++ b/tabulate.sh @@ -1,2 +1,11 @@ #!/bin/bash -for i in `seq 10 62`; do for j in `seq 1 1`; do echo -n "$i $j "; cat run_"$i"_"$j".txt | awk '/Elapsed/ || /Maximum/ || /User time/ || /System time/' | awk 'BEGIN{line=0}{if(line%4<=1)printf($4" ");if(line %4==2)printf($8" ");if(line%4==3)printf($6" ");}{line+=1}END{printf("\n");}'; done; done +for i in `seq 10 62` +do + rm -f run_"$i".txt + for j in `seq 1 40` + do + echo -n "$i $j " >> run_"$i".txt + cat run_"$i"_"$j".txt | awk '/Elapsed/ || /Maximum/ || /User time/ || /System time/' | awk 'BEGIN{line=0}{if(line%4<=1)printf($4" ");if(line %4==2)printf($8" ");if(line%4==3)printf($6" ");}{line+=1}END{printf("\n");}' >> run_"$i".txt + done + +done @@ -1,18 +1,23 @@ #!/bin/bash -if [[ $# -ne 1 ]] +if [[ $# -ne 2 ]] then - echo "Usage: "$0" LOGLEAVES" + echo "Usage: "$0" LOGLEAVES RUNS" exit 1 fi + +runs=$2 + echo "Initializing..." +rm files -rf + ./server $1 csaa.db --overwrite > /dev/null & pid=$! -sleep 1 -/usr/bin/time -v ./testcreate.sh ./client -/usr/bin/time -v ./testmodify.sh ./client -/usr/bin/time -v ./testretrieve.sh ./client -/usr/bin/time -v ./testmodifyenc.sh ./client +sleep .2 +/usr/bin/time -v ./testcreate.sh ./client $runs +/usr/bin/time -v ./testmodify.sh ./client $runs +/usr/bin/time -v ./testretrieve.sh ./client $runs +/usr/bin/time -v ./testmodifyenc.sh ./client $runs echo "Encrypted retrieve: " -/usr/bin/time -v ./testretrieve.sh ./client +/usr/bin/time -v ./testretrieve.sh ./client $runs kill -SIGINT $! diff --git a/testcreate.sh b/testcreate.sh index dd4e875..3e3ca21 100755 --- a/testcreate.sh +++ b/testcreate.sh @@ -1,6 +1,6 @@ #!/bin/bash echo "Create:" -for i in $(seq 1 100) +for i in $(seq 1 $2) do $1 -u 1 -k a create > /dev/null if [[ $? -ne 0 ]] diff --git a/testdummy.sh b/testdummy.sh index 7050655..a10d621 100755 --- a/testdummy.sh +++ b/testdummy.sh @@ -1,11 +1,19 @@ #!/bin/bash -echo "Initializing..." -rm csaa.db -sqlite3 csaa.db < sqlinit.txt -./dummy_server 10 csaa.db > /dev/null & +if [[ $# -ne 2 ]] +then + echo "Usage: "$0" LOGLEAVES RUNS" + exit 1 +fi + +runs=$2 + +echo "Initializing dummy..." +rm files -rf + +./dummy_server $1 csaa.db --overwrite > /dev/null & pid=$! -sleep 1 -/usr/bin/time -v ./testcreate.sh ./dummy_client -/usr/bin/time -v ./testmodify.sh ./dummy_client -/usr/bin/time -v ./testretrieve.sh ./dummy_client +sleep .2 +/usr/bin/time -v ./testcreate.sh ./dummy_client $runs +/usr/bin/time -v ./testmodify.sh ./dummy_client $runs +/usr/bin/time -v ./testretrieve.sh ./dummy_client $runs kill -SIGINT $! diff --git a/testmain.sh b/testmain.sh index 1bb6fc7..dacfb8f 100755 --- a/testmain.sh +++ b/testmain.sh @@ -1,19 +1,22 @@ #!/bin/bash mkdir -p results +trials=5 -for i in `seq 1 1` -do - ./testdummy.sh 2> results/dummy_$i.txt - sleep 1 -done - -for i in `seq 8 62` +for i in `seq 8 30` do echo "logleaves "$i - for j in `seq 1 1` + + runs=$(echo '2^'"$i" | bc) + + echo "Doing "$trials"x"$runs" operations" + for j in $(seq 1 $trials) do - ./testall.sh $i 2> results/run_"$i"_"$j".txt - # give time to close - sleep 1 + + ./testall.sh $i $runs 2> results/run_"$i"_"$j".txt + sleep .2 + + # dummy + ./testdummy.sh $i $runs 2> results/dummy_"$i"_"$j".txt + sleep .2 done done diff --git a/testmodify.sh b/testmodify.sh index 86a78d1..bd20dc7 100755 --- a/testmodify.sh +++ b/testmodify.sh @@ -1,9 +1,9 @@ #!/bin/bash +# modify files 1 - $2, creating a new version with fixed contents echo "Modify:" -$1 -u 1 -k a create > /dev/null -for i in $(seq 1 100) +for i in $(seq 1 $2) do - $1 -u 1 -k a modifyfile -f 1 -i container1/hello-world.tar > /dev/null + $1 -u 1 -k a modifyfile -f $i -i container1/hello-world.tar > /dev/null if [[ $? -ne 0 ]] then echo "Request failed!" diff --git a/testmodifyenc.sh b/testmodifyenc.sh index 96457ba..5c182cc 100755 --- a/testmodifyenc.sh +++ b/testmodifyenc.sh @@ -1,9 +1,8 @@ #!/bin/bash echo "Modify (encrypted):" -$1 -u 1 -k a create > /dev/null -for i in $(seq 1 100) +for i in $(seq 1 $2) do - $1 -u 1 -k a modifyfile -e -f 1 -i container1/hello-world.tar > /dev/null + $1 -u 1 -k a modifyfile -e -f $i -i container1/hello-world.tar > /dev/null if [[ $? -ne 0 ]] then echo "Request failed!" diff --git a/testretrieve.sh b/testretrieve.sh index 566c48b..ed1bbf8 100755 --- a/testretrieve.sh +++ b/testretrieve.sh @@ -1,8 +1,9 @@ #!/bin/bash +# retrieve files 1 - $2, outputting to `out' echo "Retrieve:" -for i in $(seq 1 100) +for i in $(seq 1 $2) do - $1 -u 1 -k a retrievefile -f 1 -o out > /dev/null + $1 -u 1 -k a retrievefile -f $i -o out > /dev/null if [[ $? -ne 0 ]] then echo "Request failed!" diff --git a/trusted_module.c b/trusted_module.c index c59beb1..c579316 100644 --- a/trusted_module.c +++ b/trusted_module.c @@ -90,6 +90,8 @@ void tm_savestate(const struct trusted_module *tm, const char *filename) } fwrite(&tm->root, sizeof(tm->root), 1, f); + + printf("Saving state, root=%s\n", hash_format(tm->root, 4).str); } struct trusted_module *tm_new_from_savedstate(const char *filename) @@ -114,6 +116,7 @@ struct trusted_module *tm_new_from_savedstate(const char *filename) } fread(&tm->root, sizeof(tm->root), 1, f); + printf("Loading state, root=%s\n", hash_format(tm->root, 4).str); return tm; } |