diff options
-rw-r--r-- | container1/Dockerfile | 2 | ||||
-rw-r--r-- | crypto.c | 83 | ||||
-rw-r--r-- | crypto.h | 18 | ||||
-rw-r--r-- | service_provider.c | 39 |
4 files changed, 119 insertions, 23 deletions
diff --git a/container1/Dockerfile b/container1/Dockerfile new file mode 100644 index 0000000..f8be7bb --- /dev/null +++ b/container1/Dockerfile @@ -0,0 +1,2 @@ +line1 +line2
\ No newline at end of file @@ -244,7 +244,7 @@ void restore_nodes(hash_t *nodes, const int *indices, const hash_t *values, int * point to an array of length mt_logleaves that contains the old node * values (whose indices are returned by bintree_ancestors()). NOTE: * this function will NOT set the corresponding IOMT leaf; use - * iomt_update_by_leafidx for that. */ + * iomt_update_leaf_full for that. */ void merkle_update(struct iomt *tree, uint64_t leafidx, hash_t newval, hash_t **old_dep) { if(old_dep) @@ -307,8 +307,8 @@ void iomt_update(struct iomt *tree, uint64_t idx, hash_t newval) merkle_update(tree, leaf - tree->mt_leaves, hash_node(leaf), NULL); } -void iomt_update_by_leafidx(struct iomt *tree, uint64_t leafidx, - uint64_t new_idx, uint64_t new_next_idx, hash_t new_val) +void iomt_update_leaf_full(struct iomt *tree, uint64_t leafidx, + uint64_t new_idx, uint64_t new_next_idx, hash_t new_val) { struct iomt_node *leaf = tree->mt_leaves + leafidx; leaf->idx = new_idx; @@ -318,6 +318,33 @@ void iomt_update_by_leafidx(struct iomt *tree, uint64_t leafidx, merkle_update(tree, leafidx, hash_node(leaf), NULL); } +void iomt_update_leaf_idx(struct iomt *tree, uint64_t leafidx, + uint64_t new_idx) +{ + struct iomt_node *leaf = tree->mt_leaves + leafidx; + leaf->idx = new_idx; + + merkle_update(tree, leafidx, hash_node(leaf), NULL); +} + +void iomt_update_leaf_nextidx(struct iomt *tree, uint64_t leafidx, + uint64_t new_next_idx) +{ + struct iomt_node *leaf = tree->mt_leaves + leafidx; + leaf->next_idx = new_next_idx; + + merkle_update(tree, leafidx, hash_node(leaf), NULL); +} + +void iomt_update_leaf_hash(struct iomt *tree, uint64_t leafidx, + hash_t new_val) +{ + struct iomt_node *leaf = tree->mt_leaves + leafidx; + leaf->val = new_val; + + merkle_update(tree, leafidx, hash_node(leaf), NULL); +} + /* Create a merkle tree with 2^logleaves leaves, each initialized to a * zero leaf (not a placeholder!) */ struct iomt *iomt_new(int logleaves) @@ -357,6 +384,56 @@ void iomt_free(struct iomt *tree) } } +/* arbitrary */ +#define FILELINES_LOGLEAVES 10 + +struct iomt *iomt_from_lines(const char *filename) +{ + struct iomt *tree = iomt_new(FILELINES_LOGLEAVES); + + FILE *f = fopen(filename, "r"); + + SHA256_CTX ctx; + SHA256_Init(&ctx); + + int c; + uint64_t line = 0; + + while(c != EOF) + { + c = fgetc(f); + + char ch = c; + + if(c != EOF) + SHA256_Update(&ctx, &ch, sizeof(ch)); + + if(ch == '\n' || c == EOF) + { + hash_t linehash; + SHA256_Final(linehash.hash, &ctx); + + /* set this leaf to loop around */ + iomt_update_leaf_full(tree, line, line + 1, 1, linehash); + + if(line > 0) + { + /* make previously inserted leaf point to this leaf */ + iomt_update_leaf_nextidx(tree, line - 1, line + 1); + } + + line++; + + /* re-initialize for next line */ + SHA256_Init(&ctx); + } + } + + fclose(f); + + return tree; +} + struct hashstring hash_format(hash_t h, int n) { struct hashstring ret; @@ -88,9 +88,23 @@ struct iomt *iomt_new(int logleaves); struct iomt *iomt_dup(const struct iomt *tree); void iomt_free(struct iomt *tree); +/* Find a leaf with IOMT index `idx' and change its value, propagating + * up the tree. */ void iomt_update(struct iomt *tree, uint64_t idx, hash_t newval); -void iomt_update_by_leafidx(struct iomt *tree, uint64_t leafidx, - uint64_t new_idx, uint64_t new_next_idx, hash_t new_val); + +/* Set all the fields of a leaf node (not an IOMT index!) */ +void iomt_update_leaf_full(struct iomt *tree, uint64_t leafidx, + uint64_t new_idx, uint64_t new_next_idx, hash_t new_val); +void iomt_update_leaf_idx(struct iomt *tree, uint64_t leafidx, + uint64_t new_idx); +void iomt_update_leaf_nextidx(struct iomt *tree, uint64_t leafidx, + uint64_t new_next_idx); +void iomt_update_leaf_hash(struct iomt *tree, uint64_t leafidx, + hash_t new_val); + +/* Create an IOMT where the leaves are the hash of file lines */ +struct iomt *iomt_from_lines(const char *filename); + void iomt_fill(struct iomt *tree); void iomt_dump(const struct iomt *tree); diff --git a/service_provider.c b/service_provider.c index d55ae49..421d377 100644 --- a/service_provider.c +++ b/service_provider.c @@ -156,7 +156,7 @@ struct service_provider *sp_new(const void *key, size_t keylen, int logleaves) * insert our desired number of nodes by using EQ certificates to * update the internal IOMT root. Note that leaf indices are * 1-indexed. */ - iomt_update_by_leafidx(sp->iomt, + iomt_update_leaf_full(sp->iomt, 0, 1, 1, hash_null); @@ -171,29 +171,25 @@ struct service_provider *sp_new(const void *key, size_t keylen, int logleaves) assert(eq.type == EQ); /* update previous leaf's index */ - sp->iomt->mt_leaves[i - 1].next_idx = i + 1; - merkle_update(sp->iomt, i - 1, hash_node(sp->iomt->mt_leaves + i - 1), NULL); + iomt_update_leaf_nextidx(sp->iomt, i - 1, i + 1); /* next_idx is set to 1 to keep everything circularly linked; * in the next iteration it will be updated to point to the * next node, if any */ - sp->iomt->mt_leaves[i] = (struct iomt_node) { i + 1, 1, hash_null }; - merkle_update(sp->iomt, i, hash_node(sp->iomt->mt_leaves + i), NULL); + iomt_update_leaf_full(sp->iomt, i, i + 1, 1, hash_null); assert(tm_set_equiv_root(sp->tm, &eq, hmac)); } - /* We shouldn't need this; the incremental update_tree() calls - * should give the same result. */ - //fill_tree(sp); - - /* everything else is already zeroed by calloc */ return sp; } static void free_version(struct file_version *ver) { free(ver->contents); + + iomt_free(ver->buildcode); + iomt_free(ver->composefile); } static void free_record(struct file_record *rec) @@ -395,7 +391,7 @@ struct user_request sp_createfile(struct service_provider *sp, hash_t *file_comp = merkle_complement(sp->iomt, i, &file_orders); struct iomt *acl = iomt_new(ACL_LOGLEAVES); - iomt_update_by_leafidx(acl, + iomt_update_leaf_full(acl, 0, user_id, user_id, u64_to_hash(3)); @@ -725,19 +721,26 @@ void sp_test(void) check("File creation", ack_verify(&req, "a", 1, ack_hmac)); + /* IOMT generation from file */ + struct iomt *buildcode = iomt_from_lines("container1/Dockerfile"); + check("IOMT generation from file 1", buildcode != NULL); + + struct iomt_node node1 = { 1, 2, sha256("line1\n", 6) }; + struct iomt_node node2 = { 2, 1, sha256("line2", 5) }; + + hash_t correct_root = merkle_parent(hash_node(&node1), hash_node(&node2), 0); + check("IOMT generation from file 2", hash_equals(buildcode->mt_nodes[0], correct_root)); + #define N_MODIFY 100 start = clock(); for(int i = 0; i < N_MODIFY; ++i) - req = sp_modifyfile(sp, 1, "a", 1, 1, hash_null, hash_null, NULL, NULL, "contents", 8, &ack_hmac); + req = sp_modifyfile(sp, 1, "a", 1, 1, hash_null, hash_null, buildcode, NULL, "contents", 8, &ack_hmac); stop = clock(); printf("%.1f modifications per second\n", (double)N_MODIFY * CLOCKS_PER_SEC / (stop - start)); check("File modification", ack_verify(&req, "a", 1, ack_hmac)); - } - /* file info retrieval */ - { hash_t hmac; /* check inside range, but empty slot */ struct version_info vi = sp_fileinfo(sp, 1, 12, 1, &hmac); @@ -757,7 +760,7 @@ void sp_test(void) hash_t gamma = sha256("contents", 8); hash_t kf = hash_null; - hash_t lambda = calc_lambda(gamma, NULL, NULL, kf); + hash_t lambda = calc_lambda(gamma, buildcode, NULL, kf); struct version_info correct = { 1, N_MODIFY + 1, 1, N_MODIFY, lambda }; check("File info retrieval 2", !memcmp(&correct, &vi, sizeof(vi))); @@ -780,8 +783,8 @@ void sp_test(void) { /* ACL modify */ struct iomt *newacl = iomt_new(ACL_LOGLEAVES); - iomt_update_by_leafidx(newacl, 0, 1, 2, u64_to_hash(3)); - iomt_update_by_leafidx(newacl, 1, 2, 1, u64_to_hash(1)); + iomt_update_leaf_full(newacl, 0, 1, 2, u64_to_hash(3)); + iomt_update_leaf_full(newacl, 1, 2, 1, u64_to_hash(1)); hash_t ack; bool success = true; |